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

3545 lines
89 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: watchdog.cxx *
  3. * *
  4. * Copyright (c) 1990-2002 Microsoft Corporation *
  5. * *
  6. * This module hooks the display drivers "Drv" entry points. It will *
  7. * enter/exit the watchdog appropriately, and set up try/except blocks to *
  8. * catch threads that get stuck in a driver. *
  9. * *
  10. * Erick Smith - ericks - *
  11. \**************************************************************************/
  12. #include "precomp.hxx"
  13. #include "muclean.hxx"
  14. #define MAKESOFTWAREEXCEPTION(Severity, Facility, Exception) \
  15. ((DWORD) ((Severity << 30) | (1 << 29) | (Facility << 16) | (Exception)))
  16. #define SE_THREAD_STUCK MAKESOFTWAREEXCEPTION(3,0,1)
  17. #define RECOVERY_SECTION_BEGIN(pldev) __try
  18. #define RECOVERY_SECTION_END(pldev) \
  19. __except(GetExceptionCode() == SE_THREAD_STUCK) { \
  20. HandleStuckThreadException(pldev); \
  21. }
  22. //
  23. // Context Nodes are used for DX. DdContextCreate and DdContextDestroy
  24. // create contexts that are later passed to other DX functions such as
  25. // DrawPrimitives2 or SetTextureStageState. Since we need to be able
  26. // to take the context and retrieve the original pldev, we create this
  27. // new structure to help in the association.
  28. //
  29. typedef struct _CONTEXT_NODE
  30. {
  31. PVOID Context;
  32. PDHPDEV_ASSOCIATION_NODE ppdevData;
  33. } CONTEXT_NODE, *PCONTEXT_NODE;
  34. PDHPDEV_ASSOCIATION_NODE gdhpdevAssociationList = NULL;
  35. PDHSURF_ASSOCIATION_NODE gdhsurfAssociationList = NULL;
  36. //
  37. // The following routines are used to maintain an association between the
  38. // data actually passed into a driver entry point, and a data structure
  39. // used to look up the actual entry point into the driver.
  40. //
  41. // For example, when the system call the DrvEnablePDEV entry point, the
  42. // driver will create it's own PDEV structure. We will create an
  43. // association node to associate this driver created PDEV with the LDEV for
  44. // that driver. Now on subsequent calls into the driver, we can retrieve
  45. // the PDEV via various methods, and then use that to find the LDEV. Once we
  46. // have the LDEV we can look up the correct entry point into the driver.
  47. //
  48. // GDI entry points are global accross all pdev's. However, it is possible
  49. // that a driver may return seperate DX entry points to different pdevs. For
  50. // example this could happen if a driver returned on set of entry points when
  51. // the pdev is in portrait mode, and another set when in landscape mode.
  52. //
  53. // We also store a list of DHSURF's and the association with the LDEV.
  54. //
  55. PDHPDEV_ASSOCIATION_NODE
  56. dhpdevAssociationCreateNode(
  57. VOID
  58. )
  59. {
  60. PDHPDEV_ASSOCIATION_NODE Node;
  61. Node = (PDHPDEV_ASSOCIATION_NODE) PALLOCMEM(sizeof(DHPDEV_ASSOCIATION_NODE), GDITAG_DRVSUP);
  62. return Node;
  63. }
  64. PDHSURF_ASSOCIATION_NODE
  65. dhsurfAssociationCreateNode(
  66. VOID
  67. )
  68. {
  69. PDHSURF_ASSOCIATION_NODE Node;
  70. Node = (PDHSURF_ASSOCIATION_NODE) PALLOCMEM(sizeof(DHSURF_ASSOCIATION_NODE), GDITAG_DRVSUP);
  71. return Node;
  72. }
  73. VOID
  74. AssociationDeleteNode(
  75. PVOID Node
  76. )
  77. {
  78. if (Node) {
  79. VFREEMEM(Node);
  80. }
  81. }
  82. VOID
  83. dhpdevAssociationInsertNode(
  84. PDHPDEV_ASSOCIATION_NODE Node
  85. )
  86. {
  87. GreAcquireFastMutex(gAssociationListMutex);
  88. Node->next = gdhpdevAssociationList;
  89. gdhpdevAssociationList = Node;
  90. GreReleaseFastMutex(gAssociationListMutex);
  91. }
  92. VOID
  93. dhsurfAssociationInsertNode(
  94. PDHSURF_ASSOCIATION_NODE Node
  95. )
  96. {
  97. GreAcquireFastMutex(gAssociationListMutex);
  98. Node->next = gdhsurfAssociationList;
  99. gdhsurfAssociationList = Node;
  100. GreReleaseFastMutex(gAssociationListMutex);
  101. }
  102. PDHPDEV_ASSOCIATION_NODE
  103. dhpdevAssociationRemoveNode(
  104. DHPDEV dhpdev
  105. )
  106. {
  107. PDHPDEV_ASSOCIATION_NODE Node;
  108. GreAcquireFastMutex(gAssociationListMutex);
  109. //
  110. // first find the correct node
  111. //
  112. Node = gdhpdevAssociationList;
  113. while (Node && (Node->dhpdev != dhpdev)) {
  114. Node = Node->next;
  115. }
  116. if (Node) {
  117. if (gdhpdevAssociationList == Node) {
  118. gdhpdevAssociationList = Node->next;
  119. } else {
  120. PDHPDEV_ASSOCIATION_NODE curr = gdhpdevAssociationList;
  121. while (curr && (curr->next != Node)) {
  122. curr = curr->next;
  123. }
  124. if (curr) {
  125. curr->next = Node->next;
  126. }
  127. }
  128. }
  129. GreReleaseFastMutex(gAssociationListMutex);
  130. return Node;
  131. }
  132. PDHSURF_ASSOCIATION_NODE
  133. dhsurfAssociationRemoveNode(
  134. DHSURF dhsurf
  135. )
  136. {
  137. PDHSURF_ASSOCIATION_NODE Node;
  138. GreAcquireFastMutex(gAssociationListMutex);
  139. //
  140. // first find the correct node
  141. //
  142. Node = gdhsurfAssociationList;
  143. while (Node && (Node->dhsurf != dhsurf)) {
  144. Node = Node->next;
  145. }
  146. if (Node) {
  147. if (gdhsurfAssociationList == Node) {
  148. gdhsurfAssociationList = Node->next;
  149. } else {
  150. PDHSURF_ASSOCIATION_NODE curr = gdhsurfAssociationList;
  151. while (curr && (curr->next != Node)) {
  152. curr = curr->next;
  153. }
  154. if (curr) {
  155. curr->next = Node->next;
  156. }
  157. }
  158. }
  159. GreReleaseFastMutex(gAssociationListMutex);
  160. return Node;
  161. }
  162. BOOL
  163. dhsurfAssociationIsNodeInList(
  164. DHSURF dhsurf,
  165. HSURF hsurf
  166. )
  167. {
  168. PDHSURF_ASSOCIATION_NODE Curr;
  169. BOOL bRet = FALSE;
  170. GreAcquireFastMutex(gAssociationListMutex);
  171. Curr = gdhsurfAssociationList;
  172. while (Curr) {
  173. //
  174. // We only have to check if the key and the hsurf value
  175. // are similar.
  176. //
  177. if ((Curr->dhsurf == dhsurf) &&
  178. (Curr->hsurf == hsurf)) {
  179. bRet = TRUE;
  180. break;
  181. }
  182. Curr = Curr->next;
  183. }
  184. GreReleaseFastMutex(gAssociationListMutex);
  185. return bRet;
  186. }
  187. PDHPDEV_ASSOCIATION_NODE
  188. dhpdevRetrieveNode(
  189. DHPDEV dhpdev
  190. )
  191. {
  192. PDHPDEV_ASSOCIATION_NODE Node;
  193. GreAcquireFastMutex(gAssociationListMutex);
  194. Node = gdhpdevAssociationList;
  195. while (Node) {
  196. if (Node->dhpdev == dhpdev) {
  197. break;
  198. }
  199. Node = Node->next;
  200. }
  201. GreReleaseFastMutex(gAssociationListMutex);
  202. return Node;
  203. }
  204. PLDEV
  205. dhpdevRetrieveLdev(
  206. DHPDEV dhpdev
  207. )
  208. {
  209. PDHPDEV_ASSOCIATION_NODE Node;
  210. GreAcquireFastMutex(gAssociationListMutex);
  211. Node = gdhpdevAssociationList;
  212. while (Node) {
  213. if (Node->dhpdev == dhpdev) {
  214. break;
  215. }
  216. Node = Node->next;
  217. }
  218. GreReleaseFastMutex(gAssociationListMutex);
  219. if (Node) {
  220. return (PLDEV)Node->pldev;
  221. } else {
  222. return NULL;
  223. }
  224. }
  225. PLDEV
  226. dhsurfRetrieveLdev(
  227. DHSURF dhsurf
  228. )
  229. {
  230. PDHSURF_ASSOCIATION_NODE Node;
  231. GreAcquireFastMutex(gAssociationListMutex);
  232. Node = gdhsurfAssociationList;
  233. while (Node) {
  234. if (Node->dhsurf == dhsurf) {
  235. break;
  236. }
  237. Node = Node->next;
  238. }
  239. GreReleaseFastMutex(gAssociationListMutex);
  240. if (Node) {
  241. return (PLDEV)Node->pldev;
  242. } else {
  243. return NULL;
  244. }
  245. }
  246. ULONG
  247. WatchdogDrvGetModesEmpty(
  248. IN HANDLE hDriver,
  249. IN ULONG cjSize,
  250. OUT DEVMODEW *pdm
  251. )
  252. /*++
  253. Routine Description:
  254. This function replaces a drivers DrvGetModes function when
  255. and EA has occured. We do this so that we can stop reporting
  256. modes for this device.
  257. --*/
  258. {
  259. //
  260. // Indicate NO modes!
  261. //
  262. return 0;
  263. }
  264. VOID
  265. WatchdogRecoveryThread(
  266. IN PVOID Context
  267. )
  268. {
  269. VIDEO_WIN32K_CALLBACKS_PARAMS Params;
  270. UNREFERENCED_PARAMETER(Context);
  271. Params.CalloutType = VideoChangeDisplaySettingsCallout;
  272. Params.Param = 0;
  273. Params.PhysDisp = NULL;
  274. Params.Status = 0;
  275. //
  276. // It is possible we'll hit an EA and try to recover for USER has
  277. // finished initializing. Therefore the VideoPortCallout may fail
  278. // with a STATUS_INVALID_HANDLE. We'll keep trying (with a delay)
  279. // until we get a different status code.
  280. //
  281. do {
  282. VideoPortCallout(&Params);
  283. if (Params.Status == STATUS_INVALID_HANDLE) {
  284. ZwYieldExecution();
  285. }
  286. } while (Params.Status == STATUS_INVALID_HANDLE);
  287. PsTerminateSystemThread(STATUS_SUCCESS);
  288. }
  289. VOID
  290. HandleStuckThreadException(
  291. PLDEV pldev
  292. )
  293. /*++
  294. Wake up a user mode thread waiting to reset the display resolution.
  295. --*/
  296. {
  297. UNICODE_STRING EventName;
  298. HANDLE EventHandle;
  299. HANDLE ThreadHandle;
  300. OBJECT_ATTRIBUTES ObjectAttributes;
  301. NTSTATUS Status;
  302. //
  303. // First disable all entries in the dispatch table in the pldev. This
  304. // way we can stop future threads from entring the driver.
  305. //
  306. pldev->bThreadStuck = TRUE;
  307. //
  308. // Replacd the DrvGetModes function for the driver such that the
  309. // driver reports no modes!
  310. //
  311. pldev->apfn[INDEX_DrvGetModes] = (PFN) WatchdogDrvGetModesEmpty;
  312. //
  313. // Remove non-vga device from graphics device list to stop the
  314. // system from trying to continue using the current device.
  315. //
  316. // What do we do about multi-mon?
  317. //
  318. DrvPrepareForEARecovery();
  319. //
  320. // Create a thread to do the work of changing the display resolution.
  321. //
  322. InitializeObjectAttributes(&ObjectAttributes,
  323. NULL,
  324. OBJ_KERNEL_HANDLE,
  325. NULL,
  326. NULL);
  327. Status = PsCreateSystemThread(&ThreadHandle,
  328. (ACCESS_MASK) 0,
  329. &ObjectAttributes,
  330. NtCurrentProcess(),
  331. NULL,
  332. WatchdogRecoveryThread,
  333. NULL);
  334. if (NT_SUCCESS(Status) == TRUE) {
  335. ZwClose(ThreadHandle);
  336. } else {
  337. DbgPrint("Warning, we failed to create the Recovery Thread\n");
  338. }
  339. //
  340. // Clean up any pending drivers locks that this thread is holding
  341. //
  342. GreFreeSemaphoresForCurrentThread();
  343. }
  344. DHPDEV APIENTRY
  345. WatchdogDrvEnablePDEV(
  346. DEVMODEW *pdm,
  347. LPWSTR pwszLogAddress,
  348. ULONG cPat,
  349. HSURF *phsurfPatterns,
  350. ULONG cjCaps,
  351. ULONG *pdevcaps,
  352. ULONG cjDevInfo,
  353. DEVINFO *pdi,
  354. HDEV hdev,
  355. LPWSTR pwszDeviceName,
  356. HANDLE hDriver
  357. )
  358. {
  359. PDEV *ppdev = (PDEV *)hdev;
  360. DHPDEV dhpdevRet = NULL;
  361. if (ppdev->pldev->bThreadStuck == FALSE) {
  362. PFN_DrvEnablePDEV pfn = (PFN_DrvEnablePDEV) ppdev->pldev->apfnDriver[INDEX_DrvEnablePDEV];
  363. PDHPDEV_ASSOCIATION_NODE Node = dhpdevAssociationCreateNode();
  364. if (Node) {
  365. Node->pldev = ppdev->pldev;
  366. Node->dhpdev = NULL;
  367. RECOVERY_SECTION_BEGIN(ppdev->pldev) {
  368. Node->dhpdev = pfn(pdm,
  369. pwszLogAddress,
  370. cPat,
  371. phsurfPatterns,
  372. cjCaps,
  373. (GDIINFO *)pdevcaps,
  374. cjDevInfo,
  375. pdi,
  376. hdev,
  377. pwszDeviceName,
  378. hDriver);
  379. } RECOVERY_SECTION_END(ppdev->pldev);
  380. if (Node->dhpdev) {
  381. dhpdevRet = (DHPDEV) Node->dhpdev;
  382. dhpdevAssociationInsertNode(Node);
  383. } else {
  384. AssociationDeleteNode(Node);
  385. }
  386. }
  387. }
  388. return dhpdevRet;
  389. }
  390. VOID APIENTRY
  391. WatchdogDrvCompletePDEV(
  392. DHPDEV dhpdev,
  393. HDEV hdev
  394. )
  395. {
  396. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  397. PFN_DrvCompletePDEV pfn = (PFN_DrvCompletePDEV) pldev->apfnDriver[INDEX_DrvCompletePDEV];
  398. //
  399. // Return early if we are in a thread stuck condition
  400. //
  401. if (pldev->bThreadStuck) {
  402. return;
  403. }
  404. RECOVERY_SECTION_BEGIN(pldev) {
  405. pfn(dhpdev, hdev);
  406. } RECOVERY_SECTION_END(pldev);
  407. }
  408. VOID APIENTRY
  409. WatchdogDrvDisablePDEV(
  410. DHPDEV dhpdev
  411. )
  412. {
  413. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  414. PFN_DrvDisablePDEV pfn = (PFN_DrvDisablePDEV) pldev->apfnDriver[INDEX_DrvDisablePDEV];
  415. //
  416. // Return early if we are in a thread stuck condition
  417. //
  418. if (pldev->bThreadStuck) {
  419. return;
  420. }
  421. RECOVERY_SECTION_BEGIN(pldev) {
  422. pfn(dhpdev);
  423. } RECOVERY_SECTION_END(pldev);
  424. AssociationDeleteNode(dhpdevAssociationRemoveNode(dhpdev));
  425. }
  426. HSURF APIENTRY
  427. WatchdogDrvEnableSurface(
  428. DHPDEV dhpdev
  429. )
  430. {
  431. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  432. PFN_DrvEnableSurface pfn = (PFN_DrvEnableSurface) pldev->apfnDriver[INDEX_DrvEnableSurface];
  433. HSURF hsurfRet = NULL;
  434. //
  435. // Return early if we are in a thread stuck condition
  436. //
  437. if (pldev->bThreadStuck) {
  438. return NULL;
  439. }
  440. RECOVERY_SECTION_BEGIN(pldev) {
  441. hsurfRet = pfn(dhpdev);
  442. } RECOVERY_SECTION_END(pldev);
  443. return hsurfRet;
  444. }
  445. VOID APIENTRY
  446. WatchdogDrvDisableSurface(
  447. DHPDEV dhpdev
  448. )
  449. {
  450. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  451. PFN_DrvDisableSurface pfn = (PFN_DrvDisableSurface) pldev->apfnDriver[INDEX_DrvDisableSurface];
  452. //
  453. // Return early if we are in a thread stuck condition
  454. //
  455. if (pldev->bThreadStuck) {
  456. return;
  457. }
  458. RECOVERY_SECTION_BEGIN(pldev) {
  459. pfn(dhpdev);
  460. } RECOVERY_SECTION_END(pldev);
  461. }
  462. BOOL APIENTRY
  463. WatchdogDrvAssertMode(
  464. DHPDEV dhpdev,
  465. BOOL bEnable
  466. )
  467. {
  468. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  469. PFN_DrvAssertMode pfn = (PFN_DrvAssertMode) pldev->apfnDriver[INDEX_DrvAssertMode];
  470. BOOL bRet = TRUE;
  471. //
  472. // Return early if we are in a thread stuck condition
  473. //
  474. if (pldev->bThreadStuck) {
  475. return TRUE;
  476. }
  477. RECOVERY_SECTION_BEGIN(pldev) {
  478. bRet = pfn(dhpdev, bEnable);
  479. } RECOVERY_SECTION_END(pldev);
  480. return bRet;
  481. }
  482. BOOL APIENTRY
  483. WatchdogDrvResetPDEV(
  484. DHPDEV dhpdevOld,
  485. DHPDEV dhpdevNew
  486. )
  487. {
  488. PLDEV pldev = dhpdevRetrieveLdev(dhpdevOld);
  489. PFN_DrvResetPDEV pfn = (PFN_DrvResetPDEV) pldev->apfnDriver[INDEX_DrvResetPDEV];
  490. BOOL bRet = TRUE;
  491. //
  492. // Return early if we are in a thread stuck condition
  493. //
  494. if (pldev->bThreadStuck) {
  495. return TRUE;
  496. }
  497. RECOVERY_SECTION_BEGIN(pldev) {
  498. bRet = pfn(dhpdevOld, dhpdevNew);
  499. } RECOVERY_SECTION_END(pldev);
  500. return bRet;
  501. }
  502. HBITMAP APIENTRY
  503. WatchdogDrvCreateDeviceBitmap(
  504. DHPDEV dhpdev,
  505. SIZEL sizl,
  506. ULONG iFormat
  507. )
  508. {
  509. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  510. PFN_DrvCreateDeviceBitmap pfn = (PFN_DrvCreateDeviceBitmap) pldev->apfnDriver[INDEX_DrvCreateDeviceBitmap];
  511. HBITMAP hbitmapRet = NULL;
  512. //
  513. // Return early if we are in a thread stuck condition
  514. //
  515. if (pldev->bThreadStuck == FALSE) {
  516. RECOVERY_SECTION_BEGIN(pldev) {
  517. hbitmapRet = pfn(dhpdev, sizl, iFormat);
  518. } RECOVERY_SECTION_END(pldev);
  519. }
  520. return hbitmapRet;
  521. }
  522. VOID APIENTRY
  523. WatchdogDrvDeleteDeviceBitmap(
  524. IN DHSURF dhsurf
  525. )
  526. {
  527. PLDEV pldev = dhsurfRetrieveLdev(dhsurf);
  528. PFN_DrvDeleteDeviceBitmap pfn = (PFN_DrvDeleteDeviceBitmap) pldev->apfnDriver[INDEX_DrvDeleteDeviceBitmap];
  529. if (pldev->bThreadStuck) {
  530. return;
  531. }
  532. RECOVERY_SECTION_BEGIN(pldev) {
  533. pfn(dhsurf);
  534. } RECOVERY_SECTION_END(pldev);
  535. AssociationDeleteNode(dhsurfAssociationRemoveNode(dhsurf));
  536. }
  537. BOOL APIENTRY
  538. WatchdogDrvRealizeBrush(
  539. BRUSHOBJ *pbo,
  540. SURFOBJ *psoTarget,
  541. SURFOBJ *psoPattern,
  542. SURFOBJ *psoMask,
  543. XLATEOBJ *pxlo,
  544. ULONG iHatch
  545. )
  546. {
  547. PLDEV pldev = dhpdevRetrieveLdev(psoTarget->dhpdev);
  548. PFN_DrvRealizeBrush pfn = (PFN_DrvRealizeBrush) pldev->apfnDriver[INDEX_DrvRealizeBrush];
  549. BOOL bRet = FALSE;
  550. //
  551. // Return early if we are in a thread stuck condition
  552. //
  553. if (pldev->bThreadStuck) {
  554. return FALSE;
  555. }
  556. RECOVERY_SECTION_BEGIN(pldev) {
  557. bRet = pfn(pbo, psoTarget, psoPattern, psoMask, pxlo, iHatch);
  558. } RECOVERY_SECTION_END(pldev);
  559. return bRet;
  560. }
  561. ULONG APIENTRY
  562. WatchdogDrvDitherColor(
  563. DHPDEV dhpdev,
  564. ULONG iMode,
  565. ULONG rgb,
  566. ULONG *pul
  567. )
  568. {
  569. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  570. PFN_DrvDitherColor pfn = (PFN_DrvDitherColor) pldev->apfnDriver[INDEX_DrvDitherColor];
  571. ULONG ulRet = 0;
  572. //
  573. // Return early if we are in a thread stuck condition
  574. //
  575. if (pldev->bThreadStuck) {
  576. return 0;
  577. }
  578. RECOVERY_SECTION_BEGIN(pldev) {
  579. ulRet = pfn(dhpdev, iMode, rgb, pul);
  580. } RECOVERY_SECTION_END(pldev);
  581. return ulRet;
  582. }
  583. BOOL APIENTRY
  584. WatchdogDrvStrokePath(
  585. SURFOBJ *pso,
  586. PATHOBJ *ppo,
  587. CLIPOBJ *pco,
  588. XFORMOBJ *pxo,
  589. BRUSHOBJ *pbo,
  590. POINTL *pptlBrushOrg,
  591. LINEATTRS *plineattrs,
  592. MIX mix
  593. )
  594. {
  595. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  596. PFN_DrvStrokePath pfn = (PFN_DrvStrokePath) pldev->apfnDriver[INDEX_DrvStrokePath];
  597. BOOL bRet = TRUE;
  598. //
  599. // Return early if we are in a thread stuck condition
  600. //
  601. if (pldev->bThreadStuck) {
  602. return TRUE;
  603. }
  604. RECOVERY_SECTION_BEGIN(pldev) {
  605. bRet = pfn(pso, ppo, pco, pxo, pbo, pptlBrushOrg, plineattrs, mix);
  606. } RECOVERY_SECTION_END(pldev);
  607. return bRet;
  608. }
  609. BOOL APIENTRY
  610. WatchdogDrvFillPath(
  611. SURFOBJ *pso,
  612. PATHOBJ *ppo,
  613. CLIPOBJ *pco,
  614. BRUSHOBJ *pbo,
  615. POINTL *pptlBrushOrg,
  616. MIX mix,
  617. FLONG flOptions
  618. )
  619. {
  620. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  621. PFN_DrvFillPath pfn = (PFN_DrvFillPath) pldev->apfnDriver[INDEX_DrvFillPath];
  622. BOOL bRet = TRUE;
  623. //
  624. // Return early if we are in a thread stuck condition
  625. //
  626. if (pldev->bThreadStuck) {
  627. return TRUE;
  628. }
  629. RECOVERY_SECTION_BEGIN(pldev) {
  630. bRet = pfn(pso, ppo, pco, pbo, pptlBrushOrg, mix, flOptions);
  631. } RECOVERY_SECTION_END(pldev);
  632. return bRet;
  633. }
  634. BOOL APIENTRY
  635. WatchdogDrvStrokeAndFillPath(
  636. SURFOBJ *pso,
  637. PATHOBJ *ppo,
  638. CLIPOBJ *pco,
  639. XFORMOBJ *pxo,
  640. BRUSHOBJ *pboStroke,
  641. LINEATTRS *plineattrs,
  642. BRUSHOBJ *pboFill,
  643. POINTL *pptlBrushOrg,
  644. MIX mixFill,
  645. FLONG flOptions
  646. )
  647. {
  648. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  649. PFN_DrvStrokeAndFillPath pfn = (PFN_DrvStrokeAndFillPath) pldev->apfnDriver[INDEX_DrvStrokeAndFillPath];
  650. BOOL bRet = TRUE;
  651. //
  652. // Return early if we are in a thread stuck condition
  653. //
  654. if (pldev->bThreadStuck) {
  655. return TRUE;
  656. }
  657. RECOVERY_SECTION_BEGIN(pldev) {
  658. bRet = pfn(pso, ppo, pco, pxo, pboStroke, plineattrs, pboFill, pptlBrushOrg, mixFill, flOptions);
  659. } RECOVERY_SECTION_END(pldev);
  660. return bRet;
  661. }
  662. BOOL APIENTRY
  663. WatchdogDrvBitBlt(
  664. SURFOBJ *psoDst,
  665. SURFOBJ *psoSrc,
  666. SURFOBJ *psoMask,
  667. CLIPOBJ *pco,
  668. XLATEOBJ *pxlo,
  669. RECTL *prclDst,
  670. POINTL *pptlSrc,
  671. POINTL *pptlMask,
  672. BRUSHOBJ *pbo,
  673. POINTL *pptlBrush,
  674. ROP4 rop4
  675. )
  676. {
  677. SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc;
  678. PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev);
  679. PFN_DrvBitBlt pfn = (PFN_DrvBitBlt) pldev->apfnDriver[INDEX_DrvBitBlt];
  680. BOOL bRet = TRUE;
  681. //
  682. // Return early if we are in a thread stuck condition
  683. //
  684. if (pldev->bThreadStuck) {
  685. return TRUE;
  686. }
  687. RECOVERY_SECTION_BEGIN(pldev) {
  688. bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, prclDst, pptlSrc, pptlMask, pbo, pptlBrush, rop4);
  689. } RECOVERY_SECTION_END(pldev);
  690. return bRet;
  691. }
  692. BOOL APIENTRY
  693. WatchdogDrvCopyBits(
  694. SURFOBJ *psoDst,
  695. SURFOBJ *psoSrc,
  696. CLIPOBJ *pco,
  697. XLATEOBJ *pxlo,
  698. RECTL *prclDst,
  699. POINTL *pptlSrc
  700. )
  701. {
  702. SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc;
  703. PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev);
  704. PFN_DrvCopyBits pfn = (PFN_DrvCopyBits) pldev->apfnDriver[INDEX_DrvCopyBits];
  705. BOOL bRet = TRUE;
  706. //
  707. // Return early if we are in a thread stuck condition
  708. //
  709. if (pldev->bThreadStuck) {
  710. return TRUE;
  711. }
  712. RECOVERY_SECTION_BEGIN(pldev) {
  713. bRet = pfn(psoDst, psoSrc, pco, pxlo, prclDst, pptlSrc);
  714. } RECOVERY_SECTION_END(pldev);
  715. return bRet;
  716. }
  717. BOOL APIENTRY
  718. WatchdogDrvStretchBlt(
  719. SURFOBJ *psoDst,
  720. SURFOBJ *psoSrc,
  721. SURFOBJ *psoMask,
  722. CLIPOBJ *pco,
  723. XLATEOBJ *pxlo,
  724. COLORADJUSTMENT *pca,
  725. POINTL *pptlHTOrg,
  726. RECTL *prclDst,
  727. RECTL *prclSrc,
  728. POINTL *pptlMask,
  729. ULONG iMode
  730. )
  731. {
  732. SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc;
  733. PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev);
  734. PFN_DrvStretchBlt pfn = (PFN_DrvStretchBlt) pldev->apfnDriver[INDEX_DrvStretchBlt];
  735. BOOL bRet = TRUE;
  736. //
  737. // Return early if we are in a thread stuck condition
  738. //
  739. if (pldev->bThreadStuck) {
  740. return TRUE;
  741. }
  742. RECOVERY_SECTION_BEGIN(pldev) {
  743. bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMask, iMode);
  744. } RECOVERY_SECTION_END(pldev);
  745. return bRet;
  746. }
  747. ULONG APIENTRY
  748. WatchdogDrvSetPalette(
  749. DHPDEV dhpdev,
  750. PALOBJ *ppalo,
  751. FLONG fl,
  752. ULONG iStart,
  753. ULONG cColors
  754. )
  755. {
  756. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  757. PFN_DrvSetPalette pfn = (PFN_DrvSetPalette) pldev->apfnDriver[INDEX_DrvSetPalette];
  758. ULONG ulRet = 0;
  759. //
  760. // Return early if we are in a thread stuck condition
  761. //
  762. if (pldev->bThreadStuck) {
  763. return 0;
  764. }
  765. RECOVERY_SECTION_BEGIN(pldev) {
  766. ulRet = pfn(dhpdev, ppalo, fl, iStart, cColors);
  767. } RECOVERY_SECTION_END(pldev);
  768. return ulRet;
  769. }
  770. BOOL APIENTRY
  771. WatchdogDrvTextOut(
  772. SURFOBJ *pso,
  773. STROBJ *pstro,
  774. FONTOBJ *pfo,
  775. CLIPOBJ *pco,
  776. RECTL *prclExtra,
  777. RECTL *prclOpaque,
  778. BRUSHOBJ *pboFore,
  779. BRUSHOBJ *pboOpaque,
  780. POINTL *pptlOrg,
  781. MIX mix
  782. )
  783. {
  784. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  785. PFN_DrvTextOut pfn = (PFN_DrvTextOut) pldev->apfnDriver[INDEX_DrvTextOut];
  786. BOOL bRet = TRUE;
  787. //
  788. // Return early if we are in a thread stuck condition
  789. //
  790. if (pldev->bThreadStuck) {
  791. return TRUE;
  792. }
  793. RECOVERY_SECTION_BEGIN(pldev) {
  794. bRet = pfn(pso, pstro, pfo, pco, prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix);
  795. } RECOVERY_SECTION_END(pldev);
  796. return bRet;
  797. }
  798. ULONG APIENTRY
  799. WatchdogDrvEscape(
  800. SURFOBJ *pso,
  801. ULONG iEsc,
  802. ULONG cjIn,
  803. PVOID pvIn,
  804. ULONG cjOut,
  805. PVOID pvOut
  806. )
  807. {
  808. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  809. PFN_DrvEscape pfn = (PFN_DrvEscape) pldev->apfnDriver[INDEX_DrvEscape];
  810. ULONG ulRet = 0;
  811. //
  812. // Return early if we are in a thread stuck condition
  813. //
  814. if (pldev->bThreadStuck) {
  815. return 0;
  816. }
  817. RECOVERY_SECTION_BEGIN(pldev) {
  818. ulRet = pfn(pso, iEsc, cjIn, pvIn, cjOut, pvOut);
  819. } RECOVERY_SECTION_END(pldev);
  820. return ulRet;
  821. }
  822. ULONG APIENTRY
  823. WatchdogDrvDrawEscape(
  824. IN SURFOBJ *pso,
  825. IN ULONG iEsc,
  826. IN CLIPOBJ *pco,
  827. IN RECTL *prcl,
  828. IN ULONG cjIn,
  829. IN PVOID pvIn
  830. )
  831. {
  832. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  833. PFN_DrvDrawEscape pfn = (PFN_DrvDrawEscape) pldev->apfnDriver[INDEX_DrvDrawEscape];
  834. ULONG ulRet = -1;
  835. //
  836. // Return early if we are in a thread stuck condition
  837. //
  838. if (pldev->bThreadStuck) {
  839. return -1;
  840. }
  841. RECOVERY_SECTION_BEGIN(pldev) {
  842. ulRet = pfn(pso, iEsc, pco, prcl, cjIn, pvIn);
  843. } RECOVERY_SECTION_END(pldev);
  844. return ulRet;
  845. }
  846. ULONG APIENTRY
  847. WatchdogDrvSetPointerShape(
  848. SURFOBJ *pso,
  849. SURFOBJ *psoMask,
  850. SURFOBJ *psoColor,
  851. XLATEOBJ *pxlo,
  852. LONG xHot,
  853. LONG yHot,
  854. LONG x,
  855. LONG y,
  856. RECTL *prcl,
  857. FLONG fl
  858. )
  859. {
  860. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  861. PFN_DrvSetPointerShape pfn = (PFN_DrvSetPointerShape) pldev->apfnDriver[INDEX_DrvSetPointerShape];
  862. ULONG ulRet = 0;
  863. //
  864. // Return early if we are in a thread stuck condition
  865. //
  866. if (pldev->bThreadStuck) {
  867. return 0;
  868. }
  869. RECOVERY_SECTION_BEGIN(pldev) {
  870. ulRet = pfn(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl);
  871. } RECOVERY_SECTION_END(pldev);
  872. return ulRet;
  873. }
  874. VOID APIENTRY
  875. WatchdogDrvMovePointer(
  876. SURFOBJ *pso,
  877. LONG x,
  878. LONG y,
  879. RECTL *prcl
  880. )
  881. {
  882. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  883. PFN_DrvMovePointer pfn = (PFN_DrvMovePointer) pldev->apfnDriver[INDEX_DrvMovePointer];
  884. //
  885. // Return early if we are in a thread stuck condition
  886. //
  887. if (pldev->bThreadStuck) {
  888. return;
  889. }
  890. RECOVERY_SECTION_BEGIN(pldev) {
  891. pfn(pso, x, y, prcl);
  892. } RECOVERY_SECTION_END(pldev);
  893. }
  894. BOOL APIENTRY
  895. WatchdogDrvLineTo(
  896. SURFOBJ *pso,
  897. CLIPOBJ *pco,
  898. BRUSHOBJ *pbo,
  899. LONG x1,
  900. LONG y1,
  901. LONG x2,
  902. LONG y2,
  903. RECTL *prclBounds,
  904. MIX mix
  905. )
  906. {
  907. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  908. PFN_DrvLineTo pfn = (PFN_DrvLineTo) pldev->apfnDriver[INDEX_DrvLineTo];
  909. BOOL bRet = TRUE;
  910. //
  911. // Return early if we are in a thread stuck condition
  912. //
  913. if (pldev->bThreadStuck) {
  914. return TRUE;
  915. }
  916. RECOVERY_SECTION_BEGIN(pldev) {
  917. bRet = pfn(pso, pco, pbo, x1, y1, x2, y2, prclBounds, mix);
  918. } RECOVERY_SECTION_END(pldev);
  919. return bRet;
  920. }
  921. VOID APIENTRY
  922. WatchdogDrvSynchronize(
  923. DHPDEV dhpdev,
  924. RECTL *prcl
  925. )
  926. {
  927. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  928. PFN_DrvSynchronize pfn = (PFN_DrvSynchronize) pldev->apfnDriver[INDEX_DrvSynchronize];
  929. //
  930. // Return early if we are in a thread stuck condition
  931. //
  932. if (pldev->bThreadStuck) {
  933. return;
  934. }
  935. RECOVERY_SECTION_BEGIN(pldev) {
  936. pfn(dhpdev, prcl);
  937. } RECOVERY_SECTION_END(pldev);
  938. }
  939. ULONG_PTR APIENTRY
  940. WatchdogDrvSaveScreenBits(
  941. SURFOBJ *pso,
  942. ULONG iMode,
  943. ULONG_PTR ident,
  944. RECTL *prcl
  945. )
  946. {
  947. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  948. PFN_DrvSaveScreenBits pfn = (PFN_DrvSaveScreenBits) pldev->apfnDriver[INDEX_DrvSaveScreenBits];
  949. ULONG_PTR ulptrRet = 0;
  950. //
  951. // Return early if we are in a thread stuck condition
  952. //
  953. if (pldev->bThreadStuck) {
  954. return 0;
  955. }
  956. RECOVERY_SECTION_BEGIN(pldev) {
  957. ulptrRet = pfn(pso, iMode, ident, prcl);
  958. } RECOVERY_SECTION_END(pldev);
  959. return ulptrRet;
  960. }
  961. DWORD APIENTRY
  962. WatchdogDrvSetPixelFormat(
  963. IN SURFOBJ *pso,
  964. IN LONG iPixelFormat,
  965. IN HWND hwnd
  966. )
  967. {
  968. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  969. PFN_DrvSetPixelFormat pfn = (PFN_DrvSetPixelFormat) pldev->apfnDriver[INDEX_DrvSetPixelFormat];
  970. DWORD dwRet = FALSE;
  971. //
  972. // Return early if we are in a thread stuck condition
  973. //
  974. if (pldev->bThreadStuck) {
  975. return 0;
  976. }
  977. RECOVERY_SECTION_BEGIN(pldev) {
  978. dwRet = pfn(pso, iPixelFormat, hwnd);
  979. } RECOVERY_SECTION_END(pldev);
  980. return dwRet;
  981. }
  982. LONG APIENTRY
  983. WatchdogDrvDescribePixelFormat(
  984. IN DHPDEV dhpdev,
  985. IN LONG iPixelFormat,
  986. IN ULONG cjpdf,
  987. OUT PIXELFORMATDESCRIPTOR *ppfd
  988. )
  989. {
  990. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  991. PFN_DrvDescribePixelFormat pfn = (PFN_DrvDescribePixelFormat) pldev->apfnDriver[INDEX_DrvDescribePixelFormat];
  992. LONG lRet = 0;
  993. //
  994. // Return early if we are in a thread stuck condition
  995. //
  996. if (pldev->bThreadStuck) {
  997. return 0;
  998. }
  999. RECOVERY_SECTION_BEGIN(pldev) {
  1000. lRet = pfn(dhpdev, iPixelFormat, cjpdf, ppfd);
  1001. } RECOVERY_SECTION_END(pldev);
  1002. return lRet;
  1003. }
  1004. BOOL APIENTRY
  1005. WatchdogDrvSwapBuffers(
  1006. IN SURFOBJ *pso,
  1007. IN WNDOBJ *pwo
  1008. )
  1009. {
  1010. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  1011. PFN_DrvSwapBuffers pfn = (PFN_DrvSwapBuffers) pldev->apfnDriver[INDEX_DrvSwapBuffers];
  1012. BOOL bRet = FALSE;
  1013. //
  1014. // Return early if we are in a thread stuck condition
  1015. //
  1016. if (pldev->bThreadStuck) {
  1017. return FALSE;
  1018. }
  1019. RECOVERY_SECTION_BEGIN(pldev) {
  1020. bRet = pfn(pso, pwo);
  1021. } RECOVERY_SECTION_END(pldev);
  1022. return bRet;
  1023. }
  1024. DWORD APIENTRY
  1025. WatchdogDdContextCreate(
  1026. LPD3DNTHAL_CONTEXTCREATEDATA pccd
  1027. )
  1028. {
  1029. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE)dhpdevRetrieveNode((DHPDEV)pccd->lpDDLcl->lpGbl->dhpdev);
  1030. PLDEV pldev = ppdevData->pldev;
  1031. LPD3DNTHAL_CONTEXTCREATECB pfn = (LPD3DNTHAL_CONTEXTCREATECB) ppdevData->apfnDriver[INDEX_DdContextCreate];
  1032. DWORD dwRet = DDHAL_DRIVER_NOTHANDLED;
  1033. PCONTEXT_NODE Node;
  1034. //
  1035. // Return early if we are in a thread stuck condition
  1036. //
  1037. if (pldev->bThreadStuck) {
  1038. return 0;
  1039. }
  1040. Node = (PCONTEXT_NODE)PALLOCMEM(sizeof(CONTEXT_NODE), GDITAG_DRVSUP);
  1041. if (Node) {
  1042. RECOVERY_SECTION_BEGIN(pldev) {
  1043. dwRet = pfn(pccd);
  1044. } RECOVERY_SECTION_END(pldev);
  1045. if (dwRet == DDHAL_DRIVER_HANDLED) {
  1046. //
  1047. // Store the dwhContext and the associated dhpdev
  1048. //
  1049. Node->Context = (PVOID)pccd->dwhContext;
  1050. Node->ppdevData = ppdevData;
  1051. pccd->dwhContext = (DWORD_PTR)Node;
  1052. } else {
  1053. VFREEMEM(Node);
  1054. }
  1055. }
  1056. return dwRet;
  1057. }
  1058. DWORD APIENTRY
  1059. WatchdogDdContextDestroy(
  1060. LPD3DNTHAL_CONTEXTDESTROYDATA pcdd
  1061. )
  1062. {
  1063. PCONTEXT_NODE Node = (PCONTEXT_NODE) pcdd->dwhContext;
  1064. LPD3DNTHAL_CONTEXTDESTROYCB pfn = (LPD3DNTHAL_CONTEXTDESTROYCB) Node->ppdevData->apfnDriver[INDEX_DdContextDestroy];
  1065. PLDEV pldev = Node->ppdevData->pldev;
  1066. DWORD dwRet = 0;
  1067. //
  1068. // Return early if we are in a thread stuck condition
  1069. //
  1070. if (pldev->bThreadStuck) {
  1071. return 0;
  1072. }
  1073. //
  1074. // Restore driver created context
  1075. //
  1076. pcdd->dwhContext = (DWORD_PTR) Node->Context;
  1077. RECOVERY_SECTION_BEGIN(pldev) {
  1078. dwRet = pfn(pcdd);
  1079. } RECOVERY_SECTION_END(pldev);
  1080. //
  1081. // Resore our context, just in case this stucture is re-used
  1082. //
  1083. pcdd->dwhContext = (DWORD_PTR) Node;
  1084. if (dwRet == DDHAL_DRIVER_HANDLED) {
  1085. VFREEMEM(Node);
  1086. }
  1087. return dwRet;
  1088. }
  1089. DWORD APIENTRY
  1090. WatchdogDdCanCreateSurface(
  1091. PDD_CANCREATESURFACEDATA lpCanCreateSurface
  1092. )
  1093. {
  1094. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCanCreateSurface->lpDD->dhpdev);
  1095. PLDEV pldev = ppdevData->pldev;
  1096. PDD_CANCREATESURFACE pfn = (PDD_CANCREATESURFACE) ppdevData->apfnDriver[INDEX_DdCanCreateSurface];
  1097. DWORD dwRet = 0;
  1098. //
  1099. // Return early if we are in a thread stuck condition
  1100. //
  1101. if (pldev->bThreadStuck) {
  1102. return 0;
  1103. }
  1104. RECOVERY_SECTION_BEGIN(pldev) {
  1105. dwRet = pfn(lpCanCreateSurface);
  1106. } RECOVERY_SECTION_END(pldev);
  1107. return dwRet;
  1108. }
  1109. DWORD APIENTRY
  1110. WatchdogDdCreateSurface(
  1111. PDD_CREATESURFACEDATA lpCreateSurface
  1112. )
  1113. {
  1114. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCreateSurface->lpDD->dhpdev);
  1115. PLDEV pldev = ppdevData->pldev;
  1116. PDD_CREATESURFACE pfn = (PDD_CREATESURFACE) ppdevData->apfnDriver[INDEX_DdCreateSurface];
  1117. DWORD dwRet = 0;
  1118. //
  1119. // Return early if we are in a thread stuck condition
  1120. //
  1121. if (pldev->bThreadStuck) {
  1122. return 0;
  1123. }
  1124. RECOVERY_SECTION_BEGIN(pldev) {
  1125. dwRet = pfn(lpCreateSurface);
  1126. } RECOVERY_SECTION_END(pldev);
  1127. return dwRet;
  1128. }
  1129. DWORD APIENTRY
  1130. WatchdogDdDestroySurface(
  1131. PDD_DESTROYSURFACEDATA lpDestroySurface
  1132. )
  1133. {
  1134. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpDestroySurface->lpDD->dhpdev);
  1135. PLDEV pldev = ppdevData->pldev;
  1136. PDD_SURFCB_DESTROYSURFACE pfn = (PDD_SURFCB_DESTROYSURFACE) ppdevData->apfnDriver[INDEX_DdDestroySurface];
  1137. DWORD dwRet = 0;
  1138. //
  1139. // Return early if we are in a thread stuck condition
  1140. //
  1141. if (pldev->bThreadStuck) {
  1142. return 0;
  1143. }
  1144. RECOVERY_SECTION_BEGIN(pldev) {
  1145. dwRet = pfn(lpDestroySurface);
  1146. } RECOVERY_SECTION_END(pldev);
  1147. return dwRet;
  1148. }
  1149. DWORD APIENTRY
  1150. WatchdogDdLockSurface(
  1151. PDD_LOCKDATA lpLockSurface
  1152. )
  1153. {
  1154. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpLockSurface->lpDD->dhpdev);
  1155. PLDEV pldev = ppdevData->pldev;
  1156. PDD_SURFCB_LOCK pfn = (PDD_SURFCB_LOCK) ppdevData->apfnDriver[INDEX_DdLockSurface];
  1157. DWORD dwRet = 0;
  1158. //
  1159. // Return early if we are in a thread stuck condition
  1160. //
  1161. if (pldev->bThreadStuck) {
  1162. return 0;
  1163. }
  1164. RECOVERY_SECTION_BEGIN(pldev) {
  1165. dwRet = pfn(lpLockSurface);
  1166. } RECOVERY_SECTION_END(pldev);
  1167. return dwRet;
  1168. }
  1169. DWORD APIENTRY
  1170. WatchdogDdUnlockSurface(
  1171. PDD_UNLOCKDATA lpUnlockSurface
  1172. )
  1173. {
  1174. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpUnlockSurface->lpDD->dhpdev);
  1175. PLDEV pldev = ppdevData->pldev;
  1176. PDD_SURFCB_UNLOCK pfn = (PDD_SURFCB_UNLOCK) ppdevData->apfnDriver[INDEX_DdUnlockSurface];
  1177. DWORD dwRet = 0;
  1178. //
  1179. // Return early if we are in a thread stuck condition
  1180. //
  1181. if (pldev->bThreadStuck) {
  1182. return 0;
  1183. }
  1184. RECOVERY_SECTION_BEGIN(pldev) {
  1185. dwRet = pfn(lpUnlockSurface);
  1186. } RECOVERY_SECTION_END(pldev);
  1187. return dwRet;
  1188. }
  1189. #if 0
  1190. //
  1191. // I'm not sure how I can hook this one since a DD_DRVSETCOLORKEYDATA
  1192. // structure doesn't have a way to look up the dhpdev!
  1193. //
  1194. DWORD APIENTRY
  1195. WatchdogDdSetColorKey(
  1196. PDD_DRVSETCOLORKEYDATA lpSetColorKey
  1197. )
  1198. {
  1199. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetColorKey->lpDD->dhpdev);
  1200. PLDEV pldev = ppdevData->pldev;
  1201. PDD_SURFCB_SETCOLORKEY pfn = (PDD_SURFCB_SETCOLORKEY) ppdevData->apfnDriver[INDEX_DdSetColorKey];
  1202. DWORD dwRet = 0;
  1203. if (pldev->bThreadStuck) {
  1204. return 0;
  1205. }
  1206. RECOVERY_SECTION_BEGIN(pldev) {
  1207. dwRet = pfn(lpSetColorKey);
  1208. } RECOVERY_SECTION_END(pldev);
  1209. return dwRet;
  1210. }
  1211. #endif
  1212. DWORD APIENTRY
  1213. WatchdogDdGetScanLine(
  1214. PDD_GETSCANLINEDATA pGetScanLine
  1215. )
  1216. {
  1217. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)pGetScanLine->lpDD->dhpdev);
  1218. PLDEV pldev = ppdevData->pldev;
  1219. PDD_GETSCANLINE pfn = (PDD_GETSCANLINE) ppdevData->apfnDriver[INDEX_DdGetScanLine];
  1220. DWORD dwRet = 0;
  1221. //
  1222. // Return early if we are in a thread stuck condition
  1223. //
  1224. if (pldev->bThreadStuck) {
  1225. return 0;
  1226. }
  1227. RECOVERY_SECTION_BEGIN(pldev) {
  1228. dwRet = pfn(pGetScanLine);
  1229. } RECOVERY_SECTION_END(pldev);
  1230. return dwRet;
  1231. }
  1232. DWORD APIENTRY
  1233. WatchdogDdCreatePalette(
  1234. PDD_CREATEPALETTEDATA lpCreatePalette
  1235. )
  1236. {
  1237. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCreatePalette->lpDD->dhpdev);
  1238. PLDEV pldev = ppdevData->pldev;
  1239. PDD_CREATEPALETTE pfn = (PDD_CREATEPALETTE) ppdevData->apfnDriver[INDEX_DdCreatePalette];
  1240. DWORD dwRet = 0;
  1241. //
  1242. // Return early if we are in a thread stuck condition
  1243. //
  1244. if (pldev->bThreadStuck) {
  1245. return 0;
  1246. }
  1247. RECOVERY_SECTION_BEGIN(pldev) {
  1248. dwRet = pfn(lpCreatePalette);
  1249. } RECOVERY_SECTION_END(pldev);
  1250. return dwRet;
  1251. }
  1252. DWORD APIENTRY
  1253. WatchdogDdMapMemory(
  1254. PDD_MAPMEMORYDATA lpMapMemory
  1255. )
  1256. {
  1257. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpMapMemory->lpDD->dhpdev);
  1258. PLDEV pldev = ppdevData->pldev;
  1259. PDD_MAPMEMORY pfn = (PDD_MAPMEMORY) ppdevData->apfnDriver[INDEX_DdMapMemory];
  1260. DWORD dwRet = 0;
  1261. //
  1262. // Return early if we are in a thread stuck condition
  1263. //
  1264. if (pldev->bThreadStuck) {
  1265. return 0;
  1266. }
  1267. RECOVERY_SECTION_BEGIN(pldev) {
  1268. dwRet = pfn(lpMapMemory);
  1269. } RECOVERY_SECTION_END(pldev);
  1270. return dwRet;
  1271. }
  1272. DWORD APIENTRY
  1273. WatchdogDdWaitForVerticalBlank(
  1274. PDD_WAITFORVERTICALBLANKDATA lpWaitForVerticalBlank
  1275. )
  1276. {
  1277. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpWaitForVerticalBlank->lpDD->dhpdev);
  1278. PLDEV pldev = ppdevData->pldev;
  1279. PDD_WAITFORVERTICALBLANK pfn = (PDD_WAITFORVERTICALBLANK) ppdevData->apfnDriver[INDEX_DdWaitForVerticalBlank];
  1280. DWORD dwRet = 0;
  1281. //
  1282. // Return early if we are in a thread stuck condition
  1283. //
  1284. if (pldev->bThreadStuck) {
  1285. return 0;
  1286. }
  1287. RECOVERY_SECTION_BEGIN(pldev) {
  1288. dwRet = pfn(lpWaitForVerticalBlank);
  1289. } RECOVERY_SECTION_END(pldev);
  1290. return dwRet;
  1291. }
  1292. DWORD APIENTRY
  1293. WatchdogDdFlip(
  1294. PDD_FLIPDATA lpFlip
  1295. )
  1296. {
  1297. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpFlip->lpDD->dhpdev);
  1298. PLDEV pldev = ppdevData->pldev;
  1299. PDD_SURFCB_FLIP pfn = (PDD_SURFCB_FLIP) ppdevData->apfnDriver[INDEX_DdFlip];
  1300. DWORD dwRet = 0;
  1301. //
  1302. // Return early if we are in a thread stuck condition
  1303. //
  1304. if (pldev->bThreadStuck) {
  1305. return 0;
  1306. }
  1307. RECOVERY_SECTION_BEGIN(pldev) {
  1308. dwRet = pfn(lpFlip);
  1309. } RECOVERY_SECTION_END(pldev);
  1310. return dwRet;
  1311. }
  1312. DWORD APIENTRY
  1313. WatchdogDdGetDriverState(
  1314. PDD_GETDRIVERSTATEDATA pgdsd
  1315. )
  1316. {
  1317. PCONTEXT_NODE Node = (PCONTEXT_NODE) pgdsd->dwhContext;
  1318. PDD_GETDRIVERSTATE pfn = (PDD_GETDRIVERSTATE) Node->ppdevData->apfnDriver[INDEX_DdGetDriverState];
  1319. PLDEV pldev = Node->ppdevData->pldev;
  1320. DWORD dwRet = 0;
  1321. //
  1322. // how can I validate if I created this dwhcontext?
  1323. //
  1324. if (pfn == NULL) {
  1325. pgdsd->ddRVal = D3DNTHAL_CONTEXT_BAD;
  1326. return DDHAL_DRIVER_HANDLED;
  1327. }
  1328. if (pldev->bThreadStuck) {
  1329. return 0;
  1330. }
  1331. //
  1332. // restore original context
  1333. //
  1334. pgdsd->dwhContext = (DWORD_PTR) Node->Context;
  1335. RECOVERY_SECTION_BEGIN(pldev) {
  1336. dwRet = pfn(pgdsd);
  1337. } RECOVERY_SECTION_END(pldev);
  1338. //
  1339. // save our context again in case this structure is re-used
  1340. //
  1341. pgdsd->dwhContext = (DWORD_PTR) Node;
  1342. return dwRet;
  1343. }
  1344. DWORD APIENTRY
  1345. WatchdogDdLock(
  1346. PDD_LOCKDATA lpLock
  1347. )
  1348. {
  1349. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpLock->lpDD->dhpdev);
  1350. PLDEV pldev = ppdevData->pldev;
  1351. PDD_SURFCB_LOCK pfn = (PDD_SURFCB_LOCK) ppdevData->apfnDriver[INDEX_DdLock];
  1352. DWORD dwRet = 0;
  1353. if (pldev->bThreadStuck) {
  1354. return 0;
  1355. }
  1356. RECOVERY_SECTION_BEGIN(pldev) {
  1357. dwRet = pfn(lpLock);
  1358. } RECOVERY_SECTION_END(pldev);
  1359. return dwRet;
  1360. }
  1361. DWORD APIENTRY
  1362. WatchdogDdUnlock(
  1363. PDD_UNLOCKDATA lpUnlock)
  1364. {
  1365. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpUnlock->lpDD->dhpdev);
  1366. PLDEV pldev = ppdevData->pldev;
  1367. PDD_SURFCB_UNLOCK pfn = (PDD_SURFCB_UNLOCK) ppdevData->apfnDriver[INDEX_DdUnlock];
  1368. DWORD dwRet = 0;
  1369. if (pldev->bThreadStuck) {
  1370. return 0;
  1371. }
  1372. RECOVERY_SECTION_BEGIN(pldev) {
  1373. dwRet = pfn(lpUnlock);
  1374. } RECOVERY_SECTION_END(pldev);
  1375. return dwRet;
  1376. }
  1377. DWORD APIENTRY
  1378. WatchdogDdBlt(
  1379. PDD_BLTDATA lpBlt)
  1380. {
  1381. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpBlt->lpDD->dhpdev);
  1382. PLDEV pldev = ppdevData->pldev;
  1383. PDD_SURFCB_BLT pfn = (PDD_SURFCB_BLT) ppdevData->apfnDriver[INDEX_DdBlt];
  1384. DWORD dwRet = 0;
  1385. if (pldev->bThreadStuck) {
  1386. return 0;
  1387. }
  1388. RECOVERY_SECTION_BEGIN(pldev) {
  1389. dwRet = pfn(lpBlt);
  1390. } RECOVERY_SECTION_END(pldev);
  1391. return dwRet;
  1392. }
  1393. DWORD APIENTRY
  1394. WatchdogDdAddAttachedSurface(
  1395. PDD_ADDATTACHEDSURFACEDATA lpAddAttachedSurface)
  1396. {
  1397. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpAddAttachedSurface->lpDD->dhpdev);
  1398. PLDEV pldev = ppdevData->pldev;
  1399. PDD_SURFCB_ADDATTACHEDSURFACE pfn = (PDD_SURFCB_ADDATTACHEDSURFACE) ppdevData->apfnDriver[INDEX_DdAddAttachedSurface];
  1400. DWORD dwRet = 0;
  1401. if (pldev->bThreadStuck) {
  1402. return 0;
  1403. }
  1404. RECOVERY_SECTION_BEGIN(pldev) {
  1405. dwRet = pfn(lpAddAttachedSurface);
  1406. } RECOVERY_SECTION_END(pldev);
  1407. return dwRet;
  1408. }
  1409. DWORD APIENTRY
  1410. WatchdogDdGetBltStatus(
  1411. PDD_GETBLTSTATUSDATA lpGetBltStatus)
  1412. {
  1413. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpGetBltStatus->lpDD->dhpdev);
  1414. PLDEV pldev = ppdevData->pldev;
  1415. PDD_SURFCB_GETBLTSTATUS pfn = (PDD_SURFCB_GETBLTSTATUS) ppdevData->apfnDriver[INDEX_DdGetBltStatus];
  1416. DWORD dwRet = 0;
  1417. if (pldev->bThreadStuck) {
  1418. return 0;
  1419. }
  1420. RECOVERY_SECTION_BEGIN(pldev) {
  1421. dwRet = pfn(lpGetBltStatus);
  1422. } RECOVERY_SECTION_END(pldev);
  1423. return dwRet;
  1424. }
  1425. DWORD APIENTRY
  1426. WatchdogDdGetFlipStatus(
  1427. PDD_GETFLIPSTATUSDATA lpGetFlipStatus)
  1428. {
  1429. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpGetFlipStatus->lpDD->dhpdev);
  1430. PLDEV pldev = ppdevData->pldev;
  1431. PDD_SURFCB_GETFLIPSTATUS pfn = (PDD_SURFCB_GETFLIPSTATUS) ppdevData->apfnDriver[INDEX_DdGetFlipStatus];
  1432. DWORD dwRet = 0;
  1433. if (pldev->bThreadStuck) {
  1434. return 0;
  1435. }
  1436. RECOVERY_SECTION_BEGIN(pldev) {
  1437. dwRet = pfn(lpGetFlipStatus);
  1438. } RECOVERY_SECTION_END(pldev);
  1439. return dwRet;
  1440. }
  1441. DWORD APIENTRY
  1442. WatchdogDdUpdateOverlay(
  1443. PDD_UPDATEOVERLAYDATA lpUpdateOverlay)
  1444. {
  1445. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpUpdateOverlay->lpDD->dhpdev);
  1446. PLDEV pldev = ppdevData->pldev;
  1447. PDD_SURFCB_UPDATEOVERLAY pfn = (PDD_SURFCB_UPDATEOVERLAY) ppdevData->apfnDriver[INDEX_DdUpdateOverlay];
  1448. DWORD dwRet = 0;
  1449. if (pldev->bThreadStuck) {
  1450. return 0;
  1451. }
  1452. RECOVERY_SECTION_BEGIN(pldev) {
  1453. dwRet = pfn(lpUpdateOverlay);
  1454. } RECOVERY_SECTION_END(pldev);
  1455. return dwRet;
  1456. }
  1457. DWORD APIENTRY
  1458. WatchdogDdSetOverlayPosition(
  1459. PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition)
  1460. {
  1461. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetOverlayPosition->lpDD->dhpdev);
  1462. PLDEV pldev = ppdevData->pldev;
  1463. PDD_SURFCB_SETOVERLAYPOSITION pfn = (PDD_SURFCB_SETOVERLAYPOSITION) ppdevData->apfnDriver[INDEX_DdSetOverlayPosition];
  1464. DWORD dwRet = 0;
  1465. if (pldev->bThreadStuck) {
  1466. return 0;
  1467. }
  1468. RECOVERY_SECTION_BEGIN(pldev) {
  1469. dwRet = pfn(lpSetOverlayPosition);
  1470. } RECOVERY_SECTION_END(pldev);
  1471. return dwRet;
  1472. }
  1473. DWORD APIENTRY
  1474. WatchdogDdSetPalette(
  1475. PDD_SETPALETTEDATA lpSetPalette)
  1476. {
  1477. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetPalette->lpDD->dhpdev);
  1478. PLDEV pldev = ppdevData->pldev;
  1479. PDD_SURFCB_SETPALETTE pfn = (PDD_SURFCB_SETPALETTE) ppdevData->apfnDriver[INDEX_DdSetPalette];
  1480. DWORD dwRet = 0;
  1481. if (pldev->bThreadStuck) {
  1482. return 0;
  1483. }
  1484. RECOVERY_SECTION_BEGIN(pldev) {
  1485. dwRet = pfn(lpSetPalette);
  1486. } RECOVERY_SECTION_END(pldev);
  1487. return dwRet;
  1488. }
  1489. DWORD APIENTRY
  1490. WatchdogDdDestroyPalette(
  1491. PDD_DESTROYPALETTEDATA lpDestroyPalette)
  1492. {
  1493. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpDestroyPalette->lpDD->dhpdev);
  1494. PLDEV pldev = ppdevData->pldev;
  1495. PDD_PALCB_DESTROYPALETTE pfn = (PDD_PALCB_DESTROYPALETTE) ppdevData->apfnDriver[INDEX_DdDestroyPalette];
  1496. DWORD dwRet = 0;
  1497. if (pldev->bThreadStuck) {
  1498. return 0;
  1499. }
  1500. RECOVERY_SECTION_BEGIN(pldev) {
  1501. dwRet = pfn(lpDestroyPalette);
  1502. } RECOVERY_SECTION_END(pldev);
  1503. return dwRet;
  1504. }
  1505. DWORD APIENTRY
  1506. WatchdogDdSetEntries(
  1507. PDD_SETENTRIESDATA lpSetEntries)
  1508. {
  1509. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetEntries->lpDD->dhpdev);
  1510. PLDEV pldev = ppdevData->pldev;
  1511. PDD_PALCB_SETENTRIES pfn = (PDD_PALCB_SETENTRIES) ppdevData->apfnDriver[INDEX_DdSetEntries];
  1512. DWORD dwRet = 0;
  1513. if (pldev->bThreadStuck) {
  1514. return 0;
  1515. }
  1516. RECOVERY_SECTION_BEGIN(pldev) {
  1517. dwRet = pfn(lpSetEntries);
  1518. } RECOVERY_SECTION_END(pldev);
  1519. return dwRet;
  1520. }
  1521. DWORD APIENTRY
  1522. WatchdogDdColorControl(
  1523. PDD_COLORCONTROLDATA lpColorControl)
  1524. {
  1525. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpColorControl->lpDD->dhpdev);
  1526. PLDEV pldev = ppdevData->pldev;
  1527. PDD_COLORCB_COLORCONTROL pfn = (PDD_COLORCB_COLORCONTROL) ppdevData->apfnDriver[INDEX_DdColorControl];
  1528. DWORD dwRet = 0;
  1529. if (pldev->bThreadStuck) {
  1530. return 0;
  1531. }
  1532. RECOVERY_SECTION_BEGIN(pldev) {
  1533. dwRet = pfn(lpColorControl);
  1534. } RECOVERY_SECTION_END(pldev);
  1535. return dwRet;
  1536. }
  1537. DWORD APIENTRY
  1538. WatchdogDdCanCreateD3DBuffer(
  1539. PDD_CANCREATESURFACEDATA lpCanCreateD3DBuffer)
  1540. {
  1541. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCanCreateD3DBuffer->lpDD->dhpdev);
  1542. PLDEV pldev = ppdevData->pldev;
  1543. PDD_CANCREATESURFACE pfn = (PDD_CANCREATESURFACE) ppdevData->apfnDriver[INDEX_DdCanCreateD3DBuffer];
  1544. DWORD dwRet = 0;
  1545. if (pldev->bThreadStuck) {
  1546. return 0;
  1547. }
  1548. RECOVERY_SECTION_BEGIN(pldev) {
  1549. dwRet = pfn(lpCanCreateD3DBuffer);
  1550. } RECOVERY_SECTION_END(pldev);
  1551. return dwRet;
  1552. }
  1553. DWORD APIENTRY
  1554. WatchdogDdCreateD3DBuffer(
  1555. PDD_CREATESURFACEDATA lpCreateD3DBuffer)
  1556. {
  1557. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCreateD3DBuffer->lpDD->dhpdev);
  1558. PLDEV pldev = ppdevData->pldev;
  1559. PDD_CREATESURFACE pfn = (PDD_CREATESURFACE) ppdevData->apfnDriver[INDEX_DdCreateD3DBuffer];
  1560. DWORD dwRet = 0;
  1561. if (pldev->bThreadStuck) {
  1562. return 0;
  1563. }
  1564. RECOVERY_SECTION_BEGIN(pldev) {
  1565. dwRet = pfn(lpCreateD3DBuffer);
  1566. } RECOVERY_SECTION_END(pldev);
  1567. return dwRet;
  1568. }
  1569. DWORD APIENTRY
  1570. WatchdogDdDestroyD3DBuffer(
  1571. PDD_DESTROYSURFACEDATA lpDestroyD3DBuffer)
  1572. {
  1573. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpDestroyD3DBuffer->lpDD->dhpdev);
  1574. PLDEV pldev = ppdevData->pldev;
  1575. PDD_SURFCB_DESTROYSURFACE pfn = (PDD_SURFCB_DESTROYSURFACE) ppdevData->apfnDriver[INDEX_DdDestroyD3DBuffer];
  1576. DWORD dwRet = 0;
  1577. if (pldev->bThreadStuck) {
  1578. return 0;
  1579. }
  1580. RECOVERY_SECTION_BEGIN(pldev) {
  1581. dwRet = pfn(lpDestroyD3DBuffer);
  1582. } RECOVERY_SECTION_END(pldev);
  1583. return dwRet;
  1584. }
  1585. DWORD APIENTRY
  1586. WatchdogDdLockD3DBuffer(
  1587. PDD_LOCKDATA lpLockD3DBuffer)
  1588. {
  1589. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpLockD3DBuffer->lpDD->dhpdev);
  1590. PLDEV pldev = ppdevData->pldev;
  1591. PDD_SURFCB_LOCK pfn = (PDD_SURFCB_LOCK) ppdevData->apfnDriver[INDEX_DdLockD3DBuffer];
  1592. DWORD dwRet = 0;
  1593. if (pldev->bThreadStuck) {
  1594. return 0;
  1595. }
  1596. RECOVERY_SECTION_BEGIN(pldev) {
  1597. dwRet = pfn(lpLockD3DBuffer);
  1598. } RECOVERY_SECTION_END(pldev);
  1599. return dwRet;
  1600. }
  1601. DWORD APIENTRY
  1602. WatchdogDdUnlockD3DBuffer(
  1603. PDD_UNLOCKDATA lpUnlockD3DBuffer)
  1604. {
  1605. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpUnlockD3DBuffer->lpDD->dhpdev);
  1606. PLDEV pldev = ppdevData->pldev;
  1607. PDD_SURFCB_UNLOCK pfn = (PDD_SURFCB_UNLOCK) ppdevData->apfnDriver[INDEX_DdUnlockD3DBuffer];
  1608. DWORD dwRet = 0;
  1609. if (pldev->bThreadStuck) {
  1610. return 0;
  1611. }
  1612. RECOVERY_SECTION_BEGIN(pldev) {
  1613. dwRet = pfn(lpUnlockD3DBuffer);
  1614. } RECOVERY_SECTION_END(pldev);
  1615. return dwRet;
  1616. }
  1617. DWORD APIENTRY
  1618. WatchdogDdGetAvailDriverMemory(
  1619. PDD_GETAVAILDRIVERMEMORYDATA lpGetAvailDriverMemory)
  1620. {
  1621. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpGetAvailDriverMemory->lpDD->dhpdev);
  1622. PLDEV pldev = ppdevData->pldev;
  1623. PDD_GETAVAILDRIVERMEMORY pfn = (PDD_GETAVAILDRIVERMEMORY) ppdevData->apfnDriver[INDEX_DdGetAvailDriverMemory];
  1624. DWORD dwRet = 0;
  1625. if (pldev->bThreadStuck) {
  1626. return 0;
  1627. }
  1628. RECOVERY_SECTION_BEGIN(pldev) {
  1629. dwRet = pfn(lpGetAvailDriverMemory);
  1630. } RECOVERY_SECTION_END(pldev);
  1631. return dwRet;
  1632. }
  1633. DWORD APIENTRY
  1634. WatchdogDdAlphaBlt(
  1635. PDD_BLTDATA lpAlphaBlt)
  1636. {
  1637. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpAlphaBlt->lpDD->dhpdev);
  1638. PLDEV pldev = ppdevData->pldev;
  1639. PDD_ALPHABLT pfn = (PDD_ALPHABLT) ppdevData->apfnDriver[INDEX_DdAlphaBlt];
  1640. DWORD dwRet = 0;
  1641. if (pldev->bThreadStuck) {
  1642. return 0;
  1643. }
  1644. RECOVERY_SECTION_BEGIN(pldev) {
  1645. dwRet = pfn(lpAlphaBlt);
  1646. } RECOVERY_SECTION_END(pldev);
  1647. return dwRet;
  1648. }
  1649. DWORD APIENTRY
  1650. WatchdogDdDrawPrimitives2(
  1651. LPD3DNTHAL_DRAWPRIMITIVES2DATA lpDrawPrimitives2)
  1652. {
  1653. PCONTEXT_NODE Node = (PCONTEXT_NODE) lpDrawPrimitives2->dwhContext;
  1654. LPD3DNTHAL_DRAWPRIMITIVES2CB pfn = (LPD3DNTHAL_DRAWPRIMITIVES2CB) Node->ppdevData->apfnDriver[INDEX_DdDrawPrimitives2];
  1655. PLDEV pldev = Node->ppdevData->pldev;
  1656. DWORD dwRet = 0;
  1657. if (pfn == NULL) {
  1658. lpDrawPrimitives2->ddrval = D3DNTHAL_CONTEXT_BAD;
  1659. return DDHAL_DRIVER_HANDLED;
  1660. }
  1661. if (pldev->bThreadStuck) {
  1662. return 0;
  1663. }
  1664. lpDrawPrimitives2->dwhContext = (DWORD_PTR) Node->Context;
  1665. RECOVERY_SECTION_BEGIN(pldev) {
  1666. dwRet = pfn(lpDrawPrimitives2);
  1667. } RECOVERY_SECTION_END(pldev);
  1668. lpDrawPrimitives2->dwhContext = (DWORD_PTR) Node;
  1669. return dwRet;
  1670. }
  1671. DWORD APIENTRY
  1672. WatchdogDdValidateTextureStageState(
  1673. LPD3DNTHAL_VALIDATETEXTURESTAGESTATEDATA lpValidateTextureStageState)
  1674. {
  1675. PCONTEXT_NODE Node = (PCONTEXT_NODE) lpValidateTextureStageState->dwhContext;
  1676. LPD3DNTHAL_VALIDATETEXTURESTAGESTATECB pfn = (LPD3DNTHAL_VALIDATETEXTURESTAGESTATECB) Node->ppdevData->apfnDriver[INDEX_DdValidateTextureStageState];
  1677. PLDEV pldev = Node->ppdevData->pldev;
  1678. DWORD dwRet = 0;
  1679. if (pfn == NULL) {
  1680. lpValidateTextureStageState->ddrval = D3DNTHAL_CONTEXT_BAD;
  1681. return DDHAL_DRIVER_HANDLED;
  1682. }
  1683. if (pldev->bThreadStuck) {
  1684. return 0;
  1685. }
  1686. lpValidateTextureStageState->dwhContext = (DWORD_PTR) Node->Context;
  1687. RECOVERY_SECTION_BEGIN(pldev) {
  1688. dwRet = pfn(lpValidateTextureStageState);
  1689. } RECOVERY_SECTION_END(pldev);
  1690. lpValidateTextureStageState->dwhContext = (DWORD_PTR) Node;
  1691. return dwRet;
  1692. }
  1693. DWORD APIENTRY
  1694. WatchdogDdSyncSurfaceData(
  1695. PDD_SYNCSURFACEDATA lpSyncSurfaceData)
  1696. {
  1697. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSyncSurfaceData->lpDD->lpGbl->dhpdev);
  1698. PLDEV pldev = ppdevData->pldev;
  1699. PDD_KERNELCB_SYNCSURFACE pfn = (PDD_KERNELCB_SYNCSURFACE) ppdevData->apfnDriver[INDEX_DdSyncSurfaceData];
  1700. DWORD dwRet = 0;
  1701. if (pldev->bThreadStuck) {
  1702. return 0;
  1703. }
  1704. RECOVERY_SECTION_BEGIN(pldev) {
  1705. dwRet = pfn(lpSyncSurfaceData);
  1706. } RECOVERY_SECTION_END(pldev);
  1707. return dwRet;
  1708. }
  1709. DWORD APIENTRY
  1710. WatchdogDdSyncVideoPortData(
  1711. PDD_SYNCVIDEOPORTDATA lpSyncVideoPortData)
  1712. {
  1713. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSyncVideoPortData->lpDD->lpGbl->dhpdev);
  1714. PLDEV pldev = ppdevData->pldev;
  1715. PDD_KERNELCB_SYNCVIDEOPORT pfn = (PDD_KERNELCB_SYNCVIDEOPORT) ppdevData->apfnDriver[INDEX_DdSyncVideoPortData];
  1716. DWORD dwRet = 0;
  1717. if (pldev->bThreadStuck) {
  1718. return 0;
  1719. }
  1720. RECOVERY_SECTION_BEGIN(pldev) {
  1721. dwRet = pfn(lpSyncVideoPortData);
  1722. } RECOVERY_SECTION_END(pldev);
  1723. return dwRet;
  1724. }
  1725. DWORD APIENTRY
  1726. WatchdogDdCreateSurfaceEx(
  1727. PDD_CREATESURFACEEXDATA lpCreateSurfaceEx)
  1728. {
  1729. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpCreateSurfaceEx->lpDDLcl->lpGbl->dhpdev);
  1730. PLDEV pldev = ppdevData->pldev;
  1731. PDD_CREATESURFACEEX pfn = (PDD_CREATESURFACEEX) ppdevData->apfnDriver[INDEX_DdCreateSurfaceEx];
  1732. DWORD dwRet = 0;
  1733. if (pldev->bThreadStuck) {
  1734. return 0;
  1735. }
  1736. RECOVERY_SECTION_BEGIN(pldev) {
  1737. dwRet = pfn(lpCreateSurfaceEx);
  1738. } RECOVERY_SECTION_END(pldev);
  1739. return dwRet;
  1740. }
  1741. DWORD APIENTRY
  1742. WatchdogDdDestroyDDLocal(
  1743. PDD_DESTROYDDLOCALDATA lpDestroyDDLocal)
  1744. {
  1745. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpDestroyDDLocal->pDDLcl->lpGbl->dhpdev);
  1746. PLDEV pldev = ppdevData->pldev;
  1747. PDD_DESTROYDDLOCAL pfn = (PDD_DESTROYDDLOCAL) ppdevData->apfnDriver[INDEX_DdDestroyDDLocal];
  1748. DWORD dwRet = 0;
  1749. if (pldev->bThreadStuck) {
  1750. return 0;
  1751. }
  1752. RECOVERY_SECTION_BEGIN(pldev) {
  1753. dwRet = pfn(lpDestroyDDLocal);
  1754. } RECOVERY_SECTION_END(pldev);
  1755. return dwRet;
  1756. }
  1757. DWORD APIENTRY
  1758. WatchdogDdFreeDriverMemory(
  1759. PDD_FREEDRIVERMEMORYDATA lpFreeDriverMemory)
  1760. {
  1761. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpFreeDriverMemory->lpDD->dhpdev);
  1762. PLDEV pldev = ppdevData->pldev;
  1763. PDD_FREEDRIVERMEMORY pfn = (PDD_FREEDRIVERMEMORY) ppdevData->apfnDriver[INDEX_DdFreeDriverMemory];
  1764. DWORD dwRet = 0;
  1765. if (pldev->bThreadStuck) {
  1766. return 0;
  1767. }
  1768. RECOVERY_SECTION_BEGIN(pldev) {
  1769. dwRet = pfn(lpFreeDriverMemory);
  1770. } RECOVERY_SECTION_END(pldev);
  1771. return dwRet;
  1772. }
  1773. DWORD APIENTRY
  1774. WatchdogDdSetExclusiveMode(
  1775. PDD_SETEXCLUSIVEMODEDATA lpSetExclusiveMode)
  1776. {
  1777. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpSetExclusiveMode->lpDD->dhpdev);
  1778. PLDEV pldev = ppdevData->pldev;
  1779. PDD_SETEXCLUSIVEMODE pfn = (PDD_SETEXCLUSIVEMODE) ppdevData->apfnDriver[INDEX_DdSetExclusiveMode];
  1780. DWORD dwRet = 0;
  1781. if (pldev->bThreadStuck) {
  1782. return 0;
  1783. }
  1784. RECOVERY_SECTION_BEGIN(pldev) {
  1785. dwRet = pfn(lpSetExclusiveMode);
  1786. } RECOVERY_SECTION_END(pldev);
  1787. return dwRet;
  1788. }
  1789. DWORD APIENTRY
  1790. WatchdogDdFlipToGDISurface(
  1791. PDD_FLIPTOGDISURFACEDATA lpFlipToGDISurface)
  1792. {
  1793. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode((DHPDEV)lpFlipToGDISurface->lpDD->dhpdev);
  1794. PLDEV pldev = ppdevData->pldev;
  1795. PDD_FLIPTOGDISURFACE pfn = (PDD_FLIPTOGDISURFACE) ppdevData->apfnDriver[INDEX_DdFlipToGDISurface];
  1796. DWORD dwRet = 0;
  1797. if (pldev->bThreadStuck) {
  1798. return 0;
  1799. }
  1800. RECOVERY_SECTION_BEGIN(pldev) {
  1801. dwRet = pfn(lpFlipToGDISurface);
  1802. } RECOVERY_SECTION_END(pldev);
  1803. return dwRet;
  1804. }
  1805. DWORD APIENTRY
  1806. WatchdogDdGetDriverInfo(
  1807. PDD_GETDRIVERINFODATA lpGetDriverInfo
  1808. )
  1809. {
  1810. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE)dhpdevRetrieveNode((DHPDEV)lpGetDriverInfo->dhpdev);
  1811. PLDEV pldev = ppdevData->pldev;
  1812. PDD_GETDRIVERINFO pfn = (PDD_GETDRIVERINFO) ppdevData->apfnDriver[INDEX_DdGetDriverInfo];
  1813. DWORD dwRet = 0;
  1814. //
  1815. // Return early if we are in a thread stuck condition
  1816. //
  1817. if (pldev->bThreadStuck) {
  1818. return 0;
  1819. }
  1820. RECOVERY_SECTION_BEGIN(pldev) {
  1821. dwRet = pfn(lpGetDriverInfo);
  1822. } RECOVERY_SECTION_END(pldev);
  1823. if ((dwRet == DDHAL_DRIVER_HANDLED) &&
  1824. (lpGetDriverInfo->ddRVal == DD_OK)) {
  1825. if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_ColorControlCallbacks)) {
  1826. PDD_COLORCONTROLCALLBACKS Callbacks = (PDD_COLORCONTROLCALLBACKS) lpGetDriverInfo->lpvData;
  1827. if (Callbacks->dwFlags & DDHAL_COLOR_COLORCONTROL) {
  1828. if (Callbacks->ColorControl != WatchdogDdColorControl) {
  1829. ppdevData->apfnDriver[INDEX_DdColorControl] = (PFN)Callbacks->ColorControl;
  1830. }
  1831. Callbacks->ColorControl = WatchdogDdColorControl;
  1832. }
  1833. } else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_D3DCallbacks)) {
  1834. LPD3DNTHAL_CALLBACKS Callbacks = (LPD3DNTHAL_CALLBACKS) lpGetDriverInfo->lpvData;
  1835. if (Callbacks->ContextCreate) {
  1836. if (Callbacks->ContextCreate != WatchdogDdContextCreate) {
  1837. ppdevData->apfnDriver[INDEX_DdContextCreate] = (PFN)Callbacks->ContextCreate;
  1838. }
  1839. Callbacks->ContextCreate = WatchdogDdContextCreate;
  1840. }
  1841. if (Callbacks->ContextDestroy) {
  1842. if (Callbacks->ContextDestroy != WatchdogDdContextDestroy) {
  1843. ppdevData->apfnDriver[INDEX_DdContextDestroy] = (PFN)Callbacks->ContextDestroy;
  1844. }
  1845. Callbacks->ContextDestroy = WatchdogDdContextDestroy;
  1846. }
  1847. } else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_D3DCallbacks3)) {
  1848. LPD3DNTHAL_CALLBACKS3 Callbacks = (LPD3DNTHAL_CALLBACKS3) lpGetDriverInfo->lpvData;
  1849. if (Callbacks->DrawPrimitives2) {
  1850. if (Callbacks->DrawPrimitives2 != WatchdogDdDrawPrimitives2) {
  1851. ppdevData->apfnDriver[INDEX_DdDrawPrimitives2] = (PFN)Callbacks->DrawPrimitives2;
  1852. }
  1853. Callbacks->DrawPrimitives2 = WatchdogDdDrawPrimitives2;
  1854. }
  1855. if (Callbacks->ValidateTextureStageState) {
  1856. if (Callbacks->ValidateTextureStageState != WatchdogDdValidateTextureStageState) {
  1857. ppdevData->apfnDriver[INDEX_DdValidateTextureStageState] = (PFN)Callbacks->ValidateTextureStageState;
  1858. }
  1859. Callbacks->ValidateTextureStageState = WatchdogDdValidateTextureStageState;
  1860. }
  1861. } else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_KernelCallbacks)) {
  1862. PDD_KERNELCALLBACKS Callbacks = (PDD_KERNELCALLBACKS) lpGetDriverInfo->lpvData;
  1863. if (Callbacks->dwFlags & DDHAL_KERNEL_SYNCSURFACEDATA) {
  1864. if (Callbacks->SyncSurfaceData != WatchdogDdSyncSurfaceData) {
  1865. ppdevData->apfnDriver[INDEX_DdSyncSurfaceData] = (PFN)Callbacks->SyncSurfaceData;
  1866. }
  1867. Callbacks->SyncSurfaceData = WatchdogDdSyncSurfaceData;
  1868. }
  1869. if (Callbacks->dwFlags & DDHAL_KERNEL_SYNCVIDEOPORTDATA) {
  1870. if (Callbacks->SyncVideoPortData != WatchdogDdSyncVideoPortData) {
  1871. ppdevData->apfnDriver[INDEX_DdSyncVideoPortData] = (PFN)Callbacks->SyncVideoPortData;
  1872. }
  1873. Callbacks->SyncVideoPortData = WatchdogDdSyncVideoPortData;
  1874. }
  1875. } else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_MiscellaneousCallbacks)) {
  1876. PDD_MISCELLANEOUSCALLBACKS Callbacks = (PDD_MISCELLANEOUSCALLBACKS) lpGetDriverInfo->lpvData;
  1877. if (Callbacks->dwFlags & DDHAL_MISCCB32_GETAVAILDRIVERMEMORY) {
  1878. if (Callbacks->GetAvailDriverMemory != WatchdogDdGetAvailDriverMemory) {
  1879. ppdevData->apfnDriver[INDEX_DdGetAvailDriverMemory] = (PFN)Callbacks->GetAvailDriverMemory;
  1880. }
  1881. Callbacks->GetAvailDriverMemory = WatchdogDdGetAvailDriverMemory;
  1882. }
  1883. } else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_Miscellaneous2Callbacks)) {
  1884. PDD_MISCELLANEOUS2CALLBACKS Callbacks = (PDD_MISCELLANEOUS2CALLBACKS) lpGetDriverInfo->lpvData;
  1885. if (Callbacks->dwFlags & DDHAL_MISC2CB32_ALPHABLT) {
  1886. if (Callbacks->AlphaBlt != WatchdogDdAlphaBlt) {
  1887. ppdevData->apfnDriver[INDEX_DdAlphaBlt] = (PFN)Callbacks->AlphaBlt;
  1888. }
  1889. Callbacks->AlphaBlt = WatchdogDdAlphaBlt;
  1890. }
  1891. if (Callbacks->dwFlags & DDHAL_MISC2CB32_CREATESURFACEEX) {
  1892. if (Callbacks->CreateSurfaceEx != WatchdogDdCreateSurfaceEx) {
  1893. ppdevData->apfnDriver[INDEX_DdCreateSurfaceEx] = (PFN)Callbacks->CreateSurfaceEx;
  1894. }
  1895. Callbacks->CreateSurfaceEx = WatchdogDdCreateSurfaceEx;
  1896. }
  1897. if (Callbacks->dwFlags & DDHAL_MISC2CB32_GETDRIVERSTATE) {
  1898. if (Callbacks->GetDriverState != WatchdogDdGetDriverState) {
  1899. ppdevData->apfnDriver[INDEX_DdGetDriverState] = (PFN)Callbacks->GetDriverState;
  1900. }
  1901. Callbacks->GetDriverState = WatchdogDdGetDriverState;
  1902. }
  1903. if (Callbacks->dwFlags & DDHAL_MISC2CB32_DESTROYDDLOCAL) {
  1904. if (Callbacks->DestroyDDLocal != WatchdogDdDestroyDDLocal) {
  1905. ppdevData->apfnDriver[INDEX_DdDestroyDDLocal] = (PFN)Callbacks->DestroyDDLocal;
  1906. }
  1907. Callbacks->DestroyDDLocal = WatchdogDdDestroyDDLocal;
  1908. }
  1909. } else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_MotionCompCallbacks)) {
  1910. //
  1911. // TODO: Still need to implement
  1912. //
  1913. } else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_NTCallbacks)) {
  1914. PDD_NTCALLBACKS Callbacks = (PDD_NTCALLBACKS) lpGetDriverInfo->lpvData;
  1915. if (Callbacks->dwFlags & DDHAL_NTCB32_FREEDRIVERMEMORY) {
  1916. if (Callbacks->FreeDriverMemory != WatchdogDdFreeDriverMemory) {
  1917. ppdevData->apfnDriver[INDEX_DdFreeDriverMemory] = (PFN)Callbacks->FreeDriverMemory;
  1918. }
  1919. Callbacks->FreeDriverMemory = WatchdogDdFreeDriverMemory;
  1920. }
  1921. if (Callbacks->dwFlags & DDHAL_NTCB32_SETEXCLUSIVEMODE) {
  1922. if (Callbacks->SetExclusiveMode != WatchdogDdSetExclusiveMode) {
  1923. ppdevData->apfnDriver[INDEX_DdSetExclusiveMode] = (PFN)Callbacks->SetExclusiveMode;
  1924. }
  1925. Callbacks->SetExclusiveMode = WatchdogDdSetExclusiveMode;
  1926. }
  1927. if (Callbacks->dwFlags & DDHAL_NTCB32_FLIPTOGDISURFACE) {
  1928. if (Callbacks->FlipToGDISurface != WatchdogDdFlipToGDISurface) {
  1929. ppdevData->apfnDriver[INDEX_DdFlipToGDISurface] = (PFN)Callbacks->FlipToGDISurface;
  1930. }
  1931. Callbacks->FlipToGDISurface = WatchdogDdFlipToGDISurface;
  1932. }
  1933. } else if (IsEqualGUID(&lpGetDriverInfo->guidInfo, &GUID_VideoPortCallbacks)) {
  1934. //
  1935. // TODO: Still need to implement
  1936. //
  1937. }
  1938. }
  1939. return dwRet;
  1940. }
  1941. BOOL APIENTRY
  1942. WatchdogDrvGetDirectDrawInfo(
  1943. DHPDEV dhpdev,
  1944. DD_HALINFO *pHalInfo,
  1945. DWORD *pdwNumHeaps,
  1946. VIDEOMEMORY *pvmList,
  1947. DWORD *pdwNumFourCCCodes,
  1948. DWORD *pdwFourCC
  1949. )
  1950. {
  1951. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode(dhpdev);
  1952. PLDEV pldev = ppdevData->pldev;
  1953. PFN_DrvGetDirectDrawInfo pfn = (PFN_DrvGetDirectDrawInfo) pldev->apfnDriver[INDEX_DrvGetDirectDrawInfo];
  1954. BOOL bRet = 0;
  1955. //
  1956. // Return early if we are in a thread stuck condition
  1957. //
  1958. if (pldev->bThreadStuck) {
  1959. return 0;
  1960. }
  1961. RECOVERY_SECTION_BEGIN(pldev) {
  1962. bRet = pfn(dhpdev, pHalInfo, pdwNumHeaps, pvmList, pdwNumFourCCCodes, pdwFourCC);
  1963. } RECOVERY_SECTION_END(pldev);
  1964. //
  1965. // If the function succeeded, then try to capture the DdGetDriverInfo
  1966. // function from pHalInfo.
  1967. //
  1968. if (bRet) {
  1969. if (pHalInfo->GetDriverInfo) {
  1970. if (pHalInfo->GetDriverInfo != WatchdogDdGetDriverInfo) {
  1971. ppdevData->apfnDriver[INDEX_DdGetDriverInfo] = (PFN)pHalInfo->GetDriverInfo;
  1972. }
  1973. pHalInfo->GetDriverInfo = WatchdogDdGetDriverInfo;
  1974. }
  1975. if (pHalInfo->lpD3DHALCallbacks) {
  1976. LPD3DNTHAL_CALLBACKS lpD3DHALCallbacks;
  1977. lpD3DHALCallbacks = (LPD3DNTHAL_CALLBACKS)pHalInfo->lpD3DHALCallbacks;
  1978. //
  1979. // Create copy of D3DHALCallbacks info - This is done to safely
  1980. // latch the callbacks witout actually changing driver local data
  1981. //
  1982. memcpy(&ppdevData->D3DHALCallbacks,
  1983. lpD3DHALCallbacks,
  1984. min(sizeof(ppdevData->D3DHALCallbacks), lpD3DHALCallbacks->dwSize));
  1985. pHalInfo->lpD3DHALCallbacks = lpD3DHALCallbacks = &ppdevData->D3DHALCallbacks;
  1986. if (lpD3DHALCallbacks->ContextCreate &&
  1987. lpD3DHALCallbacks->ContextDestroy) {
  1988. if (lpD3DHALCallbacks->ContextCreate != WatchdogDdContextCreate) {
  1989. ppdevData->apfnDriver[INDEX_DdContextCreate] = (PFN)lpD3DHALCallbacks->ContextCreate;
  1990. }
  1991. if (lpD3DHALCallbacks->ContextDestroy != WatchdogDdContextDestroy) {
  1992. ppdevData->apfnDriver[INDEX_DdContextDestroy] = (PFN)lpD3DHALCallbacks->ContextDestroy;
  1993. }
  1994. lpD3DHALCallbacks->ContextCreate = WatchdogDdContextCreate;
  1995. lpD3DHALCallbacks->ContextDestroy = WatchdogDdContextDestroy;
  1996. }
  1997. }
  1998. if (pHalInfo->lpD3DBufCallbacks) {
  1999. PDD_D3DBUFCALLBACKS lpD3DBufCallbacks;
  2000. lpD3DBufCallbacks = pHalInfo->lpD3DBufCallbacks;
  2001. //
  2002. // Create copy of D3DBufCallbacks info - This is done to safely
  2003. // latch the callbacks witout actually changing driver local data
  2004. //
  2005. memcpy(&ppdevData->D3DBufCallbacks,
  2006. lpD3DBufCallbacks,
  2007. min(sizeof(ppdevData->D3DBufCallbacks), lpD3DBufCallbacks->dwSize));
  2008. lpD3DBufCallbacks = pHalInfo->lpD3DBufCallbacks = &ppdevData->D3DBufCallbacks;
  2009. if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, CanCreateD3DBuffer)) &&
  2010. (lpD3DBufCallbacks->CanCreateD3DBuffer)) {
  2011. if (lpD3DBufCallbacks->CanCreateD3DBuffer != WatchdogDdCanCreateD3DBuffer) {
  2012. ppdevData->apfnDriver[INDEX_DdCanCreateD3DBuffer] = (PFN)lpD3DBufCallbacks->CanCreateD3DBuffer;
  2013. }
  2014. lpD3DBufCallbacks->CanCreateD3DBuffer = WatchdogDdCanCreateD3DBuffer;
  2015. }
  2016. if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, CreateD3DBuffer)) &&
  2017. (lpD3DBufCallbacks->CreateD3DBuffer)) {
  2018. if (lpD3DBufCallbacks->CreateD3DBuffer != WatchdogDdCreateD3DBuffer) {
  2019. ppdevData->apfnDriver[INDEX_DdCreateD3DBuffer] = (PFN)lpD3DBufCallbacks->CreateD3DBuffer;
  2020. }
  2021. lpD3DBufCallbacks->CreateD3DBuffer = WatchdogDdCreateD3DBuffer;
  2022. }
  2023. if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, DestroyD3DBuffer)) &&
  2024. (lpD3DBufCallbacks->DestroyD3DBuffer)) {
  2025. if (lpD3DBufCallbacks->DestroyD3DBuffer != WatchdogDdDestroyD3DBuffer) {
  2026. ppdevData->apfnDriver[INDEX_DdDestroyD3DBuffer] = (PFN)lpD3DBufCallbacks->DestroyD3DBuffer;
  2027. }
  2028. lpD3DBufCallbacks->DestroyD3DBuffer = WatchdogDdDestroyD3DBuffer;
  2029. }
  2030. if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, LockD3DBuffer)) &&
  2031. (lpD3DBufCallbacks->LockD3DBuffer)) {
  2032. if (lpD3DBufCallbacks->LockD3DBuffer != WatchdogDdLockD3DBuffer) {
  2033. ppdevData->apfnDriver[INDEX_DdLockD3DBuffer] = (PFN)lpD3DBufCallbacks->LockD3DBuffer;
  2034. }
  2035. lpD3DBufCallbacks->LockD3DBuffer = WatchdogDdLockD3DBuffer;
  2036. }
  2037. if ((lpD3DBufCallbacks->dwSize > FIELD_OFFSET(DD_D3DBUFCALLBACKS, UnlockD3DBuffer)) &&
  2038. (lpD3DBufCallbacks->UnlockD3DBuffer)) {
  2039. if (lpD3DBufCallbacks->UnlockD3DBuffer != WatchdogDdUnlockD3DBuffer) {
  2040. ppdevData->apfnDriver[INDEX_DdUnlockD3DBuffer] = (PFN)lpD3DBufCallbacks->UnlockD3DBuffer;
  2041. }
  2042. lpD3DBufCallbacks->UnlockD3DBuffer = WatchdogDdUnlockD3DBuffer;
  2043. }
  2044. }
  2045. }
  2046. return bRet;
  2047. }
  2048. BOOL APIENTRY
  2049. WatchdogDrvEnableDirectDraw(
  2050. DHPDEV dhpdev,
  2051. DD_CALLBACKS *pCallBacks,
  2052. DD_SURFACECALLBACKS *pSurfaceCallBacks,
  2053. DD_PALETTECALLBACKS *pPaletteCallBacks
  2054. )
  2055. {
  2056. PDHPDEV_ASSOCIATION_NODE ppdevData = (PDHPDEV_ASSOCIATION_NODE) dhpdevRetrieveNode(dhpdev);
  2057. PLDEV pldev = ppdevData->pldev;
  2058. PFN_DrvEnableDirectDraw pfn = (PFN_DrvEnableDirectDraw) pldev->apfnDriver[INDEX_DrvEnableDirectDraw];
  2059. BOOL bRet = FALSE;
  2060. //
  2061. // Return early if we are in a thread stuck condition
  2062. //
  2063. if (pldev->bThreadStuck) {
  2064. return FALSE;
  2065. }
  2066. RECOVERY_SECTION_BEGIN(pldev) {
  2067. bRet = pfn(dhpdev, pCallBacks, pSurfaceCallBacks, pPaletteCallBacks);
  2068. } RECOVERY_SECTION_END(pldev);
  2069. //
  2070. // If the function succeeded, then try to capture the Callback functions.
  2071. //
  2072. if (bRet) {
  2073. //
  2074. // Capture generic callbacks
  2075. //
  2076. if (pCallBacks->dwFlags & DDHAL_CB32_CANCREATESURFACE) {
  2077. if (pCallBacks->CanCreateSurface != WatchdogDdCanCreateSurface) {
  2078. ppdevData->apfnDriver[INDEX_DdCanCreateSurface] = (PFN)pCallBacks->CanCreateSurface;
  2079. }
  2080. pCallBacks->CanCreateSurface = WatchdogDdCanCreateSurface;
  2081. }
  2082. if (pCallBacks->dwFlags & DDHAL_CB32_CREATESURFACE) {
  2083. if (pCallBacks->CreateSurface != WatchdogDdCreateSurface) {
  2084. ppdevData->apfnDriver[INDEX_DdCreateSurface] = (PFN)pCallBacks->CreateSurface;
  2085. }
  2086. pCallBacks->CreateSurface = WatchdogDdCreateSurface;
  2087. }
  2088. if (pCallBacks->dwFlags & DDHAL_CB32_CREATEPALETTE) {
  2089. if (pCallBacks->CreatePalette != WatchdogDdCreatePalette) {
  2090. ppdevData->apfnDriver[INDEX_DdCreatePalette] = (PFN)pCallBacks->CreatePalette;
  2091. }
  2092. pCallBacks->CreatePalette = WatchdogDdCreatePalette;
  2093. }
  2094. if (pCallBacks->dwFlags & DDHAL_CB32_GETSCANLINE) {
  2095. if (pCallBacks->GetScanLine != WatchdogDdGetScanLine) {
  2096. ppdevData->apfnDriver[INDEX_DdGetScanLine] = (PFN)pCallBacks->GetScanLine;
  2097. }
  2098. pCallBacks->GetScanLine = WatchdogDdGetScanLine;
  2099. }
  2100. if (pCallBacks->dwFlags & DDHAL_CB32_MAPMEMORY) {
  2101. if (pCallBacks->MapMemory != WatchdogDdMapMemory) {
  2102. ppdevData->apfnDriver[INDEX_DdMapMemory] = (PFN)pCallBacks->MapMemory;
  2103. }
  2104. pCallBacks->MapMemory = WatchdogDdMapMemory;
  2105. }
  2106. #if 0
  2107. //
  2108. // We can't hook this because there is no way to get the dhpdev
  2109. // back
  2110. //
  2111. if (pCallBacks->dwFlags & DDHAL_CB32_SETCOLORKEY) {
  2112. if (pCallBacks->SetColorKey != WatchdogDdSetColorKey) {
  2113. ppdevData->apfnDriver[INDEX_DdSetColorKey] = (PFN)pCallBacks->SetColorKey;
  2114. }
  2115. pCallBacks->SetColorKey = WatchdogDdSetColorKey;
  2116. }
  2117. #endif
  2118. if (pCallBacks->dwFlags & DDHAL_CB32_WAITFORVERTICALBLANK) {
  2119. if (pCallBacks->WaitForVerticalBlank != WatchdogDdWaitForVerticalBlank) {
  2120. ppdevData->apfnDriver[INDEX_DdWaitForVerticalBlank] = (PFN)pCallBacks->WaitForVerticalBlank;
  2121. }
  2122. pCallBacks->WaitForVerticalBlank = WatchdogDdWaitForVerticalBlank;
  2123. }
  2124. //
  2125. // Capture Surface Callbacks
  2126. //
  2127. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_DESTROYSURFACE) {
  2128. if (pSurfaceCallBacks->DestroySurface != WatchdogDdDestroySurface) {
  2129. ppdevData->apfnDriver[INDEX_DdDestroySurface] = (PFN)pSurfaceCallBacks->DestroySurface;
  2130. }
  2131. pSurfaceCallBacks->DestroySurface = WatchdogDdDestroySurface;
  2132. }
  2133. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_FLIP) {
  2134. if (pSurfaceCallBacks->Flip != WatchdogDdFlip) {
  2135. ppdevData->apfnDriver[INDEX_DdFlip] = (PFN)pSurfaceCallBacks->Flip;
  2136. }
  2137. pSurfaceCallBacks->Flip = WatchdogDdFlip;
  2138. }
  2139. #if 0
  2140. //
  2141. // SetClipList is obsolete
  2142. //
  2143. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETCLIPLIST) {
  2144. if (pSurfaceCallBacks->SetClipList != WatchdogDdSetClipList) {
  2145. ppdevData->apfnDriver[INDEX_DdSetClipList] = (PFN)pSurfaceCallBacks->SetClipList;
  2146. }
  2147. pSurfaceCallBacks->SetClipList = WatchdogDdSetClipList;
  2148. }
  2149. #endif
  2150. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_LOCK) {
  2151. if (pSurfaceCallBacks->Lock != WatchdogDdLock) {
  2152. ppdevData->apfnDriver[INDEX_DdLock] = (PFN)pSurfaceCallBacks->Lock;
  2153. }
  2154. pSurfaceCallBacks->Lock = WatchdogDdLock;
  2155. }
  2156. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_UNLOCK) {
  2157. if (pSurfaceCallBacks->Unlock != WatchdogDdUnlock) {
  2158. ppdevData->apfnDriver[INDEX_DdUnlock] = (PFN)pSurfaceCallBacks->Unlock;
  2159. }
  2160. pSurfaceCallBacks->Unlock = WatchdogDdUnlock;
  2161. }
  2162. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_BLT) {
  2163. if (pSurfaceCallBacks->Blt != WatchdogDdBlt) {
  2164. ppdevData->apfnDriver[INDEX_DdBlt] = (PFN)pSurfaceCallBacks->Blt;
  2165. }
  2166. pSurfaceCallBacks->Blt = WatchdogDdBlt;
  2167. }
  2168. #if 0
  2169. //
  2170. // We can't hook this because there is no way to get the dhpdev
  2171. // back
  2172. //
  2173. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETCOLORKEY) {
  2174. if (pSurfaceCallBacks->SetColorKey != WatchdogDdSetColorKey) {
  2175. ppdevData->apfnDriver[INDEX_DdSetColorKey] = (PFN)pSurfaceCallBacks->SetColorKey;
  2176. }
  2177. pSurfaceCallBacks->SetColorKey = WatchdogDdSetColorKey;
  2178. }
  2179. #endif
  2180. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_ADDATTACHEDSURFACE) {
  2181. if (pSurfaceCallBacks->AddAttachedSurface != WatchdogDdAddAttachedSurface) {
  2182. ppdevData->apfnDriver[INDEX_DdAddAttachedSurface] = (PFN)pSurfaceCallBacks->AddAttachedSurface;
  2183. }
  2184. pSurfaceCallBacks->AddAttachedSurface = WatchdogDdAddAttachedSurface;
  2185. }
  2186. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_GETBLTSTATUS) {
  2187. if (pSurfaceCallBacks->GetBltStatus != WatchdogDdGetBltStatus) {
  2188. ppdevData->apfnDriver[INDEX_DdGetBltStatus] = (PFN)pSurfaceCallBacks->GetBltStatus;
  2189. }
  2190. pSurfaceCallBacks->GetBltStatus = WatchdogDdGetBltStatus;
  2191. }
  2192. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_GETFLIPSTATUS) {
  2193. if (pSurfaceCallBacks->GetFlipStatus != WatchdogDdGetFlipStatus) {
  2194. ppdevData->apfnDriver[INDEX_DdGetFlipStatus] = (PFN)pSurfaceCallBacks->GetFlipStatus;
  2195. }
  2196. pSurfaceCallBacks->GetFlipStatus = WatchdogDdGetFlipStatus;
  2197. }
  2198. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_UPDATEOVERLAY) {
  2199. if (pSurfaceCallBacks->UpdateOverlay != WatchdogDdUpdateOverlay) {
  2200. ppdevData->apfnDriver[INDEX_DdUpdateOverlay] = (PFN)pSurfaceCallBacks->UpdateOverlay;
  2201. }
  2202. pSurfaceCallBacks->UpdateOverlay = WatchdogDdUpdateOverlay;
  2203. }
  2204. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETOVERLAYPOSITION) {
  2205. if (pSurfaceCallBacks->SetOverlayPosition != WatchdogDdSetOverlayPosition) {
  2206. ppdevData->apfnDriver[INDEX_DdSetOverlayPosition] = (PFN)pSurfaceCallBacks->SetOverlayPosition;
  2207. }
  2208. pSurfaceCallBacks->SetOverlayPosition = WatchdogDdSetOverlayPosition;
  2209. }
  2210. if (pSurfaceCallBacks->dwFlags & DDHAL_SURFCB32_SETPALETTE) {
  2211. if (pSurfaceCallBacks->SetPalette != WatchdogDdSetPalette) {
  2212. ppdevData->apfnDriver[INDEX_DdSetPalette] = (PFN)pSurfaceCallBacks->SetPalette;
  2213. }
  2214. pSurfaceCallBacks->SetPalette = WatchdogDdSetPalette;
  2215. }
  2216. //
  2217. // Capture Palette Callbacks
  2218. //
  2219. if (pPaletteCallBacks->dwFlags & DDHAL_PALCB32_DESTROYPALETTE) {
  2220. if (pPaletteCallBacks->DestroyPalette != WatchdogDdDestroyPalette) {
  2221. ppdevData->apfnDriver[INDEX_DdDestroyPalette] = (PFN)pPaletteCallBacks->DestroyPalette;
  2222. }
  2223. pPaletteCallBacks->DestroyPalette = WatchdogDdDestroyPalette;
  2224. }
  2225. if (pPaletteCallBacks->dwFlags & DDHAL_PALCB32_SETENTRIES) {
  2226. if (pPaletteCallBacks->SetEntries != WatchdogDdSetEntries) {
  2227. ppdevData->apfnDriver[INDEX_DdSetEntries] = (PFN)pPaletteCallBacks->SetEntries;
  2228. }
  2229. pPaletteCallBacks->SetEntries = WatchdogDdSetEntries;
  2230. }
  2231. }
  2232. return bRet;
  2233. }
  2234. VOID APIENTRY
  2235. WatchdogDrvDisableDirectDraw(
  2236. DHPDEV dhpdev
  2237. )
  2238. {
  2239. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  2240. PFN_DrvDisableDirectDraw pfn = (PFN_DrvDisableDirectDraw) pldev->apfnDriver[INDEX_DrvDisableDirectDraw];
  2241. //
  2242. // Return early if we are in a thread stuck condition
  2243. //
  2244. if (pldev->bThreadStuck) {
  2245. return;
  2246. }
  2247. RECOVERY_SECTION_BEGIN(pldev) {
  2248. pfn(dhpdev);
  2249. } RECOVERY_SECTION_END(pldev);
  2250. }
  2251. BOOL APIENTRY
  2252. WatchdogDrvIcmSetDeviceGammaRamp(
  2253. IN DHPDEV dhpdev,
  2254. IN ULONG iFormat,
  2255. IN LPVOID ipRamp
  2256. )
  2257. {
  2258. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  2259. PFN_DrvIcmSetDeviceGammaRamp pfn = (PFN_DrvIcmSetDeviceGammaRamp) pldev->apfnDriver[INDEX_DrvIcmSetDeviceGammaRamp];
  2260. BOOL bRet = TRUE;
  2261. if (pldev->bThreadStuck) {
  2262. return bRet;
  2263. }
  2264. RECOVERY_SECTION_BEGIN(pldev) {
  2265. bRet = pfn(dhpdev, iFormat, ipRamp);
  2266. } RECOVERY_SECTION_END(pldev);
  2267. return bRet;
  2268. }
  2269. BOOL APIENTRY
  2270. WatchdogDrvStretchBltROP(
  2271. SURFOBJ *psoDst,
  2272. SURFOBJ *psoSrc,
  2273. SURFOBJ *psoMask,
  2274. CLIPOBJ *pco,
  2275. XLATEOBJ *pxlo,
  2276. COLORADJUSTMENT *pca,
  2277. POINTL *pptlHTOrg,
  2278. RECTL *prclDst,
  2279. RECTL *prclSrc,
  2280. POINTL *pptlMask,
  2281. ULONG iMode,
  2282. BRUSHOBJ *pbo,
  2283. DWORD rop4
  2284. )
  2285. {
  2286. SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc;
  2287. PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev);
  2288. PFN_DrvStretchBltROP pfn = (PFN_DrvStretchBltROP) pldev->apfnDriver[INDEX_DrvStretchBltROP];
  2289. BOOL bRet = TRUE;
  2290. //
  2291. // Return early if we are in a thread stuck condition
  2292. //
  2293. if (pldev->bThreadStuck) {
  2294. return TRUE;
  2295. }
  2296. RECOVERY_SECTION_BEGIN(pldev) {
  2297. bRet = pfn(psoDst, psoSrc, psoMask, pco, pxlo, pca, pptlHTOrg, prclDst, prclSrc, pptlMask, iMode, pbo, rop4);
  2298. } RECOVERY_SECTION_END(pldev);
  2299. return bRet;
  2300. }
  2301. BOOL APIENTRY
  2302. WatchdogDrvPlgBlt(
  2303. IN SURFOBJ *psoTrg,
  2304. IN SURFOBJ *psoSrc,
  2305. IN SURFOBJ *psoMsk,
  2306. IN CLIPOBJ *pco,
  2307. IN XLATEOBJ *pxlo,
  2308. IN COLORADJUSTMENT *pca,
  2309. IN POINTL *pptlBrushOrg,
  2310. IN POINTFIX *pptfx,
  2311. IN RECTL *prcl,
  2312. IN POINTL *pptl,
  2313. IN ULONG iMode
  2314. )
  2315. {
  2316. PLDEV pldev = dhpdevRetrieveLdev(psoTrg->dhpdev);
  2317. PFN_DrvPlgBlt pfn = (PFN_DrvPlgBlt) pldev->apfnDriver[INDEX_DrvPlgBlt];
  2318. BOOL bRet = TRUE;
  2319. //
  2320. // Return early if we are in a thread stuck condition
  2321. //
  2322. if (pldev->bThreadStuck) {
  2323. return TRUE;
  2324. }
  2325. RECOVERY_SECTION_BEGIN(pldev) {
  2326. bRet = pfn(psoTrg, psoSrc, psoMsk, pco, pxlo, pca, pptlBrushOrg, pptfx, prcl, pptl, iMode);
  2327. } RECOVERY_SECTION_END(pldev);
  2328. return bRet;
  2329. }
  2330. BOOL APIENTRY
  2331. WatchdogDrvAlphaBlend(
  2332. SURFOBJ *psoDest,
  2333. SURFOBJ *psoSrc,
  2334. CLIPOBJ *pco,
  2335. XLATEOBJ *pxlo,
  2336. RECTL *prclDest,
  2337. RECTL *prclSrc,
  2338. BLENDOBJ *pBlendObj
  2339. )
  2340. {
  2341. SURFOBJ *psoDevice = (psoDest->dhpdev) ? psoDest : psoSrc;
  2342. PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev);
  2343. PFN_DrvAlphaBlend pfn = (PFN_DrvAlphaBlend) pldev->apfnDriver[INDEX_DrvAlphaBlend];
  2344. BOOL bRet = TRUE;
  2345. //
  2346. // Return early if we are in a thread stuck condition
  2347. //
  2348. if (pldev->bThreadStuck) {
  2349. return TRUE;
  2350. }
  2351. RECOVERY_SECTION_BEGIN(pldev) {
  2352. bRet = pfn(psoDest, psoSrc, pco, pxlo, prclDest, prclSrc, pBlendObj);
  2353. } RECOVERY_SECTION_END(pldev);
  2354. return bRet;
  2355. }
  2356. BOOL APIENTRY
  2357. WatchdogDrvGradientFill(
  2358. SURFOBJ *psoDest,
  2359. CLIPOBJ *pco,
  2360. XLATEOBJ *pxlo,
  2361. TRIVERTEX *pVertex,
  2362. ULONG nVertex,
  2363. PVOID pMesh,
  2364. ULONG nMesh,
  2365. RECTL *prclExtents,
  2366. POINTL *pptlDitherOrg,
  2367. ULONG ulMode
  2368. )
  2369. {
  2370. PLDEV pldev = dhpdevRetrieveLdev(psoDest->dhpdev);
  2371. PFN_DrvGradientFill pfn = (PFN_DrvGradientFill) pldev->apfnDriver[INDEX_DrvGradientFill];
  2372. BOOL bRet = TRUE;
  2373. //
  2374. // Return early if we are in a thread stuck condition
  2375. //
  2376. if (pldev->bThreadStuck) {
  2377. return TRUE;
  2378. }
  2379. RECOVERY_SECTION_BEGIN(pldev) {
  2380. bRet = pfn(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents, pptlDitherOrg, ulMode);
  2381. } RECOVERY_SECTION_END(pldev);
  2382. return bRet;
  2383. }
  2384. BOOL APIENTRY
  2385. WatchdogDrvTransparentBlt(
  2386. SURFOBJ *psoDst,
  2387. SURFOBJ *psoSrc,
  2388. CLIPOBJ *pco,
  2389. XLATEOBJ *pxlo,
  2390. RECTL *prclDst,
  2391. RECTL *prclSrc,
  2392. ULONG iTransColor,
  2393. ULONG ulReserved
  2394. )
  2395. {
  2396. SURFOBJ *psoDevice = (psoDst->dhpdev) ? psoDst : psoSrc;
  2397. PLDEV pldev = dhpdevRetrieveLdev(psoDevice->dhpdev);
  2398. PFN_DrvTransparentBlt pfn = (PFN_DrvTransparentBlt) pldev->apfnDriver[INDEX_DrvTransparentBlt];
  2399. BOOL bRet = TRUE;
  2400. //
  2401. // Return early if we are in a thread stuck condition
  2402. //
  2403. if (pldev->bThreadStuck) {
  2404. return TRUE;
  2405. }
  2406. RECOVERY_SECTION_BEGIN(pldev) {
  2407. bRet = pfn(psoDst, psoSrc, pco, pxlo, prclDst, prclSrc, iTransColor, ulReserved);
  2408. } RECOVERY_SECTION_END(pldev);
  2409. return bRet;
  2410. }
  2411. HBITMAP APIENTRY
  2412. WatchdogDrvDeriveSurface(
  2413. DD_DIRECTDRAW_GLOBAL *pDirectDraw,
  2414. DD_SURFACE_LOCAL *pSurface
  2415. )
  2416. {
  2417. PLDEV pldev = dhpdevRetrieveLdev((DHPDEV)pDirectDraw->dhpdev);
  2418. PFN_DrvDeriveSurface pfn = (PFN_DrvDeriveSurface) pldev->apfnDriver[INDEX_DrvDeriveSurface];
  2419. HBITMAP hBitmap = NULL;
  2420. //
  2421. // Return early if we are in a thread stuck condition
  2422. //
  2423. if (pldev->bThreadStuck == FALSE) {
  2424. RECOVERY_SECTION_BEGIN(pldev) {
  2425. hBitmap = pfn(pDirectDraw, pSurface);
  2426. } RECOVERY_SECTION_END(pldev);
  2427. }
  2428. return hBitmap;
  2429. }
  2430. VOID APIENTRY
  2431. WatchdogDrvNotify(
  2432. IN SURFOBJ *pso,
  2433. IN ULONG iType,
  2434. IN PVOID pvData
  2435. )
  2436. {
  2437. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  2438. PFN_DrvNotify pfn = (PFN_DrvNotify) pldev->apfnDriver[INDEX_DrvNotify];
  2439. //
  2440. // Return early if we are in a thread stuck condition
  2441. //
  2442. if (pldev->bThreadStuck) {
  2443. return;
  2444. }
  2445. RECOVERY_SECTION_BEGIN(pldev) {
  2446. pfn(pso, iType, pvData);
  2447. } RECOVERY_SECTION_END(pldev);
  2448. }
  2449. VOID APIENTRY
  2450. WatchdogDrvSynchronizeSurface(
  2451. IN SURFOBJ *pso,
  2452. IN RECTL *prcl,
  2453. IN FLONG fl
  2454. )
  2455. {
  2456. PLDEV pldev = dhpdevRetrieveLdev(pso->dhpdev);
  2457. PFN_DrvSynchronizeSurface pfn = (PFN_DrvSynchronizeSurface) pldev->apfnDriver[INDEX_DrvSynchronizeSurface];
  2458. //
  2459. // Return early if we are in a thread stuck condition
  2460. //
  2461. if (pldev->bThreadStuck) {
  2462. return;
  2463. }
  2464. RECOVERY_SECTION_BEGIN(pldev) {
  2465. pfn(pso, prcl, fl);
  2466. } RECOVERY_SECTION_END(pldev);
  2467. }
  2468. VOID APIENTRY
  2469. WatchdogDrvResetDevice(
  2470. DHPDEV dhpdev,
  2471. PVOID Reserved
  2472. )
  2473. {
  2474. PLDEV pldev = dhpdevRetrieveLdev(dhpdev);
  2475. PFN_DrvResetDevice pfn = (PFN_DrvResetDevice) pldev->apfnDriver[INDEX_DrvResetDevice];
  2476. //
  2477. // Return early if we are in a thread stuck condition
  2478. //
  2479. if (pldev->bThreadStuck) {
  2480. return;
  2481. }
  2482. RECOVERY_SECTION_BEGIN(pldev) {
  2483. pfn(dhpdev, Reserved);
  2484. } RECOVERY_SECTION_END(pldev);
  2485. }
  2486. //
  2487. // The following table contains the replacement functions which
  2488. // hooks the real driver entry points, and set up the try/except
  2489. // handlers.
  2490. //
  2491. PFN WatchdogTable[INDEX_LAST] =
  2492. {
  2493. (PFN)WatchdogDrvEnablePDEV,
  2494. (PFN)WatchdogDrvCompletePDEV,
  2495. (PFN)WatchdogDrvDisablePDEV,
  2496. (PFN)WatchdogDrvEnableSurface,
  2497. (PFN)WatchdogDrvDisableSurface,
  2498. (PFN)WatchdogDrvAssertMode,
  2499. 0, // DrvOffset - obsolete
  2500. (PFN)WatchdogDrvResetPDEV,
  2501. 0, // DrvDisableDriver - don't hook
  2502. 0, // not assigned
  2503. (PFN)WatchdogDrvCreateDeviceBitmap,
  2504. (PFN)WatchdogDrvDeleteDeviceBitmap,
  2505. (PFN)WatchdogDrvRealizeBrush,
  2506. (PFN)WatchdogDrvDitherColor,
  2507. (PFN)WatchdogDrvStrokePath,
  2508. (PFN)WatchdogDrvFillPath,
  2509. (PFN)WatchdogDrvStrokeAndFillPath,
  2510. 0, // DrvPaint - obsolete
  2511. (PFN)WatchdogDrvBitBlt,
  2512. (PFN)WatchdogDrvCopyBits,
  2513. (PFN)WatchdogDrvStretchBlt,
  2514. 0, // not assigned
  2515. (PFN)WatchdogDrvSetPalette,
  2516. (PFN)WatchdogDrvTextOut,
  2517. (PFN)WatchdogDrvEscape,
  2518. (PFN)WatchdogDrvDrawEscape,
  2519. 0, // DrvQueryFont
  2520. 0, // DrvQueryFontTree
  2521. 0, // DrvQueryFontData
  2522. (PFN)WatchdogDrvSetPointerShape,
  2523. (PFN)WatchdogDrvMovePointer,
  2524. (PFN)WatchdogDrvLineTo,
  2525. 0, // DrvSendPage
  2526. 0, // DrvStartPage
  2527. 0, // DrvEndDoc
  2528. 0, // DrvStartDoc
  2529. 0, // not assigned
  2530. 0, // DrvGetGlyphMode
  2531. (PFN)WatchdogDrvSynchronize,
  2532. 0, // not assigned
  2533. (PFN)WatchdogDrvSaveScreenBits,
  2534. 0, // DrvGetModes - don't hook
  2535. 0, // DrvFree
  2536. 0, // DrvDestroyFont
  2537. 0, // DrvQueryFontCaps
  2538. 0, // DrvLoadFontFile
  2539. 0, // DrvUnloadFontFile
  2540. 0, // DrvFontManagement
  2541. 0, // DrvQueryTrueTypeTable
  2542. 0, // DrvQueryTrueTypeOutline
  2543. 0, // DrvGetTrueTypeFile
  2544. 0, // DrvQueryFontFile
  2545. 0, // DrvMovePanning
  2546. 0, // DrvQueryAdvanceWidths
  2547. (PFN)WatchdogDrvSetPixelFormat,
  2548. (PFN)WatchdogDrvDescribePixelFormat,
  2549. (PFN)WatchdogDrvSwapBuffers,
  2550. 0, // DrvStartBanding
  2551. 0, // DrvNextBand
  2552. (PFN)WatchdogDrvGetDirectDrawInfo,
  2553. (PFN)WatchdogDrvEnableDirectDraw,
  2554. (PFN)WatchdogDrvDisableDirectDraw,
  2555. 0, // DrvQuerySpoolType
  2556. 0, // not assigned
  2557. 0, // DrvIcmCreateColorTransform
  2558. 0, // DrvIcmDeleteColorTransform
  2559. 0, // DrvIcmCheckBitmapBits
  2560. (PFN)WatchdogDrvIcmSetDeviceGammaRamp,
  2561. (PFN)WatchdogDrvGradientFill,
  2562. (PFN)WatchdogDrvStretchBltROP,
  2563. (PFN)WatchdogDrvPlgBlt,
  2564. (PFN)WatchdogDrvAlphaBlend,
  2565. 0, // DrvSynthesizeFont
  2566. 0, // DrvGetSynthesizedFontFiles
  2567. (PFN)WatchdogDrvTransparentBlt,
  2568. 0, // DrvQueryPerBandInfo
  2569. 0, // DrvQueryDeviceSupport
  2570. 0, // reserved
  2571. 0, // reserved
  2572. 0, // reserved
  2573. 0, // reserved
  2574. 0, // reserved
  2575. 0, // reserved
  2576. 0, // reserved
  2577. 0, // reserved
  2578. (PFN)WatchdogDrvDeriveSurface,
  2579. 0, // DrvQueryGlyphAttrs
  2580. (PFN)WatchdogDrvNotify,
  2581. (PFN)WatchdogDrvSynchronizeSurface,
  2582. (PFN)WatchdogDrvResetDevice,
  2583. 0, // reserved
  2584. 0, // reserved
  2585. 0 // reserved
  2586. };
  2587. BOOL
  2588. WatchdogIsFunctionHooked(
  2589. IN PLDEV pldev,
  2590. IN ULONG functionIndex
  2591. )
  2592. /*++
  2593. Routine Description:
  2594. This function checks to see whether the Create/DeleteDeviceBitmap
  2595. driver entry points are hooked.
  2596. Return Value:
  2597. TRUE if the entry point is hooked,
  2598. FALSE otherwise
  2599. --*/
  2600. {
  2601. ASSERTGDI(functionIndex < INDEX_LAST, "functionIndex out of range");
  2602. return pldev->apfn[functionIndex] == WatchdogTable[functionIndex];
  2603. }