219 lines
6.6 KiB
C++
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;
|
|
}
|