Windows2003-3790/windows/appcompat/shims/general/forcedirectdrawwait.cpp
2020-09-30 16:53:55 +02:00

352 lines
7.4 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
ForceDirectDrawWait.cpp
Abstract:
Some applications don't specify the DD_WAIT flag to
IDirectDrawSurface::Lock, which means that if it fails because the device
is busy, the app can fail. This could also happen on Win9x of course, but
was more difficult to repro.
Note that we don't need to do this on the IDirectDraw7 interface since the
default is DDLOCK_WAIT, unless DDLOCK_DONOTWAIT is specified.
Notes:
This is a general purpose shim.
History:
03/04/2000 linstev Created
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(ForceDirectDrawWait)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY_DIRECTX_COMSERVER()
APIHOOK_ENUM_END
IMPLEMENT_DIRECTX_COMSERVER_HOOKS()
/*++
Hook create surface so we can be sure we're being called.
--*/
HRESULT
COMHOOK(IDirectDraw, CreateSurface)(
PVOID pThis,
LPDDSURFACEDESC lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
IUnknown* pUnkOuter
)
{
HRESULT hReturn;
_pfn_IDirectDraw_CreateSurface pfnOld =
ORIGINAL_COM(IDirectDraw, CreateSurface, pThis);
if (SUCCEEDED(hReturn = (*pfnOld)(
pThis,
lpDDSurfaceDesc,
lplpDDSurface,
pUnkOuter)))
{
HookObject(
NULL,
IID_IDirectDrawSurface,
(PVOID*)lplpDDSurface,
NULL,
FALSE);
}
return hReturn;
}
/*++
Hook create surface so we can be sure we're being called.
--*/
HRESULT
COMHOOK(IDirectDraw2, CreateSurface)(
PVOID pThis,
LPDDSURFACEDESC lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
IUnknown* pUnkOuter
)
{
HRESULT hReturn;
_pfn_IDirectDraw2_CreateSurface pfnOld =
ORIGINAL_COM(IDirectDraw2, CreateSurface, pThis);
if (SUCCEEDED(hReturn = (*pfnOld)(
pThis,
lpDDSurfaceDesc,
lplpDDSurface,
pUnkOuter)))
{
HookObject(
NULL,
IID_IDirectDrawSurface2,
(PVOID*)lplpDDSurface,
NULL,
FALSE);
}
return hReturn;
}
/*++
Hook create surface so we can be sure we're being called.
--*/
HRESULT
COMHOOK(IDirectDraw4, CreateSurface)(
PVOID pThis,
LPDDSURFACEDESC2 lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
IUnknown* pUnkOuter
)
{
HRESULT hReturn;
_pfn_IDirectDraw4_CreateSurface pfnOld =
ORIGINAL_COM(IDirectDraw4, CreateSurface, pThis);
if (SUCCEEDED(hReturn = (*pfnOld)(
pThis,
lpDDSurfaceDesc,
lplpDDSurface,
pUnkOuter)))
{
HookObject(
NULL,
IID_IDirectDrawSurface4,
(PVOID*)lplpDDSurface,
NULL,
FALSE);
}
return hReturn;
}
/*++
Make sure we add DDBLT_WAIT.
--*/
HRESULT
COMHOOK(IDirectDrawSurface, Blt)(
LPDIRECTDRAWSURFACE lpDDDestSurface,
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
LPRECT lpSrcRect,
DWORD dwFlags,
LPDDBLTFX lpDDBltFX
)
{
dwFlags &= ~DDBLT_DONOTWAIT;
dwFlags |= DDBLT_WAIT;
// Original Blt
_pfn_IDirectDrawSurface_Blt pfnOld = ORIGINAL_COM(
IDirectDrawSurface,
Blt,
lpDDDestSurface);
return (*pfnOld)(
lpDDDestSurface,
lpDestRect,
lpDDSrcSurface,
lpSrcRect,
dwFlags,
lpDDBltFX);
}
HRESULT
COMHOOK(IDirectDrawSurface2, Blt)(
LPDIRECTDRAWSURFACE lpDDDestSurface,
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
LPRECT lpSrcRect,
DWORD dwFlags,
LPDDBLTFX lpDDBltFX
)
{
dwFlags &= ~DDBLT_DONOTWAIT;
dwFlags |= DDBLT_WAIT;
// Original Blt
_pfn_IDirectDrawSurface_Blt pfnOld = ORIGINAL_COM(
IDirectDrawSurface2,
Blt,
lpDDDestSurface);
return (*pfnOld)(
lpDDDestSurface,
lpDestRect,
lpDDSrcSurface,
lpSrcRect,
dwFlags,
lpDDBltFX);
}
HRESULT
COMHOOK(IDirectDrawSurface4, Blt)(
LPDIRECTDRAWSURFACE lpDDDestSurface,
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
LPRECT lpSrcRect,
DWORD dwFlags,
LPDDBLTFX lpDDBltFX
)
{
dwFlags &= ~DDBLT_DONOTWAIT;
dwFlags |= DDBLT_WAIT;
// Original Blt
_pfn_IDirectDrawSurface_Blt pfnOld = ORIGINAL_COM(
IDirectDrawSurface4,
Blt,
lpDDDestSurface);
return (*pfnOld)(
lpDDDestSurface,
lpDestRect,
lpDDSrcSurface,
lpSrcRect,
dwFlags,
lpDDBltFX);
}
/*++
Make sure we add DDLOCK_WAIT.
--*/
HRESULT
COMHOOK(IDirectDrawSurface, Lock)(
LPDIRECTDRAWSURFACE lpDDSurface,
LPRECT lpDestRect,
LPDDSURFACEDESC lpDDSurfaceDesc,
DWORD dwFlags,
HANDLE hEvent
)
{
dwFlags &= ~DDLOCK_DONOTWAIT;
dwFlags |= DDLOCK_WAIT;
// Retrieve the old function
_pfn_IDirectDrawSurface_Lock pfnOld = ORIGINAL_COM(
IDirectDrawSurface,
Lock,
lpDDSurface);
// Call the old API
return (*pfnOld)(
lpDDSurface,
lpDestRect,
lpDDSurfaceDesc,
dwFlags,
hEvent);
}
HRESULT
COMHOOK(IDirectDrawSurface2, Lock)(
LPDIRECTDRAWSURFACE lpDDSurface,
LPRECT lpDestRect,
LPDDSURFACEDESC lpDDSurfaceDesc,
DWORD dwFlags,
HANDLE hEvent
)
{
dwFlags &= ~DDLOCK_DONOTWAIT;
dwFlags |= DDLOCK_WAIT;
// Retrieve the old function
_pfn_IDirectDrawSurface_Lock pfnOld = ORIGINAL_COM(
IDirectDrawSurface2,
Lock,
lpDDSurface);
// Call the old API
return (*pfnOld)(
lpDDSurface,
lpDestRect,
lpDDSurfaceDesc,
dwFlags,
hEvent);
}
HRESULT
COMHOOK(IDirectDrawSurface4, Lock)(
LPDIRECTDRAWSURFACE lpDDSurface,
LPRECT lpDestRect,
LPDDSURFACEDESC lpDDSurfaceDesc,
DWORD dwFlags,
HANDLE hEvent
)
{
dwFlags &= ~DDLOCK_DONOTWAIT;
dwFlags |= DDLOCK_WAIT;
// Retrieve the old function
_pfn_IDirectDrawSurface_Lock pfnOld = ORIGINAL_COM(
IDirectDrawSurface4,
Lock,
lpDDSurface);
// Call the old API
return (*pfnOld)(
lpDDSurface,
lpDestRect,
lpDDSurfaceDesc,
dwFlags,
hEvent);
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY_DIRECTX_COMSERVER()
COMHOOK_ENTRY(DirectDraw, IDirectDraw, CreateSurface, 6)
COMHOOK_ENTRY(DirectDraw, IDirectDraw2, CreateSurface, 6)
COMHOOK_ENTRY(DirectDraw, IDirectDraw4, CreateSurface, 6)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface, Blt, 5)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface2, Blt, 5)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface4, Blt, 5)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface, Lock, 25)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface2, Lock, 25)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface4, Lock, 25)
HOOK_END
IMPLEMENT_SHIM_END