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

C++ Discussion :

Lecture de la base de registre


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 89
    Par défaut Lecture de la base de registre
    Bonjour,

    J'ai besoin dans un programme d'accéder à la base de registre, pour trouver certaines informations sur les clé USB connectées : Vid/Pid, et numéro de série.

    J'ai pu voir que ces infos étaient disponibles sur des clé 0, 1, 2, ..... à l'endroit suivant :

    SYSTEM/CurrentControlSet/Service/USBSTOR/Enum
    J'ai écrit un petit programme pour récupérer la valeur de cette clé, mais comme je débute, j'ai une erreur et je ne comprend pas d'où elle vient.
    J'utilise le code suivant :

    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
     
    char* LectureRegistre()
    {
    	HKEY hk;
    	char *test;
    	LPBYTE valeur=NULL;
    	LPDWORD sizeValeur=NULL;
    	LPCWSTR cle = _T("SYSTEM\\CurrentControlSet\\Service\\USBSTOR\\Enum");
     
    	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, cle, 0, KEY_READ, &hk))
    	{
    		if(RegQueryValueEx(hk,  _T("0"), 0, 0, valeur, sizeValeur))
    		{
    			sizeValeur=(LPDWORD)sizeof(valeur);
    			if(RegQueryValueEx(hk,  _T("0"), 0, 0, valeur, sizeValeur))
    			{
    				test=(char*)*valeur;
    			}
    		}
    	}
    	RegCloseKey(hk);
    	return test;
     
    }
    L'erreur se produit lors de l'exécution, au niveau de la ligne test=(char*)*valeur;

    Exception non gérée à 0x0041392b dans CryptageCle.exe : 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00000000.
    Il semblerai donc que le pointeur valeur ne reçoivent pas l'adresse de cette clé.

    Merci d'avance pour votre aide

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 89
    Par défaut
    En fait, j'avais oublié un s à Services dans le chemin de la clé. Je l'ai vu en rajoutant des ERROR_SUCCESS à mes if (qui était apparemment validés à chaque fois).

    Par contre, le pointeur valeur reste toujours à l'adresse 0x00000000. Je n'arrive pas à comprendre pourquoi.

    Je laisse le nouveau code, si besoin :

    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
     
    char* LectureRegistre()
    {
    	HKEY hk;
    	BYTE test2;
    	char *data = "Erreur";
    	LPBYTE valeur=NULL;
    	LPDWORD sizeValeur=NULL;
    	LPCWSTR cle = _T("SYSTEM\\CurrentControlSet\\Services\\USBSTOR\\Enum");
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, cle, 0, KEY_READ, &hk) == ERROR_SUCCESS)
    	{
    		if(RegQueryValueEx(hk,  _T("0"), 0, 0, valeur, sizeValeur) == ERROR_SUCCESS)
    		{
    			sizeValeur=(LPDWORD)sizeof(valeur);
    			if(RegQueryValueEx(hk,  _T("0"), 0, 0, valeur, sizeValeur) == ERROR_SUCCESS)
    			{
    				data=(char*)*valeur;
    			}
    			else
    			{
    				MessageBox(0,_T("Erreur de lecture de la clé registre contenant les infos sur la clé USB"),NULL,0);
    			}
    		}
    		else
    		{
    			MessageBox(0,_T("Erreur de lecture de la clé registre contenant les infos sur la clé USB (2)"),NULL,0);
    		}
    	}
    	else
    	{
    		MessageBox(0,_T("Erreur d'ouverture de la base de registre pour lire les infos sur la clé"),NULL,0);
    	}
     
     
    	RegCloseKey(hk);
    	return data;
     
    }
    Le débogage me dit :
    + &hk 0x0012f318 HKEY__ * *
    + hk 0x00000ed0 {unused=??? } HKEY__ *
    + valeur 0x00000000 <Ptr> incorrect unsigned char *
    Sinon, j'ai oublié de préciser, je sais pas si c'est important : je suis sous windows et j'utilise visual c++ 2005

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Allez, je me lance dans la réponse

    L'appel à RegOpenKeyEx() me semble correct par contre, ca coince du côté de RegQueryValueEx()

    Ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    LPBYTE valeur=NULL;
    LPDWORD sizeValeur=NULL;
    if(RegQueryValueEx(hk,  _T("0"), 0, 0, valeur, sizeValeur) == ERROR_SUCCESS)
    Mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    BYTE valeur[256];
    DWORD sizeValeur=sizeof(valeur);
    DWORD Type;
    if(RegQueryValueEx(hk,  _T("0"), 0, &Type, valeur, &sizeValeur) == ERROR_SUCCESS)
    De plus, je ne sais pas ton mode de compilation Unicode ou Mbcs, c'est très important.

    le code "LCWSTR cle = _T("SYSTEM..." me fait croire que c'est du unicode et donc si c'est cela, la string retournée par l'appel RegQueryValueEx() sera aussi une chaine unicode. Tu ne peux pas et ne doit pas la retourner en tant que char * (code de retour de ta fonction)

    Il va falloir passer par un appel à WideCharToMultiByte().

    D'ailleur, à ce sujet, si tu es en Unicode, que fait une fonction retournant un char * ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Le pointeur valeur, tu dois l'allouer toi-même.
    Ce code corrigé devrait retourner NULL en cas d'échec, ou un pointeur générique vers les données de la clé en cas de succès.
    Ce pointeur devra être libéré en appelant la fonction FreeRegistre() quand tu n'en auras plus besoin.
    Note: Si la valeur est de type REG_SZ, les données seront un tableau de TCHAR.
    Code C++ : 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
    void* AllocRegistre(size_t taille)
    {
    	return new char[taille];
    }
     
    void FreeRegistre(void*pv)
    {
    	char* p = static_cast< char* >(pv);
    	delete[] p;
    }
     
    void* LectureRegistre()
    {
    	HKEY hk = NULL;
    	LPBYTE pValeur=NULL;
    	DWORD sizeValeur=0; /* Pas un pointeur ici */
    	LPCTSTR const cle = _T("SYSTEM\\CurrentControlSet\\Services\\USBSTOR\\Enum");
     
    	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, cle, 0, KEY_READ, &hk) == ERROR_SUCCESS)
    	{
    		if(RegQueryValueEx(hk,  _T("0"), NULL, NULL, NULL, &sizeValeur) == ERROR_SUCCESS)
    		{
    			pValeur = static_cast< LPBYTE >(AllocRegistre(sizeValeur));
    			if(RegQueryValueEx(hk,  _T("0"), NULL, NULL, pValeur, &sizeValeur) == ERROR_SUCCESS)
    			{
    				// OK!
    			}
    			else
    			{
    				MessageBox(NULL, _T("Erreur de lecture de la clé registre contenant les infos sur la clé USB"), NULL, MB_OK|MB_ICONERROR);
    				FreeRegistre(pValeur), pValeur=NULL;
    			}
    		}
    		else
    		{
    			MessageBox(NULL, _T("Erreur de lecture de la clé registre contenant les infos sur la clé USB (2)"), NULL, MB_OK|MB_ICONERROR);
    		}
    		RegCloseKey(hk);
    	}
    	else
    	{
    		MessageBox(NULL, _T("Erreur d'ouverture de la base de registre pour lire les infos sur la clé"), NULL, MB_OK|MB_ICONERROR);
    	}
    	return pValeur;
    }
    Au sujet du LPDWORD: http://blogs.msdn.com/oldnewthing/ar...28/508689.aspx
    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.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 89
    Par défaut
    Merci pour vos réponses.

    Je test ça dans l'après midi, et je vous dis ce que ça donne.

    Pour le mode de compilation, je sais pas ce que j'utilise. J'ai créé un projet MFC et je n'ai pas touché aux paramètres de compilation. Où est ce que je peux voir ça?

    Sinon, cette fonction retourne un char car je veux traiter le résultat, et le mettre dans un fichier texte, mais ce n'est peut être pas la meilleur solution.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Le problème pour "retourner un char", c'est que RegQueryValueEx() retourne des TCHAR, donc il y aura (ou pas, selon le mode de compilation) une conversion à faire.
    Vu que le nom de la valeur est hard-codé, je te conseille d'utiliser explicitement RegQueryValueExA(). Et peut-être réjouter du code pour être sûr que la variable est bien de type REG_SZ...
    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
    void* AllocRegistre(size_t taille)
    {
    	return new char[taille];
    }
     
    void FreeRegistre(void*pv)
    {
    	char* p = static_cast< char* >(pv);
    	delete[] p;
    }
     
    char* LectureRegistre()
    {
    	HKEY hk = NULL;
    	LPBYTE pValeur=NULL;
    	LPCTSTR const cle = _T("SYSTEM\\CurrentControlSet\\Services\\USBSTOR\\Enum");
     
    	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, cle, 0, KEY_READ, &hk) == ERROR_SUCCESS)
    	{
    		DWORD sizeValeur=0; /* Pas un pointeur ici */
    		DWORD type = 0;
    		if(RegQueryValueExA(hk,  "0", NULL, &type, NULL, &sizeValeur) == ERROR_SUCCESS && type==REG_SZ)
    		{
    			pValeur = static_cast< LPBYTE >(AllocRegistre(sizeValeur));
    			if(RegQueryValueExA(hk,  "0", NULL, NULL, pValeur, &sizeValeur) == ERROR_SUCCESS)
    			{
    				// OK!
    			}
    			else
    			{
    				MessageBox(NULL, _T("Erreur de lecture de la clé registre contenant les infos sur la clé USB"), NULL, MB_OK|MB_ICONERROR);
    				FreeRegistre(pValeur), pValeur=NULL;
    			}
    		}
    		else
    		{
    			MessageBox(NULL, _T("Erreur de lecture de la clé registre contenant les infos sur la clé USB (2)"), NULL, MB_OK|MB_ICONERROR);
    		}
    		RegCloseKey(hk);
    	}
    	else
    	{
    		MessageBox(NULL, _T("Erreur d'ouverture de la base de registre pour lire les infos sur la clé"), NULL, MB_OK|MB_ICONERROR);
    	}
    	return pValeur;
    }
    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 confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 89
    Par défaut
    Re-bonjour,

    J'ai essayé les deux solutions que vous m'avez proposé, mais je n'arrive toujours pas à obtenir la chaîne que je veux. L'erreur d'exécution est corrigée, et j'arrive à obtenir quelque chose dans mon fichier de sortie :

    Avec le code de ram_0000, j'obtiens la chaîne suivante :
    ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÀõ ÌÌÌÌÌÌÌÌÌÌÌ ÌÌÌÌÌÌÌÌü ÌÌÌÌÌÌÌÌ
    Avec celui de Médinoc, j'obtiens la première lettre de la chaîne stockée dans le registre : U. j'ai essayé avec d'autres clés registre, et cela correspond bien à la première lettre de la chaîne de caractères

    Je devrai obtenir la chaîne suivante (de type REG_SZ) :
    USB\Vid_0930&Pid_6533\0DA0C560B370CA66
    J'ai bien vu :
    Note: Si la valeur est de type REG_SZ, les données seront un tableau de TCHAR.
    mais lorsque je cast en TCHAR, je n'obtient que la valeur héxadécimal de la lettre que j'avais avant.

    J'ai essayé plusieurs codes pour récupérer les lettres suivantes, mais j'ai une erreur à chaque fois... J'avoue que je n'ai pas vraiment compris le fonctionnement du code de Médinoc, ce qui m'empêche de trouver la solution moi même :

    -Pour moi, une fonction de la forme void nomFonction() ne renvoie rien.
    -pValeur est un pointeur, et devrait donc être une adresse héxadécimale, mais quand je fais valeur=(char*)LectureRegistre(); je devrai avoir une adresse dans valeur.

    Est ce que quelqu'un peut m'expliquer ça?

    Merci d'avance

    edit : Désolé, j'avais pas vu ton dernier message Médinoc, peut être que ça va m'aider. Je m'y met tout de suite

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 89
    Par défaut
    Ça marche.

    Merci beaucoup pour ton aide.

    Juste une dernière question : une fois que j'ai appelé la fonction lectureRegistre dans le programme principal, je dois appeler FreeRegistre() pour libérer le pointeur, c'est bien ça?

    Merci encore, ça fait un petit moment que j'essayais d'obtenir ces infos sans succès, et grâce à toi, j'ai pu me débloquer.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Citation Envoyé par CyberSlan Voir le message
    Juste une dernière question : une fois que j'ai appelé la fonction lectureRegistre dans le programme principal, je dois appeler FreeRegistre() pour libérer le pointeur, c'est bien ça?
    Oui, c'est bien ça.
    Citation Envoyé par CyberSlan Voir le message
    Ça marche.

    Merci beaucoup pour ton aide.

    <snip>

    Merci encore, ça fait un petit moment que j'essayais d'obtenir ces infos sans succès, et grâce à toi, j'ai pu me débloquer.
    De rien
    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.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture dans la base de registre
    Par therealmancool dans le forum C
    Réponses: 10
    Dernier message: 21/04/2009, 18h39
  2. Ecriture, lecture de la base de registre sous vista
    Par ninaleo dans le forum API, COM et SDKs
    Réponses: 7
    Dernier message: 05/12/2008, 10h07
  3. Java Lecture clé en base de registre
    Par ritchie23 dans le forum Débuter avec Java
    Réponses: 0
    Dernier message: 07/11/2008, 18h00
  4. Lecture de la base de registre
    Par scourt dans le forum Windows
    Réponses: 3
    Dernier message: 13/01/2007, 13h23
  5. Réponses: 2
    Dernier message: 12/07/2006, 16h45

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