We were discussing GUIDs in another thread (https://masm32.com/board/index.php?topic=12071.0). I took a look at the little Microsoft utility to get GUIDs, GUIDGEN.EXE. After figuring out how to get a GUID (easy peasy, just call UuidCreate()), I thought it might be nice to have a utility like that more useful to us assembly-language programmers.
Here it is, attached to this post. It displays the GUID in three forms: as the standard XXXXXXXX-XXXX-XXXX ... form, as a set of DB statements, and as a GUID structure declaration.
It works fine. However, before anyone starts using this, I wonder if someone could check my work here. Specifically, I'm really not sure about byte (and nybble) order. The top display field shows the data returned in the GUID structure as a sequence of bytes, left to right. What I'm not sure about is the values in the GUID structure (last field). Are those values correct? They're both byte- and nybble-swapped. (Dontcha just love little-endianness?)
So where the first part (4 bytes, 8 hex characters) is FCFFD8CD, the DWORD value in the structure is 0DC8DFFCFh. Izzat correct?
(https://i.postimg.cc/CZbgHxhT/GUID4ASM.jpg) (https://postimg.cc/CZbgHxhT)
Just use UuidToString to see how the bytes are formatted.
edit: The program works OK
Also a string for register would be useful, as it might be needed for later usage.
Quote from: TimoVJL on June 30, 2024, 06:22:38 PMAlso a string for register would be useful, as it might be needed for later usage.
You mean for the registry? I thought that was the
XXXXXXXX-XXXX-XXXX ... form. What format exactly is it?
Quote from: sinsi on June 30, 2024, 05:25:17 PMedit: The program works OK
Welllll ... there was a pretty basic error in there (I left out a character from my hex conversion table). Fixed that, but I'm still very confused. Check out screen shot:
(https://i.postimg.cc/G8X525Y4/GUID4-ASM-2.jpg) (https://postimg.cc/G8X525Y4)
The output from
UuidToString() is shown in the status bar at bottom, so we can assume that's correct, right? So what's the correct byte order for things? I guess my GUID string (1st one at top) should match that one, right? Which means they're using the binary order (little-endian), not the byte order. Aaaaargh.
Quote from: NoCforMe on June 30, 2024, 07:03:37 PMThe output from UuidToString() is shown in the status bar at bottom
Not here.
Sorry, a later revision. See screenshot. Well, might as well attach it here.
Here's what I get
e4 4c 54 8a 70 77 18 4d-83 70 0a e4 8a 29 78 52
8a544ce4-7770-4d18-8370-0ae48a297852
Typical MS, the format doesn't match the structure layout.
So it looks like my mistake was reversing nybbles within each byte.
In your example, it looks like it does match the structure. First 4 bytes:
e4 4c 54 8a
which makes a DWORD (Data1) of
8a544ce4
Right?
GUID STRUCT
Data1 DWORD ?
Data2 WORD ?
Data3 WORD ?
Data4 BYTE 8 DUP (?)
GUID ENDS
Doesn't match the grouping
Data1 dd 8a544ce4h
Data2 dw 7770h
Data3 dw 4d18h
Data? db 83h,70h
Data? db 0ah,0e4h,8ah,29h,78h,52h
[/code]
Wonder if there's a good (and accurate) description of the actual layout somewhere online?
(Besides the Micro$oft docs!)
Quote from: NoCforMe on June 30, 2024, 08:26:47 PMWonder if there's a good (and accurate) description of the actual layout somewhere online?
Sinsi's structure is ok. Windows Learn: https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid
Yes, we know the structure is correct. But what about the byte order of the data? That's the issue here.
If you look at the layout, it's xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 8-4-4-4-12 digits
but the structure is 8-4-4-16, and the last 8 bytes (4-12 16 digits) are split but in a weird way.
How about this: let's take a completely empirical approach:
- Use UuidCreate() to get a GUID
- Look at the data in the GUID structure, byte by byte
- Use UuidToString() to create the string
- Compare the data layout to the byte order in the string
That should show us the correct order of things.
Quote from: NoCforMe on June 30, 2024, 08:58:42 PMHow about this: let's take a completely empirical approach:
- Use UuidCreate() to get a GUID
- Look at the data in the GUID structure, byte by byte
- Use UuidToString() to create the string
- Compare the data layout to the byte order in the string
That should show us the correct order of things.
Already did that.
e4 4c 54 8a 70 77 18 4d-83 70 0a e4 8a 29 78 52
8a544ce4-7770-4d18-8370-0ae48a297852
The top line is the buffer from UuidCreate
The next line is from UuidToString
What is a GUID? (https://guid.one/guid)
A Universally Unique IDentifier (UUID) URN Namespace (https://www.ietf.org/rfc/rfc4122.txt)
Quote from: NoCforMe on June 30, 2024, 06:55:39 PMQuote from: TimoVJL on June 30, 2024, 06:22:38 PMAlso a string for register would be useful, as it might be needed for later usage.
You mean for the registry? I thought that was the XXXXXXXX-XXXX-XXXX ... form. What format exactly is it?
string like "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
So all I need to do is enclose it in {}. Easy peasy.
Quote from: sinsi on June 30, 2024, 09:32:12 PMQuote from: NoCforMe on June 30, 2024, 08:58:42 PMHow about this: let's take a completely empirical approach:
- Use UuidCreate() to get a GUID
- Look at the data in the GUID structure, byte by byte
- Use UuidToString() to create the string
- Compare the data layout to the byte order in the string
That should show us the correct order of things.
Already did that.
e4 4c 54 8a 70 77 18 4d-83 70 0a e4 8a 29 78 52
8a544ce4-7770-4d18-8370-0ae48a297852
The top line is the buffer from UuidCreate
The next line is from UuidToString
This is my guide, then, to fixing my utility so it shows the value properly. Probably be done later today ...
Quote from: NoCforMe on July 01, 2024, 06:38:36 AMSo all I need to do is enclose it in {}. Easy peasy.
Windows API function StringFromGUID2() make it in UNICODE form for reference.
Quote from: TimoVJL on July 01, 2024, 07:47:29 AMQuote from: NoCforMe on July 01, 2024, 06:38:36 AMSo all I need to do is enclose it in {}. Easy peasy.
Windows API function StringFromGUID2() make it in UNICODE form for reference.
Unicode, schmunicode; all that's needed are plain ASCII characters here.
OK, new version attached. It puts the GUID in the same format (byte-order wise) as
UuidToString(), as shown in the status bar).
Timo, I added "
{}" to the GUID string shown at the top: happy? It ain't Unicode, but you can certainly copy and paste into anything.
So it turns out that the GUID format is:
- First 4 bytes (8 hex chars.) in DWORD order (little-endian)
- Next 2 sets of 2 bytes each (4 hex chars.) in WORD order
- Next set of 2 bytes in non-byte-swapped order (?????)
- Last set of 6 bytes (12 hex chars.) in non-byte-swapped order
Weird.
Last question: I'm using uppercase hex characters here, but
UuidToString() renders them in lowercase. Probly doesn't matter, but I could put in an option for case here; anyone think that would be a good thing?
In windows register GUIDs are mostly uppercase, like CLSIDs, but not necessarily.
Quote from: TimoVJL on July 01, 2024, 08:15:45 AMIn windows register registry GUIDs are mostly uppercase, like CLSIDs, but not necessarily.
New version gives you the choice of uppercase or not.