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.

662 lines
20 KiB

  1. //==========================================================================;
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright (c) 1992 - 1996 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //==========================================================================;
  11. #include "strmini.h"
  12. #include "ksmedia.h"
  13. #include "ddkmapi.h"
  14. #include "capmain.h"
  15. #include "capdebug.h"
  16. #define _NO_COM
  17. #include "ddkernel.h"
  18. #define DD_OK 0
  19. // The following should be defined in ddkmapi.h, but for some reason are not!
  20. #ifndef booboo // DDKERNELCAPS_SKIPFIELDS
  21. /*
  22. * Indicates that the device supports field skipping.
  23. */
  24. #define DDKERNELCAPS_SKIPFIELDS 0x00000001l
  25. /*
  26. * Indicates that the device can support software autoflipping.
  27. */
  28. #define DDKERNELCAPS_AUTOFLIP 0x00000002l
  29. /*
  30. * Indicates that the device can switch between bob and weave.
  31. */
  32. #define DDKERNELCAPS_SETSTATE 0x00000004l
  33. /*
  34. * Indicates that a client can gain direct access to the frame buffer.
  35. */
  36. #define DDKERNELCAPS_LOCK 0x00000008l
  37. /*
  38. * Indicates that a client can manually flip the video port.
  39. */
  40. #define DDKERNELCAPS_FLIPVIDEOPORT 0x00000010l
  41. /*
  42. * Indicates that a client can manually flip the overlay.
  43. */
  44. #define DDKERNELCAPS_FLIPOVERLAY 0x00000020l
  45. /*
  46. * Indicates that the device supports a fast, asynchronous transfer
  47. * mechanism to system memory.
  48. */
  49. #define DDKERNELCAPS_TRANSFER_SYSMEM 0x00000040l
  50. /*
  51. * Indicates that the device supports a fast, asynchronous transfer
  52. * mechanism via AGP.
  53. */
  54. #define DDKERNELCAPS_TRANSFER_AGP 0x00000080l
  55. /*
  56. * Indicates that the device can report the polarity (even/odd) of
  57. * the curent video field.
  58. */
  59. #define DDKERNELCAPS_FIELDPOLARITY 0x00000100l
  60. /****************************************************************************
  61. *
  62. * DDKERNELCAPS IRQ CAPS
  63. *
  64. ****************************************************************************/
  65. /*
  66. * The device can generate display VSYNC IRQs
  67. */
  68. #define DDIRQ_DISPLAY_VSYNC 0x00000001l
  69. /*
  70. * Reserved
  71. */
  72. #define DDIRQ_RESERVED1 0x00000002l
  73. /*
  74. * The device can generate video ports VSYNC IRQs using video port 0
  75. */
  76. #define DDIRQ_VPORT0_VSYNC 0x00000004l
  77. /*
  78. * The device can generate video ports line IRQs using video port 0
  79. */
  80. #define DDIRQ_VPORT0_LINE 0x00000008l
  81. /*
  82. * The device can generate video ports VSYNC IRQs using video port 1
  83. */
  84. #define DDIRQ_VPORT1_VSYNC 0x00000010l
  85. /*
  86. * The device can generate video ports line IRQs using video port 1
  87. */
  88. #define DDIRQ_VPORT1_LINE 0x00000020l
  89. /*
  90. * The device can generate video ports VSYNC IRQs using video port 2
  91. */
  92. #define DDIRQ_VPORT2_VSYNC 0x00000040l
  93. /*
  94. * The device can generate video ports line IRQs using video port 2
  95. */
  96. #define DDIRQ_VPORT2_LINE 0x00000080l
  97. /*
  98. * The device can generate video ports VSYNC IRQs using video port 3
  99. */
  100. #define DDIRQ_VPORT3_VSYNC 0x00000100l
  101. /*
  102. * The device can generate video ports line IRQs using video port 3
  103. */
  104. #define DDIRQ_VPORT3_LINE 0x00000200l
  105. /*
  106. * The device can generate video ports VSYNC IRQs using video port 4
  107. */
  108. #define DDIRQ_VPORT4_VSYNC 0x00000400l
  109. /*
  110. * The device can generate video ports line IRQs using video port 4
  111. */
  112. #define DDIRQ_VPORT4_LINE 0x00000800l
  113. /*
  114. * The device can generate video ports VSYNC IRQs using video port 5
  115. */
  116. #define DDIRQ_VPORT5_VSYNC 0x00001000l
  117. /*
  118. * The device can generate video ports line IRQs using video port 5
  119. */
  120. #define DDIRQ_VPORT5_LINE 0x00002000l
  121. /*
  122. * The device can generate video ports VSYNC IRQs using video port 6
  123. */
  124. #define DDIRQ_VPORT6_VSYNC 0x00004000l
  125. /*
  126. * The device can generate video ports line IRQs using video port 6
  127. */
  128. #define DDIRQ_VPORT6_LINE 0x00008000l
  129. /*
  130. * The device can generate video ports VSYNC IRQs using video port 7
  131. */
  132. #define DDIRQ_VPORT7_VSYNC 0x00010000l
  133. /*
  134. * The device can generate video ports line IRQs using video port 7
  135. */
  136. #define DDIRQ_VPORT7_LINE 0x00020000l
  137. /*
  138. * The device can generate video ports VSYNC IRQs using video port 8
  139. */
  140. #define DDIRQ_VPORT8_VSYNC 0x00040000l
  141. /*
  142. * The device can generate video ports line IRQs using video port 8
  143. */
  144. #define DDIRQ_VPORT8_LINE 0x00080000l
  145. /*
  146. * The device can generate video ports VSYNC IRQs using video port 9
  147. */
  148. #define DDIRQ_VPORT9_VSYNC 0x00010000l
  149. /*
  150. * The device can generate video ports line IRQs using video port 9
  151. */
  152. #define DDIRQ_VPORT9_LINE 0x00020000l
  153. #endif
  154. DWORD FAR PASCAL
  155. DirectDrawEventCallback (
  156. DWORD dwEvent, PVOID pContext, DWORD dwParam1, DWORD dwParam2
  157. )
  158. {
  159. switch (dwEvent)
  160. {
  161. case DDNOTIFY_PRERESCHANGE:
  162. {
  163. PSTREAMEX pStrmEx = (PSTREAMEX)pContext;
  164. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  165. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  166. DbgLogInfo(("Testcap: DDNOTIFY_PRERESCHANGE; stream = %d\n", StreamNumber));
  167. pStrmEx->PreEventOccurred = TRUE;
  168. }
  169. break;
  170. case DDNOTIFY_POSTRESCHANGE:
  171. {
  172. PSTREAMEX pStrmEx = (PSTREAMEX)pContext;
  173. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  174. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  175. DbgLogInfo(("Testcap: DDNOTIFY_POSTRESCHANGE; stream = %d\n", StreamNumber));
  176. pStrmEx->PostEventOccurred = TRUE;
  177. DbgLogInfo(("Testcap: Before Attempted Renegotiation due to DDNOTIFY_POSTRESCHANGE\n"));
  178. // AttemptRenegotiation(pStrmEx);
  179. DbgLogInfo(("Testcap: Afer Attempted Renegotiation due to DDNOTIFY_POSTRESCHANGE\n"));
  180. }
  181. break;
  182. case DDNOTIFY_PREDOSBOX:
  183. {
  184. PSTREAMEX pStrmEx = (PSTREAMEX)pContext;
  185. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  186. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  187. DbgLogInfo(("Testcap: DDNOTIFY_PREDOSBOX; stream = %d\n", StreamNumber));
  188. pStrmEx->PreEventOccurred = TRUE;
  189. }
  190. break;
  191. case DDNOTIFY_POSTDOSBOX:
  192. {
  193. PSTREAMEX pStrmEx = (PSTREAMEX)pContext;
  194. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  195. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  196. DbgLogInfo(("Testcap: DDNOTIFY_POSTDOSBOX; stream = %d\n", StreamNumber));
  197. pStrmEx->PostEventOccurred = TRUE;
  198. DbgLogInfo(("Testcap: Before Attempted Renegotiation due to DDNOTIFY_POSTDOSBOX\n"));
  199. // AttemptRenegotiation(pStrmEx);
  200. DbgLogInfo(("Testcap: After Attempted Renegotiation due to DDNOTIFY_POSTDOSBOX\n"));
  201. }
  202. break;
  203. case DDNOTIFY_CLOSEDIRECTDRAW:
  204. {
  205. PSTREAMEX pStrmEx = (PSTREAMEX)pContext;
  206. PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pContext;
  207. DbgLogInfo(("Testcap: DDNOTIFY_CLOSEDIRECTDRAW\n"));
  208. pStrmEx->KernelDirectDrawHandle = 0;
  209. pStrmEx->UserDirectDrawHandle = 0;
  210. }
  211. break;
  212. case DDNOTIFY_CLOSESURFACE:
  213. {
  214. PHW_STREAM_REQUEST_BLOCK pSrb = (PHW_STREAM_REQUEST_BLOCK)pContext;
  215. PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;
  216. DbgLogInfo(("Testcap: DDNOTIFY_CLOSESURFACE\n"));
  217. pSrbExt->KernelSurfaceHandle = 0;
  218. }
  219. break;
  220. default:
  221. TRAP;
  222. break;
  223. }
  224. return 0;
  225. }
  226. BOOL
  227. RegisterForDirectDrawEvents (
  228. PSTREAMEX pStrmEx
  229. )
  230. {
  231. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  232. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  233. DDREGISTERCALLBACK ddRegisterCallback;
  234. DWORD ddOut;
  235. DbgLogInfo(("Testcap: Stream %d registering for DirectDraw events\n", StreamNumber));
  236. // =============== DDEVENT_PRERESCHANGE ===============
  237. RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback));
  238. RtlZeroMemory(&ddOut, sizeof(ddOut));
  239. ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle;
  240. ddRegisterCallback.dwEvents = DDEVENT_PRERESCHANGE;
  241. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  242. ddRegisterCallback.pContext = pStrmEx;
  243. DxApi(DD_DXAPI_REGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
  244. if (ddOut != DD_OK) {
  245. DbgLogInfo(("Testcap: DD_DXAPI_REGISTER_CALLBACK failed.\n"));
  246. TRAP;
  247. return FALSE;
  248. }
  249. // =============== DDEVENT_POSTRESCHANGE ==============
  250. RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback));
  251. RtlZeroMemory(&ddOut, sizeof(ddOut));
  252. ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle;
  253. ddRegisterCallback.dwEvents = DDEVENT_POSTRESCHANGE;
  254. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  255. ddRegisterCallback.pContext = pStrmEx;
  256. DxApi(DD_DXAPI_REGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
  257. if (ddOut != DD_OK) {
  258. DbgLogInfo(("Testcap: DD_DXAPI_REGISTER_CALLBACK failed.\n"));
  259. TRAP;
  260. return FALSE;
  261. }
  262. // =============== DDEVENT_PREDOSBOX =================
  263. RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback));
  264. RtlZeroMemory(&ddOut, sizeof(ddOut));
  265. ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle;
  266. ddRegisterCallback.dwEvents = DDEVENT_PREDOSBOX;
  267. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  268. ddRegisterCallback.pContext = pStrmEx;
  269. DxApi(DD_DXAPI_REGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
  270. if (ddOut != DD_OK) {
  271. DbgLogInfo(("Testcap: DD_DXAPI_REGISTER_CALLBACK failed.\n"));
  272. TRAP;
  273. return FALSE;
  274. }
  275. // =============== DDEVENT_POSTDOSBOX ================
  276. RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback));
  277. RtlZeroMemory(&ddOut, sizeof(ddOut));
  278. ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle;
  279. ddRegisterCallback.dwEvents = DDEVENT_POSTDOSBOX;
  280. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  281. ddRegisterCallback.pContext = pStrmEx;
  282. DxApi(DD_DXAPI_REGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
  283. if (ddOut != DD_OK) {
  284. DbgLogInfo(("Testcap: DD_DXAPI_REGISTER_CALLBACK failed.\n"));
  285. TRAP;
  286. return FALSE;
  287. }
  288. pStrmEx->KernelDirectDrawRegistered = TRUE;
  289. return TRUE;
  290. }
  291. BOOL
  292. UnregisterForDirectDrawEvents (
  293. PSTREAMEX pStrmEx
  294. )
  295. {
  296. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  297. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  298. DDREGISTERCALLBACK ddRegisterCallback;
  299. DWORD ddOut;
  300. DbgLogInfo(("Testcap: Stream %d UNregistering for DirectDraw events\n", StreamNumber));
  301. // =============== DDEVENT_PRERESCHANGE ===============
  302. RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback));
  303. RtlZeroMemory(&ddOut, sizeof(ddOut));
  304. ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle;
  305. ddRegisterCallback.dwEvents = DDEVENT_PRERESCHANGE ;
  306. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  307. ddRegisterCallback.pContext = pStrmEx;
  308. DxApi(DD_DXAPI_UNREGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
  309. if (ddOut != DD_OK) {
  310. DbgLogInfo(("Testcap: DD_DXAPI_UNREGISTER_CALLBACK failed.\n"));
  311. TRAP;
  312. return FALSE;
  313. }
  314. // =============== DDEVENT_POSTRESCHANGE ==============
  315. RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback));
  316. RtlZeroMemory(&ddOut, sizeof(ddOut));
  317. ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle;
  318. ddRegisterCallback.dwEvents = DDEVENT_POSTRESCHANGE;
  319. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  320. ddRegisterCallback.pContext = pStrmEx;
  321. DxApi(DD_DXAPI_UNREGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
  322. if (ddOut != DD_OK) {
  323. DbgLogInfo(("Testcap: DD_DXAPI_UNREGISTER_CALLBACK failed.\n"));
  324. TRAP;
  325. return FALSE;
  326. }
  327. // =============== DDEVENT_PREDOSBOX ==================
  328. RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback));
  329. RtlZeroMemory(&ddOut, sizeof(ddOut));
  330. ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle;
  331. ddRegisterCallback.dwEvents = DDEVENT_PREDOSBOX;
  332. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  333. ddRegisterCallback.pContext = pStrmEx;
  334. DxApi(DD_DXAPI_UNREGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
  335. if (ddOut != DD_OK) {
  336. DbgLogInfo(("Testcap: DD_DXAPI_UNREGISTER_CALLBACK failed.\n"));
  337. TRAP;
  338. return FALSE;
  339. }
  340. // =============== DDEVENT_POSTDOSBOX =================
  341. RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback));
  342. RtlZeroMemory(&ddOut, sizeof(ddOut));
  343. ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle;
  344. ddRegisterCallback.dwEvents = DDEVENT_POSTDOSBOX;
  345. ddRegisterCallback.pfnCallback = DirectDrawEventCallback;
  346. ddRegisterCallback.pContext = pStrmEx;
  347. DxApi(DD_DXAPI_UNREGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
  348. if (ddOut != DD_OK) {
  349. DbgLogInfo(("Testcap: DD_DXAPI_UNREGISTER_CALLBACK failed.\n"));
  350. TRAP;
  351. return FALSE;
  352. }
  353. pStrmEx->KernelDirectDrawRegistered = FALSE;
  354. return TRUE;
  355. }
  356. BOOL
  357. OpenKernelDirectDraw (
  358. PSTREAMEX pStrmEx
  359. )
  360. {
  361. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  362. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  363. if (pStrmEx->UserDirectDrawHandle != 0) {
  364. DDOPENDIRECTDRAWIN ddOpenIn;
  365. DDOPENDIRECTDRAWOUT ddOpenOut;
  366. ASSERT (pStrmEx->KernelDirectDrawHandle == 0);
  367. DbgLogInfo(("Testcap: Stream %d getting Kernel ddraw handle\n", StreamNumber));
  368. RtlZeroMemory(&ddOpenIn, sizeof(ddOpenIn));
  369. RtlZeroMemory(&ddOpenOut, sizeof(ddOpenOut));
  370. ddOpenIn.dwDirectDrawHandle = (DWORD_PTR) pStrmEx->UserDirectDrawHandle;
  371. ddOpenIn.pfnDirectDrawClose = DirectDrawEventCallback;
  372. ddOpenIn.pContext = pStrmEx;
  373. DxApi(DD_DXAPI_OPENDIRECTDRAW,
  374. &ddOpenIn,
  375. sizeof(ddOpenIn),
  376. &ddOpenOut,
  377. sizeof(ddOpenOut));
  378. if (ddOpenOut.ddRVal != DD_OK) {
  379. DbgLogInfo(("Testcap: DD_DXAPI_OPENDIRECTDRAW failed.\n"));
  380. }
  381. else {
  382. pStrmEx->KernelDirectDrawHandle = ddOpenOut.hDirectDraw;
  383. return TRUE;
  384. }
  385. }
  386. return FALSE;
  387. }
  388. BOOL
  389. CloseKernelDirectDraw (
  390. PSTREAMEX pStrmEx
  391. )
  392. {
  393. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  394. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  395. if (pStrmEx->KernelDirectDrawHandle != 0) {
  396. DWORD ddOut;
  397. DDCLOSEHANDLE ddClose;
  398. DbgLogInfo(("Testcap: Stream %d CloseKernelDirectDraw\n", StreamNumber));
  399. ddClose.hHandle = pStrmEx->KernelDirectDrawHandle;
  400. DxApi(DD_DXAPI_CLOSEHANDLE,
  401. &ddClose,
  402. sizeof(ddClose),
  403. &ddOut,
  404. sizeof(ddOut));
  405. pStrmEx->KernelDirectDrawHandle = 0;
  406. if (ddOut != DD_OK) {
  407. DbgLogInfo(("Testcap: CloseKernelDirectDraw FAILED.\n"));
  408. TRAP;
  409. return FALSE;
  410. }
  411. }
  412. return TRUE;
  413. }
  414. BOOL
  415. IsKernelLockAndFlipAvailable (
  416. PSTREAMEX pStrmEx
  417. )
  418. {
  419. PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt;
  420. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  421. if (pStrmEx->KernelDirectDrawHandle != 0) {
  422. DDGETKERNELCAPSOUT ddGetKernelCapsOut;
  423. DbgLogInfo(("Testcap: Stream %d getting Kernel Caps\n", StreamNumber));
  424. RtlZeroMemory(&ddGetKernelCapsOut, sizeof(ddGetKernelCapsOut));
  425. DxApi(DD_DXAPI_GETKERNELCAPS,
  426. &pStrmEx->KernelDirectDrawHandle,
  427. sizeof(pStrmEx->KernelDirectDrawHandle),
  428. &ddGetKernelCapsOut,
  429. sizeof(ddGetKernelCapsOut));
  430. if (ddGetKernelCapsOut.ddRVal != DD_OK) {
  431. DbgLogInfo(("Testcap: DDGETKERNELCAPSOUT failed.\n"));
  432. }
  433. else {
  434. DbgLogInfo(("Testcap: Stream %d KernelCaps = %x\n",
  435. StreamNumber, ddGetKernelCapsOut.dwCaps));
  436. if ((ddGetKernelCapsOut.dwCaps & (DDKERNELCAPS_LOCK | DDKERNELCAPS_FLIPOVERLAY)) ==
  437. (DDKERNELCAPS_LOCK | DDKERNELCAPS_FLIPOVERLAY)) {
  438. // TODO: Check where we may need to set up for kernel flipping
  439. }
  440. return TRUE;
  441. }
  442. }
  443. return FALSE;
  444. }
  445. BOOL
  446. OpenKernelDDrawSurfaceHandle(
  447. IN PHW_STREAM_REQUEST_BLOCK pSrb
  448. )
  449. {
  450. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  451. PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
  452. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  453. PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;
  454. ASSERT (pStrmEx->KernelDirectDrawHandle != 0);
  455. ASSERT (pSrbExt->UserSurfaceHandle != 0);
  456. if (pSrbExt->UserSurfaceHandle == 0) {
  457. DDOPENSURFACEIN ddOpenSurfaceIn;
  458. DDOPENSURFACEOUT ddOpenSurfaceOut;
  459. DbgLogInfo(("Testcap: Stream %d getting Kernel surface handle\n", StreamNumber));
  460. RtlZeroMemory(&ddOpenSurfaceIn, sizeof(ddOpenSurfaceIn));
  461. RtlZeroMemory(&ddOpenSurfaceOut, sizeof(ddOpenSurfaceOut));
  462. ddOpenSurfaceIn.hDirectDraw = pStrmEx->UserDirectDrawHandle;
  463. ddOpenSurfaceIn.pfnSurfaceClose = DirectDrawEventCallback;
  464. ddOpenSurfaceIn.pContext = pSrb;
  465. ddOpenSurfaceIn.dwSurfaceHandle = (DWORD_PTR) pSrbExt->UserSurfaceHandle;
  466. DxApi(DD_DXAPI_OPENSURFACE,
  467. &ddOpenSurfaceIn,
  468. sizeof(ddOpenSurfaceIn),
  469. &ddOpenSurfaceOut,
  470. sizeof(ddOpenSurfaceOut));
  471. if (ddOpenSurfaceOut.ddRVal != DD_OK) {
  472. pSrbExt->KernelSurfaceHandle = 0;
  473. DbgLogInfo(("Testcap: DD_DXAPI_OPENSURFACE failed.\n"));
  474. TRAP;
  475. }
  476. else {
  477. pSrbExt->KernelSurfaceHandle = ddOpenSurfaceOut.hSurface;
  478. return TRUE;
  479. }
  480. }
  481. return FALSE;
  482. }
  483. BOOL
  484. CloseKernelDDrawSurfaceHandle (
  485. IN PHW_STREAM_REQUEST_BLOCK pSrb
  486. )
  487. {
  488. PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
  489. PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
  490. int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
  491. PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;
  492. ASSERT (pStrmEx->KernelDirectDrawHandle != 0);
  493. ASSERT (pSrbExt->UserSurfaceHandle != 0);
  494. ASSERT (pSrbExt->KernelSurfaceHandle != 0);
  495. if (pSrbExt->KernelSurfaceHandle != 0) {
  496. DWORD ddOut;
  497. DDCLOSEHANDLE ddClose;
  498. DbgLogInfo(("Testcap: Stream %d ReleaseKernelDDrawSurfaceHandle\n", StreamNumber));
  499. ddClose.hHandle = pSrbExt->KernelSurfaceHandle;
  500. DxApi(DD_DXAPI_CLOSEHANDLE, &ddClose, sizeof(ddClose), &ddOut, sizeof(ddOut));
  501. pSrbExt->KernelSurfaceHandle = 0; // what else can we do?
  502. if (ddOut != DD_OK) {
  503. DbgLogInfo(("Testcap: ReleaseKernelDDrawSurfaceHandle FAILED.\n"));
  504. TRAP;
  505. return FALSE;
  506. }
  507. else {
  508. return TRUE;
  509. }
  510. }
  511. return FALSE;
  512. }