|
|
/******************************Module*Header*******************************\
* Module Name: watchdog.cxx * * * * Copyright (c) 1990-2002 Microsoft Corporation * * * * This module hooks the display drivers "Drv" entry points. It will * * enter/exit the watchdog appropriately, and set up try/except blocks to * * catch threads that get stuck in a driver. * * * * Erick Smith - ericks - * \**************************************************************************/
#include "precomp.hxx"
#include "muclean.hxx"
#define MAKESOFTWAREEXCEPTION(Severity, Facility, Exception) \
((DWORD) ((Severity << 30) | (1 << 29) | (Facility << 16) | (Exception)))
#define SE_THREAD_STUCK MAKESOFTWAREEXCEPTION(3,0,1)
#define RECOVERY_SECTION_BEGIN(pldev) __try
#define RECOVERY_SECTION_END(pldev) \
__except(GetExceptionCode() == SE_THREAD_STUCK) { \ HandleStuckThreadException(pldev); \ }
//
// Context Nodes are used for DX. DdContextCreate and DdContextDestroy
// create contexts that are later passed to other DX functions such as
// DrawPrimitives2 or SetTextureStageState. Since we need to be able
// to take the context and retrieve the original pldev, we create this
// new structure to help in the association.
//
typedef struct _CONTEXT_NODE { PVOID Context; PDHPDEV_ASSOCIATION_NODE ppdevData; } CONTEXT_NODE, *PCONTEXT_NODE;
PDHPDEV_ASSOCIATION_NODE gdhpdevAssociationList = NULL; PDHSURF_ASSOCIATION_NODE gdhsurfAssociationList = NULL;
//
// The following routines are used to maintain an association between the
// data actually passed into a driver entry point, and a data structure
// used to look up the actual entry point into the driver.
//
// For example, when the system call the DrvEnablePDEV entry point, the
// driver will create it's own PDEV structure. We will create an
// association node to associate this driver created PDEV with the LDEV for
// that driver. Now on subsequent calls into the driver, we can retrieve
// the PDEV via various methods, and then use that to find the LDEV. Once we
// have the LDEV we can look up the correct entry point into the driver.
//
// GDI entry points are global accross all pdev's. However, it is possible
// that a driver may return seperate DX entry points to different pdevs. For
// example this could happen if a driver returned on set of entry points when
// the pdev is in portrait mode, and another set when in landscape mode.
//
// We also store a list of DHSURF's and the association with the LDEV.
//
PDHPDEV_ASSOCIATION_NODE dhpdevAssociationCreateNode( VOID )
{ PDHPDEV_ASSOCIATION_NODE Node; Node = (PDHPDEV_ASSOCIATION_NODE) PALLOCMEM(sizeof(DHPDEV_ASSOCIATION_NODE), GDITAG_DRVSUP); return Node; }
PDHSURF_ASSOCIATION_NODE dhsurfAssociationCreateNode( VOID )
{ PDHSURF_ASSOCIATION_NODE Node; Node = (PDHSURF_ASSOCIATION_NODE) PALLOCMEM(sizeof(DHSURF_ASSOCIATION_NODE), GDITAG_DRVSUP); return Node; }
VOID AssociationDeleteNode( PVOID Node )
{ if (Node) { VFREEMEM(Node); } }
VOID dhpdevAssociationInsertNode( PDHPDEV_ASSOCIATION_NODE Node )
{ GreAcquireFastMutex(gAssociationListMutex);
Node->next = gdhpdevAssociationList; gdhpdevAssociationList = Node;
GreReleaseFastMutex(gAssociationListMutex); }
VOID dhsurfAssociationInsertNode( PDHSURF_ASSOCIATION_NODE Node )
{ GreAcquireFastMutex(gAssociationListMutex);
Node->next = gdhsurfAssociationList; gdhsurfAssociationList = Node;
GreReleaseFastMutex(gAssociationListMutex); }
PDHPDEV_ASSOCIATION_NODE dhpdevAssociationRemoveNode( DHPDEV dhpdev )
{ PDHPDEV_ASSOCIATION_NODE Node;
GreAcquireFastMutex(gAssociationListMutex);
//
// first find the correct node
//
Node = gdhpdevAssociationList;
while (Node && (Node->dhpdev != dhpdev)) { Node = Node->next; }
if (Node) {
if (gdhpdevAssociationList == Node) {
gdhpdevAssociationList = Node->next;
} else {
PDHPDEV_ASSOCIATION_NODE curr = gdhpdevAssociationList;
while (curr && (curr->next != Node)) { curr = curr->next; }
if (curr) { curr->next = Node->next; } } }
GreReleaseFastMutex(gAssociationListMutex);
return Node; }
PDHSURF_ASSOCIATION_NODE dhsurfAssociationRemoveNode( DHSURF dhsurf )
{ PDHSURF_ASSOCIATION_NODE Node;
GreAcquireFastMutex(gAssociationListMutex);
//
// first find the correct node
//
Node = gdhsurfAssociationList;
while (Node && (Node->dhsurf != dhsurf)) { Node = Node->next; }
if (Node) {
if (gdhsurfAssociationList == Node) {
gdhsurfAssociationList = Node->next;
} else {
PDHSURF_ASSOCIATION_NODE curr = gdhsurfAssociationList;
while (curr && (curr->next != Node)) { curr = curr->next; }
if (curr) { curr->next = Node->next; } } }
GreReleaseFastMutex(gAssociationListMutex);
return Node; }
BOOL dhsurfAssociationIsNodeInList( DHSURF dhsurf, HSURF hsurf )
{ PDHSURF_ASSOCIATION_NODE Curr; BOOL bRet = FALSE;
GreAcquireFastMutex(gAssociationListMutex);
Curr = gdhsurfAssociationList;
while (Curr) {
//
// We only have to check if the key and the hsurf value
// are similar.
//
if ((Curr->dhsurf == dhsurf) && (Curr->hsurf == hsurf)) {
bRet = TRUE; break; }
Curr = Curr->next; }
GreReleaseFastMutex(gAssociationListMutex);
return bRet; }
PDHPDEV_ASSOCIATION_NODE dhpdevRetrieveNode( DHPDEV dhpdev )
{ PDHPDEV_ASSOCIATION_NODE Node;
GreAcquireFastMutex(gAssociationListMutex);
Node = gdhpdevAssociationList;
while (Node) {
if (Node->dhpdev == dhpdev) { break; }
Node = Node->next; }
GreReleaseFastMutex(gAssociationListMutex);
return Node; }
PLDEV dhpdevRetrieveLdev( DHPDEV dhpdev )
{ PDHPDEV_ASSOCIATION_NODE Node;
GreAcquireFastMutex(gAssociationListMutex);
Node = gdhpdevAssociationList;
while (Node) {
if (Node->dhpdev == dhpdev) { break; }
Node = Node->next; }
GreReleaseFastMutex(gAssociationListMutex);
if (Node) { return (PLDEV)Node->pldev; } else { return NULL; } }
PLDEV dhsurfRetrieveLdev( DHSURF dhsurf )
{ PDHSURF_ASSOCIATION_NODE Node;
GreAcquireFastMutex(gAssociationListMutex);
Node = gdhsurfAssociationList;
while (Node) {
if (Node->dhsurf == dhsurf) { break; }
Node = Node->next; }
GreReleaseFastMutex(gAssociationListMutex);
if (Node) { return (PLDEV)Node->pldev; } else { return NULL; } }
ULONG WatchdogDrvGetModesEmpty( IN HANDLE hDriver, IN ULONG cjSize, OUT DEVMODEW *pdm )
/*++
Routine Description:
This function replaces a drivers DrvGetModes function when and EA has occured. We do this so that we can stop reporting modes for this device.
--*/
{ //
// Indicate NO modes!
//
return 0; }
VOID WatchdogRecoveryThread( IN PVOID Context )
{ VIDEO_WIN32K_CALLBACKS_PARAMS Params;
UNREFERENCED_PARAMETER(Context);
Params.CalloutType = VideoChangeDisplaySettingsCallout; Params.Param = 0; Params.PhysDisp = NULL; Params.Status = 0;
//
// It is possible we'll hit an EA and try to recover for USER has
// finished initializing. Therefore the VideoPortCallout may fail
// with a STATUS_INVALID_HANDLE. We'll keep trying (with a delay)
// until we get a different status code.
//
do {
VideoPortCallout(&Params);
if (Params.Status == STATUS_INVALID_HANDLE) {
ZwYieldExecution(); }
} while (Params.Status == STATUS_INVALID_HANDLE);
PsTerminateSystemThread(STATUS_SUCCESS); }
VOID HandleStuckThreadException( PLDEV pldev )
/*++
Wake up a user mode thread waiting to reset the display resolution.
--*/
{ UNICODE_STRING EventName; HANDLE EventHandle; HANDLE ThreadHandle; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status;
//
// First disable all entries in the dispatch table in the pldev. This
// way we can stop future threads from entring the driver.
//
pldev->bThreadStuck = TRUE;
//
// Replacd the DrvGetModes function for the driver such that the
// driver reports no modes!
//
pldev->apfn[INDEX_DrvGetModes] = (PFN) WatchdogDrvGetModesEmpty;
//
// Remove non-vga device from graphics device list to stop the
// system from trying to continue using the current device.
//
// What do we do about multi-mon?
//
DrvPrepareForEARecovery();
//
// Create a thread to do the work of changing the display resolution.
//
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
Status = PsCreateSystemThread(&ThreadHandle, (ACCESS_MASK) 0, &ObjectAttributes, NtCurrentProcess(), NULL, WatchdogRecoveryThread, NULL);
if (NT_SUCCESS(Status) == TRUE) {
ZwClose(ThreadHandle);
} else {
DbgPrint("Warning, we failed to create the Recovery Thread\n"); }
//
// Clean up any pending drivers locks that this thread is holding
//
GreFreeSemaphoresForCurrentThread(); }
DHPDEV APIENTRY WatchdogDrvEnablePDEV( DEVMODEW *pdm, LPWSTR pwszLogAddress, ULONG cPat, HSURF *phsurfPatterns, ULONG cjCaps, ULONG *pdevcaps, ULONG cjDevInfo, DEVINFO *pdi, HDEV hdev, LPWSTR pwszDeviceName, HANDLE hDriver )
{ PDEV *ppdev = (PDEV *)hdev; DHPDEV dhpdevRet = NULL;
if (ppdev->pldev->bThreadStuck == FALSE) {
PFN_DrvEnablePDEV pfn = (PFN_DrvEnablePDEV) ppdev->pldev->apfnDriver[INDEX_DrvEnablePDEV]; PDHPDEV_ASSOCIATION_NODE Node = dhpdevAssociationCreateNode();
if (Node) {
Node->pldev = ppdev->pldev; Node->dhpdev = NULL;
RECOVERY_SECTION_BEGIN(ppdev->pldev) {
Node->dhpdev = pfn(pdm, pwszLogAddress, cPat, phsurfPatterns, cjCaps, (GDIINFO *)pdevcaps, cjDevInfo, pdi, hdev, pwszDeviceName, hDriver);
} RECOVERY_SECTION_END(ppdev->pldev); if (Node->dhpdev) {
dhpdevRet = (DHPDEV) Node->dhpdev;
dhpdevAssociationInsertNode(Node);
} else {
AssociationDeleteNode(Node); } } }
return dhpdevRet; }
VOID APIENTRY WatchdogDrvCompletePDEV( DHPDEV dhpdev, HDEV hdev )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvCompletePDEV pfn = (PFN_DrvCompletePDEV) pldev->apfnDriver[INDEX_DrvCompletePDEV];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) { pfn(dhpdev, hdev); } RECOVERY_SECTION_END(pldev); }
VOID APIENTRY WatchdogDrvDisablePDEV( DHPDEV dhpdev )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvDisablePDEV pfn = (PFN_DrvDisablePDEV) pldev->apfnDriver[INDEX_DrvDisablePDEV];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(dhpdev);
} RECOVERY_SECTION_END(pldev);
AssociationDeleteNode(dhpdevAssociationRemoveNode(dhpdev)); }
HSURF APIENTRY WatchdogDrvEnableSurface( DHPDEV dhpdev )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvEnableSurface pfn = (PFN_DrvEnableSurface) pldev->apfnDriver[INDEX_DrvEnableSurface]; HSURF hsurfRet = NULL;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return NULL; }
RECOVERY_SECTION_BEGIN(pldev) {
hsurfRet = pfn(dhpdev);
} RECOVERY_SECTION_END(pldev);
return hsurfRet; }
VOID APIENTRY WatchdogDrvDisableSurface( DHPDEV dhpdev )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvDisableSurface pfn = (PFN_DrvDisableSurface) pldev->apfnDriver[INDEX_DrvDisableSurface];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(dhpdev);
} RECOVERY_SECTION_END(pldev); }
BOOL APIENTRY WatchdogDrvAssertMode( DHPDEV dhpdev, BOOL bEnable )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvAssertMode pfn = (PFN_DrvAssertMode) pldev->apfnDriver[INDEX_DrvAssertMode]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(dhpdev, bEnable);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvResetPDEV( DHPDEV dhpdevOld, DHPDEV dhpdevNew )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdevOld); PFN_DrvResetPDEV pfn = (PFN_DrvResetPDEV) pldev->apfnDriver[INDEX_DrvResetPDEV]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(dhpdevOld, dhpdevNew);
} RECOVERY_SECTION_END(pldev);
return bRet; }
HBITMAP APIENTRY WatchdogDrvCreateDeviceBitmap( DHPDEV dhpdev, SIZEL sizl, ULONG iFormat )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvCreateDeviceBitmap pfn = (PFN_DrvCreateDeviceBitmap) pldev->apfnDriver[INDEX_DrvCreateDeviceBitmap]; HBITMAP hbitmapRet = NULL;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck == FALSE) {
RECOVERY_SECTION_BEGIN(pldev) {
hbitmapRet = pfn(dhpdev, sizl, iFormat);
} RECOVERY_SECTION_END(pldev); }
return hbitmapRet; }
VOID APIENTRY WatchdogDrvDeleteDeviceBitmap( IN DHSURF dhsurf )
{ PLDEV pldev = dhsurfRetrieveLdev(dhsurf); PFN_DrvDeleteDeviceBitmap pfn = (PFN_DrvDeleteDeviceBitmap) pldev->apfnDriver[INDEX_DrvDeleteDeviceBitmap];
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(dhsurf);
} RECOVERY_SECTION_END(pldev);
AssociationDeleteNode(dhsurfAssociationRemoveNode(dhsurf)); }
BOOL APIENTRY WatchdogDrvRealizeBrush( BRUSHOBJ *pbo, SURFOBJ *psoTarget, SURFOBJ *psoPattern, SURFOBJ *psoMask, XLATEOBJ *pxlo, ULONG iHatch )
{ PLDEV pldev = dhpdevRetrieveLdev(psoTarget->dhpdev); PFN_DrvRealizeBrush pfn = (PFN_DrvRealizeBrush) pldev->apfnDriver[INDEX_DrvRealizeBrush]; BOOL bRet = FALSE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return FALSE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(pbo, psoTarget, psoPattern, psoMask, pxlo, iHatch);
} RECOVERY_SECTION_END(pldev);
return bRet; }
ULONG APIENTRY WatchdogDrvDitherColor( DHPDEV dhpdev, ULONG iMode, ULONG rgb, ULONG *pul )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvDitherColor pfn = (PFN_DrvDitherColor) pldev->apfnDriver[INDEX_DrvDitherColor]; ULONG ulRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
ulRet = pfn(dhpdev, iMode, rgb, pul);
} RECOVERY_SECTION_END(pldev);
return ulRet; }
BOOL APIENTRY WatchdogDrvStrokePath( SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, XFORMOBJ *pxo, BRUSHOBJ *pbo, POINTL *pptlBrushOrg, LINEATTRS *plineattrs, MIX mix )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvStrokePath pfn = (PFN_DrvStrokePath) pldev->apfnDriver[INDEX_DrvStrokePath]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(pso, ppo, pco, pxo, pbo, pptlBrushOrg, plineattrs, mix);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvFillPath( SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, BRUSHOBJ *pbo, POINTL *pptlBrushOrg, MIX mix, FLONG flOptions )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvFillPath pfn = (PFN_DrvFillPath) pldev->apfnDriver[INDEX_DrvFillPath]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(pso, ppo, pco, pbo, pptlBrushOrg, mix, flOptions);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvStrokeAndFillPath( SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, XFORMOBJ *pxo, BRUSHOBJ *pboStroke, LINEATTRS *plineattrs, BRUSHOBJ *pboFill, POINTL *pptlBrushOrg, MIX mixFill, FLONG flOptions )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvStrokeAndFillPath pfn = (PFN_DrvStrokeAndFillPath) pldev->apfnDriver[INDEX_DrvStrokeAndFillPath]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(pso, ppo, pco, pxo, pboStroke, plineattrs, pboFill, pptlBrushOrg, mixFill, flOptions);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvBitBlt( SURFOBJ *psoDst, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDst, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 rop4 )
{ SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc; PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev); PFN_DrvBitBlt pfn = (PFN_DrvBitBlt) pldev->apfnDriver[INDEX_DrvBitBlt]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, prclDst, pptlSrc, pptlMask, pbo, pptlBrush, rop4);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvCopyBits( SURFOBJ *psoDst, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDst, POINTL *pptlSrc )
{ SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc; PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev); PFN_DrvCopyBits pfn = (PFN_DrvCopyBits) pldev->apfnDriver[INDEX_DrvCopyBits]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(psoDst, psoSrc, pco, pxlo, prclDst, pptlSrc);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvStretchBlt( SURFOBJ *psoDst, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, COLORADJUSTMENT *pca, POINTL *pptlHTOrg, RECTL *prclDst, RECTL *prclSrc, POINTL *pptlMask, ULONG iMode )
{ SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc; PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev); PFN_DrvStretchBlt pfn = (PFN_DrvStretchBlt) pldev->apfnDriver[INDEX_DrvStretchBlt]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMask, iMode);
} RECOVERY_SECTION_END(pldev); return bRet; }
ULONG APIENTRY WatchdogDrvSetPalette( DHPDEV dhpdev, PALOBJ *ppalo, FLONG fl, ULONG iStart, ULONG cColors )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvSetPalette pfn = (PFN_DrvSetPalette) pldev->apfnDriver[INDEX_DrvSetPalette]; ULONG ulRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
ulRet = pfn(dhpdev, ppalo, fl, iStart, cColors);
} RECOVERY_SECTION_END(pldev);
return ulRet; }
BOOL APIENTRY WatchdogDrvTextOut( SURFOBJ *pso, STROBJ *pstro, FONTOBJ *pfo, CLIPOBJ *pco, RECTL *prclExtra, RECTL *prclOpaque, BRUSHOBJ *pboFore, BRUSHOBJ *pboOpaque, POINTL *pptlOrg, MIX mix )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvTextOut pfn = (PFN_DrvTextOut) pldev->apfnDriver[INDEX_DrvTextOut]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(pso, pstro, pfo, pco, prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix);
} RECOVERY_SECTION_END(pldev);
return bRet;
}
ULONG APIENTRY WatchdogDrvEscape( SURFOBJ *pso, ULONG iEsc, ULONG cjIn, PVOID pvIn, ULONG cjOut, PVOID pvOut )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvEscape pfn = (PFN_DrvEscape) pldev->apfnDriver[INDEX_DrvEscape]; ULONG ulRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
ulRet = pfn(pso, iEsc, cjIn, pvIn, cjOut, pvOut);
} RECOVERY_SECTION_END(pldev);
return ulRet; }
ULONG APIENTRY WatchdogDrvDrawEscape( IN SURFOBJ *pso, IN ULONG iEsc, IN CLIPOBJ *pco, IN RECTL *prcl, IN ULONG cjIn, IN PVOID pvIn )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvDrawEscape pfn = (PFN_DrvDrawEscape) pldev->apfnDriver[INDEX_DrvDrawEscape]; ULONG ulRet = -1;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return -1; }
RECOVERY_SECTION_BEGIN(pldev) {
ulRet = pfn(pso, iEsc, pco, prcl, cjIn, pvIn);
} RECOVERY_SECTION_END(pldev);
return ulRet;
}
ULONG APIENTRY WatchdogDrvSetPointerShape( SURFOBJ *pso, SURFOBJ *psoMask, SURFOBJ *psoColor, XLATEOBJ *pxlo, LONG xHot, LONG yHot, LONG x, LONG y, RECTL *prcl, FLONG fl )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvSetPointerShape pfn = (PFN_DrvSetPointerShape) pldev->apfnDriver[INDEX_DrvSetPointerShape]; ULONG ulRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
ulRet = pfn(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl);
} RECOVERY_SECTION_END(pldev);
return ulRet; }
VOID APIENTRY WatchdogDrvMovePointer( SURFOBJ *pso, LONG x, LONG y, RECTL *prcl )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvMovePointer pfn = (PFN_DrvMovePointer) pldev->apfnDriver[INDEX_DrvMovePointer];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(pso, x, y, prcl);
} RECOVERY_SECTION_END(pldev); }
BOOL APIENTRY WatchdogDrvLineTo( SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, LONG x1, LONG y1, LONG x2, LONG y2, RECTL *prclBounds, MIX mix )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvLineTo pfn = (PFN_DrvLineTo) pldev->apfnDriver[INDEX_DrvLineTo]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(pso, pco, pbo, x1, y1, x2, y2, prclBounds, mix);
} RECOVERY_SECTION_END(pldev);
return bRet; }
VOID APIENTRY WatchdogDrvSynchronize( DHPDEV dhpdev, RECTL *prcl )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvSynchronize pfn = (PFN_DrvSynchronize) pldev->apfnDriver[INDEX_DrvSynchronize];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(dhpdev, prcl);
} RECOVERY_SECTION_END(pldev); }
ULONG_PTR APIENTRY WatchdogDrvSaveScreenBits( SURFOBJ *pso, ULONG iMode, ULONG_PTR ident, RECTL *prcl )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvSaveScreenBits pfn = (PFN_DrvSaveScreenBits) pldev->apfnDriver[INDEX_DrvSaveScreenBits]; ULONG_PTR ulptrRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
ulptrRet = pfn(pso, iMode, ident, prcl);
} RECOVERY_SECTION_END(pldev);
return ulptrRet; }
DWORD APIENTRY WatchdogDrvSetPixelFormat( IN SURFOBJ *pso, IN LONG iPixelFormat, IN HWND hwnd )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvSetPixelFormat pfn = (PFN_DrvSetPixelFormat) pldev->apfnDriver[INDEX_DrvSetPixelFormat]; DWORD dwRet = FALSE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(pso, iPixelFormat, hwnd);
} RECOVERY_SECTION_END(pldev); return dwRet; }
LONG APIENTRY WatchdogDrvDescribePixelFormat( IN DHPDEV dhpdev, IN LONG iPixelFormat, IN ULONG cjpdf, OUT PIXELFORMATDESCRIPTOR *ppfd )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvDescribePixelFormat pfn = (PFN_DrvDescribePixelFormat) pldev->apfnDriver[INDEX_DrvDescribePixelFormat]; LONG lRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
lRet = pfn(dhpdev, iPixelFormat, cjpdf, ppfd);
} RECOVERY_SECTION_END(pldev); return lRet; }
BOOL APIENTRY WatchdogDrvSwapBuffers( IN SURFOBJ *pso, IN WNDOBJ *pwo )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvSwapBuffers pfn = (PFN_DrvSwapBuffers) pldev->apfnDriver[INDEX_DrvSwapBuffers]; BOOL bRet = FALSE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return FALSE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(pso, pwo);
} RECOVERY_SECTION_END(pldev);
return bRet; }
DWORD APIENTRY WatchdogDdContextCreate( LPD3DNTHAL_CONTEXTCREATEDATA pccd )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE)dhpdevRetrieveNode((DHPDEV)pccd->lpDDLcl->lpGbl->dhpdev); PLDEV pldev = ppdevData->pldev; LPD3DNTHAL_CONTEXTCREATECB pfn = (LPD3DNTHAL_CONTEXTCREATECB) ppdevData->apfnDriver[INDEX_DdContextCreate]; DWORD dwRet = DDHAL_DRIVER_NOTHANDLED; PCONTEXT_NODE Node;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
Node = (PCONTEXT_NODE)PALLOCMEM(sizeof(CONTEXT_NODE), GDITAG_DRVSUP);
if (Node) {
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(pccd);
} RECOVERY_SECTION_END(pldev);
if (dwRet == DDHAL_DRIVER_HANDLED) {
//
// Store the dwhContext and the associated dhpdev
//
Node->Context = (PVOID)pccd->dwhContext; Node->ppdevData = ppdevData;
pccd->dwhContext = (DWORD_PTR)Node;
} else {
VFREEMEM(Node); } }
return dwRet; }
DWORD APIENTRY WatchdogDdContextDestroy( LPD3DNTHAL_CONTEXTDESTROYDATA pcdd )
{ PCONTEXT_NODE Node = (PCONTEXT_NODE) pcdd->dwhContext; LPD3DNTHAL_CONTEXTDESTROYCB pfn = (LPD3DNTHAL_CONTEXTDESTROYCB) Node->ppdevData->apfnDriver[INDEX_DdContextDestroy]; PLDEV pldev = Node->ppdevData->pldev; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
//
// Restore driver created context
//
pcdd->dwhContext = (DWORD_PTR) Node->Context;
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(pcdd);
} RECOVERY_SECTION_END(pldev); //
// Resore our context, just in case this stucture is re-used
//
pcdd->dwhContext = (DWORD_PTR) Node;
if (dwRet == DDHAL_DRIVER_HANDLED) {
VFREEMEM(Node); }
return dwRet; }
DWORD APIENTRY WatchdogDdCanCreateSurface( PDD_CANCREATESURFACEDATA lpCanCreateSurface )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCanCreateSurface->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_CANCREATESURFACE pfn = (PDD_CANCREATESURFACE) ppdevData->apfnDriver[INDEX_DdCanCreateSurface]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpCanCreateSurface);
} RECOVERY_SECTION_END(pldev);
return dwRet; }
DWORD APIENTRY WatchdogDdCreateSurface( PDD_CREATESURFACEDATA lpCreateSurface )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCreateSurface->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_CREATESURFACE pfn = (PDD_CREATESURFACE) ppdevData->apfnDriver[INDEX_DdCreateSurface]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpCreateSurface);
} RECOVERY_SECTION_END(pldev);
return dwRet; }
DWORD APIENTRY WatchdogDdDestroySurface( PDD_DESTROYSURFACEDATA lpDestroySurface )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpDestroySurface->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_DESTROYSURFACE pfn = (PDD_SURFCB_DESTROYSURFACE) ppdevData->apfnDriver[INDEX_DdDestroySurface]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpDestroySurface);
} RECOVERY_SECTION_END(pldev);
return dwRet; }
DWORD APIENTRY WatchdogDdLockSurface( PDD_LOCKDATA lpLockSurface )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpLockSurface->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_LOCK pfn = (PDD_SURFCB_LOCK) ppdevData->apfnDriver[INDEX_DdLockSurface]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpLockSurface);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdUnlockSurface( PDD_UNLOCKDATA lpUnlockSurface )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpUnlockSurface->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_UNLOCK pfn = (PDD_SURFCB_UNLOCK) ppdevData->apfnDriver[INDEX_DdUnlockSurface]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpUnlockSurface);
} RECOVERY_SECTION_END(pldev);
return dwRet; }
#if 0
//
// I'm not sure how I can hook this one since a DD_DRVSETCOLORKEYDATA
// structure doesn't have a way to look up the dhpdev!
//
DWORD APIENTRY WatchdogDdSetColorKey( PDD_DRVSETCOLORKEYDATA lpSetColorKey )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetColorKey->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_SETCOLORKEY pfn = (PDD_SURFCB_SETCOLORKEY) ppdevData->apfnDriver[INDEX_DdSetColorKey]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpSetColorKey);
} RECOVERY_SECTION_END(pldev);
return dwRet; } #endif
DWORD APIENTRY WatchdogDdGetScanLine( PDD_GETSCANLINEDATA pGetScanLine )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)pGetScanLine->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_GETSCANLINE pfn = (PDD_GETSCANLINE) ppdevData->apfnDriver[INDEX_DdGetScanLine]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(pGetScanLine);
} RECOVERY_SECTION_END(pldev);
return dwRet; }
DWORD APIENTRY WatchdogDdCreatePalette( PDD_CREATEPALETTEDATA lpCreatePalette )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCreatePalette->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_CREATEPALETTE pfn = (PDD_CREATEPALETTE) ppdevData->apfnDriver[INDEX_DdCreatePalette]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpCreatePalette);
} RECOVERY_SECTION_END(pldev);
return dwRet; }
DWORD APIENTRY WatchdogDdMapMemory( PDD_MAPMEMORYDATA lpMapMemory )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpMapMemory->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_MAPMEMORY pfn = (PDD_MAPMEMORY) ppdevData->apfnDriver[INDEX_DdMapMemory]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpMapMemory);
} RECOVERY_SECTION_END(pldev);
return dwRet; }
DWORD APIENTRY WatchdogDdWaitForVerticalBlank( PDD_WAITFORVERTICALBLANKDATA lpWaitForVerticalBlank )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpWaitForVerticalBlank->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_WAITFORVERTICALBLANK pfn = (PDD_WAITFORVERTICALBLANK) ppdevData->apfnDriver[INDEX_DdWaitForVerticalBlank]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpWaitForVerticalBlank);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdFlip( PDD_FLIPDATA lpFlip )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpFlip->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_FLIP pfn = (PDD_SURFCB_FLIP) ppdevData->apfnDriver[INDEX_DdFlip]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpFlip);
} RECOVERY_SECTION_END(pldev);
return dwRet; }
DWORD APIENTRY WatchdogDdGetDriverState( PDD_GETDRIVERSTATEDATA pgdsd )
{ PCONTEXT_NODE Node = (PCONTEXT_NODE) pgdsd->dwhContext; PDD_GETDRIVERSTATE pfn = (PDD_GETDRIVERSTATE) Node->ppdevData->apfnDriver[INDEX_DdGetDriverState]; PLDEV pldev = Node->ppdevData->pldev; DWORD dwRet = 0;
//
// how can I validate if I created this dwhcontext?
//
if (pfn == NULL) { pgdsd->ddRVal = D3DNTHAL_CONTEXT_BAD; return DDHAL_DRIVER_HANDLED; }
if (pldev->bThreadStuck) { return 0; }
//
// restore original context
//
pgdsd->dwhContext = (DWORD_PTR) Node->Context;
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(pgdsd);
} RECOVERY_SECTION_END(pldev); //
// save our context again in case this structure is re-used
//
pgdsd->dwhContext = (DWORD_PTR) Node;
return dwRet; }
DWORD APIENTRY WatchdogDdLock( PDD_LOCKDATA lpLock ) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpLock->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_LOCK pfn = (PDD_SURFCB_LOCK) ppdevData->apfnDriver[INDEX_DdLock]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpLock);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdUnlock( PDD_UNLOCKDATA lpUnlock) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpUnlock->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_UNLOCK pfn = (PDD_SURFCB_UNLOCK) ppdevData->apfnDriver[INDEX_DdUnlock]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpUnlock);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdBlt( PDD_BLTDATA lpBlt) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpBlt->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_BLT pfn = (PDD_SURFCB_BLT) ppdevData->apfnDriver[INDEX_DdBlt]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpBlt);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdAddAttachedSurface( PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpAddAttachedSurface->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_ADDATTACHEDSURFACE pfn = (PDD_SURFCB_ADDATTACHEDSURFACE) ppdevData->apfnDriver[INDEX_DdAddAttachedSurface]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpAddAttachedSurface);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdGetBltStatus( PDD_GETBLTSTATUSDATA lpGetBltStatus) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpGetBltStatus->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_GETBLTSTATUS pfn = (PDD_SURFCB_GETBLTSTATUS) ppdevData->apfnDriver[INDEX_DdGetBltStatus]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpGetBltStatus);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdGetFlipStatus( PDD_GETFLIPSTATUSDATA lpGetFlipStatus) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpGetFlipStatus->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_GETFLIPSTATUS pfn = (PDD_SURFCB_GETFLIPSTATUS) ppdevData->apfnDriver[INDEX_DdGetFlipStatus]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpGetFlipStatus);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdUpdateOverlay( PDD_UPDATEOVERLAYDATA lpUpdateOverlay) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpUpdateOverlay->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_UPDATEOVERLAY pfn = (PDD_SURFCB_UPDATEOVERLAY) ppdevData->apfnDriver[INDEX_DdUpdateOverlay]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpUpdateOverlay);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdSetOverlayPosition( PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetOverlayPosition->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_SETOVERLAYPOSITION pfn = (PDD_SURFCB_SETOVERLAYPOSITION) ppdevData->apfnDriver[INDEX_DdSetOverlayPosition]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpSetOverlayPosition);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdSetPalette( PDD_SETPALETTEDATA lpSetPalette) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetPalette->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_SETPALETTE pfn = (PDD_SURFCB_SETPALETTE) ppdevData->apfnDriver[INDEX_DdSetPalette]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpSetPalette);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdDestroyPalette( PDD_DESTROYPALETTEDATA lpDestroyPalette) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpDestroyPalette->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_PALCB_DESTROYPALETTE pfn = (PDD_PALCB_DESTROYPALETTE) ppdevData->apfnDriver[INDEX_DdDestroyPalette]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpDestroyPalette);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdSetEntries( PDD_SETENTRIESDATA lpSetEntries) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetEntries->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_PALCB_SETENTRIES pfn = (PDD_PALCB_SETENTRIES) ppdevData->apfnDriver[INDEX_DdSetEntries]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpSetEntries);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdColorControl( PDD_COLORCONTROLDATA lpColorControl) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpColorControl->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_COLORCB_COLORCONTROL pfn = (PDD_COLORCB_COLORCONTROL) ppdevData->apfnDriver[INDEX_DdColorControl]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpColorControl);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdCanCreateD3DBuffer( PDD_CANCREATESURFACEDATA lpCanCreateD3DBuffer) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCanCreateD3DBuffer->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_CANCREATESURFACE pfn = (PDD_CANCREATESURFACE) ppdevData->apfnDriver[INDEX_DdCanCreateD3DBuffer]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpCanCreateD3DBuffer);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdCreateD3DBuffer( PDD_CREATESURFACEDATA lpCreateD3DBuffer) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCreateD3DBuffer->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_CREATESURFACE pfn = (PDD_CREATESURFACE) ppdevData->apfnDriver[INDEX_DdCreateD3DBuffer]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpCreateD3DBuffer);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdDestroyD3DBuffer( PDD_DESTROYSURFACEDATA lpDestroyD3DBuffer) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpDestroyD3DBuffer->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_DESTROYSURFACE pfn = (PDD_SURFCB_DESTROYSURFACE) ppdevData->apfnDriver[INDEX_DdDestroyD3DBuffer]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpDestroyD3DBuffer);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdLockD3DBuffer( PDD_LOCKDATA lpLockD3DBuffer) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpLockD3DBuffer->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_LOCK pfn = (PDD_SURFCB_LOCK) ppdevData->apfnDriver[INDEX_DdLockD3DBuffer]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpLockD3DBuffer);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdUnlockD3DBuffer( PDD_UNLOCKDATA lpUnlockD3DBuffer) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpUnlockD3DBuffer->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SURFCB_UNLOCK pfn = (PDD_SURFCB_UNLOCK) ppdevData->apfnDriver[INDEX_DdUnlockD3DBuffer]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpUnlockD3DBuffer);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdGetAvailDriverMemory( PDD_GETAVAILDRIVERMEMORYDATA lpGetAvailDriverMemory) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpGetAvailDriverMemory->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_GETAVAILDRIVERMEMORY pfn = (PDD_GETAVAILDRIVERMEMORY) ppdevData->apfnDriver[INDEX_DdGetAvailDriverMemory]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpGetAvailDriverMemory);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdAlphaBlt( PDD_BLTDATA lpAlphaBlt) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpAlphaBlt->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_ALPHABLT pfn = (PDD_ALPHABLT) ppdevData->apfnDriver[INDEX_DdAlphaBlt]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpAlphaBlt);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdDrawPrimitives2( LPD3DNTHAL_DRAWPRIMITIVES2DATA lpDrawPrimitives2) { PCONTEXT_NODE Node = (PCONTEXT_NODE) lpDrawPrimitives2->dwhContext; LPD3DNTHAL_DRAWPRIMITIVES2CB pfn = (LPD3DNTHAL_DRAWPRIMITIVES2CB) Node->ppdevData->apfnDriver[INDEX_DdDrawPrimitives2]; PLDEV pldev = Node->ppdevData->pldev; DWORD dwRet = 0;
if (pfn == NULL) { lpDrawPrimitives2->ddrval = D3DNTHAL_CONTEXT_BAD; return DDHAL_DRIVER_HANDLED; }
if (pldev->bThreadStuck) { return 0; }
lpDrawPrimitives2->dwhContext = (DWORD_PTR) Node->Context;
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpDrawPrimitives2);
} RECOVERY_SECTION_END(pldev); lpDrawPrimitives2->dwhContext = (DWORD_PTR) Node;
return dwRet; }
DWORD APIENTRY WatchdogDdValidateTextureStageState( LPD3DNTHAL_VALIDATETEXTURESTAGESTATEDATA lpValidateTextureStageState) { PCONTEXT_NODE Node = (PCONTEXT_NODE) lpValidateTextureStageState->dwhContext; LPD3DNTHAL_VALIDATETEXTURESTAGESTATECB pfn = (LPD3DNTHAL_VALIDATETEXTURESTAGESTATECB) Node->ppdevData->apfnDriver[INDEX_DdValidateTextureStageState]; PLDEV pldev = Node->ppdevData->pldev; DWORD dwRet = 0;
if (pfn == NULL) { lpValidateTextureStageState->ddrval = D3DNTHAL_CONTEXT_BAD; return DDHAL_DRIVER_HANDLED; }
if (pldev->bThreadStuck) { return 0; }
lpValidateTextureStageState->dwhContext = (DWORD_PTR) Node->Context;
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpValidateTextureStageState);
} RECOVERY_SECTION_END(pldev); lpValidateTextureStageState->dwhContext = (DWORD_PTR) Node;
return dwRet; }
DWORD APIENTRY WatchdogDdSyncSurfaceData( PDD_SYNCSURFACEDATA lpSyncSurfaceData) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSyncSurfaceData->lpDD->lpGbl->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_KERNELCB_SYNCSURFACE pfn = (PDD_KERNELCB_SYNCSURFACE) ppdevData->apfnDriver[INDEX_DdSyncSurfaceData]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpSyncSurfaceData);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdSyncVideoPortData( PDD_SYNCVIDEOPORTDATA lpSyncVideoPortData) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSyncVideoPortData->lpDD->lpGbl->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_KERNELCB_SYNCVIDEOPORT pfn = (PDD_KERNELCB_SYNCVIDEOPORT) ppdevData->apfnDriver[INDEX_DdSyncVideoPortData]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpSyncVideoPortData);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdCreateSurfaceEx( PDD_CREATESURFACEEXDATA lpCreateSurfaceEx) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCreateSurfaceEx->lpDDLcl->lpGbl->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_CREATESURFACEEX pfn = (PDD_CREATESURFACEEX) ppdevData->apfnDriver[INDEX_DdCreateSurfaceEx]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpCreateSurfaceEx);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdDestroyDDLocal( PDD_DESTROYDDLOCALDATA lpDestroyDDLocal) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpDestroyDDLocal->pDDLcl->lpGbl->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_DESTROYDDLOCAL pfn = (PDD_DESTROYDDLOCAL) ppdevData->apfnDriver[INDEX_DdDestroyDDLocal]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpDestroyDDLocal);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdFreeDriverMemory( PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpFreeDriverMemory->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_FREEDRIVERMEMORY pfn = (PDD_FREEDRIVERMEMORY) ppdevData->apfnDriver[INDEX_DdFreeDriverMemory]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpFreeDriverMemory);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdSetExclusiveMode( PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetExclusiveMode->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_SETEXCLUSIVEMODE pfn = (PDD_SETEXCLUSIVEMODE) ppdevData->apfnDriver[INDEX_DdSetExclusiveMode]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpSetExclusiveMode);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdFlipToGDISurface( PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface) { PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpFlipToGDISurface->lpDD->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_FLIPTOGDISURFACE pfn = (PDD_FLIPTOGDISURFACE) ppdevData->apfnDriver[INDEX_DdFlipToGDISurface]; DWORD dwRet = 0;
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpFlipToGDISurface);
} RECOVERY_SECTION_END(pldev); return dwRet; }
DWORD APIENTRY WatchdogDdGetDriverInfo( PDD_GETDRIVERINFODATA lpGetDriverInfo )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE)dhpdevRetrieveNode((DHPDEV)lpGetDriverInfo->dhpdev); PLDEV pldev = ppdevData->pldev; PDD_GETDRIVERINFO pfn = (PDD_GETDRIVERINFO) ppdevData->apfnDriver[INDEX_DdGetDriverInfo]; DWORD dwRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
dwRet = pfn(lpGetDriverInfo);
} RECOVERY_SECTION_END(pldev);
if ((dwRet == DDHAL_DRIVER_HANDLED) && (lpGetDriverInfo->ddRVal == DD_OK)) {
if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_ColorControlCallbacks)) {
PDD_COLORCONTROLCALLBACKS Callbacks = (PDD_COLORCONTROLCALLBACKS) lpGetDriverInfo->lpvData;
if (Callbacks->dwFlags & DDHAL_COLOR_COLORCONTROL) {
if (Callbacks->ColorControl != WatchdogDdColorControl) {
ppdevData->apfnDriver[INDEX_DdColorControl] = (PFN)Callbacks->ColorControl; } Callbacks->ColorControl = WatchdogDdColorControl; }
} else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_D3DCallbacks)) {
LPD3DNTHAL_CALLBACKS Callbacks = (LPD3DNTHAL_CALLBACKS) lpGetDriverInfo->lpvData;
if (Callbacks->ContextCreate) {
if (Callbacks->ContextCreate != WatchdogDdContextCreate) { ppdevData->apfnDriver[INDEX_DdContextCreate] = (PFN)Callbacks->ContextCreate; } Callbacks->ContextCreate = WatchdogDdContextCreate; }
if (Callbacks->ContextDestroy) {
if (Callbacks->ContextDestroy != WatchdogDdContextDestroy) { ppdevData->apfnDriver[INDEX_DdContextDestroy] = (PFN)Callbacks->ContextDestroy; } Callbacks->ContextDestroy = WatchdogDdContextDestroy; }
} else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_D3DCallbacks3)) {
LPD3DNTHAL_CALLBACKS3 Callbacks = (LPD3DNTHAL_CALLBACKS3) lpGetDriverInfo->lpvData;
if (Callbacks->DrawPrimitives2) {
if (Callbacks->DrawPrimitives2 != WatchdogDdDrawPrimitives2) { ppdevData->apfnDriver[INDEX_DdDrawPrimitives2] = (PFN)Callbacks->DrawPrimitives2; } Callbacks->DrawPrimitives2 = WatchdogDdDrawPrimitives2; }
if (Callbacks->ValidateTextureStageState) {
if (Callbacks->ValidateTextureStageState != WatchdogDdValidateTextureStageState) { ppdevData->apfnDriver[INDEX_DdValidateTextureStageState] = (PFN)Callbacks->ValidateTextureStageState; } Callbacks->ValidateTextureStageState = WatchdogDdValidateTextureStageState; }
} else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_KernelCallbacks)) {
PDD_KERNELCALLBACKS Callbacks = (PDD_KERNELCALLBACKS) lpGetDriverInfo->lpvData;
if (Callbacks->dwFlags & DDHAL_KERNEL_SYNCSURFACEDATA) {
if (Callbacks->SyncSurfaceData != WatchdogDdSyncSurfaceData) { ppdevData->apfnDriver[INDEX_DdSyncSurfaceData] = (PFN)Callbacks->SyncSurfaceData; } Callbacks->SyncSurfaceData = WatchdogDdSyncSurfaceData; }
if (Callbacks->dwFlags & DDHAL_KERNEL_SYNCVIDEOPORTDATA) {
if (Callbacks->SyncVideoPortData != WatchdogDdSyncVideoPortData) { ppdevData->apfnDriver[INDEX_DdSyncVideoPortData] = (PFN)Callbacks->SyncVideoPortData; } Callbacks->SyncVideoPortData = WatchdogDdSyncVideoPortData; }
} else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_MiscellaneousCallbacks)) {
PDD_MISCELLANEOUSCALLBACKS Callbacks = (PDD_MISCELLANEOUSCALLBACKS) lpGetDriverInfo->lpvData;
if (Callbacks->dwFlags & DDHAL_MISCCB32_GETAVAILDRIVERMEMORY) {
if (Callbacks->GetAvailDriverMemory != WatchdogDdGetAvailDriverMemory) { ppdevData->apfnDriver[INDEX_DdGetAvailDriverMemory] = (PFN)Callbacks->GetAvailDriverMemory; } Callbacks->GetAvailDriverMemory = WatchdogDdGetAvailDriverMemory; }
} else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_Miscellaneous2Callbacks)) {
PDD_MISCELLANEOUS2CALLBACKS Callbacks = (PDD_MISCELLANEOUS2CALLBACKS) lpGetDriverInfo->lpvData;
if (Callbacks->dwFlags & DDHAL_MISC2CB32_ALPHABLT) {
if (Callbacks->AlphaBlt != WatchdogDdAlphaBlt) { ppdevData->apfnDriver[INDEX_DdAlphaBlt] = (PFN)Callbacks->AlphaBlt; } Callbacks->AlphaBlt = WatchdogDdAlphaBlt; }
if (Callbacks->dwFlags & DDHAL_MISC2CB32_CREATESURFACEEX) {
if (Callbacks->CreateSurfaceEx != WatchdogDdCreateSurfaceEx) { ppdevData->apfnDriver[INDEX_DdCreateSurfaceEx] = (PFN)Callbacks->CreateSurfaceEx; } Callbacks->CreateSurfaceEx = WatchdogDdCreateSurfaceEx; }
if (Callbacks->dwFlags & DDHAL_MISC2CB32_GETDRIVERSTATE) {
if (Callbacks->GetDriverState != WatchdogDdGetDriverState) { ppdevData->apfnDriver[INDEX_DdGetDriverState] = (PFN)Callbacks->GetDriverState; } Callbacks->GetDriverState = WatchdogDdGetDriverState; }
if (Callbacks->dwFlags & DDHAL_MISC2CB32_DESTROYDDLOCAL) {
if (Callbacks->DestroyDDLocal != WatchdogDdDestroyDDLocal) { ppdevData->apfnDriver[INDEX_DdDestroyDDLocal] = (PFN)Callbacks->DestroyDDLocal; } Callbacks->DestroyDDLocal = WatchdogDdDestroyDDLocal; }
} else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_MotionCompCallbacks)) {
//
// TODO: Still need to implement
//
} else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_NTCallbacks)) {
PDD_NTCALLBACKS Callbacks = (PDD_NTCALLBACKS) lpGetDriverInfo->lpvData;
if (Callbacks->dwFlags & DDHAL_NTCB32_FREEDRIVERMEMORY) {
if (Callbacks->FreeDriverMemory != WatchdogDdFreeDriverMemory) { ppdevData->apfnDriver[INDEX_DdFreeDriverMemory] = (PFN)Callbacks->FreeDriverMemory; } Callbacks->FreeDriverMemory = WatchdogDdFreeDriverMemory; }
if (Callbacks->dwFlags & DDHAL_NTCB32_SETEXCLUSIVEMODE) {
if (Callbacks->SetExclusiveMode != WatchdogDdSetExclusiveMode) { ppdevData->apfnDriver[INDEX_DdSetExclusiveMode] = (PFN)Callbacks->SetExclusiveMode; } Callbacks->SetExclusiveMode = WatchdogDdSetExclusiveMode; }
if (Callbacks->dwFlags & DDHAL_NTCB32_FLIPTOGDISURFACE) {
if (Callbacks->FlipToGDISurface != WatchdogDdFlipToGDISurface) { ppdevData->apfnDriver[INDEX_DdFlipToGDISurface] = (PFN)Callbacks->FlipToGDISurface; } Callbacks->FlipToGDISurface = WatchdogDdFlipToGDISurface; }
} else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_VideoPortCallbacks)) {
//
// TODO: Still need to implement
//
} }
return dwRet; }
BOOL APIENTRY WatchdogDrvGetDirectDrawInfo( DHPDEV dhpdev, DD_HALINFO *pHalInfo, DWORD *pdwNumHeaps, VIDEOMEMORY *pvmList, DWORD *pdwNumFourCCCodes, DWORD *pdwFourCC )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode(dhpdev); PLDEV pldev = ppdevData->pldev; PFN_DrvGetDirectDrawInfo pfn = (PFN_DrvGetDirectDrawInfo) pldev->apfnDriver[INDEX_DrvGetDirectDrawInfo]; BOOL bRet = 0;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return 0; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(dhpdev, pHalInfo, pdwNumHeaps, pvmList, pdwNumFourCCCodes, pdwFourCC);
} RECOVERY_SECTION_END(pldev);
//
// If the function succeeded, then try to capture the DdGetDriverInfo
// function from pHalInfo.
//
if (bRet) { if (pHalInfo->GetDriverInfo) {
if (pHalInfo->GetDriverInfo != WatchdogDdGetDriverInfo) { ppdevData->apfnDriver[INDEX_DdGetDriverInfo] = (PFN)pHalInfo->GetDriverInfo; } pHalInfo->GetDriverInfo = WatchdogDdGetDriverInfo; }
if (pHalInfo->lpD3DHALCallbacks) {
LPD3DNTHAL_CALLBACKS lpD3DHALCallbacks;
lpD3DHALCallbacks = (LPD3DNTHAL_CALLBACKS)pHalInfo->lpD3DHALCallbacks;
//
// Create copy of D3DHALCallbacks info - This is done to safely
// latch the callbacks witout actually changing driver local data
//
memcpy(&ppdevData->D3DHALCallbacks, lpD3DHALCallbacks, min(sizeof(ppdevData->D3DHALCallbacks), lpD3DHALCallbacks->dwSize));
pHalInfo->lpD3DHALCallbacks = lpD3DHALCallbacks = &ppdevData->D3DHALCallbacks;
if (lpD3DHALCallbacks->ContextCreate && lpD3DHALCallbacks->ContextDestroy) {
if (lpD3DHALCallbacks->ContextCreate != WatchdogDdContextCreate) { ppdevData->apfnDriver[INDEX_DdContextCreate] = (PFN)lpD3DHALCallbacks->ContextCreate; }
if (lpD3DHALCallbacks->ContextDestroy != WatchdogDdContextDestroy) { ppdevData->apfnDriver[INDEX_DdContextDestroy] = (PFN)lpD3DHALCallbacks->ContextDestroy; }
lpD3DHALCallbacks->ContextCreate = WatchdogDdContextCreate; lpD3DHALCallbacks->ContextDestroy = WatchdogDdContextDestroy; } }
if (pHalInfo->lpD3DBufCallbacks) {
PDD_D3DBUFCALLBACKS lpD3DBufCallbacks;
lpD3DBufCallbacks = pHalInfo->lpD3DBufCallbacks;
//
// Create copy of D3DBufCallbacks info - This is done to safely
// latch the callbacks witout actually changing driver local data
//
memcpy(&ppdevData->D3DBufCallbacks, lpD3DBufCallbacks, min(sizeof(ppdevData->D3DBufCallbacks), lpD3DBufCallbacks->dwSize));
lpD3DBufCallbacks = pHalInfo->lpD3DBufCallbacks = &ppdevData->D3DBufCallbacks;
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, CanCreateD3DBuffer)) && (lpD3DBufCallbacks->CanCreateD3DBuffer)) {
if (lpD3DBufCallbacks->CanCreateD3DBuffer != WatchdogDdCanCreateD3DBuffer) { ppdevData->apfnDriver[INDEX_DdCanCreateD3DBuffer] = (PFN)lpD3DBufCallbacks->CanCreateD3DBuffer; } lpD3DBufCallbacks->CanCreateD3DBuffer = WatchdogDdCanCreateD3DBuffer; }
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, CreateD3DBuffer)) && (lpD3DBufCallbacks->CreateD3DBuffer)) {
if (lpD3DBufCallbacks->CreateD3DBuffer != WatchdogDdCreateD3DBuffer) { ppdevData->apfnDriver[INDEX_DdCreateD3DBuffer] = (PFN)lpD3DBufCallbacks->CreateD3DBuffer; } lpD3DBufCallbacks->CreateD3DBuffer = WatchdogDdCreateD3DBuffer; }
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, DestroyD3DBuffer)) && (lpD3DBufCallbacks->DestroyD3DBuffer)) {
if (lpD3DBufCallbacks->DestroyD3DBuffer != WatchdogDdDestroyD3DBuffer) { ppdevData->apfnDriver[INDEX_DdDestroyD3DBuffer] = (PFN)lpD3DBufCallbacks->DestroyD3DBuffer; } lpD3DBufCallbacks->DestroyD3DBuffer = WatchdogDdDestroyD3DBuffer; }
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, LockD3DBuffer)) && (lpD3DBufCallbacks->LockD3DBuffer)) {
if (lpD3DBufCallbacks->LockD3DBuffer != WatchdogDdLockD3DBuffer) { ppdevData->apfnDriver[INDEX_DdLockD3DBuffer] = (PFN)lpD3DBufCallbacks->LockD3DBuffer; } lpD3DBufCallbacks->LockD3DBuffer = WatchdogDdLockD3DBuffer; }
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, UnlockD3DBuffer)) && (lpD3DBufCallbacks->UnlockD3DBuffer)) {
if (lpD3DBufCallbacks->UnlockD3DBuffer != WatchdogDdUnlockD3DBuffer) { ppdevData->apfnDriver[INDEX_DdUnlockD3DBuffer] = (PFN)lpD3DBufCallbacks->UnlockD3DBuffer; } lpD3DBufCallbacks->UnlockD3DBuffer = WatchdogDdUnlockD3DBuffer; } } }
return bRet; }
BOOL APIENTRY WatchdogDrvEnableDirectDraw( DHPDEV dhpdev, DD_CALLBACKS *pCallBacks, DD_SURFACECALLBACKS *pSurfaceCallBacks, DD_PALETTECALLBACKS *pPaletteCallBacks )
{ PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode(dhpdev); PLDEV pldev = ppdevData->pldev; PFN_DrvEnableDirectDraw pfn = (PFN_DrvEnableDirectDraw) pldev->apfnDriver[INDEX_DrvEnableDirectDraw]; BOOL bRet = FALSE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return FALSE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(dhpdev, pCallBacks, pSurfaceCallBacks, pPaletteCallBacks);
} RECOVERY_SECTION_END(pldev);
//
// If the function succeeded, then try to capture the Callback functions.
//
if (bRet) {
//
// Capture generic callbacks
//
if (pCallBacks->dwFlags & DDHAL_CB32_CANCREATESURFACE) {
if (pCallBacks->CanCreateSurface != WatchdogDdCanCreateSurface) { ppdevData->apfnDriver[INDEX_DdCanCreateSurface] = (PFN)pCallBacks->CanCreateSurface; } pCallBacks->CanCreateSurface = WatchdogDdCanCreateSurface; }
if (pCallBacks->dwFlags & DDHAL_CB32_CREATESURFACE) {
if (pCallBacks->CreateSurface != WatchdogDdCreateSurface) { ppdevData->apfnDriver[INDEX_DdCreateSurface] = (PFN)pCallBacks->CreateSurface; } pCallBacks->CreateSurface = WatchdogDdCreateSurface; }
if (pCallBacks->dwFlags & DDHAL_CB32_CREATEPALETTE) {
if (pCallBacks->CreatePalette != WatchdogDdCreatePalette) { ppdevData->apfnDriver[INDEX_DdCreatePalette] = (PFN)pCallBacks->CreatePalette; } pCallBacks->CreatePalette = WatchdogDdCreatePalette; }
if (pCallBacks->dwFlags & DDHAL_CB32_GETSCANLINE) {
if (pCallBacks->GetScanLine != WatchdogDdGetScanLine) { ppdevData->apfnDriver[INDEX_DdGetScanLine] = (PFN)pCallBacks->GetScanLine; } pCallBacks->GetScanLine = WatchdogDdGetScanLine; }
if (pCallBacks->dwFlags & DDHAL_CB32_MAPMEMORY) {
if (pCallBacks->MapMemory != WatchdogDdMapMemory) { ppdevData->apfnDriver[INDEX_DdMapMemory] = (PFN)pCallBacks->MapMemory; } pCallBacks->MapMemory = WatchdogDdMapMemory; }
#if 0
//
// We can't hook this because there is no way to get the dhpdev
// back
//
if (pCallBacks->dwFlags & DDHAL_CB32_SETCOLORKEY) {
if (pCallBacks->SetColorKey != WatchdogDdSetColorKey) { ppdevData->apfnDriver[INDEX_DdSetColorKey] = (PFN)pCallBacks->SetColorKey; } pCallBacks->SetColorKey = WatchdogDdSetColorKey; } #endif
if (pCallBacks->dwFlags & DDHAL_CB32_WAITFORVERTICALBLANK) {
if (pCallBacks->WaitForVerticalBlank != WatchdogDdWaitForVerticalBlank) { ppdevData->apfnDriver[INDEX_DdWaitForVerticalBlank] = (PFN)pCallBacks->WaitForVerticalBlank; } pCallBacks->WaitForVerticalBlank = WatchdogDdWaitForVerticalBlank; }
//
// Capture Surface Callbacks
//
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_DESTROYSURFACE) {
if (pSurfaceCallBacks->DestroySurface != WatchdogDdDestroySurface) { ppdevData->apfnDriver[INDEX_DdDestroySurface] = (PFN)pSurfaceCallBacks->DestroySurface; } pSurfaceCallBacks->DestroySurface = WatchdogDdDestroySurface; }
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_FLIP) {
if (pSurfaceCallBacks->Flip != WatchdogDdFlip) { ppdevData->apfnDriver[INDEX_DdFlip] = (PFN)pSurfaceCallBacks->Flip; } pSurfaceCallBacks->Flip = WatchdogDdFlip; }
#if 0
//
// SetClipList is obsolete
//
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETCLIPLIST) {
if (pSurfaceCallBacks->SetClipList != WatchdogDdSetClipList) { ppdevData->apfnDriver[INDEX_DdSetClipList] = (PFN)pSurfaceCallBacks->SetClipList; } pSurfaceCallBacks->SetClipList = WatchdogDdSetClipList; } #endif
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_LOCK) {
if (pSurfaceCallBacks->Lock != WatchdogDdLock) { ppdevData->apfnDriver[INDEX_DdLock] = (PFN)pSurfaceCallBacks->Lock; } pSurfaceCallBacks->Lock = WatchdogDdLock; }
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_UNLOCK) {
if (pSurfaceCallBacks->Unlock != WatchdogDdUnlock) { ppdevData->apfnDriver[INDEX_DdUnlock] = (PFN)pSurfaceCallBacks->Unlock; } pSurfaceCallBacks->Unlock = WatchdogDdUnlock; }
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_BLT) {
if (pSurfaceCallBacks->Blt != WatchdogDdBlt) { ppdevData->apfnDriver[INDEX_DdBlt] = (PFN)pSurfaceCallBacks->Blt; } pSurfaceCallBacks->Blt = WatchdogDdBlt; }
#if 0
//
// We can't hook this because there is no way to get the dhpdev
// back
//
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETCOLORKEY) {
if (pSurfaceCallBacks->SetColorKey != WatchdogDdSetColorKey) { ppdevData->apfnDriver[INDEX_DdSetColorKey] = (PFN)pSurfaceCallBacks->SetColorKey; } pSurfaceCallBacks->SetColorKey = WatchdogDdSetColorKey; } #endif
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_ADDATTACHEDSURFACE) {
if (pSurfaceCallBacks->AddAttachedSurface != WatchdogDdAddAttachedSurface) { ppdevData->apfnDriver[INDEX_DdAddAttachedSurface] = (PFN)pSurfaceCallBacks->AddAttachedSurface; } pSurfaceCallBacks->AddAttachedSurface = WatchdogDdAddAttachedSurface; }
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_GETBLTSTATUS) {
if (pSurfaceCallBacks->GetBltStatus != WatchdogDdGetBltStatus) { ppdevData->apfnDriver[INDEX_DdGetBltStatus] = (PFN)pSurfaceCallBacks->GetBltStatus; } pSurfaceCallBacks->GetBltStatus = WatchdogDdGetBltStatus; }
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_GETFLIPSTATUS) {
if (pSurfaceCallBacks->GetFlipStatus != WatchdogDdGetFlipStatus) { ppdevData->apfnDriver[INDEX_DdGetFlipStatus] = (PFN)pSurfaceCallBacks->GetFlipStatus; } pSurfaceCallBacks->GetFlipStatus = WatchdogDdGetFlipStatus; }
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_UPDATEOVERLAY) {
if (pSurfaceCallBacks->UpdateOverlay != WatchdogDdUpdateOverlay) { ppdevData->apfnDriver[INDEX_DdUpdateOverlay] = (PFN)pSurfaceCallBacks->UpdateOverlay; } pSurfaceCallBacks->UpdateOverlay = WatchdogDdUpdateOverlay; }
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETOVERLAYPOSITION) {
if (pSurfaceCallBacks->SetOverlayPosition != WatchdogDdSetOverlayPosition) { ppdevData->apfnDriver[INDEX_DdSetOverlayPosition] = (PFN)pSurfaceCallBacks->SetOverlayPosition; } pSurfaceCallBacks->SetOverlayPosition = WatchdogDdSetOverlayPosition; }
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETPALETTE) {
if (pSurfaceCallBacks->SetPalette != WatchdogDdSetPalette) { ppdevData->apfnDriver[INDEX_DdSetPalette] = (PFN)pSurfaceCallBacks->SetPalette; } pSurfaceCallBacks->SetPalette = WatchdogDdSetPalette; }
//
// Capture Palette Callbacks
//
if (pPaletteCallBacks->dwFlags & DDHAL_PALCB32_DESTROYPALETTE) {
if (pPaletteCallBacks->DestroyPalette != WatchdogDdDestroyPalette) { ppdevData->apfnDriver[INDEX_DdDestroyPalette] = (PFN)pPaletteCallBacks->DestroyPalette; } pPaletteCallBacks->DestroyPalette = WatchdogDdDestroyPalette; }
if (pPaletteCallBacks->dwFlags & DDHAL_PALCB32_SETENTRIES) {
if (pPaletteCallBacks->SetEntries != WatchdogDdSetEntries) { ppdevData->apfnDriver[INDEX_DdSetEntries] = (PFN)pPaletteCallBacks->SetEntries; } pPaletteCallBacks->SetEntries = WatchdogDdSetEntries; } }
return bRet; }
VOID APIENTRY WatchdogDrvDisableDirectDraw( DHPDEV dhpdev )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvDisableDirectDraw pfn = (PFN_DrvDisableDirectDraw) pldev->apfnDriver[INDEX_DrvDisableDirectDraw];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(dhpdev);
} RECOVERY_SECTION_END(pldev); }
BOOL APIENTRY WatchdogDrvIcmSetDeviceGammaRamp( IN DHPDEV dhpdev, IN ULONG iFormat, IN LPVOID ipRamp )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvIcmSetDeviceGammaRamp pfn = (PFN_DrvIcmSetDeviceGammaRamp) pldev->apfnDriver[INDEX_DrvIcmSetDeviceGammaRamp]; BOOL bRet = TRUE;
if (pldev->bThreadStuck) { return bRet; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(dhpdev, iFormat, ipRamp);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvStretchBltROP( SURFOBJ *psoDst, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, COLORADJUSTMENT *pca, POINTL *pptlHTOrg, RECTL *prclDst, RECTL *prclSrc, POINTL *pptlMask, ULONG iMode, BRUSHOBJ *pbo, DWORD rop4 )
{ SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc; PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev); PFN_DrvStretchBltROP pfn = (PFN_DrvStretchBltROP) pldev->apfnDriver[INDEX_DrvStretchBltROP]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMask, iMode, pbo, rop4);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvPlgBlt( IN SURFOBJ *psoTrg, IN SURFOBJ *psoSrc, IN SURFOBJ *psoMsk, IN CLIPOBJ *pco, IN XLATEOBJ *pxlo, IN COLORADJUSTMENT *pca, IN POINTL *pptlBrushOrg, IN POINTFIX *pptfx, IN RECTL *prcl, IN POINTL *pptl, IN ULONG iMode )
{ PLDEV pldev = dhpdevRetrieveLdev(psoTrg->dhpdev); PFN_DrvPlgBlt pfn = (PFN_DrvPlgBlt) pldev->apfnDriver[INDEX_DrvPlgBlt]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(psoTrg, psoSrc, psoMsk, pco, pxlo, pca, pptlBrushOrg, pptfx, prcl, pptl, iMode);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvAlphaBlend( SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDest, RECTL *prclSrc, BLENDOBJ *pBlendObj )
{ SURFOBJ *psoDevice = (psoDest->dhpdev) ? psoDest : psoSrc; PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev); PFN_DrvAlphaBlend pfn = (PFN_DrvAlphaBlend) pldev->apfnDriver[INDEX_DrvAlphaBlend]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(psoDest, psoSrc, pco, pxlo, prclDest, prclSrc, pBlendObj);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvGradientFill( SURFOBJ *psoDest, CLIPOBJ *pco, XLATEOBJ *pxlo, TRIVERTEX *pVertex, ULONG nVertex, PVOID pMesh, ULONG nMesh, RECTL *prclExtents, POINTL *pptlDitherOrg, ULONG ulMode )
{ PLDEV pldev = dhpdevRetrieveLdev(psoDest->dhpdev); PFN_DrvGradientFill pfn = (PFN_DrvGradientFill) pldev->apfnDriver[INDEX_DrvGradientFill]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents, pptlDitherOrg, ulMode);
} RECOVERY_SECTION_END(pldev);
return bRet; }
BOOL APIENTRY WatchdogDrvTransparentBlt( SURFOBJ *psoDst, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDst, RECTL *prclSrc, ULONG iTransColor, ULONG ulReserved )
{ SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc; PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev); PFN_DrvTransparentBlt pfn = (PFN_DrvTransparentBlt) pldev->apfnDriver[INDEX_DrvTransparentBlt]; BOOL bRet = TRUE;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return TRUE; }
RECOVERY_SECTION_BEGIN(pldev) {
bRet = pfn(psoDst, psoSrc, pco, pxlo, prclDst, prclSrc, iTransColor, ulReserved);
} RECOVERY_SECTION_END(pldev);
return bRet; }
HBITMAP APIENTRY WatchdogDrvDeriveSurface( DD_DIRECTDRAW_GLOBAL *pDirectDraw, DD_SURFACE_LOCAL *pSurface )
{ PLDEV pldev = dhpdevRetrieveLdev((DHPDEV)pDirectDraw->dhpdev); PFN_DrvDeriveSurface pfn = (PFN_DrvDeriveSurface) pldev->apfnDriver[INDEX_DrvDeriveSurface]; HBITMAP hBitmap = NULL;
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck == FALSE) { RECOVERY_SECTION_BEGIN(pldev) {
hBitmap = pfn(pDirectDraw, pSurface);
} RECOVERY_SECTION_END(pldev); }
return hBitmap; }
VOID APIENTRY WatchdogDrvNotify( IN SURFOBJ *pso, IN ULONG iType, IN PVOID pvData )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvNotify pfn = (PFN_DrvNotify) pldev->apfnDriver[INDEX_DrvNotify];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(pso, iType, pvData);
} RECOVERY_SECTION_END(pldev); }
VOID APIENTRY WatchdogDrvSynchronizeSurface( IN SURFOBJ *pso, IN RECTL *prcl, IN FLONG fl )
{ PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev); PFN_DrvSynchronizeSurface pfn = (PFN_DrvSynchronizeSurface) pldev->apfnDriver[INDEX_DrvSynchronizeSurface];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(pso, prcl, fl);
} RECOVERY_SECTION_END(pldev); }
VOID APIENTRY WatchdogDrvResetDevice( DHPDEV dhpdev, PVOID Reserved )
{ PLDEV pldev = dhpdevRetrieveLdev(dhpdev); PFN_DrvResetDevice pfn = (PFN_DrvResetDevice) pldev->apfnDriver[INDEX_DrvResetDevice];
//
// Return early if we are in a thread stuck condition
//
if (pldev->bThreadStuck) { return; }
RECOVERY_SECTION_BEGIN(pldev) {
pfn(dhpdev, Reserved);
} RECOVERY_SECTION_END(pldev); }
//
// The following table contains the replacement functions which
// hooks the real driver entry points, and set up the try/except
// handlers.
//
PFN WatchdogTable[INDEX_LAST] = { (PFN)WatchdogDrvEnablePDEV, (PFN)WatchdogDrvCompletePDEV, (PFN)WatchdogDrvDisablePDEV, (PFN)WatchdogDrvEnableSurface, (PFN)WatchdogDrvDisableSurface,
(PFN)WatchdogDrvAssertMode, 0, // DrvOffset - obsolete
(PFN)WatchdogDrvResetPDEV, 0, // DrvDisableDriver - don't hook
0, // not assigned
(PFN)WatchdogDrvCreateDeviceBitmap, (PFN)WatchdogDrvDeleteDeviceBitmap, (PFN)WatchdogDrvRealizeBrush, (PFN)WatchdogDrvDitherColor, (PFN)WatchdogDrvStrokePath,
(PFN)WatchdogDrvFillPath, (PFN)WatchdogDrvStrokeAndFillPath, 0, // DrvPaint - obsolete
(PFN)WatchdogDrvBitBlt, (PFN)WatchdogDrvCopyBits,
(PFN)WatchdogDrvStretchBlt, 0, // not assigned
(PFN)WatchdogDrvSetPalette, (PFN)WatchdogDrvTextOut, (PFN)WatchdogDrvEscape,
(PFN)WatchdogDrvDrawEscape, 0, // DrvQueryFont
0, // DrvQueryFontTree
0, // DrvQueryFontData
(PFN)WatchdogDrvSetPointerShape,
(PFN)WatchdogDrvMovePointer, (PFN)WatchdogDrvLineTo, 0, // DrvSendPage
0, // DrvStartPage
0, // DrvEndDoc
0, // DrvStartDoc
0, // not assigned
0, // DrvGetGlyphMode
(PFN)WatchdogDrvSynchronize, 0, // not assigned
(PFN)WatchdogDrvSaveScreenBits, 0, // DrvGetModes - don't hook
0, // DrvFree
0, // DrvDestroyFont
0, // DrvQueryFontCaps
0, // DrvLoadFontFile
0, // DrvUnloadFontFile
0, // DrvFontManagement
0, // DrvQueryTrueTypeTable
0, // DrvQueryTrueTypeOutline
0, // DrvGetTrueTypeFile
0, // DrvQueryFontFile
0, // DrvMovePanning
0, // DrvQueryAdvanceWidths
(PFN)WatchdogDrvSetPixelFormat,
(PFN)WatchdogDrvDescribePixelFormat, (PFN)WatchdogDrvSwapBuffers, 0, // DrvStartBanding
0, // DrvNextBand
(PFN)WatchdogDrvGetDirectDrawInfo,
(PFN)WatchdogDrvEnableDirectDraw, (PFN)WatchdogDrvDisableDirectDraw, 0, // DrvQuerySpoolType
0, // not assigned
0, // DrvIcmCreateColorTransform
0, // DrvIcmDeleteColorTransform
0, // DrvIcmCheckBitmapBits
(PFN)WatchdogDrvIcmSetDeviceGammaRamp, (PFN)WatchdogDrvGradientFill, (PFN)WatchdogDrvStretchBltROP,
(PFN)WatchdogDrvPlgBlt, (PFN)WatchdogDrvAlphaBlend, 0, // DrvSynthesizeFont
0, // DrvGetSynthesizedFontFiles
(PFN)WatchdogDrvTransparentBlt,
0, // DrvQueryPerBandInfo
0, // DrvQueryDeviceSupport
0, // reserved
0, // reserved
0, // reserved
0, // reserved
0, // reserved
0, // reserved
0, // reserved
0, // reserved
(PFN)WatchdogDrvDeriveSurface, 0, // DrvQueryGlyphAttrs
(PFN)WatchdogDrvNotify, (PFN)WatchdogDrvSynchronizeSurface, (PFN)WatchdogDrvResetDevice,
0, // reserved
0, // reserved
0 // reserved
};
BOOL WatchdogIsFunctionHooked( IN PLDEV pldev, IN ULONG functionIndex )
/*++
Routine Description:
This function checks to see whether the Create/DeleteDeviceBitmap driver entry points are hooked.
Return Value:
TRUE if the entry point is hooked, FALSE otherwise
--*/
{ ASSERTGDI(functionIndex < INDEX_LAST, "functionIndex out of range"); return pldev->apfn[functionIndex] == WatchdogTable[functionIndex]; }
|