看看AxMan的源代码是怎么获取COM组件的信息的
主要看AxMan枚举所有ActiveX的属性的地方。
是个坑,但是偶尔也会填填。
1、如何确定机器上有哪些ActiveX已经装上了?
很明智的做法:
RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Classes\\CLSID"), 0, KEY_READ, &hKey);
RegQueryInfoKey(
hKey, // key handle
NULL, // buffer for class name
NULL, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
NULL, // longest subkey size
NULL, // longest class string
NULL, // number of values for this key
NULL, // longest value name
NULL, // longest value data
NULL, // security descriptor
NULL // last write time
);
for (j = 0; j<cSubKeys; j++)
{
cbName=MAX_PATH;
achKey[0] = '\0';
RegEnumKeyEx(hKey, j,
achKey,
&cbName,
NULL,
NULL,
NULL,
&ftime);
_ftprintf(output, _T("\t'%s'%s\n"), achKey, j == (cSubKeys-1) ? _T("") : _T(","));
fflush(output);
scan_clsid(achKey);
}
针对找到的每个CLSID主键都调用一次“自己 GO {CLSID}”,很明智的递归方式,因为我发现在枚举的时候它就崩了无数次了。搁在一个进程里面估计这程序就完了。
2、看看GO CLSID的时候它做了啥:
(a)先设置一个异常处理程序,以便出错的时候做报告。 虽然我一次都没见它报告过。
(b)调用CLSIDFromString将传来的CLSID转为CLSID类型,简单来说就是转成这样:
typedef struct {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
byte Data4[ 8 ];
} GUID;
(c)读取HKLM\SOFTWARE\CLASSES\CLSID{SOME-CLSID}\的默认值,通常它像是:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000000-12C9-4305-82F9-43058F20E8D2}
(默认) QQDownload IE Left Helper REG_SZ
是的,这里有描述。
(d)再读HKLM\SOFTWARE\CLASSES\CLSID{SOME-CLSID}\ProgId的默认值,通常它的值像是:
还是上面的例子,
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000000-12C9-4305-82F9-43058F20E8D2}\ProgID
(默认) QQIEHelper.QQCycloneHelper.1 REG_SZ
对,就是ProgId,字面意思。
(e)再读HKLM\SOFTWARE\CLASSES\CLSID{SOME-CLSID}\InProc32的默认值,通常它就是要加载的DLL,至于ThreadingModel,大家不是都默认Both或者Apartment了吗,它也没管。
(f)然后就到了最重要的部分,它怎么枚举属性和方法?
[I] 先CoCreateInstance创建一个实例,查询其IObjectSecurity接口;
[II] 如果实现了这个接口,查询是否设置了Safe for init和Safe for script位,这个是它待会儿要写到测试的配置里面去的;
[III] 调用IDispatch中的GetTypeInfo获取ITypeInfo接口用来展开相关的内容;
The ITypeInfo interface provides access to the following:
The set of function descriptions associated with the type. For interfaces, this contains the set of member functions in the interface.
The set of data member descriptions associated with the type. For structures, this contains the set of members of the type.
The general attributes of the type, such as whether it describes a structure, an interface, and so on.
简单的说就是ITypeInfo接口提供了对这个接口中的成员函数、成员变量、通用属性(是否定义了一个结构体,一个接口等等)。
[IV] 对TypeInfo调用GetDocumentation获取函数数量,然后对各个函数调用GetFuncDesc获取函数描述,然后这里就可以获得函数名,返回值,参数数量和参数。