Read GUID value stored in registry
Asked Answered
S

1

5

I try to read a GUID value stored as a binary value in registry in Delphi. When I read it with BintoHex, but the result is in reverse order. It seems that I have to swap bytes but I thought BinToHex would do it.

I refered to this thread but I can't find the right solution : how to convert byte array to its hex representation in Delphi It seems that it is due to little Eendian.

Below, you can see the GUID stored in registry

Here is my code :

var
s : string;
buffer : pointer;
...

begin
getmem(buffer, 1024*1024);
....
reg.ReadBinaryData(iValueOfregistry, buffer^, 1024*1024);
....
bintohex(pointer(longint(buffer)+14), PChar(s), 32);

Output for s : 90E24D373F126545916439C4925E467B

GUID should be FOLDERID_Downloads GUID :
{374DE290-123F-4565-9164-39C4925E467B}

Please help Here

Silversmith answered 12/2, 2013 at 8:30 Comment(0)
S
8

A GUID in binary form is best thought of as a record. Indeed in Delphi the record already exists – it is TGUID.

All you need to do is to copy the relevant bytes directly into a variable of type TGUID and your job is done. If you want a string representation, use GUIDToString.

var
  GUID: TGUID;
  strGUID: string;
....
GUID := PGUID(PAnsiChar(buffer)+14)^;
strGUID := GUIDToString(GUID);

This will take care of all the endian issues automatically. Let's take a look at the declaration of TGUID:

TGUID = packed record
  D1: LongWord;
  D2: Word;
  D3: Word;
  D4: array[0..7] of Byte;
end;

Your code treats this as a straight array of bytes. However, in the record, D1, D2 and D3 are integral types on a little endian machine. So your code reverses the first 4 bytes, those belonging to D1. It then reverses the two bytes of D2, and also the two bytes of D3. The array of 8 bytes at the end of the GUID are not reversed, of course.

So, whilst you could readily do all the byte swapping yourself, it's far better to use a record to do so, and take advantage of the helper function that converts a binary GUID record to a properly formatted GUID string.

Subauricular answered 12/2, 2013 at 8:46 Comment(2)
The GUID is not the only thing stored in the binary registry value. So, I have to read it in a buffer and read TGUID at position $e in that buffer. I suspect a "move" from buffer (at position $e) to GUID will not do the job because it is a byte-to-byte copy. Is that true? What do you suggest, David?Silversmith
A Move will do the job perfectly. Just blit the data onto a TGUID and the job is done. It can be done without move using a cast to PGUID. The latest update shows you how.Subauricular

© 2022 - 2024 — McMap. All rights reserved.