/*++ Copyright (C) 1996-2001 Microsoft Corporation Module Name: COMMAIN.CPP Abstract: COM Helpers History: --*/ #include #include #include #include #include #include "commain.h" DWORD MyBreakOnDbgAndRenterLoop(void) { __try { DebugBreak(); } _except (EXCEPTION_EXECUTE_HANDLER) {}; return EXCEPTION_CONTINUE_EXECUTION; } void CreatePathString( TCHAR* pTo, int cTo, WCHAR* pId, TCHAR* pPrefix ) { TCHAR chId[128]; #ifdef UNICODE StringCchCopy( chId, 128, pId ); #else wcstombs( chId, pId, 128 ); #endif StringCchCopy( pTo, cTo, pPrefix ); StringCchCat( pTo, cTo, chId ); } struct CClassInfo { LIST_ENTRY m_Entry; const CLSID* m_pClsid; CUnkInternal* m_pFactory; LPTSTR m_szName; BOOL m_bFreeThreaded; BOOL m_bReallyFree; DWORD m_dwCookie; public: CClassInfo(): m_pClsid(0), m_pFactory(0), m_szName(0), m_bFreeThreaded(0), m_dwCookie(0){} CClassInfo(CLSID* pClsid, LPTSTR szName, BOOL bFreeThreaded, BOOL bReallyFree) : m_pClsid(pClsid), m_pFactory(NULL), m_szName(szName), m_bFreeThreaded(bFreeThreaded), m_bReallyFree( bReallyFree ) {} virtual ~CClassInfo() { delete [] m_szName; m_pFactory->InternalRelease(); } }; LIST_ENTRY g_ClassInfoHead = { &g_ClassInfoHead, &g_ClassInfoHead }; static HMODULE ghModule; void SetModuleHandle(HMODULE hModule) { ghModule = hModule; } HMODULE GetThisModuleHandle() { return ghModule; } HRESULT RegisterServer(CClassInfo* pInfo, BOOL bExe) { WCHAR wchId[128]; TCHAR szPath[256]; TCHAR szModule[MAX_PATH+1]; HKEY hKey1, hKey2; StringFromGUID2( *pInfo->m_pClsid, wchId, 128 ); // Create the path. CreatePathString( szPath, 256, wchId, TEXT("SOFTWARE\\Classes\\CLSID\\")); // Create entries under CLSID RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hKey1); int cLen = lstrlen(pInfo->m_szName)+100; TCHAR* szName = new TCHAR[cLen]; StringCchPrintf( szName, cLen, L"Microsoft WBEM %s", pInfo->m_szName ); RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)szName, (lstrlen(szName)+1) * sizeof(TCHAR)); RegCreateKey(hKey1, bExe?TEXT("LocalServer32"): TEXT("InprocServer32"), &hKey2); szModule[MAX_PATH] = L'0'; GetModuleFileName(ghModule, szModule, MAX_PATH); RegSetValueEx(hKey2, NULL, 0, REG_SZ, (BYTE *)szModule, (lstrlen(szModule)+1) * sizeof(TCHAR)); const TCHAR* szModel; if(pInfo->m_bFreeThreaded) { if ( !pInfo->m_bReallyFree ) { szModel = TEXT("Both"); } else { szModel = TEXT("Free"); } } else { szModel = TEXT("Apartment"); } RegSetValueEx(hKey2, TEXT("ThreadingModel"), 0, REG_SZ, (BYTE *)szModel, (lstrlen(szModel)+1) * sizeof(TCHAR)); RegCloseKey(hKey1); RegCloseKey(hKey2); return NOERROR; } HRESULT UnregisterServer(CClassInfo* pInfo, BOOL bExe) { WCHAR wchId[128]; TCHAR szPath[256]; HKEY hKey; StringFromGUID2( *pInfo->m_pClsid, wchId, 128 ); // Create the path using the CLSID CreatePathString( szPath, 256, wchId, TEXT("SOFTWARE\\Classes\\CLSID\\")); // First delete the InProcServer subkey. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, szPath, &hKey); if(dwRet == NO_ERROR) { RegDeleteKey(hKey, bExe? TEXT("LocalServer32"): TEXT("InProcServer32")); RegCloseKey(hKey); } dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Classes\\CLSID"), &hKey); if(dwRet == NO_ERROR) { RegDeleteKeyW(hKey, wchId); RegCloseKey(hKey); } return NOERROR; } extern CLifeControl* g_pLifeControl; CComServer* g_pServer = NULL; CComServer::CComServer() { g_pServer = this; } CLifeControl* CComServer::GetLifeControl() { return g_pLifeControl; } HRESULT CComServer::InitializeCom() { return CoInitialize(NULL); } HRESULT CComServer::AddClassInfo( REFCLSID rclsid, CUnkInternal* pFactory, LPTSTR szName, BOOL bFreeThreaded, BOOL bReallyFree /* = FALSE */) { if(pFactory == NULL) return E_OUTOFMEMORY; CClassInfo* pNewInfo = new CClassInfo; if (!pNewInfo) return E_OUTOFMEMORY; // // this object does not hold external references to class factories. // pFactory->InternalAddRef(); pNewInfo->m_pFactory = pFactory; pNewInfo->m_pClsid = &rclsid; pNewInfo->m_szName = new TCHAR[lstrlen(szName) + 1]; if (!pNewInfo->m_szName) { delete pNewInfo; return E_OUTOFMEMORY; } StringCchCopy( pNewInfo->m_szName, lstrlen(szName)+1, szName); pNewInfo->m_bFreeThreaded = bFreeThreaded; pNewInfo->m_bReallyFree = bReallyFree; InsertTailList(&g_ClassInfoHead,&pNewInfo->m_Entry); return S_OK; } HRESULT CComServer::RegisterInterfaceMarshaler(REFIID riid, LPTSTR szName, int nNumMembers, REFIID riidParent) { WCHAR wchId[128]; TCHAR szPath[256]; HKEY hKey1, hKey2; StringFromGUID2( riid, wchId, 128 ); // Create the path. CreatePathString(szPath,256,wchId,TEXT("SOFTWARE\\Classes\\Interface\\")); // Create entries under CLSID RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hKey1); RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)szName, (lstrlen(szName)+1) * sizeof(TCHAR)); RegCreateKey(hKey1, TEXT("ProxyStubClsid32"), &hKey2); RegSetValueExW( hKey2, NULL, 0, REG_SZ,(BYTE*)wchId,(wcslen(wchId)+1)*2); RegCloseKey(hKey1); RegCloseKey(hKey2); return S_OK; } HRESULT CComServer::RegisterInterfaceMarshaler( REFIID riid, CLSID psclsid, LPTSTR szName, int nNumMembers, REFIID riidParent) { WCHAR wchId[128]; WCHAR wchClsid[128]; TCHAR szPath[256]; TCHAR szNumMethods[32]; HKEY hKey1, hKey2, hKey3; // Create the path. StringFromGUID2(riid, wchId, 128); // ProxyStub Class ID StringFromGUID2(psclsid, wchClsid, 128); CreatePathString( szPath, 256, wchId, TEXT("SOFTWARE\\Classes\\Interface\\")); // Number of Methods StringCchPrintf( szNumMethods, 32, TEXT("%d"), nNumMembers ); // Create entries under CLSID RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hKey1); RegSetValueEx(hKey1, NULL, 0, REG_SZ, (BYTE *)szName, (lstrlen(szName)+1) * sizeof(TCHAR)); RegCreateKey(hKey1, TEXT("ProxyStubClsid32"), &hKey2); RegSetValueExW(hKey2,NULL,0,REG_SZ,(BYTE*)wchClsid,(wcslen(wchClsid)+1)*2); RegCreateKey(hKey1, TEXT("NumMethods"), &hKey3); RegSetValueEx(hKey3, NULL, 0, REG_SZ, (BYTE *)szNumMethods, (lstrlen(szNumMethods)+1) * sizeof(TCHAR)); RegCloseKey(hKey1); RegCloseKey(hKey2); RegCloseKey(hKey3); return S_OK; } HRESULT CComServer::UnregisterInterfaceMarshaler(REFIID riid) { WCHAR wchId[128]; TCHAR szPath[256]; HKEY hKey; // Create the path using the CLSID StringFromGUID2(riid, wchId, 128); CreatePathString(szPath,256,wchId,TEXT("SOFTWARE\\Classes\\Interface\\")); // First delete the ProxyStubClsid32 subkey. DWORD dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, szPath, &hKey); if(dwRet == NO_ERROR) { RegDeleteKey(hKey, TEXT("ProxyStubClsid32")); RegCloseKey(hKey); } dwRet = RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Classes\\Interface"), &hKey); if(dwRet == NO_ERROR) { RegDeleteKeyW( hKey, wchId ); RegCloseKey(hKey); } return S_OK; } // // the caller will hold g_CS // void EmptyList() { while(!IsListEmpty(&g_ClassInfoHead)) { CClassInfo * pInfo = CONTAINING_RECORD(g_ClassInfoHead.Blink,CClassInfo,m_Entry); RemoveEntryList(&pInfo->m_Entry); delete pInfo; } } BOOL GlobalCanShutdown() { return g_pServer->CanShutdown(); } HRESULT GlobalInitialize() { return g_pServer->Initialize(); } void GlobalUninitialize() { g_pServer->Uninitialize(); EmptyList(); } void GlobalPostUninitialize() { g_pServer->PostUninitialize(); } void GlobalRegister() { g_pServer->Register(); } void GlobalUnregister() { g_pServer->Unregister(); } HRESULT GlobalInitializeCom() { return g_pServer->InitializeCom(); }