Pourquoi ce programme provoque une erreur (windows)? [c/c++/dll] - C++ - Programmation
Marsh Posté le 19-04-2002 à 00:07:04
Je suis pas sûr du tout mais essaye :
if(EnumProcesses(&lpidProcess,sizeof(lpidProcess),&cbNeeded))
Marsh Posté le 19-04-2002 à 13:30:49
Messire_Le_Geux a écrit a écrit : Je suis pas sûr du tout mais essaye : if(EnumProcesses(&lpidProcess,sizeof(lpidProcess),&cbNeeded)) |
le problème ne vient pas de cette ligne (elle est bonne car je récupère les PID des Processus) mais de EnumProcessModules.
edit: lpidProcess est un tableau, donc son adresse est bien lpidProcess (et sa valeur lpidProcess[i] )
et j'ai vérifié sur http://www.codeguru.com/system/killer.html
[jfdsdjhfuetppo]--Message édité par nico23--[/jfdsdjhfuetppo]
Marsh Posté le 19-04-2002 à 17:45:03
aucune idée, jamais bossé avec ça. en attendant, tu peux essayer plusieurs trucs :
* aligner ton bloc de mem sur 4 octets
* passer à la fonction un trèèès gros tableau
* passer à la fonction le nombre d'entrées du tableau, et pas sa taille en bytes
oui, le dernier point contredit la doc. mais la doc crosoft, sur les trucs pointus, j'ai essayé et j'ai eu beaucoup de problèmes. teste voir.
si tu ne veux qu'énumérer les process, tu peux utiliser la librairie toolhelp (qui énumère les process, threads, dlls) : http://msdn.microsoft.com/library/ [...] Module.asp
Marsh Posté le 19-04-2002 à 18:21:35
youdontcare a écrit a écrit : * aligner ton bloc de mem sur 4 octets |
je comprend pas ce que tu veux dire?
merci pour ces infos, je vais essayer (j'essayerai toolhelp un peu plus tard)
[jfdsdjhfuetppo]--Message édité par nico23--[/jfdsdjhfuetppo]
Marsh Posté le 19-04-2002 à 18:27:23
nico23 a écrit a écrit : je comprend pas ce que tu veux dire? |
c'est juste un des trucs qui m'est venu à l'esprit, y'a de fortes chances que ça n'ait rien à voir, mais on sait jamais.
aligner =
char* ptr = new .....
ptr = 0x78787f
aligné sur 4 octets, l'adresse est un multiple de 4. (la taille d'un pid).
et tu obtiens quelle taille dans cbNeeded ?
Marsh Posté le 19-04-2002 à 18:50:18
youdontcare a écrit a écrit : * passer à la fonction un trèèès gros tableau * passer à la fonction le nombre d'entrées du tableau, et pas sa taille en bytes |
Je viens de regarder le code mais il n'y a pas de tableau.
HMODULE hMod;
if ( EnumProcessesModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) // ligne 54
{
GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) ); //56
Marsh Posté le 19-04-2002 à 18:56:57
plus haut j'ai écrit a écrit : et tu obtiens quelle taille dans cbNeeded ? |
et si tu lui passais un (gros) tableau à la fonction ?
Marsh Posté le 19-04-2002 à 18:59:10
youdontcare a écrit a écrit : c'est juste un des trucs qui m'est venu à l'esprit, y'a de fortes chances que ça n'ait rien à voir, mais on sait jamais. aligner = char* ptr = new ..... ptr = 0x78787f aligné sur 4 octets, l'adresse est un multiple de 4. (la taille d'un pid). et tu obtiens quelle taille dans cbNeeded ? |
la taille dépend du nom récupérer si c'est InternetExplorer.exe cbNeeded =264 (j'en ai un autre à 104 mais ca plante lorsque je veux récupérer le nom, si je mets en commentaire le getmodulebasename je vais un peut plus loin avant un autre plantage du cette fois à enumprocessmodules)
Marsh Posté le 19-04-2002 à 19:10:59
youdontcare a écrit a écrit : et si tu lui passais un (gros) tableau à la fonction ? |
Ca change rien.
Marsh Posté le 19-04-2002 à 19:13:52
Quant on fait int * ptr=new int[10];
il faut faire delete [10] ptr; ou delete ptr; ?
D'après ma doc il faut faire la 1ère solution mais mon compilateur n'en veut pas.
Marsh Posté le 19-04-2002 à 19:19:21
trois choses :
* j'ai lu ton code plus en détail, c'est infâme. INDENTE et SOIS CONSISTENT. (tu es en partie responsable de mon mal de crâne )
* CHAR szProcessName[MAX_PATH] = _T("unknown" );
vire cette atrocité. je n'ai aucune idée du comportement de la chose. char name[...]; ok. ensuite pour copier une string dedans, strcpy(). un char* name = "string" alloue un tableau de la taille de la string en question.
* passe un tableau à EnumProcessesModules() :
HMODULE modules[1024];
if (EnumProcessesModules(..., modules, sizeof(modules), ...)
Marsh Posté le 19-04-2002 à 19:19:50
nico23 a écrit a écrit : Quant on fait int * ptr=new int[10]; il faut faire delete [10] ptr; ou delete ptr; ? D'après ma doc il faut faire la 1ère solution mais mon compilateur n'en veut pas. |
delete [] ptr.
Marsh Posté le 19-04-2002 à 23:34:29
J'ai fait le programme avec la librairie toolhelp et la j'ai pas de problème. Je me demande d'où vient le problème popur l'autre programme.
Marsh Posté le 20-04-2002 à 11:06:45
nico23 a écrit a écrit : J'ai fait le programme avec la librairie toolhelp et la j'ai pas de problème. |
cool.
nico23 a écrit a écrit : Je me demande d'où vient le problème popur l'autre programme. |
me too. mais comme je n'ai ni 2000 ni xp, je ne peux pas tester.
Marsh Posté le 20-04-2002 à 17:30:46
Maintenant pour m'éviter de tous redéclaré a chaque fois (si j'ai besoin de réutiliser ces fonctions), je voudrais savoir comment je pourrais déclarer des librairies (avec le fichier header ...) pour utiliser ces fonctions de dll. (j'ai pas les headers car j'utilise dev-c++)
Pour éviter de faire ca à chaque fois:
typedef HANDLE (WINAPI *PCreateToolhelp32Snapshot) (DWORD , DWORD );
HINSTANCE hModPSAPI = LoadLibrary("KERNEL32.dll" );
PCreateToolhelp32Snapshot CreateToolhelp32Snapshot;
CreateToolhelp32Snapshot = (PCreateToolhelp32Snapshot) GetProcAddress(hModPSAPI ,"CreateToolhelp32Snapshot" );
Marsh Posté le 20-04-2002 à 17:34:47
j'ai écrit a écrit : J'ai fait le programme avec la librairie toolhelp et la j'ai pas de problème. Je me demande d'où vient le problème popur l'autre programme. |
enfin si un petit: dans les msdn ils disent (si j'ai bien traduit) qu'il faut utiliser la fonction CloseToolhelp32Snapshot et pas closehandle sinon ca fait une erreur. Or j'ai le contraire, plantage si j'utilise CloseToolhelp32Snapshot et pas de plantage pour closehandle (d'ailleurs le closehandle retourne true donc il a bien fonctionné): bizzare!
edit:
PS:
[citation]
trois choses :
* j'ai lu ton code plus en détail, c'est infâme. INDENTE et SOIS CONSISTENT. (tu es en partie responsable de mon mal de crâne )
* CHAR szProcessName[MAX_PATH] = _T("unknown" );
vire cette atrocité. je n'ai aucune idée du comportement de la chose. char name[...]; ok. ensuite pour copier une string dedans, strcpy(). un char* name = "string" alloue un tableau de la taille de la string en question.
* passe un tableau à EnumProcessesModules() :
HMODULE modules[1024];
if (EnumProcessesModules(..., modules, sizeof(modules), ...) [/citation]
Le code n'est pas de moi à 100% (seulement environ 95% )
exemple pris sur: http://www.codeguru.com/system/killer.html
[jfdsdjhfuetppo]--Message édité par nico23--[/jfdsdjhfuetppo]
Marsh Posté le 21-04-2002 à 17:14:32
>> Maintenant pour m'éviter de tous redéclaré a chaque fois
dans l'exemple, il déclare pour pouvoir charger la dll dynamiquement -> le code marchera sur tout windows, en cas d'erreur (si pas nt, la fonction n'est pas dispo), il peut afficher son message d'erreur explicatif. sinon windows te sort un charabia.
donc pour éviter de tout redéclarer, tu inclus le .h, tu appelles la fonction, et s'il faut une librairie, tu linkes avec elle (project settings > link).
>> problème avec CloseHandle()
houla, j'en sais rien, réinstalle windows ?
>> Le code n'est pas de moi à 100% (seulement environ 95% )
ce qui n'empêche qu'il est infâme. tu es sur un forum, la moindre des politesses est de présenter un code lisible et de se relire.
Marsh Posté le 21-04-2002 à 22:44:54
youdontcare a écrit a écrit : dans l'exemple, il déclare pour pouvoir charger la dll dynamiquement -> le code marchera sur tout windows, en cas d'erreur (si pas nt, la fonction n'est pas dispo), il peut afficher son message d'erreur explicatif. sinon windows te sort un charabia. donc pour éviter de tout redéclarer, tu inclus le .h, tu appelles la fonction, et s'il faut une librairie, tu linkes avec elle (project settings > link). |
Tu as peut-être pas fait attention, mais j'ai dit que je n'avait pas le .h (j'utilises dev-c++) donc je souhaite le crée avec la librairie.
Mais je trouve pas ca terrible de faire un truc du genre:
HANDLE CreateToolhelp32Snapshot (DWORD SNAP, DWORD ID)
{
typedef HANDLE (WINAPI *PCreateToolhelp32Snapshot) (DWORD , DWORD );
hModPSAPI = LoadLibrary("KERNEL32.dll" );
PCreateToolhelp32Snapshot sCreateToolhelp32Snapshot;
sCreateToolhelp32Snapshot = (PCreateToolhelp32Snapshot) GetProcAddress(hModPSAPI ,"CreateToolhelp32Snapshot" );
return sCreateToolhelp32Snapshot(SNAP,ID);
}
Donc existerait-il un autre moyen pour déclaré les fonctions d'une dll (pour eviter de redefinir la fonction comme ci dessus)?
Marsh Posté le 21-04-2002 à 22:54:22
nico23 a écrit a écrit : Donc existerait-il un autre moyen pour déclaré les fonctions d'une dll (pour eviter de redefinir la fonction comme ci dessus)? |
non. mais tu peux toujours écrire une macro.
si tu downloades la platform sdk sur msdn.microsoft.com, tu devrais avoir les headers.
Marsh Posté le 18-04-2002 à 20:31:59
Salut
Quelqu'un pourrait m'expliquer pourquoi ce programme (très inspiré de http://www.codeguru.com/system/killer.html) provoque une erreur (et est fermé par windows)?
Le problème viendrai de la ligne 54 (le if), si elle est mise en commentaire y a plus le problème. La ligne 56 quant a elle ferait planter le programme plus rapidement. (dépassement? mais d'où viendrait il?)
(Ce programme utilise la dll psapi, donc seul les pocesseurs de NT, 2k et xp peuvent l'essayer.)
#include <stdio.h>
#include <windows.h>
#include <iostream.h>
int main(int argc, char *argv[])
{ CHAR szProcessName[MAX_PATH] = _T("unknown" ); HMODULE hMod;
HINSTANCE hModPSAPI ;
typedef bool (*PEnumProcesses)(DWORD* , UINT, DWORD *);
typedef bool (*PEnumProcessesModules)( HANDLE, HMODULE*, DWORD, LPDWORD );
typedef DWORD (WINAPI *PGetModuleBaseName)( HANDLE, HMODULE, LPTSTR, UINT );
hModPSAPI = LoadLibrary("psapi.dll" );
PEnumProcesses EnumProcesses;
EnumProcesses = (PEnumProcesses) GetProcAddress(hModPSAPI ,"EnumProcesses" );
PEnumProcessesModules EnumProcessesModules;
EnumProcessesModules = (PEnumProcessesModules) GetProcAddress(hModPSAPI,"EnumProcessModules" );
#ifdef UNICODE
PGetModuleBaseName GetModuleBaseName =
(PGetModuleBaseName)GetProcAddress( hModPSAPI,
"GetModuleBaseNameW" );
#else
PGetModuleBaseName GetModuleBaseName =
(PGetModuleBaseName)GetProcAddress( hModPSAPI,
"GetModuleBaseNameA" );
#endif
if ( !EnumProcesses) {printf("pb" ); getchar(); return false;}
DWORD lpidProcess[100]; // array of process identifiers
//DWORD cb=100; // size of array
DWORD cbNeeded; // number of bytes returned
if(EnumProcesses(lpidProcess,sizeof(lpidProcess),&cbNeeded))
{ //printf("nb octets:%d\n",cbNeeded);
int nb_proc=cbNeeded/sizeof(DWORD);
printf("nb de processus: %d\n",nb_proc);
//printf("liste des processus:\n" );
for(int i=0;i<nb_proc;i++)
{
printf("num: %d PID:%d\n",i,lpidProcess[i]);//}
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, lpidProcess[i] );
cout<<hProcess<<"\n";
if ( hProcess==NULL ) {printf("echec! erreur: %d\n",GetLastError());} else
{ //cout<<hProcess<<"\n";
//printf("%d\n",lpidProcess[i]);
getchar();
if ( EnumProcessesModules( hProcess, &hMod, (DWORD) sizeof(hMod), &cbNeeded) ) // ligne 54
{
GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) ); //56
cout<<szProcessName<<"\n";
}
}
CloseHandle( hProcess );
}
} else printf("echec! erreur: %d",GetLastError());
getchar();
return 0;
}
[jfdsdjhfuetppo]--Message édité par nico23--[/jfdsdjhfuetppo]