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.

997 lines
25 KiB

  1. /*****************************Module*Header*******************************\
  2. * Module Name: local.c *
  3. * *
  4. * Support routines for client side objects and attribute caching. *
  5. * *
  6. * Created: 30-May-1991 21:55:57 *
  7. * Author: Charles Whitmer [chuckwh] *
  8. * *
  9. * Copyright (c) 1991-1999 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include "stdarg.h"
  14. #include "wowgdip.h"
  15. #include "vdm.h"
  16. extern CFONT *pcfDeleteList;
  17. VOID vFreeCFONTCrit(CFONT *pcf);
  18. RTL_CRITICAL_SECTION semLocal; // Semaphore for handle allocation.
  19. //
  20. // ahStockObjects will contain both the stock objects visible to an
  21. // application, and internal ones such as the private stock bitmap.
  22. //
  23. ULONG_PTR ahStockObjects[PRIV_STOCK_LAST+1];
  24. #if DBG
  25. ULONG gdi_dbgflags; // Debug flags - FIREWALL.H.
  26. #endif
  27. #if DBG
  28. INT gbCheckHandleLevel=0;
  29. #endif
  30. /******************************Public*Routine******************************\
  31. * GdiQueryTable()
  32. *
  33. * private entry point for wow to get the gdi handle table. This allows
  34. * WOW to do fix up's on handles since they throw away the high word.
  35. *
  36. * History:
  37. * 24-Jul-1995 -by- Eric Kutter [erick]
  38. * Wrote it.
  39. \**************************************************************************/
  40. PVOID GdiQueryTable()
  41. {
  42. VDM_QUERY_VDM_PROCESS_DATA QueryVdmProcessData;
  43. NTSTATUS Status;
  44. //
  45. // Check the Target Process to see if this is a Wx86 process
  46. //
  47. QueryVdmProcessData.IsVdmProcess = FALSE;
  48. QueryVdmProcessData.ProcessHandle = NtCurrentProcess();
  49. Status = NtVdmControl(VdmQueryVdmProcess, &QueryVdmProcessData);
  50. if (!NT_SUCCESS(Status) || QueryVdmProcessData.IsVdmProcess == FALSE) {
  51. return NULL;
  52. }
  53. return((PVOID)pGdiSharedHandleTable);
  54. }
  55. /******************************Public*Routine******************************\
  56. *
  57. * History:
  58. * 02-Aug-1995 -by- Eric Kutter [erick]
  59. * Wrote it.
  60. \**************************************************************************/
  61. PLDC pldcGet(HDC hdc)
  62. {
  63. PLDC pldc = NULL;
  64. PDC_ATTR pdca;
  65. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  66. if (pdca)
  67. pldc = (PLDC)pdca->pvLDC;
  68. return(pldc);
  69. }
  70. /******************************Public*Routine******************************\
  71. * pldcCreate()
  72. *
  73. * History:
  74. * 25-Jan-1995 -by- Eric Kutter [erick]
  75. * Wrote it.
  76. \**************************************************************************/
  77. PLDC pldcCreate(
  78. HDC hdc,
  79. ULONG ulType)
  80. {
  81. PLDC pldc;
  82. pldc = (PLDC)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,sizeof(LDC));
  83. if (!pldc)
  84. {
  85. WARNING("pldcCreate - failed to allocate plinkCreate\n");
  86. }
  87. else
  88. {
  89. PDC_ATTR pdca;
  90. pldc->iType = ulType;
  91. pldc->hdc = hdc;
  92. // make sure that all three of these pointer need to be set to zero
  93. // on print server's dc. ppSubUFIHash certainly has to (tessiew).
  94. pldc->ppUFIHash = pldc->ppDVUFIHash = pldc->ppSubUFIHash = NULL;
  95. // initalize postscript data list.
  96. InitializeListHead(&(pldc->PSDataList));
  97. // Put pointer to DC_ATTR in LDC.
  98. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  99. if (pdca)
  100. {
  101. pdca->pvLDC = pldc;
  102. }
  103. }
  104. ASSERTGDI((offsetof(LINK,metalink ) == offsetof(METALINK16,metalink )) &&
  105. (offsetof(LINK,plinkNext) == offsetof(METALINK16,pmetalink16Next)) &&
  106. (offsetof(LINK,hobj ) == offsetof(METALINK16,hobj )) &&
  107. (offsetof(LINK,pv ) == offsetof(METALINK16,pv )),
  108. "pldcCreate - invalid structures\n");
  109. return(pldc);
  110. }
  111. /******************************Public*Routine******************************\
  112. * VOID vSetPldc()
  113. *
  114. * This is used if a we already have a pldc and want to set it in this DC.
  115. * The purpose is ResetDC since we don't know if we still have the same dcattr.
  116. *
  117. * History:
  118. * 03-Aug-1995 -by- Eric Kutter [erick]
  119. * Wrote it.
  120. \**************************************************************************/
  121. VOID vSetPldc(
  122. HDC hdc,
  123. PLDC pldc)
  124. {
  125. PDC_ATTR pdca;
  126. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  127. if (pdca)
  128. {
  129. pdca->pvLDC = pldc;
  130. }
  131. if (pldc)
  132. {
  133. pldc->hdc = hdc;
  134. }
  135. }
  136. /******************************Public*Routine******************************\
  137. * bDeleteLDC()
  138. *
  139. * History:
  140. * 25-Jan-1995 -by- Eric Kutter [erick]
  141. * Wrote it.
  142. \**************************************************************************/
  143. BOOL bDeleteLDC(
  144. PLDC pldc
  145. )
  146. {
  147. if (pldc->pDevMode)
  148. {
  149. LOCALFREE(pldc->pDevMode);
  150. }
  151. if (pldc->hEMFSpool)
  152. {
  153. DeleteEMFSpoolData(pldc);
  154. }
  155. if (pldc->dwSizeOfPSDataToRecord)
  156. {
  157. PPS_INJECTION_DATA pPSData;
  158. PLIST_ENTRY p = pldc->PSDataList.Flink;
  159. while(p != &(pldc->PSDataList))
  160. {
  161. // get pointer to this cell.
  162. pPSData = CONTAINING_RECORD(p,PS_INJECTION_DATA,ListEntry);
  163. // get pointer to next cell.
  164. p = p->Flink;
  165. // free this cell.
  166. LOCALFREE(pPSData);
  167. }
  168. }
  169. LocalFree(pldc);
  170. return(TRUE);
  171. }
  172. /******************************Public*Routine******************************\
  173. * GdiCleanCacheDC (hdcLocal) *
  174. * *
  175. * Resets the state of a cached DC, but has no effect on an OWNDC. *
  176. * Should be called by WOW when the app calls ReleaseDC. *
  177. * *
  178. * History: *
  179. * Sat 30-Jan-1993 11:49:12 -by- Charles Whitmer [chuckwh] *
  180. * Wrote it. *
  181. \**************************************************************************/
  182. BOOL GdiCleanCacheDC(HDC hdc)
  183. {
  184. // Validate the call. It must be a direct display DC.
  185. if (IS_ALTDC_TYPE(hdc))
  186. {
  187. GdiSetLastError(ERROR_INVALID_HANDLE);
  188. return(FALSE);
  189. }
  190. // any other dc doesn't really matter.
  191. return(TRUE);
  192. }
  193. /******************************Public*Routine******************************\
  194. * GdiConvertAndCheckDC
  195. *
  196. * Private entry point for USER's drawing routine. This function differs
  197. * from GdiConvertDC in that it also does printing specific things for the
  198. * given dc. This is for APIs that apps can use for printing.
  199. *
  200. * History:
  201. * 14-Apr-1992 -by- Wendy Wu [wendywu]
  202. * Wrote it.
  203. \**************************************************************************/
  204. HDC GdiConvertAndCheckDC(HDC hdc)
  205. {
  206. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  207. {
  208. PLDC pldc;
  209. DC_PLDC(hdc,pldc,(HDC)0);
  210. if (pldc->fl & LDC_SAP_CALLBACK)
  211. vSAPCallback(pldc);
  212. if (pldc->fl & LDC_DOC_CANCELLED)
  213. return(FALSE);
  214. if (pldc->fl & LDC_CALL_STARTPAGE)
  215. StartPage(hdc);
  216. }
  217. return(hdc);
  218. }
  219. /******************************Public*Routine******************************\
  220. * GdiIsMetaFileDC
  221. *
  222. * History:
  223. * 02-12-92 mikeke Created
  224. \**************************************************************************/
  225. BOOL GdiIsMetaFileDC(HDC hdc)
  226. {
  227. BOOL b = FALSE;
  228. if (IS_ALTDC_TYPE(hdc))
  229. {
  230. if (IS_METADC16_TYPE(hdc))
  231. {
  232. b = TRUE;
  233. }
  234. else
  235. {
  236. PLDC pldc;
  237. DC_PLDC(hdc,pldc,FALSE);
  238. if (pldc->iType == LO_METADC)
  239. b = TRUE;
  240. }
  241. }
  242. return(b);
  243. }
  244. /******************************Public*Routine******************************\
  245. *
  246. * GdiIsMetaPrintDC
  247. *
  248. * Tests whether the given DC is a metafile-spooled printer DC
  249. *
  250. * History:
  251. * Fri Jun 16 12:00:11 1995 -by- Drew Bliss [drewb]
  252. * Created
  253. *
  254. \**************************************************************************/
  255. BOOL APIENTRY GdiIsMetaPrintDC(HDC hdc)
  256. {
  257. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  258. {
  259. PLDC pldc;
  260. DC_PLDC(hdc, pldc, FALSE);
  261. return (pldc->fl & LDC_META_PRINT) != 0;
  262. }
  263. return FALSE;
  264. }
  265. /**************************************************************************\
  266. *
  267. * WINBUG #82862 2-7-2000 bhouse Possible cleanup of stubs
  268. *
  269. * Old Comment:
  270. * Client stubs for USER that do things with handles and caching. They are
  271. * now NOP's and should be removed from USER as soon as this stuff is part
  272. * of the main build.
  273. *
  274. \**************************************************************************/
  275. HDC GdiConvertDC(HDC hdc)
  276. {
  277. FIXUP_HANDLEZ(hdc);
  278. return(hdc);
  279. }
  280. HFONT GdiConvertFont(HFONT hfnt)
  281. {
  282. FIXUP_HANDLEZ(hfnt);
  283. return(hfnt);
  284. }
  285. BOOL GdiValidateHandle(HANDLE hObj)
  286. {
  287. UINT uiIndex;
  288. if (hObj == NULL)
  289. return(TRUE);
  290. uiIndex = HANDLE_TO_INDEX(hObj);
  291. if (uiIndex < MAX_HANDLE_COUNT)
  292. {
  293. PENTRY pentry = &pGdiSharedHandleTable[uiIndex];
  294. if ((pentry->FullUnique == (USHORT)((ULONG_PTR)hObj >> 16)) &&
  295. ((OBJECTOWNER_PID(pentry->ObjectOwner) == gW32PID) ||
  296. (OBJECTOWNER_PID(pentry->ObjectOwner) == 0))
  297. )
  298. {
  299. return(TRUE);
  300. }
  301. }
  302. WARNING1("GdiValidateHandle: Bad handle\n");
  303. return(FALSE);
  304. }
  305. HFONT GdiGetLocalFont(HFONT hfntRemote)
  306. {
  307. return(hfntRemote);
  308. }
  309. HBRUSH GdiGetLocalBrush(HBRUSH hbrushRemote)
  310. {
  311. return(hbrushRemote);
  312. }
  313. HANDLE META WINAPI SelectBrushLocal(HDC hdc,HANDLE h)
  314. {
  315. return(h);
  316. }
  317. HANDLE META WINAPI SelectFontLocal(HDC hdc,HANDLE h)
  318. {
  319. return(h);
  320. }
  321. BOOL GdiSetAttrs(HDC hdc)
  322. {
  323. hdc;
  324. return(TRUE);
  325. }
  326. HBITMAP GdiConvertBitmap(HBITMAP hbm)
  327. {
  328. FIXUP_HANDLEZ(hbm);
  329. return(hbm);
  330. }
  331. HBRUSH GdiConvertBrush(HBRUSH hbrush)
  332. {
  333. FIXUP_HANDLEZ(hbrush);
  334. return (hbrush);
  335. }
  336. HPALETTE GdiConvertPalette(HPALETTE hpal)
  337. {
  338. FIXUP_HANDLEZ(hpal);
  339. return(hpal);
  340. }
  341. HRGN GdiConvertRegion(HRGN hrgn)
  342. {
  343. FIXUP_HANDLEZ(hrgn);
  344. return(hrgn);
  345. }
  346. void APIENTRY GdiSetServerAttr(HDC hdc, PVOID pattr)
  347. {
  348. hdc;
  349. pattr;
  350. }
  351. /******************************Public*Routine******************************\
  352. * plfCreateLOCALFONT (fl)
  353. *
  354. * Allocates a LOCALFONT. Actually pulls one from a preallocated pool.
  355. * Does simple initialization.
  356. *
  357. * WARNING: This routines assume that the caller has grabbed semLocal
  358. *
  359. * Sun 10-Jan-1993 01:46:12 -by- Charles Whitmer [chuckwh]
  360. * Wrote it.
  361. \**************************************************************************/
  362. #define LF_ALLOCCOUNT 10
  363. LOCALFONT *plfFreeListLOCALFONT = (LOCALFONT *) NULL;
  364. LOCALFONT *plfCreateLOCALFONT(FLONG fl)
  365. {
  366. LOCALFONT *plf;
  367. // Try to get one off the free list.
  368. plf = plfFreeListLOCALFONT;
  369. if (plf != (LOCALFONT *) NULL)
  370. {
  371. plfFreeListLOCALFONT = *((LOCALFONT **) plf);
  372. }
  373. // Otherwise expand the free list.
  374. else
  375. {
  376. plf = (LOCALFONT *) LOCALALLOC(LF_ALLOCCOUNT * sizeof(LOCALFONT));
  377. if (plf != (LOCALFONT *) NULL)
  378. {
  379. int ii;
  380. // Link all the new ones into the free list.
  381. *((LOCALFONT **) plf) = (LOCALFONT *) NULL;
  382. plf++;
  383. for (ii=0; ii<LF_ALLOCCOUNT-2; ii++,plf++)
  384. *((LOCALFONT **) plf) = plf-1;
  385. plfFreeListLOCALFONT = plf-1;
  386. // Keep the last one for us!
  387. }
  388. else
  389. {
  390. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  391. }
  392. }
  393. if (plf != (LOCALFONT *) NULL)
  394. {
  395. plf->fl = fl;
  396. plf->pcf = (CFONT *) NULL;
  397. }
  398. return(plf);
  399. }
  400. /******************************Public*Routine******************************\
  401. * vDeleteLOCALFONT (plf) *
  402. * *
  403. * Frees a LOCALFONT after unreferencing any CFONTs it points to. *
  404. * *
  405. * Sun 10-Jan-1993 02:27:50 -by- Charles Whitmer [chuckwh] *
  406. * Wrote it. *
  407. \**************************************************************************/
  408. VOID vDeleteLOCALFONT(LOCALFONT *plf)
  409. {
  410. ASSERTGDI(plf != (LOCALFONT *) NULL,"Trying to free NULL LOCALFONT.\n");
  411. ENTERCRITICALSECTION(&semLocal);
  412. {
  413. CFONT *pcf;
  414. pcf = plf->pcf;
  415. // Walk the CFONT list and delallocate those CFONTs not in use.
  416. // put those which are in use back on the global CFONT delete list.
  417. while( pcf != (CFONT*) NULL )
  418. {
  419. ASSERTGDI(!(pcf->fl & CFONT_PUBLIC),"vDeleteLocalFont - public font error\n");
  420. if( pcf->cRef )
  421. {
  422. // this CFONT is in use so we'll put it on the global
  423. // delete list and free it later.
  424. CFONT *pcfTmp = pcf->pcfNext;
  425. #if DBG
  426. DbgPrint("\n\nvDeleteLOCALFONT: CFONT in use putting on delete list, cRef = %ld, hf = %lx.\n",pcf->cRef, pcf->hf);
  427. #endif
  428. pcf->pcfNext = pcfDeleteList;
  429. pcfDeleteList = pcf;
  430. pcf = pcfTmp;
  431. }
  432. else
  433. {
  434. CFONT *pcfTmp;
  435. pcfTmp = pcf->pcfNext;
  436. vFreeCFONTCrit(pcf);
  437. pcf = pcfTmp;
  438. }
  439. }
  440. *((LOCALFONT **) plf) = plfFreeListLOCALFONT;
  441. plfFreeListLOCALFONT = plf;
  442. }
  443. LEAVECRITICALSECTION(&semLocal);
  444. }
  445. /******************************Public*Routine******************************\
  446. * bLoadSpooler()
  447. *
  448. * This function loads the spooler and gets the address's of all routines
  449. * GDI calls in the spooler. This should be called the first time the
  450. * spooler is needed.
  451. *
  452. * History:
  453. * 09-Aug-1994 -by- Eric Kutter [erick]
  454. * Wrote it.
  455. \**************************************************************************/
  456. HINSTANCE ghSpooler = NULL;
  457. FPSTARTDOCDLGW fpStartDocDlgW;
  458. FPOPENPRINTERW fpOpenPrinterW;
  459. FPRESETPRINTERW fpResetPrinterW;
  460. FPCLOSEPRINTER fpClosePrinter;
  461. FPGETPRINTERW fpGetPrinterW;
  462. FPGETPRINTERDRIVERW fpGetPrinterDriverW;
  463. FPENDDOCPRINTER fpEndDocPrinter;
  464. FPENDPAGEPRINTER fpEndPagePrinter;
  465. FPREADPRINTER fpReadPrinter;
  466. FPSPLREADPRINTER fpSplReadPrinter;
  467. FPSTARTDOCPRINTERW fpStartDocPrinterW;
  468. FPSTARTPAGEPRINTER fpStartPagePrinter;
  469. FPABORTPRINTER fpAbortPrinter;
  470. PFNDOCUMENTEVENT fpDocumentEvent;
  471. FPQUERYSPOOLMODE fpQuerySpoolMode;
  472. FPQUERYREMOTEFONTS fpQueryRemoteFonts;
  473. FPSEEKPRINTER fpSeekPrinter;
  474. FPQUERYCOLORPROFILE fpQueryColorProfile;
  475. FPSPLDRIVERUNLOADCOMPLETE fpSplDriverUnloadComplete;
  476. FPGETSPOOLFILEHANDLE fpGetSpoolFileHandle;
  477. FPCOMMITSPOOLDATA fpCommitSpoolData;
  478. FPCLOSESPOOLFILEHANDLE fpCloseSpoolFileHandle;
  479. FPDOCUMENTPROPERTIESW fpDocumentPropertiesW;
  480. FPLOADSPLWOW64 fpLoadSplWow64;
  481. FPISVALIDDEVMODEW fpIsValidDevmodeW;
  482. BOOL bLoadSpooler()
  483. {
  484. if (ghSpooler != NULL)
  485. WARNING("spooler already loaded\n");
  486. ENTERCRITICALSECTION(&semLocal);
  487. // make sure someone else didn't sneak in under us and load it.
  488. if (ghSpooler == NULL)
  489. {
  490. HANDLE hSpooler = LoadLibraryW(L"winspool.drv");
  491. if (hSpooler != NULL)
  492. {
  493. #define GETSPOOLERPROC_(type, procname) \
  494. fp##procname = (type) GetProcAddress(hSpooler, #procname)
  495. GETSPOOLERPROC_(FPSTARTDOCDLGW, StartDocDlgW);
  496. GETSPOOLERPROC_(FPOPENPRINTERW, OpenPrinterW);
  497. GETSPOOLERPROC_(FPRESETPRINTERW, ResetPrinterW);
  498. GETSPOOLERPROC_(FPCLOSEPRINTER, ClosePrinter);
  499. GETSPOOLERPROC_(FPGETPRINTERW, GetPrinterW);
  500. GETSPOOLERPROC_(FPGETPRINTERDRIVERW, GetPrinterDriverW);
  501. GETSPOOLERPROC_(FPENDDOCPRINTER, EndDocPrinter);
  502. GETSPOOLERPROC_(FPENDPAGEPRINTER, EndPagePrinter);
  503. GETSPOOLERPROC_(FPREADPRINTER, ReadPrinter);
  504. GETSPOOLERPROC_(FPSTARTDOCPRINTERW, StartDocPrinterW);
  505. GETSPOOLERPROC_(FPSTARTPAGEPRINTER, StartPagePrinter);
  506. GETSPOOLERPROC_(FPABORTPRINTER, AbortPrinter);
  507. GETSPOOLERPROC_(PFNDOCUMENTEVENT, DocumentEvent);
  508. GETSPOOLERPROC_(FPQUERYSPOOLMODE, QuerySpoolMode);
  509. GETSPOOLERPROC_(FPQUERYREMOTEFONTS, QueryRemoteFonts);
  510. GETSPOOLERPROC_(FPSEEKPRINTER, SeekPrinter);
  511. GETSPOOLERPROC_(FPQUERYCOLORPROFILE, QueryColorProfile);
  512. GETSPOOLERPROC_(FPSPLDRIVERUNLOADCOMPLETE, SplDriverUnloadComplete);
  513. GETSPOOLERPROC_(FPDOCUMENTPROPERTIESW, DocumentPropertiesW);
  514. fpLoadSplWow64 = (FPLOADSPLWOW64) GetProcAddress(hSpooler, (LPCSTR) MAKELPARAM(224, 0));
  515. GETSPOOLERPROC_(FPISVALIDDEVMODEW, IsValidDevmodeW);
  516. #ifdef EMULATE_SPOOLFILE_INTERFACE
  517. fpGetSpoolFileHandle = GetSpoolFileHandle;
  518. fpCommitSpoolData = CommitSpoolData;
  519. fpCloseSpoolFileHandle = CloseSpoolFileHandle;
  520. #else
  521. GETSPOOLERPROC_(FPGETSPOOLFILEHANDLE, GetSpoolFileHandle);
  522. GETSPOOLERPROC_(FPCOMMITSPOOLDATA, CommitSpoolData);
  523. GETSPOOLERPROC_(FPCLOSESPOOLFILEHANDLE, CloseSpoolFileHandle);
  524. #endif
  525. fpSplReadPrinter = (FPSPLREADPRINTER)GetProcAddress(hSpooler, (LPCSTR) MAKELPARAM(205, 0));
  526. if (! fpStartDocDlgW ||
  527. ! fpOpenPrinterW ||
  528. ! fpResetPrinterW ||
  529. ! fpClosePrinter ||
  530. ! fpGetPrinterW ||
  531. ! fpGetPrinterDriverW ||
  532. ! fpEndDocPrinter ||
  533. ! fpEndPagePrinter ||
  534. ! fpReadPrinter ||
  535. ! fpSplReadPrinter ||
  536. ! fpStartDocPrinterW ||
  537. ! fpStartPagePrinter ||
  538. ! fpAbortPrinter ||
  539. ! fpDocumentEvent ||
  540. ! fpQuerySpoolMode ||
  541. ! fpQueryRemoteFonts ||
  542. ! fpSeekPrinter ||
  543. ! fpQueryColorProfile ||
  544. ! fpSplDriverUnloadComplete ||
  545. ! fpGetSpoolFileHandle ||
  546. ! fpCommitSpoolData ||
  547. ! fpCloseSpoolFileHandle ||
  548. ! fpDocumentPropertiesW ||
  549. ! fpLoadSplWow64 ||
  550. ! fpIsValidDevmodeW)
  551. {
  552. FreeLibrary(hSpooler);
  553. hSpooler = NULL;
  554. }
  555. ghSpooler = hSpooler;
  556. }
  557. }
  558. LEAVECRITICALSECTION(&semLocal);
  559. if (ghSpooler == NULL)
  560. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  561. return(ghSpooler != NULL);
  562. }
  563. /******************************Public*Routine******************************\
  564. * GdiGetLocalDC
  565. *
  566. * Arguments:
  567. *
  568. * hdc - handle to dc
  569. *
  570. * Return Value:
  571. *
  572. * same DC or NULL for failure
  573. *
  574. \**************************************************************************/
  575. HDC
  576. GdiGetLocalDC(HDC hdc)
  577. {
  578. return(hdc);
  579. }
  580. /******************************Public*Routine******************************\
  581. * GdiDeleteLocalDC
  582. *
  583. * Free client DC_ATTR regardless of reference count
  584. *
  585. * Arguments:
  586. *
  587. * hdc
  588. *
  589. * Return Value:
  590. *
  591. * Status
  592. *
  593. * History:
  594. *
  595. * 04-May-1995 -by- Mark Enstrom [marke]
  596. *
  597. \**************************************************************************/
  598. BOOL GdiDeleteLocalDC(HDC hdc)
  599. {
  600. return(TRUE);
  601. }
  602. /******************************Public*Routine******************************\
  603. * GdiReleaseLocalDC
  604. *
  605. * Routine Description:
  606. *
  607. * When the reference count of DC_ATTR drops to zero, free it
  608. *
  609. * Arguments:
  610. *
  611. * hdc - DC handle
  612. *
  613. * Return Value:
  614. *
  615. * BOOL status
  616. *
  617. * History:
  618. *
  619. * 02-May-1995 -by- Mark Enstrom [marke]
  620. *
  621. \**************************************************************************/
  622. BOOL GdiReleaseLocalDC(HDC hdc)
  623. {
  624. #if DBG
  625. DbgPrint("Error, call to GdiReleaseLocalDC\n");
  626. DbgBreakPoint();
  627. #endif
  628. return(TRUE);
  629. }
  630. /******************************Public*Routine******************************\
  631. * GdiFixUpHandle()
  632. *
  633. * given a handle with the high word 0'd, return the actual handle
  634. *
  635. * History:
  636. * 16-Feb-1995 -by- Eric Kutter [erick]
  637. * Wrote it.
  638. \**************************************************************************/
  639. HANDLE GdiFixUpHandle(
  640. HANDLE h)
  641. {
  642. HANDLE hNew = NULL;
  643. if ((((ULONG_PTR)h & FULLUNIQUE_MASK) == 0) && ((ULONG_PTR)h < MAX_HANDLE_COUNT))
  644. {
  645. hNew = (HANDLE)MAKE_HMGR_HANDLE((ULONG)(ULONG_PTR)h,pGdiSharedHandleTable[(ULONG_PTR)h].FullUnique);
  646. }
  647. return(hNew);
  648. }
  649. /******************************Public*Routine******************************\
  650. * DoRip()
  651. *
  652. * go to the user mode debugger in checked builds
  653. *
  654. * Effects:
  655. *
  656. * Warnings:
  657. * Leave this enabled in case efloat.lib needs it.
  658. * efloat.lib uses gre\engine.h's ASSERTGDI macro.
  659. *
  660. * History:
  661. * 09-Aug-1994 -by- Eric Kutter [erick]
  662. * Wrote it.
  663. \**************************************************************************/
  664. VOID DoRip(PSZ psz)
  665. {
  666. DbgPrint("GDI Assertion Failure: ");
  667. DbgPrint(psz);
  668. DbgPrint("\n");
  669. DbgBreakPoint();
  670. }
  671. /******************************Public*Routine******************************\
  672. * DoIDRip()
  673. *
  674. * go to the user mode debugger in checked builds
  675. *
  676. * Effects:
  677. *
  678. * Warnings:
  679. * Leave this enabled in case efloat.lib needs it.
  680. * efloat.lib uses gre\engine.h's ASSERTGDI macro.
  681. *
  682. * History:
  683. * 31-Aug-2000 -by- Jason Hartman [jasonha]
  684. * Wrote it.
  685. \**************************************************************************/
  686. VOID DoIDRip(PCSTR ID, PSZ psz)
  687. {
  688. DbgPrint("GDI Assertion Failure: ");
  689. if (ID)
  690. {
  691. DbgPrint((PCH)ID);
  692. DbgPrint(": ");
  693. }
  694. DbgPrint(psz);
  695. DbgPrint("\n");
  696. DbgBreakPoint();
  697. }
  698. DWORD
  699. GetFileMappingAlignment()
  700. /*++
  701. Routine Description:
  702. Alignment for file mapping starting offset
  703. Arguments:
  704. NONE
  705. Return Value:
  706. see above
  707. --*/
  708. {
  709. static DWORD alignment = 0;
  710. if (alignment == 0)
  711. {
  712. SYSTEM_INFO sysinfo;
  713. //
  714. // Set file mapping alignment for EMF spool file to
  715. // the system memory allocation granularity
  716. //
  717. GetSystemInfo(&sysinfo);
  718. alignment = sysinfo.dwAllocationGranularity;
  719. }
  720. return alignment;
  721. }
  722. DWORD
  723. GetSystemPageSize()
  724. /*++
  725. Routine Description:
  726. Returns the page size for the current system
  727. Arguments:
  728. NONE
  729. Return Value:
  730. see above
  731. --*/
  732. {
  733. static DWORD pagesize = 0;
  734. if (pagesize == 0)
  735. {
  736. SYSTEM_INFO sysinfo;
  737. GetSystemInfo(&sysinfo);
  738. pagesize = sysinfo.dwPageSize;
  739. }
  740. return pagesize;
  741. }
  742. VOID
  743. CopyMemoryToMemoryMappedFile(
  744. PVOID Destination,
  745. CONST VOID *Source,
  746. DWORD Length
  747. )
  748. /*++
  749. Routine Description:
  750. Copy data into memory-mapped file (assuming mostly sequential access pattern)
  751. Arguments:
  752. Destination - Points to destination buffer
  753. Source - Points to source buffer
  754. Length - Number of bytes to be copied
  755. Return Value:
  756. NONE
  757. --*/
  758. {
  759. PBYTE dst = (PBYTE) Destination;
  760. PBYTE src = (PBYTE) Source;
  761. DWORD alignment = GetFileMappingAlignment();
  762. DWORD count;
  763. //
  764. // Copy the initial portion so that the destination buffer
  765. // pointer is properly aligned
  766. //
  767. count = (DWORD) ((ULONG_PTR) dst % alignment);
  768. if (count != 0)
  769. {
  770. count = min(alignment-count, Length);
  771. RtlCopyMemory(dst, src, count);
  772. Length -= count;
  773. dst += count;
  774. src += count;
  775. }
  776. //
  777. // Copy the middle portion in 64KB chunks
  778. //
  779. count = Length / alignment;
  780. Length -= count * alignment;
  781. while (count--)
  782. {
  783. RtlCopyMemory(dst, src, alignment);
  784. VirtualUnlock(dst, alignment);
  785. dst += alignment;
  786. src += alignment;
  787. }
  788. //
  789. // Finish up the remaining portion
  790. //
  791. if (Length > 0)
  792. RtlCopyMemory(dst, src, Length);
  793. }