You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
388 lines
9.2 KiB
388 lines
9.2 KiB
/*++
|
|
|
|
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();
|
|
}
|
|
|