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.

945 lines
22 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. umpd.cxx
  5. Abstract:
  6. User-mode printer driver support
  7. Environment:
  8. Windows NT 5.0
  9. Revision History:
  10. 07/8/97 -lingyunw-
  11. Created it.
  12. 09/17/97 -davidx-
  13. Clean up km-um thunking.
  14. --*/
  15. #include "umpd.h"
  16. //
  17. // LPC
  18. //
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. typedef struct ProxyPort
  23. {
  24. HANDLE PortHandle;
  25. HANDLE SectionHandle;
  26. SSIZE_T ClientMemoryBase;
  27. SIZE_T ClientMemorySize;
  28. SSIZE_T ServerMemoryBase;
  29. SSIZE_T ServerMemoryDelta;
  30. ULONG ClientMemoryAllocSize;
  31. HANDLE hSecure;
  32. } ProxyPort;
  33. typedef KERNEL_PVOID UM64_PVOID;
  34. typedef ULONG SERVEROFF;
  35. typedef struct _PROXYMSG {
  36. PORT_MESSAGE h;
  37. ULONG cjIn;
  38. UM64_PVOID pvIn;
  39. ULONG cjOut;
  40. UM64_PVOID pvOut;
  41. } PROXYMSG, *PPROXYMSG;
  42. #ifdef __cplusplus
  43. } // extern "C"
  44. #endif
  45. #define UMPD_MAX_FONTFACELINK 10
  46. class PROXYPORT
  47. {
  48. private:
  49. ProxyPort *pp;
  50. public:
  51. PROXYPORT (ProxyPort* pIn) { pp = pIn; }
  52. PROXYPORT (ULONGLONG inMaxSize);
  53. ~PROXYPORT () {}
  54. BOOL bValid() { return (pp != NULL); }
  55. ProxyPort* GetProxyPort() { return (pp); }
  56. VOID HeapInit()
  57. {
  58. pp->ClientMemoryAllocSize = 0;
  59. }
  60. UM64_PVOID HeapAlloc(ULONG inSize);
  61. KERNEL_PVOID GetKernelPtr(UM64_PVOID pv)
  62. {
  63. return (KERNEL_PVOID) (pv ? ((PBYTE) pv - pp->ServerMemoryDelta) : NULL);
  64. }
  65. PPORT_MESSAGE
  66. InitMsg(PPROXYMSG Msg,
  67. UM64_PVOID pvIn,
  68. ULONG cjIn,
  69. UM64_PVOID pvOut,
  70. ULONG cjOut);
  71. BOOL
  72. CheckMsg(NTSTATUS Status,
  73. PPROXYMSG Msg,
  74. UM64_PVOID pvOut,
  75. ULONG cjOut);
  76. NTSTATUS
  77. SendRequest(UM64_PVOID pvIn, ULONG cjIn, UM64_PVOID pvOut, ULONG cjOut);
  78. VOID Close();
  79. };
  80. PLDEV
  81. UMPD_ldevLoadDriver(
  82. LPWSTR pwszDriver,
  83. LDEVTYPE ldt
  84. );
  85. VOID
  86. UMPD_ldevUnloadImage(PLDEV pldev);
  87. //
  88. // Special flag passed to EngCreateDeviceSurface and EngCreateDeviceBitmap
  89. // to indicate the call is a user mode printer driver
  90. //
  91. #define UMPD_FLAG 0x8000
  92. //
  93. // User-mode printer driver support - memory tag
  94. //
  95. #define UMPD_MEMORY_TAG 'pmuG'
  96. //
  97. // private structure to make N-UP printing work on DrawPatRect
  98. //
  99. typedef struct _DRAWPATRECTP {
  100. DRAWPATRECT DrawPatRect;
  101. XFORMOBJ *pXformObj;
  102. } DRAWPATRECTP, *PDRAWPATRECTP;
  103. #if !defined(_GDIPLUS_)
  104. BOOL UMPDDrvEnableDriver(
  105. LPWSTR pwszDriver,
  106. PVOID *pCookie
  107. );
  108. BOOL UMPDDrvDriverFn(
  109. PVOID cookie,
  110. BOOL * pbDrvFn
  111. );
  112. VOID UMPDDrvDeleteDeviceBitmap(
  113. DHPDEV dhpdev,
  114. DHSURF dhsurf
  115. );
  116. CLIPOBJ *CaptureAndMungeCLIPOBJ(CLIPOBJ *pcoUm, CLIPOBJ *pcoKm, SIZEL *szLimit);
  117. //
  118. // Align UMPD buffer on double-word boundary
  119. //
  120. //
  121. // Change it to sizeof(PVOID) aligned, bug 101774
  122. //
  123. #define ALIGN_UMPD_BUFFER(cj) (((cj) + (sizeof(PVOID) -1)) & ~(sizeof(PVOID)-1))
  124. #define ROUNDUP_MULTIPLE(n, m) ((((n) + (m) - 1) / (m)) * (m))
  125. //
  126. // UMPD memory manager
  127. //
  128. typedef struct _UMPDHEAP {
  129. PVOID pAddress; // starting heap address
  130. HANDLE hSecure; // secured handle
  131. SIZE_T CommitSize; // committed heap size
  132. ULONG AllocSize; // allocated heap size
  133. } UMPDHEAP, *PUMPDHEAP;
  134. VOID
  135. DestroyUMPDHeap(
  136. PUMPDHEAP pHeap
  137. );
  138. //
  139. // Data structure for mapping between kernel-mode DDI objects
  140. // and user-mode DDI objects.
  141. //
  142. typedef struct _DDIOBJMAP {
  143. KERNEL_PVOID kmobj; // pointer to kernel mode object
  144. UM64_PVOID umobj; // user mode object memory object
  145. } DDIOBJMAP, *PDDIOBJMAP;
  146. //
  147. // flags used by m_flags in UMPDOBJ
  148. //
  149. #define UMPDOBJ_ENGCALL 0x1
  150. #define RELEASE_BASEFONT 0x10
  151. #define RELEASE_SYSTTFONT 0x20
  152. #define RELEASE_SYSEUDCFONT 0x40
  153. #define RELEASE_DEFEUDCFONT 0x80
  154. //
  155. // UMPDOBJ is used to push saved kernel object pointers on to thread
  156. // we allocate a UMPDOBJ on the stack for each Drv-call, push it onto
  157. // the thread, and release it when the Drv-call is finished.
  158. //
  159. // The reason that we can't keep a one layer UMPDOBJ is that
  160. // some Drv-call may call back to the Engine and Engine makes another
  161. // Drv-call with totally different parameters
  162. //
  163. typedef class UMPDOBJ *PUMPDOBJ;
  164. class UMPDOBJ : public OBJECT
  165. {
  166. private:
  167. //
  168. // Constructor and destructor
  169. //
  170. UMPDOBJ()
  171. {
  172. // do nothing -- only here to ensure nobody tries to use constructor
  173. }
  174. ~UMPDOBJ()
  175. {
  176. // do nothing -- only here to ensure nobody tries to use destructor
  177. }
  178. public:
  179. BOOL Init(VOID);
  180. VOID Term(VOID)
  181. {
  182. //
  183. // Back-propogate pvConsumer field from user-mode
  184. // FONTOBJ to kernel-mode FONTOBJ, if necessary
  185. //
  186. if (m_fo.umobj != NULL)
  187. {
  188. ((FONTOBJ *) m_fo.kmobj)->pvConsumer = ((FONTOBJ *) GetKernelPtr(m_fo.umobj))->pvConsumer;
  189. }
  190. Cleanup();
  191. }
  192. //
  193. // Allocate user mode memory out of the UMPD heap
  194. //
  195. KERNEL_PVOID AllocUserMem(ULONG ulSize) { return _AllocUserMem(ulSize, FALSE); }
  196. KERNEL_PVOID AllocUserMemZ(ULONG ulSize) { return _AllocUserMem(ulSize, TRUE); }
  197. //
  198. // Cleanup when this object is destroyed
  199. //
  200. VOID Cleanup();
  201. //
  202. // Proxy support
  203. //
  204. BOOL bWOW64()
  205. {
  206. return m_proxyPort != NULL;
  207. }
  208. BOOL bWOW64Client()
  209. {
  210. return ((m_proxyPort != NULL) && (!(m_flags & UMPDOBJ_ENGCALL)));
  211. }
  212. BOOL bNeedThunk(PVOID pvIn)
  213. {
  214. return (bWOW64() || IS_SYSTEM_ADDRESS(pvIn));
  215. }
  216. PW32THREAD clientTid()
  217. {
  218. return (m_clientTid);
  219. }
  220. W32PID clientPid()
  221. {
  222. return (m_clientPid);
  223. }
  224. VOID vSetFlags(ULONG f)
  225. {
  226. m_flags |= f;
  227. }
  228. VOID vClearFlags(ULONG f)
  229. {
  230. m_flags &= ~f;
  231. }
  232. BOOL bAllocFontLinks(UINT numLinks)
  233. {
  234. if (m_pfontLinks = (BOOL*)PALLOCMEM(sizeof(BOOL) * numLinks, UMPD_MEMORY_TAG))
  235. m_fontLinks = numLinks;
  236. return (m_pfontLinks != NULL);
  237. }
  238. VOID vFreeFontLinks()
  239. {
  240. if (m_pfontLinks)
  241. VFREEMEM(m_pfontLinks);
  242. }
  243. ULONG GetFlags()
  244. {
  245. return (m_flags);
  246. }
  247. BOOL bLinkedFonts()
  248. {
  249. return (m_pfontLinks != NULL);
  250. }
  251. UINT numLinkedFonts()
  252. {
  253. return (m_fontLinks);
  254. }
  255. BOOL bLinkedFont(UINT i)
  256. {
  257. return (i < m_fontLinks && m_pfontLinks[i]);
  258. }
  259. VOID vSetFontLink(UINT i)
  260. {
  261. if (i < m_fontLinks && m_pfontLinks)
  262. m_pfontLinks[i] = TRUE;
  263. }
  264. VOID vClearFontLink(UINT i)
  265. {
  266. if (i < m_fontLinks && m_pfontLinks)
  267. m_pfontLinks[i] = FALSE;
  268. }
  269. ULONG ulAllocSize()
  270. {
  271. ASSERTGDI(m_proxyPort,"proxyport is NULL\n");
  272. return (m_proxyPort->ClientMemoryAllocSize);
  273. }
  274. ULONG ulGetMaxSize()
  275. {
  276. if (m_proxyPort && (m_proxyPort->ClientMemorySize > m_proxyPort->ClientMemoryAllocSize))
  277. return (ULONG)(m_proxyPort->ClientMemorySize - m_proxyPort->ClientMemoryAllocSize);
  278. else
  279. return 0;
  280. }
  281. //
  282. // Used only by WOW64 printing while the bitmap in SURFOBJ is bigger than 4MB
  283. //
  284. KERNEL_PVOID UMPDAllocUserMem(ULONG cjSize);
  285. //
  286. // Make a copy of the bitmap on wow64 printing
  287. //
  288. BOOL bSendLargeBitmap(SURFOBJ *pso, BOOL *pbLargeBitmap);
  289. BOOL bThunkLargeBitmap(SURFOBJ *pso,PVOID *ppvBits, PVOID *ppvScan0, BOOL *pbSavePtr, BOOL *pbLargeBitmap, PULONG pcjSize);
  290. BOOL bThunkLargeBitmaps(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMsk,
  291. PVOID *ppvBitTrg, PVOID *ppvScanTrg,
  292. PVOID *ppvBitSrc, PVOID *ppvScanSrc,
  293. PVOID *ppvBitMsk, PVOID *ppvScanMsk,
  294. BOOL *pbSaveTrg, BOOL *pbLargeTrg,
  295. BOOL *pbSaveSrc, BOOL *pbLargeSrc,
  296. BOOL *pbSaveMsk, BOOL *pbLargeMsk, PULONG pcjSize);
  297. BOOL bDeleteLargeBitmaps(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMsk);
  298. VOID RestoreBitmap(SURFOBJ *pso, PVOID pvBits, PVOID pvScan0, BOOL bSavePtr, BOOL bLargeBitmap);
  299. VOID RestoreBitmaps(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMsk,
  300. PVOID pvBitTrg, PVOID pvScanTrg,
  301. PVOID pvBitSrc, PVOID pvScanSrc,
  302. PVOID pvBitMsk, PVOID pvScanMsk,
  303. BOOL bSaveTrg, BOOL bLargeTrg,
  304. BOOL bSaveSrc, BOOL bLargeSrc,
  305. BOOL bSaveMsk, BOOL bLargeMsk);
  306. //
  307. // functions for packing kernel mode objects
  308. // before thunking out to the user mode
  309. //
  310. BOOL psoDest(SURFOBJ **ppso, BOOL bLargeBitmap)
  311. {
  312. return pso(&m_soDest, ppso, bLargeBitmap);
  313. }
  314. BOOL psoSrc(SURFOBJ **ppso, BOOL bLargeBitmap)
  315. {
  316. return pso(&m_soSrc, ppso, bLargeBitmap);
  317. }
  318. BOOL psoMask(SURFOBJ **ppso, BOOL bLargeBitmap)
  319. {
  320. return pso(&m_soMask, ppso, bLargeBitmap);
  321. }
  322. BOOL pco(CLIPOBJ **ppco)
  323. {
  324. return ThunkDDIOBJ(&m_co, (KERNEL_PVOID *) ppco, sizeof(CLIPOBJ));
  325. }
  326. BOOL pcoCreated(CLIPOBJ **ppco)
  327. {
  328. return ThunkDDIOBJ(&m_coCreated, (KERNEL_PVOID *) ppco, sizeof(CLIPOBJ));
  329. }
  330. BOOL pbo(BRUSHOBJ **ppbo)
  331. {
  332. return ThunkDDIOBJ(&m_bo, (KERNEL_PVOID *)ppbo, sizeof(BRUSHOBJ));
  333. }
  334. BOOL pboFill(BRUSHOBJ **ppbo)
  335. {
  336. return ThunkDDIOBJ(&m_boFill, (KERNEL_PVOID *)ppbo, sizeof(BRUSHOBJ));
  337. }
  338. BOOL pfo(FONTOBJ **ppfo)
  339. {
  340. return ThunkDDIOBJ(&m_fo, (KERNEL_PVOID *) ppfo, sizeof(FONTOBJ));
  341. }
  342. BOOL pstro(STROBJ **ppstro);
  343. BOOL pxlo(XLATEOBJ **ppxlo);
  344. BOOL ppo(PATHOBJ **pppo)
  345. {
  346. return ThunkDDIOBJ(&m_po, (KERNEL_PVOID *) pppo, sizeof(PATHOBJ));
  347. }
  348. BOOL ppoClip(PATHOBJ **pppo)
  349. {
  350. return ThunkDDIOBJ(&m_poClip, (KERNEL_PVOID *) pppo, sizeof(PATHOBJ));
  351. }
  352. BOOL ppoGlyph(PATHOBJ **pppo)
  353. {
  354. return ThunkDDIOBJ(&m_poGlyph, (KERNEL_PVOID *) pppo, sizeof(PATHOBJ));
  355. }
  356. BOOL pxo(XFORMOBJ **ppxo)
  357. {
  358. return ThunkDDIOBJ(&m_xo, (KERNEL_PVOID *) ppxo, sizeof(XFORMOBJ));
  359. }
  360. BOOL pxoFont(XFORMOBJ **ppxo)
  361. {
  362. return ThunkDDIOBJ(&m_xoFont, (KERNEL_PVOID *) ppxo, sizeof(XFORMOBJ));
  363. }
  364. BOOL ThunkBLENDOBJ(PBLENDOBJ *ppblendobj)
  365. {
  366. return ThunkDDIOBJ(&m_blendObj, (KERNEL_PVOID *) ppblendobj, sizeof(BLENDOBJ));
  367. }
  368. BOOL ThunkLINEATTRS(LINEATTRS **pplineattrs);
  369. BOOL ThunkMemBlock(PVOID *ppInput, ULONG ulSize);
  370. BOOL ThunkStringW(PWSTR *ppwstr)
  371. {
  372. return (*ppwstr == NULL) ?
  373. TRUE :
  374. ThunkMemBlock((PVOID *) ppwstr, (wcslen(*ppwstr) + 1) * sizeof(WCHAR));
  375. }
  376. BOOL ThunkRECTL(PRECTL *pprcl)
  377. {
  378. return ThunkMemBlock((PVOID *) pprcl, sizeof(RECTL));
  379. }
  380. BOOL ThunkPOINTL(PPOINTL *pptl)
  381. {
  382. return ThunkMemBlock((PVOID *) pptl, sizeof(POINTL));
  383. }
  384. BOOL ThunkPOINTFIX(PPOINTFIX *pptfx)
  385. {
  386. return ThunkMemBlock((PVOID *) pptfx, sizeof(POINTFIX));
  387. }
  388. BOOL ThunkCOLORADJUSTMENT(PCOLORADJUSTMENT *ppca)
  389. {
  390. return ThunkMemBlock((PVOID *) ppca, sizeof(COLORADJUSTMENT));
  391. }
  392. //
  393. // Functions for mapping user mode objects to kernel mode
  394. // objects during Eng-callbacks
  395. //
  396. CLIPOBJ *GetDDIOBJ(CLIPOBJ *pco)
  397. {
  398. return (pco == m_co.umobj) ? (CLIPOBJ *) m_co.kmobj : NULL;
  399. }
  400. CLIPOBJ *GetDDIOBJ(CLIPOBJ *pco, SIZEL *szLimit)
  401. {
  402. return (pco == m_co.umobj) ?
  403. (CLIPOBJ *) m_co.kmobj :
  404. (pco == m_coCreated.umobj) ?
  405. CaptureAndMungeCLIPOBJ(pco, (CLIPOBJ *) m_coCreated.kmobj, szLimit) :
  406. NULL;
  407. }
  408. BRUSHOBJ *GetDDIOBJ(BRUSHOBJ *pbo)
  409. {
  410. return (BRUSHOBJ *)
  411. ((pbo == m_bo.umobj) ? m_bo.kmobj :
  412. (pbo == m_boFill.umobj) ? m_boFill.kmobj : NULL);
  413. }
  414. FONTOBJ *GetDDIOBJ(FONTOBJ *pfo)
  415. {
  416. return (FONTOBJ *) ((pfo == m_fo.umobj) ? m_fo.kmobj : NULL);
  417. }
  418. STROBJ *GetDDIOBJ(STROBJ *pstro)
  419. {
  420. return (STROBJ *) ((pstro == m_stro.umobj) ? m_stro.kmobj : NULL);
  421. }
  422. XLATEOBJ *GetDDIOBJ(XLATEOBJ *pxlo)
  423. {
  424. return (XLATEOBJ *) ((pxlo == m_xlo.umobj) ? m_xlo.kmobj : NULL);
  425. }
  426. PATHOBJ *GetDDIOBJ(PATHOBJ *ppo)
  427. {
  428. return (PATHOBJ *)
  429. ((ppo == m_po.umobj) ? m_po.kmobj :
  430. (ppo == m_poClip.umobj) ? m_poClip.kmobj :
  431. (ppo == m_poGlyph.umobj) ? m_poGlyph.kmobj : NULL);
  432. }
  433. XFORMOBJ *GetDDIOBJ(XFORMOBJ *pxo)
  434. {
  435. return (XFORMOBJ *)
  436. ((pxo == m_xo.umobj) ? m_xo.kmobj :
  437. (pxo == m_xoFont.umobj) ? m_xoFont.kmobj : NULL);
  438. }
  439. BLENDOBJ *GetDDIOBJ(BLENDOBJ *pBlendObj)
  440. {
  441. return (BLENDOBJ *)
  442. ((pBlendObj == m_blendObj.umobj) ? m_blendObj.kmobj : NULL);
  443. }
  444. SURFOBJ *GetSURFOBJ(SURFOBJ *pso)
  445. {
  446. return (SURFOBJ *)
  447. ((pso == m_soDest.umobj) ? (m_soDest.kmobj) :
  448. (pso == m_soSrc.umobj) ? (m_soSrc.kmobj) :
  449. (pso == m_soMask.umobj) ? (m_soMask.kmobj) : NULL);
  450. }
  451. SURFOBJ *LockSurface(HSURF hsurf);
  452. VOID UnlockSurface(SURFOBJ *pso);
  453. PATHOBJ *GetCLIPOBJPath(CLIPOBJ *pco);
  454. VOID DeleteCLIPOBJPath(PATHOBJ *ppo);
  455. CLIPOBJ *CreateCLIPOBJ();
  456. VOID DeleteCLIPOBJ(CLIPOBJ *pco);
  457. GLYPHBITS *CacheGlyphBits(GLYPHBITS *pgb);
  458. PATHOBJ *CacheGlyphPath(PATHOBJ *ppo);
  459. XFORMOBJ *GetFONTOBJXform(FONTOBJ *pfo);
  460. PIFIMETRICS pifi() { return m_pifi; }
  461. VOID pifi(PIFIMETRICS pifi) { m_pifi = pifi; }
  462. PFD_GLYPHSET pfdg() { return m_pfdg; }
  463. VOID pfdg(PFD_GLYPHSET pfdg) { m_pfdg = pfdg; }
  464. PFD_GLYPHATTR pfdga() { return m_pfdga; }
  465. VOID pfdga(PFD_GLYPHATTR pfdga) { m_pfdga = pfdga; }
  466. PVOID pvFontFile(ULONG *size) { *size = m_size; return m_pvFontFile; }
  467. VOID pvFontFile(PVOID pvFontFile, PVOID pvFontBase, ULONG size)
  468. {
  469. m_pFontProcess = PsGetCurrentProcess();
  470. m_pvFontFile = pvFontFile;
  471. m_pvFontBase = pvFontBase;
  472. m_size = size;
  473. }
  474. KERNEL_PVOID GetKernelPtr(UM64_PVOID pv);
  475. VOID ResetHeap();
  476. DWORD Thunk(PVOID pvIn, ULONG cjIn, PVOID pvOut, ULONG cjOut);
  477. private:
  478. //
  479. // Data members
  480. //
  481. ULONG m_magic; // data structure signature
  482. PUMPDOBJ m_pNext; // link-list pointer
  483. PUMPDHEAP m_pHeap; // pointer to user mode memory heap
  484. DDIOBJMAP m_soDest; // SURFOBJ
  485. DDIOBJMAP m_soSrc; // SURFOBJ
  486. DDIOBJMAP m_soMask; // SURFOBJ
  487. DDIOBJMAP m_co; // CLIPOBJ
  488. DDIOBJMAP m_coCreated; // CLIPOBJ via EngCreateClip
  489. DDIOBJMAP m_bo; // BRUSHOBJ
  490. DDIOBJMAP m_boFill; // BRUSHOBJ
  491. DDIOBJMAP m_fo; // FONTOBJ
  492. DDIOBJMAP m_stro; // STROBJ
  493. DDIOBJMAP m_xlo; // XLATEOBJ
  494. DDIOBJMAP m_po; // PATHOBJ
  495. DDIOBJMAP m_poClip; // PATHOBJ
  496. DDIOBJMAP m_poGlyph; // PATHOBJ
  497. DDIOBJMAP m_xo; // XFORMOBJ
  498. DDIOBJMAP m_xoFont; // XFORMOBJ
  499. DDIOBJMAP m_blendObj; // BLENDOBJ
  500. PIFIMETRICS m_pifi; // pointer to temporary pifi buffer
  501. PFD_GLYPHSET m_pfdg; // pointer to temporary pfdg buffer
  502. PFD_GLYPHATTR m_pfdga; // pointer to temporary pfdga buffer
  503. GLYPHBITS *m_pgb; // pointer to temporary GLYPHBITS buffer
  504. ULONG m_gbSize; // GLYPHBITS buffer size
  505. PVOID m_pvFontBase; // cached info for FONTOBJ_pvTrueTypeFontFile
  506. PVOID m_pvFontFile; //
  507. ULONG m_size; //
  508. PEPROCESS m_pFontProcess; //
  509. struct ProxyPort * m_proxyPort; // Proxy server if needed
  510. PW32THREAD m_clientTid; // Printing client tid
  511. W32PID m_clientPid; // Printing client pid
  512. ULONG m_flags;
  513. UINT m_fontLinks; // Number of linked fonts
  514. BOOL *m_pfontLinks; // Keep track of the linked font semaphores
  515. //
  516. // Internal helper functions
  517. //
  518. UM64_PVOID _AllocUserMem(ULONG ulSize, BOOL bZeroInit);
  519. BOOL ThunkDDIOBJ(PDDIOBJMAP pMap, KERNEL_PVOID *ppObj, ULONG objSize);
  520. BOOL pso(PDDIOBJMAP pMap, SURFOBJ **ppso, BOOL bLargeBitmap);
  521. // Internal UMPD heap functions
  522. PUMPDHEAP CreateUMPDHeap(void);
  523. PUMPDHEAP InitUMPDHeap(PUMPDHEAP pHeap);
  524. BOOL GrowUMPDHeap(PUMPDHEAP pHeap, ULONG ulBytesNeeded);
  525. };
  526. typedef class XUMPDOBJ *PXUMPDOBJ;
  527. class XUMPDOBJ
  528. {
  529. public:
  530. XUMPDOBJ()
  531. {
  532. PUMPDOBJ pumpdobj = (PUMPDOBJ) PALLOCMEM(sizeof(UMPDOBJ), 'dpxG');
  533. m_pumpdobj = NULL;
  534. if(pumpdobj)
  535. {
  536. if(pumpdobj->Init())
  537. m_pumpdobj = pumpdobj;
  538. else
  539. VFREEMEM(pumpdobj);
  540. }
  541. }
  542. BOOL bValid(void) { return m_pumpdobj != NULL; }
  543. PUMPDOBJ pumpdobj(VOID) { return m_pumpdobj; }
  544. HUMPD hUMPD() { return (HUMPD)m_pumpdobj->hGet(); }
  545. ~XUMPDOBJ()
  546. {
  547. if(m_pumpdobj)
  548. {
  549. m_pumpdobj->Term();
  550. VFREEMEM(m_pumpdobj);
  551. }
  552. }
  553. private:
  554. UMPDOBJ * m_pumpdobj;
  555. };
  556. class UMPDREF
  557. {
  558. public:
  559. UMPDREF(HUMPD humpd) { m_pumpd = humpd ? (PUMPDOBJ)HmgShareLock((HOBJ)humpd, UMPD_TYPE) : NULL; }
  560. BOOL bWOW64() { return m_pumpd->bWOW64(); }
  561. PW32THREAD clientTid() { return m_pumpd->clientTid(); }
  562. W32PID clientPid() { return m_pumpd->clientPid(); }
  563. UMPDOBJ* pumpdGet() { return m_pumpd; }
  564. ~UMPDREF()
  565. {
  566. if(m_pumpd)
  567. DEC_SHARE_REF_CNT(m_pumpd);
  568. }
  569. private:
  570. UMPDOBJ* m_pumpd;
  571. };
  572. //
  573. // Inline function to thunk a block of memory from kernel mode to user mode
  574. //
  575. __inline
  576. BOOL UMPDOBJ::ThunkMemBlock(
  577. PVOID *ppInput,
  578. ULONG ulSize
  579. )
  580. {
  581. PVOID pvIn;
  582. if ((pvIn = *ppInput) == NULL || ulSize == 0)
  583. return TRUE;
  584. UM64_PVOID pv;
  585. if ((pv = AllocUserMem(ulSize)) == NULL)
  586. return FALSE;
  587. RtlCopyMemory(GetKernelPtr(pv), pvIn, ulSize);
  588. *ppInput = pv;
  589. return TRUE;
  590. }
  591. //
  592. // Inline function to thunk a kernel mode object to user mode
  593. //
  594. __inline
  595. BOOL UMPDOBJ::ThunkDDIOBJ(
  596. PDDIOBJMAP pMap,
  597. KERNEL_PVOID *ppObj,
  598. ULONG objSize
  599. )
  600. {
  601. KERNEL_PVOID kmobj;
  602. UM64_PVOID umobj;
  603. if ((kmobj = *ppObj) == NULL)
  604. return TRUE;
  605. if ((umobj = AllocUserMem(objSize)) == NULL)
  606. return FALSE;
  607. RtlCopyMemory(GetKernelPtr(umobj), kmobj, objSize);
  608. pMap->kmobj = kmobj;
  609. *ppObj = pMap->umobj = umobj;
  610. return TRUE;
  611. }
  612. //
  613. // Inline function to allocate a block of user mode memory
  614. //
  615. __inline
  616. KERNEL_PVOID UMPDOBJ::GetKernelPtr(UM64_PVOID pv)
  617. {
  618. if(bWOW64Client())
  619. {
  620. PROXYPORT proxyport(m_proxyPort);
  621. return proxyport.GetKernelPtr(pv);
  622. }
  623. else
  624. return pv;
  625. }
  626. __inline
  627. UM64_PVOID UMPDOBJ::_AllocUserMem(
  628. ULONG ulSize,
  629. BOOL bZeroInit
  630. )
  631. {
  632. UM64_PVOID pv;
  633. if(bWOW64())
  634. {
  635. PROXYPORT proxyport(m_proxyPort);
  636. pv = proxyport.HeapAlloc(ALIGN_UMPD_BUFFER(ulSize));
  637. }
  638. else
  639. {
  640. if (m_pHeap == NULL || m_pHeap->pAddress == NULL ||
  641. ulSize > m_pHeap->CommitSize - m_pHeap->AllocSize && !GrowUMPDHeap(m_pHeap, ulSize))
  642. {
  643. return NULL;
  644. }
  645. else
  646. {
  647. pv = (PBYTE) m_pHeap->pAddress + m_pHeap->AllocSize;
  648. m_pHeap->AllocSize += ALIGN_UMPD_BUFFER(ulSize);
  649. }
  650. }
  651. if (pv && bZeroInit)
  652. RtlZeroMemory(GetKernelPtr(pv), ulSize);
  653. return pv;
  654. }
  655. //
  656. // Wrapper class for mapping user mode SURFOBJ pointers
  657. // to their kernel mode counterparts
  658. //
  659. class UMPDSURFOBJ
  660. {
  661. public:
  662. UMPDSURFOBJ(SURFOBJ *pso, PUMPDOBJ pUMObjs)
  663. {
  664. m_bLocked = (m_pso = pso) != NULL &&
  665. (m_pso = pUMObjs->GetSURFOBJ(pso)) == NULL &&
  666. (m_pso = GetLockedSURFOBJ(pso)) != NULL;
  667. }
  668. ~UMPDSURFOBJ()
  669. {
  670. if (m_bLocked)
  671. EngUnlockSurface(m_pso);
  672. }
  673. SURFOBJ *pso() { return m_pso; }
  674. private:
  675. SURFOBJ *m_pso;
  676. BOOL m_bLocked;
  677. SURFOBJ *GetLockedSURFOBJ(SURFOBJ *pso);
  678. };
  679. //
  680. // A few DDI callbacks which are implemented differently for UMPD
  681. //
  682. PVOID FONTOBJ_pvTrueTypeFontFileUMPD(FONTOBJ *pfo, ULONG *pcjFile, PVOID *ppBase);
  683. PVOID BRUSHOBJ_pvAllocRbrushUMPD(BRUSHOBJ *pbo, ULONG cj);
  684. PVOID BRUSHOBJ_pvGetRbrushUMPD(BRUSHOBJ *pbo);
  685. typedef struct _PRINTCLIENTID
  686. {
  687. PW32THREAD clientTid;
  688. W32PID clientPid;
  689. } PRINTCLIENTID, PPRINTCLIENTID;
  690. BOOL UMPDEngFreeUserMem(KERNEL_PVOID pv);
  691. BOOL UMPDReleaseRFONTSem(
  692. RFONTOBJ& rfo,
  693. PUMPDOBJ pumpdobj,
  694. ULONG* pfl,
  695. ULONG* pnumLinks,
  696. BOOL** ppFaceLink
  697. );
  698. VOID UMPDAcquireRFONTSem(
  699. RFONTOBJ& rfo,
  700. PUMPDOBJ pumpdobj,
  701. ULONG fl,
  702. ULONG numLinks,
  703. BOOL* pFaceLink
  704. );
  705. VOID TextOutBitBlt(
  706. SURFACE *pSurf,
  707. RFONTOBJ& rfo,
  708. SURFOBJ *psoSrc,
  709. SURFOBJ *psoMask,
  710. CLIPOBJ *pco,
  711. XLATEOBJ *pxlo,
  712. RECTL *prclTrg,
  713. POINTL *pptlSrc,
  714. POINTL *pptlMask,
  715. BRUSHOBJ *pbo,
  716. POINTL *pptlBrush,
  717. ROP4 rop4
  718. );
  719. BOOL GetETMFontManagement(
  720. RFONTOBJ& rfo,
  721. PDEVOBJ pdo,
  722. SURFOBJ *pso,
  723. FONTOBJ *pfo,
  724. ULONG iEsc,
  725. ULONG cjIn,
  726. PVOID pvIn,
  727. ULONG cjOut,
  728. PVOID pvOut
  729. );
  730. #endif // !_GDIPLUS_