Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

307 lines
6.0 KiB

/*==========================================================================
*
* Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
*
* File: classfac.c
* Content: a generic class factory
*
*
* This is a generic C class factory. All you need to do is implement
* a function called DoCreateInstance that will create an instace of
* your object.
*
* GP_ stands for "General Purpose"
*
* History:
* Date By Reason
* ==== == ======
* 10/13/98 jwo Created it.
* 04/11/00 rodtoll Added code for redirection for custom builds if registry bit is set
* 08/23/2000 rodtoll DllCanUnloadNow always returning TRUE!
* 06/27/2001 rodtoll RC2: DPVOICE: DPVACM's DllMain calls into acm -- potential hang
* Move global initialization to first object creation
***************************************************************************/
#include "dpvacmpch.h"
DNCRITICAL_SECTION g_csObjectCountLock;
LONG g_lNumObjects = 0;
HINSTANCE g_hDllInst = NULL;
LONG g_lNumLocks = 0;
typedef struct GPCLASSFACTORY
{
IClassFactoryVtbl *lpVtbl;
LONG lRefCnt;
CLSID clsid;
} GPCLASSFACTORY, *LPGPCLASSFACTORY;
/*
* GP_QueryInterface
*/
STDMETHODIMP GP_QueryInterface(
LPCLASSFACTORY This,
REFIID riid,
LPVOID *ppvObj )
{
LPGPCLASSFACTORY pcf;
HRESULT hr;
pcf = (LPGPCLASSFACTORY)This;
*ppvObj = NULL;
if( IsEqualIID(riid, IID_IClassFactory) ||
IsEqualIID(riid, IID_IUnknown))
{
InterlockedIncrement( &pcf->lRefCnt );
*ppvObj = This;
hr = S_OK;
}
else
{
hr = E_NOINTERFACE;
}
return hr;
} /* GP_QueryInterface */
/*
* GP_AddRef
*/
STDMETHODIMP_(ULONG) GP_AddRef( LPCLASSFACTORY This )
{
LPGPCLASSFACTORY pcf;
pcf = (LPGPCLASSFACTORY)This;
return InterlockedIncrement( &pcf->lRefCnt );
} /* GP_AddRef */
/*
* GP_Release
*/
STDMETHODIMP_(ULONG) GP_Release( LPCLASSFACTORY This )
{
LPGPCLASSFACTORY pcf;
ULONG ulResult;
pcf = (LPGPCLASSFACTORY)This;
if( (ulResult = (ULONG) InterlockedDecrement( &pcf->lRefCnt ) ) == 0 )
{
DNFree( pcf );
DecrementObjectCount();
}
return ulResult;
} /* GP_Release */
/*
* GP_CreateInstance
*
* Creates an instance of a DNServiceProvider object
*/
STDMETHODIMP GP_CreateInstance(
LPCLASSFACTORY This,
LPUNKNOWN pUnkOuter,
REFIID riid,
LPVOID *ppvObj
)
{
HRESULT hr = S_OK;
LPGPCLASSFACTORY pcf;
if( pUnkOuter != NULL )
{
return CLASS_E_NOAGGREGATION;
}
pcf = (LPGPCLASSFACTORY) This;
*ppvObj = NULL;
/*
* create the object by calling DoCreateInstance. This function
* must be implemented specifically for your COM object
*/
hr = DoCreateInstance(This, pUnkOuter, pcf->clsid, riid, ppvObj);
if (FAILED(hr))
{
*ppvObj = NULL;
return hr;
}
return S_OK;
} /* GP_CreateInstance */
/*
* GP_LockServer
*
* Called to force our DLL to stayed loaded
*/
STDMETHODIMP GP_LockServer(
LPCLASSFACTORY This,
BOOL fLock
)
{
if( fLock )
{
InterlockedIncrement( &g_lNumLocks );
}
else
{
InterlockedDecrement( &g_lNumLocks );
}
return S_OK;
} /* GP_LockServer */
static IClassFactoryVtbl GPClassFactoryVtbl =
{
GP_QueryInterface,
GP_AddRef,
GP_Release,
GP_CreateInstance,
GP_LockServer
};
/*
* DllGetClassObject
*
* Entry point called by COM to get a ClassFactory pointer
*/
STDAPI DllGetClassObject(
REFCLSID rclsid,
REFIID riid,
LPVOID *ppvObj )
{
LPGPCLASSFACTORY pcf;
HRESULT hr;
*ppvObj = NULL;
/*
* is this our class id?
*/
// you must implement GetClassID() for your specific COM object
if (!IsClassImplemented(rclsid))
{
return CLASS_E_CLASSNOTAVAILABLE;
}
/*
* only allow IUnknown and IClassFactory
*/
if( !IsEqualIID( riid, IID_IUnknown ) &&
!IsEqualIID( riid, IID_IClassFactory ) )
{
return E_NOINTERFACE;
}
/*
* create a class factory object
*/
pcf = (LPGPCLASSFACTORY)DNMalloc( sizeof( GPCLASSFACTORY ) );
if( NULL == pcf)
{
return E_OUTOFMEMORY;
}
pcf->lpVtbl = &GPClassFactoryVtbl;
pcf->lRefCnt = 0;
pcf->clsid = rclsid;
hr = GP_QueryInterface( (LPCLASSFACTORY) pcf, riid, ppvObj );
if( FAILED( hr ) )
{
DNFree ( pcf );
*ppvObj = NULL;
}
else
{
IncrementObjectCount();
}
return hr;
} /* DllGetClassObject */
/*
* DllCanUnloadNow
*
* Entry point called by COM to see if it is OK to free our DLL
*/
STDAPI DllCanUnloadNow( void )
{
HRESULT hr = S_FALSE;
// if (0 == gnObjects)
if ( (0 == g_lNumObjects) && (0 == g_lNumLocks) )
{
hr = S_OK;
}
return hr;
} /* DllCanUnloadNow */
#undef DPF_MODNAME
#define DPF_MODNAME "IncrementObjectCount"
LONG IncrementObjectCount()
{
LONG lNewCount;
DNEnterCriticalSection( &g_csObjectCountLock );
g_lNumObjects++;
lNewCount = g_lNumObjects;
if( g_lNumObjects == 1 )
{
DPFX(DPFPREP,1,"Initializing Dll Global State" );
CDPVACMI::InitCompressionList(g_hDllInst,DPVOICE_REGISTRY_BASE DPVOICE_REGISTRY_CP DPVOICE_REGISTRY_DPVACM );
}
DNLeaveCriticalSection( &g_csObjectCountLock );
return lNewCount;
}
#undef DPF_MODNAME
#define DPF_MODNAME "DecrementObjectCount"
LONG DecrementObjectCount()
{
LONG lNewCount;
DNEnterCriticalSection( &g_csObjectCountLock );
g_lNumObjects--;
lNewCount = g_lNumObjects;
if( g_lNumObjects == 0 )
{
DPFX(DPFPREP,1,"Freeing Dll Global State" );
CDPVCPI::DeInitCompressionList();
}
DNLeaveCriticalSection( &g_csObjectCountLock );
return lNewCount;
}