ComQIPtrAssign PROC

pp:DWORD,// reference of variable to receive a pointer

lp:DWORD// reference to existing COM pointer

riid:DWORD// reference to existing COM pointer

Parameters

pp

reference of variable to receive a pointer.

lp

reference to existing COM pointer. Must be valid.

riid

reference to an interface identifier

Return Value

None.

See Also

 

 


APPENDIX G INITIALIZING LARGE DATA STRUCTURES IN MASM

 

When working with large structures in MASM, you will run up against a very hard limit: the character count of any given line may not exceed. Logical lines cannot exceed a total of 512 characters.

 

Period.

 

Dang.

 

So, what are you to do when like myself, you wish to implement a vtable consisting of 10 interfaces with 82 function pointers? That is 82 DWORDs alone, and as the string

"DWORD " is 7 characters long, 82 * 7 = 574, so we can't even fit all the type casts inside that structure. What to do?

 

Easy, you cheat. Finagle. Lie boldface to the compiler.

 

CoLib structures are arrays of other structures. Small items grouped together to make larger structures. Usually, you can break a large structure into small pieces, and put the pieces into the full structure. That lets you define the structure. Now to initialize an instance of the structure.... cheat!

 

Structures define how an area of memory is arranged. It is really a compiler directive, not runtime code. So... just make the instance initialization a series of WORDS, BYTES, and DWORDS as you need to duplicate the big structure. Put one nice big label at the top of this data structure.

 

Say you call the "real" structure "sCOLLUSUS," and this data structure "COLLUSUS." Then you may access its members with:

 

mov eax, sCOLLUSUS PTR COLLUSUS.MemberDataItem

 

Yeah, I know, not very clean. But it does work.

 


APPENDIX H Creating Registrar Scripts

A registrar script provides data-driven, rather than API-driven, access to the system registry. Data-driven access is typically more efficient since it takes only one or two lines in a script to add a key to the registry.

 

You will need to generate a registrar script for your COM server. You then make this .rgs script a resource to your project.

 

The CoLib DllRegisterServerandDllUnregisterServerexports processes your registrar script at run time.

 

Registrar scripts use the following string literals. Script symbols are case sensitive, The following table describes the string literals used in an ATL Registrar script.

 

String Literal Description  
ForceRemove   Completely remove the following key (if it exists) and then recreate it.  
NoRemove   Do not remove the following key during Unregister.  
val   The following <Key Name> is actually a named value.  
Delete   Delete the following key during Register.  
s   The following value is a string.  
d   The following value is a DWORD.  
HKCR   HKEY_CLASSES_ROOT  
HKCU   HKEY_CURRENT_USER  
HKLM   HKEY_LOCAL_MACHINE  
HKCC   HKEY_CURRENT_CONFIG  
HKDD   HKEY_DYN_DATA  
HKU   HKEY_USERS  

 

In a registrar script you define one or more parse trees in your script. A parse tree can add multiple keys and subkeys to the <root key>. In doing so, it keeps a subkeys handle open until the parser has completed parsing all its subkeys. This approach is more efficient than operating on a single key at a time, as seen in the following parse tree example:

 

HKCR

{

'MyVeryOwnKey'

{

'HasASubKey'

{

'PrettyCool?'

}

}

}

 

Here, the Registrar initially opens (creates) HKEY_CLASSES_ROOTMyVeryOwnKey. It then sees that MyVeryOwnKey has a subkey. Rather than close the key to MyVeryOwnKey, the Registrar retains the handle and opens (creates) HasASubKey using this parent handle. (The system registry can be slower when no parent handle is open.) Thus, opening HKEY_CLASSES_ROOTMyVeryOwnKey and then opening HasASubKey with MyVeryOwnKey as the parent is faster than opening MyVeryOwnKey, closing MyVeryOwnKey, and then opening MyVeryOwnKeyHasASubKey.

 

Using %MODULE%

It is very often required that a component register the filenamepath where it is stored. This is accomplished with the %MODULE% parameter. CoLib uses this replaceable parameter for the actual location of your server's DLL or EXE. The following example shows how to use the replacement:

 

'MyGoofyKey' = s '%MODULE%, 1'

 

will be registered as if it was:

 

'MyGoofyKey' = s 'myfoldermydll.dll, 1'

 

Where "myfolder" is the filepath of the dll, and "mydll.dll" is the file name.

 

 


APPENDIX H KNOWN ISSUES

 

· Plans exist to include support for objects that aggregate other objects, though currently this is unsupported.

 

· Plans exist to include support for the ISupportErrorInfo interface is still in process.

 

· The self-registration methods fail catastrophically in NT

 


 

APPENDIX I The complete CoLib object map  
This map of all the CoLib objects and their interconnections was saved for last, as not to scare away the faint of heart. However, since a picture is still worth about a buck fifty, I felt forced to include it.