windows-nt/Source/XPSP1/NT/multimedia/directx/dinput/dx8/dll/dimapshp.c
2020-09-26 16:20:57 +08:00

458 lines
11 KiB
C

/*****************************************************************************
*
* dimapshp.c
*
* Copyright (c) 1997 Microsoft Corporation. All Rights Reserved.
*
* Abstract:
*
* The IDirectInputMapperW shepherd.
*
* The shepherd does the annoying work of babysitting the
* IDirectInputMapperW.
*
* It makes sure nobody parties on bad handles.
*
* It handles cross-process (or even intra-process) effect
* management.
*
* Contents:
*
* CMapShep_New
*
*****************************************************************************/
#include "dinputpr.h"
#ifdef UNICODE
#undef _UNICODE
#define _UNICODE
#endif // !UNICODE
/*****************************************************************************
*
* The sqiffle for this file.
*
*****************************************************************************/
#define sqfl sqflEShep/*Should we use own area?*/
#pragma BEGIN_CONST_DATA
/*****************************************************************************
*
* Declare the interfaces we will be providing.
*
*****************************************************************************/
Primary_Interface(CMapShep, IDirectInputMapShepherd);
/*****************************************************************************
*
* @doc INTERNAL
*
* @struct CMapShep |
*
* The <i IDirectInputMapShepherd> object, which
* babysits an <i IDirectInputMapperW>.
*
* @field IDirectInputMapShepherd | dms |
*
* DirectInputMapShepherd object (containing vtbl).
*
* @field IDirectInputMapperW * | pdimap |
*
* Delegated mapper interface.
*
* @field HINSTANCE | hinstdimapdll |
*
* The instance handle of the DLL that contains the mapper.
*
*****************************************************************************/
typedef struct CMapShep {
/* Supported interfaces */
IDirectInputMapShepherd dms;
IDirectInputMapperW* pdimap;
HINSTANCE hinstdimapdll;
} CMapShep, MS, *PMS;
typedef IDirectInputMapShepherd DMS, *PDMS;
#define ThisClass CMapShep
#define ThisInterface IDirectInputMapShepherd
/*****************************************************************************
*
* @doc EXTERNAL
*
* @method HRESULT | IDirectInputMapShepherd | QueryInterface |
*
* Gives a client access to other interfaces on an object.
*
* @cwrap LPDIRECTINPUT | lpDirectInput
*
* @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 | IDirectInputMapShepherd | AddRef |
*
* Increments the reference count for the interface.
*
* @cwrap LPDIRECTINPUT | lpDirectInput
*
* @returns
*
* Returns the object reference count.
*
* @xref OLE documentation for <mf IUnknown::AddRef>.
*
*****************************************************************************
*
* @doc EXTERNAL
*
* @method HRESULT | IDirectInputMapShepherd | 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 LPDIRECTINPUT | lpDirectInput
*
* @returns
*
* Returns the object reference count.
*
* @xref OLE documentation for <mf IUnknown::Release>.
*
*//**************************************************************************
*
* @doc INTERNAL
*
* @method HRESULT | IDirectInputMapShepherd | 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
*
* @method HRESULT | IDirectInputMapShepherd | 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.
*
*****************************************************************************/
#ifdef DEBUG
Default_QueryInterface(CMapShep)
Default_AddRef(CMapShep)
Default_Release(CMapShep)
#else
#define CMapShep_QueryInterface Common_QueryInterface
#define CMapShep_AddRef Common_AddRef
#define CMapShep_Release Common_Release
#endif
#define CMapShep_QIHelper Common_QIHelper
#define CMapShep_AppFinalize Common_AppFinalize
/*****************************************************************************
*
* @doc INTERNAL
*
* @func void | CMapShep_Finalize |
*
* Clean up our instance data.
*
* @parm PV | pvObj |
*
* Object being released. Note that it may not have been
* completely initialized, so everything should be done
* carefully.
*
*****************************************************************************/
void INTERNAL
CMapShep_Finalize(PV pvObj)
{
PMS this = pvObj;
Invoke_Release(&this->pdimap);
if( this->hinstdimapdll)
{
FreeLibrary(this->hinstdimapdll);
this->hinstdimapdll = NULL;
}
}
/*****************************************************************************
* ForceUnload
*****************************************************************************/
void INTERNAL
CMapShep_ForceUnload(PV pvObj)/**why are this two functions same??????**/
{
PMS this = pvObj;
Invoke_Release(&this->pdimap);
if( this->hinstdimapdll)
{
FreeLibrary(this->hinstdimapdll);
this->hinstdimapdll = NULL;
}
}
/*****************************************************************************
* InitDll
*****************************************************************************/
HRESULT INTERNAL
CMapShep_InitDll(PMS this,REFGUID lpDeviceGUID,LPCWSTR lpcwstrFileName)
{
//do _CreateInstance()
HRESULT hres = S_OK;
if (this->hinstdimapdll == NULL)
{
hres = _CreateInstance(&IID_IDirectInputMapClsFact/*should be CLSID_CDIMap*/,
TEXT("dimap.dll"), NULL, &IID_IDirectInputMapIW,
(LPVOID*) & this->pdimap, &this->hinstdimapdll);
if (SUCCEEDED(hres) && this->pdimap != NULL)
{
hres = this->pdimap->lpVtbl->Initialize(this->pdimap,
lpDeviceGUID, lpcwstrFileName, 0);
if(!SUCCEEDED(hres))
CMapShep_Finalize(this);
}
}
return hres;
}
/*****************************************************************************
* GetActionMap
*****************************************************************************/
STDMETHODIMP
CMapShep_GetActionMapW
(
PDMS pdms,
REFGUID lpDeviceGUID,
LPCWSTR lpcwstrFileName,
LPDIACTIONFORMATW lpDIActionFormat,
LPCWSTR lpcwstrUserName,
LPFILETIME lpFileTime,
DWORD dwFlags
)
{
PMS this;
HRESULT hres = S_OK;
EnterProcI(IDirectInputMapShepherd::GetActionMapW, (_ "p", pdms));
this = _thisPvNm(pdms, dms);
if (!this->hinstdimapdll)
{
hres = CMapShep_InitDll(this, lpDeviceGUID, lpcwstrFileName);
}
//call the fn
if (SUCCEEDED(hres) && this->pdimap != NULL)
{
hres = this->pdimap->lpVtbl->GetActionMap(this->pdimap,
lpDIActionFormat, lpcwstrUserName, lpFileTime, dwFlags );
}
ExitOleProcR();
return hres;
}
/*****************************************************************************
* SaveActionMap
*****************************************************************************/
STDMETHODIMP
CMapShep_SaveActionMapW
(
PDMS pdms,
REFGUID lpDeviceGUID,
LPCWSTR lpcwstrFileName,
LPDIACTIONFORMATW lpDIActionFormat,
LPCWSTR lpcwstrUserName,
DWORD dwFlags)
{
PMS this;
HRESULT hres = S_OK;
EnterProcI(IDirectInputMapShepherd::SaveActionMapW, (_ "p", pdms));
this = _thisPvNm(pdms, dms);
if (!this->hinstdimapdll)
{
hres = CMapShep_InitDll(this, lpDeviceGUID, lpcwstrFileName);
}
//call the fn
if (SUCCEEDED(hres) && this->pdimap != NULL)
{
hres = this->pdimap->lpVtbl->SaveActionMap(this->pdimap,
lpDIActionFormat, lpcwstrUserName, dwFlags );
}
// CMapShep_Finalize(this);
ExitOleProcR();
return hres;
}
/*****************************************************************************
* GetImageInfo
*****************************************************************************/
STDMETHODIMP
CMapShep_GetImageInfoW
(
PDMS pdms,
REFGUID lpDeviceGUID,
LPCWSTR lpcwstrFileName,
LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader
)
{
PMS this;
HRESULT hres = S_OK;
EnterProcI(IDirectInputMapShepherd::GetImageInfoW, (_ "p", pdms));
this = _thisPvNm(pdms, dms);
if (!this->hinstdimapdll)
{
hres = CMapShep_InitDll(this, lpDeviceGUID, lpcwstrFileName);
}
//call the fn
if (SUCCEEDED(hres) && this->pdimap != NULL)
{
hres = this->pdimap->lpVtbl->GetImageInfo(this->pdimap,
lpdiDevImageInfoHeader );
}
ExitOleProcR();
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @method HRESULT | IDirectInputMapShepherd | New |
*
* Create a new instance of an IDirectInputMapShepherd object.
*
* @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
CMapShep_New(PUNK punkOuter, RIID riid, PPV ppvObj)
{
HRESULT hres;
EnterProcR(IDirectInputMapShepherd::<constructor>, (_ "G", riid));
hres = Common_NewRiid(CMapShep, punkOuter, riid, ppvObj);
if (SUCCEEDED(hres)) {
/* Must use _thisPv in case of aggregation */
PMS this = _thisPv(*ppvObj);
this->hinstdimapdll = NULL;
/* In case of mapper we do this inside each method...
if (SUCCEEDED(hres = CMap_InitDll(this))) {
} else {
Invoke_Release(ppvObj);
}*/
}
ExitOleProcPpvR(ppvObj);
return hres;
}
/*****************************************************************************
*
* The long-awaited vtbls and templates
*
*****************************************************************************/
#pragma BEGIN_CONST_DATA
//#define CEShep_Signature 0x50454853 /* "SHEP" */
Interface_Template_Begin(CMapShep)
Primary_Interface_Template(CMapShep, IDirectInputMapShepherd)
Interface_Template_End(CMapShep)
Primary_Interface_Begin(CMapShep, IDirectInputMapShepherd)
CMapShep_GetActionMapW,
CMapShep_SaveActionMapW,
CMapShep_GetImageInfoW,
Primary_Interface_End(CMapShep, IDirectInputMapShepherd)