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.

686 lines
20 KiB

  1. /*++ BUILD Version: 0001 // Increment this if a change has global effects
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. usergdi.h
  5. Abstract:
  6. This module contains private USER functions used by GDI.
  7. All of these function are named Userxxx.
  8. Author:
  9. Chris Williams (chriswil) 25-May-1995
  10. Revision History:
  11. --*/
  12. #ifndef _USERGDI_ZWAPI_INC_
  13. #define _USERGDI_ZWAPI_INC_
  14. #include <zwapi.h>
  15. #endif
  16. extern PDRIVER_OBJECT gpWin32kDriverObject;
  17. VOID
  18. VideoPortCallout(
  19. IN PVOID Params
  20. );
  21. BOOL FASTCALL
  22. UserScreenAccessCheck(
  23. VOID
  24. );
  25. HDC
  26. UserGetDesktopDC(
  27. ULONG type,
  28. BOOL bAltType,
  29. BOOL bValidate
  30. );
  31. BOOL
  32. UserReleaseDC(
  33. HDC hdc
  34. );
  35. HDEV
  36. UserGetHDEV(
  37. VOID
  38. );
  39. VOID
  40. UserAssociateHwnd(
  41. HWND hwnd,
  42. PVOID pwo
  43. );
  44. HRGN
  45. UserGetClientRgn(
  46. HWND hwnd,
  47. LPRECT lprc,
  48. BOOL bWindowInsteadOfClient
  49. );
  50. BOOL
  51. UserGetHwnd(
  52. HDC hdc,
  53. HWND *phwnd,
  54. PVOID *ppwo,
  55. BOOL bCheckStyle
  56. );
  57. VOID
  58. UserEnterUserCritSec(
  59. VOID
  60. );
  61. VOID
  62. UserLeaveUserCritSec(
  63. VOID
  64. );
  65. BOOL
  66. UserGetCurrentDesktopId(
  67. DWORD* pdwDesktopId
  68. );
  69. VOID
  70. UserRedrawDesktop(
  71. VOID
  72. );
  73. UINT_PTR
  74. UserSetTimer(
  75. UINT dwElapse,
  76. PVOID pTimerFunc
  77. );
  78. BOOL
  79. UserVisrgnFromHwnd(
  80. HRGN *phrgn,
  81. HWND hwnd
  82. );
  83. VOID
  84. UserKillTimer(
  85. UINT_PTR nID
  86. );
  87. #if DBG
  88. VOID
  89. UserAssertUserCritSecIn(
  90. VOID
  91. );
  92. VOID
  93. UserAssertUserCritSecOut(
  94. VOID
  95. );
  96. #endif
  97. VOID
  98. UserGetDisconnectDeviceResolutionHint(
  99. PDEVMODEW
  100. );
  101. NTSTATUS
  102. UserSessionSwitchEnterCrit(
  103. VOID
  104. );
  105. VOID
  106. UserSessionSwitchLeaveCrit(
  107. VOID
  108. );
  109. BOOL
  110. UserIsUserCritSecIn(
  111. VOID
  112. );
  113. DWORD
  114. GetAppCompatFlags2(
  115. WORD wVersion
  116. );
  117. BOOL
  118. UserGetRedirectedWindowOrigin(
  119. HDC hdc,
  120. LPPOINT ppt
  121. );
  122. HBITMAP
  123. UserGetRedirectionBitmap(
  124. HWND hwnd
  125. );
  126. //
  127. // User-mode printer driver kernel-to-client callback mechanism.
  128. //
  129. DWORD
  130. ClientPrinterThunk(
  131. PVOID pvIn,
  132. ULONG cjIn,
  133. PVOID pvOut,
  134. ULONG cjOut
  135. );
  136. //
  137. // Gdi fonts stuff
  138. //
  139. VOID
  140. GdiMultiUserFontCleanup();
  141. #define BEGIN_REENTERCRIT() \
  142. { \
  143. BOOL fAlreadyHadCrit; \
  144. \
  145. /* \
  146. * If we're not in the user crit then acquire it. \
  147. */ \
  148. fAlreadyHadCrit = ExIsResourceAcquiredExclusiveLite(gpresUser); \
  149. if (fAlreadyHadCrit == FALSE) { \
  150. EnterCrit(); \
  151. }
  152. #define END_REENTERCRIT() \
  153. if (fAlreadyHadCrit == FALSE) { \
  154. LeaveCrit(); \
  155. } \
  156. }
  157. /*
  158. * Pool memory allocation functions used in win32k
  159. */
  160. /*
  161. * From ntos\inc\pool.h
  162. */
  163. #define SESSION_POOL_MASK 32
  164. #if DBG
  165. #define TRACE_MAP_VIEWS
  166. #define MAP_VIEW_STACK_TRACE
  167. #else
  168. #if defined(PRERELEASE) || defined(USER_INSTRUMENTATION)
  169. #define TRACE_MAP_VIEWS
  170. #define MAP_VIEW_STACK_TRACE
  171. #endif
  172. #endif
  173. #define TAG_SECTION_SHARED 101
  174. #define TAG_SECTION_DESKTOP 102
  175. #define TAG_SECTION_GDI 103
  176. #define TAG_SECTION_FONT 104
  177. #define TAG_SECTION_REMOTEFONT 105
  178. #define TAG_SECTION_CREATESECTION 106
  179. #define TAG_SECTION_DIB 107
  180. #define TAG_SECTION_HMGR 108
  181. struct tagWin32MapView;
  182. #define MAP_VIEW_STACK_TRACE_SIZE 6
  183. typedef struct tagWin32Section {
  184. struct tagWin32Section* pNext;
  185. struct tagWin32Section* pPrev;
  186. struct tagWin32MapView* pFirstView;
  187. PVOID SectionObject;
  188. LARGE_INTEGER SectionSize;
  189. DWORD SectionTag;
  190. #ifdef MAP_VIEW_STACK_TRACE
  191. PVOID trace[MAP_VIEW_STACK_TRACE_SIZE];
  192. #endif // MAP_VIEW_STACK_TRACE
  193. } Win32Section, *PWin32Section;
  194. typedef struct tagWin32MapView {
  195. struct tagWin32MapView* pNext;
  196. struct tagWin32MapView* pPrev;
  197. PWin32Section pSection;
  198. PVOID pViewBase;
  199. SIZE_T ViewSize;
  200. #ifdef MAP_VIEW_STACK_TRACE
  201. PVOID trace[MAP_VIEW_STACK_TRACE_SIZE];
  202. #endif // MAP_VIEW_STACK_TRACE
  203. } Win32MapView, *PWin32MapView;
  204. #ifndef TRACE_MAP_VIEWS
  205. NTSTATUS __inline Win32CreateSection(
  206. PVOID *SectionObject,
  207. ACCESS_MASK DesiredAccess,
  208. POBJECT_ATTRIBUTES ObjectAttributes,
  209. PLARGE_INTEGER InputMaximumSize,
  210. ULONG SectionPageProtection,
  211. ULONG AllocationAttributes,
  212. HANDLE FileHandle,
  213. PFILE_OBJECT FileObject,
  214. DWORD SectionTag)
  215. {
  216. NTSTATUS Status;
  217. Status = MmCreateSection(
  218. SectionObject,
  219. DesiredAccess,
  220. ObjectAttributes,
  221. InputMaximumSize,
  222. SectionPageProtection,
  223. AllocationAttributes,
  224. FileHandle,
  225. FileObject);
  226. if (NT_SUCCESS(Status)) {
  227. ObDeleteCapturedInsertInfo (*SectionObject);
  228. }
  229. return Status;
  230. }
  231. NTSTATUS __inline ZwWin32CreateSection(
  232. PVOID *SectionObject,
  233. ACCESS_MASK DesiredAccess,
  234. POBJECT_ATTRIBUTES ObjectAttributes,
  235. PLARGE_INTEGER InputMaximumSize,
  236. ULONG SectionPageProtection,
  237. ULONG AllocationAttributes,
  238. HANDLE FileHandle,
  239. PFILE_OBJECT FileObject,
  240. DWORD SectionTag)
  241. {
  242. HANDLE SectionHandle;
  243. NTSTATUS Status;
  244. Status = ZwCreateSection(
  245. &SectionHandle,
  246. DesiredAccess,
  247. ObjectAttributes,
  248. InputMaximumSize,
  249. SectionPageProtection,
  250. AllocationAttributes,
  251. FileHandle);
  252. if (!NT_SUCCESS(Status))
  253. {
  254. return Status;
  255. }
  256. Status = ObReferenceObjectByHandle(
  257. SectionHandle,
  258. DesiredAccess,
  259. *(POBJECT_TYPE *)MmSectionObjectType,
  260. KernelMode,
  261. SectionObject,
  262. NULL);
  263. ZwClose(SectionHandle);
  264. return Status;
  265. }
  266. NTSTATUS __inline Win32MapViewInSessionSpace(
  267. PVOID Section,
  268. PVOID *MappedBase,
  269. PSIZE_T ViewSize)
  270. {
  271. return MmMapViewInSessionSpace(Section, MappedBase, ViewSize);
  272. }
  273. NTSTATUS __inline Win32UnmapViewInSessionSpace(
  274. PVOID MappedBase)
  275. {
  276. return MmUnmapViewInSessionSpace(MappedBase);
  277. }
  278. VOID __inline Win32DestroySection(PVOID Section)
  279. {
  280. ObDereferenceObject(Section);
  281. }
  282. #else
  283. NTSTATUS _Win32CreateSection(
  284. PVOID* pSectionObject,
  285. ACCESS_MASK DesiredAccess,
  286. POBJECT_ATTRIBUTES ObjectAttributes,
  287. PLARGE_INTEGER pInputMaximumSize,
  288. ULONG SectionPageProtection,
  289. ULONG AllocationAttributes,
  290. HANDLE FileHandle,
  291. PFILE_OBJECT FileObject,
  292. DWORD SectionTag);
  293. NTSTATUS _ZwWin32CreateSection(
  294. PVOID* pSectionObject,
  295. ACCESS_MASK DesiredAccess,
  296. POBJECT_ATTRIBUTES ObjectAttributes,
  297. PLARGE_INTEGER pInputMaximumSize,
  298. ULONG SectionPageProtection,
  299. ULONG AllocationAttributes,
  300. HANDLE FileHandle,
  301. PFILE_OBJECT FileObject,
  302. DWORD SectionTag);
  303. NTSTATUS _Win32MapViewInSessionSpace(
  304. PVOID Section,
  305. PVOID* pMappedBase,
  306. PSIZE_T pViewSize);
  307. NTSTATUS _Win32UnmapViewInSessionSpace(
  308. PVOID MappedBase);
  309. VOID _Win32DestroySection(
  310. PVOID Section);
  311. #define Win32CreateSection _Win32CreateSection
  312. #define ZwWin32CreateSection _ZwWin32CreateSection
  313. #define Win32MapViewInSessionSpace _Win32MapViewInSessionSpace
  314. #define Win32UnmapViewInSessionSpace _Win32UnmapViewInSessionSpace
  315. #define Win32DestroySection _Win32DestroySection
  316. #endif // TRACE_MAP_VIEWS
  317. #if DBG
  318. #define POOL_INSTR
  319. #define POOL_INSTR_API
  320. #else
  321. #define POOL_INSTR
  322. #endif // DBG
  323. /*++
  324. How the registry controls pool instrumentation in win32k.sys:
  325. --------------------------------------------------------------
  326. If pool instrumentation is turned on (this can be done for free builds as
  327. well as checked) then there are several levels of tracing controlled from
  328. the registry under the following key:
  329. HKLM\System\CurrentControlSet\Control\Session Manager\SubSystems\Pool
  330. if this key doesn't exist default settings are used for each of the following key.
  331. 1. HeavyRemoteSession REG_DWORD
  332. default: 1
  333. if this is non zero or the key doesn't exist then pool tracing is on
  334. for remote sessions of win32k.sys.
  335. 2. HeavyConsoleSession REG_DWORD
  336. default: 0
  337. if this is non zero then pool tracing is on for console sessions
  338. of win32k.sys. it the key doesn't exist then pool tracing is off for
  339. the main session.
  340. 3. StackTraces REG_DWORD
  341. default:
  342. - 1 for remote sessions
  343. - 0 for the main session
  344. if non zero then a stack trace record will be saved for every
  345. pool allocation made.
  346. 4. KeepFailRecords REG_DWORD
  347. default: 32
  348. if non zero then win32k.sys will keep a list of the last x allocations
  349. that failed (tag + stack trace). Use !dpa -f to dump the stack traces of
  350. the failed allocations
  351. 4. UseTailString REG_DWORD
  352. default: 0
  353. if non zero for every pool allocation there will be a string attached
  354. to the end of the allocation to catch some specific type of memory corruption.
  355. 5. KeepFreeRecords REG_DWORD
  356. default: 0
  357. not implemented yet. the number will specify how many free pointers will
  358. be kept in a list so we can differentiate when we call ExFreePool between
  359. a totally bogus value and a pointer that was already freed.
  360. 6. AllocationIndex REG_DWORD
  361. 7. AllocationsToFail REG_DWORD
  362. If AllocationIndex is non zero then win32k counts the pool allocations
  363. made and will start failing from allocation AllocationIndex a number
  364. of AllocationsToFail allocations. This is useful during boot time when
  365. a user mode test cannot call Win32PoolAllocationStats to fail pool allocations.
  366. 8. BreakForPoolLeaks REG_DWORD
  367. default: 0
  368. Breaks in the debugger (if started with /debug in boot.ini) if pool leaks
  369. are detected in win32k.sys for remote sessions.
  370. --*/
  371. #ifdef POOL_INSTR
  372. PVOID HeavyAllocPool(SIZE_T uBytes, ULONG iTag, DWORD dwFlags, EX_POOL_PRIORITY priority);
  373. VOID HeavyFreePool(PVOID p);
  374. #define Win32AllocPool(uBytes, iTag) \
  375. HeavyAllocPool(uBytes, iTag, 0, (EX_POOL_PRIORITY)0)
  376. #define Win32AllocPoolWithPriority(uBytes, iTag, priority) \
  377. HeavyAllocPool(uBytes, iTag, DAP_PRIORITY, priority)
  378. #define Win32AllocPoolZInit(uBytes, iTag) \
  379. HeavyAllocPool(uBytes, iTag, DAP_ZEROINIT, (EX_POOL_PRIORITY)0)
  380. #define Win32AllocPoolZInitWithPriority(uBytes, iTag, priority) \
  381. HeavyAllocPool(uBytes, iTag, DAP_ZEROINIT | DAP_PRIORITY, priority)
  382. #define Win32AllocPoolWithQuota(uBytes, iTag) \
  383. HeavyAllocPool(uBytes, iTag, DAP_USEQUOTA, (EX_POOL_PRIORITY)0)
  384. #define Win32AllocPoolWithQuotaZInit(uBytes, iTag) \
  385. HeavyAllocPool(uBytes, iTag, DAP_USEQUOTA | DAP_ZEROINIT, (EX_POOL_PRIORITY)0)
  386. #define Win32AllocPoolNonPaged(uBytes, iTag) \
  387. HeavyAllocPool(uBytes, iTag, DAP_NONPAGEDPOOL, (EX_POOL_PRIORITY)0);
  388. #define Win32AllocPoolNonPagedWithPriority(uBytes, iTag, priority) \
  389. HeavyAllocPool(uBytes, iTag, DAP_NONPAGEDPOOL | DAP_PRIORITY, priority);
  390. #define Win32AllocPoolWithQuotaNonPaged(uBytes, iTag) \
  391. HeavyAllocPool(uBytes, iTag, DAP_USEQUOTA | DAP_NONPAGEDPOOL, (EX_POOL_PRIORITY)0);
  392. #define Win32AllocPoolNonPagedNS(uBytes, iTag) \
  393. HeavyAllocPool(uBytes, iTag, DAP_NONPAGEDPOOL | DAP_NONSESSION, (EX_POOL_PRIORITY)0);
  394. #define Win32AllocPoolNonPagedNSWithPriority(uBytes, iTag, priority) \
  395. HeavyAllocPool(uBytes, iTag, DAP_NONPAGEDPOOL | DAP_NONSESSION | DAP_PRIORITY, priority);
  396. #define Win32FreePool HeavyFreePool
  397. #else
  398. PVOID __inline Win32AllocPool(SIZE_T uBytes, ULONG uTag)
  399. {
  400. return ExAllocatePoolWithTag(
  401. (POOL_TYPE)(SESSION_POOL_MASK | PagedPool),
  402. uBytes, uTag);
  403. }
  404. PVOID __inline Win32AllocPoolWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority)
  405. {
  406. return ExAllocatePoolWithTagPriority(
  407. (POOL_TYPE)(SESSION_POOL_MASK | PagedPool),
  408. uBytes, uTag, priority);
  409. }
  410. PVOID __inline Win32AllocPoolWithQuota(SIZE_T uBytes, ULONG uTag)
  411. {
  412. return ExAllocatePoolWithQuotaTag(
  413. (POOL_TYPE)(SESSION_POOL_MASK | PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE),
  414. uBytes, uTag);
  415. }
  416. PVOID __inline Win32AllocPoolNonPaged(SIZE_T uBytes, ULONG uTag)
  417. {
  418. return ExAllocatePoolWithTag(
  419. (POOL_TYPE)(SESSION_POOL_MASK | NonPagedPool),
  420. uBytes, uTag);
  421. }
  422. PVOID __inline Win32AllocPoolNonPagedWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority)
  423. {
  424. return ExAllocatePoolWithTagPriority(
  425. (POOL_TYPE)(SESSION_POOL_MASK | NonPagedPool),
  426. uBytes, uTag, priority);
  427. }
  428. PVOID __inline Win32AllocPoolNonPagedNS(SIZE_T uBytes, ULONG uTag)
  429. {
  430. return ExAllocatePoolWithTag(
  431. (POOL_TYPE)NonPagedPool,
  432. uBytes, uTag);
  433. }
  434. PVOID __inline Win32AllocPoolNonPagedNSWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority)
  435. {
  436. return ExAllocatePoolWithTagPriority(
  437. (POOL_TYPE)NonPagedPool,
  438. uBytes, uTag, priority);
  439. }
  440. PVOID __inline Win32AllocPoolWithQuotaNonPaged(SIZE_T uBytes, ULONG uTag)
  441. {
  442. return ExAllocatePoolWithQuotaTag(
  443. (POOL_TYPE)(SESSION_POOL_MASK | NonPagedPool), uBytes, uTag);
  444. }
  445. PVOID Win32AllocPoolWithTagZInit(SIZE_T uBytes, ULONG uTag);
  446. PVOID Win32AllocPoolWithTagZInitWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority);
  447. PVOID Win32AllocPoolWithQuotaTagZInit(SIZE_T uBytes, ULONG uTag);
  448. PVOID __inline Win32AllocPoolZInit(SIZE_T uBytes, ULONG uTag)
  449. {
  450. return Win32AllocPoolWithTagZInit(uBytes, uTag);
  451. }
  452. PVOID __inline Win32AllocPoolZInitWithPriority(SIZE_T uBytes, ULONG uTag, EX_POOL_PRIORITY priority)
  453. {
  454. return Win32AllocPoolWithTagZInitWithPriority(uBytes, uTag, priority);
  455. }
  456. PVOID __inline Win32AllocPoolWithQuotaZInit(SIZE_T uBytes, ULONG uTag)
  457. {
  458. return Win32AllocPoolWithQuotaTagZInit(uBytes, uTag);
  459. }
  460. #define Win32FreePool ExFreePool
  461. #endif // POOL_INSTR
  462. /*
  463. * All the User* allocation functions are defined to be Win32*
  464. */
  465. #define UserAllocPool Win32AllocPool
  466. #define UserAllocPoolZInit Win32AllocPoolZInit
  467. #define UserAllocPoolWithQuota Win32AllocPoolWithQuota
  468. #define UserAllocPoolWithQuotaZInit Win32AllocPoolWithQuotaZInit
  469. #define UserAllocPoolNonPaged Win32AllocPoolNonPaged
  470. #define UserAllocPoolNonPagedNS Win32AllocPoolNonPagedNS
  471. #define UserAllocPoolWithQuotaNonPaged Win32AllocPoolWithQuotaNonPaged
  472. #define UserFreePool Win32FreePool
  473. SIZE_T Win32QueryPoolSize(
  474. PVOID p);
  475. PVOID UserReAllocPoolWithTag(
  476. PVOID pSrc,
  477. SIZE_T uBytesSrc,
  478. SIZE_T uBytes,
  479. ULONG uTag);
  480. PVOID UserReAllocPoolWithQuotaTag(
  481. PVOID pSrc,
  482. SIZE_T uBytesSrc,
  483. SIZE_T uBytes,
  484. ULONG uTag);
  485. PVOID __inline UserReAllocPool(PVOID p, SIZE_T uBytesSrc, SIZE_T uBytes, ULONG uTag)
  486. {
  487. return UserReAllocPoolWithTag(p, uBytesSrc, uBytes, uTag);
  488. }
  489. PVOID __inline UserReAllocPoolWithQuota(PVOID p, SIZE_T uBytesSrc, SIZE_T uBytes, ULONG uTag)
  490. {
  491. return UserReAllocPoolWithQuotaTag(p, uBytesSrc, uBytes, uTag);
  492. }
  493. /*
  494. * Since the ReAllocPoolZInit functions are not yet used, they are
  495. * made inline to save code space. Consider making them non-inline
  496. * if they get a few uses.
  497. */
  498. PVOID __inline UserReAllocPoolZInit(PVOID p, SIZE_T uBytesSrc, SIZE_T uBytes, ULONG uTag)
  499. {
  500. PVOID pv;
  501. pv = UserReAllocPoolWithTag(p, uBytesSrc, uBytes, uTag);
  502. if (pv && uBytes > uBytesSrc) {
  503. RtlZeroMemory((BYTE *)pv + uBytesSrc, uBytes - uBytesSrc);
  504. }
  505. return pv;
  506. }
  507. PVOID __inline UserReAllocPoolWithQuotaZInit(PVOID p, SIZE_T uBytesSrc, SIZE_T uBytes, ULONG uTag)
  508. {
  509. PVOID pv;
  510. pv = UserReAllocPoolWithQuotaTag(p, uBytesSrc, uBytes, uTag);
  511. if (pv && uBytes > uBytesSrc) {
  512. RtlZeroMemory((BYTE *)pv + uBytesSrc, uBytes - uBytesSrc);
  513. }
  514. return pv;
  515. }
  516. #define DAP_USEQUOTA 0x01
  517. #define DAP_ZEROINIT 0x02
  518. #define DAP_NONPAGEDPOOL 0x04
  519. #define DAP_NONSESSION 0x08
  520. #define DAP_PRIORITY 0x10
  521. //!!!dbug -- there has to be a better one somewhere...
  522. /*
  523. * Memory manager (ExAllocate..., etc.) pool header size.
  524. */
  525. #define MM_POOL_HEADER_SIZE 8
  526. #define POOL_ALLOC_TRACE_SIZE 8
  527. typedef struct tagWin32PoolHead {
  528. SIZE_T size; // the size of the allocation (doesn't include
  529. // this structure
  530. struct tagWin32PoolHead* pPrev; // pointer to the previous allocation of this tag
  531. struct tagWin32PoolHead* pNext; // pointer to the next allocation of this tag
  532. PVOID* pTrace; // pointer to the stack trace
  533. } Win32PoolHead, *PWin32PoolHead;
  534. /*
  535. * Memory barrier
  536. * This macro ensures the pending write-back instructions retire before the next
  537. * code, settles the multi-proc rare problems (see KeMemoryBarrier macros).
  538. * RISC chips could reorder the retirement of the instructions, so when it's
  539. * critical to ensure the order of the write operation, those macros should be
  540. * used.
  541. */
  542. #if defined(_X86_)
  543. #define Win32MemoryBarrier()
  544. #elif defined(_IA64_)
  545. #if defined(NT_UP)
  546. #define Win32MemoryBarrier()
  547. #else
  548. #define WIN32_MEMORY_BARRIER_REQUIRED
  549. #define Win32MemoryBarrier() __mf()
  550. #endif
  551. #elif defined(_AMD64_)
  552. #define Win32MemoryBarrier()
  553. #else
  554. #error unknown CPU type.
  555. #endif