Windows2003-3790/windows/advcore/duser/engine/services/commanager.cpp
2020-09-30 16:53:55 +02:00

219 lines
6.6 KiB
C++

/***************************************************************************\
*
* File: ComManager.cpp
*
* Description:
* ComManager.cpp implements the process-wide COM manager used for all COM, OLE
* and Automation operations.
*
*
* History:
* 1/18/2000: JStall: Created
*
* Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
*
\***************************************************************************/
#include "stdafx.h"
#include "Services.h"
#include "ComManager.h"
int ComManager::s_cRefs = 0;
CritLock ComManager::s_lock;
HINSTANCE ComManager::s_hDllCOM = NULL;
CoInitializeExProc ComManager::s_pfnCoInit = NULL;
CoUninitializeProc ComManager::s_pfnCoUninit = NULL;
CoCreateInstanceProc ComManager::s_pfnCreate = NULL;
OleInitializeProc ComManager::s_pfnOleInit = NULL;
OleUninitializeProc ComManager::s_pfnOleUninit = NULL;
RegisterDragDropProc ComManager::s_pfnRegisterDragDrop = NULL;
RevokeDragDropProc ComManager::s_pfnRevokeDragDrop = NULL;
ReleaseStgMediumProc ComManager::s_pfnReleaseStgMedium = NULL;
HINSTANCE ComManager::s_hDllAuto = NULL;
SysAllocStringProc ComManager::s_pfnAllocString = NULL;
SysFreeStringProc ComManager::s_pfnFreeString = NULL;
VariantInitProc ComManager::s_pfnVariantInit = NULL;
VariantClearProc ComManager::s_pfnVariantClear = NULL;
//------------------------------------------------------------------------------
ComManager::ComManager()
{
m_fInitCOM = FALSE;
m_fInitOLE = FALSE;
s_lock.Enter();
s_cRefs++;
s_lock.Leave();
}
//------------------------------------------------------------------------------
ComManager::~ComManager()
{
s_lock.Enter();
if ((s_pfnOleUninit != NULL) && m_fInitOLE) {
(s_pfnOleUninit)();
}
if ((s_pfnCoUninit != NULL) && m_fInitCOM) {
(s_pfnCoUninit)();
}
AssertMsg(s_cRefs > 0, "Must have at least one outstanding reference");
if (--s_cRefs == 0) {
if (s_hDllAuto != NULL) {
FreeLibrary(s_hDllAuto);
s_hDllAuto = NULL;
}
if (s_hDllCOM != NULL) {
FreeLibrary(s_hDllCOM);
s_hDllCOM = NULL;
}
s_pfnCoInit = NULL;
s_pfnCoUninit = NULL;
s_pfnCreate = NULL;
s_pfnOleInit = NULL;
s_pfnOleUninit = NULL;
s_pfnRegisterDragDrop = NULL;
s_pfnRevokeDragDrop = NULL;
s_pfnReleaseStgMedium = NULL;
s_pfnAllocString = NULL;
s_pfnFreeString = NULL;
s_pfnVariantInit = NULL;
s_pfnVariantClear = NULL;
}
s_lock.Leave();
}
//------------------------------------------------------------------------------
BOOL
ComManager::Init(UINT nMask)
{
BOOL fSuccess = TRUE;
s_lock.Enter();
if (TestFlag(nMask, sAuto)) {
// OLE-Automation need COM.
SetFlag(nMask, sCOM);
}
if (TestFlag(nMask, sCOM | sOLE)) {
//
// Load the DLL
//
if (s_hDllCOM == NULL) {
s_hDllCOM = LoadLibrary(_T("ole32.dll"));
if (s_hDllCOM == NULL) {
fSuccess = FALSE;
goto errorexit;
}
s_pfnCoInit = (CoInitializeExProc) GetProcAddress(s_hDllCOM, _T("CoInitializeEx"));
s_pfnCoUninit = (CoUninitializeProc) GetProcAddress(s_hDllCOM, _T("CoUninitialize"));
s_pfnCreate = (CoCreateInstanceProc)GetProcAddress(s_hDllCOM, _T("CoCreateInstance"));
s_pfnOleInit = (OleInitializeProc) GetProcAddress(s_hDllCOM, _T("OleInitialize"));
s_pfnOleUninit = (OleUninitializeProc) GetProcAddress(s_hDllCOM, _T("OleUninitialize"));
s_pfnRegisterDragDrop = (RegisterDragDropProc) GetProcAddress(s_hDllCOM, _T("RegisterDragDrop"));
s_pfnRevokeDragDrop = (RevokeDragDropProc) GetProcAddress(s_hDllCOM, _T("RevokeDragDrop"));
s_pfnReleaseStgMedium = (ReleaseStgMediumProc) GetProcAddress(s_hDllCOM, _T("ReleaseStgMedium"));
if ((s_pfnCoInit == NULL) || (s_pfnCoUninit == NULL) || (s_pfnCreate == NULL) ||
(s_pfnOleInit == NULL) || (s_pfnOleUninit == NULL) ||
(s_pfnRegisterDragDrop == NULL) || (s_pfnRevokeDragDrop == NULL) ||
(s_pfnReleaseStgMedium == NULL)) {
fSuccess = FALSE;
goto errorexit;
}
}
//
// Start COM / OLE
//
if (TestFlag(nMask, sCOM) && (!m_fInitCOM)) {
// UI threads can not be free-threaded, so use apartment.
HRESULT hr = (s_pfnCoInit)(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) {
fSuccess = FALSE;
goto errorexit;
}
m_fInitCOM = TRUE;
}
if (TestFlag(nMask, sOLE) && (!m_fInitOLE)) {
HRESULT hr = (s_pfnOleInit)(NULL);
if (FAILED(hr)) {
fSuccess = FALSE;
goto errorexit;
}
m_fInitOLE = TRUE;
}
}
if (TestFlag(nMask, sAuto) && (s_hDllAuto == NULL)) {
s_hDllAuto = LoadLibrary(_T("oleaut32.dll"));
if (s_hDllAuto == NULL) {
fSuccess = FALSE;
goto errorexit;
}
s_pfnAllocString = (SysAllocStringProc) GetProcAddress(s_hDllAuto, _T("SysAllocString"));
s_pfnFreeString = (SysFreeStringProc) GetProcAddress(s_hDllAuto, _T("SysFreeString"));
s_pfnVariantInit = (VariantInitProc) GetProcAddress(s_hDllAuto, _T("VariantInit"));
s_pfnVariantClear = (VariantClearProc) GetProcAddress(s_hDllAuto, _T("VariantClear"));
if ((s_pfnAllocString == NULL) || (s_pfnFreeString == NULL) ||
(s_pfnVariantInit == NULL) || (s_pfnVariantClear == NULL)) {
fSuccess = FALSE;
goto errorexit;
}
}
errorexit:
s_lock.Leave();
return fSuccess;
}
//------------------------------------------------------------------------------
BOOL
ComManager::IsInit(UINT nMask) const
{
if (TestFlag(nMask, sCOM) && (s_hDllCOM != NULL) && m_fInitCOM) {
return TRUE;
}
if (TestFlag(nMask, sOLE) && (s_hDllCOM != NULL) && m_fInitOLE) {
return TRUE;
}
if (TestFlag(nMask, sAuto) && (s_hDllAuto != NULL)) {
return TRUE;
}
return FALSE;
}