|
|
/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
COMMAIN.CPP
Abstract:
COM Helpers
History:
--*/
#include <windows.h>
#include <objbase.h>
#include <stdio.h>
#include <vector>
#include <clsfac.h>
#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(); }
|