OVH Cloud OVH Cloud

Récupération d'un DWORD d'une value de la registry

6 réponses
Avatar
vbadier
Bonjour,

J'ai un pb avec RegQueryValueEx() : autant la fonction renvoie
correctement une chaine de caract=E8re, autant elle me renvois jamais la
bonne valeur pour un DWORD.

J'ai =E9cris une fonction qui est sens=E9e me permettre de r=E9cup=E9rer
une valeur depuis la registry. Je passe le nom d'une valeur =E0 la
fonction, ainsi que la cl=E9e qui l'abrite. Si la r=E9cup=E9ration se
passe bien, un pointeur sur une structure correctement remplie est
retourn=E9e, sinon NULL.

typedef struct {
DWORD Type;
BYTE * Data;
DWORD DataLen;
} REGVALUE;

Je n'ai pas utilis=E9, volontairement, RegEnumValue() afin de ne pas
avoir =E0 parser d'=E9ventuelles grande quantit=E9 de valeur.


D=E9sol=E9 pour la longeur de la fonction :

REGVALUE * PkgGetKeyValue (char * KeyName, char * ValueName)
{
HKEY * hkey;
REGVALUE * RegValue;

hkey =3D PkgOpenRegistry(KeyName);
if (hkey =3D=3D NULL)
return NULL;

RegValue =3D malloc(sizeof(REGVALUE));
if (RegValue =3D=3D NULL)
return NULL;

/* Get the Type and length of the value */
if (RegQueryValueEx(*hkey, ValueName, NULL, &RegValue->Type,
NULL, &RegValue->DataLen) !=3D ERROR_SUCCESS)
{
free(RegValue);
PkgCloseRegistry(hkey);
return NULL;
}

/* Get the exact amount of memory for the value requested */
if ((RegValue->Type =3D=3D REG_SZ)
|| (RegValue->Type =3D=3D REG_EXPAND_SZ)
|| (RegValue->Type =3D=3D REG_MULTI_SZ))
{
RegValue->Data =3D malloc((RegValue->DataLen)+1);
if (RegValue->Data =3D=3D NULL)
{
free(RegValue);
return NULL;
}
memset(RegValue->Data, '\0', RegValue->DataLen + 1);
}
else
{
RegValue->Data =3D malloc(RegValue->DataLen);
if (RegValue->Data =3D=3D NULL)
{
free(RegValue);
return NULL;
}
RegValue->Data =3D 0;
}

/* Get the Value */
if (RegQueryValueEx(*hkey, ValueName, NULL, &RegValue->Type,
RegValue->Data, &RegValue->DataLen) !=3D ERROR_SUCCESS)
{
free(RegValue->Data);
free(RegValue);
PkgCloseRegistry(hkey);
return NULL;
}

/* Just because DevC++ debugger crash often */
if ((RegValue->Type =3D=3D REG_SZ)
|| (RegValue->Type =3D=3D REG_EXPAND_SZ)
|| (RegValue->Type =3D=3D REG_MULTI_SZ))
{
printf("Data (char) : %s\n", RegValue->Data);
}
else
printf("Data (DWORD) : %i\n", RegValue->Data);

PkgCloseRegistry(hkey);
return RegValue;
}

6 réponses

Avatar
Vincent Burel
quand vous faites un RegQueryValueEx, il faut impérativement initialiser la
taille (chez vous RegValue->DataLen) avec la bonne valeur. Cette argument
est IN / OUT.

VB


wrote in message
news:
Bonjour,

J'ai un pb avec RegQueryValueEx() : autant la fonction renvoie
correctement une chaine de caractère, autant elle me renvois jamais la
bonne valeur pour un DWORD.

J'ai écris une fonction qui est sensée me permettre de récupérer
une valeur depuis la registry. Je passe le nom d'une valeur à la
fonction, ainsi que la clée qui l'abrite. Si la récupération se
passe bien, un pointeur sur une structure correctement remplie est
retournée, sinon NULL.

typedef struct {
DWORD Type;
BYTE * Data;
DWORD DataLen;
} REGVALUE;

Je n'ai pas utilisé, volontairement, RegEnumValue() afin de ne pas
avoir à parser d'éventuelles grande quantité de valeur.


Désolé pour la longeur de la fonction :

REGVALUE * PkgGetKeyValue (char * KeyName, char * ValueName)
{
HKEY * hkey;
REGVALUE * RegValue;

hkey = PkgOpenRegistry(KeyName);
if (hkey == NULL)
return NULL;

RegValue = malloc(sizeof(REGVALUE));
if (RegValue == NULL)
return NULL;

/* Get the Type and length of the value */
if (RegQueryValueEx(*hkey, ValueName, NULL, &RegValue->Type,
NULL, &RegValue->DataLen) != ERROR_SUCCESS)
{
free(RegValue);
PkgCloseRegistry(hkey);
return NULL;
}
Avatar
vbadier
Bonjour,

Dans cette fonction, je fait 2 fois appel à RegQueryValueEx(). La
première afin de déterminer la taille mémoire que je doit alouer
pour que le second appel à RegQueryValueEx() n'échoue pas et qu'il
n'y ai pas de perte de place. Je me suis référé au SDK pour cela, et
notez que sur le second appel la valeur lpcbData (RegValue->DataLen
ici) est correctement initialisée.

D'ailleurs, en debuggant, j'ai pu vérifier qu'après le retour du
premier appel à RegQueryValueEx(), la valeur RegValue->DataLen est
correct (4 pour un DWORD). Or, le retour du second appel ne me renvois
pas la valeur de cette clée (toujours 0 àlors qu'elle a une autre
valeur en réalité).

Donc, oui, je suis d'accord pour le IN/OUT, et c'est ce qui est fait
dans le second appel. Mais ca ne résoud pas mon problème,
malheureusement.
Avatar
Vincent Burel
ha ouai, mais faut initialiser aussi le type avant appel !
RegValue->Type = REG_DWORD pour un entier 32 byte.
ou RegValue->Type = REG_BINARY si vous ne connaissez pas la taille.

VB

wrote in message
news:
Bonjour,

Dans cette fonction, je fait 2 fois appel à RegQueryValueEx(). La
première afin de déterminer la taille mémoire que je doit alouer
pour que le second appel à RegQueryValueEx() n'échoue pas et qu'il
n'y ai pas de perte de place. Je me suis référé au SDK pour cela, et
notez que sur le second appel la valeur lpcbData (RegValue->DataLen
ici) est correctement initialisée.

D'ailleurs, en debuggant, j'ai pu vérifier qu'après le retour du
premier appel à RegQueryValueEx(), la valeur RegValue->DataLen est
correct (4 pour un DWORD). Or, le retour du second appel ne me renvois
pas la valeur de cette clée (toujours 0 àlors qu'elle a une autre
valeur en réalité).

Donc, oui, je suis d'accord pour le IN/OUT, et c'est ce qui est fait
dans le second appel. Mais ca ne résoud pas mon problème,
malheureusement.
Avatar
vbadier
J'ai réduit mon code à l'ECM suivant. J'ai mis en place à la main la
valeur de type DWORD dans la bdr sous HKEY_LOCAL_MACHINE. Le type connu
et initialisé, la mémoire pour recevoir la valeur également.

Mais j'ai toujours le problème. Il ne me retourne pas la bonne valeur
(qui devrait être 1).

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

/* Result returned :
* Len : 4
* Value : 4142928
*/
int main(int argc, char *argv[])
{
DWORD len = sizeof(DWORD);
DWORD type = REG_DWORD;
BYTE * data = NULL;

data = malloc(sizeof(DWORD));
if (data==NULL)
return (-2);

memset(data, 0, len);

if (RegQueryValueEx(HKEY_LOCAL_MACHINE, "Uses", NULL, &type, data,
&len) == ERROR_SUCCESS)
printf("Len : %inValue : %in", len, data);
else
printf("Failedn");
}
Avatar
Christian ASTOR
a écrit :

J'ai réduit mon code à l'ECM suivant. J'ai mis en place à la main la
valeur de type DWORD dans la bdr sous HKEY_LOCAL_MACHINE. Le type connu
et initialisé, la mémoire pour recevoir la valeur également.

Mais j'ai toujours le problème. Il ne me retourne pas la bonne valeur
(qui devrait être 1).



Si tu récupères l'adresse, forcément...

DWORD dwType;
DWORD dwData;
DWORD nSize = sizeof(dwData);
DWORD dwResult = RegQueryValueEx(HKEY_LOCAL_MACHINE, "Uses", NULL,
&dwType, (LPBYTE)&dwData, &nSize);
if (ERROR_SUCCESS == dwResult)
printf("Len : %dnValue : %lun", nSize, dwData);
else
printf("Failedn");
Avatar
vbadier
Mais quelle truffe!!!

Effectivement, comment passer pour un idiot en 4 posts ... ;)

Merci d'avoir mis le doigt dessus.