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.

313 lines
13 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: dxg.cxx
  3. *
  4. * Contains the kernel-mode code for DirectX graphics.
  5. *
  6. * Created: 20-Apr-2000
  7. * Author: Hideyuki Nagase [hideyukn]
  8. *
  9. * Copyright (c) 2000 Microsoft Corporation
  10. *
  11. \**************************************************************************/
  12. #include <precomp.hxx>
  13. extern "C" {
  14. NTSTATUS
  15. DriverEntry(
  16. PDRIVER_OBJECT DriverObject,
  17. PUNICODE_STRING RegistryPath
  18. );
  19. }
  20. #if defined(ALLOC_PRAGMA)
  21. #pragma alloc_text(INIT,DriverEntry)
  22. #endif
  23. #if defined(_X86_)
  24. ULONG_PTR DxgUserProbeAddress;
  25. #endif
  26. DRVFN gaDxgFuncs[] =
  27. {
  28. { INDEX_DxDxgGenericThunk, (PFN) DxDxgGenericThunk },
  29. { INDEX_DxD3dContextCreate, (PFN) DxD3dContextCreate },
  30. { INDEX_DxD3dContextDestroy, (PFN) DxD3dContextDestroy },
  31. { INDEX_DxD3dContextDestroyAll, (PFN) DxD3dContextDestroyAll },
  32. { INDEX_DxD3dValidateTextureStageState, (PFN) DxD3dValidateTextureStageState },
  33. { INDEX_DxD3dDrawPrimitives2, (PFN) DxD3dDrawPrimitives2 },
  34. { INDEX_DxDdGetDriverState, (PFN) DxDdGetDriverState },
  35. { INDEX_DxDdAddAttachedSurface, (PFN) DxDdAddAttachedSurface },
  36. { INDEX_DxDdAlphaBlt, (PFN) DxDdAlphaBlt },
  37. { INDEX_DxDdAttachSurface, (PFN) DxDdAttachSurface },
  38. { INDEX_DxDdBeginMoCompFrame, (PFN) DxDdBeginMoCompFrame },
  39. { INDEX_DxDdBlt, (PFN) DxDdBlt },
  40. { INDEX_DxDdCanCreateSurface, (PFN) DxDdCanCreateSurface },
  41. { INDEX_DxDdCanCreateD3DBuffer, (PFN) DxDdCanCreateD3DBuffer },
  42. { INDEX_DxDdColorControl, (PFN) DxDdColorControl },
  43. { INDEX_DxDdCreateDirectDrawObject, (PFN) DxDdCreateDirectDrawObject },
  44. { INDEX_DxDdCreateSurface, (PFN) DxDdCreateSurface },
  45. { INDEX_DxDdCreateD3DBuffer, (PFN) DxDdCreateD3DBuffer },
  46. { INDEX_DxDdCreateMoComp, (PFN) DxDdCreateMoComp },
  47. { INDEX_DxDdCreateSurfaceObject, (PFN) DxDdCreateSurfaceObject },
  48. { INDEX_DxDdDeleteDirectDrawObject, (PFN) DxDdDeleteDirectDrawObject },
  49. { INDEX_DxDdDeleteSurfaceObject, (PFN) DxDdDeleteSurfaceObject },
  50. { INDEX_DxDdDestroyMoComp, (PFN) DxDdDestroyMoComp },
  51. { INDEX_DxDdDestroySurface, (PFN) DxDdDestroySurface },
  52. { INDEX_DxDdDestroyD3DBuffer, (PFN) DxDdDestroyD3DBuffer },
  53. { INDEX_DxDdEndMoCompFrame, (PFN) DxDdEndMoCompFrame },
  54. { INDEX_DxDdFlip, (PFN) DxDdFlip },
  55. { INDEX_DxDdFlipToGDISurface, (PFN) DxDdFlipToGDISurface },
  56. { INDEX_DxDdGetAvailDriverMemory, (PFN) DxDdGetAvailDriverMemory },
  57. { INDEX_DxDdGetBltStatus, (PFN) DxDdGetBltStatus },
  58. { INDEX_DxDdGetDC, (PFN) DxDdGetDC },
  59. { INDEX_DxDdGetDriverInfo, (PFN) DxDdGetDriverInfo },
  60. { INDEX_DxDdGetDxHandle, (PFN) DxDdGetDxHandle },
  61. { INDEX_DxDdGetFlipStatus, (PFN) DxDdGetFlipStatus },
  62. { INDEX_DxDdGetInternalMoCompInfo, (PFN) DxDdGetInternalMoCompInfo },
  63. { INDEX_DxDdGetMoCompBuffInfo, (PFN) DxDdGetMoCompBuffInfo },
  64. { INDEX_DxDdGetMoCompGuids, (PFN) DxDdGetMoCompGuids },
  65. { INDEX_DxDdGetMoCompFormats, (PFN) DxDdGetMoCompFormats },
  66. { INDEX_DxDdGetScanLine, (PFN) DxDdGetScanLine },
  67. { INDEX_DxDdLock, (PFN) DxDdLock },
  68. { INDEX_DxDdLockD3D, (PFN) DxDdLockD3D },
  69. { INDEX_DxDdQueryDirectDrawObject, (PFN) DxDdQueryDirectDrawObject },
  70. { INDEX_DxDdQueryMoCompStatus, (PFN) DxDdQueryMoCompStatus },
  71. { INDEX_DxDdReenableDirectDrawObject, (PFN) DxDdReenableDirectDrawObject },
  72. { INDEX_DxDdReleaseDC, (PFN) DxDdReleaseDC },
  73. { INDEX_DxDdRenderMoComp, (PFN) DxDdRenderMoComp },
  74. { INDEX_DxDdResetVisrgn, (PFN) DxDdResetVisrgn },
  75. { INDEX_DxDdSetColorKey, (PFN) DxDdSetColorKey },
  76. { INDEX_DxDdSetExclusiveMode, (PFN) DxDdSetExclusiveMode },
  77. { INDEX_DxDdSetGammaRamp, (PFN) DxDdSetGammaRamp },
  78. { INDEX_DxDdCreateSurfaceEx, (PFN) DxDdCreateSurfaceEx },
  79. { INDEX_DxDdSetOverlayPosition, (PFN) DxDdSetOverlayPosition },
  80. { INDEX_DxDdUnattachSurface, (PFN) DxDdUnattachSurface },
  81. { INDEX_DxDdUnlock, (PFN) DxDdUnlock },
  82. { INDEX_DxDdUnlockD3D, (PFN) DxDdUnlockD3D },
  83. { INDEX_DxDdUpdateOverlay, (PFN) DxDdUpdateOverlay },
  84. { INDEX_DxDdWaitForVerticalBlank, (PFN) DxDdWaitForVerticalBlank },
  85. { INDEX_DxDvpCanCreateVideoPort, (PFN) DxDvpCanCreateVideoPort },
  86. { INDEX_DxDvpColorControl, (PFN) DxDvpColorControl },
  87. { INDEX_DxDvpCreateVideoPort, (PFN) DxDvpCreateVideoPort },
  88. { INDEX_DxDvpDestroyVideoPort, (PFN) DxDvpDestroyVideoPort },
  89. { INDEX_DxDvpFlipVideoPort, (PFN) DxDvpFlipVideoPort },
  90. { INDEX_DxDvpGetVideoPortBandwidth, (PFN) DxDvpGetVideoPortBandwidth },
  91. { INDEX_DxDvpGetVideoPortField, (PFN) DxDvpGetVideoPortField },
  92. { INDEX_DxDvpGetVideoPortFlipStatus, (PFN) DxDvpGetVideoPortFlipStatus },
  93. { INDEX_DxDvpGetVideoPortInputFormats, (PFN) DxDvpGetVideoPortInputFormats },
  94. { INDEX_DxDvpGetVideoPortLine, (PFN) DxDvpGetVideoPortLine },
  95. { INDEX_DxDvpGetVideoPortOutputFormats, (PFN) DxDvpGetVideoPortOutputFormats },
  96. { INDEX_DxDvpGetVideoPortConnectInfo, (PFN) DxDvpGetVideoPortConnectInfo },
  97. { INDEX_DxDvpGetVideoSignalStatus, (PFN) DxDvpGetVideoSignalStatus },
  98. { INDEX_DxDvpUpdateVideoPort, (PFN) DxDvpUpdateVideoPort },
  99. { INDEX_DxDvpWaitForVideoPortSync, (PFN) DxDvpWaitForVideoPortSync },
  100. { INDEX_DxDvpAcquireNotification, (PFN) DxDvpAcquireNotification },
  101. { INDEX_DxDvpReleaseNotification, (PFN) DxDvpReleaseNotification },
  102. { INDEX_DxDdHeapVidMemAllocAligned, (PFN) DxDdHeapVidMemAllocAligned },
  103. { INDEX_DxDdHeapVidMemFree, (PFN) DxDdHeapVidMemFree },
  104. { INDEX_DxDdEnableDirectDraw, (PFN) DxDdEnableDirectDraw },
  105. { INDEX_DxDdDisableDirectDraw, (PFN) DxDdDisableDirectDraw },
  106. { INDEX_DxDdSuspendDirectDraw, (PFN) DxDdSuspendDirectDraw },
  107. { INDEX_DxDdResumeDirectDraw, (PFN) DxDdResumeDirectDraw },
  108. { INDEX_DxDdDynamicModeChange, (PFN) DxDdDynamicModeChange },
  109. { INDEX_DxDdCloseProcess, (PFN) DxDdCloseProcess },
  110. { INDEX_DxDdGetDirectDrawBounds, (PFN) DxDdGetDirectDrawBounds },
  111. { INDEX_DxDdEnableDirectDrawRedirection, (PFN) DxDdEnableDirectDrawRedirection },
  112. { INDEX_DxDdAllocPrivateUserMem, (PFN) DxDdAllocPrivateUserMem },
  113. { INDEX_DxDdFreePrivateUserMem, (PFN) DxDdFreePrivateUserMem },
  114. { INDEX_DxDdLockDirectDrawSurface, (PFN) DxDdLockDirectDrawSurface },
  115. { INDEX_DxDdUnlockDirectDrawSurface, (PFN) DxDdUnlockDirectDrawSurface },
  116. { INDEX_DxDdSetAccelLevel, (PFN) DxDdSetAccelLevel },
  117. { INDEX_DxDdGetSurfaceLock, (PFN) DxDdGetSurfaceLock },
  118. { INDEX_DxDdEnumLockedSurfaceRect, (PFN) DxDdEnumLockedSurfaceRect },
  119. { INDEX_DxDdIoctl, (PFN) DxDdIoctl }
  120. };
  121. ULONG gcDxgFuncs = sizeof(gaDxgFuncs) / sizeof(DRVFN);
  122. //
  123. // Pointer to the pointer table to Win32k.sys
  124. //
  125. DRVFN *gpEngFuncs = NULL;
  126. //
  127. // This is the global pointer to the dummy page to which all of the video
  128. // memory is mapped when we need to forcibly unmap it. Instead of causing
  129. // the app to fault accessing unmapped memory, we remap it to this play
  130. // area where it can doodle around till it discovers that it had "lost"
  131. // surfaces.
  132. //
  133. PVOID gpDummyPage;
  134. LONG gcDummyPageRefCnt;
  135. HSEMAPHORE ghsemDummyPage;
  136. PEPROCESS gpepSession = NULL;
  137. /***************************************************************************\
  138. * NTSTATUS DriverEntry
  139. *
  140. * This routine is never actually called, but we need it to link.
  141. *
  142. \***************************************************************************/
  143. extern "C"
  144. NTSTATUS
  145. DriverEntry(
  146. PDRIVER_OBJECT DriverObject,
  147. PUNICODE_STRING RegistryPath
  148. )
  149. {
  150. return(STATUS_SUCCESS);
  151. }
  152. /***************************************************************************\
  153. * NTSTATUS StartupDxGraphics
  154. *
  155. * This routine is called by win32k.sys to initialize dxg.sys.
  156. *
  157. \***************************************************************************/
  158. extern "C"
  159. NTSTATUS
  160. DxDdStartupDxGraphics(
  161. ULONG cjEng,
  162. DRVENABLEDATA *pdedEng,
  163. ULONG cjDxg,
  164. DRVENABLEDATA *pdedDxg,
  165. DWORD *pdwDirectDrawContext,
  166. PEPROCESS pepSession
  167. )
  168. {
  169. if ((cjEng >= sizeof(DRVENABLEDATA)) &&
  170. (cjDxg >= sizeof(DRVENABLEDATA)))
  171. {
  172. //
  173. // Initialize global variables
  174. //
  175. gpDummyPage = NULL;
  176. gcDummyPageRefCnt = 0;
  177. ghsemDummyPage = NULL;
  178. //
  179. // Give back function pointers to GDI, which they will call.
  180. //
  181. pdedDxg->iDriverVersion = 0x00080000; // Supporting until DX8.
  182. pdedDxg->c = gcDxgFuncs;
  183. pdedDxg->pdrvfn = gaDxgFuncs;
  184. //
  185. // pdedEng->iDriverVersion contains win32k version (= OS platform version).
  186. //
  187. // - 0x00050001 for Whistler.
  188. //
  189. //
  190. // Check the function printers from GDI, which we will call.
  191. //
  192. if (pdedEng->c != INDEX_WIN32K_TABLE_SIZE)
  193. {
  194. WARNING("pdedEng->c != INDEX_WIN32K_TABLE_MAX\n");
  195. return STATUS_INTERNAL_ERROR;
  196. }
  197. //
  198. // Make sure all pointers are sorted and nothing missing.
  199. //
  200. for (ULONG i = 1; i < INDEX_WIN32K_TABLE_SIZE; i++)
  201. {
  202. if ((pdedEng->pdrvfn[i].iFunc != i) ||
  203. (pdedEng->pdrvfn[i].pfn == NULL))
  204. {
  205. WARNING("pdedEng->pdrvfn is not well orded or pointer is missing\n");
  206. return STATUS_INTERNAL_ERROR;
  207. }
  208. }
  209. //
  210. // If everything is good, keep the pointer.
  211. //
  212. gpEngFuncs = pdedEng->pdrvfn;
  213. //
  214. // Return size of DirectDraw context, so that GDI can allocate it inside HDEV.
  215. //
  216. *pdwDirectDrawContext = sizeof(EDD_DIRECTDRAW_GLOBAL);
  217. //
  218. // Initialize handle manager
  219. //
  220. if (!DdHmgCreate())
  221. {
  222. goto Error_Exit;
  223. }
  224. //
  225. // Create semaphore to sync dummy page global variable.
  226. //
  227. if ((ghsemDummyPage = EngCreateSemaphore()) == NULL)
  228. {
  229. goto Error_Exit;
  230. }
  231. #if defined(_X86_)
  232. //
  233. // Keep our own copy of this to avoid double indirections on probing
  234. //
  235. DxgUserProbeAddress = *MmUserProbeAddress;
  236. #endif
  237. //
  238. // Keep pointer to CsrSS process for this session.
  239. //
  240. gpepSession = pepSession;
  241. return(STATUS_SUCCESS);
  242. }
  243. return(STATUS_BUFFER_TOO_SMALL);
  244. Error_Exit:
  245. DdHmgDestroy();
  246. if (ghsemDummyPage)
  247. {
  248. EngDeleteSemaphore(ghsemDummyPage);
  249. ghsemDummyPage = NULL;
  250. }
  251. return(STATUS_NO_MEMORY);
  252. }
  253. /***************************************************************************\
  254. * NTSTATUS CleanupDxGraphics
  255. *
  256. * This routine is called by win32k.sys to uninitialize dxg.sys
  257. * just before unload.
  258. *
  259. \***************************************************************************/
  260. extern "C"
  261. NTSTATUS
  262. DxDdCleanupDxGraphics(VOID)
  263. {
  264. DdHmgDestroy();
  265. if (ghsemDummyPage)
  266. {
  267. if (gpDummyPage)
  268. {
  269. ExFreePool(gpDummyPage);
  270. gpDummyPage = NULL;
  271. gcDummyPageRefCnt = 0;
  272. }
  273. EngDeleteSemaphore(ghsemDummyPage);
  274. ghsemDummyPage = NULL;
  275. }
  276. return (STATUS_SUCCESS);
  277. }