375 lines
10 KiB
C
375 lines
10 KiB
C
/*****************************************************************************
|
|
*
|
|
* DICF.c
|
|
*
|
|
* Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* Abstract:
|
|
*
|
|
* DirectInput ClassFactory.
|
|
*
|
|
* Contents:
|
|
*
|
|
* IClassFactory::CreateInstance
|
|
* IClassFactory::LockServer
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "dinputpr.h"
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* The sqiffle for this file.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#define sqfl sqflFactory
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Declare the interfaces we will be providing.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
Primary_Interface(CDIFactory, IClassFactory);
|
|
|
|
Interface_Template_Begin(CDIFactory)
|
|
Primary_Interface_Template(CDIFactory, IClassFactory)
|
|
Interface_Template_End(CDIFactory)
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @struct CDIFactory |
|
|
*
|
|
* The DirectInput <i IClassFactory>, which is how you create an
|
|
* <i IDirectInput> object.
|
|
* There really isn't anything interesting in the structure
|
|
* itself.
|
|
*
|
|
* @field IClassFactory | cf |
|
|
*
|
|
* ClassFactory object (containing vtbl).
|
|
*
|
|
* @field CREATEFUNC | pfnCreate |
|
|
*
|
|
* Function that creates new objects.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
typedef struct CDIFactory {
|
|
|
|
/* Supported interfaces */
|
|
IClassFactory cf;
|
|
|
|
CREATEFUNC pfnCreate;
|
|
|
|
} CDIFactory, DCF, *PDCF;
|
|
|
|
typedef IClassFactory CF, *PCF;
|
|
|
|
#define ThisClass CDIFactory
|
|
#define ThisInterface IClassFactory
|
|
#define ThisInterfaceT IClassFactory
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc EXTERNAL
|
|
*
|
|
* @method HRESULT | IClassFactory | QueryInterface |
|
|
*
|
|
* Gives a client access to other interfaces on an object.
|
|
*
|
|
* @cwrap LPCLASSFACTORY | lpClassFactory
|
|
*
|
|
* @parm IN REFIID | riid |
|
|
*
|
|
* The requested interface's IID.
|
|
*
|
|
* @parm OUT LPVOID * | ppvObj |
|
|
*
|
|
* Receives a pointer to the obtained interface.
|
|
*
|
|
* @returns
|
|
*
|
|
* Returns a COM error code.
|
|
*
|
|
* @xref OLE documentation for <mf IUnknown::QueryInterface>.
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* @doc EXTERNAL
|
|
*
|
|
* @method HRESULT | IClassFactory | AddRef |
|
|
*
|
|
* Increments the reference count for the interface.
|
|
*
|
|
* @cwrap LPCLASSFACTORY | lpClassFactory
|
|
*
|
|
* @returns
|
|
*
|
|
* Returns the object reference count.
|
|
*
|
|
* @xref OLE documentation for <mf IUnknown::AddRef>.
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* @doc EXTERNAL
|
|
*
|
|
* @method HRESULT | IClassFactory | Release |
|
|
*
|
|
* Decrements the reference count for the interface.
|
|
* If the reference count on the object falls to zero,
|
|
* the object is freed from memory.
|
|
*
|
|
* @cwrap LPCLASSFACTORY | lpClassFactory
|
|
*
|
|
* @returns
|
|
*
|
|
* Returns the object reference count.
|
|
*
|
|
* @xref OLE documentation for <mf IUnknown::Release>.
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @method HRESULT | IClassFactory | QIHelper |
|
|
*
|
|
* We don't have any dynamic interfaces and simply forward
|
|
* to <f Common_QIHelper>.
|
|
*
|
|
* @parm IN REFIID | riid |
|
|
*
|
|
* The requested interface's IID.
|
|
*
|
|
* @parm OUT LPVOID * | ppvObj |
|
|
*
|
|
* Receives a pointer to the obtained interface.
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func HRESULT | IClassFactory_AppFinalize |
|
|
*
|
|
* We don't have any weak pointers, so we can just
|
|
* forward to <f Common_Finalize>.
|
|
*
|
|
* @parm PV | pvObj |
|
|
*
|
|
* Object being released from the application's perspective.
|
|
*
|
|
*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func HRESULT | IClassFactory_Finalize |
|
|
*
|
|
* We don't have any instance data, so we can just
|
|
* forward to <f Common_Finalize>.
|
|
*
|
|
* @parm PV | pvObj |
|
|
*
|
|
* Object being released.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#ifdef DEBUG
|
|
|
|
Default_QueryInterface(CDIFactory)
|
|
Default_AddRef(CDIFactory)
|
|
Default_Release(CDIFactory)
|
|
|
|
#else
|
|
|
|
#define CDIFactory_QueryInterface Common_QueryInterface
|
|
#define CDIFactory_AddRef Common_AddRef
|
|
#define CDIFactory_Release Common_Release
|
|
|
|
#endif
|
|
|
|
#define CDIFactory_QIHelper Common_QIHelper
|
|
#define CDIFactory_AppFinalize Common_AppFinalize
|
|
#define CDIFactory_Finalize Common_Finalize
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc EXTERNAL
|
|
*
|
|
* @method HRESULT | IClassFactory | CreateInstance |
|
|
*
|
|
* This function creates a new DirectInput object with
|
|
* the specified interface.
|
|
*
|
|
* @cwrap LPCLASSFACTORY | lpClassFactory
|
|
*
|
|
* @parm IN LPUNKNOWN | punkOuter | Pointer to controlling unknown.
|
|
* Aggregation is not supported in this version of DirectInput,
|
|
* so the value "should" be 0.
|
|
*
|
|
* @parm IN REFIID | riid |
|
|
* Desired interface. This parameter "must" point to a valid
|
|
* interface identifier.
|
|
*
|
|
* @parm OUT LPVOID * | ppvOut |
|
|
* Points to where to return the pointer to the created interface,
|
|
* if successful.
|
|
*
|
|
* @returns
|
|
*
|
|
* Returns a COM error code. The following error codes are
|
|
* intended to be illustrative and not necessarily comprehensive.
|
|
*
|
|
* <c S_OK>: The operation completed successfully.
|
|
*
|
|
* <c E_INVALIDARG>: The
|
|
* <p ppvOut> parameter is not a valid pointer.
|
|
*
|
|
* <c CLASS_E_NOAGGREGATION>:
|
|
* Aggregation not supported.
|
|
*
|
|
* <c E_OUTOFMEMORY>:
|
|
* Out of memory.
|
|
*
|
|
* <c E_NOINTERFACE>:
|
|
* The specified interface is not supported.
|
|
*
|
|
* @xref OLE documentation for <mf IClassFactory::CreateInstance>.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
CDIFactory_CreateInstance(PCF pcf, PUNK punkOuter, RIID riid, PPV ppvObj)
|
|
{
|
|
HRESULT hres;
|
|
EnterProcR(IClassFactory::CreateInstance,
|
|
(_ "ppGp", pcf, punkOuter, riid, ppvObj));
|
|
|
|
if (SUCCEEDED(hres = hresPv(pcf))) {
|
|
PDCF this;
|
|
if (Num_Interfaces(CDIFactory) == 1) {
|
|
this = _thisPvNm(pcf, cf);
|
|
} else {
|
|
this = _thisPv(pcf);
|
|
}
|
|
|
|
/*
|
|
* All parameters will be validated by pfnCreate.
|
|
*/
|
|
hres = this->pfnCreate(punkOuter, riid, ppvObj);
|
|
}
|
|
|
|
ExitOleProcPpvR(ppvObj);
|
|
return hres;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc EXTERNAL
|
|
*
|
|
* @method HRESULT | IClassFactory | LockServer |
|
|
*
|
|
* This function increments or decrements the DLL lock
|
|
* count. While the DLL lock count is nonzero,
|
|
* it will not be removed from memory.
|
|
*
|
|
* @cwrap LPCLASSFACTORY | lpClassFactory
|
|
*
|
|
* @parm BOOL | fLock |
|
|
* If <c TRUE>, increments the lock count.
|
|
* If <c FALSE>, decrements the lock count.
|
|
*
|
|
* @returns
|
|
* Returns a COM error code. The following error codes are
|
|
* intended to be illustrative and not necessarily comprehensive.
|
|
*
|
|
* <c S_OK>: The operation completed successfully.
|
|
*
|
|
* <c E_OUTOFMEMORY>: Out of memory.
|
|
*
|
|
* @xref OLE documentation for <mf IClassFactory::LockServer>.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
CDIFactory_LockServer(PCF pcf, BOOL fLock)
|
|
{
|
|
HRESULT hres;
|
|
EnterProcR(IClassFactory::LockServer, (_ "px", pcf, fLock));
|
|
|
|
if (SUCCEEDED(hres = hresPv(pcf))) {
|
|
if (fLock) {
|
|
DllAddRef();
|
|
} else {
|
|
DllRelease();
|
|
}
|
|
}
|
|
|
|
ExitOleProc();
|
|
return hres;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @mfunc HRESULT | IClassFactory | New |
|
|
*
|
|
* Create a new instance of the class factory.
|
|
*
|
|
* @parm IN PUNK | punkOuter |
|
|
*
|
|
* Controlling unknown for aggregation.
|
|
*
|
|
* @parm IN RIID | riid |
|
|
* Desired interface to new object.
|
|
*
|
|
* @parm OUT PPV | ppvObj |
|
|
* Output pointer for new object.
|
|
*
|
|
* @returns
|
|
*
|
|
* Standard OLE <t HRESULT>.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
CDIFactory_New(CREATEFUNC pfnCreate, RIID riid, PPV ppvObj)
|
|
{
|
|
HRESULT hres;
|
|
EnterProcR(IClassFactory::<constructor>, (_ "G", riid));
|
|
|
|
hres = Common_NewRiid(CDIFactory, 0, riid, ppvObj);
|
|
|
|
if (SUCCEEDED(hres)) {
|
|
PDCF this;
|
|
if (Num_Interfaces(CDIFactory) == 1) {
|
|
/* We can go directly in because we cannot be aggregated */
|
|
this = *ppvObj;
|
|
} else {
|
|
this = _thisPv(*ppvObj);
|
|
}
|
|
|
|
this->pfnCreate = pfnCreate;
|
|
}
|
|
|
|
ExitOleProcPpvR(ppvObj);
|
|
return hres;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* The long-awaited vtbl.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#pragma BEGIN_CONST_DATA
|
|
#define CDIFactory_Signature 0x20204643 /* "CF " */
|
|
|
|
Primary_Interface_Begin(CDIFactory, IClassFactory)
|
|
CDIFactory_CreateInstance,
|
|
CDIFactory_LockServer,
|
|
Primary_Interface_End(CDIFactory, IClassFactory)
|