/* CMikeCF.c

Contains the implementation of the Class factory
for a COM server written in C

Back to the "COM Inproc Server in C" tutorial.


*/

#include "CMikeCF.h"
#include "CMike.h"

HRESULT _stdcall CMikeCFQueryInterface( IClassFactory *pCF, REFIID iid, void **ppvObject)
{
CMikeCF *pThis = (CMikeCF *)pCF;

if( IsEqualIID( iid, &IID_IUnknown) ||
IsEqualIID( iid, &IID_IClassFactory) )
{
*ppvObject = pThis;
pThis->icf.lpVtbl->AddRef( pCF );
return S_OK;
}
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
}

ULONG _stdcall CMikeCFAddRef( IClassFactory *pCF )
{
CMikeCF *pThis = (CMikeCF *)pCF;

return ++pThis->cRef;
}

ULONG _stdcall CMikeCFRelease( IClassFactory *pCF )
{
CMikeCF *pThis = (CMikeCF *)pCF;

if( --pThis->cRef == 0 )
{
free( pThis );
return 0;
}
else
return pThis->cRef;
}

HRESULT _stdcall CMikeCFCreateInstance( IClassFactory *pICF, IUnknown * pUnkOuter, //Pointer to whether object is or isn't part of an aggregate
REFIID riid, /*Reference to the identifier of the interface*/
void ** ppvObject /*indirect pointer to the interface*/
)
{
CMikeCF *pThis = (CMikeCF *)pICF;
CMike *pCM;


if( pUnkOuter != NULL )
{
return CLASS_E_NOAGGREGATION;
}
pCM = (CMike *)malloc( sizeof( CMike ) );
if( NULL == pCM )
{
return E_OUTOFMEMORY;
}
pCM->Im.lpVtbl = &IMVT;
pCM->cRef = 1;
if( S_OK != pCM->Im.lpBack to the "COM Inproc Server in C" tutorial.tbl->pfnQueryInterface( &(pCM->Im), riid, ppvObject ) )
{
free( pCM );
return E_NOINTERFACE;
}
pCM->Im.lpVtbl->pfnRelease(&(pCM->Im));
cCMike++; /*increment the count of CMikes so we know when to
return TRUE in DllCanUnloadNow */
}

HRESULT _stdcall CMikeCFLockServer( IClassFactory *pICF, BOOL fLock)
{
if( TRUE == fLock)
{
cCMike--;
}
else
{
cCMike++;
}
return S_OK;
}

struct IClassFactoryVtbl ICFVT = { CMikeCFQueryInterface,
CMikeCFAddRef,
CMikeCFRelease,
CMikeCFCreateInstance,
CMikeCFLockServer };

/*//////////////////////// End of ClassFactory implementation //////////////////////*/