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