Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
887 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [c/c++/dll]Pourquoi ce programme provoque une erreur (windows)?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[c/c++/dll]Pourquoi ce programme provoque une erreur (windows)?

n°128129
nico23
Posté le 18-04-2002 à 20:31:59  profilanswer
 

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]

mood
Publicité
Posté le 18-04-2002 à 20:31:59  profilanswer
 

n°128191
Messire_Le​_Geux
Posté le 19-04-2002 à 00:07:04  profilanswer
 

Je suis pas sûr du tout mais essaye :
if(EnumProcesses(&lpidProcess,sizeof(lpidProcess),&cbNeeded))

n°128511
nico23
Posté le 19-04-2002 à 13:30:49  profilanswer
 

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.
 
 [:dirakocha]
 
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]

n°128695
nico23
Posté le 19-04-2002 à 17:34:52  profilanswer
 

[:ruisseau%20de%20larmes]  [:dirakocha]

n°128696
youdontcar​e
Posté le 19-04-2002 à 17:45:03  profilanswer
 

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

n°128697
youdontcar​e
Posté le 19-04-2002 à 17:46:36  profilanswer
 

(et toolhelp marche aussi sur win9x).

n°128702
nico23
Posté le 19-04-2002 à 18:21:35  profilanswer
 

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]

n°128706
youdontcar​e
Posté le 19-04-2002 à 18:27:23  profilanswer
 

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 ?

n°128709
nico23
Posté le 19-04-2002 à 18:50:18  profilanswer
 

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

n°128711
youdontcar​e
Posté le 19-04-2002 à 18:56:57  profilanswer
 

plus haut j'ai écrit a écrit :

et tu obtiens quelle taille dans cbNeeded ?


et si tu lui passais un (gros) tableau à la fonction ?

mood
Publicité
Posté le 19-04-2002 à 18:56:57  profilanswer
 

n°128713
nico23
Posté le 19-04-2002 à 18:59:10  profilanswer
 

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)

n°128715
nico23
Posté le 19-04-2002 à 19:10:59  profilanswer
 

youdontcare a écrit a écrit :

et si tu lui passais un (gros) tableau à la fonction ?  




 
Ca change rien.

n°128716
nico23
Posté le 19-04-2002 à 19:13:52  profilanswer
 

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.

n°128717
youdontcar​e
Posté le 19-04-2002 à 19:19:21  profilanswer
 

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 :lol:)
 
* 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), ...)

n°128718
youdontcar​e
Posté le 19-04-2002 à 19:19:50  profilanswer
 

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.

n°128772
nico23
Posté le 19-04-2002 à 23:34:29  profilanswer
 

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.

n°128824
youdontcar​e
Posté le 20-04-2002 à 11:06:45  profilanswer
 

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.

n°128885
nico23
Posté le 20-04-2002 à 17:30:46  profilanswer
 

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" );

n°128886
nico23
Posté le 20-04-2002 à 17:34:47  profilanswer
 

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 :lol:)  
 
* 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%  :D )
exemple pris sur: http://www.codeguru.com/system/killer.html

 

[jfdsdjhfuetppo]--Message édité par nico23--[/jfdsdjhfuetppo]

n°129059
youdontcar​e
Posté le 21-04-2002 à 17:14:32  profilanswer
 

>> 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 ? :D
 
>> 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.

n°129119
nico23
Posté le 21-04-2002 à 22:44:54  profilanswer
 

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)?

n°129120
youdontcar​e
Posté le 21-04-2002 à 22:54:22  profilanswer
 

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.

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [c/c++/dll]Pourquoi ce programme provoque une erreur (windows)?

 

Sujets relatifs
[Delphi] lancer un programme DOS ? [résolu][PERL] execution de programme externe
Probleme de formulaire ou de PHP... j'arrive pas a trouver l'erreur[delphi]ca vous dit quelque chose ce message d'erreur?
C/C++/windows 2000 : empécher l'écran de s'éteindre[C++Builder] Message Windows de rafraichissement
ASP erreur bizarreErreur Sql
programme qui "lance" d'un index.htm lorsqu'on met un cdromerreur php pairage
Plus de sujets relatifs à : [c/c++/dll]Pourquoi ce programme provoque une erreur (windows)?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR