Leaked source code of windows server 2003
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

/*++
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();
}