From 10daaf90a6a85bf84f6bc276e3de7d201902f0d6 Mon Sep 17 00:00:00 2001 From: Gregor Brunmar Date: Sun, 24 Aug 2008 11:18:30 +0000 Subject: [PATCH] D3D9: * Implemented IDirect3DSwapChain9::GetDevice() and GetPresentParameters() * Added helper function to D3D9BaseObject to convert IUnknown* to IDirect3D9Device* * Fixed behavior in IDirect3DDevice9::GetSwapChain() when an invalid index was specified svn path=/trunk/; revision=35594 --- reactos/dll/directx/d3d9/d3d9_baseobject.c | 10 +++ reactos/dll/directx/d3d9/d3d9_baseobject.h | 4 ++ reactos/dll/directx/d3d9/d3d9_device.c | 10 +-- reactos/dll/directx/d3d9/d3d9_swapchain.c | 75 +++++++++++++++++++++- reactos/dll/directx/d3d9/d3d9_swapchain.h | 2 + 5 files changed, 95 insertions(+), 6 deletions(-) diff --git a/reactos/dll/directx/d3d9/d3d9_baseobject.c b/reactos/dll/directx/d3d9/d3d9_baseobject.c index 3064b561d6b..aef859673df 100644 --- a/reactos/dll/directx/d3d9/d3d9_baseobject.c +++ b/reactos/dll/directx/d3d9/d3d9_baseobject.c @@ -61,3 +61,13 @@ ULONG D3D9BaseObject_Release(D3D9BaseObject* pBaseObject) return Ref; } + +HRESULT D3D9BaseObject_GetDevice(D3D9BaseObject* pBaseObject, IDirect3DDevice9** ppDevice) +{ + if (pBaseObject->pUnknown) + { + return pBaseObject->pUnknown->lpVtbl->QueryInterface((IUnknown*) &pBaseObject->pUnknown->lpVtbl, &IID_IDirect3DDevice9, (void**)ppDevice); + } + + return E_NOINTERFACE; +} diff --git a/reactos/dll/directx/d3d9/d3d9_baseobject.h b/reactos/dll/directx/d3d9/d3d9_baseobject.h index 3b87b44b538..73bfbab06b3 100644 --- a/reactos/dll/directx/d3d9/d3d9_baseobject.h +++ b/reactos/dll/directx/d3d9/d3d9_baseobject.h @@ -9,6 +9,9 @@ #define _D3D9_BASEOBJECT_H_ #include "d3d9_common.h" +#include + +struct _D3D9BaseObject; enum REF_TYPE { @@ -38,5 +41,6 @@ VOID InitD3D9BaseObject(D3D9BaseObject* pBaseObject, enum REF_TYPE RefType, IUnk ULONG D3D9BaseObject_AddRef(D3D9BaseObject* pBaseObject); ULONG D3D9BaseObject_Release(D3D9BaseObject* pBaseObject); +HRESULT D3D9BaseObject_GetDevice(D3D9BaseObject* pBaseObject, IDirect3DDevice9** ppDevice); #endif // _D3D9_BASEOBJECT_H_ diff --git a/reactos/dll/directx/d3d9/d3d9_device.c b/reactos/dll/directx/d3d9/d3d9_device.c index b9153135c47..376658eedbb 100644 --- a/reactos/dll/directx/d3d9/d3d9_device.c +++ b/reactos/dll/directx/d3d9/d3d9_device.c @@ -341,16 +341,18 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9 iface, LPDIRECT3DDEVICE9_INT This = impl_from_IDirect3DDevice9(iface); LOCK_D3DDEVICE9(); - if (iSwapChain >= IDirect3DDevice9_GetNumberOfSwapChains(iface)) + if (IsBadWritePtr(ppSwapChain, sizeof(IDirect3DSwapChain9*))) { - DPRINT1("Invalid iSwapChain parameter specified"); + DPRINT1("Invalid ppSwapChain parameter specified"); UNLOCK_D3DDEVICE9(); return D3DERR_INVALIDCALL; } - if (IsBadWritePtr(ppSwapChain, sizeof(IDirect3DSwapChain9*))) + *ppSwapChain = NULL; + + if (iSwapChain >= IDirect3DDevice9_GetNumberOfSwapChains(iface)) { - DPRINT1("Invalid ppSwapChain parameter specified"); + DPRINT1("Invalid iSwapChain parameter specified"); UNLOCK_D3DDEVICE9(); return D3DERR_INVALIDCALL; } diff --git a/reactos/dll/directx/d3d9/d3d9_swapchain.c b/reactos/dll/directx/d3d9/d3d9_swapchain.c index 363485a43b1..661d6ed36f4 100644 --- a/reactos/dll/directx/d3d9/d3d9_swapchain.c +++ b/reactos/dll/directx/d3d9/d3d9_swapchain.c @@ -13,6 +13,11 @@ #include "d3d9_helpers.h" #include "d3d9_device.h" +#define LOCK_D3DDEVICE9() if (This->BaseObject.pUnknown && ((LPDIRECT3DDEVICE9_INT)This->BaseObject.pUnknown)->bLockDevice) \ + EnterCriticalSection(&((LPDIRECT3DDEVICE9_INT)This->BaseObject.pUnknown)->CriticalSection); +#define UNLOCK_D3DDEVICE9() if (This->BaseObject.pUnknown && ((LPDIRECT3DDEVICE9_INT)This->BaseObject.pUnknown)->bLockDevice) \ + LeaveCriticalSection(&((LPDIRECT3DDEVICE9_INT)This->BaseObject.pUnknown)->CriticalSection); + /* Convert a IDirect3DSwapChain9 pointer safely to the internal implementation struct */ static LPDIRECT3DSWAPCHAIN9_INT IDirect3DSwapChain9ToImpl(LPDIRECT3DSWAPCHAIN9 iface) { @@ -81,15 +86,81 @@ static HRESULT WINAPI Direct3DSwapChain9_GetDisplayMode(LPDIRECT3DSWAPCHAIN9 ifa return D3D_OK; } +/*++ +* @name IDirect3DSwapChain9::GetDevice +* @implemented +* +* The function Direct3DSwapChain9_GetDevice sets the ppDevice argument +* to the device connected to create the swap chain. +* +* @param LPDIRECT3DSWAPCHAIN9 iface +* Pointer to a IDirect3DSwapChain9 object returned from IDirect3D9Device::GetSwapChain() +* +* @param IDirect3DDevice9** ppDevice +* Pointer to a IDirect3DDevice9* structure to be set to the device object. +* +* @return HRESULT +* If the method successfully sets the ppDevice value, the return value is D3D_OK. +* If ppDevice is a bad pointer the return value will be D3DERR_INVALIDCALL. +* If the swap chain didn't contain any device, the return value will be D3DERR_INVALIDDEVICE. +* +*/ static HRESULT WINAPI Direct3DSwapChain9_GetDevice(LPDIRECT3DSWAPCHAIN9 iface, IDirect3DDevice9** ppDevice) { - UNIMPLEMENTED + LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface); + LOCK_D3DDEVICE9(); + + if (IsBadWritePtr(ppDevice, sizeof(IDirect3DDevice9**))) + { + DPRINT1("Invalid ppDevice parameter specified"); + UNLOCK_D3DDEVICE9(); + return D3DERR_INVALIDCALL; + } + + if (FAILED(D3D9BaseObject_GetDevice(&This->BaseObject, ppDevice))) + { + DPRINT1("Invalid This parameter speficied"); + UNLOCK_D3DDEVICE9(); + return D3DERR_INVALIDDEVICE; + } + + UNLOCK_D3DDEVICE9(); return D3D_OK; } +/*++ +* @name IDirect3DSwapChain9::GetPresentParameters +* @implemented +* +* The function Direct3DSwapChain9_GetPresentParameters fills the pPresentationParameters +* argument with the D3DPRESENT_PARAMETERS parameters that was used to create the swap chain. +* +* @param LPDIRECT3DSWAPCHAIN9 iface +* Pointer to a IDirect3DSwapChain9 object returned from IDirect3D9Device::GetSwapChain() +* +* @param D3DPRESENT_PARAMETERS* pPresentationParameters +* Pointer to a D3DPRESENT_PARAMETERS structure to be filled with the creation parameters. +* +* @return HRESULT +* If the method successfully fills the pPresentationParameters structure, the return value is D3D_OK. +* If pPresentationParameters is a bad pointer the return value will be D3DERR_INVALIDCALL. +* +*/ static HRESULT WINAPI Direct3DSwapChain9_GetPresentParameters(LPDIRECT3DSWAPCHAIN9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters) { - UNIMPLEMENTED + LPDIRECT3DSWAPCHAIN9_INT This = IDirect3DSwapChain9ToImpl(iface); + LOCK_D3DDEVICE9(); + + if (IsBadWritePtr(pPresentationParameters, sizeof(D3DPRESENT_PARAMETERS))) + { + DPRINT1("Invalid pPresentationParameters parameter specified"); + UNLOCK_D3DDEVICE9(); + return D3DERR_INVALIDCALL; + } + + *pPresentationParameters = This->PresentParameters; + + UNLOCK_D3DDEVICE9(); return D3D_OK; } diff --git a/reactos/dll/directx/d3d9/d3d9_swapchain.h b/reactos/dll/directx/d3d9/d3d9_swapchain.h index 1fa23b14df9..4a2de2210c8 100644 --- a/reactos/dll/directx/d3d9/d3d9_swapchain.h +++ b/reactos/dll/directx/d3d9/d3d9_swapchain.h @@ -13,6 +13,8 @@ #include #include "d3d9_baseobject.h" +struct _Direct3DDevice9_INT; + typedef struct _Direct3DSwapChain9_INT { /* 0x0000 */ D3D9BaseObject BaseObject;