Search code examples
winapiregistrydelphi-7delphi

Read REG_BINARY to String


I use this code to read binary data from the registry to a string

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:

It works fine with a fixed declared array of byte/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;

I'm stuck. What do I do wrong and what is the solution?

Thank you for your help.

EDIT:

I am aware of that I am reading binary data from the registry. So it might be already 0 terminated and can return false results. I can guarantee that there are no #0 chars in the binary data because I wrote a long text (String with CR/LF) in the Value before.


Solution

  • Buffer: array of char;
    

    is dynamic array of chars, that is, in fact, pointer variable. And this string resets the pointer to Nil:

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

    So dynamic array is not valid now.

    To fill the contents of dynamic array by zeroes, you have to use

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

    but this is not necessary, because SetLength makes the job.