Mi pregunta es similar a Getting CLSID for a DLL file?, creo.Dado un DLL COM, extraer todas las clases CLSID y el nombre de interfaz correspondiente
Tengo un directorio con algunas DLL, cada una implementando una o más interfaces COM. Me gustaría llegar:
1) El nombre de cada interfaz 2) El CLSID de la clase que implementa la interfaz
Para cada DLL. Es importante que todo se pueda hacer programáticamente (así que no puedo usar algún tipo de navegador COM y buscar manualmente esa información).
Más tarde buscaré el CLSID dado el nombre de la interfaz y llamaré algunos métodos usando IDispatch.
Una alternativa parece ser escanear el registro tratando de coincidir con el tipo, interfaz y clase GUID y el nombre de archivo .dll. Pero eso parece ser lento y no robusto.
¿Alguien tiene una solución clara a este problema?
EDIT:
Con la respuesta de Ben Voigt, vine con el siguiente código, que se adapte a mis necesidades:
ITypeLib *typelib;
ITypeInfo *typeinfo;
LoadTypeLibEx(_T("c:\\mydir\\mycom1"), REGKIND_NONE, &typelib);
for (UINT i = 0;i < typelib->GetTypeInfoCount();++i) {
TYPEKIND typekind;
typelib->GetTypeInfoType(i, &typekind);
if (typekind == TKIND_COCLASS) {
// class!
CComBSTR className;
TYPEATTR *typeattr;
typelib->GetTypeInfo(i, &typeinfo);
typeinfo->GetDocumentation(MEMBERID_NIL, &className, NULL, NULL, NULL);
typeinfo->GetTypeAttr(&typeattr);
GUID classGUID = typeattr->guid;
for (UINT j = 0;j < typeattr->cImplTypes;++j) {
// interface!
CComBSTR interfaceName;
HREFTYPE hreftype;
ITypeInfo *classtypeinfo;
typeinfo->GetRefTypeOfImplType(j, &hreftype);
typeinfo->GetRefTypeInfo(hreftype, &classtypeinfo);
classtypeinfo->GetDocumentation(MEMBERID_NIL, &interfaceName, NULL, NULL, NULL);
// associate interfaceName with classGUID here
}
}
}
'DllGetClassObject' podría tener efectos secundarios no deseados, por lo que no se recomienda este. Además, es completamente posible tener una combinación de CLSID públicos y privados. Como la DLL se carga mediante la creación de un tipo público, no hay necesidad de cargar la DLL fuera de los mecanismos COM. –
Bueno, el análisis forense * ultimate * implicaría desmontar el archivo DLL y pasar por el código de DllGetClassObject(). En la implementación típica (léase: el de ATL) habría una estructura de datos global que enumera cuidadosamente todos los CLSID en un solo lugar. Difícilmente puedo imaginarme una DLL COM donde el conjunto de coclasses compatibles es condicional. –
Depende de qué tan furtivo sea el esquema de licencias. Definitivamente puedo imaginar un requisito para instanciar un objeto de administrador de licencia y usarlo antes de que se puedan crear instancias de otras clases, la pregunta es si la falla al intentar crear objetos sin una licencia es "No conozco ese objeto" o "Intenté" para crear ese objeto pero falló " –