2012-08-13 4 views
2

J'utilise ce code pour lire les données binaires du registre à une chaîneLire REG_BINARY à cordes

function ReadBinary (RootKey: HKEY; SubKey,ValueName: WideString; var Data : String): Bool; 
var 
    Key  : HKey; 
    Buffer : array of char; 
    Size : Cardinal; 
    RegType : DWORD; 
begin 
    result := FALSE; 
    RegType := REG_BINARY; 
    if RegOpenKeyExW(RootKey, pwidechar(SubKey), 0, KEY_READ, Key) = ERROR_SUCCESS then begin 
    if RegQueryValueExW(Key,pwidechar(ValueName),NIL,@RegType, NIL,@Size) = ERROR_SUCCESS then begin 
     SetLength (Buffer, Size + 1); 
     FillChar(Buffer, SizeOf (Buffer), #0); 
     if RegQueryValueExW(Key,pwidechar(ValueName),NIL,@RegType, @Buffer[0],@Size) = ERROR_SUCCESS then begin 
     result := TRUE; 
     Data := String (Buffer); // Shows empty or sometimes 1 random char. 
     end; 
    end;   
    end; 
    RegCloseKey (Key); 
end; 

EDIT2:

Il fonctionne très bien avec un tableau déclaré fixe de l'octet/char

function ReadBinary (RootKey: HKEY; SubKey,ValueName: WideString; var Data : String): Bool; 
var 
    Key  : HKey; 
    Buffer : array [0..200] of char; 
    Size : Cardinal; 
    RegType : DWORD; 
begin 
    result := FALSE; 
    RegType := REG_BINARY; 
    if RegOpenKeyExW(RootKey, pwidechar(SubKey), 0, KEY_READ, Key) = ERROR_SUCCESS then begin 
    if RegQueryValueExW(Key,pwidechar(ValueName),NIL,@RegType, NIL,@Size) = ERROR_SUCCESS then begin 
     FillChar(Buffer, SizeOf (Buffer), #0); 
     if RegQueryValueExW(Key,pwidechar(ValueName),NIL,@RegType, @Buffer,@Size) = ERROR_SUCCESS then begin 
     result := TRUE; 
     Data := String (Buffer); 
     end; 
    end;   
    end; 
    RegCloseKey (Key); 
end; 

Je suis coincé. Qu'est-ce que je fais de mal et quelle est la solution?

Nous vous remercions de votre aide.

EDIT:

Je suis conscient que je suis en train de lire des données binaires à partir du Registre. Il peut donc déjà être terminé et peut renvoyer des résultats erronés. Je peux garantir qu'il n'y a pas de caractères # 0 dans les données binaires parce que j'ai écrit un texte long (Chaîne avec CR/LF) dans la valeur avant.

+2

Si vous définissez un point d'arrêt de débogage sur l'affectation 'Data: = String (Buffer)' et examinez Buffer', que contient-il réellement? –

+0

semble que je ne peux même pas y accéder. Mais je pense que c'est # 0. Je reçois beaucoup de violations d'accès si j'essaie quelque chose comme ceci: si buffer [0] = '' then messagebox (0, 'ERROR', '', 0); –

+0

EDIT: Je reçois 000000 messagebox (0, pchar (Format ('% 8p', [@buffer [0]])), '', 0); –

Répondre

6
Buffer: array of char; 

est un tableau dynamique de caractères, c'est-à-dire, une variable de pointeur. Et cette chaîne remet à zéro le pointeur sur Nil:

FillChar(Buffer, SizeOf (Buffer), #0); 

donc tableau dynamique n'est pas valide maintenant.

Pour remplir le contenu du tableau dynamique par des zéros, vous devez utiliser

FillChar(Buffer[0], SizeOf(Buffer[0]) * Length(Buffer), #0) 

mais ce n'est pas nécessaire, car SetLength rend le travail.

+0

génial. C'était ça! Merci beaucoup. Bien sûr, je ne voulais pas NIL l'adresse du tableau. –

0
  1. Le tableau dynamique est un pointeur de type somethign. En C/C++ ce serait exactement pareil. En Delphi ce n'est pas le cas, mais vous pouvez penser de cette façon pour la sémantique. @Buffer n'est pas l'adresse de la 1ère voiture, mais l'adresse du pointeur lui-même. Ib les appels à FillChar et RegQueryValueExW vous devez passer tampon [0] et @Buffer [0] à la place
  2. Pourquoi utilisez-u API Windows au lieu de TRegistry norme? Ou peut-être que TNT Unicode Controls ou quelque chose de similaire ont un accès au registre readymade compatible avec unicode.
  3. Win API xxxxxxxW Les fonctions sont compatibles Unicode. Avez-vous vérifié les données que vous avez? Est-ce que c'est 8 ou 16 bits? Regardez les données reçues sous forme de tableau d'octets dans HEX - contiennent-elles des octets de $ 00 ou pas? On dirait qu'ils le font et vous avez des données Unicode dans le tampon. Ensuite, il serait attendu et le comportement correct de la chaîne n'accepte que 1 lettre (ou 0, selon l'ordre des octets intel ou motorola). Vérifiez les données binaires que vous avez dans Buffer.
  4. Personnellement, j'avais fait de Buffer un tableau d'octets. Ensuite, après l'accès au registre, j'utilisais la procédure SetString pour obtenir de la valeur si D7 l'avait. Si non, alors je le copierais comme SetLength (Data, Size); Move (Tampon [0], Données [1], Taille); Et je supprimer complètement FillChar. De cette façon, la copie serait à la fois légèrement plus rapide et ne casserait pas le premier octet # 0 parasite.
  5. Je n'utiliserais pas de types de caractères et de chaînes de caractères ambigus lorsque j'utiliserais le codage de données binaires de bas niveau, mais utiliserais plutôt des types AnsiString et AnsiChar concrets. Si votre code serait compilé par Delphi ou FreePascal, plus récent, compatible Unicode, cela le ferait fonctionner. Raccourcis "char" et "chaîne" peuvent changer leur signification en fonction de la version du compilateur. Et puis vous auriez du mal à déterminer pourquoi et où il s'est cassé et quoi faire.
+0

-1. Bien que la plupart de ces informations soient de bonne qualité, elles ne répondent pas à la question posée ici. –

+1

@KenWhite: il a quelques points valables ici (il prend encore trop de médicaments à mon humble avis) ... – whosrdaddy

+1

@whosrdaddy, et je l'ai dit. Il reste cependant à dire qu'il n'y a pas une seule chose qui permette d'apporter une solution à cette question. (L'utilisation impropre de 'FillChar' qui a fait' buffer' nil n'est pas du tout mentionnée.) –