HRESULT typeLibForInterface(REFIID iid, ITypeLib** typeLib ) { if ( !typeLib ) return E_POINTER; *typeLib = 0; mol::RegKey root(HKEY_CLASSES_ROOT); mol::RegKey interfaces = root.open(_T("Interface"),KEY_READ); std::wstring siid = stringFromCLSID(iid); mol::RegKey iface = interfaces.open(siid,KEY_READ); if ( iface ) { mol::RegKey lib = iface.open(_T("TypeLib"),KEY_READ); if ( lib ) { std::wstring guid = lib.get(); std::wstring version = _T("1.0"); try { version = lib.get(_T("Version")); } catch(...) {} size_t pos = version.find(_T(".")); if ( pos == std::wstring::npos ) return E_FAIL; #ifdef _UNICODE int major = _wtoi( version.substr(0,pos).c_str() ); int minor = _wtoi( version.substr(pos+1).c_str() ); #else int major = atoi( version.substr(0,pos).c_str() ); int minor = atoi( version.substr(pos+1).c_str() ); #endif CLSID clsid; if ( S_OK == CLSIDFromString( (LPOLESTR)(mol::towstring(guid).c_str()),&clsid) ) { TypeLib tl; tl.load(clsid,major,minor); return tl.queryInterface(typeLib); } } } return S_OK; }
static void cleanup(void) { HKEY rootKey; HKEY hKey; HKEY hKey2; TCHAR buffer[39]; stringFromCLSID(&buffer[0], (REFCLSID)(&CLSID_IExample3)); // Open "HKEY_LOCAL_MACHINE\Software\Classes" if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, &ClassKeyName[0], 0, KEY_WRITE, &rootKey)) { // Delete ProgID subkey and everything under it if (!RegOpenKeyEx(rootKey, &OurProgID[0], 0, KEY_ALL_ACCESS, &hKey)) { RegDeleteKey(hKey, &CLSID_Str[0]); RegCloseKey(hKey); RegDeleteKey(rootKey, &OurProgID[0]); // Delete our CLSID key and everything under it if (!RegOpenKeyEx(rootKey, &CLSID_Str[0], 0, KEY_ALL_ACCESS, &hKey)) { if (!RegOpenKeyEx(hKey, &buffer[0], 0, KEY_ALL_ACCESS, &hKey2)) { RegDeleteKey(hKey2, &InprocServer32Name[0]); RegDeleteKey(hKey2, &ProgIDName[0]); RegCloseKey(hKey2); RegDeleteKey(hKey, &buffer[0]); } RegCloseKey(hKey); } } RegCloseKey(rootKey); // Unregister type library UnRegisterTypeLib(&CLSID_TypeLib, 1, 0, LOCALE_NEUTRAL, SYS_WIN32); } }
int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow) { int result; TCHAR filename[MAX_PATH]; { OPENFILENAME ofn; // Pick out where our DLL is located. We need to know its location in // order to register it as a COM component lstrcpy(&filename[0], &OurDllName[0]); ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrFilter = &FileDlgExt[0]; ofn.lpstrFile = &filename[0]; ofn.nMaxFile = MAX_PATH; ofn.lpstrTitle = &FileDlgTitle[0]; ofn.Flags = OFN_FILEMUSTEXIST|OFN_EXPLORER|OFN_PATHMUSTEXIST; result = GetOpenFileName(&ofn); } if (result > 0) { HKEY rootKey; HKEY hKey; HKEY hKey2; HKEY hkExtra; TCHAR buffer[39]; DWORD disposition; // Assume an error result = 1; // Open "HKEY_LOCAL_MACHINE\Software\Classes" if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, &ClassKeyName[0], 0, KEY_WRITE, &rootKey)) { // For a script engine to call the OLE function CLSIDFromProgID() (passing // our registered ProgID in order to get our IExample2 object's GUID), then // we need to create a subkey named with our IExample2 ProgID string. We've // decided to use the ProgID "IExample2.object" if (!RegCreateKeyEx(rootKey, &OurProgID[0], 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey, &disposition)) { // Set its default value to some "friendly" string that helps // a user identify what this COM DLL is for. Setting this value // is optional. You don't need to do it RegSetValueEx(hKey, 0, 0, REG_SZ, (const BYTE *)&ObjectDescription[0], sizeof(ObjectDescription)); // Create a "CLSID" subkey whose default value is our IExample2 object's GUID (in ascii string format) if (!(disposition = RegCreateKeyEx(hKey, &CLSID_Str[0], 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey2, &disposition))) { stringFromCLSID(&buffer[0], (REFCLSID)(&CLSID_IExample3)); disposition = RegSetValueEx(hKey2, 0, 0, REG_SZ, (const BYTE *)&buffer[0], lstrlen(&buffer[0]) + 1); RegCloseKey(hKey2); } RegCloseKey(hKey); if (!disposition) { // Open "HKEY_LOCAL_MACHINE\Software\Classes\CLSID" if (!RegOpenKeyEx(rootKey, &CLSID_Str[0], 0, KEY_ALL_ACCESS, &hKey)) { // Create a subkey whose name is the ascii string that represents // our IExample2 object's GUID if (!RegCreateKeyEx(hKey, &buffer[0], 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey2, &disposition)) { // Set its default value to some "friendly" string that helps // a user identify what this COM DLL is for. Setting this value // is optional. You don't need to do it RegSetValueEx(hKey2, 0, 0, REG_SZ, (const BYTE *)&ObjectDescription[0], sizeof(ObjectDescription)); // Create an "InprocServer32" key whose default value is the path of this DLL if (!RegCreateKeyEx(hKey2, &InprocServer32Name[0], 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hkExtra, &disposition)) { disposition = 1; if (!RegSetValueEx(hkExtra, 0, 0, REG_SZ, (const BYTE *)&filename[0], lstrlen(&filename[0]) + 1)) { // Create a "ThreadingModel" value set to the string "both" (ie, we don't need to restrict an // application to calling this DLL's functions only from a single thread. We don't use global // data in our IExample2 functions, so we're thread-safe) disposition = RegSetValueEx(hkExtra, &ThreadingModel[0], 0, REG_SZ, (const BYTE *)&BothStr[0], sizeof(BothStr)); } RegCloseKey(hkExtra); // Create a "ProgID" subkey whose default value is our ProgID. This allows the app to call ProgIDFromCLSID() if (!disposition && !(disposition = RegCreateKeyEx(hKey2, &ProgIDName[0], 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hkExtra, &disposition))) { disposition = RegSetValueEx(hkExtra, 0, 0, REG_SZ, (const BYTE *)&OurProgID[0], sizeof(OurProgID)); RegCloseKey(hkExtra); if (!disposition) result = 0; } } RegCloseKey(hKey2); } RegCloseKey(hKey); } // Register the type lib (which is assumed to be a .TLB file in the same dir as this DLL) if (!result) { ITypeLib *pTypeLib; LPTSTR str; str = &filename[0] + lstrlen(&filename[0]); while (str > &filename[0] && *(str - 1) != '\\') --str; lstrcpy(str, &TypeLibName[0]); #ifdef UNICODE if (!(result = LoadTypeLib(&filename[0], &pTypeLib))) { result = RegisterTypeLib(pTypeLib, &filename[0], 0); pTypeLib->lpVtbl->Release(pTypeLib); } #else { wchar_t wbuffer[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, &filename[0], -1, &wbuffer[0], MAX_PATH); if (!(result = LoadTypeLib(&wbuffer[0], &pTypeLib))) { result = RegisterTypeLib(pTypeLib, &wbuffer[0], 0); pTypeLib->lpVtbl->Release(pTypeLib); } } #endif } if (!result) MessageBox(0, "Successfully registered IExample3.DLL as a COM component.", &ObjectDescription[0], MB_OK); } } RegCloseKey(rootKey); } // If an error, make sure we clean everything up if (result) { cleanup(); MessageBox(0, "Failed to register IExample3.DLL as a COM component.", &ObjectDescription[0], MB_OK|MB_ICONEXCLAMATION); } } return(0); }
int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow) { int result; TCHAR filename[MAX_PATH]; { OPENFILENAME ofn; // Pick out where our DLL is located. We need to know its location in // order to register it as a COM component lstrcpy(&filename[0], &OurDllName[0]); ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrFilter = &FileDlgExt[0]; ofn.lpstrFile = &filename[0]; ofn.nMaxFile = MAX_PATH; ofn.lpstrTitle = &FileDlgTitle[0]; ofn.Flags = OFN_FILEMUSTEXIST|OFN_EXPLORER|OFN_PATHMUSTEXIST; result = GetOpenFileName(&ofn); } if (result > 0) { HKEY rootKey; HKEY hKey; HKEY hKey2; TCHAR buffer[39]; stringFromCLSID(&buffer[0], (REFCLSID)(&CLSID_IExample2)); // Open "HKEY_LOCAL_MACHINE\Software\Classes" if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, &ClassKeyName[0], 0, KEY_WRITE, &rootKey)) { // Delete ProgID subkey and everything under it if (!RegOpenKeyEx(rootKey, &OurProgID[0], 0, KEY_ALL_ACCESS, &hKey)) { RegDeleteKey(hKey, &CLSID_Str[0]); RegCloseKey(hKey); RegDeleteKey(rootKey, &OurProgID[0]); // Delete our CLSID key and everything under it if (!RegOpenKeyEx(rootKey, &CLSID_Str[0], 0, KEY_ALL_ACCESS, &hKey)) { if (!RegOpenKeyEx(hKey, &buffer[0], 0, KEY_ALL_ACCESS, &hKey2)) { RegDeleteKey(hKey2, &InprocServer32Name[0]); RegDeleteKey(hKey2, &ProgIDName[0]); RegCloseKey(hKey2); RegDeleteKey(hKey, &buffer[0]); } RegCloseKey(hKey); } } RegCloseKey(rootKey); // Unregister type library UnRegisterTypeLib(&CLSID_TypeLib, 1, 0, LOCALE_NEUTRAL, SYS_WIN32); } MessageBox(0, "De-registered IExample2.DLL as a COM component.", &ObjectDescription[0], MB_OK|MB_ICONEXCLAMATION); } return(0); }