News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Convert String Version CLSID to GUID

Started by Zen, July 24, 2015, 08:33:35 AM

Previous topic - Next topic

Zen

What I need to do is write a procedure that converts a string version of a CLSID (of the type that you use to open a registry key under: HKEY_CLASSES_ROOT\CLSID) to a real live CLSID that I can use with CoCreateInstance or a Class Moniker.

These strings have this format:
{22D6F312-B0F6-11D0-94AB-0080C74C7E95}    (This one happens to be Windows Media Player)

...So, I've been searching the macros.asm file for cool macros that I can use for this purpose (...\masm32\macros\macros.asm)
And,...well,...I'm embarrassed to admit that I have NEVER written a macro,...and they mystify me,...as I don't really understand the syntax (like QWORD does),...
Anyway,...I've found a number of macros that look promising. If you scroll down to line 4248 (of macros.asm), you will find a section entitled:
sscanf conversion macros. The MSDN documentation is here: sscanf, _sscanf_l, swscanf, _swscanf_l

...But, I wanted to do it the hard way,...'cause I'm trying to prove that I'm NOT a mediocre assembly programmer,...:dazzled:
...So,...I have a couple of simple questions: Where the heck is, crt_sscanf ??? He invokes it in all those macros,...
...And,...is this REALLY a good idea ??? Is there a better way ??? Is sscanf really a good a good approach ???

Can't I just convert the string byte by byte into DWORDs and WORDs and then assemble it into the CLSID structure ???

    GUID STRUCT
        Data1 dd ?
        Data2 dw ?
        Data3 dw ?
        Data4 db 8 dup(?)
    GUID ENDS


...As you all probably know,...A CLSID and a GUID have exactly the same structure, just a different name,...


Zen

...Yeah, I thought of that,...Even better: CLSIDFromString, MSDN

...There's also this, which I found in Japheth's COM stuff:
    DEFINE_GUID macro name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8
exitm <name GUID { l , w1 , w2 , { b1 , b2 , b3 , b4 , b5 , b6 , b7 , b8 } } >
    exitm <externdef name:GUID>
    endm

jj2007

Quote from: Zen on July 24, 2015, 08:43:50 AM
...Yeah, I thought of that,...Even better: CLSIDFromString, MSDN

CLSIDFromString is convenient is the string is generated somewhere. If it is in the .data section, the macro is more efficient: 16 bytes vs about 44.

qWord

UUID macro name,guid
s2uuid_data1 = @CatStr(<0>,@SubStr(<&guid>,2 ,8),<h>)
s2uuid_data2 = @CatStr(<0>,@SubStr(<&guid>,11,4),<h>)
s2uuid_data3 = @CatStr(<0>,@SubStr(<&guid>,16,4),<h>)
s2uuid_bytes TEXTEQU <>
FOR index,<21,23,26,28,30,32,34,36>
s2uuid_bytes TEXTEQU s2uuid_bytes,<,0>,@SubStr(<&guid>,index,2),<h>
ENDM
s2uuid_bytes SUBSTR s2uuid_bytes,2
name GUID <s2uuid_data1,s2uuid_data2,s2uuid_data3,<s2uuid_bytes>>
endm

align 16
UUID IID_IFoo,"22D6F312-B0F6-11D0-94AB-0080C74C7E95"
UUID IID_IFoo2,{23D6F312-B0F6-11D0-94AB-0080C74C7E95}
MREAL macros - when you need floating point arithmetic while assembling!

Zen

#5
JOCHEN,
Thanks, for the information. I'll have to try both techniques just to see if I actually understand what's happening,... :bgrin:

...And,...QWORD,...Thanks,...it's amazing how little I know about macros. It's embarrassing. But, I studied the UUID macro for quite some time, and, I think I understand it (although I have my doubts). I actually had to look up @CatStr and @SubStr, because I've never used them in code. One question: what is <h> ??? I'm guessing that the h is for hexadecimal,...and, this designates the text string as hex.
From, Programmer's Guide Microsoft MASM: "You can define symbolic integer constants with either of the data assignment directives, EQU or the equal sign (=). These directives assign values to symbols during assembly, not during program execution. Symbolic constants are used to assign names to constant values."
...Heck,...I didn't even know that,...:dazzled:
...I also had to read up on: FOR Loops and Variable-Length Parameters to understand the FOR directive (never used that one, either),...

...So,...I learned alot just from that macro example,...Thanks, again,...I appreciate it,...

Zen

Well, I couldn't get CLSIDFromString or QWORD's macro to work.
In the case of CLSIDFromString, I couldn't get the correct string format in the first place.  The documentation states: "Converts a string generated by the StringFromCLSID function back into the original CLSID." I tried various different CLSID string formats, and kept getting a return value of: CO_E_CLASSSTRING (The class string was improperly formatted.)

In the case of QWORD's macro, I'm sure I was calling it incorrectly (the UUID macro compiles without error). My initial impression was to use pointers, but I didn't. And, I had no idea where the converted CLSID was supposed to end up, so I just zeroed a GUID structure. My code was like this:
      invoke RtlZeroMemory, ADDR COMClassClsid, SIZEOF CLSID    ;       
[Line 79]      UUID EnteredCLSID, COMClassClsid

Just to make sure, I also called it like this:
      invoke RtlZeroMemory, ADDR COMClassClsid, SIZEOF CLSID    ;       
[Line 79]      UUID COMClassClsid, EnteredCLSID


...Where COMClassClsid was a CLSID structure (CLSID EQU <GUID>)
    GUID STRUCT
        Data1 dd ?
        Data2 dw ?
        Data3 dw ?
        Data4 db 8 dup(?)
    GUID ENDS

...And,...EnteredCLSID is a character buffer with the string version of the CLSID in it (same format as in the first post).
{22D6F312-B0F6-11D0-94AB-0080C74C7E95}

I kept getting the same error when I tried to compile,...

***********
ASCII build
***********

F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2093: count value too l
arge
@SubStr(1): Macro Called From
  @CatStr(1): Macro Called From
   UUID(2): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  @CatStr(1): Macro Called From
   UUID(3): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  MacroLoop(1): iteration 1: Macro Called From
   UUID(7): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  MacroLoop(1): iteration 2: Macro Called From
   UUID(7): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  MacroLoop(1): iteration 3: Macro Called From
   UUID(7): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  MacroLoop(1): iteration 4: Macro Called From
   UUID(7): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  MacroLoop(1): iteration 5: Macro Called From
   UUID(7): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  MacroLoop(1): iteration 6: Macro Called From
   UUID(7): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  MacroLoop(1): iteration 7: Macro Called From
   UUID(7): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
@SubStr(1): Macro Called From
  MacroLoop(1): iteration 8: Macro Called From
   UUID(7): Macro Called From
    F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2091: index value past
end of string
UUID(8): Macro Called From
  F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
F:\Test COM Class Decoder\COMClasRoutns.inc(79) : error A2206: missing operator
in expression
UUID(1): Macro Called From
  F:\Test COM Class Decoder\COMClasRoutns.inc(79): Include File
_
Assembly Error


COMClasRoutns.inc is the include file in which I call QWORD's UUID macro.

qWord

Zen, that was a misunderstanding from my side: the macro does only work with constants at assembly time.
The function CLSIDFromString does expect an Unicode string.
MREAL macros - when you need floating point arithmetic while assembling!

Zen

#8
...Ooohhh,...
Well, that's helpful,...anyway,...Thanks,...
I'll play around with it. Convert it to a procedure, maybe. I think I got the general idea of how it was supposed to work,...
(I don't know what I was thinking,...a macro expands at assembly time, doesn't it ???...I have SO much to learn)

UPDATE: Using MultiByteToWideChar I converted the string version CLSID to a real UNICODE string CLSID (and then, to an actual CLSID by calling CLSIDFromString).
And, this returned NOERROR. It works,...and, is almost foolproof.
...Cool, thanks, dudes, for the info,...
Now, I can call CreateClassMoniker (I've converted the IMoniker struct from one of Japheth's old files). That also works.
Progress,...:icon_eek:

...Oh,...and thanks, JOCHEN,...I'll study it,...