views:

90

answers:

2

I am trying to remotely read a binary (REG_BINARY) registry value, but I get nothing but junk back. Any ideas what is wrong with this code? I'm using Delphi 2010:

function GetBinaryRegistryData(ARootKey: HKEY; AKey, AValue, sMachine: string; var sResult: string): boolean;
    var
      MyReg: TRegistry;
      RegDataType: TRegDataType;
      DataSize, Len: integer;
      sBinData: string;
      bResult: Boolean;
    begin
      bResult := False;
      MyReg := TRegistry.Create(KEY_QUERY_VALUE);

      try
        MyReg.RootKey := ARootKey;
        if MyReg.RegistryConnect('\\' + sMachine) then
        begin
          if MyReg.KeyExists(AKey) then
          begin
            if MyReg.OpenKeyReadOnly(AKey) then
            begin
              try
                RegDataType := MyReg.GetDataType(AValue);
                if RegDataType = rdBinary then
                begin
                  DataSize := MyReg.GetDataSize(AValue);
                  if DataSize > 0 then
                  begin
                    SetLength(sBinData, DataSize);
                    Len := MyReg.ReadBinaryData(AValue, PChar(sBinData)^, DataSize);
                    if Len <> DataSize then
                      raise Exception.Create(SysErrorMessage(ERROR_CANTREAD))
                    else
                    begin
                      sResult := sBinData;
                      bResult := True;
                    end;
                  end;
                end;
              except
                MyReg.CloseKey;
              end;
              MyReg.CloseKey;
            end;
          end;
        end;
      finally
        MyReg.Free;
      end;

      Result := bResult;
    end;

And I call it like this:

GetBinaryRegistryData(
   HKEY_LOCAL_MACHINE, 
   '\SOFTWARE\Microsoft\Windows NT\CurrentVersion', 
   'DigitalProductId', '192.168.100.105', 
   sProductId
);

WriteLn(sProductId);

The result I receive from the WriteLn on the console is:

ñ ♥ ???????????6Z ????1   ???????☺  ???♦            ??3   ? ??? ?
??
+5  A: 

You're using Delphi 2010, so all your characters are two bytes wide. When you set the length of your result string, you're allocating twice the amount of space you need. Then you call ReadBinaryData, and it fills half your buffer. There are two bytes of data in each character. Look at each byte separately, and you'll probably find that your data looks less garbage-like.

Don't use strings for storing arbitrary data. Use strings for storing text. To store arbitrary blobs of data, use TBytes, which is an array of bytes.

Rob Kennedy
Excellent point.
Mick
+5  A: 

Assuming that you are already connected remotely, try using the GetDataAsString function to read binary data from the registry.

sResult := MyReg.GetDataAsString(AValue);
RRUZ
That will return a hex-formatted string. If the user needs the actual binary data, he/she would have to decode the string back to its original binary.
Remy Lebeau - TeamB