Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3545 lines
89 KiB

/******************************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];
}