windows-nt/Source/XPSP1/NT/com/ole32/common/stdcf.cxx
2020-09-26 16:20:57 +08:00

241 lines
10 KiB
C++

//+-------------------------------------------------------------------
//
// File: stdcf.cxx
//
// Contents: class implementing standard CF for internal OLE classes
//
// Classes: CStdClassFactory
//
// History: Rickhi 06-24-97 Created
//
//+-------------------------------------------------------------------
#include <ole2int.h>
#include <stdcf.hxx>
// CreateInstance functions for each of the internal classes.
extern HRESULT CGIPTableCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void **ppv);
extern HRESULT CAccessControlCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void **ppv);
extern HRESULT CAsyncActManagerCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void **ppv);
extern HRESULT CComCatCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CComCatCSCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CItemMonikerCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CCompositeMonikerCF_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CPackagerMonikerCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CAntiMonikerCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CPointerMonikerCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CErrorObjectCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CRpcHelperCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CObjectContextCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CComCatalogCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CStdEventCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CManualResetEventCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CSynchronizeContainerCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CFreeThreadedMarshalerCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CActivationPropertiesInCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CActivationPropertiesOutCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CInprocActpropsUnmarshallerCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CComActivatorCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
extern HRESULT CAddrControlCF_CreateInstance (IUnknown *pUnkOuter, REFIID riid, void** ppv);
//+-------------------------------------------------------------------
// Entry in the global calss objects table. Contains a ptr to a clsid
// and a ptr to the corresponding CreateInstance function for that
// clsid.
//+-------------------------------------------------------------------
typedef struct tagCFEntry
{
const CLSID *pclsid; // ptr to clsid
LPFNCREATEINSTANCE pfnCI; // ptr to CreateInstance fn
DWORD dwFlags; // misc flags. see CCF_FLAGS
} CFEntry;
typedef enum tagCCF_FLAGS
{
CCF_NONE = 0x0,
CCF_AGGREGATABLE = 0x1, // class is aggregatable
} CCF_FLAGS;
//+-------------------------------------------------------------------
//
// gInternalClassObjects - table of clsids and the corresponding
// CreateInstance functions for those clsids. The CI function is
// passed to the standard implementation of the class factory object.
//
//+-------------------------------------------------------------------
const CFEntry gInternalClassObjects[] =
{
{&CLSID_StdEvent, CStdEventCF_CreateInstance, CCF_AGGREGATABLE},
{&CLSID_ManualResetEvent, CManualResetEventCF_CreateInstance, CCF_AGGREGATABLE},
{&CLSID_SynchronizeContainer, CSynchronizeContainerCF_CreateInstance, CCF_AGGREGATABLE},
{&CLSID_StdGlobalInterfaceTable, CGIPTableCF_CreateInstance, CCF_NONE},
{&CLSID_DCOMAccessControl, CAccessControlCF_CreateInstance, CCF_AGGREGATABLE},
{&CLSID_ErrorObject, CErrorObjectCF_CreateInstance, CCF_NONE},
{&CLSID_COMCatalog, CComCatalogCF_CreateInstance, CCF_NONE},
{&CLSID_ItemMoniker, CItemMonikerCF_CreateInstance, CCF_NONE},
{&CLSID_CompositeMoniker, CCompositeMonikerCF_CreateInstance, CCF_NONE},
{&CLSID_PackagerMoniker, CPackagerMonikerCF_CreateInstance, CCF_NONE},
{&CLSID_AntiMoniker, CAntiMonikerCF_CreateInstance, CCF_NONE},
{&CLSID_PointerMoniker, CPointerMonikerCF_CreateInstance, CCF_NONE},
{&CLSID_StdComponentCategoriesMgr, CComCatCF_CreateInstance, CCF_AGGREGATABLE},
{&CLSID_GblComponentCategoriesMgr, CComCatCSCF_CreateInstance, CCF_AGGREGATABLE},
{&CLSID_RpcHelper, CRpcHelperCF_CreateInstance, CCF_NONE},
{&CLSID_ObjectContext, CObjectContextCF_CreateInstance, CCF_NONE},
{&CLSID_InProcFreeMarshaler, CFreeThreadedMarshalerCF_CreateInstance, CCF_AGGREGATABLE},
{&CLSID_ActivationPropertiesIn, CActivationPropertiesInCF_CreateInstance, CCF_NONE},
{&CLSID_ActivationPropertiesOut, CActivationPropertiesOutCF_CreateInstance, CCF_NONE},
{&CLSID_InprocActpropsUnmarshaller, CInprocActpropsUnmarshallerCF_CreateInstance, CCF_NONE},
{&CLSID_ComActivator, CComActivatorCF_CreateInstance, CCF_NONE},
{&CLSID_AddrControl, CAddrControlCF_CreateInstance, CCF_NONE},
{NULL, NULL}
};
//+-------------------------------------------------------------------
//
// Function: ComDllGetClassObject
//
// Synopsis: Function to return internal class objects.
//
// Notes: Uses the gInternalClassObjects table and the
// CStdClassFactory implementation.
//
//+-------------------------------------------------------------------
INTERNAL ComDllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
{
ComDebOut((DEB_ACTIVATE, "ComDllGetClassObject rclsid:%I riid:%I ppv:%x\n",
&rclsid, &riid, ppv));
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
int i=0;
while (gInternalClassObjects[i].pclsid)
{
if (InlineIsEqualGUID(*gInternalClassObjects[i].pclsid, rclsid))
{
// found a matching CLSID. Create an instance of the std class factory
// passing in the creatinstance function from the table.
hr = E_OUTOFMEMORY;
CStdClassFactory *pCF = new CStdClassFactory(i);
if (pCF)
{
hr = pCF->QueryInterface(riid, ppv);
pCF->Release();
}
break;
}
i++;
}
ComDebOut((DEB_ACTIVATE, "ComDllGetClassObject hr:%x pv:%x\n", hr, *ppv));
return hr;
}
//+-------------------------------------------------------------------
//
// Member: CStdClassFactory::AddRef, public
//
// Synopsis: Adds a reference to an interface
//
//--------------------------------------------------------------------
STDMETHODIMP_(ULONG) CStdClassFactory::AddRef(void)
{
return InterlockedIncrement((LONG *)&_cRefs);
}
//+-------------------------------------------------------------------
//
// Member: CStdClassFactory::Release, public
//
// Synopsis: Adds a reference to an interface
//
//--------------------------------------------------------------------
STDMETHODIMP_(ULONG) CStdClassFactory::Release(void)
{
ULONG cRefs = (ULONG) InterlockedDecrement((LONG *)&_cRefs);
if (cRefs == 0)
{
delete this;
}
return cRefs;
}
//+-------------------------------------------------------------------
//
// Member: CStdClassFactory::QueryInterface, public
//
// Synopsis: Returns a pointer to the requested interface.
//
//--------------------------------------------------------------------
STDMETHODIMP CStdClassFactory::QueryInterface(REFIID riid, void **ppv)
{
if (IsEqualIID(riid, IID_IClassFactory) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppv = (IClassFactory *) this;
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
//+-------------------------------------------------------------------
//
// Member: CStdClassFactory::CreateInstance, public
//
// Synopsis: Create an instance of the requested class by calling
// the creation function member variable.
//
// Notes: Does the parameter checking here to avoid having to
// replicate it in all the creation functions.
//
//--------------------------------------------------------------------
STDMETHODIMP CStdClassFactory::CreateInstance(IUnknown *pUnkOuter,
REFIID riid,
void **ppv)
{
ComDebOut((DEB_ACTIVATE,
"CStdClassFactory::CreateInstance _dwIndex:%x pUnkOuter:%x riid:%I ppv:%x\n",
_dwIndex, pUnkOuter, &riid, ppv));
// Validate the parameters.
HRESULT hr = E_INVALIDARG;
if (ppv != NULL)
{
*ppv = NULL;
// If the caller wants to aggregate, only IID_IUnknown may be requested.
if (pUnkOuter == NULL || IsEqualGUID(IID_IUnknown, riid))
{
// check if aggregation desired and supported.
hr = CLASS_E_NOAGGREGATION;
if ( pUnkOuter == NULL ||
(gInternalClassObjects[_dwIndex].dwFlags & CCF_AGGREGATABLE))
{
// Create the object instance
IUnknown *pUnk=NULL;
hr = (gInternalClassObjects[_dwIndex].pfnCI)(pUnkOuter, riid, (void **)&pUnk);
if (SUCCEEDED(hr))
{
// get the requested interface
hr = pUnk->QueryInterface(riid, ppv);
pUnk->Release();
}
}
}
}
ComDebOut((DEB_ACTIVATE, "CStdClassFactory::CreateInstance hr:%x *ppv:%x\n",
hr, *ppv));
return hr;
}