3338 lines
83 KiB
C++
3338 lines
83 KiB
C++
/******************************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)
|
|
|
|
typedef struct _CONTEXT_NODE
|
|
{
|
|
PVOID Context;
|
|
PLDEV pldev;
|
|
} CONTEXT_NODE, *PCONTEXT_NODE;
|
|
|
|
PASSOCIATION_NODE gAssociationList = NULL;
|
|
|
|
//
|
|
// The following routines are used to maintain an association between the
|
|
// data actually passed into a driver entry point, and the LDEV for the
|
|
// driver. We need this association because we need access to the LDEV
|
|
// in order to look up the actual driver entry point.
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
PASSOCIATION_NODE
|
|
AssociationCreateNode(
|
|
VOID
|
|
)
|
|
|
|
{
|
|
PASSOCIATION_NODE Node;
|
|
|
|
Node = (PASSOCIATION_NODE) PALLOCMEM(sizeof(ASSOCIATION_NODE), GDITAG_DRVSUP);
|
|
|
|
return Node;
|
|
}
|
|
|
|
VOID
|
|
AssociationDeleteNode(
|
|
PASSOCIATION_NODE Node
|
|
)
|
|
|
|
{
|
|
if (Node) {
|
|
VFREEMEM(Node);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
AssociationInsertNode(
|
|
PASSOCIATION_NODE Node
|
|
)
|
|
|
|
{
|
|
GreAcquireFastMutex(gAssociationListMutex);
|
|
|
|
Node->next = gAssociationList;
|
|
gAssociationList = Node;
|
|
|
|
GreReleaseFastMutex(gAssociationListMutex);
|
|
}
|
|
|
|
VOID
|
|
AssociationInsertNodeAtTail(
|
|
PASSOCIATION_NODE Node
|
|
)
|
|
|
|
{
|
|
GreAcquireFastMutex(gAssociationListMutex);
|
|
|
|
if (gAssociationList) {
|
|
|
|
PASSOCIATION_NODE Curr;
|
|
|
|
Curr = gAssociationList;
|
|
|
|
while (Curr && Curr->next) {
|
|
Curr = Curr->next;
|
|
}
|
|
|
|
//
|
|
// The following test for NULL is not really required, but I
|
|
// added it to make prefast happy.
|
|
//
|
|
|
|
if (Curr) {
|
|
Curr->next = Node;
|
|
}
|
|
|
|
} else {
|
|
|
|
gAssociationList = Node;
|
|
}
|
|
|
|
GreReleaseFastMutex(gAssociationListMutex);
|
|
}
|
|
|
|
PASSOCIATION_NODE
|
|
AssociationRemoveNode(
|
|
ULONG_PTR key
|
|
)
|
|
|
|
{
|
|
PASSOCIATION_NODE Node;
|
|
|
|
GreAcquireFastMutex(gAssociationListMutex);
|
|
|
|
//
|
|
// first find the correct node
|
|
//
|
|
|
|
Node = gAssociationList;
|
|
|
|
while (Node && (Node->key != key)) {
|
|
Node = Node->next;
|
|
}
|
|
|
|
if (Node) {
|
|
|
|
if (gAssociationList == Node) {
|
|
|
|
gAssociationList = Node->next;
|
|
|
|
} else {
|
|
|
|
PASSOCIATION_NODE curr = gAssociationList;
|
|
|
|
while (curr && (curr->next != Node)) {
|
|
curr = curr->next;
|
|
}
|
|
|
|
if (curr) {
|
|
curr->next = Node->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
GreReleaseFastMutex(gAssociationListMutex);
|
|
|
|
return Node;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
AssociationIsNodeInList(
|
|
PASSOCIATION_NODE Node
|
|
)
|
|
|
|
{
|
|
PASSOCIATION_NODE Curr = gAssociationList;
|
|
|
|
while (Curr) {
|
|
|
|
//
|
|
// We only have to check if the key and the hsurf value
|
|
// are similar.
|
|
//
|
|
|
|
if ((Curr->key == Node->key) &&
|
|
(Curr->hsurf == Node->hsurf)) {
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Curr = Curr->next;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
ULONG_PTR
|
|
AssociationRetrieveData(
|
|
ULONG_PTR key
|
|
)
|
|
|
|
{
|
|
|
|
PASSOCIATION_NODE Node;
|
|
|
|
GreAcquireFastMutex(gAssociationListMutex);
|
|
|
|
Node = gAssociationList;
|
|
|
|
while (Node) {
|
|
|
|
if (Node->key == key) {
|
|
break;
|
|
}
|
|
|
|
Node = Node->next;
|
|
}
|
|
|
|
GreReleaseFastMutex(gAssociationListMutex);
|
|
|
|
if (Node) {
|
|
return Node->data;
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
PFN
|
|
dhpdevRetrievePfn(
|
|
ULONG_PTR dhpdev,
|
|
ULONG Index
|
|
)
|
|
|
|
{
|
|
PLDEV pldev = (PLDEV)AssociationRetrieveData(dhpdev);
|
|
return pldev->apfnDriver[Index];
|
|
}
|
|
|
|
PLDEV
|
|
dhpdevRetrieveLdev(
|
|
DHPDEV dhpdev
|
|
)
|
|
|
|
{
|
|
return (PLDEV)AssociationRetrieveData((ULONG_PTR)dhpdev);
|
|
}
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
PKEVENT StuckThreadEvent;
|
|
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];
|
|
PASSOCIATION_NODE Node = AssociationCreateNode();
|
|
|
|
if (Node) {
|
|
|
|
Node->data = (ULONG_PTR)ppdev->pldev;
|
|
Node->key = NULL;
|
|
|
|
__try {
|
|
|
|
Node->key = (ULONG_PTR)pfn(pdm,
|
|
pwszLogAddress,
|
|
cPat,
|
|
phsurfPatterns,
|
|
cjCaps,
|
|
(GDIINFO *)pdevcaps,
|
|
cjDevInfo,
|
|
pdi,
|
|
hdev,
|
|
pwszDeviceName,
|
|
hDriver);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(ppdev->pldev);
|
|
}
|
|
|
|
if (Node->key) {
|
|
|
|
dhpdevRet = (DHPDEV) Node->key;
|
|
|
|
AssociationInsertNode(Node);
|
|
|
|
} else {
|
|
|
|
AssociationDeleteNode(Node);
|
|
}
|
|
}
|
|
}
|
|
|
|
return dhpdevRet;
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvCompletePDEV(
|
|
DHPDEV dhpdev,
|
|
HDEV hdev
|
|
)
|
|
|
|
{
|
|
PFN_DrvCompletePDEV pfn = (PFN_DrvCompletePDEV) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvCompletePDEV);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(dhpdev, hdev);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvDisablePDEV(
|
|
DHPDEV dhpdev
|
|
)
|
|
|
|
{
|
|
PFN_DrvDisablePDEV pfn = (PFN_DrvDisablePDEV) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvDisablePDEV);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(dhpdev);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
AssociationDeleteNode(AssociationRemoveNode((ULONG_PTR)dhpdev));
|
|
}
|
|
|
|
HSURF APIENTRY
|
|
WatchdogDrvEnableSurface(
|
|
DHPDEV dhpdev
|
|
)
|
|
|
|
{
|
|
PFN_DrvEnableSurface pfn = (PFN_DrvEnableSurface) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvEnableSurface);
|
|
HSURF hsurfRet = NULL;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return NULL;
|
|
}
|
|
|
|
__try {
|
|
|
|
hsurfRet = pfn(dhpdev);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
return hsurfRet;
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvDisableSurface(
|
|
DHPDEV dhpdev
|
|
)
|
|
|
|
{
|
|
PFN_DrvDisableSurface pfn = (PFN_DrvDisableSurface) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvDisableSurface);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(dhpdev);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvAssertMode(
|
|
DHPDEV dhpdev,
|
|
BOOL bEnable
|
|
)
|
|
|
|
{
|
|
PFN_DrvAssertMode pfn = (PFN_DrvAssertMode) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvAssertMode);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(dhpdev, bEnable);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvResetPDEV(
|
|
DHPDEV dhpdevOld,
|
|
DHPDEV dhpdevNew
|
|
)
|
|
|
|
{
|
|
PFN_DrvResetPDEV pfn = (PFN_DrvResetPDEV) dhpdevRetrievePfn((ULONG_PTR)dhpdevOld,INDEX_DrvResetPDEV);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdevOld)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(dhpdevOld, dhpdevNew);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdevOld));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
HBITMAP APIENTRY
|
|
WatchdogDrvCreateDeviceBitmap(
|
|
DHPDEV dhpdev,
|
|
SIZEL sizl,
|
|
ULONG iFormat
|
|
)
|
|
|
|
{
|
|
PFN_DrvCreateDeviceBitmap pfn = (PFN_DrvCreateDeviceBitmap) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvCreateDeviceBitmap);
|
|
HBITMAP hbitmapRet = NULL;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck == FALSE) {
|
|
|
|
PASSOCIATION_NODE Node = AssociationCreateNode();
|
|
|
|
if (Node) {
|
|
|
|
__try {
|
|
|
|
hbitmapRet = pfn(dhpdev, sizl, iFormat);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
if (hbitmapRet && ((ULONG_PTR)hbitmapRet != -1)) {
|
|
|
|
//
|
|
// Get the DHSURF that is associated with the hbitmap, and
|
|
// cache it away so we can look it up when a DrvDeleteDeviceBitmap
|
|
// call comes down.
|
|
//
|
|
|
|
SURFREF so;
|
|
|
|
so.vAltCheckLockIgnoreStockBit((HSURF)hbitmapRet);
|
|
|
|
Node->key = (ULONG_PTR)so.ps->dhsurf();
|
|
Node->data = (ULONG_PTR)dhpdevRetrieveLdev(dhpdev);
|
|
Node->hsurf = (ULONG_PTR)hbitmapRet;
|
|
|
|
//
|
|
// If an association node already exists, with this association
|
|
// then use it.
|
|
//
|
|
|
|
if (AssociationIsNodeInList(Node) == FALSE) {
|
|
|
|
AssociationInsertNodeAtTail(Node);
|
|
|
|
} else {
|
|
|
|
AssociationDeleteNode(Node);
|
|
}
|
|
|
|
} else {
|
|
|
|
AssociationDeleteNode(Node);
|
|
}
|
|
}
|
|
}
|
|
|
|
return hbitmapRet;
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvDeleteDeviceBitmap(
|
|
IN DHSURF dhsurf
|
|
)
|
|
|
|
{
|
|
PFN_DrvDeleteDeviceBitmap pfn = (PFN_DrvDeleteDeviceBitmap) dhpdevRetrievePfn((ULONG_PTR)dhsurf,INDEX_DrvDeleteDeviceBitmap);
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)dhsurf)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(dhsurf);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)dhsurf));
|
|
}
|
|
|
|
AssociationDeleteNode(AssociationRemoveNode((ULONG_PTR)dhsurf));
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvRealizeBrush(
|
|
BRUSHOBJ *pbo,
|
|
SURFOBJ *psoTarget,
|
|
SURFOBJ *psoPattern,
|
|
SURFOBJ *psoMask,
|
|
XLATEOBJ *pxlo,
|
|
ULONG iHatch
|
|
)
|
|
|
|
{
|
|
PFN_DrvRealizeBrush pfn = (PFN_DrvRealizeBrush) dhpdevRetrievePfn((ULONG_PTR)psoTarget->dhpdev,INDEX_DrvRealizeBrush);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoTarget->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(pbo, psoTarget, psoPattern, psoMask, pxlo, iHatch);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoTarget->dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
ULONG APIENTRY
|
|
WatchdogDrvDitherColor(
|
|
DHPDEV dhpdev,
|
|
ULONG iMode,
|
|
ULONG rgb,
|
|
ULONG *pul
|
|
)
|
|
|
|
{
|
|
PFN_DrvDitherColor pfn = (PFN_DrvDitherColor) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvDitherColor);
|
|
ULONG ulRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
ulRet = pfn(dhpdev, iMode, rgb, pul);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
return ulRet;
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvStrokePath(
|
|
SURFOBJ *pso,
|
|
PATHOBJ *ppo,
|
|
CLIPOBJ *pco,
|
|
XFORMOBJ *pxo,
|
|
BRUSHOBJ *pbo,
|
|
POINTL *pptlBrushOrg,
|
|
LINEATTRS *plineattrs,
|
|
MIX mix
|
|
)
|
|
|
|
{
|
|
PFN_DrvStrokePath pfn = (PFN_DrvStrokePath) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvStrokePath);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(pso, ppo, pco, pxo, pbo, pptlBrushOrg, plineattrs, mix);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvFillPath(
|
|
SURFOBJ *pso,
|
|
PATHOBJ *ppo,
|
|
CLIPOBJ *pco,
|
|
BRUSHOBJ *pbo,
|
|
POINTL *pptlBrushOrg,
|
|
MIX mix,
|
|
FLONG flOptions
|
|
)
|
|
|
|
{
|
|
PFN_DrvFillPath pfn = (PFN_DrvFillPath) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvFillPath);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(pso, ppo, pco, pbo, pptlBrushOrg, mix, flOptions);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
{
|
|
PFN_DrvStrokeAndFillPath pfn = (PFN_DrvStrokeAndFillPath) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvStrokeAndFillPath);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(pso, ppo, pco, pxo, pboStroke, plineattrs, pboFill, pptlBrushOrg, mixFill, flOptions);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
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;
|
|
PFN_DrvBitBlt pfn = (PFN_DrvBitBlt) dhpdevRetrievePfn((ULONG_PTR)psoDevice->dhpdev,INDEX_DrvBitBlt);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoDevice->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, prclDst, pptlSrc, pptlMask, pbo, pptlBrush, rop4);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoDevice->dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvCopyBits(
|
|
SURFOBJ *psoDst,
|
|
SURFOBJ *psoSrc,
|
|
CLIPOBJ *pco,
|
|
XLATEOBJ *pxlo,
|
|
RECTL *prclDst,
|
|
POINTL *pptlSrc
|
|
)
|
|
|
|
{
|
|
SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc;
|
|
PFN_DrvCopyBits pfn = (PFN_DrvCopyBits) dhpdevRetrievePfn((ULONG_PTR)psoDevice->dhpdev,INDEX_DrvCopyBits);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoDevice->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(psoDst, psoSrc, pco, pxlo, prclDst, pptlSrc);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoDevice->dhpdev));
|
|
}
|
|
|
|
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;
|
|
PFN_DrvStretchBlt pfn = (PFN_DrvStretchBlt) dhpdevRetrievePfn((ULONG_PTR)psoDevice->dhpdev,INDEX_DrvStretchBlt);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoDevice->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMask, iMode);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoDevice->dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
ULONG APIENTRY
|
|
WatchdogDrvSetPalette(
|
|
DHPDEV dhpdev,
|
|
PALOBJ *ppalo,
|
|
FLONG fl,
|
|
ULONG iStart,
|
|
ULONG cColors
|
|
)
|
|
|
|
{
|
|
PFN_DrvSetPalette pfn = (PFN_DrvSetPalette) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvSetPalette);
|
|
ULONG ulRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
ulRet = pfn(dhpdev, ppalo, fl, iStart, cColors);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
{
|
|
PFN_DrvTextOut pfn = (PFN_DrvTextOut) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvTextOut);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(pso, pstro, pfo, pco, prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
ULONG APIENTRY
|
|
WatchdogDrvEscape(
|
|
SURFOBJ *pso,
|
|
ULONG iEsc,
|
|
ULONG cjIn,
|
|
PVOID pvIn,
|
|
ULONG cjOut,
|
|
PVOID pvOut
|
|
)
|
|
|
|
{
|
|
PFN_DrvEscape pfn = (PFN_DrvEscape) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvEscape);
|
|
ULONG ulRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
ulRet = pfn(pso, iEsc, cjIn, pvIn, cjOut, pvOut);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
return ulRet;
|
|
}
|
|
|
|
ULONG APIENTRY
|
|
WatchdogDrvDrawEscape(
|
|
IN SURFOBJ *pso,
|
|
IN ULONG iEsc,
|
|
IN CLIPOBJ *pco,
|
|
IN RECTL *prcl,
|
|
IN ULONG cjIn,
|
|
IN PVOID pvIn
|
|
)
|
|
|
|
{
|
|
PFN_DrvDrawEscape pfn = (PFN_DrvDrawEscape) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvDrawEscape);
|
|
ULONG ulRet = -1;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return -1;
|
|
}
|
|
|
|
__try {
|
|
|
|
ulRet = pfn(pso, iEsc, pco, prcl, cjIn, pvIn);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
{
|
|
PFN_DrvSetPointerShape pfn = (PFN_DrvSetPointerShape) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvSetPointerShape);
|
|
ULONG ulRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
ulRet = pfn(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
return ulRet;
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvMovePointer(
|
|
SURFOBJ *pso,
|
|
LONG x,
|
|
LONG y,
|
|
RECTL *prcl
|
|
)
|
|
|
|
{
|
|
PFN_DrvMovePointer pfn = (PFN_DrvMovePointer) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvMovePointer);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(pso, x, y, prcl);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvLineTo(
|
|
SURFOBJ *pso,
|
|
CLIPOBJ *pco,
|
|
BRUSHOBJ *pbo,
|
|
LONG x1,
|
|
LONG y1,
|
|
LONG x2,
|
|
LONG y2,
|
|
RECTL *prclBounds,
|
|
MIX mix
|
|
)
|
|
|
|
{
|
|
PFN_DrvLineTo pfn = (PFN_DrvLineTo) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvLineTo);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(pso, pco, pbo, x1, y1, x2, y2, prclBounds, mix);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvSynchronize(
|
|
DHPDEV dhpdev,
|
|
RECTL *prcl
|
|
)
|
|
|
|
{
|
|
PFN_DrvSynchronize pfn = (PFN_DrvSynchronize) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvSynchronize);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(dhpdev, prcl);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
}
|
|
|
|
ULONG_PTR APIENTRY
|
|
WatchdogDrvSaveScreenBits(
|
|
SURFOBJ *pso,
|
|
ULONG iMode,
|
|
ULONG_PTR ident,
|
|
RECTL *prcl
|
|
)
|
|
|
|
{
|
|
PFN_DrvSaveScreenBits pfn = (PFN_DrvSaveScreenBits) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvSaveScreenBits);
|
|
ULONG_PTR ulptrRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
ulptrRet = pfn(pso, iMode, ident, prcl);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
return ulptrRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDrvSetPixelFormat(
|
|
IN SURFOBJ *pso,
|
|
IN LONG iPixelFormat,
|
|
IN HWND hwnd
|
|
)
|
|
|
|
{
|
|
PFN_DrvSetPixelFormat pfn = (PFN_DrvSetPixelFormat) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvSetPixelFormat);
|
|
DWORD dwRet = FALSE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(pso, iPixelFormat, hwnd);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
LONG APIENTRY
|
|
WatchdogDrvDescribePixelFormat(
|
|
IN DHPDEV dhpdev,
|
|
IN LONG iPixelFormat,
|
|
IN ULONG cjpdf,
|
|
OUT PIXELFORMATDESCRIPTOR *ppfd
|
|
)
|
|
|
|
{
|
|
PFN_DrvDescribePixelFormat pfn = (PFN_DrvDescribePixelFormat) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvDescribePixelFormat);
|
|
LONG lRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
lRet = pfn(dhpdev, iPixelFormat, cjpdf, ppfd);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvSwapBuffers(
|
|
IN SURFOBJ *pso,
|
|
IN WNDOBJ *pwo
|
|
)
|
|
|
|
{
|
|
PFN_DrvSwapBuffers pfn = (PFN_DrvSwapBuffers) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev,INDEX_DrvSwapBuffers);
|
|
BOOL bRet = FALSE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(pso, pwo);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdContextCreate(
|
|
LPD3DNTHAL_CONTEXTCREATEDATA pccd
|
|
)
|
|
|
|
{
|
|
PLDEV pldev = (PLDEV)AssociationRetrieveData((ULONG_PTR)pccd->lpDDLcl->lpGbl->dhpdev);
|
|
LPD3DNTHAL_CONTEXTCREATECB pfn = (LPD3DNTHAL_CONTEXTCREATECB) pldev->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(ASSOCIATION_NODE), GDITAG_DRVSUP);
|
|
|
|
if (Node) {
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(pccd);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(pldev);
|
|
}
|
|
|
|
if (dwRet == DDHAL_DRIVER_HANDLED) {
|
|
|
|
//
|
|
// Store the dwhContext and the associated dhpdev
|
|
//
|
|
|
|
Node->Context = (PVOID)pccd->dwhContext;
|
|
Node->pldev = pldev;
|
|
|
|
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->pldev->apfnDriver[INDEX_DdContextDestroy];
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (Node->pldev->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Restore driver created context
|
|
//
|
|
|
|
pcdd->dwhContext = (DWORD_PTR) Node->Context;
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(pcdd);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)pcdd->dwhContext));
|
|
}
|
|
|
|
//
|
|
// 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
|
|
)
|
|
|
|
{
|
|
PDD_CANCREATESURFACE pfn = (PDD_CANCREATESURFACE) dhpdevRetrievePfn((ULONG_PTR)lpCanCreateSurface->lpDD->dhpdev,INDEX_DdCanCreateSurface);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpCanCreateSurface->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpCanCreateSurface);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpCanCreateSurface->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdCreateSurface(
|
|
PDD_CREATESURFACEDATA lpCreateSurface
|
|
)
|
|
|
|
{
|
|
PDD_CREATESURFACE pfn = (PDD_CREATESURFACE) dhpdevRetrievePfn((ULONG_PTR)lpCreateSurface->lpDD->dhpdev,INDEX_DdCreateSurface);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpCreateSurface->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpCreateSurface);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpCreateSurface->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdDestroySurface(
|
|
PDD_DESTROYSURFACEDATA lpDestroySurface
|
|
)
|
|
|
|
{
|
|
PDD_SURFCB_DESTROYSURFACE pfn = (PDD_SURFCB_DESTROYSURFACE) dhpdevRetrievePfn((ULONG_PTR)lpDestroySurface->lpDD->dhpdev,INDEX_DdDestroySurface);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpDestroySurface->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpDestroySurface);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpDestroySurface->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdLockSurface(
|
|
PDD_LOCKDATA lpLockSurface
|
|
)
|
|
|
|
{
|
|
PDD_SURFCB_LOCK pfn = (PDD_SURFCB_LOCK) dhpdevRetrievePfn((ULONG_PTR)lpLockSurface->lpDD->dhpdev,INDEX_DdLockSurface);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpLockSurface->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpLockSurface);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpLockSurface->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdUnlockSurface(
|
|
PDD_UNLOCKDATA lpUnlockSurface
|
|
)
|
|
|
|
{
|
|
PDD_SURFCB_UNLOCK pfn = (PDD_SURFCB_UNLOCK) dhpdevRetrievePfn((ULONG_PTR)lpUnlockSurface->lpDD->dhpdev,INDEX_DdUnlockSurface);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpUnlockSurface->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpUnlockSurface);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpUnlockSurface->lpDD->dhpdev));
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
{
|
|
PDD_SURFCB_SETCOLORKEY pfn = (PDD_SURFCB_SETCOLORKEY)dhpdevRetrievePfn((ULONG_PTR)lpSetColorKey->lpDD->dhpdev,INDEX_DdSetColorKey);
|
|
DWORD dwRet;
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpSetColorKey);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException();
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
#endif
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdGetScanLine(
|
|
PDD_GETSCANLINEDATA pGetScanLine
|
|
)
|
|
|
|
{
|
|
PDD_GETSCANLINE pfn = (PDD_GETSCANLINE)dhpdevRetrievePfn((ULONG_PTR)pGetScanLine->lpDD->dhpdev,INDEX_DdGetScanLine);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)pGetScanLine->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(pGetScanLine);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)pGetScanLine->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdCreatePalette(
|
|
PDD_CREATEPALETTEDATA lpCreatePalette
|
|
)
|
|
|
|
{
|
|
PDD_CREATEPALETTE pfn = (PDD_CREATEPALETTE) dhpdevRetrievePfn((ULONG_PTR)lpCreatePalette->lpDD->dhpdev,INDEX_DdCreatePalette);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpCreatePalette->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpCreatePalette);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpCreatePalette->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdMapMemory(
|
|
PDD_MAPMEMORYDATA lpMapMemory
|
|
)
|
|
|
|
{
|
|
PDD_MAPMEMORY pfn = (PDD_MAPMEMORY) dhpdevRetrievePfn((ULONG_PTR)lpMapMemory->lpDD->dhpdev,INDEX_DdMapMemory);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpMapMemory->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpMapMemory);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpMapMemory->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdWaitForVerticalBlank(
|
|
PDD_WAITFORVERTICALBLANKDATA lpWaitForVerticalBlank
|
|
)
|
|
|
|
{
|
|
PDD_WAITFORVERTICALBLANK pfn = (PDD_WAITFORVERTICALBLANK) dhpdevRetrievePfn((ULONG_PTR)lpWaitForVerticalBlank->lpDD->dhpdev,INDEX_DdWaitForVerticalBlank);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpWaitForVerticalBlank->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpWaitForVerticalBlank);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpWaitForVerticalBlank->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdFlip(
|
|
PDD_FLIPDATA lpFlip
|
|
)
|
|
|
|
{
|
|
PDD_SURFCB_FLIP pfn = (PDD_SURFCB_FLIP) dhpdevRetrievePfn((ULONG_PTR)lpFlip->lpDD->dhpdev,INDEX_DdFlip);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpFlip->lpDD->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpFlip);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpFlip->lpDD->dhpdev));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdGetDriverState(
|
|
PDD_GETDRIVERSTATEDATA pgdsd
|
|
)
|
|
|
|
{
|
|
PCONTEXT_NODE Node = (PCONTEXT_NODE) pgdsd->dwhContext;
|
|
PDD_GETDRIVERSTATE pfn = (PDD_GETDRIVERSTATE) Node->pldev->apfnDriver[INDEX_DdGetDriverState];
|
|
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 (Node->pldev->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// restore original context
|
|
//
|
|
|
|
pgdsd->dwhContext = (DWORD_PTR) Node->Context;
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(pgdsd);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(Node->pldev);
|
|
}
|
|
|
|
//
|
|
// save our context again in case this structure is re-used
|
|
//
|
|
|
|
pgdsd->dwhContext = (DWORD_PTR) Node;
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
//
|
|
// TODO: I don't think I want to check in with this macro to build
|
|
// functions, but for now lets use it.
|
|
//
|
|
|
|
#define BUILD_FUNCTION_1(Func, ArgType, FuncType) \
|
|
DWORD APIENTRY \
|
|
WatchdogDd##Func( \
|
|
ArgType lp##Func) \
|
|
{ \
|
|
FuncType pfn = (FuncType) dhpdevRetrievePfn((ULONG_PTR)lp##Func->lpDD->dhpdev,INDEX_Dd##Func); \
|
|
DWORD dwRet = 0; \
|
|
\
|
|
if (dhpdevRetrieveLdev((DHPDEV)lp##Func->lpDD->dhpdev)->bThreadStuck) { \
|
|
return 0; \
|
|
} \
|
|
\
|
|
__try { \
|
|
\
|
|
dwRet = pfn(lp##Func); \
|
|
\
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {\
|
|
\
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lp##Func->lpDD->dhpdev));\
|
|
\
|
|
}\
|
|
\
|
|
return dwRet;\
|
|
}
|
|
|
|
#define BUILD_FUNCTION_2(Func, ArgType, FuncType) \
|
|
DWORD APIENTRY \
|
|
WatchdogDd##Func( \
|
|
ArgType lp##Func) \
|
|
{ \
|
|
PCONTEXT_NODE Node = (PCONTEXT_NODE) lp##Func->dwhContext; \
|
|
FuncType pfn = (FuncType) Node->pldev->apfnDriver[INDEX_Dd##Func]; \
|
|
DWORD dwRet = 0; \
|
|
\
|
|
if (pfn == NULL) {\
|
|
lp##Func->ddrval = D3DNTHAL_CONTEXT_BAD; \
|
|
return DDHAL_DRIVER_HANDLED; \
|
|
}\
|
|
\
|
|
if (Node->pldev->bThreadStuck) { \
|
|
return 0; \
|
|
} \
|
|
\
|
|
lp##Func->dwhContext = (DWORD_PTR) Node->Context; \
|
|
\
|
|
__try { \
|
|
\
|
|
dwRet = pfn(lp##Func); \
|
|
\
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {\
|
|
\
|
|
HandleStuckThreadException(Node->pldev);\
|
|
\
|
|
}\
|
|
\
|
|
lp##Func->dwhContext = (DWORD_PTR) Node; \
|
|
\
|
|
return dwRet;\
|
|
}
|
|
|
|
#define BUILD_FUNCTION_3(Func, ArgType, FuncType) \
|
|
DWORD APIENTRY \
|
|
WatchdogDd##Func( \
|
|
ArgType lp##Func) \
|
|
{ \
|
|
FuncType pfn = (FuncType) dhpdevRetrievePfn((ULONG_PTR)lp##Func->lpDD->lpGbl->dhpdev,INDEX_Dd##Func); \
|
|
DWORD dwRet = 0; \
|
|
\
|
|
if (dhpdevRetrieveLdev((DHPDEV)lp##Func->lpDD->lpGbl->dhpdev)->bThreadStuck) { \
|
|
return 0; \
|
|
} \
|
|
\
|
|
__try { \
|
|
\
|
|
dwRet = pfn(lp##Func); \
|
|
\
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {\
|
|
\
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lp##Func->lpDD->lpGbl->dhpdev));\
|
|
\
|
|
}\
|
|
\
|
|
return dwRet;\
|
|
}
|
|
|
|
#define BUILD_FUNCTION_4(Func, ArgType, FuncType) \
|
|
DWORD APIENTRY \
|
|
WatchdogDd##Func( \
|
|
ArgType lp##Func) \
|
|
{ \
|
|
FuncType pfn = (FuncType) dhpdevRetrievePfn((ULONG_PTR)lp##Func->lpDDLcl->lpGbl->dhpdev,INDEX_Dd##Func); \
|
|
DWORD dwRet = 0; \
|
|
\
|
|
if (dhpdevRetrieveLdev((DHPDEV)lp##Func->lpDDLcl->lpGbl->dhpdev)->bThreadStuck) { \
|
|
return 0; \
|
|
} \
|
|
\
|
|
__try { \
|
|
\
|
|
dwRet = pfn(lp##Func); \
|
|
\
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {\
|
|
\
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lp##Func->lpDDLcl->lpGbl->dhpdev));\
|
|
\
|
|
}\
|
|
\
|
|
return dwRet;\
|
|
}
|
|
|
|
#define BUILD_FUNCTION_5(Func, ArgType, FuncType) \
|
|
DWORD APIENTRY \
|
|
WatchdogDd##Func( \
|
|
ArgType lp##Func) \
|
|
{ \
|
|
FuncType pfn = (FuncType) dhpdevRetrievePfn((ULONG_PTR)lp##Func->pDDLcl->lpGbl->dhpdev,INDEX_Dd##Func); \
|
|
DWORD dwRet = 0; \
|
|
\
|
|
if (dhpdevRetrieveLdev((DHPDEV)lp##Func->pDDLcl->lpGbl->dhpdev)->bThreadStuck) { \
|
|
return 0; \
|
|
} \
|
|
\
|
|
__try { \
|
|
\
|
|
dwRet = pfn(lp##Func); \
|
|
\
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {\
|
|
\
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lp##Func->pDDLcl->lpGbl->dhpdev));\
|
|
\
|
|
}\
|
|
\
|
|
return dwRet;\
|
|
}
|
|
|
|
|
|
BUILD_FUNCTION_1(Lock, PDD_LOCKDATA, PDD_SURFCB_LOCK);
|
|
BUILD_FUNCTION_1(Unlock, PDD_UNLOCKDATA, PDD_SURFCB_UNLOCK);
|
|
BUILD_FUNCTION_1(Blt, PDD_BLTDATA, PDD_SURFCB_BLT);
|
|
BUILD_FUNCTION_1(AddAttachedSurface, PDD_ADDATTACHEDSURFACEDATA, PDD_SURFCB_ADDATTACHEDSURFACE);
|
|
BUILD_FUNCTION_1(GetBltStatus, PDD_GETBLTSTATUSDATA, PDD_SURFCB_GETBLTSTATUS);
|
|
BUILD_FUNCTION_1(GetFlipStatus, PDD_GETFLIPSTATUSDATA, PDD_SURFCB_GETFLIPSTATUS);
|
|
BUILD_FUNCTION_1(UpdateOverlay, PDD_UPDATEOVERLAYDATA, PDD_SURFCB_UPDATEOVERLAY);
|
|
BUILD_FUNCTION_1(SetOverlayPosition, PDD_SETOVERLAYPOSITIONDATA, PDD_SURFCB_SETOVERLAYPOSITION);
|
|
BUILD_FUNCTION_1(SetPalette, PDD_SETPALETTEDATA, PDD_SURFCB_SETPALETTE);
|
|
BUILD_FUNCTION_1(DestroyPalette, PDD_DESTROYPALETTEDATA, PDD_PALCB_DESTROYPALETTE);
|
|
BUILD_FUNCTION_1(SetEntries, PDD_SETENTRIESDATA, PDD_PALCB_SETENTRIES);
|
|
BUILD_FUNCTION_1(ColorControl, PDD_COLORCONTROLDATA, PDD_COLORCB_COLORCONTROL);
|
|
BUILD_FUNCTION_1(CanCreateD3DBuffer, PDD_CANCREATESURFACEDATA, PDD_CANCREATESURFACE);
|
|
BUILD_FUNCTION_1(CreateD3DBuffer, PDD_CREATESURFACEDATA, PDD_CREATESURFACE);
|
|
BUILD_FUNCTION_1(DestroyD3DBuffer, PDD_DESTROYSURFACEDATA, PDD_SURFCB_DESTROYSURFACE);
|
|
BUILD_FUNCTION_1(LockD3DBuffer, PDD_LOCKDATA, PDD_SURFCB_LOCK);
|
|
BUILD_FUNCTION_1(UnlockD3DBuffer, PDD_UNLOCKDATA, PDD_SURFCB_UNLOCK);
|
|
BUILD_FUNCTION_1(GetAvailDriverMemory, PDD_GETAVAILDRIVERMEMORYDATA, PDD_GETAVAILDRIVERMEMORY);
|
|
BUILD_FUNCTION_1(AlphaBlt, PDD_BLTDATA, PDD_ALPHABLT);
|
|
|
|
BUILD_FUNCTION_2(DrawPrimitives2, LPD3DNTHAL_DRAWPRIMITIVES2DATA, LPD3DNTHAL_DRAWPRIMITIVES2CB);
|
|
BUILD_FUNCTION_2(ValidateTextureStageState, LPD3DNTHAL_VALIDATETEXTURESTAGESTATEDATA, LPD3DNTHAL_VALIDATETEXTURESTAGESTATECB);
|
|
|
|
BUILD_FUNCTION_3(SyncSurfaceData, PDD_SYNCSURFACEDATA, PDD_KERNELCB_SYNCSURFACE);
|
|
BUILD_FUNCTION_3(SyncVideoPortData, PDD_SYNCVIDEOPORTDATA, PDD_KERNELCB_SYNCVIDEOPORT);
|
|
|
|
BUILD_FUNCTION_4(CreateSurfaceEx, PDD_CREATESURFACEEXDATA, PDD_CREATESURFACEEX);
|
|
|
|
BUILD_FUNCTION_5(DestroyDDLocal, PDD_DESTROYDDLOCALDATA, PDD_DESTROYDDLOCAL);
|
|
|
|
BUILD_FUNCTION_1(FreeDriverMemory, PDD_FREEDRIVERMEMORYDATA, PDD_FREEDRIVERMEMORY);
|
|
BUILD_FUNCTION_1(SetExclusiveMode, PDD_SETEXCLUSIVEMODEDATA, PDD_SETEXCLUSIVEMODE);
|
|
BUILD_FUNCTION_1(FlipToGDISurface, PDD_FLIPTOGDISURFACEDATA, PDD_FLIPTOGDISURFACE);
|
|
|
|
DWORD APIENTRY
|
|
WatchdogDdGetDriverInfo(
|
|
PDD_GETDRIVERINFODATA lpGetDriverInfo
|
|
)
|
|
|
|
{
|
|
PDD_GETDRIVERINFO pfn = (PDD_GETDRIVERINFO) dhpdevRetrievePfn((ULONG_PTR)lpGetDriverInfo->dhpdev,INDEX_DdGetDriverInfo);
|
|
DWORD dwRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)lpGetDriverInfo->dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
dwRet = pfn(lpGetDriverInfo);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)lpGetDriverInfo->dhpdev));
|
|
}
|
|
|
|
if ((dwRet == DDHAL_DRIVER_HANDLED) &&
|
|
(lpGetDriverInfo->ddRVal == DD_OK)) {
|
|
|
|
PLDEV pldev = dhpdevRetrieveLdev((DHPDEV)lpGetDriverInfo->dhpdev);
|
|
|
|
if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_ColorControlCallbacks)) {
|
|
|
|
PDD_COLORCONTROLCALLBACKS Callbacks = (PDD_COLORCONTROLCALLBACKS) lpGetDriverInfo->lpvData;
|
|
|
|
if (Callbacks->dwFlags & DDHAL_COLOR_COLORCONTROL) {
|
|
|
|
if (Callbacks->ColorControl != WatchdogDdColorControl) {
|
|
pldev->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) {
|
|
pldev->apfnDriver[INDEX_DdContextCreate] = (PFN)Callbacks->ContextCreate;
|
|
}
|
|
Callbacks->ContextCreate = WatchdogDdContextCreate;
|
|
}
|
|
|
|
if (Callbacks->ContextDestroy) {
|
|
|
|
if (Callbacks->ContextDestroy != WatchdogDdContextDestroy) {
|
|
pldev->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) {
|
|
pldev->apfnDriver[INDEX_DdDrawPrimitives2] = (PFN)Callbacks->DrawPrimitives2;
|
|
}
|
|
Callbacks->DrawPrimitives2 = WatchdogDdDrawPrimitives2;
|
|
}
|
|
|
|
if (Callbacks->ValidateTextureStageState) {
|
|
|
|
if (Callbacks->ValidateTextureStageState != WatchdogDdValidateTextureStageState) {
|
|
pldev->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) {
|
|
pldev->apfnDriver[INDEX_DdSyncSurfaceData] = (PFN)Callbacks->SyncSurfaceData;
|
|
}
|
|
Callbacks->SyncSurfaceData = WatchdogDdSyncSurfaceData;
|
|
}
|
|
|
|
if (Callbacks->dwFlags & DDHAL_KERNEL_SYNCVIDEOPORTDATA) {
|
|
|
|
if (Callbacks->SyncVideoPortData != WatchdogDdSyncVideoPortData) {
|
|
pldev->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) {
|
|
pldev->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) {
|
|
pldev->apfnDriver[INDEX_DdAlphaBlt] = (PFN)Callbacks->AlphaBlt;
|
|
}
|
|
Callbacks->AlphaBlt = WatchdogDdAlphaBlt;
|
|
}
|
|
|
|
if (Callbacks->dwFlags & DDHAL_MISC2CB32_CREATESURFACEEX) {
|
|
|
|
if (Callbacks->CreateSurfaceEx != WatchdogDdCreateSurfaceEx) {
|
|
pldev->apfnDriver[INDEX_DdCreateSurfaceEx] = (PFN)Callbacks->CreateSurfaceEx;
|
|
}
|
|
Callbacks->CreateSurfaceEx = WatchdogDdCreateSurfaceEx;
|
|
}
|
|
|
|
if (Callbacks->dwFlags & DDHAL_MISC2CB32_GETDRIVERSTATE) {
|
|
|
|
if (Callbacks->GetDriverState != WatchdogDdGetDriverState) {
|
|
pldev->apfnDriver[INDEX_DdGetDriverState] = (PFN)Callbacks->GetDriverState;
|
|
}
|
|
Callbacks->GetDriverState = WatchdogDdGetDriverState;
|
|
}
|
|
|
|
if (Callbacks->dwFlags & DDHAL_MISC2CB32_DESTROYDDLOCAL) {
|
|
|
|
if (Callbacks->DestroyDDLocal != WatchdogDdDestroyDDLocal) {
|
|
pldev->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) {
|
|
pldev->apfnDriver[INDEX_DdFreeDriverMemory] = (PFN)Callbacks->FreeDriverMemory;
|
|
}
|
|
Callbacks->FreeDriverMemory = WatchdogDdFreeDriverMemory;
|
|
}
|
|
|
|
if (Callbacks->dwFlags & DDHAL_NTCB32_SETEXCLUSIVEMODE) {
|
|
|
|
if (Callbacks->SetExclusiveMode != WatchdogDdSetExclusiveMode) {
|
|
pldev->apfnDriver[INDEX_DdSetExclusiveMode] = (PFN)Callbacks->SetExclusiveMode;
|
|
}
|
|
Callbacks->SetExclusiveMode = WatchdogDdSetExclusiveMode;
|
|
}
|
|
|
|
if (Callbacks->dwFlags & DDHAL_NTCB32_FLIPTOGDISURFACE) {
|
|
|
|
if (Callbacks->FlipToGDISurface != WatchdogDdFlipToGDISurface) {
|
|
pldev->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
|
|
)
|
|
|
|
{
|
|
PFN_DrvGetDirectDrawInfo pfn = (PFN_DrvGetDirectDrawInfo) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvGetDirectDrawInfo);
|
|
BOOL bRet = 0;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return 0;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(dhpdev, pHalInfo, pdwNumHeaps, pvmList, pdwNumFourCCCodes, pdwFourCC);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
//
|
|
// If the function succeeded, then try to capture the DdGetDriverInfo
|
|
// function from pHalInfo.
|
|
//
|
|
|
|
if (bRet) {
|
|
|
|
PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
|
|
|
|
if (pHalInfo->GetDriverInfo) {
|
|
|
|
if (pHalInfo->GetDriverInfo != WatchdogDdGetDriverInfo) {
|
|
pldev->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(&pldev->D3DHALCallbacks,
|
|
lpD3DHALCallbacks,
|
|
min(sizeof(pldev->D3DHALCallbacks), lpD3DHALCallbacks->dwSize));
|
|
|
|
pHalInfo->lpD3DHALCallbacks = lpD3DHALCallbacks = &pldev->D3DHALCallbacks;
|
|
|
|
if (lpD3DHALCallbacks->ContextCreate &&
|
|
lpD3DHALCallbacks->ContextDestroy) {
|
|
|
|
if (lpD3DHALCallbacks->ContextCreate != WatchdogDdContextCreate) {
|
|
pldev->apfnDriver[INDEX_DdContextCreate] = (PFN)lpD3DHALCallbacks->ContextCreate;
|
|
}
|
|
|
|
if (lpD3DHALCallbacks->ContextDestroy != WatchdogDdContextDestroy) {
|
|
pldev->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(&pldev->D3DBufCallbacks,
|
|
lpD3DBufCallbacks,
|
|
min(sizeof(pldev->D3DBufCallbacks), lpD3DBufCallbacks->dwSize));
|
|
|
|
lpD3DBufCallbacks = pHalInfo->lpD3DBufCallbacks = &pldev->D3DBufCallbacks;
|
|
|
|
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, CanCreateD3DBuffer)) &&
|
|
(lpD3DBufCallbacks->CanCreateD3DBuffer)) {
|
|
|
|
if (lpD3DBufCallbacks->CanCreateD3DBuffer != WatchdogDdCanCreateD3DBuffer) {
|
|
pldev->apfnDriver[INDEX_DdCanCreateD3DBuffer] = (PFN)lpD3DBufCallbacks->CanCreateD3DBuffer;
|
|
}
|
|
lpD3DBufCallbacks->CanCreateD3DBuffer = WatchdogDdCanCreateD3DBuffer;
|
|
}
|
|
|
|
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, CreateD3DBuffer)) &&
|
|
(lpD3DBufCallbacks->CreateD3DBuffer)) {
|
|
|
|
if (lpD3DBufCallbacks->CreateD3DBuffer != WatchdogDdCreateD3DBuffer) {
|
|
pldev->apfnDriver[INDEX_DdCreateD3DBuffer] = (PFN)lpD3DBufCallbacks->CreateD3DBuffer;
|
|
}
|
|
lpD3DBufCallbacks->CreateD3DBuffer = WatchdogDdCreateD3DBuffer;
|
|
}
|
|
|
|
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, DestroyD3DBuffer)) &&
|
|
(lpD3DBufCallbacks->DestroyD3DBuffer)) {
|
|
|
|
if (lpD3DBufCallbacks->DestroyD3DBuffer != WatchdogDdDestroyD3DBuffer) {
|
|
pldev->apfnDriver[INDEX_DdDestroyD3DBuffer] = (PFN)lpD3DBufCallbacks->DestroyD3DBuffer;
|
|
}
|
|
lpD3DBufCallbacks->DestroyD3DBuffer = WatchdogDdDestroyD3DBuffer;
|
|
}
|
|
|
|
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, LockD3DBuffer)) &&
|
|
(lpD3DBufCallbacks->LockD3DBuffer)) {
|
|
|
|
if (lpD3DBufCallbacks->LockD3DBuffer != WatchdogDdLockD3DBuffer) {
|
|
pldev->apfnDriver[INDEX_DdLockD3DBuffer] = (PFN)lpD3DBufCallbacks->LockD3DBuffer;
|
|
}
|
|
lpD3DBufCallbacks->LockD3DBuffer = WatchdogDdLockD3DBuffer;
|
|
}
|
|
|
|
if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, UnlockD3DBuffer)) &&
|
|
(lpD3DBufCallbacks->UnlockD3DBuffer)) {
|
|
|
|
if (lpD3DBufCallbacks->UnlockD3DBuffer != WatchdogDdUnlockD3DBuffer) {
|
|
pldev->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
|
|
)
|
|
|
|
{
|
|
PFN_DrvEnableDirectDraw pfn = (PFN_DrvEnableDirectDraw) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvEnableDirectDraw);
|
|
BOOL bRet = FALSE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return FALSE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(dhpdev, pCallBacks, pSurfaceCallBacks, pPaletteCallBacks);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
//
|
|
// If the function succeeded, then try to capture the Callback functions.
|
|
//
|
|
|
|
if (bRet) {
|
|
|
|
PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
|
|
|
|
//
|
|
// Capture generic callbacks
|
|
//
|
|
|
|
if (pCallBacks->dwFlags & DDHAL_CB32_CANCREATESURFACE) {
|
|
|
|
if (pCallBacks->CanCreateSurface != WatchdogDdCanCreateSurface) {
|
|
pldev->apfnDriver[INDEX_DdCanCreateSurface] = (PFN)pCallBacks->CanCreateSurface;
|
|
}
|
|
pCallBacks->CanCreateSurface = WatchdogDdCanCreateSurface;
|
|
}
|
|
|
|
if (pCallBacks->dwFlags & DDHAL_CB32_CREATESURFACE) {
|
|
|
|
if (pCallBacks->CreateSurface != WatchdogDdCreateSurface) {
|
|
pldev->apfnDriver[INDEX_DdCreateSurface] = (PFN)pCallBacks->CreateSurface;
|
|
}
|
|
pCallBacks->CreateSurface = WatchdogDdCreateSurface;
|
|
}
|
|
|
|
if (pCallBacks->dwFlags & DDHAL_CB32_CREATEPALETTE) {
|
|
|
|
if (pCallBacks->CreatePalette != WatchdogDdCreatePalette) {
|
|
pldev->apfnDriver[INDEX_DdCreatePalette] = (PFN)pCallBacks->CreatePalette;
|
|
}
|
|
pCallBacks->CreatePalette = WatchdogDdCreatePalette;
|
|
}
|
|
|
|
if (pCallBacks->dwFlags & DDHAL_CB32_GETSCANLINE) {
|
|
|
|
if (pCallBacks->GetScanLine != WatchdogDdGetScanLine) {
|
|
pldev->apfnDriver[INDEX_DdGetScanLine] = (PFN)pCallBacks->GetScanLine;
|
|
}
|
|
pCallBacks->GetScanLine = WatchdogDdGetScanLine;
|
|
}
|
|
|
|
if (pCallBacks->dwFlags & DDHAL_CB32_MAPMEMORY) {
|
|
|
|
if (pCallBacks->MapMemory != WatchdogDdMapMemory) {
|
|
pldev->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) {
|
|
pldev->apfnDriver[INDEX_DdSetColorKey] = (PFN)pCallBacks->SetColorKey;
|
|
}
|
|
pCallBacks->SetColorKey = WatchdogDdSetColorKey;
|
|
}
|
|
#endif
|
|
|
|
if (pCallBacks->dwFlags & DDHAL_CB32_WAITFORVERTICALBLANK) {
|
|
|
|
if (pCallBacks->WaitForVerticalBlank != WatchdogDdWaitForVerticalBlank) {
|
|
pldev->apfnDriver[INDEX_DdWaitForVerticalBlank] = (PFN)pCallBacks->WaitForVerticalBlank;
|
|
}
|
|
pCallBacks->WaitForVerticalBlank = WatchdogDdWaitForVerticalBlank;
|
|
}
|
|
|
|
//
|
|
// Capture Surface Callbacks
|
|
//
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_DESTROYSURFACE) {
|
|
|
|
if (pSurfaceCallBacks->DestroySurface != WatchdogDdDestroySurface) {
|
|
pldev->apfnDriver[INDEX_DdDestroySurface] = (PFN)pSurfaceCallBacks->DestroySurface;
|
|
}
|
|
pSurfaceCallBacks->DestroySurface = WatchdogDdDestroySurface;
|
|
}
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_FLIP) {
|
|
|
|
if (pSurfaceCallBacks->Flip != WatchdogDdFlip) {
|
|
pldev->apfnDriver[INDEX_DdFlip] = (PFN)pSurfaceCallBacks->Flip;
|
|
}
|
|
pSurfaceCallBacks->Flip = WatchdogDdFlip;
|
|
}
|
|
|
|
#if 0
|
|
//
|
|
// SetClipList is obsolete
|
|
//
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETCLIPLIST) {
|
|
|
|
if (pSurfaceCallBacks->SetClipList != WatchdogDdSetClipList) {
|
|
pldev->apfnDriver[INDEX_DdSetClipList] = (PFN)pSurfaceCallBacks->SetClipList;
|
|
}
|
|
pSurfaceCallBacks->SetClipList = WatchdogDdSetClipList;
|
|
}
|
|
#endif
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_LOCK) {
|
|
|
|
if (pSurfaceCallBacks->Lock != WatchdogDdLock) {
|
|
pldev->apfnDriver[INDEX_DdLock] = (PFN)pSurfaceCallBacks->Lock;
|
|
}
|
|
pSurfaceCallBacks->Lock = WatchdogDdLock;
|
|
}
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_UNLOCK) {
|
|
|
|
if (pSurfaceCallBacks->Unlock != WatchdogDdUnlock) {
|
|
pldev->apfnDriver[INDEX_DdUnlock] = (PFN)pSurfaceCallBacks->Unlock;
|
|
}
|
|
pSurfaceCallBacks->Unlock = WatchdogDdUnlock;
|
|
}
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_BLT) {
|
|
|
|
if (pSurfaceCallBacks->Blt != WatchdogDdBlt) {
|
|
pldev->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) {
|
|
pldev->apfnDriver[INDEX_DdSetColorKey] = (PFN)pSurfaceCallBacks->SetColorKey;
|
|
}
|
|
pSurfaceCallBacks->SetColorKey = WatchdogDdSetColorKey;
|
|
}
|
|
#endif
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_ADDATTACHEDSURFACE) {
|
|
|
|
if (pSurfaceCallBacks->AddAttachedSurface != WatchdogDdAddAttachedSurface) {
|
|
pldev->apfnDriver[INDEX_DdAddAttachedSurface] = (PFN)pSurfaceCallBacks->AddAttachedSurface;
|
|
}
|
|
pSurfaceCallBacks->AddAttachedSurface = WatchdogDdAddAttachedSurface;
|
|
}
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_GETBLTSTATUS) {
|
|
|
|
if (pSurfaceCallBacks->GetBltStatus != WatchdogDdGetBltStatus) {
|
|
pldev->apfnDriver[INDEX_DdGetBltStatus] = (PFN)pSurfaceCallBacks->GetBltStatus;
|
|
}
|
|
pSurfaceCallBacks->GetBltStatus = WatchdogDdGetBltStatus;
|
|
}
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_GETFLIPSTATUS) {
|
|
|
|
if (pSurfaceCallBacks->GetFlipStatus != WatchdogDdGetFlipStatus) {
|
|
pldev->apfnDriver[INDEX_DdGetFlipStatus] = (PFN)pSurfaceCallBacks->GetFlipStatus;
|
|
}
|
|
pSurfaceCallBacks->GetFlipStatus = WatchdogDdGetFlipStatus;
|
|
}
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_UPDATEOVERLAY) {
|
|
|
|
if (pSurfaceCallBacks->UpdateOverlay != WatchdogDdUpdateOverlay) {
|
|
pldev->apfnDriver[INDEX_DdUpdateOverlay] = (PFN)pSurfaceCallBacks->UpdateOverlay;
|
|
}
|
|
pSurfaceCallBacks->UpdateOverlay = WatchdogDdUpdateOverlay;
|
|
}
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETOVERLAYPOSITION) {
|
|
|
|
if (pSurfaceCallBacks->SetOverlayPosition != WatchdogDdSetOverlayPosition) {
|
|
pldev->apfnDriver[INDEX_DdSetOverlayPosition] = (PFN)pSurfaceCallBacks->SetOverlayPosition;
|
|
}
|
|
pSurfaceCallBacks->SetOverlayPosition = WatchdogDdSetOverlayPosition;
|
|
}
|
|
|
|
if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETPALETTE) {
|
|
|
|
if (pSurfaceCallBacks->SetPalette != WatchdogDdSetPalette) {
|
|
pldev->apfnDriver[INDEX_DdSetPalette] = (PFN)pSurfaceCallBacks->SetPalette;
|
|
}
|
|
pSurfaceCallBacks->SetPalette = WatchdogDdSetPalette;
|
|
}
|
|
|
|
//
|
|
// Capture Palette Callbacks
|
|
//
|
|
|
|
if (pPaletteCallBacks->dwFlags & DDHAL_PALCB32_DESTROYPALETTE) {
|
|
|
|
if (pPaletteCallBacks->DestroyPalette != WatchdogDdDestroyPalette) {
|
|
pldev->apfnDriver[INDEX_DdDestroyPalette] = (PFN)pPaletteCallBacks->DestroyPalette;
|
|
}
|
|
pPaletteCallBacks->DestroyPalette = WatchdogDdDestroyPalette;
|
|
}
|
|
|
|
if (pPaletteCallBacks->dwFlags & DDHAL_PALCB32_SETENTRIES) {
|
|
|
|
if (pPaletteCallBacks->SetEntries != WatchdogDdSetEntries) {
|
|
pldev->apfnDriver[INDEX_DdSetEntries] = (PFN)pPaletteCallBacks->SetEntries;
|
|
}
|
|
pPaletteCallBacks->SetEntries = WatchdogDdSetEntries;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvDisableDirectDraw(
|
|
DHPDEV dhpdev
|
|
)
|
|
|
|
{
|
|
PFN_DrvDisableDirectDraw pfn = (PFN_DrvDisableDirectDraw) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvDisableDirectDraw);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(dhpdev);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
WatchdogDrvIcmSetDeviceGammaRamp(
|
|
IN DHPDEV dhpdev,
|
|
IN ULONG iFormat,
|
|
IN LPVOID ipRamp
|
|
)
|
|
|
|
{
|
|
PFN_DrvIcmSetDeviceGammaRamp pfn = (PFN_DrvIcmSetDeviceGammaRamp) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvIcmSetDeviceGammaRamp);
|
|
BOOL bRet = TRUE;
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return bRet;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(dhpdev, iFormat, ipRamp);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
|
|
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;
|
|
PFN_DrvStretchBltROP pfn = (PFN_DrvStretchBltROP) dhpdevRetrievePfn((ULONG_PTR)psoDevice->dhpdev,INDEX_DrvStretchBltROP);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoDevice->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMask, iMode, pbo, rop4);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoDevice->dhpdev));
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
{
|
|
PFN_DrvPlgBlt pfn = (PFN_DrvPlgBlt) dhpdevRetrievePfn((ULONG_PTR)psoTrg->dhpdev,INDEX_DrvPlgBlt);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoTrg->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(psoTrg, psoSrc, psoMsk, pco, pxlo, pca, pptlBrushOrg, pptfx, prcl, pptl, iMode);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoTrg->dhpdev));
|
|
}
|
|
|
|
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;
|
|
PFN_DrvAlphaBlend pfn = (PFN_DrvAlphaBlend) dhpdevRetrievePfn((ULONG_PTR)psoDevice->dhpdev,INDEX_DrvAlphaBlend);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoDevice->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(psoDest, psoSrc, pco, pxlo, prclDest, prclSrc, pBlendObj);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoDevice->dhpdev));
|
|
}
|
|
|
|
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
|
|
)
|
|
|
|
{
|
|
PFN_DrvGradientFill pfn = (PFN_DrvGradientFill) dhpdevRetrievePfn((ULONG_PTR)psoDest->dhpdev,INDEX_DrvGradientFill);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoDest->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents, pptlDitherOrg, ulMode);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoDest->dhpdev));
|
|
}
|
|
|
|
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;
|
|
PFN_DrvTransparentBlt pfn = (PFN_DrvTransparentBlt) dhpdevRetrievePfn((ULONG_PTR)psoDevice->dhpdev,INDEX_DrvTransparentBlt);
|
|
BOOL bRet = TRUE;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(psoDevice->dhpdev)->bThreadStuck) {
|
|
return TRUE;
|
|
}
|
|
|
|
__try {
|
|
|
|
bRet = pfn(psoDst, psoSrc, pco, pxlo, prclDst, prclSrc, iTransColor, ulReserved);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(psoDevice->dhpdev));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
HBITMAP APIENTRY
|
|
WatchdogDrvDeriveSurface(
|
|
DD_DIRECTDRAW_GLOBAL *pDirectDraw,
|
|
DD_SURFACE_LOCAL *pSurface
|
|
)
|
|
|
|
{
|
|
PFN_DrvDeriveSurface pfn = (PFN_DrvDeriveSurface) dhpdevRetrievePfn((ULONG_PTR)pDirectDraw->dhpdev, INDEX_DrvDeriveSurface);
|
|
HBITMAP hBitmap = NULL;
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev((DHPDEV)pDirectDraw->dhpdev)->bThreadStuck == FALSE) {
|
|
|
|
PASSOCIATION_NODE Node = AssociationCreateNode();
|
|
|
|
if (Node) {
|
|
|
|
__try {
|
|
|
|
hBitmap = pfn(pDirectDraw, pSurface);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev((DHPDEV)pDirectDraw->dhpdev));
|
|
}
|
|
|
|
if (hBitmap) {
|
|
|
|
//
|
|
// Get the DHSURF that is associated with the hbitmap, and
|
|
// cache it away so we can look it up when a DrvDeleteDeviceBitmap
|
|
// call comes down.
|
|
//
|
|
|
|
SURFREF so;
|
|
|
|
so.vAltCheckLockIgnoreStockBit((HSURF)hBitmap);
|
|
|
|
Node->key = (ULONG_PTR)so.ps->dhsurf();
|
|
Node->data = (ULONG_PTR)dhpdevRetrieveLdev((DHPDEV)pDirectDraw->dhpdev);
|
|
Node->hsurf = (ULONG_PTR)hBitmap;
|
|
|
|
//
|
|
// If an association node already exists, with this association
|
|
// then use it.
|
|
//
|
|
|
|
if (AssociationIsNodeInList(Node) == FALSE) {
|
|
|
|
AssociationInsertNodeAtTail(Node);
|
|
|
|
} else {
|
|
|
|
AssociationDeleteNode(Node);
|
|
}
|
|
|
|
} else {
|
|
|
|
AssociationDeleteNode(Node);
|
|
}
|
|
}
|
|
}
|
|
|
|
return hBitmap;
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvNotify(
|
|
IN SURFOBJ *pso,
|
|
IN ULONG iType,
|
|
IN PVOID pvData
|
|
)
|
|
|
|
{
|
|
PFN_DrvNotify pfn = (PFN_DrvNotify) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev, INDEX_DrvNotify);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(pso, iType, pvData);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvSynchronizeSurface(
|
|
IN SURFOBJ *pso,
|
|
IN RECTL *prcl,
|
|
IN FLONG fl
|
|
)
|
|
|
|
{
|
|
PFN_DrvSynchronizeSurface pfn = (PFN_DrvSynchronizeSurface) dhpdevRetrievePfn((ULONG_PTR)pso->dhpdev, INDEX_DrvSynchronizeSurface);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(pso->dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(pso, prcl, fl);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(pso->dhpdev));
|
|
}
|
|
}
|
|
|
|
VOID APIENTRY
|
|
WatchdogDrvResetDevice(
|
|
DHPDEV dhpdev,
|
|
PVOID Reserved
|
|
)
|
|
|
|
{
|
|
PFN_DrvResetDevice pfn = (PFN_DrvResetDevice) dhpdevRetrievePfn((ULONG_PTR)dhpdev,INDEX_DrvResetDevice);
|
|
|
|
//
|
|
// Return early if we are in a thread stuck condition
|
|
//
|
|
|
|
if (dhpdevRetrieveLdev(dhpdev)->bThreadStuck) {
|
|
return;
|
|
}
|
|
|
|
__try {
|
|
|
|
pfn(dhpdev, Reserved);
|
|
|
|
} __except(GetExceptionCode() == SE_THREAD_STUCK) {
|
|
|
|
//
|
|
// Handle stuck thread excepton
|
|
//
|
|
|
|
HandleStuckThreadException(dhpdevRetrieveLdev(dhpdev));
|
|
}
|
|
}
|
|
|
|
//
|
|
// 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];
|
|
}
|