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.
 
 
 
 
 
 

241 lines
7.6 KiB

// @doc
/**********************************************************************
*
* @module IDirectInputEffectDriverClassFactory.cpp |
*
* Contains Class Implementation of CIDirectInputEffectDriverClassFactory:
* Factory for Creating Proper Effect Driver
*
* History
* ----------------------------------------------------------
* Matthew L. Coill (mlc) Original Jul-7-1999
*
* (c) 1999 Microsoft Corporation. All right reserved.
*
* @topic This IDirectInputEffectDriver |
* This Driver sits on top of the standard PID driver (which is also
* an IDirectInputEffectDriver) and passes most requests to the PID driver.
* Some requests such as, DownloadEffect and SendForceFeedback command are
* modified for our use. Modification purposes are described at each function
* definition.
*
**********************************************************************/
#include "IDirectInputEffectDriverClassFactory.h"
#include "IDirectInputEffectDriver.h"
#include <crtdbg.h>
#include <objbase.h>
LONG DllAddRef();
LONG DllRelease();
extern CIDirectInputEffectDriverClassFactory* g_pClassFactoryObject;
/******************** Class CIDirectInputEffectDriverClassFactory ***********************/
/*****************************************************************************
**
** CIDirectInputEffectDriverClassFactory::CIDirectInputEffectDriverClassFactory()
**
** @mfunc Constructor
**
*****************************************************************************/
CIDirectInputEffectDriverClassFactory::CIDirectInputEffectDriverClassFactory
(
IClassFactory* pIPIDClassFactory //@parm [IN] Default PID Factory
) :
m_ulLockCount(0),
m_ulReferenceCount(1),
m_pIPIDClassFactory(pIPIDClassFactory)
{
// Increase global object count
DllAddRef();
// Add count to held object
m_pIPIDClassFactory->AddRef();
}
/*****************************************************************************
**
** CIDirectInputEffectDriverClassFactory::~CIDirectInputEffectDriverClassFactory()
**
** @mfunc Destructor
**
*****************************************************************************/
CIDirectInputEffectDriverClassFactory::~CIDirectInputEffectDriverClassFactory()
{
// Decrease Global object count
DllRelease();
_ASSERTE(m_pIPIDClassFactory == NULL);
_ASSERTE(m_ulLockCount == 0);
}
/***********************************************************************************
**
** ULONG CIDirectInputEffectDriverClassFactory::QueryInterface(REFIID refiid, void** ppvObject)
**
** @func Query an Unknown for a particular type. This causes increase locally only
** If it is a type we don't know, should we give the PID factory a crack (PID factory
** might have a customized private interface, we don't want to ruin that. Currently not
** going to pass on the Query, because this could screwup Symmetry.
**
** @rdesc S_OK if all is well, E_INVALIDARG if ppvObject is NULL or E_NOINTERFACE
**
*************************************************************************************/
HRESULT __stdcall CIDirectInputEffectDriverClassFactory::QueryInterface
(
REFIID refiid, //@parm [IN] Identifier of the requested interface
void** ppvObject //@parm [OUT] Address to place requested interface pointer
)
{
HRESULT hrPidQuery = m_pIPIDClassFactory->QueryInterface(refiid, ppvObject);
if (SUCCEEDED(hrPidQuery))
{
*ppvObject = this;
// Increase our reference count only (pid class fact would be incremented by AddRef call)
::InterlockedIncrement((LONG*)&m_ulReferenceCount);
}
return hrPidQuery;
}
/***********************************************************************************
**
** ULONG CIDirectInputEffectDriverClassFactory::AddRef()
**
** @func Bumps up the reference count
** The PID Factory reference count is left alone. We only decrement it when
** this factory is ready to go away.
**
** @rdesc New reference count
**
*************************************************************************************/
ULONG __stdcall CIDirectInputEffectDriverClassFactory::AddRef()
{
m_pIPIDClassFactory->AddRef();
return (ULONG)::InterlockedIncrement((LONG*)&m_ulReferenceCount);
}
/***********************************************************************************
**
** ULONG CIDirectInputEffectDriverClassFactory::Release()
**
** @func Decrements the reference count.
** If both the reference count and the lock count are zero the PID Factory is
** released and this object is destroyed.
** The PID Factory reference is only effected if it is time to release all.
**
** @rdesc New reference count
**
*************************************************************************************/
ULONG __stdcall CIDirectInputEffectDriverClassFactory::Release()
{
m_pIPIDClassFactory->Release();
if (::InterlockedDecrement((LONG*)&m_ulReferenceCount) != 0)
{
return m_ulReferenceCount;
}
m_pIPIDClassFactory = NULL;
g_pClassFactoryObject = NULL;
delete this;
return 0;
}
/***********************************************************************************
**
** HRESULT CIDirectInputEffectDriverClassFactory::CreateInstance(IUnknown * pUnkOuter, REFIID riid, void** ppvObject)
**
** @func Create an instance of the object
** Also tells the PID factory to create an instance, this is stored in our instance.
**
**
** @rdesc S_OK if intstance is created
** E_INVALIDARG if (ppvObject == NULL)
** CLASS_E_NOAGGREGATION if aggrigation is attempted (pUnkOuter != NULL)
**
*************************************************************************************/
HRESULT __stdcall CIDirectInputEffectDriverClassFactory::CreateInstance
(
IUnknown* pUnkOuter, //@parm [IN] Aggregate class or NULL
REFIID riid, //@parm [IN] IID of Object to create
void** ppvObject //@parm [OUT] Address to place the requested object
)
{
if (pUnkOuter != NULL)
{
return CLASS_E_NOAGGREGATION;
}
if (ppvObject == NULL)
{
return E_INVALIDARG;
}
if (riid == IID_IDirectInputEffectDriver)
{
// Let the PID Factory Create its driver
IDirectInputEffectDriver* pPIDDriver = NULL;
HRESULT hrPID = m_pIPIDClassFactory->CreateInstance(pUnkOuter, riid, (void**)(&pPIDDriver));
if (FAILED(hrPID) || (pPIDDriver == NULL))
{
return hrPID;
}
// Create our effect driver
*ppvObject = new CIDirectInputEffectDriver(pPIDDriver, m_pIPIDClassFactory);
pPIDDriver->Release(); // We no longer care about this (held in our CIDirectInputEffectDriver)
if (*ppvObject == NULL)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
return E_NOINTERFACE;
}
/***********************************************************************************
**
** HRESULT CIDirectInputEffectDriverClassFactory::LockServer(BOOL fLock)
**
** @func Lock this factory down (prevents Release from causing deletion)
** If Unlocked compleatly (m_ulLockCount becomes 0) and reference count
** is at 0 - this Factory is destroyed (and the PID factory is released)
**
** @rdesc S_OK : All is well
** E_UNEXPECTED: Unlock on non-locked object
**
*************************************************************************************/
HRESULT __stdcall CIDirectInputEffectDriverClassFactory::LockServer
(
BOOL fLock //@parm [IN] Is the server being locked or unlocked
)
{
HRESULT hrPidLock = m_pIPIDClassFactory->LockServer(fLock);
if (FAILED(hrPidLock))
{
return hrPidLock;
}
if (fLock != FALSE)
{
::InterlockedIncrement((LONG*)&m_ulLockCount);
return S_OK;
}
if (m_ulLockCount == 0)
{
return E_UNEXPECTED;
}
::InterlockedDecrement((LONG*)&m_ulLockCount);
return hrPidLock;
}