windows-nt/Source/XPSP1/NT/shell/shell32/defclsf.c
2020-09-26 16:20:57 +08:00

117 lines
3.3 KiB
C

//
// This file contains the implementation of SHCreateDefClassObject
//
#include "shellprv.h"
#pragma hdrstop
typedef struct
{
IClassFactory cf;
UINT cRef; // Reference count
DWORD dwFlags; // Flags to control creation...
LPFNCREATEINSTANCE pfnCreateInstance; // CreateInstance callback entry
UINT * pcRefDll; // Reference count of the DLL
} CClassFactory;
STDMETHODIMP CClassFactory_QueryInterface(IClassFactory *pcf, REFIID riid, void **ppvObj)
{
CClassFactory *this = IToClass(CClassFactory, cf, pcf);
if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
{
InterlockedIncrement(&this->cRef);
*ppvObj = (LPVOID) (IClassFactory *) &this->cf;
return NOERROR;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CClassFactory_AddRef(IClassFactory *pcf)
{
CClassFactory *this = IToClass(CClassFactory, cf, pcf);
return this->cRef;
}
STDMETHODIMP_(ULONG) CClassFactory_Release(IClassFactory *pcf)
{
CClassFactory *this = IToClass(CClassFactory, cf, pcf);
if (--this->cRef > 0)
return this->cRef;
LocalFree((HLOCAL)this);
return 0;
}
STDMETHODIMP CClassFactory_CreateInstance(IClassFactory *pcf, IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
{
CClassFactory *this = IToClass(CClassFactory, cf, pcf);
*ppvObject = NULL;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
return this->pfnCreateInstance(pUnkOuter, riid, ppvObject);
}
STDMETHODIMP CClassFactory_LockServer(IClassFactory *pcf, BOOL fLock)
{
CClassFactory *this = IToClass(CClassFactory, cf, pcf);
if (this->pcRefDll)
{
if (fLock)
this->pcRefDll++;
else
this->pcRefDll--;
}
return S_OK;
}
const IClassFactoryVtbl c_vtblAppUIClassFactory = {
CClassFactory_QueryInterface, CClassFactory_AddRef, CClassFactory_Release,
CClassFactory_CreateInstance,
CClassFactory_LockServer
};
//
// creates a simple default implementation of IClassFactory
//
// Parameters:
// riid -- Specifies the interface to the class object
// ppv -- Specifies the pointer to LPVOID where the class object pointer
// will be returned.
// pfnCreateInstance -- Specifies the callback entry for instanciation.
// pcRefDll -- Specifies the address to the DLL reference count (optional)
//
// Notes:
// The riidInst will be specified only if the instance of the class
// support only one interface.
//
// we would like to get rid of this
// this API called by MMSYS.CPL, RNAUI.DLL, SYNCUI.DLL
STDAPI SHCreateDefClassObject(REFIID riid, void **ppv, LPFNCREATEINSTANCE pfnCreateInstance, UINT *pcRefDll, REFIID riidInst)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IClassFactory))
{
CClassFactory *pacf = (CClassFactory *)LocalAlloc(LPTR, SIZEOF(CClassFactory));
if (pacf)
{
pacf->cf.lpVtbl = &c_vtblAppUIClassFactory;
pacf->cRef++; // pacf->cRef=0; (generates smaller code)
pacf->pcRefDll = pcRefDll;
pacf->pfnCreateInstance = pfnCreateInstance;
(IClassFactory *)*ppv = &pacf->cf;
return NOERROR;
}
return E_OUTOFMEMORY;
}
return E_NOINTERFACE;
}