IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Problème fonction EnumServicesStatusEx()


Sujet :

Windows

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 162
    Points : 62
    Points
    62
    Par défaut Problème fonction EnumServicesStatusEx()
    Bonjour à tous !
    J'essaye au travers de ce code ci-dessous, de récupérer la liste des services sur une machine locale.Cependant j'ai un souci pour trouver la taille nécessaire de la variable dwBufSize

    Constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Services::Services()//constructeur
    {
        //variables
           dwBufSize=0;
           dwrest = 0;
           dwrsmhndl=0;
           dwSvrCount = 0;
           pessp =0;
           pqsc = 0;
           buffer = (char*) VirtualAlloc(0,8192,MEMDISPO,PAGE_READWRITE);
        //allocation mémoire 
        pessp = (LPENUM_SERVICE_STATUS_PROCESS) (buffer + 1024); // 3 Ko dispo
        pqsc = (LPQUERY_SERVICE_CONFIG) (buffer + 4096); // 4 Ko dispo 
        handleServices =OpenSCManager(0,0,SC_MANAGER_ENUMERATE_SERVICE);
    
    }
    Ma fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    char* Services::getServices(int i)
    {
       
        //variable de mon .h
       /* SC_HANDLE handleServices ;
        DWORD dwrest, dwrsmhndl, dwSvrCount, bok;
        DWORD dwBufSize; // la varible 
        LPENUM_SERVICE_STATUS_PROCESS pessp ;
        LPQUERY_SERVICE_CONFIG pqsc ;
        char * buffer;*/ 
    
        if(!buffer) 
         {
           perror("ERREUR_BUFFER");
           exit(0);
         }
    
        
        if(!handleServices)
        {
            dwerror = GetLastError();
            printf("Erreur handle de services : %s\n",dwerror);
        }
        
        bok = EnumServicesStatusEx(handleServices, 
                                       SC_ENUM_PROCESS_INFO,
                                       SERVICE_WIN32 | SERVICE_DRIVER,
                                       SERVICE_STATE_ALL,
                                       (byte*)pessp,
                                       dwBufSize,
                                       &dwrest,
                                       &dwSvrCount,
                                       NULL,
                                       NULL);
         
          
         return (char*)pessp[i].lpDisplayName ;
    
    }

  2. #2
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par Hellgast Voir le message
    Cependant j'ai un souci pour trouver la taille nécessaire de la variable dwBufSize
    Pas d'problème, MSDN est ton ami,
    EnumServicesStatusEx Function

    Return Value
    If the function succeeds, the return value is nonzero.
    If the function fails, the return value is zero. To get extended error information, call GetLastError. The following errors may be returned.

    Return code -> Description
    ERROR_MORE_DATA -> The buffer is too small. Not all data in the active database could be returned. The pcbBytesNeeded parameter contains the number of bytes required to receive the remaining entries.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 162
    Points : 62
    Points
    62
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Pas d'problème, MSDN est ton ami,
    J'ai déjà vérifié, c'est pas très clair et les exemple encore moins, j'arrive a afficher que 127 services au lieu de plus de 200 ... mystère !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    char* Services::getServices(int i)
    {
    
    	//variables
    	 SC_HANDLE handleServices ;
    	 DWORD dwrest, dwrsmhndl, dwSvrCount, bok;
    	 DWORD dwBufSize;
    	 LPENUM_SERVICE_STATUS_PROCESS pessp ;
    	 LPQUERY_SERVICE_CONFIG pqsc ;
    	 char * buffer;
    	 
    	 //allocation mémoire 
    	 //  : buffer 1024, pessp 3072, pqsc 4096, total = 8192
    	    buffer = (char*) VirtualAlloc(0,20000,MEMDISPO,PAGE_READWRITE); //#define MEMDISPO  (MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN)
    	    pessp = (LPENUM_SERVICE_STATUS_PROCESS) (buffer + 1024); // 3 Ko dispo
    	    pqsc = (LPQUERY_SERVICE_CONFIG) (buffer + 4096); // 4 Ko dispo
    	    handleServices =OpenSCManager(0,0,SC_MANAGER_ENUMERATE_SERVICE);
    
    	    if(!buffer) 
    	    {
    	      perror("PROBLEME MEMOIRE");
    	    }
    
    	
    	if(!handleServices)
    	{
    		dwerror = GetLastError();
    		printf("Erreur handle de services : %s\n",dwerror);
    	}
    	//On récupère la valaur de 'dwrest' qui nous donne le nombre d'octets nécessaire
    	//pour contenir les entrée de services
    	 EnumServicesStatusEx(
    	  handleServices,
    	  SC_ENUM_PROCESS_INFO,
    	  SERVICE_WIN32, 
    	  SERVICE_STATE_ALL,
    	  (BYTE*)NULL,
    	  dwBufSize,
    	  &dwrest,
    	  &dwSvrCount,
    	  NULL,
    	  NULL);
    
    	 if (dwrest< 0x01)
    	 {
    	  printf("EnumServicesStatusEx fail ?? \n");	 
    	 }
    	 dwBufSize = dwrest; //initialisation de la taille du BufSize; correspond à 'pcbBytesNeeded' au nombre d'octets nécessaires
    
    	cout<<"=====Test n° 1====="<<endl;
    	cout<<"Octets necessaires:["<<dwrest<<"]"<<endl;
    	cout<<"Taille du buffer:["<<dwBufSize<<"]"<<endl;
    	cout<<"Nombre de services :["<<dwSvrCount<<"]"<<endl;
    
    	//initialiser les variables
    	dwrsmhndl = 0;
    	dwSvrCount = 0;
    	dwerror = 0;
    	
    	bok = EnumServicesStatusEx(handleServices, 
    			  					 SC_ENUM_PROCESS_INFO,
    			  					 SERVICE_WIN32 | SERVICE_DRIVER,
    			  					 SERVICE_STATE_ALL,
    			  					 (BYTE*)pessp,
    			  					 dwBufSize,
    			  					 &dwrest,
    			  					 &dwSvrCount,
    			  					 &dwrsmhndl,
    			  					 NULL);
    	
    	//test affichage
    	cout<<"=====Test n° 2====="<<endl;
    	cout<<"Taille du buffer:"<<dwBufSize<<endl;
    	cout<<"Octets necessaires:"<<dwrest<<endl;
    	cout<<"Nombre de services :"<<dwSvrCount<<endl;
    		
    	//test de la fonction 'EnumServicesStatusEx' 
    	 if(bok == 0)// la fonction retourne 0 en cas d'erreur
    	 {
    		 dwerror = GetLastError();
    	 }
    	  if((dwerror = GetLastError()) != ERROR_MORE_DATA)//si il n'y a pas assez d'espace
    	  {
    		  perror("ERROR_MORE_DATA");
    	  }
    	  if(!dwSvrCount)
    	 {
    		  perror("dwSvrCount"); 
         }
    	 
    	  for(unsigned int i=0;i<dwSvrCount;i++)
    	  {
    		  //lister les services [description][nom du service]
    		  printf("Nom service [%d] : [%s][%s]\n",i,pessp[i].lpDisplayName,pessp[i].lpServiceName);
    		  printf("---------------------------------\n");
    		  	
    	  }
    	  CloseServiceHandle(handleServices);
    	  
    	 return (char*)pessp[i].lpDisplayName ;
    }

  4. #4
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Yop !

    Je ne pourrai pas beaucoup t'aider, je ne suis pas spécialiste C et le code est difficile à lire sur le forum.

    Néanmoins, je t'ai trouvé ça :
    Si la fonction renvoie Error_More_Data c'est que le buffer est trop petit pour recevoir la totalité des informations des membres du groupe, dans ce cas effectuez d'autres appels tant qu'il reste des informations à lire ou augmentez la taille du buffer.
    Bon, c'est du Delphi, mais ça ressemble et l'idée y est...
    Fais une rechercher sur ERROR_MORE_DATA dans la page.

    Sinon, un exemple en VB (j'aime bien le "While lResult = ERROR_MORE_DATA"), un truc à lire (le dernier commentaire tout en bas), et un petit dernier pour la route.
    Avec ça, tu devrais y arriver,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 162
    Points : 62
    Points
    62
    Par défaut
    Si la fonction renvoie Error_More_Data c'est que le buffer est trop petit pour recevoir la totalité des informations des membres du groupe, dans ce cas effectuez d'autres appels tant qu'il reste des informations à lire ou augmentez la taille du buffer.
    En faite il faut appeler la fonction EnumServicesStatusEx() plusieur fois ? je regarderais les doc ce soir, merci en tout cas !

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Généralement, on appelle ce genre de fonctions deux fois: Une avec une taille nulle pour que la fonction retourne la taille nécessaire, et une fois après avoir alloué le buffer.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 162
    Points : 62
    Points
    62
    Par défaut
    c'est ce que je fais:

    - dans un premier temps, on lance la fonction avec les données vides
    = ce qui nous retourne la taille nécessaire pour les donnée (dans mon code la variable dwrest)
    -Puis, on initialise ta taille du buffer avec cette même variable qui renvoi la taille nécessaire (dans mon code dwBufSize =dwrest)
    -Ensuite on lance la fonction avec tout les paramètres corrects

    Résultat quand j'affiche les variable :
    >>1er partie, après avoir appelé la fonction 'vide'
    =====Test n° 1=====
    Octets necessaires:[13160] // dwrest
    Taille du buffer:[13160] // dwBufSize
    Nombre de services :[0] //dwSvrCoun, le compteur
    =>dwrsmhndl :0
    >>Test 2, après avoir exécuter la fonctionqui contient les données
    =====Test n° 2=====
    Taille du buffer:13160 //ok, bien initialisé
    Octets necessaires:18804 // la je comprend pas pourquoi on à une nouvelle valeur
    Nombre de services :127 //que 127 service au lieu de 200 ou plus
    =>dwrsmhndl :127 // sa non plus

  8. #8
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Salut,

    dans un des liens que je t'ai passé ("un truc à lire"), on peut lire, tout en bas,
    > even though the buffer is adequate
    after each reading (RegQueryValueEx) of a registry value, buffersizeentry is changed to the size of last read number of bytes. So you should set again this value before using it in a new RegQueryValueEx
    Je ne sais pas du tout si ça peut s'appliquer à ton cas mais bon, c'est à creuser...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 162
    Points : 62
    Points
    62
    Par défaut
    Après l'exécution de ma fonction, GetLastError() me renvoi l'erreur n° 87 qui représente INVALID_PARAMETER . D'où cela pourrai provenir ?

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Qu'au moins un des paramètres n'est pas bon.

    Trêve de plaisanterie, je pense que vous réinitialisez de manière incorrecte les paramètres.

    Pouvez-vous poster un projet VS minimaliste reproduisant le problème ?

Discussions similaires

  1. Problème : Fonctions et commande Execute
    Par bubi dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 15/11/2005, 11h01
  2. Problème fonction SDL
    Par seeme dans le forum SDL
    Réponses: 2
    Dernier message: 06/11/2005, 20h22
  3. Problème fonction PL/SQL
    Par SSJ17Vegeta dans le forum PL/SQL
    Réponses: 2
    Dernier message: 29/10/2005, 21h14
  4. Problème fonction et trigger sous 7.2
    Par anoukhan dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 22/06/2005, 22h53
  5. Réponses: 2
    Dernier message: 20/08/2004, 17h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo