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 (https://msdn.microsoft.com/en-us/library/zkx076cy.aspx)
...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,...
GuidFromString (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1136)
...Yeah, I thought of that,...Even better: CLSIDFromString, MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/ms680589(v=vs.85).aspx)
...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
Quote from: Zen on July 24, 2015, 08:43:50 AM
...Yeah, I thought of that,...Even better: CLSIDFromString, MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/ms680589(v=vs.85).aspx)
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.
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}
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,...
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.
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.
...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,...