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.

8584 lines
211 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: priv.c
  3. * This file contains stubs for calls made by USERSRVL
  4. *
  5. * Created: 01-Nov-1994 07:45:35
  6. * Author: Eric Kutter [erick]
  7. *
  8. * Copyright (c) 1993-1999 Microsoft Corporation
  9. *
  10. \**************************************************************************/
  11. #include "engine.h"
  12. #include "winfont.h"
  13. #include "server.h"
  14. #include "dciddi.h"
  15. #include "limits.h"
  16. #include "drvsup.hxx"
  17. #ifdef DBGEXCEPT
  18. int bStopExcept = FALSE;
  19. int bWarnExcept = FALSE;
  20. #endif
  21. #define DWORD_TO_FLOAT(dw) (*(PFLOAT)(PDWORD)&(dw))
  22. #define DWORD_TO_FLOATL(dw) (*(FLOATL *)(PDWORD)&(dw))
  23. typedef struct {
  24. ULONG uM11;
  25. ULONG uM12;
  26. ULONG uM21;
  27. ULONG uM22;
  28. ULONG uDx;
  29. ULONG uDy;
  30. } ULONGXFORM, *PULONGXFORM;
  31. VOID ProbeAndWriteBuffer(PVOID Dst, PVOID Src, ULONG Length)
  32. {
  33. if (((ULONG_PTR)Dst + Length <= (ULONG_PTR)Dst) ||
  34. ((ULONG_PTR)Dst + Length > (ULONG_PTR)MM_USER_PROBE_ADDRESS)) {
  35. *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0;
  36. }
  37. RtlCopyMemory(Dst, Src, Length);
  38. return;
  39. }
  40. VOID ProbeAndWriteAlignedBuffer(PVOID Dst, PVOID Src, ULONG Length, ULONG Alignment)
  41. {
  42. ASSERT(((Alignment) == 1) || ((Alignment) == 2) ||
  43. ((Alignment) == 4) || ((Alignment) == 8) ||
  44. ((Alignment) == 16));
  45. if (((ULONG_PTR)Dst + Length <= (ULONG_PTR)Dst) ||
  46. ((ULONG_PTR)Dst + Length > (ULONG_PTR) MM_USER_PROBE_ADDRESS) ||
  47. ((((ULONG_PTR)Dst) & (Alignment - 1)) != 0)) {
  48. *(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0;
  49. }
  50. RtlCopyMemory(Dst, Src, Length);
  51. return;
  52. }
  53. /******************************Public*Routine******************************\
  54. * bConvertDwordToFloat
  55. *
  56. * This routine casts a DWORD to a float, and checks whether the float
  57. * is valid (on the Alpha). This is accomplished by doing a floating
  58. * point operation and catching the exception if one is generated.
  59. *
  60. * Arguments:
  61. *
  62. * dword - the float before the cast
  63. * *floatl - a pointer to a float that will receive the value after the
  64. * cast
  65. *
  66. * Return Value:
  67. *
  68. * TRUE for valid floats, FALSE otherwise.
  69. *
  70. * History:
  71. *
  72. * 13-May-1998 -by- Ori Gershony [OriG]
  73. *
  74. \**************************************************************************/
  75. BOOL
  76. bConvertDwordToFloat(
  77. DWORD dword,
  78. FLOATL *floatl
  79. )
  80. {
  81. BOOL bRet=TRUE;
  82. try
  83. {
  84. *floatl = DWORD_TO_FLOATL(dword);
  85. }
  86. except(EXCEPTION_EXECUTE_HANDLER)
  87. {
  88. bRet = FALSE;
  89. }
  90. return bRet;
  91. }
  92. /******************************Public*Routine******************************\
  93. *
  94. * ProbeAndConvertXFORM
  95. *
  96. * This routine probe and copy a user mode xform into kernel mode address,
  97. * At the same time, it checks if the each FLOAT in the XFORM is valid, to prevent
  98. * us to get into a floating point trap on ALPHA. Refer to bConvertDwordToFloat
  99. * for more info.
  100. *
  101. * History:
  102. * 11/24/98 by Lingyun Wang [lingyunw]
  103. * Wrote it.
  104. \**************************************************************************/
  105. BOOL
  106. ProbeAndConvertXFORM(
  107. XFORML *kpXform,
  108. XFORML *pXform
  109. )
  110. {
  111. BOOL bRet=TRUE;
  112. try
  113. {
  114. ULONGXFORM *pUXform = (ULONGXFORM *)kpXform;
  115. ProbeForRead(pUXform, sizeof(ULONGXFORM), sizeof(BYTE));
  116. bRet = (bConvertDwordToFloat (pUXform->uM11, &(pXform->eM11))) &&
  117. (bConvertDwordToFloat (pUXform->uM12, &(pXform->eM12))) &&
  118. (bConvertDwordToFloat (pUXform->uM21, &(pXform->eM21))) &&
  119. (bConvertDwordToFloat (pUXform->uM22, &(pXform->eM22))) &&
  120. (bConvertDwordToFloat (pUXform->uDx, &(pXform->eDx))) &&
  121. (bConvertDwordToFloat (pUXform->uDy, &(pXform->eDy)));
  122. }
  123. except(EXCEPTION_EXECUTE_HANDLER)
  124. {
  125. bRet = FALSE;
  126. }
  127. return bRet;
  128. }
  129. /******************************Public*Routine******************************\
  130. *
  131. * NtGdiGetCharacterPlacementW
  132. *
  133. * History:
  134. * 26-Jul-1995 -by- Bodin Dresevic [BodinD]
  135. * Wrote it.
  136. \**************************************************************************/
  137. #define ALIGN4(X) (((X) + 3) & ~3)
  138. DWORD NtGdiGetCharacterPlacementW(
  139. HDC hdc,
  140. LPWSTR pwsz,
  141. int nCount,
  142. int nMaxExtent,
  143. LPGCP_RESULTSW pgcpw,
  144. DWORD dwFlags
  145. )
  146. {
  147. DWORD dwRet = 0;
  148. BOOL bOk = TRUE; // only change is something goes wrong
  149. LPWSTR pwszTmp = NULL; // probe for read
  150. ULONG cjW = 0;
  151. ULONG dpOutString = 0;
  152. ULONG dpOrder = 0;
  153. ULONG dpDx = 0;
  154. ULONG dpCaretPos = 0;
  155. ULONG dpClass = 0;
  156. ULONG dpGlyphs = 0;
  157. DWORD cjWord, cjDword;
  158. LPGCP_RESULTSW pgcpwTmp = NULL;
  159. VOID *pv = NULL;
  160. // it is much easier to structure the code if we copy pgcpw locally
  161. // at the beginning.
  162. GCP_RESULTSW gcpwLocal;
  163. // valitidy checking
  164. if ((nCount < 0) || ((nMaxExtent < 0) && (nMaxExtent != -1)) || !pwsz)
  165. {
  166. return dwRet;
  167. }
  168. if (pgcpw)
  169. {
  170. try
  171. {
  172. // we are eventually going to want to write to this structure
  173. // so we will do ProbeForWrite now, which will probe the structure
  174. // for both writing and reading. Otherwise, at this time
  175. // ProbeForRead would suffice.
  176. ProbeForWrite(pgcpw, sizeof(GCP_RESULTSW), sizeof(DWORD));
  177. gcpwLocal = *pgcpw;
  178. // take nCount to be the smaller of the nCounts and gcpwLocal.nGlyphs
  179. // Win 95 does the same thing [bodind]
  180. if (nCount > (int)gcpwLocal.nGlyphs)
  181. nCount = (int)gcpwLocal.nGlyphs;
  182. }
  183. except(EXCEPTION_EXECUTE_HANDLER)
  184. {
  185. WARNINGX(1);
  186. return dwRet;
  187. }
  188. }
  189. // Check for overflow of cjByte, cjWord, and cjDword (cjByte is implicit
  190. // in handling of gcpwLocal.lpClass case below).
  191. if (nCount > (MAXIMUM_POOL_ALLOC / sizeof(DWORD)))
  192. {
  193. return dwRet;
  194. }
  195. cjWord = (DWORD)nCount * sizeof(WCHAR);
  196. cjDword = (DWORD)nCount * sizeof(DWORD);
  197. // if pgcpw != NULL, pgcpw may contain some input data and it may
  198. // point to some output data.
  199. if (pgcpw)
  200. {
  201. cjW = sizeof(GCP_RESULTSW);
  202. if (gcpwLocal.lpOutString)
  203. {
  204. dpOutString = cjW;
  205. cjW += ALIGN4(cjWord);
  206. if (cjW < dpOutString)
  207. return dwRet;
  208. }
  209. if (gcpwLocal.lpOrder)
  210. {
  211. dpOrder = cjW;
  212. cjW += cjDword;
  213. if (cjW < dpOrder)
  214. return dwRet;
  215. }
  216. if (gcpwLocal.lpDx)
  217. {
  218. dpDx = cjW;
  219. cjW += cjDword;
  220. if (cjW < dpDx)
  221. return dwRet;
  222. }
  223. if (gcpwLocal.lpCaretPos)
  224. {
  225. dpCaretPos = cjW;
  226. cjW += cjDword;
  227. if (cjW < dpCaretPos)
  228. return dwRet;
  229. }
  230. if (gcpwLocal.lpClass)
  231. {
  232. dpClass = cjW;
  233. cjW += ALIGN4(sizeof(char) * nCount);
  234. if (cjW < dpClass)
  235. return dwRet;
  236. }
  237. if (gcpwLocal.lpGlyphs)
  238. {
  239. dpGlyphs = cjW;
  240. cjW += cjWord;
  241. if (cjW < dpGlyphs)
  242. return dwRet;
  243. }
  244. }
  245. // alloc mem for gcpw and the string
  246. if (cjW <= (MAXIMUM_POOL_ALLOC - cjWord))
  247. pv = AllocFreeTmpBuffer(cjW + cjWord);
  248. if (pv)
  249. {
  250. pwszTmp = (WCHAR*)((BYTE*)pv + cjW);
  251. if (pgcpw)
  252. {
  253. pgcpwTmp = (LPGCP_RESULTSW)pv;
  254. if (gcpwLocal.lpOutString)
  255. pgcpwTmp->lpOutString = (LPWSTR)((BYTE *)pgcpwTmp + dpOutString);
  256. else
  257. pgcpwTmp->lpOutString = NULL;
  258. if (gcpwLocal.lpOrder)
  259. pgcpwTmp->lpOrder = (UINT FAR*)((BYTE *)pgcpwTmp + dpOrder);
  260. else
  261. pgcpwTmp->lpOrder = NULL;
  262. if (gcpwLocal.lpDx)
  263. pgcpwTmp->lpDx = (int FAR *)((BYTE *)pgcpwTmp + dpDx);
  264. else
  265. pgcpwTmp->lpDx = NULL;
  266. if (gcpwLocal.lpCaretPos)
  267. pgcpwTmp->lpCaretPos = (int FAR *)((BYTE *)pgcpwTmp + dpCaretPos);
  268. else
  269. pgcpwTmp->lpCaretPos = NULL;
  270. if (gcpwLocal.lpClass)
  271. pgcpwTmp->lpClass = (LPSTR)((BYTE *)pgcpwTmp + dpClass);
  272. else
  273. pgcpwTmp->lpClass = NULL;
  274. if (gcpwLocal.lpGlyphs)
  275. pgcpwTmp->lpGlyphs = (LPWSTR)((BYTE *)pgcpwTmp + dpGlyphs);
  276. else
  277. pgcpwTmp->lpGlyphs = NULL;
  278. pgcpwTmp->lStructSize = cjW;
  279. pgcpwTmp->nGlyphs = nCount;
  280. }
  281. // check the memory with input data:
  282. try
  283. {
  284. ProbeAndReadBuffer(pwszTmp, pwsz, cjWord);
  285. if ((dwFlags & GCP_JUSTIFYIN) && pgcpw && gcpwLocal.lpDx)
  286. {
  287. // must probe for read, lpDx contains input explaining which glyphs to
  288. // use as spacers for in justifying string
  289. ProbeAndReadBuffer(pgcpwTmp->lpDx,gcpwLocal.lpDx, cjDword);
  290. }
  291. }
  292. except(EXCEPTION_EXECUTE_HANDLER)
  293. {
  294. WARNINGX(2);
  295. // SetLastError(GetExceptionCode());
  296. bOk = FALSE;
  297. }
  298. if (bOk)
  299. {
  300. dwRet = GreGetCharacterPlacementW(hdc, pwszTmp,(DWORD)nCount,
  301. (DWORD)nMaxExtent,
  302. pgcpwTmp, dwFlags);
  303. if (dwRet && pgcpw) // copy data out
  304. {
  305. try
  306. {
  307. // ProbeForWrite(pgcpw, sizeof(GCP_RESULTSW), sizeof(DWORD));
  308. // we did this above, see the comment
  309. pgcpw->nMaxFit = pgcpwTmp->nMaxFit;
  310. pgcpw->nGlyphs = nCount = pgcpwTmp->nGlyphs;
  311. cjWord = (DWORD)nCount * 2;
  312. cjDword = (DWORD)nCount * 4;
  313. if (gcpwLocal.lpOutString)
  314. {
  315. ProbeAndWriteBuffer(gcpwLocal.lpOutString, pgcpwTmp->lpOutString,
  316. cjWord);
  317. }
  318. if (gcpwLocal.lpOrder)
  319. {
  320. ProbeAndWriteBuffer(gcpwLocal.lpOrder, pgcpwTmp->lpOrder, cjDword);
  321. }
  322. if (gcpwLocal.lpDx)
  323. {
  324. ProbeAndWriteBuffer(gcpwLocal.lpDx, pgcpwTmp->lpDx, cjDword);
  325. }
  326. if (gcpwLocal.lpCaretPos)
  327. {
  328. ProbeAndWriteBuffer(gcpwLocal.lpCaretPos, pgcpwTmp->lpCaretPos,
  329. cjDword);
  330. }
  331. if (gcpwLocal.lpClass)
  332. {
  333. ProbeAndWriteBuffer(gcpwLocal.lpClass, pgcpwTmp->lpClass, nCount);
  334. }
  335. if (gcpwLocal.lpGlyphs)
  336. {
  337. ProbeAndWriteBuffer(gcpwLocal.lpGlyphs, pgcpwTmp->lpGlyphs, cjWord);
  338. }
  339. }
  340. except(EXCEPTION_EXECUTE_HANDLER)
  341. {
  342. WARNINGX(3);
  343. // SetLastError(GetExceptionCode());
  344. bOk = FALSE;
  345. }
  346. }
  347. }
  348. FreeTmpBuffer(pv);
  349. }
  350. else
  351. {
  352. bOk = FALSE;
  353. }
  354. return (bOk ? dwRet : 0);
  355. }
  356. /*******************************************************************\
  357. * pbmiConvertInfo *
  358. * *
  359. * Converts BITMAPCOREHEADER into BITMAPINFOHEADER *
  360. * copies the the color table *
  361. * *
  362. * 10-1-95 -by- Lingyun Wang [lingyunw] *
  363. \******************************************************************/
  364. LPBITMAPINFO pbmiConvertInfo(CONST BITMAPINFO *pbmi, ULONG iUsage)
  365. {
  366. LPBITMAPINFO pbmiNew;
  367. ULONG cjRGB;
  368. ULONG cColorsMax;
  369. ULONG cColors;
  370. UINT uiBitCount;
  371. ULONG ulSize;
  372. RGBTRIPLE *pTri;
  373. RGBQUAD *pQuad;
  374. ASSERTGDI (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER), "bad header size\n");
  375. //
  376. // convert COREHEADER and copy color table
  377. //
  378. cjRGB = sizeof(RGBQUAD);
  379. uiBitCount = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcBitCount;
  380. //
  381. // figure out the number of entries
  382. //
  383. switch (uiBitCount)
  384. {
  385. case 1:
  386. cColorsMax = 2;
  387. break;
  388. case 4:
  389. cColorsMax = 16;
  390. break;
  391. case 8:
  392. cColorsMax = 256;
  393. break;
  394. default:
  395. if (iUsage == DIB_PAL_COLORS)
  396. {
  397. iUsage = DIB_RGB_COLORS;
  398. }
  399. cColorsMax = 0;
  400. switch (uiBitCount)
  401. {
  402. case 16:
  403. case 24:
  404. case 32:
  405. break;
  406. default:
  407. WARNING("pbmiConvertInfo failed invalid bitcount in bmi BI_RGB\n");
  408. return(0);
  409. }
  410. }
  411. cColors = cColorsMax;
  412. if (iUsage == DIB_PAL_COLORS)
  413. cjRGB = sizeof(USHORT);
  414. else if (iUsage == DIB_PAL_INDICES)
  415. cjRGB = 0;
  416. //
  417. // convert the core header
  418. //
  419. ulSize = sizeof(BITMAPINFOHEADER);
  420. pbmiNew = PALLOCNOZ(ulSize +
  421. cjRGB * cColors,'pmtG');
  422. if (pbmiNew == NULL)
  423. return (0);
  424. pbmiNew->bmiHeader.biSize = ulSize;
  425. //
  426. // copy BITMAPCOREHEADER
  427. //
  428. pbmiNew->bmiHeader.biWidth = ((BITMAPCOREHEADER *)pbmi)->bcWidth;
  429. pbmiNew->bmiHeader.biHeight = ((BITMAPCOREHEADER *)pbmi)->bcHeight;
  430. pbmiNew->bmiHeader.biPlanes = ((BITMAPCOREHEADER *)pbmi)->bcPlanes;
  431. pbmiNew->bmiHeader.biBitCount = ((BITMAPCOREHEADER *)pbmi)->bcBitCount;
  432. pbmiNew->bmiHeader.biCompression = 0;
  433. pbmiNew->bmiHeader.biSizeImage = 0;
  434. pbmiNew->bmiHeader.biXPelsPerMeter = 0;
  435. pbmiNew->bmiHeader.biYPelsPerMeter = 0;
  436. pbmiNew->bmiHeader.biClrUsed = 0;
  437. pbmiNew->bmiHeader.biClrImportant = 0;
  438. //
  439. // copy the color table
  440. //
  441. pTri = (RGBTRIPLE *)((LPBYTE)pbmi + sizeof(BITMAPCOREHEADER));
  442. pQuad = (RGBQUAD *)((LPBYTE)pbmiNew + sizeof(BITMAPINFOHEADER));
  443. //
  444. // copy RGBTRIPLE to RGBQUAD
  445. //
  446. if (iUsage != DIB_PAL_COLORS)
  447. {
  448. INT cj = cColors;
  449. while (cj--)
  450. {
  451. pQuad->rgbRed = pTri->rgbtRed;
  452. pQuad->rgbGreen = pTri->rgbtGreen;
  453. pQuad->rgbBlue = pTri->rgbtBlue;
  454. pQuad->rgbReserved = 0;
  455. pQuad++;
  456. pTri++;
  457. }
  458. }
  459. else
  460. // DIB_PAL_COLORS
  461. {
  462. RtlCopyMemory((LPBYTE)pQuad,(LPBYTE)pTri,cColors * sizeof(USHORT));
  463. }
  464. return(pbmiNew);
  465. }
  466. LPDEVMODEW
  467. CaptureDEVMODEW(
  468. LPDEVMODEW pdm
  469. )
  470. /*++
  471. Routine Description:
  472. Make a kernel-mode copy of a user-mode DEVMODEW structure
  473. Arguments:
  474. pdm - Pointer to user mode DEVMODEW structure to be copied
  475. Return Value:
  476. Pointer to kernel mode copy of DEVMODEW structure
  477. NULL if there is an error
  478. Note:
  479. This function must be called inside try/except.
  480. --*/
  481. {
  482. LPDEVMODEW pdmKm;
  483. WORD dmSize, dmDriverExtra;
  484. ULONG ulSize;
  485. ProbeForRead (pdm, offsetof(DEVMODEW, dmFields), sizeof(BYTE));
  486. dmSize = pdm->dmSize;
  487. dmDriverExtra = pdm->dmDriverExtra;
  488. ulSize = dmSize + dmDriverExtra;
  489. if ((ulSize <= offsetof(DEVMODEW, dmFields)) || BALLOC_OVERFLOW1(ulSize, BYTE))
  490. {
  491. WARNING("bad devmodew size\n");
  492. return NULL;
  493. }
  494. if ((pdmKm = PALLOCTHREADMEMNOZ(ulSize, 'pmtG')) != NULL)
  495. {
  496. try
  497. {
  498. ProbeAndReadBuffer(pdmKm, pdm, ulSize);
  499. pdmKm->dmSize = dmSize;
  500. pdmKm->dmDriverExtra = dmDriverExtra;
  501. }
  502. except(EXCEPTION_EXECUTE_HANDLER)
  503. {
  504. VFREETHREADMEM(pdmKm);
  505. pdmKm = NULL;
  506. }
  507. }
  508. else
  509. {
  510. WARNING("Memory allocation failed in CaptureDEVMODEW\n");
  511. }
  512. return pdmKm;
  513. }
  514. DRIVER_INFO_2W*
  515. CaptureDriverInfo2W(
  516. DRIVER_INFO_2W *pUmDriverInfo2
  517. )
  518. /*++
  519. Routine Description:
  520. Make a kernel-mode copy of a user-mode DRIVER_INFO_2W structure
  521. Arguments:
  522. pUmDriverInfo2 - Pointer to user mode DRIVER_INFO_2W structure
  523. Return Value:
  524. Pointer to copied kernel mode DRIVER_INFO_2W structure
  525. NULL if there is an error
  526. Note:
  527. We're not copying pEnvironment and pConfigFile fields of
  528. DRIVER_INFO_2W structure.
  529. This function must be called inside try/except.
  530. --*/
  531. {
  532. DRIVER_INFO_2W *pKmDriverInfo2;
  533. ULONG NameLen, DriverPathLen, DataFileLen, TotalSize;
  534. PWSTR pName, pDriverPath, pDataFile;
  535. ProbeForRead(pUmDriverInfo2, sizeof(DRIVER_INFO_2W), sizeof(BYTE));
  536. if ((pName = pUmDriverInfo2->pName) == NULL ||
  537. (pDriverPath = pUmDriverInfo2->pDriverPath) == NULL ||
  538. (pDataFile = pUmDriverInfo2->pDataFile) == NULL)
  539. {
  540. WARNING("Missing driver name or driver path\n");
  541. return NULL;
  542. }
  543. NameLen = wcslensafe(pName);
  544. DriverPathLen = wcslensafe(pDriverPath);
  545. TotalSize = sizeof(DRIVER_INFO_2W) +
  546. (NameLen + 1) * sizeof(WCHAR) +
  547. (DriverPathLen + 1) * sizeof(WCHAR);
  548. // pDataFile != NULL
  549. DataFileLen = wcslensafe(pDataFile);
  550. TotalSize += (DataFileLen + 1) * sizeof(WCHAR);
  551. if (BALLOC_OVERFLOW1(TotalSize, BYTE))
  552. return NULL;
  553. // Note: allocated memory is zero-initialized.
  554. pKmDriverInfo2 = (DRIVER_INFO_2W *) PALLOCTHREADMEM(TotalSize, 'pmtG');
  555. if (pKmDriverInfo2 != NULL)
  556. {
  557. __try
  558. {
  559. RtlCopyMemory(pKmDriverInfo2, pUmDriverInfo2, sizeof(DRIVER_INFO_2W));
  560. pKmDriverInfo2->pEnvironment =
  561. pKmDriverInfo2->pConfigFile = NULL;
  562. pKmDriverInfo2->pName = (PWSTR) ((PBYTE) pKmDriverInfo2 + sizeof(DRIVER_INFO_2W));
  563. pKmDriverInfo2->pDriverPath = pKmDriverInfo2->pName + (NameLen + 1);
  564. ProbeAndReadBuffer(pKmDriverInfo2->pName, pName, NameLen * sizeof(WCHAR));
  565. ProbeAndReadBuffer(pKmDriverInfo2->pDriverPath, pDriverPath, DriverPathLen * sizeof(WCHAR));
  566. pKmDriverInfo2->pDataFile = pKmDriverInfo2->pDriverPath + (DriverPathLen + 1);
  567. ProbeAndReadBuffer(pKmDriverInfo2->pDataFile, pDataFile, DataFileLen * sizeof(WCHAR));
  568. }
  569. __except(EXCEPTION_EXECUTE_HANDLER)
  570. {
  571. VFREETHREADMEM(pKmDriverInfo2);
  572. pKmDriverInfo2 = NULL;
  573. }
  574. }
  575. else
  576. {
  577. WARNING("Memory allocation failed in CaptureDriverInfo2W\n");
  578. }
  579. return pKmDriverInfo2;
  580. }
  581. __inline VOID
  582. vFreeDriverInfo2(
  583. DRIVER_INFO_2W *pKmDriverInfo2
  584. )
  585. {
  586. if (pKmDriverInfo2 != NULL)
  587. VFREETHREADMEM(pKmDriverInfo2);
  588. }
  589. /******************************Public*Routine******************************\
  590. * GreGetBitmapSize
  591. *
  592. * Returns the size of the header and the color table.
  593. *
  594. * History:
  595. * Wed 19-Aug-1992 -by- Patrick Haluptzok [patrickh]
  596. * add 16 and 32 bit support
  597. *
  598. * Wed 04-Dec-1991 -by- Patrick Haluptzok [patrickh]
  599. * Make it handle DIB_PAL_INDICES.
  600. *
  601. * Tue 08-Oct-1991 -by- Patrick Haluptzok [patrickh]
  602. * Make it handle DIB_PAL_COLORS, calculate max colors based on bpp.
  603. *
  604. * 22-Jul-1991 -by- Eric Kutter [erick]
  605. * 14-Apr-1998 FritzS Convert to Gre function for use by ntuser
  606. * Wrote it.
  607. \**************************************************************************/
  608. ULONG GreGetBitmapSize(CONST BITMAPINFO *pbmi, ULONG iUsage)
  609. {
  610. ULONG cjRet;
  611. ULONG cjHeader;
  612. ULONG cjRGB;
  613. ULONG cColorsMax;
  614. ULONG cColors;
  615. UINT uiBitCount;
  616. UINT uiPalUsed;
  617. UINT uiCompression;
  618. UINT uiHeaderSize;
  619. // check for error
  620. if (pbmi == (LPBITMAPINFO) NULL)
  621. {
  622. WARNING("GreGetBitmapSize failed - NULL pbmi\n");
  623. return(0);
  624. }
  625. uiHeaderSize = pbmi->bmiHeader.biSize;
  626. // Check for PM-style DIB
  627. if (uiHeaderSize == sizeof(BITMAPCOREHEADER))
  628. {
  629. cjHeader = sizeof(BITMAPCOREHEADER);
  630. cjRGB = sizeof(RGBTRIPLE);
  631. uiBitCount = ((LPBITMAPCOREINFO)pbmi)->bmciHeader.bcBitCount;
  632. uiPalUsed = 0;
  633. uiCompression = (UINT) BI_RGB;
  634. }
  635. else if (uiHeaderSize >= sizeof(BITMAPINFOHEADER))
  636. {
  637. cjHeader = uiHeaderSize;
  638. cjRGB = sizeof(RGBQUAD);
  639. uiBitCount = pbmi->bmiHeader.biBitCount;
  640. uiPalUsed = pbmi->bmiHeader.biClrUsed;
  641. uiCompression = (UINT) pbmi->bmiHeader.biCompression;
  642. }
  643. else
  644. {
  645. WARNING("cjBitmapHeaderSize failed - invalid header size\n");
  646. return(0);
  647. }
  648. if (uiCompression == BI_BITFIELDS)
  649. {
  650. // Handle 16 and 32 bit per pel bitmaps.
  651. if (iUsage == DIB_PAL_COLORS)
  652. {
  653. iUsage = DIB_RGB_COLORS;
  654. }
  655. switch (uiBitCount)
  656. {
  657. case 16:
  658. case 32:
  659. break;
  660. default:
  661. #if DBG
  662. DbgPrint("GreGetBitmapSize %lu\n", uiBitCount);
  663. #endif
  664. WARNING("GreGetBitmapSize failed for BI_BITFIELDS\n");
  665. return(0);
  666. }
  667. if (uiHeaderSize <= sizeof(BITMAPINFOHEADER))
  668. {
  669. uiPalUsed = cColorsMax = 3;
  670. }
  671. else
  672. {
  673. //
  674. // masks are imbedded in BITMAPV4 +
  675. //
  676. uiPalUsed = cColorsMax = 0;
  677. }
  678. }
  679. else if (uiCompression == BI_RGB)
  680. {
  681. switch (uiBitCount)
  682. {
  683. case 1:
  684. cColorsMax = 2;
  685. break;
  686. case 4:
  687. cColorsMax = 16;
  688. break;
  689. case 8:
  690. cColorsMax = 256;
  691. break;
  692. default:
  693. if (iUsage == DIB_PAL_COLORS)
  694. {
  695. iUsage = DIB_RGB_COLORS;
  696. }
  697. cColorsMax = 0;
  698. switch (uiBitCount)
  699. {
  700. case 16:
  701. case 24:
  702. case 32:
  703. break;
  704. default:
  705. WARNING("GreGetBitmapSize failed invalid bitcount in bmi BI_RGB\n");
  706. return(0);
  707. }
  708. }
  709. }
  710. else if (uiCompression == BI_CMYK)
  711. {
  712. ASSERTGDI (iUsage == DIB_RGB_COLORS, "BI_CMYK:iUsage should be DIB_RGB_COLORS\n");
  713. switch (uiBitCount)
  714. {
  715. case 1:
  716. cColorsMax = 2;
  717. break;
  718. case 4:
  719. cColorsMax = 16;
  720. break;
  721. case 8:
  722. cColorsMax = 256;
  723. break;
  724. case 32:
  725. cColorsMax = 0;
  726. break;
  727. default:
  728. WARNING("GreGetBitmapSize failed invalid bitcount in bmi BI_CMYK\n");
  729. return(0);
  730. }
  731. }
  732. else if ((uiCompression == BI_RLE4) || (uiCompression == BI_CMYKRLE4))
  733. {
  734. if (uiBitCount != 4)
  735. {
  736. return(0);
  737. }
  738. cColorsMax = 16;
  739. }
  740. else if ((uiCompression == BI_RLE8) || (uiCompression == BI_CMYKRLE8))
  741. {
  742. if (uiBitCount != 8)
  743. {
  744. return(0);
  745. }
  746. cColorsMax = 256;
  747. }
  748. else if ((uiCompression == BI_JPEG) || (uiCompression == BI_PNG))
  749. {
  750. cColorsMax = 0;
  751. }
  752. else
  753. {
  754. WARNING("GreGetBitmapSize failed invalid Compression in header\n");
  755. return(0);
  756. }
  757. if (uiPalUsed != 0)
  758. {
  759. if (uiPalUsed <= cColorsMax)
  760. cColors = uiPalUsed;
  761. else
  762. cColors = cColorsMax;
  763. }
  764. else
  765. cColors = cColorsMax;
  766. if (iUsage == DIB_PAL_COLORS)
  767. cjRGB = sizeof(USHORT);
  768. else if (iUsage == DIB_PAL_INDICES)
  769. cjRGB = 0;
  770. cjRet = ((cjHeader + (cjRGB * cColors)) + 3) & ~3;
  771. // (cjRGB * cColors) has a maximum of 256*sizeof(USHORT) so it will not
  772. // overflow, but we need to check the sum.
  773. if (cjRet < cjHeader)
  774. return 0;
  775. else
  776. return cjRet;
  777. return(((cjHeader + (cjRGB * cColors)) + 3) & ~3);
  778. }
  779. /******************************Public*Routine******************************\
  780. * noOverflowCJSCAN
  781. *
  782. * compute the amount of memory used by a bitmap
  783. *
  784. * Arguments:
  785. *
  786. * ulWidth -- The width of the bitmap
  787. * wPlanes -- The number of color planes
  788. * wBitCount -- The number of bits per color
  789. * ulHeight -- The height of the bitmap
  790. *
  791. * Return Value:
  792. *
  793. * The storage required (assuming each scanline is DWORD aligned) if less than
  794. * ULONG_MAX, 0 otherwise.
  795. *
  796. * History:
  797. *
  798. * 27-Aug-1997 -by- Ori Gershony [orig]
  799. *
  800. \**************************************************************************/
  801. ULONG
  802. noOverflowCJSCAN(
  803. ULONG ulWidth,
  804. WORD wPlanes,
  805. WORD wBitCount,
  806. ULONG ulHeight
  807. )
  808. {
  809. ULONGLONG product;
  810. //
  811. // Note that the following cannot overflow: 32+16+16=64
  812. // (even after adding 31!)
  813. //
  814. product = (((ULONGLONG) ulWidth) * wPlanes * wBitCount);
  815. product = ((product + 31) & ((ULONGLONG) ~31)) / 8;
  816. if (product > MAXULONG)
  817. {
  818. //
  819. // Already too large, final result will not fit in a ULONG
  820. //
  821. return 0; // Overflow
  822. }
  823. product *= ulHeight;
  824. if (product > MAXULONG)
  825. {
  826. return 0; // Overflow
  827. }
  828. else
  829. {
  830. return ((ULONG) product);
  831. }
  832. }
  833. /******************************Public*Routine******************************\
  834. * noOverflowCJSCANW
  835. *
  836. * compute the amount of memory used by a bitmap
  837. *
  838. * Arguments:
  839. *
  840. * ulWidth -- The width of the bitmap
  841. * wPlanes -- The number of color planes
  842. * wBitCount -- The number of bits per color
  843. * ulHeight -- The height of the bitmap
  844. *
  845. * Return Value:
  846. *
  847. * The storage required (assuming each scanline is WORD aligned) if less than
  848. * ULONG_MAX, 0 otherwise.
  849. *
  850. * History:
  851. *
  852. * 27-Aug-1997 -by- Ori Gershony [orig]
  853. *
  854. \**************************************************************************/
  855. ULONG
  856. noOverflowCJSCANW(
  857. ULONG ulWidth,
  858. WORD wPlanes,
  859. WORD wBitCount,
  860. ULONG ulHeight
  861. )
  862. {
  863. ULONGLONG product;
  864. //
  865. // Note that the following cannot overflow: 32+16+16=64
  866. // (even after adding 31!)
  867. //
  868. product = (((ULONGLONG) ulWidth) * wPlanes * wBitCount);
  869. product = ((product + 15) & ((ULONGLONG) ~15)) / 8;
  870. if (product > MAXULONG)
  871. {
  872. //
  873. // Already too large, final result will not fit in a ULONG
  874. //
  875. return 0; // Overflow
  876. }
  877. product *= ulHeight;
  878. if (product > MAXULONG)
  879. {
  880. return 0; // Overflow
  881. }
  882. else
  883. {
  884. return ((ULONG) product);
  885. }
  886. }
  887. /******************************Public*Routine******************************\
  888. * GreGetBitmapBitsSize()
  889. *
  890. * copied from gdi\client
  891. *
  892. * History:
  893. * 20-Feb-1995 -by- Eric Kutter [erick]
  894. * 14-Apr-1998 FritzS make Gre call for use by ntuser
  895. * Wrote it.
  896. \**************************************************************************/
  897. ULONG GreGetBitmapBitsSize(CONST BITMAPINFO *pbmi)
  898. {
  899. // Check for PM-style DIB
  900. if (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
  901. {
  902. LPBITMAPCOREINFO pbmci;
  903. pbmci = (LPBITMAPCOREINFO)pbmi;
  904. return(noOverflowCJSCAN(pbmci->bmciHeader.bcWidth,
  905. pbmci->bmciHeader.bcPlanes,
  906. pbmci->bmciHeader.bcBitCount,
  907. pbmci->bmciHeader.bcHeight));
  908. }
  909. // not a core header
  910. if ((pbmi->bmiHeader.biCompression == BI_RGB) ||
  911. (pbmi->bmiHeader.biCompression == BI_BITFIELDS) ||
  912. (pbmi->bmiHeader.biCompression == BI_CMYK)
  913. )
  914. {
  915. return(noOverflowCJSCAN(pbmi->bmiHeader.biWidth,
  916. (WORD) pbmi->bmiHeader.biPlanes,
  917. (WORD) pbmi->bmiHeader.biBitCount,
  918. ABS(pbmi->bmiHeader.biHeight)));
  919. }
  920. else
  921. {
  922. return(pbmi->bmiHeader.biSizeImage);
  923. }
  924. }
  925. /******************************Public*Routine******************************\
  926. * BOOL bCaptureBitmapInfo (LPBITMAPINFO pbmi, INT *pcjHeader)
  927. *
  928. * Capture the Bitmapinfo struct. The header must be a BITMAPINFOHEADER
  929. * or BITMAPV4HEADER
  930. * converted at the client side already.
  931. *
  932. * Note: this has to be called inside a TRY-EXCEPT.
  933. *
  934. * 23-Mar-1995 -by- Lingyun Wang [lingyunw]
  935. * Wrote it.
  936. \**************************************************************************/
  937. BOOL bCaptureBitmapInfo (
  938. LPBITMAPINFO pbmi,
  939. DWORD dwUsage,
  940. UINT cjHeader,
  941. LPBITMAPINFO *ppbmiTmp)
  942. {
  943. ASSERTGDI(ppbmiTmp != NULL,"bCaptureBitmapInfo(): pbmiTmp == NULL\n");
  944. //
  945. // Make sure we have at least the biSize field of header.
  946. //
  947. if ((cjHeader < sizeof(DWORD)) || (pbmi == (LPBITMAPINFO) NULL))
  948. {
  949. WARNING("bCaptureBitmapInfo - header too small or NULL\n");
  950. return FALSE;
  951. }
  952. else
  953. {
  954. *ppbmiTmp = PALLOCNOZ(cjHeader,'pmtG');
  955. if (*ppbmiTmp)
  956. {
  957. ProbeAndReadBuffer (*ppbmiTmp,pbmi,cjHeader);
  958. //
  959. // First, make sure that cjHeader is at least as
  960. // big as biSize so that the captured header
  961. // has sufficient data for GreGetBitmapSize to use.
  962. // Note that the first thing GreGetBitmapSize does is
  963. // validate biSize, so it isn't necessary for us
  964. // to check cjHeader against BITMAPCOREHEADER, etc.
  965. //
  966. // Next, recompute the header size from the captured
  967. // header: it better still match. Otherwise, we have
  968. // failed to safely capture the entire header (i.e.,
  969. // another thread changed the data changed during
  970. // capture or bogus data was passed to the API).
  971. //
  972. if (((*ppbmiTmp)->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) ||
  973. (cjHeader < (*ppbmiTmp)->bmiHeader.biSize) ||
  974. (cjHeader != GreGetBitmapSize(*ppbmiTmp, dwUsage)))
  975. {
  976. WARNING("bCapturebitmapInfo - bad header size\n");
  977. VFREEMEM(*ppbmiTmp);
  978. *ppbmiTmp = NULL;
  979. return FALSE;
  980. }
  981. return TRUE;
  982. }
  983. else
  984. {
  985. return FALSE;
  986. }
  987. }
  988. }
  989. /******************************Public*Routine******************************\
  990. * NtGdiSetDIBitsToDeviceInternal()
  991. *
  992. * History:
  993. * 01-Nov-1994 -by- Eric Kutter [erick]
  994. * Wrote it.
  995. * 23-Mar-1995 -by- Lingyun Wang [lingyunw]
  996. * call CaptureBitmapInfo to convert BITMAPCOREINFO if it is so.
  997. \**************************************************************************/
  998. int
  999. APIENTRY
  1000. NtGdiSetDIBitsToDeviceInternal(
  1001. HDC hdcDest,
  1002. int xDst,
  1003. int yDst,
  1004. DWORD cx,
  1005. DWORD cy,
  1006. int xSrc,
  1007. int ySrc,
  1008. DWORD iStartScan,
  1009. DWORD cNumScan,
  1010. LPBYTE pInitBits,
  1011. LPBITMAPINFO pbmi,
  1012. DWORD iUsage,
  1013. UINT cjMaxBits,
  1014. UINT cjMaxInfo,
  1015. BOOL bTransformCoordinates,
  1016. HANDLE hcmXform
  1017. )
  1018. {
  1019. int iRet = 1;
  1020. HANDLE hSecure = 0;
  1021. ULONG cjHeader = cjMaxInfo;
  1022. LPBITMAPINFO pbmiTmp = NULL;
  1023. iUsage &= (DIB_PAL_INDICES | DIB_PAL_COLORS | DIB_RGB_COLORS);
  1024. try
  1025. {
  1026. if (bCaptureBitmapInfo(pbmi,iUsage,cjHeader,&pbmiTmp))
  1027. {
  1028. if (pInitBits)
  1029. {
  1030. //
  1031. // Use cjMaxBits passed in, this size takes cNumScan
  1032. // into account. pInitBits has already been aligned
  1033. // in user mode.
  1034. //
  1035. ProbeForRead(pInitBits,cjMaxBits,sizeof(DWORD));
  1036. hSecure = MmSecureVirtualMemory(pInitBits,cjMaxBits, PAGE_READONLY);
  1037. if (hSecure == 0)
  1038. {
  1039. iRet = 0;
  1040. }
  1041. }
  1042. }
  1043. else
  1044. {
  1045. iRet = 0;
  1046. }
  1047. }
  1048. except(EXCEPTION_EXECUTE_HANDLER)
  1049. {
  1050. WARNINGX(4);
  1051. // SetLastError(GetExceptionCode());
  1052. iRet = 0;
  1053. }
  1054. // if we didn't hit an error above
  1055. if (iRet == 1)
  1056. {
  1057. iRet = GreSetDIBitsToDeviceInternal(
  1058. hdcDest,
  1059. xDst,
  1060. yDst,
  1061. cx,
  1062. cy,
  1063. xSrc,
  1064. ySrc,
  1065. iStartScan,
  1066. cNumScan,
  1067. pInitBits,
  1068. pbmiTmp,
  1069. iUsage,
  1070. cjMaxBits,
  1071. cjHeader,
  1072. bTransformCoordinates,
  1073. hcmXform
  1074. );
  1075. }
  1076. if (hSecure)
  1077. {
  1078. MmUnsecureVirtualMemory(hSecure);
  1079. }
  1080. if (pbmiTmp)
  1081. VFREEMEM(pbmiTmp);
  1082. return(iRet);
  1083. }
  1084. /******************************Public*Routine******************************\
  1085. * NtGdiPolyPolyDraw()
  1086. *
  1087. * History:
  1088. * 22-Feb-1995 -by- Eric Kutter [erick]
  1089. * Wrote it.
  1090. \**************************************************************************/
  1091. BOOL NtGdiFastPolyPolyline(HDC, CONST POINT*, ULONG*, ULONG); // drawgdi.cxx
  1092. ULONG_PTR
  1093. APIENTRY
  1094. NtGdiPolyPolyDraw(
  1095. HDC hdc,
  1096. PPOINT ppt,
  1097. PULONG pcpt,
  1098. ULONG ccpt,
  1099. int iFunc
  1100. )
  1101. {
  1102. ULONG cpt;
  1103. PULONG pulCounts;
  1104. ULONG_PTR ulRet = 1;
  1105. ULONG ulCount;
  1106. POINT apt[10];
  1107. PPOINT pptTmp;
  1108. if (ccpt > 0)
  1109. {
  1110. // If a PolyPolyline, first try the fast-path polypolyline code.
  1111. if ((iFunc != I_POLYPOLYLINE) ||
  1112. (!NtGdiFastPolyPolyline(hdc, ppt, pcpt, ccpt)))
  1113. {
  1114. if (ccpt > 1)
  1115. {
  1116. // If ccpt > 1 we cant have I_POLYLINETO/I_POLYBEZIERTO/I_POLYBEZIER
  1117. if (iFunc == I_POLYLINETO || iFunc == I_POLYBEZIERTO || iFunc == I_POLYBEZIER)
  1118. {
  1119. return 0;
  1120. }
  1121. //
  1122. // make sure allocation is within reasonable limits
  1123. //
  1124. if (!BALLOC_OVERFLOW1(ccpt,ULONG))
  1125. {
  1126. pulCounts = PALLOCNOZ(ccpt * sizeof(ULONG),'pmtG');
  1127. }
  1128. else
  1129. {
  1130. EngSetLastError(ERROR_INVALID_PARAMETER);
  1131. pulCounts = NULL;
  1132. }
  1133. }
  1134. else
  1135. {
  1136. pulCounts = &ulCount;
  1137. }
  1138. if (pulCounts)
  1139. {
  1140. pptTmp = apt;
  1141. try
  1142. {
  1143. UINT i;
  1144. //
  1145. // we did make sure ccpt * sizeof(ULONG) will not overflow
  1146. // in above. then here is safe.
  1147. //
  1148. ProbeAndReadBuffer(pulCounts,pcpt,ccpt * sizeof(ULONG));
  1149. cpt = 0;
  1150. for (i = 0; i < ccpt; ++i)
  1151. cpt += pulCounts[i];
  1152. // we need to make sure that the cpt array won't overflow
  1153. // a DWORD in terms of number of bytes
  1154. if (!BALLOC_OVERFLOW1(cpt,POINT))
  1155. {
  1156. if (cpt > 10)
  1157. {
  1158. pptTmp = AllocFreeTmpBuffer(cpt * sizeof(POINT));
  1159. }
  1160. if (pptTmp)
  1161. {
  1162. ProbeAndReadBuffer(pptTmp,ppt,cpt*sizeof(POINT));
  1163. }
  1164. else
  1165. {
  1166. ulRet = 0;
  1167. }
  1168. }
  1169. else
  1170. {
  1171. ulRet = 0;
  1172. }
  1173. }
  1174. except(EXCEPTION_EXECUTE_HANDLER)
  1175. {
  1176. WARNINGX(5);
  1177. // SetLastError(GetExceptionCode());
  1178. ulRet = 0;
  1179. }
  1180. if (ulRet != 0)
  1181. {
  1182. switch(iFunc)
  1183. {
  1184. case I_POLYPOLYGON:
  1185. ulRet =
  1186. (ULONG_PTR) GrePolyPolygonInternal
  1187. (
  1188. hdc,
  1189. pptTmp,
  1190. (LPINT)pulCounts,
  1191. ccpt,
  1192. cpt
  1193. );
  1194. break;
  1195. case I_POLYPOLYLINE:
  1196. ulRet =
  1197. (ULONG_PTR) GrePolyPolylineInternal
  1198. (
  1199. hdc,
  1200. pptTmp,
  1201. pulCounts,
  1202. ccpt,
  1203. cpt
  1204. );
  1205. break;
  1206. case I_POLYBEZIER:
  1207. ulRet =
  1208. (ULONG_PTR) GrePolyBezier
  1209. (
  1210. hdc,
  1211. pptTmp,
  1212. ulCount
  1213. );
  1214. break;
  1215. case I_POLYLINETO:
  1216. ulRet =
  1217. (ULONG_PTR) GrePolylineTo
  1218. (
  1219. hdc,
  1220. pptTmp,
  1221. ulCount
  1222. );
  1223. break;
  1224. case I_POLYBEZIERTO:
  1225. ulRet =
  1226. (ULONG_PTR) GrePolyBezierTo
  1227. (
  1228. hdc,
  1229. pptTmp,
  1230. ulCount
  1231. );
  1232. break;
  1233. case I_POLYPOLYRGN:
  1234. ulRet =
  1235. (ULONG_PTR) GreCreatePolyPolygonRgnInternal
  1236. (
  1237. pptTmp,
  1238. (LPINT)pulCounts,
  1239. ccpt,
  1240. (INT)(ULONG_PTR)hdc, // the mode
  1241. cpt
  1242. );
  1243. break;
  1244. default:
  1245. ulRet = 0;
  1246. }
  1247. }
  1248. if (pptTmp && (pptTmp != apt))
  1249. FreeTmpBuffer(pptTmp);
  1250. if (pulCounts != &ulCount)
  1251. VFREEMEM(pulCounts);
  1252. }
  1253. else
  1254. {
  1255. ulRet = 0;
  1256. }
  1257. }
  1258. }
  1259. else
  1260. {
  1261. ulRet = 0;
  1262. }
  1263. return(ulRet);
  1264. }
  1265. /******************************Public*Routine******************************\
  1266. * NtGdiStretchDIBitsInternal()
  1267. *
  1268. * History:
  1269. * 01-Nov-1994 -by- Eric Kutter [erick]
  1270. * Wrote it.
  1271. * 04-MAR-1995 -by- Lingyun Wang [lingyunw]
  1272. * Expanded it.
  1273. \**************************************************************************/
  1274. int
  1275. APIENTRY
  1276. NtGdiStretchDIBitsInternal(
  1277. HDC hdc,
  1278. int xDst,
  1279. int yDst,
  1280. int cxDst,
  1281. int cyDst,
  1282. int xSrc,
  1283. int ySrc,
  1284. int cxSrc,
  1285. int cySrc,
  1286. LPBYTE pjInit,
  1287. LPBITMAPINFO pbmi,
  1288. DWORD dwUsage,
  1289. DWORD dwRop4,
  1290. UINT cjMaxInfo,
  1291. UINT cjMaxBits,
  1292. HANDLE hcmXform
  1293. )
  1294. {
  1295. LPBITMAPINFO pbmiTmp = NULL;
  1296. INT iRet = 1;
  1297. ULONG cjHeader = cjMaxInfo;
  1298. ULONG cjBits = cjMaxBits;
  1299. HANDLE hSecure = 0;
  1300. if (pjInit && pbmi && cjHeader)
  1301. {
  1302. try
  1303. {
  1304. if (bCaptureBitmapInfo(pbmi, dwUsage, cjHeader, &pbmiTmp))
  1305. {
  1306. if (pjInit)
  1307. {
  1308. ProbeForRead(pjInit, cjBits, sizeof(DWORD));
  1309. hSecure = MmSecureVirtualMemory(pjInit, cjBits, PAGE_READONLY);
  1310. if (!hSecure)
  1311. {
  1312. iRet = 0;
  1313. }
  1314. }
  1315. }
  1316. else
  1317. {
  1318. iRet = 0;
  1319. }
  1320. }
  1321. except(EXCEPTION_EXECUTE_HANDLER)
  1322. {
  1323. WARNINGX(6);
  1324. // SetLastError(GetExceptionCode());
  1325. iRet = 0;
  1326. }
  1327. }
  1328. else
  1329. {
  1330. // it is completely valid to pass in NULL here if the ROP doesn't use
  1331. // a source.
  1332. pbmiTmp = NULL;
  1333. pjInit = NULL;
  1334. pjInit = NULL;
  1335. }
  1336. if (iRet)
  1337. {
  1338. iRet = GreStretchDIBitsInternal(
  1339. hdc,
  1340. xDst,
  1341. yDst,
  1342. cxDst,
  1343. cyDst,
  1344. xSrc,
  1345. ySrc,
  1346. cxSrc,
  1347. cySrc,
  1348. pjInit,
  1349. pbmiTmp,
  1350. dwUsage,
  1351. dwRop4,
  1352. cjHeader,
  1353. cjBits,
  1354. hcmXform
  1355. );
  1356. if (hSecure)
  1357. {
  1358. MmUnsecureVirtualMemory(hSecure);
  1359. }
  1360. }
  1361. if (pbmiTmp)
  1362. {
  1363. VFREEMEM(pbmiTmp);
  1364. }
  1365. return (iRet);
  1366. }
  1367. /******************************Public*Routine******************************\
  1368. * NtGdiGetOutlineTextMetricsInternalW
  1369. *
  1370. * Arguments:
  1371. *
  1372. * hdc - device context
  1373. * cjotm - size of metrics data array
  1374. * potmw - pointer to array of OUTLINETEXTMETRICW structures or NULL
  1375. * ptmd - pointer to TMDIFF strcture
  1376. *
  1377. * Return Value:
  1378. *
  1379. * If potmw is NULL, return size of buffer needed, else TRUE.
  1380. * If the function fails, the return value is FALSE;
  1381. *
  1382. * History:
  1383. *
  1384. * 15-Mar-1995 -by- Mark Enstrom [marke]
  1385. *
  1386. \**************************************************************************/
  1387. ULONG
  1388. APIENTRY
  1389. NtGdiGetOutlineTextMetricsInternalW(
  1390. HDC hdc,
  1391. ULONG cjotm,
  1392. OUTLINETEXTMETRICW *potmw,
  1393. TMDIFF *ptmd
  1394. )
  1395. {
  1396. DWORD dwRet = (DWORD)1;
  1397. OUTLINETEXTMETRICW *pkmOutlineTextMetricW;
  1398. TMDIFF kmTmDiff;
  1399. if ((cjotm == 0) || (potmw == (OUTLINETEXTMETRICW *)NULL))
  1400. {
  1401. cjotm = 0;
  1402. pkmOutlineTextMetricW = (OUTLINETEXTMETRICW *)NULL;
  1403. }
  1404. else
  1405. {
  1406. pkmOutlineTextMetricW = AllocFreeTmpBuffer(cjotm);
  1407. if (pkmOutlineTextMetricW == (OUTLINETEXTMETRICW *)NULL)
  1408. {
  1409. dwRet = (DWORD)-1;
  1410. }
  1411. }
  1412. if (dwRet != (DWORD)-1)
  1413. {
  1414. dwRet = GreGetOutlineTextMetricsInternalW(
  1415. hdc,
  1416. cjotm,
  1417. pkmOutlineTextMetricW,
  1418. &kmTmDiff);
  1419. if (dwRet != (DWORD)-1 && dwRet != (DWORD) 0)
  1420. {
  1421. try
  1422. {
  1423. //
  1424. // copy TMDIFF structure out
  1425. //
  1426. ProbeAndWriteAlignedBuffer(ptmd, &kmTmDiff, sizeof(TMDIFF), sizeof(DWORD));
  1427. //
  1428. // copy OTM out if needed
  1429. //
  1430. if (cjotm != 0)
  1431. {
  1432. ProbeAndWriteAlignedBuffer(potmw, pkmOutlineTextMetricW, cjotm, sizeof(DWORD));
  1433. }
  1434. }
  1435. except(EXCEPTION_EXECUTE_HANDLER)
  1436. {
  1437. WARNINGX(7);
  1438. // SetLastError(GetExceptionCode());
  1439. dwRet = (DWORD)-1;
  1440. }
  1441. }
  1442. }
  1443. if (pkmOutlineTextMetricW != (OUTLINETEXTMETRICW *)NULL)
  1444. {
  1445. FreeTmpBuffer(pkmOutlineTextMetricW);
  1446. }
  1447. return(dwRet);
  1448. }
  1449. // PUBLIC
  1450. /******************************Public*Routine******************************\
  1451. * NtGdiGetBoundsRect()
  1452. *
  1453. * History:
  1454. * 01-Nov-1994 -by- Eric Kutter [erick]
  1455. * Wrote it.
  1456. \**************************************************************************/
  1457. DWORD
  1458. APIENTRY
  1459. NtGdiGetBoundsRect(
  1460. HDC hdc,
  1461. LPRECT prc,
  1462. DWORD f
  1463. )
  1464. {
  1465. DWORD dwRet;
  1466. RECT rc = {0, 0, 0, 0};
  1467. dwRet = GreGetBoundsRect(hdc,&rc,f);
  1468. if (dwRet)
  1469. {
  1470. try
  1471. {
  1472. ProbeAndWriteStructure(prc,rc,RECT);
  1473. }
  1474. except(EXCEPTION_EXECUTE_HANDLER)
  1475. {
  1476. WARNINGX(8);
  1477. // SetLastError(GetExceptionCode());
  1478. dwRet = 0;
  1479. }
  1480. }
  1481. return(dwRet);
  1482. }
  1483. /******************************Public*Routine******************************\
  1484. * NtGdiGetBitmapBits()
  1485. *
  1486. * History:
  1487. * 01-Nov-1994 -by- Eric Kutter [erick]
  1488. * Wrote it.
  1489. * 03-Mar-1995 -by- Lingyun Wang [lingyunw]
  1490. * Expanded it.
  1491. \**************************************************************************/
  1492. LONG
  1493. APIENTRY
  1494. NtGdiGetBitmapBits(
  1495. HBITMAP hbm,
  1496. ULONG cjMax,
  1497. PBYTE pjOut
  1498. )
  1499. {
  1500. LONG lRet = 1;
  1501. HANDLE hSecure = 0;
  1502. LONG lOffset = 0;
  1503. ULONG cjBmSize = 0;
  1504. //
  1505. // get the bitmap size, just in case they pass
  1506. // in a cjMax greater than the bitmap size
  1507. //
  1508. cjBmSize = GreGetBitmapBits(hbm,0,NULL,&lOffset);
  1509. if (cjMax > cjBmSize)
  1510. {
  1511. cjMax = cjBmSize;
  1512. }
  1513. if (pjOut)
  1514. {
  1515. try
  1516. {
  1517. // WINBUG #83051 2-8-2000 bhouse Investigate possible stale comment
  1518. // The below old comment mentions how this is ideal for try execept block ...
  1519. // hmmm ... but we are in a try except block... this needs verifying that
  1520. // it is just an old stale comment.
  1521. // Old Comment:
  1522. // - this would be a prime candidate for a try/except
  1523. // instead of MmSecureVirtualMemory
  1524. ProbeForWrite(pjOut,cjMax,sizeof(BYTE));
  1525. hSecure = MmSecureVirtualMemory (pjOut, cjMax, PAGE_READWRITE);
  1526. if (hSecure == 0)
  1527. {
  1528. lRet = 0;
  1529. }
  1530. }
  1531. except(EXCEPTION_EXECUTE_HANDLER)
  1532. {
  1533. WARNINGX(9);
  1534. // SetLastError(GetExceptionCode());
  1535. lRet = 0;
  1536. }
  1537. }
  1538. if (lRet)
  1539. {
  1540. lRet = GreGetBitmapBits(hbm,cjMax,pjOut,&lOffset);
  1541. }
  1542. if (hSecure)
  1543. {
  1544. MmUnsecureVirtualMemory(hSecure);
  1545. }
  1546. return (lRet);
  1547. }
  1548. /******************************Public*Routine******************************\
  1549. * NtGdiCreateDIBitmapInternal()
  1550. *
  1551. * History:
  1552. * 01-Nov-1994 -by- Eric Kutter [erick]
  1553. * Wrote it.
  1554. *
  1555. * History:
  1556. * 03-Mar-1995 -by- Lingyun Wang [lingyunw]
  1557. * Expanded it.
  1558. *
  1559. * Difference from NtGdiCreateDIBitmapInternal():
  1560. * Takes in cx, cy
  1561. *
  1562. \**************************************************************************/
  1563. HBITMAP
  1564. APIENTRY
  1565. NtGdiCreateDIBitmapInternal(
  1566. HDC hdc,
  1567. INT cx, //Bitmap width
  1568. INT cy, //Bitmap Height
  1569. DWORD fInit,
  1570. LPBYTE pjInit,
  1571. LPBITMAPINFO pbmi,
  1572. DWORD iUsage,
  1573. UINT cjMaxInitInfo,
  1574. UINT cjMaxBits,
  1575. FLONG f,
  1576. HANDLE hcmXform
  1577. )
  1578. {
  1579. LPBITMAPINFO pbmiTmp = NULL;
  1580. ULONG cjHeader = cjMaxInitInfo;
  1581. ULONG cjBits = cjMaxBits;
  1582. ULONG_PTR iRet = 1;
  1583. HANDLE hSecure = 0;
  1584. if (pbmi && cjHeader)
  1585. {
  1586. try
  1587. {
  1588. if (bCaptureBitmapInfo(pbmi, iUsage, cjHeader, &pbmiTmp))
  1589. {
  1590. if (pjInit)
  1591. {
  1592. ProbeForRead(pjInit,cjBits,sizeof(DWORD));
  1593. hSecure = MmSecureVirtualMemory(pjInit, cjBits, PAGE_READONLY);
  1594. if (!hSecure)
  1595. {
  1596. iRet = 0;
  1597. }
  1598. }
  1599. }
  1600. else
  1601. {
  1602. iRet = 0;
  1603. }
  1604. }
  1605. except(EXCEPTION_EXECUTE_HANDLER)
  1606. {
  1607. WARNINGX(10);
  1608. // SetLastError(GetExceptionCode());
  1609. iRet = 0;
  1610. }
  1611. }
  1612. // if we didn't hit an error above
  1613. if (iRet == 1)
  1614. {
  1615. if (!(fInit & CBM_CREATEDIB))
  1616. {
  1617. //create an compatible bitmap
  1618. iRet = (ULONG_PTR)GreCreateDIBitmapComp(
  1619. hdc,
  1620. cx,
  1621. cy,
  1622. fInit,
  1623. pjInit,
  1624. pbmiTmp,
  1625. iUsage,
  1626. cjHeader,
  1627. cjBits,
  1628. 0,
  1629. hcmXform);
  1630. }
  1631. else
  1632. {
  1633. iRet = (ULONG_PTR)GreCreateDIBitmapReal(
  1634. hdc,
  1635. fInit,
  1636. pjInit,
  1637. pbmiTmp,
  1638. iUsage,
  1639. cjHeader,
  1640. cjBits,
  1641. (HANDLE)0,
  1642. 0,
  1643. (HANDLE)0,
  1644. 0,
  1645. 0,
  1646. NULL);
  1647. }
  1648. }
  1649. //free up
  1650. if (pbmiTmp)
  1651. {
  1652. VFREEMEM(pbmiTmp);
  1653. }
  1654. if (hSecure)
  1655. {
  1656. MmUnsecureVirtualMemory(hSecure);
  1657. }
  1658. return((HBITMAP)iRet);
  1659. }
  1660. /******************************Public*Routine******************************\
  1661. * NtGdiCreateDIBSection
  1662. *
  1663. * Arguments:
  1664. *
  1665. * hdc - Handle to a device context. If the value of iUsage is
  1666. * DIB_PAL_COLORS, the function uses this device context's logical
  1667. * palette to initialize the device-independent bitmap's colors.
  1668. *
  1669. *
  1670. * hSection - Handle to a file mapping object that the function will use to
  1671. * create the device-independent bitmap. This parameter can be
  1672. * NULL. If hSection is not NULL, it must be a handle to a file
  1673. * mapping object created by calling the CreateFileMapping
  1674. * function. Handles created by other means will cause
  1675. * CreateDIBSection to fail. If hSection is not NULL, the
  1676. * CreateDIBSection function locates the bitmap's bit values at
  1677. * offset dwOffset in the file mapping object referred to by
  1678. * hSection. An application can later retrieve the hSection
  1679. * handle by calling the GetObject function with the HBITMAP
  1680. * returned by CreateDIBSection.
  1681. *
  1682. *
  1683. *
  1684. * dwOffset - Specifies the offset from the beginning of the file mapping
  1685. * object referenced by hSection where storage for the bitmap's
  1686. * bit values is to begin. This value is ignored if hSection is
  1687. * NULL. The bitmap's bit values are aligned on doubleword
  1688. * boundaries, so dwOffset must be a multiple of the size of a
  1689. * DWORD.
  1690. *
  1691. * If hSection is NULL, the operating system allocates memory for
  1692. * the device-independent bitmap. In this case, the
  1693. * CreateDIBSection function ignores the dwOffset parameter. An
  1694. * application cannot later obtain a handle to this memory: the
  1695. * dshSection member of the DIBSECTION structure filled in by
  1696. * calling the GetObject function will be NULL.
  1697. *
  1698. *
  1699. * pbmi - Points to a BITMAPINFO structure that specifies various
  1700. * attributes of the device-independent bitmap, including the
  1701. * bitmap's dimensions and colors.iUsage
  1702. *
  1703. * iUsage - Specifies the type of data contained in the bmiColors array
  1704. * member of the BITMAPINFO structure pointed to by pbmi: logical
  1705. * palette indices or literal RGB values.
  1706. *
  1707. * cjMaxInfo - Maximum size of pbmi
  1708. *
  1709. * cjMaxBits - Maximum size of bitamp
  1710. *
  1711. *
  1712. * Return Value:
  1713. *
  1714. * handle of bitmap or NULL
  1715. *
  1716. * History:
  1717. *
  1718. * 28-Mar-1995 -by- Mark Enstrom [marke]
  1719. *
  1720. \**************************************************************************/
  1721. HBITMAP
  1722. APIENTRY
  1723. NtGdiCreateDIBSection(
  1724. IN HDC hdc,
  1725. IN HANDLE hSectionApp,
  1726. IN DWORD dwOffset,
  1727. IN LPBITMAPINFO pbmi,
  1728. IN DWORD iUsage,
  1729. IN UINT cjHeader,
  1730. IN FLONG fl,
  1731. IN ULONG_PTR dwColorSpace,
  1732. OUT PVOID *ppvBits
  1733. )
  1734. {
  1735. HBITMAP hRet = NULL;
  1736. BOOL bStatus = FALSE;
  1737. if (pbmi != NULL)
  1738. {
  1739. LPBITMAPINFO pbmiTmp = NULL;
  1740. PVOID pvBase = NULL;
  1741. try
  1742. {
  1743. bCaptureBitmapInfo(pbmi, iUsage, cjHeader, &pbmiTmp);
  1744. }
  1745. except(EXCEPTION_EXECUTE_HANDLER)
  1746. {
  1747. WARNINGX(11);
  1748. EngSetLastError(ERROR_INVALID_PARAMETER);
  1749. if (pbmiTmp != NULL)
  1750. {
  1751. VFREEMEM(pbmiTmp);
  1752. pbmiTmp = NULL;
  1753. }
  1754. }
  1755. if (pbmiTmp)
  1756. {
  1757. NTSTATUS Status;
  1758. ULONG cjBits = GreGetBitmapBitsSize(pbmiTmp);
  1759. SIZE_T cjView = (SIZE_T)cjBits;
  1760. if (cjBits)
  1761. {
  1762. HANDLE hDIBSection = hSectionApp;
  1763. //
  1764. // if the app's hsection is NULL, then just
  1765. // allocate the proper range of virtual memory
  1766. //
  1767. if (hDIBSection == NULL)
  1768. {
  1769. Status = ZwAllocateVirtualMemory(
  1770. NtCurrentProcess(),
  1771. &pvBase,
  1772. 0L,
  1773. &cjView,
  1774. MEM_COMMIT | MEM_RESERVE,
  1775. PAGE_READWRITE
  1776. );
  1777. dwOffset = 0;
  1778. if (!NT_SUCCESS(Status))
  1779. {
  1780. EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1781. }
  1782. }
  1783. else
  1784. {
  1785. LARGE_INTEGER SectionOffset;
  1786. PVOID pObj;
  1787. SectionOffset.LowPart = dwOffset & 0xFFFF0000;
  1788. SectionOffset.HighPart = 0;
  1789. //
  1790. // Notice, header is not included in section as it is
  1791. // in client-server. We do need to leave room for
  1792. // the offset, however.
  1793. //
  1794. cjView += (dwOffset & 0x0000FFFF);
  1795. Status = ObReferenceObjectByHandle(hDIBSection,
  1796. SECTION_MAP_READ|SECTION_MAP_WRITE,
  1797. *(POBJECT_TYPE *)MmSectionObjectType,
  1798. PsGetCurrentThreadPreviousMode(),
  1799. &pObj,
  1800. 0L);
  1801. if(NT_SUCCESS(Status))
  1802. {
  1803. Status = MmMapViewOfSection(
  1804. pObj,
  1805. PsGetCurrentProcess(),
  1806. (PVOID *) &pvBase,
  1807. 0L,
  1808. cjView,
  1809. &SectionOffset,
  1810. &cjView,
  1811. ViewShare,
  1812. 0L,
  1813. PAGE_READWRITE);
  1814. if (!NT_SUCCESS(Status))
  1815. {
  1816. EngSetLastError(ERROR_INVALID_PARAMETER);
  1817. }
  1818. //
  1819. // we're not going to use this again
  1820. //
  1821. ObDereferenceObject(pObj);
  1822. }
  1823. else
  1824. {
  1825. WARNING("NtGdiCreateDIBSection: ObReferenceObjectByHandle failed\n");
  1826. EngSetLastError(ERROR_INVALID_PARAMETER);
  1827. //
  1828. //This will now fall through to the cleanup code at the end of the routine
  1829. //to free pbmiTmp
  1830. //
  1831. }
  1832. }
  1833. // set the pointer to the beginning of the bits
  1834. if (NT_SUCCESS(Status))
  1835. {
  1836. HANDLE hSecure = NULL;
  1837. PBYTE pDIB = NULL;
  1838. pDIB = (PBYTE)pvBase + (dwOffset & 0x0000FFFF);
  1839. //
  1840. // try to secure memory, keep secure until bitmap
  1841. // is deleted
  1842. //
  1843. hSecure = MmSecureVirtualMemory(
  1844. pvBase,
  1845. cjView,
  1846. PAGE_READWRITE);
  1847. if (hSecure)
  1848. {
  1849. //
  1850. // Make the GDI Bitmap
  1851. //
  1852. hRet = GreCreateDIBitmapReal(
  1853. hdc,
  1854. CBM_CREATEDIB,
  1855. pDIB,
  1856. pbmiTmp,
  1857. iUsage,
  1858. cjHeader,
  1859. cjBits,
  1860. hDIBSection,
  1861. dwOffset,
  1862. hSecure,
  1863. (fl & CDBI_NOPALETTE) | CDBI_DIBSECTION,
  1864. dwColorSpace,
  1865. NULL);
  1866. if (hRet != NULL)
  1867. {
  1868. try
  1869. {
  1870. ProbeAndWriteStructure(ppvBits,pDIB,PVOID);
  1871. bStatus = TRUE;
  1872. }
  1873. except(EXCEPTION_EXECUTE_HANDLER)
  1874. {
  1875. WARNINGX(12);
  1876. EngSetLastError(ERROR_INVALID_PARAMETER);
  1877. }
  1878. }
  1879. else
  1880. {
  1881. EngSetLastError(ERROR_INVALID_PARAMETER);
  1882. }
  1883. }
  1884. else
  1885. {
  1886. EngSetLastError(ERROR_INVALID_PARAMETER);
  1887. }
  1888. // if we failed, we need to do cleanup.
  1889. if (!bStatus)
  1890. {
  1891. //
  1892. // The bDeleteSurface call will free DIBSection memory,
  1893. // only do cleanup if MmSecureVirtualMemory or GreCreateDIBitmapReal
  1894. // failed
  1895. //
  1896. if (hRet)
  1897. {
  1898. bDeleteSurface((HSURF)hRet);
  1899. hRet = NULL;
  1900. }
  1901. else
  1902. {
  1903. // do we need to unsecure the memory?
  1904. if (hSecure)
  1905. {
  1906. MmUnsecureVirtualMemory(hSecure);
  1907. }
  1908. // free the memory based on allocation
  1909. if (hSectionApp == NULL)
  1910. {
  1911. cjView = 0;
  1912. ZwFreeVirtualMemory(
  1913. NtCurrentProcess(),
  1914. &pDIB,
  1915. &cjView,
  1916. MEM_RELEASE);
  1917. }
  1918. else
  1919. {
  1920. //
  1921. // unmap view of section
  1922. //
  1923. ZwUnmapViewOfSection(
  1924. NtCurrentProcess(),
  1925. pvBase);
  1926. }
  1927. }
  1928. }
  1929. }
  1930. }
  1931. // the only way to have gotten here is if we did allocate the pbmiTmp
  1932. VFREEMEM(pbmiTmp);
  1933. }
  1934. }
  1935. return(hRet);
  1936. }
  1937. /******************************Public*Routine******************************\
  1938. * NtGdiExtCreatePen()
  1939. *
  1940. * History:
  1941. * 01-Nov-1994 -by- Eric Kutter [erick]
  1942. * Wrote it.
  1943. \**************************************************************************/
  1944. HPEN
  1945. APIENTRY
  1946. NtGdiExtCreatePen(
  1947. ULONG flPenStyle,
  1948. ULONG ulWidth,
  1949. ULONG iBrushStyle,
  1950. ULONG ulColor,
  1951. ULONG_PTR lClientHatch,
  1952. ULONG_PTR lHatch,
  1953. ULONG cstyle,
  1954. PULONG pulStyle,
  1955. ULONG cjDIB,
  1956. BOOL bOldStylePen,
  1957. HBRUSH hbrush
  1958. )
  1959. {
  1960. PULONG pulStyleTmp = NULL;
  1961. PULONG pulDIB = NULL;
  1962. HPEN hpenRet = (HPEN)1;
  1963. if (pulStyle)
  1964. {
  1965. if (!BALLOC_OVERFLOW1(cstyle,ULONG))
  1966. {
  1967. pulStyleTmp = PALLOCNOZ(cstyle * sizeof(ULONG),'pmtG');
  1968. }
  1969. if (!pulStyleTmp)
  1970. hpenRet = (HPEN)0;
  1971. }
  1972. if (iBrushStyle == BS_DIBPATTERNPT)
  1973. {
  1974. pulDIB = AllocFreeTmpBuffer(cjDIB);
  1975. if (!pulDIB)
  1976. hpenRet = (HPEN)0;
  1977. }
  1978. if (hpenRet)
  1979. {
  1980. try
  1981. {
  1982. if (pulStyle)
  1983. {
  1984. ProbeAndReadAlignedBuffer(pulStyleTmp,pulStyle,cstyle * sizeof(ULONG), sizeof(ULONG));
  1985. }
  1986. // if it is a DIBPATTERN type, the lHatch is a pointer to the BMI
  1987. if (iBrushStyle == BS_DIBPATTERNPT)
  1988. {
  1989. ProbeAndReadAlignedBuffer(pulDIB,(PVOID)lHatch,cjDIB,sizeof(ULONG));
  1990. lHatch = (ULONG_PTR)pulDIB;
  1991. }
  1992. }
  1993. except(EXCEPTION_EXECUTE_HANDLER)
  1994. {
  1995. WARNINGX(13);
  1996. // SetLastError(GetExceptionCode());
  1997. hpenRet = (HPEN)0;
  1998. }
  1999. // if all has succeeded
  2000. if (hpenRet)
  2001. {
  2002. hpenRet = GreExtCreatePen(
  2003. flPenStyle,ulWidth,iBrushStyle,
  2004. ulColor,lClientHatch,lHatch,cstyle,
  2005. pulStyleTmp,cjDIB,bOldStylePen,hbrush
  2006. );
  2007. }
  2008. }
  2009. else
  2010. {
  2011. // SetLastError(GetExceptionCode());
  2012. }
  2013. // cleanup
  2014. if (pulDIB)
  2015. FreeTmpBuffer(pulDIB);
  2016. if (pulStyleTmp)
  2017. VFREEMEM(pulStyleTmp);
  2018. return(hpenRet);
  2019. }
  2020. /******************************Public*Routine******************************\
  2021. * NtGdiHfontCreate()
  2022. *
  2023. * History:
  2024. * 01-Nov-1994 -by- Eric Kutter [erick]
  2025. * Wrote it.
  2026. \**************************************************************************/
  2027. HFONT
  2028. APIENTRY
  2029. NtGdiHfontCreate(
  2030. ENUMLOGFONTEXDVW * plfw,
  2031. ULONG cjElfw,
  2032. LFTYPE lft,
  2033. FLONG fl,
  2034. PVOID pvCliData
  2035. )
  2036. {
  2037. ULONG_PTR iRet = 1;
  2038. // check for bad parameter
  2039. if (plfw && cjElfw && (cjElfw <= sizeof(ENUMLOGFONTEXDVW)))
  2040. {
  2041. ENUMLOGFONTEXDVW elfwTmp; // too big a structure on the stack?
  2042. try
  2043. {
  2044. ProbeAndReadBuffer(&elfwTmp, plfw, cjElfw);
  2045. }
  2046. except(EXCEPTION_EXECUTE_HANDLER)
  2047. {
  2048. WARNINGX(15);
  2049. // SetLastError(GetExceptionCode());
  2050. iRet = 0;
  2051. }
  2052. // Ignore the DV because adobe said they will never ship a mm otf font
  2053. // This is a hack to avoid changing lot of code to remove mm support from the system
  2054. elfwTmp.elfDesignVector.dvNumAxes = 0;
  2055. if (iRet)
  2056. {
  2057. iRet = (ULONG_PTR)hfontCreate(&elfwTmp, lft, fl, pvCliData);
  2058. }
  2059. }
  2060. else
  2061. {
  2062. iRet = 0;
  2063. }
  2064. return ((HFONT)iRet);
  2065. }
  2066. /******************************Public*Routine******************************\
  2067. * NtGdiExtCreateRegion()
  2068. *
  2069. * History:
  2070. * 01-Nov-1994 -by- Eric Kutter [erick]
  2071. * Wrote it.
  2072. * 24-Feb-1995 -by- Lingyun Wang [lingyunw]
  2073. * expanded it.
  2074. \**************************************************************************/
  2075. HRGN
  2076. APIENTRY
  2077. NtGdiExtCreateRegion(
  2078. LPXFORM px,
  2079. DWORD cj,
  2080. LPRGNDATA prgn
  2081. )
  2082. {
  2083. LPRGNDATA prgnTmp;
  2084. XFORM xf;
  2085. HRGN hrgn = (HRGN)NULL;
  2086. // check for bad parameter
  2087. if (cj >= sizeof(RGNDATAHEADER))
  2088. {
  2089. // do the real work
  2090. prgnTmp = AllocFreeTmpBuffer(cj);
  2091. if (prgnTmp)
  2092. {
  2093. BOOL bConvert = TRUE;
  2094. if (px)
  2095. {
  2096. bConvert = ProbeAndConvertXFORM ((XFORML *)px, (XFORML *)&xf);
  2097. px = &xf;
  2098. }
  2099. if (bConvert)
  2100. {
  2101. try
  2102. {
  2103. ProbeAndReadBuffer(prgnTmp, prgn, cj);
  2104. hrgn = (HRGN)1;
  2105. }
  2106. except(EXCEPTION_EXECUTE_HANDLER)
  2107. {
  2108. WARNINGX(16);
  2109. // SetLastError(GetExceptionCode());
  2110. }
  2111. }
  2112. if (hrgn)
  2113. hrgn = GreExtCreateRegion((XFORML *)px,cj,prgnTmp);
  2114. FreeTmpBuffer(prgnTmp);
  2115. }
  2116. else
  2117. {
  2118. // fail to allocate memory
  2119. // SetLastError();
  2120. }
  2121. }
  2122. return(hrgn);
  2123. }
  2124. /******************************Public*Routine******************************\
  2125. * NtGdiPolyDraw()
  2126. *
  2127. * History:
  2128. * 01-Nov-1994 -by- Eric Kutter [erick]
  2129. * Wrote it.
  2130. \**************************************************************************/
  2131. BOOL
  2132. APIENTRY
  2133. NtGdiPolyDraw(
  2134. HDC hdc,
  2135. LPPOINT ppt,
  2136. LPBYTE pjAttr,
  2137. ULONG cpt
  2138. )
  2139. {
  2140. BOOL bRet = TRUE;
  2141. BOOL bLocked = FALSE;
  2142. HANDLE hSecure1 = 0;
  2143. HANDLE hSecure2 = 0;
  2144. try
  2145. {
  2146. // Make sure lengths do not overflow.
  2147. //
  2148. // Note: sizeof(BYTE) < sizeof(POINT), so the single test
  2149. // suffices for both lengths
  2150. //
  2151. // Note: using MAXULONG instead of MAXIMUM_POOL_ALLOC (or the
  2152. // BALLOC_ macros) because we are not allocating memory.
  2153. if (cpt <= (MAXULONG / sizeof(POINT)))
  2154. {
  2155. ProbeForRead(ppt, cpt * sizeof(POINT), sizeof(DWORD));
  2156. ProbeForRead(pjAttr,cpt * sizeof(BYTE), sizeof(BYTE));
  2157. hSecure1 = MmSecureVirtualMemory(ppt, cpt * sizeof(POINT), PAGE_READONLY);
  2158. hSecure2 = MmSecureVirtualMemory(pjAttr, cpt * sizeof(BYTE), PAGE_READONLY);
  2159. }
  2160. if (!hSecure1 || !hSecure2)
  2161. {
  2162. bRet = FALSE;
  2163. }
  2164. }
  2165. except(EXCEPTION_EXECUTE_HANDLER)
  2166. {
  2167. WARNINGX(17);
  2168. // SetLastError(GetExceptionCode());
  2169. bRet = FALSE;
  2170. }
  2171. if (bRet)
  2172. {
  2173. bRet = GrePolyDraw(hdc,ppt,pjAttr,cpt);
  2174. }
  2175. if (hSecure1)
  2176. {
  2177. MmUnsecureVirtualMemory(hSecure1);
  2178. }
  2179. if (hSecure2)
  2180. {
  2181. MmUnsecureVirtualMemory(hSecure2);
  2182. }
  2183. return(bRet);
  2184. }
  2185. /******************************Public*Routine******************************\
  2186. * NtGdiPolyTextOutW
  2187. *
  2188. * Arguments:
  2189. *
  2190. * hdc - Handle to device context
  2191. * pptw - pointer to array of POLYTEXTW
  2192. * cStr - number of POLYTEXTW
  2193. *
  2194. * Return Value:
  2195. *
  2196. * Status
  2197. *
  2198. * History:
  2199. *
  2200. * 24-Mar-1995 -by- Mark Enstrom [marke]
  2201. *
  2202. \**************************************************************************/
  2203. BOOL
  2204. APIENTRY
  2205. NtGdiPolyTextOutW(
  2206. HDC hdc,
  2207. POLYTEXTW *pptw,
  2208. UINT cStr,
  2209. DWORD dwCodePage
  2210. )
  2211. {
  2212. BOOL bStatus = TRUE;
  2213. ULONG ulSize = sizeof(POLYTEXTW) * cStr;
  2214. ULONG ulIndex;
  2215. PPOLYTEXTW pPoly = NULL;
  2216. PBYTE pjBuffer;
  2217. PBYTE pjBufferEnd;
  2218. ULONG cjdx;
  2219. //
  2220. // Check for overflow
  2221. //
  2222. if (!BALLOC_OVERFLOW1(cStr,POLYTEXTW))
  2223. {
  2224. //
  2225. // add up size off all array elements
  2226. //
  2227. try
  2228. {
  2229. ProbeForRead(pptw,cStr * sizeof(POLYTEXTW),sizeof(ULONG));
  2230. for (ulIndex=0;ulIndex<cStr;ulIndex++)
  2231. {
  2232. int n = pptw[ulIndex].n;
  2233. ULONG ulTmp; // used to check for
  2234. // overflow of ulSize
  2235. //
  2236. // Pull count from each, also check for
  2237. // non-zero length and NULL string
  2238. //
  2239. ulTmp = ulSize;
  2240. ulSize += n * sizeof(WCHAR);
  2241. if (BALLOC_OVERFLOW1(n, WCHAR) || (ulSize < ulTmp))
  2242. {
  2243. bStatus = FALSE;
  2244. break;
  2245. }
  2246. if (pptw[ulIndex].pdx != (int *)NULL)
  2247. {
  2248. cjdx = n * sizeof(int);
  2249. if (pptw[ulIndex].uiFlags & ETO_PDY)
  2250. {
  2251. if (BALLOC_OVERFLOW1(n*2,int))
  2252. bStatus = FALSE;
  2253. cjdx *= 2;
  2254. }
  2255. else
  2256. {
  2257. if (BALLOC_OVERFLOW1(n,int))
  2258. bStatus = FALSE;
  2259. }
  2260. ulTmp = ulSize;
  2261. ulSize += cjdx;
  2262. if (!bStatus || (ulSize < ulTmp))
  2263. {
  2264. bStatus = FALSE;
  2265. break;
  2266. }
  2267. }
  2268. if (n != 0)
  2269. {
  2270. if (pptw[ulIndex].lpstr == NULL)
  2271. {
  2272. bStatus = FALSE;
  2273. break;
  2274. }
  2275. }
  2276. }
  2277. } except(EXCEPTION_EXECUTE_HANDLER)
  2278. {
  2279. WARNINGX(18);
  2280. // SetLastError(GetExceptionCode());
  2281. bStatus = FALSE;
  2282. }
  2283. }
  2284. else
  2285. {
  2286. bStatus = FALSE;
  2287. }
  2288. if (bStatus && ulSize)
  2289. {
  2290. pPoly = (PPOLYTEXTW)AllocFreeTmpBuffer(ulSize);
  2291. if (pPoly != (POLYTEXTW *)NULL)
  2292. {
  2293. try
  2294. {
  2295. // Note: pptw already read probed
  2296. RtlCopyMemory(pPoly,pptw,sizeof(POLYTEXTW) * cStr);
  2297. pjBuffer = ((PBYTE)pPoly) + sizeof(POLYTEXTW) * cStr;
  2298. pjBufferEnd = ((PBYTE)pPoly) + ulSize;
  2299. //
  2300. // copy strings and pdx into kernel mode
  2301. // buffer and update pointers. Copy all pdx
  2302. // values first, then copy strings to avoid
  2303. // unaligned accesses due to odd length strings...
  2304. //
  2305. for (ulIndex=0;ulIndex<cStr;ulIndex++)
  2306. {
  2307. //
  2308. // Pull count from each, also check for
  2309. // non-zero length and NULL string
  2310. //
  2311. if (pPoly[ulIndex].n != 0)
  2312. {
  2313. if (pPoly[ulIndex].pdx != (int *)NULL)
  2314. {
  2315. cjdx = pPoly[ulIndex].n * sizeof(int);
  2316. if (pPoly[ulIndex].uiFlags & ETO_PDY)
  2317. {
  2318. typedef struct _TWOINT
  2319. {
  2320. int i1;
  2321. int i2;
  2322. } TWOINT;
  2323. if (BALLOC_OVERFLOW1(pPoly[ulIndex].n,TWOINT))
  2324. {
  2325. bStatus = FALSE;
  2326. }
  2327. cjdx *= 2;
  2328. }
  2329. else
  2330. {
  2331. if (BALLOC_OVERFLOW1(pPoly[ulIndex].n,int))
  2332. {
  2333. bStatus = FALSE;
  2334. }
  2335. }
  2336. //
  2337. // Check for cjdx overflow and check that kernel
  2338. // mode buffer still has space.
  2339. //
  2340. if (!bStatus || ((pjBuffer + cjdx) > pjBufferEnd))
  2341. {
  2342. bStatus = FALSE; // need set if past end of
  2343. // KM buffer but compuation // overflowed but computa
  2344. // of cjdx didn't overflow
  2345. break;
  2346. }
  2347. ProbeAndReadAlignedBuffer(
  2348. pjBuffer,
  2349. pPoly[ulIndex].pdx,
  2350. cjdx, sizeof(int));
  2351. pPoly[ulIndex].pdx = (int *)pjBuffer;
  2352. pjBuffer += cjdx;
  2353. }
  2354. }
  2355. }
  2356. //
  2357. // now copy strings
  2358. //
  2359. if (bStatus)
  2360. {
  2361. for (ulIndex=0;ulIndex<cStr;ulIndex++)
  2362. {
  2363. //
  2364. // Pull count from each, also check for
  2365. // non-zero length and NULL string
  2366. //
  2367. if (pPoly[ulIndex].n != 0)
  2368. {
  2369. if (pPoly[ulIndex].lpstr != NULL)
  2370. {
  2371. ULONG StrSize = pPoly[ulIndex].n * sizeof(WCHAR);
  2372. //
  2373. // Check for overflow of StrSize and check
  2374. // that kernel mode buffer has space.
  2375. //
  2376. if (BALLOC_OVERFLOW1(pPoly[ulIndex].n, WCHAR) ||
  2377. ((pjBuffer + StrSize) > pjBufferEnd))
  2378. {
  2379. bStatus = FALSE;
  2380. break;
  2381. }
  2382. ProbeAndReadAlignedBuffer(
  2383. pjBuffer,
  2384. (PVOID)pPoly[ulIndex].lpstr,
  2385. StrSize,
  2386. sizeof(WCHAR));
  2387. pPoly[ulIndex].lpstr = (LPWSTR)pjBuffer;
  2388. pjBuffer += StrSize;
  2389. }
  2390. else
  2391. {
  2392. //
  2393. // data error, n != 0 but lpstr = NULL
  2394. //
  2395. bStatus = FALSE;
  2396. break;
  2397. }
  2398. }
  2399. }
  2400. }
  2401. } except(EXCEPTION_EXECUTE_HANDLER)
  2402. {
  2403. WARNINGX(19);
  2404. // SetLastError(GetExceptionCode());
  2405. bStatus = FALSE;
  2406. }
  2407. if (bStatus)
  2408. {
  2409. //
  2410. // Finally ready to call gre function
  2411. //
  2412. bStatus = GrePolyTextOutW(hdc,pPoly,cStr,dwCodePage);
  2413. }
  2414. FreeTmpBuffer(pPoly);
  2415. }
  2416. else
  2417. {
  2418. WARNING("NtGdiPolyTextOut failed to allocate memory\n");
  2419. bStatus = FALSE;
  2420. }
  2421. }
  2422. return(bStatus);
  2423. }
  2424. /******************************Public*Routine******************************\
  2425. * NtGdiRectVisible()
  2426. *
  2427. * History:
  2428. * 01-Nov-1994 -by- Eric Kutter [erick]
  2429. * Wrote it.
  2430. * 24-Feb-1995 -by- Lingyun Wang [lingyunw]
  2431. * Expanded it.
  2432. \**************************************************************************/
  2433. BOOL
  2434. APIENTRY
  2435. NtGdiRectVisible(
  2436. HDC hdc,
  2437. LPRECT prc
  2438. )
  2439. {
  2440. DWORD dwRet;
  2441. RECT rc;
  2442. try
  2443. {
  2444. rc = ProbeAndReadStructure(prc,RECT);
  2445. dwRet = 1;
  2446. }
  2447. except(EXCEPTION_EXECUTE_HANDLER)
  2448. {
  2449. WARNINGX(22);
  2450. // SetLastError(GetExceptionCode());
  2451. dwRet = 0;
  2452. }
  2453. if (dwRet)
  2454. {
  2455. dwRet = GreRectVisible(hdc,&rc);
  2456. }
  2457. return(dwRet);
  2458. }
  2459. /******************************Public*Routine******************************\
  2460. * NtGdiSetMetaRgn()
  2461. *
  2462. * History:
  2463. * 01-Nov-1994 -by- Eric Kutter [erick]
  2464. * Wrote it.
  2465. \**************************************************************************/
  2466. int
  2467. APIENTRY
  2468. NtGdiSetMetaRgn(
  2469. HDC hdc
  2470. )
  2471. {
  2472. return(GreSetMetaRgn(hdc));
  2473. }
  2474. /******************************Public*Routine******************************\
  2475. * NtGdiGetAppClipBox()
  2476. *
  2477. * History:
  2478. * 01-Nov-1994 -by- Eric Kutter [erick]
  2479. * Wrote it.
  2480. \**************************************************************************/
  2481. int
  2482. APIENTRY
  2483. NtGdiGetAppClipBox(
  2484. HDC hdc,
  2485. LPRECT prc
  2486. )
  2487. {
  2488. int iRet;
  2489. RECT rc;
  2490. iRet = GreGetAppClipBox(hdc,&rc);
  2491. if (iRet != ERROR)
  2492. {
  2493. try
  2494. {
  2495. ProbeAndWriteStructure(prc,rc,RECT);
  2496. }
  2497. except(EXCEPTION_EXECUTE_HANDLER)
  2498. {
  2499. WARNINGX(23);
  2500. // SetLastError(GetExceptionCode());
  2501. iRet = 0;
  2502. }
  2503. }
  2504. return(iRet);
  2505. }
  2506. /******************************Public*Routine******************************\
  2507. * NtGdiGetTextExtentEx()
  2508. *
  2509. * History:
  2510. * Fri 06-Oct-1995 -by- Bodin Dresevic [BodinD]
  2511. * Rewrote it.
  2512. * 07-Feb-1995 -by- Andre Vachon [andreva]
  2513. * Wrote it.
  2514. \**************************************************************************/
  2515. #define LOCAL_CWC_MAX 16
  2516. BOOL
  2517. APIENTRY
  2518. NtGdiGetTextExtentExW(
  2519. HDC hdc,
  2520. LPWSTR lpwsz,
  2521. ULONG cwc,
  2522. ULONG dxMax,
  2523. ULONG *pcCh,
  2524. PULONG pdxOut,
  2525. LPSIZE psize,
  2526. FLONG fl
  2527. )
  2528. {
  2529. SIZE size;
  2530. ULONG cCh = 0;
  2531. ULONG Localpdx[LOCAL_CWC_MAX];
  2532. WCHAR Localpwsz[LOCAL_CWC_MAX];
  2533. PWSZ pwszCapt = NULL;
  2534. PULONG pdxCapt = NULL;
  2535. BOOL UseLocals = FALSE;
  2536. BOOL bRet = FALSE;
  2537. BOOL b;
  2538. if ( (b = (psize != NULL)) )
  2539. {
  2540. if (cwc == 0)
  2541. {
  2542. cCh = 0;
  2543. size.cx = 0;
  2544. size.cy = 0;
  2545. bRet = TRUE;
  2546. }
  2547. else
  2548. {
  2549. // capture the string
  2550. // NULL string causes failiure.
  2551. if ( cwc > LOCAL_CWC_MAX ) {
  2552. UseLocals = FALSE;
  2553. } else {
  2554. UseLocals = TRUE;
  2555. }
  2556. if (lpwsz != NULL)
  2557. {
  2558. try
  2559. {
  2560. if ( UseLocals ) {
  2561. pwszCapt = Localpwsz;
  2562. pdxCapt = Localpdx;
  2563. } else {
  2564. if (cwc && !BALLOC_OVERFLOW2(cwc,ULONG,WCHAR))
  2565. {
  2566. pdxCapt = (PULONG) AllocFreeTmpBuffer(cwc * (sizeof(ULONG) + sizeof(WCHAR)));
  2567. }
  2568. pwszCapt = (PWSZ) &pdxCapt[cwc];
  2569. }
  2570. if (pdxCapt)
  2571. {
  2572. // Capture the string into the buffer.
  2573. ProbeAndReadBuffer(pwszCapt, lpwsz, cwc*sizeof(WCHAR));
  2574. bRet = TRUE;
  2575. }
  2576. }
  2577. except(EXCEPTION_EXECUTE_HANDLER)
  2578. {
  2579. WARNINGX(24);
  2580. // SetLastError(GetExceptionCode());
  2581. bRet = FALSE;
  2582. }
  2583. }
  2584. if (bRet)
  2585. {
  2586. bRet = GreGetTextExtentExW(hdc,
  2587. pwszCapt,
  2588. cwc,
  2589. pcCh ? dxMax : ULONG_MAX,
  2590. &cCh,
  2591. pdxOut ? pdxCapt : NULL,
  2592. &size, fl);
  2593. }
  2594. }
  2595. // Write the value back into the user mode buffer if the call succeded
  2596. if (bRet)
  2597. {
  2598. try
  2599. {
  2600. ProbeAndWriteStructure(psize,size,SIZE);
  2601. if (pcCh)
  2602. {
  2603. ProbeAndWriteUlong(pcCh,cCh);
  2604. }
  2605. // We will only try to copy the data if pcCh is not zero,
  2606. // and it is set to zero if cwc is zero.
  2607. if (cCh)
  2608. {
  2609. // only copy if the caller requested the data, and the
  2610. // data is present.
  2611. if (pdxOut && pdxCapt)
  2612. {
  2613. ProbeAndWriteAlignedBuffer(pdxOut, pdxCapt, cCh * sizeof(ULONG), sizeof(ULONG));
  2614. }
  2615. }
  2616. }
  2617. except(EXCEPTION_EXECUTE_HANDLER)
  2618. {
  2619. WARNINGX(25);
  2620. // SetLastError(GetExceptionCode());
  2621. bRet = FALSE;
  2622. }
  2623. }
  2624. if (!UseLocals && pdxCapt)
  2625. {
  2626. FreeTmpBuffer(pdxCapt);
  2627. }
  2628. }
  2629. return (bRet);
  2630. }
  2631. /******************************Public*Routine******************************\
  2632. * NtGdiGetCharABCWidthsW()
  2633. *
  2634. * Arguments:
  2635. *
  2636. * hdc - handle to device context
  2637. * wchFirst - first char (if pwch is NULL)
  2638. * cwch - Number of chars to get ABC widths for
  2639. * pwch - array of WCHARs (mat be NULL)
  2640. * bInteger - return int or float ABC values
  2641. * pvBuf - results buffer
  2642. *
  2643. * Return Value:
  2644. *
  2645. * BOOL Status
  2646. *
  2647. * History:
  2648. *
  2649. * 14-Mar-1995 -by- Mark Enstrom [marke]
  2650. *
  2651. \**************************************************************************/
  2652. BOOL
  2653. APIENTRY
  2654. NtGdiGetCharABCWidthsW(
  2655. HDC hdc,
  2656. UINT wchFirst,
  2657. ULONG cwch,
  2658. PWCHAR pwch,
  2659. FLONG fl,
  2660. PVOID pvBuf
  2661. )
  2662. {
  2663. BOOL bStatus = FALSE;
  2664. PVOID pTemp_pvBuf = NULL;
  2665. PWCHAR pTemp_pwc = (PWCHAR)NULL;
  2666. BOOL bUse_pwc = FALSE;
  2667. ULONG OutputBufferSize = 0;
  2668. if (pvBuf == NULL)
  2669. {
  2670. return(bStatus);
  2671. }
  2672. //
  2673. // allocate memory for buffers, pwch may be NULL
  2674. //
  2675. if (pwch != (PWCHAR)NULL)
  2676. {
  2677. bUse_pwc = TRUE;
  2678. if (cwch && !BALLOC_OVERFLOW1(cwch,WCHAR))
  2679. {
  2680. pTemp_pwc = (PWCHAR)PALLOCNOZ(cwch * sizeof(WCHAR),'pmtG');
  2681. }
  2682. }
  2683. if ((!bUse_pwc) || (pTemp_pwc != (PWCHAR)NULL))
  2684. {
  2685. if (fl & GCABCW_INT)
  2686. {
  2687. if (!BALLOC_OVERFLOW1(cwch,ABC))
  2688. {
  2689. pTemp_pvBuf = (PVOID)AllocFreeTmpBuffer(cwch * sizeof(ABC));
  2690. OutputBufferSize = cwch * sizeof(ABC);
  2691. }
  2692. }
  2693. else
  2694. {
  2695. if (!BALLOC_OVERFLOW1(cwch,ABCFLOAT))
  2696. {
  2697. pTemp_pvBuf = (PVOID)AllocFreeTmpBuffer(cwch * sizeof(ABCFLOAT));
  2698. OutputBufferSize = cwch * sizeof(ABCFLOAT);
  2699. }
  2700. }
  2701. if (pTemp_pvBuf != NULL)
  2702. {
  2703. BOOL bErr = FALSE;
  2704. //
  2705. // copy input data to kernel mode buffer, if needed
  2706. //
  2707. if (bUse_pwc)
  2708. {
  2709. try
  2710. {
  2711. ProbeAndReadBuffer(pTemp_pwc,pwch,cwch * sizeof(WCHAR));
  2712. }
  2713. except(EXCEPTION_EXECUTE_HANDLER)
  2714. {
  2715. WARNINGX(26);
  2716. // SetLastError(GetExceptionCode());
  2717. bErr = TRUE;
  2718. }
  2719. }
  2720. if (!bErr)
  2721. {
  2722. bStatus = GreGetCharABCWidthsW(hdc,wchFirst,cwch,pTemp_pwc,fl,pTemp_pvBuf);
  2723. //
  2724. // copy results from kernel mode buffer to user buffer
  2725. //
  2726. if (bStatus)
  2727. {
  2728. try
  2729. {
  2730. ProbeAndWriteBuffer(pvBuf,pTemp_pvBuf,OutputBufferSize);
  2731. }
  2732. except(EXCEPTION_EXECUTE_HANDLER)
  2733. {
  2734. WARNINGX(27);
  2735. // SetLastError(GetExceptionCode());
  2736. bStatus = FALSE;
  2737. }
  2738. }
  2739. }
  2740. FreeTmpBuffer(pTemp_pvBuf);
  2741. }
  2742. if (bUse_pwc)
  2743. {
  2744. if (pTemp_pwc)
  2745. VFREEMEM(pTemp_pwc);
  2746. }
  2747. }
  2748. return(bStatus);
  2749. }
  2750. /******************************Public*Routine******************************\
  2751. * NtGdiAngleArc()
  2752. *
  2753. * History:
  2754. * 01-Nov-1994 -by- Eric Kutter [erick]
  2755. * Wrote it.
  2756. \**************************************************************************/
  2757. BOOL
  2758. APIENTRY
  2759. NtGdiAngleArc(
  2760. HDC hdc,
  2761. int x,
  2762. int y,
  2763. DWORD dwRadius,
  2764. DWORD dwStartAngle,
  2765. DWORD dwSweepAngle
  2766. )
  2767. {
  2768. FLOATL l_eStartAngle;
  2769. FLOATL l_eSweepAngle;
  2770. // Validate arguments and cast to floats
  2771. BOOL bRet = (bConvertDwordToFloat(dwStartAngle, &l_eStartAngle) &&
  2772. bConvertDwordToFloat(dwSweepAngle ,&l_eSweepAngle));
  2773. if (bRet)
  2774. {
  2775. bRet = GreAngleArc(hdc,x,y,dwRadius,l_eStartAngle,l_eSweepAngle);
  2776. }
  2777. return bRet;
  2778. }
  2779. /******************************Public*Routine******************************\
  2780. * NtGdiSetMiterLimit()
  2781. *
  2782. * History:
  2783. * 01-Nov-1994 -by- Eric Kutter [erick]
  2784. * Wrote it.
  2785. \**************************************************************************/
  2786. BOOL
  2787. APIENTRY
  2788. NtGdiSetMiterLimit(
  2789. HDC hdc,
  2790. DWORD dwNew,
  2791. PDWORD pdwOut
  2792. )
  2793. {
  2794. BOOL bRet = TRUE;
  2795. FLOATL l_e;
  2796. FLOATL l_eNew;
  2797. ASSERTGDI(sizeof(FLOATL) == sizeof(DWORD),"sizeof(FLOATL) != sizeof(DWORD)\n");
  2798. // Validate argument and cast to float
  2799. bRet = bConvertDwordToFloat(dwNew, &l_eNew);
  2800. if (bRet)
  2801. {
  2802. bRet = GreSetMiterLimit(hdc,l_eNew,&l_e);
  2803. }
  2804. if (bRet && pdwOut)
  2805. {
  2806. try
  2807. {
  2808. ProbeAndWriteAlignedBuffer(pdwOut, &l_e, sizeof(DWORD), sizeof(DWORD));
  2809. }
  2810. except(EXCEPTION_EXECUTE_HANDLER)
  2811. {
  2812. WARNINGX(113);
  2813. // SetLastError(GetExceptionCode());
  2814. bRet = 0;
  2815. }
  2816. }
  2817. return(bRet);
  2818. }
  2819. /******************************Public*Routine******************************\
  2820. * NtGdiSetFontXform()
  2821. *
  2822. * History:
  2823. * 01-Nov-1994 -by- Eric Kutter [erick]
  2824. * Wrote it.
  2825. \**************************************************************************/
  2826. BOOL
  2827. APIENTRY
  2828. NtGdiSetFontXform(
  2829. HDC hdc,
  2830. DWORD dwxScale,
  2831. DWORD dwyScale
  2832. )
  2833. {
  2834. FLOATL l_exScale;
  2835. FLOATL l_eyScale;
  2836. // Validate arguments and cast to floats
  2837. BOOL bRet = (bConvertDwordToFloat (dwxScale, &l_exScale) &&
  2838. bConvertDwordToFloat (dwyScale, &l_eyScale));
  2839. if (bRet)
  2840. {
  2841. bRet = GreSetFontXform(hdc,l_exScale,l_eyScale);
  2842. }
  2843. return bRet;
  2844. }
  2845. /******************************Public*Routine******************************\
  2846. * NtGdiGetMiterLimit()
  2847. *
  2848. * History:
  2849. * 01-Nov-1994 -by- Eric Kutter [erick]
  2850. * Wrote it.
  2851. \**************************************************************************/
  2852. BOOL
  2853. APIENTRY
  2854. NtGdiGetMiterLimit(
  2855. HDC hdc,
  2856. PDWORD pdwOut
  2857. )
  2858. {
  2859. BOOL bRet;
  2860. FLOATL l_e;
  2861. bRet = GreGetMiterLimit(hdc,&l_e);
  2862. if (bRet)
  2863. {
  2864. try
  2865. {
  2866. ProbeAndWriteAlignedBuffer(pdwOut, &l_e, sizeof(DWORD), sizeof(DWORD));
  2867. }
  2868. except(EXCEPTION_EXECUTE_HANDLER)
  2869. {
  2870. WARNINGX(29);
  2871. // SetLastError(GetExceptionCode());
  2872. bRet = 0;
  2873. }
  2874. }
  2875. return(bRet);
  2876. }
  2877. /******************************Public*Routine******************************\
  2878. * NtGdiMaskBlt()
  2879. *
  2880. * History:
  2881. * 01-Nov-1994 -by- Eric Kutter [erick]
  2882. * Wrote it.
  2883. \**************************************************************************/
  2884. BOOL
  2885. APIENTRY
  2886. NtGdiMaskBlt(
  2887. HDC hdc,
  2888. int xDst,
  2889. int yDst,
  2890. int cx,
  2891. int cy,
  2892. HDC hdcSrc,
  2893. int xSrc,
  2894. int ySrc,
  2895. HBITMAP hbmMask,
  2896. int xMask,
  2897. int yMask,
  2898. DWORD dwRop4,
  2899. DWORD crBackColor
  2900. )
  2901. {
  2902. return(GreMaskBlt(
  2903. hdc,xDst,yDst,cx,cy,
  2904. hdcSrc,xSrc,ySrc,
  2905. hbmMask,xMask,yMask,
  2906. dwRop4,crBackColor
  2907. ));
  2908. }
  2909. /******************************Public*Routine******************************\
  2910. * NtGdiGetCharWidthW
  2911. *
  2912. * History:
  2913. *
  2914. * 10-Mar-1995 -by- Mark Enstrom [marke]
  2915. *
  2916. \**************************************************************************/
  2917. BOOL
  2918. APIENTRY
  2919. NtGdiGetCharWidthW(
  2920. HDC hdc,
  2921. UINT wcFirst,
  2922. UINT cwc,
  2923. PWCHAR pwc,
  2924. FLONG fl,
  2925. PVOID pvBuf
  2926. )
  2927. {
  2928. BOOL bStatus = FALSE;
  2929. PVOID pTemp_pvBuf = NULL;
  2930. PWCHAR pTemp_pwc = (PWCHAR)NULL;
  2931. BOOL bUse_pwc = FALSE;
  2932. //
  2933. // allocate memory for buffers, pwc may be NULL
  2934. //
  2935. if (!cwc)
  2936. {
  2937. return(FALSE);
  2938. }
  2939. if (pwc != (PWCHAR)NULL)
  2940. {
  2941. bUse_pwc = TRUE;
  2942. if (!BALLOC_OVERFLOW1(cwc,WCHAR))
  2943. {
  2944. pTemp_pwc = (PWCHAR)PALLOCNOZ(cwc * sizeof(WCHAR),'pmtG');
  2945. }
  2946. }
  2947. if ((!bUse_pwc) || (pTemp_pwc != (PWCHAR)NULL))
  2948. {
  2949. if (!BALLOC_OVERFLOW1(cwc,ULONG))
  2950. {
  2951. pTemp_pvBuf = (PVOID)AllocFreeTmpBuffer(cwc * sizeof(ULONG));
  2952. }
  2953. if (pTemp_pvBuf != NULL)
  2954. {
  2955. //
  2956. // copy input data to kernel mode buffer, if needed
  2957. //
  2958. if (bUse_pwc)
  2959. {
  2960. try
  2961. {
  2962. ProbeAndReadBuffer(pTemp_pwc,pwc,cwc * sizeof(WCHAR));
  2963. }
  2964. except(EXCEPTION_EXECUTE_HANDLER)
  2965. {
  2966. WARNINGX(30);
  2967. // SetLastError(GetExceptionCode());
  2968. bStatus = FALSE;
  2969. }
  2970. }
  2971. bStatus = GreGetCharWidthW(hdc,wcFirst,cwc,pTemp_pwc,fl,pTemp_pvBuf);
  2972. //
  2973. // copy results from kernel mode buffer to user buffer
  2974. //
  2975. if (bStatus)
  2976. {
  2977. try
  2978. {
  2979. ProbeAndWriteBuffer(pvBuf,pTemp_pvBuf,cwc * sizeof(ULONG));
  2980. }
  2981. except(EXCEPTION_EXECUTE_HANDLER)
  2982. {
  2983. WARNINGX(31);
  2984. // SetLastError(GetExceptionCode());
  2985. bStatus = FALSE;
  2986. }
  2987. }
  2988. FreeTmpBuffer(pTemp_pvBuf);
  2989. }
  2990. if (bUse_pwc)
  2991. {
  2992. VFREEMEM(pTemp_pwc);
  2993. }
  2994. }
  2995. return(bStatus);
  2996. }
  2997. /******************************Public*Routine******************************\
  2998. * NtGdiDrawEscape
  2999. *
  3000. * Arguments:
  3001. *
  3002. * hdc - handle of device context
  3003. * iEsc - specifies escape function
  3004. * cjIn - size of structure for input
  3005. * pjIn - address of structure for input
  3006. *
  3007. * Return Value:
  3008. *
  3009. * > 0 if successful
  3010. * == 0 if function not supported
  3011. * < 0 if error
  3012. *
  3013. * History:
  3014. *
  3015. * 16-Mar-1995 -by- Mark Enstrom [marke]
  3016. *
  3017. \**************************************************************************/
  3018. #define DRAWESCAPE_BUFFER_SIZE 64
  3019. int
  3020. APIENTRY
  3021. NtGdiDrawEscape(
  3022. HDC hdc,
  3023. int iEsc,
  3024. int cjIn,
  3025. LPSTR pjIn
  3026. )
  3027. {
  3028. int cRet = 0;
  3029. ULONG AllocSize;
  3030. UCHAR StackBuffer[DRAWESCAPE_BUFFER_SIZE];
  3031. LPSTR pCallBuffer = pjIn;
  3032. HANDLE hSecure = 0;
  3033. //
  3034. // Validate.
  3035. //
  3036. if (cjIn < 0)
  3037. {
  3038. return -1;
  3039. }
  3040. //
  3041. // Check cjIn is 0 for NULL pjIn
  3042. //
  3043. if (pjIn == (LPSTR)NULL)
  3044. {
  3045. if (cjIn != 0)
  3046. {
  3047. cRet = -1;
  3048. }
  3049. else
  3050. {
  3051. cRet = GreDrawEscape(hdc,iEsc,0,(LPSTR)NULL);
  3052. }
  3053. }
  3054. else
  3055. {
  3056. //
  3057. // Try to alloc off stack, otherwise lock buffer
  3058. //
  3059. AllocSize = (cjIn + 3) & ~0x03;
  3060. if (AllocSize <= DRAWESCAPE_BUFFER_SIZE)
  3061. {
  3062. pCallBuffer = (LPSTR)StackBuffer;
  3063. //
  3064. // copy data into buffer
  3065. //
  3066. try
  3067. {
  3068. ProbeAndReadBuffer(pCallBuffer,pjIn,cjIn);
  3069. }
  3070. except(EXCEPTION_EXECUTE_HANDLER)
  3071. {
  3072. WARNINGX(32);
  3073. // SetLastError(GetExceptionCode());
  3074. cRet = -1;
  3075. }
  3076. }
  3077. else
  3078. {
  3079. hSecure = MmSecureVirtualMemory(pjIn, cjIn, PAGE_READONLY);
  3080. if (hSecure == 0)
  3081. {
  3082. cRet = -1;
  3083. }
  3084. }
  3085. if (cRet >= 0)
  3086. {
  3087. cRet = GreDrawEscape(hdc,iEsc,cjIn,pCallBuffer);
  3088. }
  3089. if (hSecure)
  3090. {
  3091. MmUnsecureVirtualMemory(hSecure);
  3092. }
  3093. }
  3094. return(cRet);
  3095. }
  3096. /******************************Public*Routine******************************\
  3097. * NtGdiExtEscape
  3098. *
  3099. * Arguments:
  3100. *
  3101. * hdc - handle of device context
  3102. * pDriver - buffer containing name of font driver
  3103. * nDriver - length of driver name
  3104. * iEsc - escape function
  3105. * cjIn - size, in bytes, of input data structure
  3106. * pjIn - address of input structure
  3107. * cjOut - size, in bytes, of output data structure
  3108. * pjOut - address of output structure
  3109. *
  3110. * Return Value:
  3111. *
  3112. * > 0 : success
  3113. * == 0 : escape not implemented
  3114. * < 0 : error
  3115. *
  3116. * History:
  3117. *
  3118. * 17-Mar-1995 -by- Mark Enstrom [marke]
  3119. *
  3120. \**************************************************************************/
  3121. #define EXT_STACK_DATA_SIZE 32
  3122. int
  3123. APIENTRY
  3124. NtGdiExtEscape(
  3125. HDC hdc,
  3126. PWCHAR pDriver, // only used for NamedEscape call
  3127. int nDriver, // only used for NamedEscape call
  3128. int iEsc,
  3129. int cjIn,
  3130. LPSTR pjIn,
  3131. int cjOut,
  3132. LPSTR pjOut
  3133. )
  3134. {
  3135. UCHAR StackInputData[EXT_STACK_DATA_SIZE];
  3136. UCHAR StackOutputData[EXT_STACK_DATA_SIZE];
  3137. WCHAR StackDriver[EXT_STACK_DATA_SIZE];
  3138. HANDLE hSecureIn;
  3139. LPSTR pkmIn, pkmOut;
  3140. BOOL bAllocOut, bAllocIn, bAllocDriver;
  3141. PWCHAR pkmDriver = NULL;
  3142. BOOL bStatus = TRUE;
  3143. BOOL iRet = -1;
  3144. bAllocOut = bAllocIn = bAllocDriver = FALSE;
  3145. hSecureIn = NULL;
  3146. pkmIn = pkmOut = NULL;
  3147. if ((cjIn < 0) || (cjOut < 0) || (nDriver < 0))
  3148. {
  3149. WARNING("NtGdiExtEscape: negative count passed in\n");
  3150. bStatus = FALSE;
  3151. }
  3152. if (pDriver && bStatus)
  3153. {
  3154. if (nDriver <= EXT_STACK_DATA_SIZE-1)
  3155. {
  3156. pkmDriver = StackDriver;
  3157. }
  3158. else
  3159. {
  3160. if (!BALLOC_OVERFLOW1((nDriver+1),WCHAR))
  3161. {
  3162. pkmDriver = (WCHAR*)PALLOCNOZ((nDriver+1) * sizeof(WCHAR),'pmtG');
  3163. }
  3164. // even if we fail this is okay because we check for NULL before FREE
  3165. bAllocDriver = TRUE;
  3166. }
  3167. if (pkmDriver != NULL)
  3168. {
  3169. try
  3170. {
  3171. ProbeAndReadAlignedBuffer(pkmDriver,pDriver,nDriver*sizeof(WCHAR), sizeof(WCHAR));
  3172. pkmDriver[nDriver] = 0; // NULL terminate the string
  3173. }
  3174. except(EXCEPTION_EXECUTE_HANDLER)
  3175. {
  3176. WARNINGX(94);
  3177. bStatus = FALSE;
  3178. }
  3179. }
  3180. else
  3181. {
  3182. bStatus = FALSE;
  3183. }
  3184. }
  3185. if ((cjIn != 0) && bStatus)
  3186. {
  3187. try
  3188. {
  3189. if (cjIn <= EXT_STACK_DATA_SIZE)
  3190. {
  3191. pkmIn = (LPSTR) StackInputData;
  3192. ProbeAndReadBuffer(pkmIn, pjIn, cjIn);
  3193. }
  3194. else if (pkmDriver != NULL)
  3195. {
  3196. //
  3197. // make kernel copies for the fontdrv
  3198. // otherwise just secure the memory
  3199. //
  3200. pkmIn = (LPSTR)PALLOCNOZ(cjIn,'pmtG');
  3201. if (pkmIn != (LPSTR)NULL)
  3202. {
  3203. bAllocIn = TRUE;
  3204. try
  3205. {
  3206. ProbeAndReadBuffer(pkmIn,pjIn,cjIn);
  3207. }
  3208. except(EXCEPTION_EXECUTE_HANDLER)
  3209. {
  3210. WARNINGX(33);
  3211. // SetLastError(GetExceptionCode());
  3212. bStatus = FALSE;
  3213. }
  3214. }
  3215. else
  3216. {
  3217. bStatus = FALSE;
  3218. }
  3219. }
  3220. else
  3221. {
  3222. ProbeForRead(pjIn,cjIn,sizeof(BYTE));
  3223. if (hSecureIn = MmSecureVirtualMemory(pjIn, cjIn, PAGE_READONLY))
  3224. {
  3225. pkmIn = pjIn;
  3226. }
  3227. else
  3228. {
  3229. bStatus = FALSE;
  3230. }
  3231. }
  3232. }
  3233. except(EXCEPTION_EXECUTE_HANDLER)
  3234. {
  3235. WARNINGX(33);
  3236. bStatus = FALSE;
  3237. }
  3238. }
  3239. if ((cjOut != 0) && bStatus)
  3240. {
  3241. if (cjOut <= EXT_STACK_DATA_SIZE)
  3242. pkmOut = (LPSTR) StackOutputData;
  3243. else if (pkmOut = (LPSTR) PALLOCNOZ(cjOut, 'pmtG'))
  3244. bAllocOut = TRUE;
  3245. else
  3246. bStatus = FALSE;
  3247. // Security: zero initialize the return buffer or we may open
  3248. // a hole that returns old pool data or old kernel stack data.
  3249. if (pkmOut)
  3250. {
  3251. RtlZeroMemory((PVOID) pkmOut, cjOut);
  3252. }
  3253. }
  3254. if (bStatus)
  3255. {
  3256. iRet = (pkmDriver) ?
  3257. GreNamedEscape(pkmDriver, iEsc, cjIn, pkmIn, cjOut, pkmOut) :
  3258. GreExtEscape(hdc, iEsc, cjIn, pkmIn, cjOut, pkmOut);
  3259. if (cjOut != 0)
  3260. {
  3261. try
  3262. {
  3263. ProbeAndWriteBuffer(pjOut, pkmOut, cjOut);
  3264. }
  3265. except(EXCEPTION_EXECUTE_HANDLER)
  3266. {
  3267. WARNINGX(34);
  3268. iRet = -1;
  3269. }
  3270. }
  3271. }
  3272. if (hSecureIn)
  3273. MmUnsecureVirtualMemory(hSecureIn);
  3274. if (bAllocOut && pkmOut)
  3275. VFREEMEM(pkmOut);
  3276. if (bAllocIn && pkmIn)
  3277. VFREEMEM(pkmIn);
  3278. if (bAllocDriver && pkmDriver)
  3279. VFREEMEM(pkmDriver);
  3280. return(iRet);
  3281. }
  3282. /******************************Public*Routine******************************\
  3283. * NtGdiGetFontData()
  3284. *
  3285. * Arguments:
  3286. *
  3287. * hdc - handle to device context
  3288. * dwTable - name of a font metric table
  3289. * dwOffset - ffset from the beginning of the font metric table
  3290. * pvBuf - buffer to receive the font information
  3291. * cjBuf - length, in bytes, of the information to be retrieved
  3292. *
  3293. * Return Value:
  3294. *
  3295. * Count of byte written to buffer, of GDI_ERROR for failure
  3296. *
  3297. * History:
  3298. *
  3299. * 14-Mar-1995 -by- Mark Enstrom [marke]
  3300. *
  3301. \**************************************************************************/
  3302. ULONG
  3303. APIENTRY
  3304. NtGdiGetFontData(
  3305. HDC hdc,
  3306. DWORD dwTable,
  3307. DWORD dwOffset,
  3308. PVOID pvBuf,
  3309. ULONG cjBuf
  3310. )
  3311. {
  3312. PVOID pvkmBuf = NULL;
  3313. ULONG ReturnBytes = GDI_ERROR;
  3314. if (cjBuf == 0)
  3315. {
  3316. ReturnBytes = ulGetFontData(
  3317. hdc,
  3318. dwTable,
  3319. dwOffset,
  3320. pvkmBuf,
  3321. cjBuf);
  3322. }
  3323. else
  3324. {
  3325. pvkmBuf = AllocFreeTmpBuffer(cjBuf);
  3326. if (pvkmBuf != NULL)
  3327. {
  3328. ReturnBytes = ulGetFontData(
  3329. hdc,
  3330. dwTable,
  3331. dwOffset,
  3332. pvkmBuf,
  3333. cjBuf);
  3334. if (ReturnBytes != GDI_ERROR)
  3335. {
  3336. try
  3337. {
  3338. ProbeAndWriteBuffer(pvBuf,pvkmBuf,ReturnBytes);
  3339. }
  3340. except(EXCEPTION_EXECUTE_HANDLER)
  3341. {
  3342. WARNINGX(35);
  3343. // SetLastError(GetExceptionCode());
  3344. ReturnBytes = GDI_ERROR;
  3345. }
  3346. }
  3347. FreeTmpBuffer(pvkmBuf);
  3348. }
  3349. }
  3350. return(ReturnBytes);
  3351. }
  3352. /******************************Public*Routine******************************\
  3353. * NtGdiGetGlyphOutline
  3354. *
  3355. * Arguments:
  3356. *
  3357. * hdc - device context
  3358. * wch - character to query
  3359. * iFormat - format of data to return
  3360. * pgm - address of structure for metrics
  3361. * cjBuf - size of buffer for data
  3362. * pvBuf - address of buffer for data
  3363. * pmat2 - address of transformation matrix structure
  3364. * bIgnoreRotation - internal rotation flag
  3365. *
  3366. * Return Value:
  3367. *
  3368. * If the function succeeds, and GGO_BITMAP or GGO_NATIVE is specified,
  3369. * then return value is greater than zero.
  3370. * If the function succeeds, and GGO_METRICS is specified,
  3371. * then return value is zero.
  3372. * If GGO_BITMAP or GGO_NATIVE is specified,
  3373. * and the buffer size or address is zero,
  3374. * then return value specifies the required buffer size.
  3375. * If GGO_BITMAP or GGO_NATIVE is specified,
  3376. * and the function fails for other reasons,
  3377. * then return value is GDI_ERROR.
  3378. * If GGO_METRICS is specified, and the function fails,
  3379. * then return value is GDI_ERROR.
  3380. *
  3381. * History:
  3382. *
  3383. * 15-Mar-1995 -by- Mark Enstrom [marke]
  3384. *
  3385. \**************************************************************************/
  3386. ULONG
  3387. APIENTRY
  3388. NtGdiGetGlyphOutline(
  3389. HDC hdc,
  3390. WCHAR wch,
  3391. UINT iFormat,
  3392. LPGLYPHMETRICS pgm,
  3393. ULONG cjBuf,
  3394. PVOID pvBuf,
  3395. LPMAT2 pmat2,
  3396. BOOL bIgnoreRotation
  3397. )
  3398. {
  3399. // error return value of -1 from server.inc
  3400. DWORD dwRet = (DWORD)-1;
  3401. PVOID pvkmBuf;
  3402. MAT2 kmMat2;
  3403. GLYPHMETRICS kmGlyphMetrics;
  3404. // try to allocate buffer
  3405. pvkmBuf = (cjBuf) ? AllocFreeTmpBuffer(cjBuf) : NULL;
  3406. if ((pvkmBuf != NULL) || !cjBuf)
  3407. {
  3408. BOOL bStatus = TRUE;
  3409. // copy input structures
  3410. try
  3411. {
  3412. kmMat2 = ProbeAndReadStructure(pmat2,MAT2);
  3413. }
  3414. except(EXCEPTION_EXECUTE_HANDLER)
  3415. {
  3416. WARNINGX(36);
  3417. // SetLastError(GetExceptionCode());
  3418. bStatus = FALSE;
  3419. }
  3420. if (bStatus)
  3421. {
  3422. dwRet = GreGetGlyphOutlineInternal(
  3423. hdc,
  3424. wch,
  3425. iFormat,
  3426. &kmGlyphMetrics,
  3427. cjBuf,
  3428. pvkmBuf,
  3429. &kmMat2,
  3430. bIgnoreRotation);
  3431. if (dwRet != (DWORD)-1)
  3432. {
  3433. try
  3434. {
  3435. if( pvkmBuf )
  3436. {
  3437. ProbeAndWriteBuffer(pvBuf,pvkmBuf,cjBuf);
  3438. }
  3439. ProbeAndWriteStructure(pgm,kmGlyphMetrics,GLYPHMETRICS);
  3440. }
  3441. except(EXCEPTION_EXECUTE_HANDLER)
  3442. {
  3443. WARNINGX(37);
  3444. // SetLastError(GetExceptionCode());
  3445. dwRet = (DWORD)-1;
  3446. }
  3447. }
  3448. }
  3449. if( pvkmBuf )
  3450. {
  3451. FreeTmpBuffer(pvkmBuf);
  3452. }
  3453. }
  3454. return(dwRet);
  3455. }
  3456. /******************************Public*Routine******************************\
  3457. * NtGdiGetRasterizerCaps()
  3458. *
  3459. * History:
  3460. * 08-Mar-1995 -by- Mark Enstrom [marke]
  3461. * Wrote it.
  3462. \**************************************************************************/
  3463. BOOL
  3464. APIENTRY
  3465. NtGdiGetRasterizerCaps(
  3466. LPRASTERIZER_STATUS praststat,
  3467. ULONG cjBytes
  3468. )
  3469. {
  3470. BOOL bStatus = FALSE;
  3471. RASTERIZER_STATUS tempRasStatus;
  3472. if (praststat && cjBytes)
  3473. {
  3474. cjBytes = min(cjBytes, sizeof(RASTERIZER_STATUS));
  3475. if (GreGetRasterizerCaps(&tempRasStatus))
  3476. {
  3477. try
  3478. {
  3479. ProbeAndWriteAlignedBuffer(praststat, &tempRasStatus, cjBytes, sizeof(DWORD));
  3480. bStatus = TRUE;
  3481. }
  3482. except(EXCEPTION_EXECUTE_HANDLER)
  3483. {
  3484. WARNINGX(38);
  3485. // SetLastError(GetExceptionCode());
  3486. }
  3487. }
  3488. }
  3489. return(bStatus);
  3490. }
  3491. /******************************Public*Routine******************************\
  3492. * NtGdiGetKerningPairs
  3493. *
  3494. * Arguments:
  3495. *
  3496. * hdc - device context
  3497. * cPairs - number of pairs to retrieve
  3498. * pkpDst - Pointer to buffer to recieve kerning pairs data or NULL
  3499. *
  3500. * Return Value:
  3501. *
  3502. * If pkpDst is NULL, return number of Kerning pairs in font,
  3503. * otherwise return number of kerning pairs written to buffer.
  3504. * If failure, return 0
  3505. *
  3506. * History:
  3507. *
  3508. * 15-Mar-1995 -by- Mark Enstrom [marke]
  3509. *
  3510. \**************************************************************************/
  3511. ULONG
  3512. APIENTRY
  3513. NtGdiGetKerningPairs(
  3514. HDC hdc,
  3515. ULONG cPairs,
  3516. KERNINGPAIR *pkpDst
  3517. )
  3518. {
  3519. ULONG cRet = 0;
  3520. KERNINGPAIR *pkmKerningPair = (KERNINGPAIR *)NULL;
  3521. if (pkpDst != (KERNINGPAIR *)NULL)
  3522. {
  3523. if (!BALLOC_OVERFLOW1(cPairs,KERNINGPAIR))
  3524. {
  3525. pkmKerningPair = AllocFreeTmpBuffer(sizeof(KERNINGPAIR) * cPairs);
  3526. }
  3527. }
  3528. if ((pkpDst == (KERNINGPAIR *)NULL) ||
  3529. (pkmKerningPair != (KERNINGPAIR *)NULL))
  3530. {
  3531. cRet = GreGetKerningPairs(hdc,cPairs,pkmKerningPair);
  3532. //
  3533. // copy data out if needed
  3534. //
  3535. if (pkpDst != (KERNINGPAIR *)NULL)
  3536. {
  3537. if (cRet != 0)
  3538. {
  3539. try
  3540. {
  3541. ProbeAndWriteBuffer(pkpDst,pkmKerningPair,sizeof(KERNINGPAIR) * cRet);
  3542. }
  3543. except(EXCEPTION_EXECUTE_HANDLER)
  3544. {
  3545. WARNINGX(39);
  3546. // SetLastError(GetExceptionCode());
  3547. cRet = 0;
  3548. }
  3549. }
  3550. FreeTmpBuffer(pkmKerningPair);
  3551. }
  3552. }
  3553. return(cRet);
  3554. }
  3555. /******************************Public*Routine******************************\
  3556. * NtGdiGetObjectBitmapHandle()
  3557. *
  3558. * History:
  3559. * 01-Nov-1994 -by- Eric Kutter [erick]
  3560. * Wrote it.
  3561. \**************************************************************************/
  3562. HBITMAP
  3563. APIENTRY
  3564. NtGdiGetObjectBitmapHandle(
  3565. HBRUSH hbr,
  3566. UINT *piUsage
  3567. )
  3568. {
  3569. UINT iUsage;
  3570. HBITMAP hbitmap = (HBITMAP)1;
  3571. // error checking
  3572. int iType = LO_TYPE(hbr);
  3573. if ((iType != LO_BRUSH_TYPE) &&
  3574. (iType != LO_EXTPEN_TYPE))
  3575. {
  3576. return((HBITMAP)hbr);
  3577. }
  3578. hbitmap = GreGetObjectBitmapHandle(hbr,&iUsage);
  3579. if (hbitmap)
  3580. {
  3581. try
  3582. {
  3583. ProbeAndWriteUlong(piUsage,iUsage);
  3584. }
  3585. except(EXCEPTION_EXECUTE_HANDLER)
  3586. {
  3587. WARNINGX(40);
  3588. // SetLastError(GetExceptionCode());
  3589. hbitmap = (HBITMAP)0;
  3590. }
  3591. }
  3592. return (hbitmap);
  3593. }
  3594. /******************************Public*Routine******************************\
  3595. * NtGdiResetDC()
  3596. *
  3597. * History:
  3598. * 01-Nov-1994 -by- Eric Kutter [erick]
  3599. * Wrote it.
  3600. * 26-Feb-1995 -by- Lingyun Wang [lingyunw]
  3601. * Expanded it.
  3602. \**************************************************************************/
  3603. BOOL
  3604. APIENTRY
  3605. NtGdiResetDC(
  3606. HDC hdc,
  3607. LPDEVMODEW pdm,
  3608. BOOL *pbBanding,
  3609. DRIVER_INFO_2W *pDriverInfo2,
  3610. PVOID ppUMdhpdev
  3611. )
  3612. {
  3613. LPDEVMODEW pdmTmp = NULL;
  3614. DWORD dwTmp;
  3615. INT iRet = 1;
  3616. INT cj;
  3617. DRIVER_INFO_2W *pKmDriverInfo2 = NULL;
  3618. try
  3619. {
  3620. // Make a kernel mode copy of DEVMODEW structure
  3621. iRet = (pdm == NULL) ||
  3622. (pdmTmp = CaptureDEVMODEW(pdm)) != NULL;
  3623. // Make a kernel mode copy of DRIVER_INFO_2W structure
  3624. iRet = iRet &&
  3625. ((pDriverInfo2 == NULL) ||
  3626. (pKmDriverInfo2 = CaptureDriverInfo2W(pDriverInfo2)) != NULL);
  3627. }
  3628. except(EXCEPTION_EXECUTE_HANDLER)
  3629. {
  3630. WARNINGX(41);
  3631. iRet = 0;
  3632. }
  3633. if (iRet)
  3634. {
  3635. iRet = GreResetDCInternal(hdc,pdmTmp,&dwTmp, pKmDriverInfo2, ppUMdhpdev);
  3636. if (iRet)
  3637. {
  3638. try
  3639. {
  3640. ProbeAndWriteUlong(pbBanding,dwTmp);
  3641. }
  3642. except(EXCEPTION_EXECUTE_HANDLER)
  3643. {
  3644. WARNINGX(42);
  3645. // SetLastError(GetExceptionCode());
  3646. iRet = 0;
  3647. }
  3648. }
  3649. }
  3650. if (pdmTmp)
  3651. {
  3652. VFREETHREADMEM(pdmTmp);
  3653. }
  3654. vFreeDriverInfo2(pKmDriverInfo2);
  3655. return (iRet);
  3656. }
  3657. /******************************Public*Routine******************************\
  3658. * NtGdiSetBoundsRect()
  3659. *
  3660. * History:
  3661. * 01-Nov-1994 -by- Eric Kutter [erick]
  3662. * Wrote it.
  3663. \**************************************************************************/
  3664. DWORD
  3665. APIENTRY
  3666. NtGdiSetBoundsRect(
  3667. HDC hdc,
  3668. LPRECT prc,
  3669. DWORD f
  3670. )
  3671. {
  3672. DWORD dwRet=0;
  3673. RECT rc;
  3674. if (prc)
  3675. {
  3676. try
  3677. {
  3678. rc = ProbeAndReadStructure(prc,RECT);
  3679. prc = &rc;
  3680. dwRet = 1;
  3681. }
  3682. except(EXCEPTION_EXECUTE_HANDLER)
  3683. {
  3684. WARNINGX(43);
  3685. // SetLastError(GetExceptionCode());
  3686. dwRet = 0;
  3687. }
  3688. }
  3689. else
  3690. {
  3691. // can't use the DCB_ACCUMULATE without a rectangle
  3692. f &= ~DCB_ACCUMULATE;
  3693. dwRet = 1;
  3694. }
  3695. if (dwRet)
  3696. dwRet = GreSetBoundsRect(hdc,prc,f);
  3697. return(dwRet);
  3698. }
  3699. /******************************Public*Routine******************************\
  3700. * NtGdiGetColorAdjustment()
  3701. *
  3702. * History:
  3703. * 01-Nov-1994 -by- Eric Kutter [erick]
  3704. * Wrote it.
  3705. \**************************************************************************/
  3706. BOOL
  3707. APIENTRY
  3708. NtGdiGetColorAdjustment(
  3709. HDC hdc,
  3710. PCOLORADJUSTMENT pcaOut
  3711. )
  3712. {
  3713. BOOL bRet;
  3714. COLORADJUSTMENT ca;
  3715. bRet = GreGetColorAdjustment(hdc,&ca);
  3716. if (bRet)
  3717. {
  3718. try
  3719. {
  3720. ProbeAndWriteStructure(pcaOut,ca,COLORADJUSTMENT);
  3721. }
  3722. except(EXCEPTION_EXECUTE_HANDLER)
  3723. {
  3724. WARNINGX(44);
  3725. // SetLastError(GetExceptionCode());
  3726. bRet = 0;
  3727. }
  3728. }
  3729. return(bRet);
  3730. }
  3731. /******************************Public*Routine******************************\
  3732. * NtGdiSetColorAdjustment()
  3733. *
  3734. * History:
  3735. * 01-Nov-1994 -by- Eric Kutter [erick]
  3736. * Wrote it.
  3737. \**************************************************************************/
  3738. BOOL
  3739. APIENTRY
  3740. NtGdiSetColorAdjustment(
  3741. HDC hdc,
  3742. PCOLORADJUSTMENT pca
  3743. )
  3744. {
  3745. BOOL bRet;
  3746. COLORADJUSTMENT ca;
  3747. try
  3748. {
  3749. ca = ProbeAndReadStructure(pca,COLORADJUSTMENT);
  3750. bRet = 1;
  3751. }
  3752. except(EXCEPTION_EXECUTE_HANDLER)
  3753. {
  3754. WARNINGX(45);
  3755. // SetLastError(GetExceptionCode());
  3756. bRet = 0;
  3757. }
  3758. if (bRet)
  3759. {
  3760. // Range check all the adjustment values. Return FALSE if any of them
  3761. // is out of range.
  3762. if ((ca.caSize != sizeof(COLORADJUSTMENT)) ||
  3763. (ca.caIlluminantIndex > ILLUMINANT_MAX_INDEX) ||
  3764. ((ca.caRedGamma > RGB_GAMMA_MAX) ||
  3765. (ca.caRedGamma < RGB_GAMMA_MIN)) ||
  3766. ((ca.caGreenGamma > RGB_GAMMA_MAX) ||
  3767. (ca.caGreenGamma < RGB_GAMMA_MIN)) ||
  3768. ((ca.caBlueGamma > RGB_GAMMA_MAX) ||
  3769. (ca.caBlueGamma < RGB_GAMMA_MIN)) ||
  3770. ((ca.caReferenceBlack > REFERENCE_BLACK_MAX) ||
  3771. (ca.caReferenceBlack < REFERENCE_BLACK_MIN)) ||
  3772. ((ca.caReferenceWhite > REFERENCE_WHITE_MAX) ||
  3773. (ca.caReferenceWhite < REFERENCE_WHITE_MIN)) ||
  3774. ((ca.caContrast > COLOR_ADJ_MAX) ||
  3775. (ca.caContrast < COLOR_ADJ_MIN)) ||
  3776. ((ca.caBrightness > COLOR_ADJ_MAX) ||
  3777. (ca.caBrightness < COLOR_ADJ_MIN)) ||
  3778. ((ca.caColorfulness > COLOR_ADJ_MAX) ||
  3779. (ca.caColorfulness < COLOR_ADJ_MIN)) ||
  3780. ((ca.caRedGreenTint > COLOR_ADJ_MAX) ||
  3781. (ca.caRedGreenTint < COLOR_ADJ_MIN)))
  3782. {
  3783. bRet = 0;
  3784. }
  3785. else
  3786. {
  3787. bRet = GreSetColorAdjustment(hdc,&ca);
  3788. }
  3789. }
  3790. return(bRet);
  3791. }
  3792. /******************************Public*Routine******************************\
  3793. * NtGdiCancelDC()
  3794. *
  3795. * History:
  3796. * 01-Nov-1994 -by- Eric Kutter [erick]
  3797. * Wrote it.
  3798. \**************************************************************************/
  3799. BOOL
  3800. APIENTRY
  3801. NtGdiCancelDC(
  3802. HDC hdc
  3803. )
  3804. {
  3805. return(GreCancelDC(hdc));
  3806. }
  3807. //API's used by USER
  3808. /******************************Public*Routine******************************\
  3809. * NtGdiSelectBrush()
  3810. *
  3811. * History:
  3812. * 01-Nov-1994 -by- Eric Kutter [erick]
  3813. * Wrote it.
  3814. \**************************************************************************/
  3815. HBRUSH
  3816. APIENTRY
  3817. NtGdiSelectBrush(
  3818. HDC hdc,
  3819. HBRUSH hbrush
  3820. )
  3821. {
  3822. return(GreSelectBrush(hdc,(HANDLE)hbrush));
  3823. }
  3824. /******************************Public*Routine******************************\
  3825. * NtGdiSelectPen()
  3826. *
  3827. * History:
  3828. * 01-Nov-1994 -by- Eric Kutter [erick]
  3829. * Wrote it.
  3830. \**************************************************************************/
  3831. HPEN
  3832. APIENTRY
  3833. NtGdiSelectPen(
  3834. HDC hdc,
  3835. HPEN hpen
  3836. )
  3837. {
  3838. return(GreSelectPen(hdc,hpen));
  3839. }
  3840. /******************************Public*Routine******************************\
  3841. * NtGdiSelectFont()
  3842. *
  3843. * History:
  3844. * 18-Mar-1996 -by- Bodin Dresevic [BodinD]
  3845. * Wrote it.
  3846. \**************************************************************************/
  3847. HFONT
  3848. APIENTRY
  3849. NtGdiSelectFont(HDC hdc, HFONT hf)
  3850. {
  3851. return(GreSelectFont(hdc, hf));
  3852. }
  3853. /******************************Public*Routine******************************\
  3854. * NtGdiSelectBitmap()
  3855. *
  3856. * History:
  3857. * 01-Nov-1994 -by- Eric Kutter [erick]
  3858. * Wrote it.
  3859. \**************************************************************************/
  3860. HBITMAP
  3861. APIENTRY
  3862. NtGdiSelectBitmap(
  3863. HDC hdc,
  3864. HBITMAP hbm
  3865. )
  3866. {
  3867. return(hbmSelectBitmap(hdc,hbm,FALSE));
  3868. }
  3869. /******************************Public*Routine******************************\
  3870. * NtGdiExtSelectClipRgn()
  3871. *
  3872. * History:
  3873. * 01-Nov-1994 -by- Eric Kutter [erick]
  3874. * Wrote it.
  3875. \**************************************************************************/
  3876. int
  3877. APIENTRY
  3878. NtGdiExtSelectClipRgn(
  3879. HDC hdc,
  3880. HRGN hrgn,
  3881. int iMode
  3882. )
  3883. {
  3884. return(GreExtSelectClipRgn(hdc,hrgn,iMode));
  3885. }
  3886. /******************************Public*Routine******************************\
  3887. * NtGdiCreatePen()
  3888. *
  3889. * History:
  3890. * 01-Nov-1994 -by- Eric Kutter [erick]
  3891. * Wrote it.
  3892. \**************************************************************************/
  3893. HPEN
  3894. APIENTRY
  3895. NtGdiCreatePen(
  3896. int iPenStyle,
  3897. int iPenWidth,
  3898. COLORREF cr,
  3899. HBRUSH hbr
  3900. )
  3901. {
  3902. return(GreCreatePen(iPenStyle,iPenWidth,cr,hbr));
  3903. }
  3904. /******************************Public*Routine******************************\
  3905. *
  3906. *
  3907. * History:
  3908. * 01-Nov-1994 -by- Eric Kutter [erick]
  3909. * Wrote it.
  3910. \**************************************************************************/
  3911. BOOL
  3912. APIENTRY
  3913. NtGdiStretchBlt(
  3914. HDC hdcDst,
  3915. int xDst,
  3916. int yDst,
  3917. int cxDst,
  3918. int cyDst,
  3919. HDC hdcSrc,
  3920. int xSrc,
  3921. int ySrc,
  3922. int cxSrc,
  3923. int cySrc,
  3924. DWORD dwRop,
  3925. DWORD dwBackColor
  3926. )
  3927. {
  3928. return(GreStretchBlt(
  3929. hdcDst,xDst,yDst,cxDst,cyDst,
  3930. hdcSrc,xSrc,ySrc,cxSrc,cySrc,
  3931. dwRop,dwBackColor));
  3932. }
  3933. /******************************Public*Routine******************************\
  3934. * NtGdiMoveTo()
  3935. *
  3936. * History:
  3937. * 01-Nov-1994 -by- Eric Kutter [erick]
  3938. * Wrote it.
  3939. \**************************************************************************/
  3940. BOOL
  3941. APIENTRY
  3942. NtGdiMoveTo(
  3943. HDC hdc,
  3944. int x,
  3945. int y,
  3946. LPPOINT pptOut
  3947. )
  3948. {
  3949. BOOL bRet;
  3950. POINT pt;
  3951. bRet = GreMoveTo(hdc,x,y,&pt);
  3952. if (bRet && pptOut)
  3953. {
  3954. try
  3955. {
  3956. ProbeAndWriteStructure(pptOut,pt,POINT);
  3957. }
  3958. except(EXCEPTION_EXECUTE_HANDLER)
  3959. {
  3960. WARNINGX(47);
  3961. // SetLastError(GetExceptionCode());
  3962. bRet = 0;
  3963. }
  3964. }
  3965. return(bRet);
  3966. }
  3967. /******************************Public*Routine******************************\
  3968. * NtGdiGetDeviceCaps()
  3969. *
  3970. * History:
  3971. * 01-Nov-1994 -by- Eric Kutter [erick]
  3972. * Wrote it.
  3973. \**************************************************************************/
  3974. int
  3975. APIENTRY
  3976. NtGdiGetDeviceCaps(
  3977. HDC hdc,
  3978. int i
  3979. )
  3980. {
  3981. return(GreGetDeviceCaps(hdc,i));
  3982. }
  3983. /******************************Public*Routine******************************\
  3984. * NtGdiSaveDC()
  3985. *
  3986. * History:
  3987. * 01-Nov-1994 -by- Eric Kutter [erick]
  3988. * Wrote it.
  3989. \**************************************************************************/
  3990. int
  3991. APIENTRY
  3992. NtGdiSaveDC(
  3993. HDC hdc
  3994. )
  3995. {
  3996. return(GreSaveDC(hdc));
  3997. }
  3998. /******************************Public*Routine******************************\
  3999. * NtGdiRestoreDC()
  4000. *
  4001. * History:
  4002. * 01-Nov-1994 -by- Eric Kutter [erick]
  4003. * Wrote it.
  4004. \**************************************************************************/
  4005. BOOL
  4006. APIENTRY
  4007. NtGdiRestoreDC(
  4008. HDC hdc,
  4009. int iLevel
  4010. )
  4011. {
  4012. return(GreRestoreDC(hdc,iLevel));
  4013. }
  4014. /******************************Public*Routine******************************\
  4015. * NtGdiGetNearestColor()
  4016. *
  4017. * History:
  4018. * 01-Nov-1994 -by- Eric Kutter [erick]
  4019. * Wrote it.
  4020. \**************************************************************************/
  4021. COLORREF
  4022. APIENTRY
  4023. NtGdiGetNearestColor(
  4024. HDC hdc,
  4025. COLORREF cr
  4026. )
  4027. {
  4028. return(GreGetNearestColor(hdc,cr));
  4029. }
  4030. /******************************Public*Routine******************************\
  4031. * NtGdiGetSystemPaletteUse()
  4032. *
  4033. * History:
  4034. * 01-Nov-1994 -by- Eric Kutter [erick]
  4035. * Wrote it.
  4036. \**************************************************************************/
  4037. UINT
  4038. APIENTRY
  4039. NtGdiGetSystemPaletteUse(
  4040. HDC hdc
  4041. )
  4042. {
  4043. return(GreGetSystemPaletteUse(hdc));
  4044. }
  4045. /******************************Public*Routine******************************\
  4046. * NtGdiSetSystemPaletteUse()
  4047. *
  4048. * History:
  4049. * 01-Nov-1994 -by- Eric Kutter [erick]
  4050. * Wrote it.
  4051. \**************************************************************************/
  4052. UINT
  4053. APIENTRY
  4054. NtGdiSetSystemPaletteUse(
  4055. HDC hdc,
  4056. UINT ui
  4057. )
  4058. {
  4059. return(GreSetSystemPaletteUse(hdc,ui));
  4060. }
  4061. /******************************Public*Routine******************************\
  4062. * NtGdiGetRandomRgn()
  4063. *
  4064. * History:
  4065. * 01-Nov-1994 -by- Eric Kutter [erick]
  4066. * Wrote it.
  4067. \**************************************************************************/
  4068. int
  4069. APIENTRY
  4070. NtGdiGetRandomRgn(
  4071. HDC hdc,
  4072. HRGN hrgn,
  4073. int iRgn
  4074. )
  4075. {
  4076. return(GreGetRandomRgn(hdc,hrgn,iRgn));
  4077. }
  4078. /******************************Public*Routine******************************\
  4079. * NtGdiIntersectClipRect()
  4080. *
  4081. * History:
  4082. * 01-Nov-1994 -by- Eric Kutter [erick]
  4083. * Wrote it.
  4084. \**************************************************************************/
  4085. int
  4086. APIENTRY
  4087. NtGdiIntersectClipRect(
  4088. HDC hdc,
  4089. int xLeft,
  4090. int yTop,
  4091. int xRight,
  4092. int yBottom
  4093. )
  4094. {
  4095. return(GreIntersectClipRect(hdc,xLeft,yTop,xRight,yBottom));
  4096. }
  4097. /******************************Public*Routine******************************\
  4098. * NtGdiExcludeClipRect()
  4099. *
  4100. * History:
  4101. * 01-Nov-1994 -by- Eric Kutter [erick]
  4102. * Wrote it.
  4103. \**************************************************************************/
  4104. int
  4105. APIENTRY
  4106. NtGdiExcludeClipRect(
  4107. HDC hdc,
  4108. int xLeft,
  4109. int yTop,
  4110. int xRight,
  4111. int yBottom
  4112. )
  4113. {
  4114. return(GreExcludeClipRect(hdc,xLeft,yTop,xRight,yBottom));
  4115. }
  4116. /******************************Public*Routine******************************\
  4117. * NtGdiOpenDCW()
  4118. *
  4119. * History:
  4120. * 01-Nov-1994 -by- Eric Kutter [erick]
  4121. * Wrote it.
  4122. * 27-Feb-1995 -by- Lingyun Wang [lingyunw]
  4123. * Expanded it.
  4124. \**************************************************************************/
  4125. HDC
  4126. APIENTRY
  4127. NtGdiOpenDCW(
  4128. PUNICODE_STRING pustrDevice,
  4129. DEVMODEW * pdm,
  4130. PUNICODE_STRING pustrLogAddr,
  4131. ULONG iType,
  4132. HANDLE hspool,
  4133. DRIVER_INFO_2W *pDriverInfo2,
  4134. PVOID ppUMdhpdev
  4135. )
  4136. {
  4137. HDC hdc = NULL;
  4138. ULONG iRet = 0;
  4139. PWSZ pwszDevice = NULL;
  4140. LPDEVMODEW pdmTmp = NULL;
  4141. INT cjDevice;
  4142. PWSTR pwstrDevice;
  4143. DRIVER_INFO_2W *pKmDriverInfo2 = NULL;
  4144. //
  4145. // This API overloads the pwszDevice parameter.
  4146. //
  4147. // If pustrDevice is NULL, it is equivalent to calling with "DISPLAY"
  4148. // which means to get a DC on the current device, which is done by
  4149. // calling USER
  4150. //
  4151. if (pustrDevice == NULL)
  4152. {
  4153. hdc = UserGetDesktopDC(iType, FALSE, TRUE);
  4154. }
  4155. else
  4156. {
  4157. try
  4158. {
  4159. ProbeForRead(pustrDevice,sizeof(UNICODE_STRING), sizeof(CHAR));
  4160. cjDevice = pustrDevice->Length;
  4161. pwstrDevice = pustrDevice->Buffer;
  4162. if (cjDevice)
  4163. {
  4164. if (cjDevice <= (MAXIMUM_POOL_ALLOC - sizeof(WCHAR)))
  4165. {
  4166. pwszDevice = AllocFreeTmpBuffer(cjDevice + sizeof(WCHAR));
  4167. }
  4168. if (pwszDevice)
  4169. {
  4170. ProbeAndReadBuffer(pwszDevice,pwstrDevice,cjDevice);
  4171. pwszDevice[(cjDevice/sizeof(WCHAR))] = L'\0';
  4172. }
  4173. }
  4174. // Make a kernel copy of DEVMODEW structure
  4175. iRet = (pdm == NULL) ||
  4176. (pdmTmp = CaptureDEVMODEW(pdm)) != NULL;
  4177. // Make a kernel copy of DRIVER_INFO_2W structure
  4178. iRet = iRet &&
  4179. ((pDriverInfo2 == NULL) ||
  4180. (pKmDriverInfo2 = CaptureDriverInfo2W(pDriverInfo2)) != NULL);
  4181. }
  4182. except(EXCEPTION_EXECUTE_HANDLER)
  4183. {
  4184. WARNINGX(48);
  4185. // SetLastError(GetExceptionCode());
  4186. iRet = 0;
  4187. }
  4188. if (iRet)
  4189. {
  4190. hdc = hdcOpenDCW(pwszDevice,
  4191. pdmTmp,
  4192. iType,
  4193. hspool,
  4194. NULL,
  4195. pKmDriverInfo2,
  4196. ppUMdhpdev);
  4197. }
  4198. if (pwszDevice)
  4199. FreeTmpBuffer(pwszDevice);
  4200. if (pdmTmp)
  4201. VFREETHREADMEM(pdmTmp);
  4202. vFreeDriverInfo2(pKmDriverInfo2);
  4203. }
  4204. return (hdc);
  4205. }
  4206. /******************************Public*Routine******************************\
  4207. * NtGdiCreateCompatibleBitmap()
  4208. *
  4209. * History:
  4210. * 01-Nov-1994 -by- Eric Kutter [erick]
  4211. * Wrote it.
  4212. \**************************************************************************/
  4213. HBITMAP
  4214. APIENTRY
  4215. NtGdiCreateCompatibleBitmap(
  4216. HDC hdc,
  4217. int cx,
  4218. int cy
  4219. )
  4220. {
  4221. return(GreCreateCompatibleBitmap(hdc,cx,cy));
  4222. }
  4223. /******************************Public*Routine******************************\
  4224. * NtGdiCreateBitmap()
  4225. *
  4226. * History:
  4227. * 01-Nov-1994 -by- Eric Kutter [erick]
  4228. * Wrote it.
  4229. * 04-MAR-1995 -by- Lingyun Wang [lingyunw]
  4230. * Expanded it.
  4231. \**************************************************************************/
  4232. HBITMAP
  4233. APIENTRY
  4234. NtGdiCreateBitmap(
  4235. int cx,
  4236. int cy,
  4237. UINT cPlanes,
  4238. UINT cBPP,
  4239. LPBYTE pjInit
  4240. )
  4241. {
  4242. ULONG_PTR iRet = 1;
  4243. HANDLE hSecure = 0;
  4244. INT cj;
  4245. if (pjInit == (VOID *) NULL)
  4246. {
  4247. cj = 0;
  4248. }
  4249. else
  4250. {
  4251. // only needs to word aligned and sized
  4252. cj = noOverflowCJSCANW(cx,(WORD) cPlanes,(WORD) cBPP,cy);
  4253. if (cj == 0)
  4254. iRet = 0;
  4255. }
  4256. if (cj)
  4257. {
  4258. try
  4259. {
  4260. ProbeForRead(pjInit,cj,sizeof(BYTE));
  4261. hSecure = MmSecureVirtualMemory(pjInit, cj, PAGE_READONLY);
  4262. if (hSecure == 0)
  4263. {
  4264. iRet = 0;
  4265. }
  4266. }
  4267. except (EXCEPTION_EXECUTE_HANDLER)
  4268. {
  4269. WARNINGX(49);
  4270. iRet = 0;
  4271. }
  4272. }
  4273. // if we didn't hit an error above
  4274. if (iRet)
  4275. {
  4276. iRet = (ULONG_PTR)GreCreateBitmap(cx,cy,cPlanes,cBPP,pjInit);
  4277. }
  4278. if (hSecure)
  4279. {
  4280. MmUnsecureVirtualMemory(hSecure);
  4281. }
  4282. return((HBITMAP)iRet);
  4283. }
  4284. /******************************Public*Routine******************************\
  4285. * NtGdiSetBitmapAttributes()
  4286. *
  4287. * History:
  4288. * 27-Oct-2000 -by- Pravin Santiago [pravins]
  4289. * Wrote it.
  4290. \**************************************************************************/
  4291. HBITMAP
  4292. APIENTRY
  4293. NtGdiSetBitmapAttributes(
  4294. HBITMAP hbm,
  4295. DWORD dwFlags
  4296. )
  4297. {
  4298. if (dwFlags & SBA_STOCK)
  4299. return(GreMakeBitmapStock(hbm));
  4300. return (HBITMAP)0;
  4301. }
  4302. /******************************Public*Routine******************************\
  4303. * NtGdiClearBitmapAttributes()
  4304. *
  4305. * History:
  4306. * 27-Oct-2000 -by- Pravin Santiago [pravins]
  4307. * Wrote it.
  4308. \**************************************************************************/
  4309. HBITMAP
  4310. APIENTRY
  4311. NtGdiClearBitmapAttributes(
  4312. HBITMAP hbm,
  4313. DWORD dwFlags
  4314. )
  4315. {
  4316. if (dwFlags & SBA_STOCK)
  4317. return(GreMakeBitmapNonStock(hbm));
  4318. return (HBITMAP)0;
  4319. }
  4320. /******************************Public*Routine******************************\
  4321. * NtGdiSetBrushAttributes()
  4322. *
  4323. * History:
  4324. * 27-Oct-2000 -by- Pravin Santiago [pravins]
  4325. * Wrote it.
  4326. \**************************************************************************/
  4327. HBRUSH
  4328. APIENTRY
  4329. NtGdiSetBrushAttributes(
  4330. HBRUSH hbr,
  4331. DWORD dwFlags
  4332. )
  4333. {
  4334. if (dwFlags & SBA_STOCK)
  4335. return(GreMakeBrushStock(hbr));
  4336. return (HBRUSH)0;
  4337. }
  4338. /******************************Public*Routine******************************\
  4339. * NtGdiClearBrushAttributes()
  4340. *
  4341. * History:
  4342. * 27-Oct-2000 -by- Pravin Santiago [pravins]
  4343. * Wrote it.
  4344. \**************************************************************************/
  4345. HBRUSH
  4346. APIENTRY
  4347. NtGdiClearBrushAttributes(
  4348. HBRUSH hbr,
  4349. DWORD dwFlags
  4350. )
  4351. {
  4352. if (dwFlags & SBA_STOCK)
  4353. return(GreMakeBrushNonStock(hbr));
  4354. return (HBRUSH)0;
  4355. }
  4356. /******************************Public*Routine******************************\
  4357. * NtGdiCreateHalftonePalette()
  4358. *
  4359. * History:
  4360. * 01-Nov-1994 -by- Eric Kutter [erick]
  4361. * Wrote it.
  4362. \**************************************************************************/
  4363. HPALETTE
  4364. APIENTRY
  4365. NtGdiCreateHalftonePalette(
  4366. HDC hdc
  4367. )
  4368. {
  4369. return(GreCreateCompatibleHalftonePalette(hdc));
  4370. }
  4371. /******************************Public*Routine******************************\
  4372. * NtGdiGetStockObject()
  4373. *
  4374. * History:
  4375. * 01-Nov-1994 -by- Eric Kutter [erick]
  4376. * Wrote it.
  4377. \**************************************************************************/
  4378. HANDLE
  4379. APIENTRY
  4380. NtGdiGetStockObject(
  4381. int iObject
  4382. )
  4383. {
  4384. return(GreGetStockObject(iObject));
  4385. }
  4386. /******************************Public*Routine******************************\
  4387. * NtGdiExtGetObjectW()
  4388. *
  4389. * History:
  4390. * 01-Nov-1994 -by- Eric Kutter [erick]
  4391. * Wrote it.
  4392. \**************************************************************************/
  4393. int
  4394. APIENTRY
  4395. NtGdiExtGetObjectW(
  4396. HANDLE h,
  4397. int cj,
  4398. LPVOID pvOut
  4399. )
  4400. {
  4401. int iRet = 0;
  4402. union
  4403. {
  4404. BITMAP bm;
  4405. DIBSECTION ds;
  4406. EXTLOGPEN elp;
  4407. LOGPEN l;
  4408. LOGBRUSH lb;
  4409. LOGFONTW lf;
  4410. ENUMLOGFONTEXDVW elf;
  4411. LOGCOLORSPACEEXW lcsp;
  4412. } obj;
  4413. int iType = LO_TYPE(h);
  4414. int ci;
  4415. if ((cj < 0) || (cj > sizeof(obj)))
  4416. {
  4417. WARNING("GetObject size too big\n");
  4418. cj = sizeof(obj);
  4419. }
  4420. ci = cj;
  4421. //
  4422. // make the getobject call on brush
  4423. // still work even the app passes in
  4424. // a cj < sizeof(LOGBRUSH)
  4425. //
  4426. if (iType == LO_BRUSH_TYPE)
  4427. {
  4428. cj = sizeof(LOGBRUSH);
  4429. }
  4430. iRet = GreExtGetObjectW(h,cj,pvOut ? &obj : NULL);
  4431. if (iType == LO_BRUSH_TYPE)
  4432. {
  4433. cj = min(cj, ci);
  4434. }
  4435. if (iRet && pvOut)
  4436. {
  4437. try
  4438. {
  4439. ProbeAndWriteAlignedBuffer(pvOut,&obj,MIN(cj,iRet), sizeof(WORD));
  4440. }
  4441. except(EXCEPTION_EXECUTE_HANDLER)
  4442. {
  4443. WARNINGX(50);
  4444. // SetLastError(GetExceptionCode());
  4445. iRet = 0;
  4446. }
  4447. }
  4448. return(iRet);
  4449. }
  4450. /******************************Public*Routine******************************\
  4451. * NtGdiSetBrushOrg()
  4452. *
  4453. * History:
  4454. * 01-Nov-1994 -by- Eric Kutter [erick]
  4455. * Wrote it.
  4456. \**************************************************************************/
  4457. BOOL
  4458. APIENTRY
  4459. NtGdiSetBrushOrg(
  4460. HDC hdc,
  4461. int x,
  4462. int y,
  4463. LPPOINT pptOut
  4464. )
  4465. {
  4466. BOOL bRet;
  4467. POINT pt;
  4468. bRet = GreSetBrushOrg(hdc,x,y,&pt);
  4469. if (bRet && pptOut)
  4470. {
  4471. try
  4472. {
  4473. ProbeAndWriteStructure(pptOut,pt,POINT);
  4474. }
  4475. except(EXCEPTION_EXECUTE_HANDLER)
  4476. {
  4477. WARNINGX(51);
  4478. // SetLastError(GetExceptionCode());
  4479. bRet = 0;
  4480. }
  4481. }
  4482. return(bRet);
  4483. }
  4484. /******************************Public*Routine******************************\
  4485. * NtGdiUnrealizeObject()
  4486. *
  4487. * History:
  4488. * 01-Nov-1994 -by- Eric Kutter [erick]
  4489. * Wrote it.
  4490. \**************************************************************************/
  4491. BOOL
  4492. APIENTRY
  4493. NtGdiUnrealizeObject(
  4494. HANDLE h
  4495. )
  4496. {
  4497. return(GreUnrealizeObject(h));
  4498. }
  4499. /******************************Public*Routine******************************\
  4500. *
  4501. *
  4502. * History:
  4503. * 01-Nov-1994 -by- Eric Kutter [erick]
  4504. * Wrote it.
  4505. \**************************************************************************/
  4506. int
  4507. APIENTRY
  4508. NtGdiCombineRgn(
  4509. HRGN hrgnDst,
  4510. HRGN hrgnSrc1,
  4511. HRGN hrgnSrc2,
  4512. int iMode
  4513. )
  4514. {
  4515. return(GreCombineRgn(hrgnDst,hrgnSrc1,hrgnSrc2,iMode));
  4516. }
  4517. /******************************Public*Routine******************************\
  4518. * NtGdiSetRectRgn()
  4519. *
  4520. * History:
  4521. * 01-Nov-1994 -by- Eric Kutter [erick]
  4522. * Wrote it.
  4523. \**************************************************************************/
  4524. BOOL
  4525. APIENTRY
  4526. NtGdiSetRectRgn(
  4527. HRGN hrgn,
  4528. int xLeft,
  4529. int yTop,
  4530. int xRight,
  4531. int yBottom
  4532. )
  4533. {
  4534. return(GreSetRectRgn(hrgn,xLeft,yTop,xRight,yBottom));
  4535. }
  4536. /******************************Public*Routine******************************\
  4537. * NtGdiSetBitmapBits()
  4538. *
  4539. * History:
  4540. * 01-Nov-1994 -by- Eric Kutter [erick]
  4541. * Wrote it.
  4542. \**************************************************************************/
  4543. LONG
  4544. APIENTRY
  4545. NtGdiSetBitmapBits(
  4546. HBITMAP hbm,
  4547. ULONG cj,
  4548. PBYTE pjInit
  4549. )
  4550. {
  4551. LONG lRet = 1;
  4552. LONG lOffset = 0;
  4553. HANDLE hSecure = 0;
  4554. try
  4555. {
  4556. // Each scan is copied seperately
  4557. ProbeForRead(pjInit,cj,sizeof(BYTE));
  4558. hSecure = MmSecureVirtualMemory(pjInit, cj, PAGE_READONLY);
  4559. if (hSecure == 0)
  4560. {
  4561. lRet = 0;
  4562. }
  4563. }
  4564. except(EXCEPTION_EXECUTE_HANDLER)
  4565. {
  4566. WARNINGX(52);
  4567. // SetLastError(GetExceptionCode());
  4568. lRet = 0;
  4569. }
  4570. if (lRet)
  4571. lRet = GreSetBitmapBits(hbm,cj,pjInit,&lOffset);
  4572. if (hSecure)
  4573. {
  4574. MmUnsecureVirtualMemory(hSecure);
  4575. }
  4576. return (lRet);
  4577. }
  4578. /******************************Public*Routine******************************\
  4579. * NtGdiOffsetRgn()
  4580. *
  4581. * History:
  4582. * 01-Nov-1994 -by- Eric Kutter [erick]
  4583. * Wrote it.
  4584. \**************************************************************************/
  4585. int
  4586. APIENTRY
  4587. NtGdiOffsetRgn(
  4588. HRGN hrgn,
  4589. int cx,
  4590. int cy
  4591. )
  4592. {
  4593. return(GreOffsetRgn(hrgn,cx,cy));
  4594. }
  4595. /******************************Public*Routine******************************\
  4596. * NtGdiGetRgnBox()
  4597. *
  4598. * History:
  4599. * 01-Nov-1994 -by- Eric Kutter [erick]
  4600. * Wrote it.
  4601. * 24-Feb-1995 -by- Lingyun Wang [lingyunw]
  4602. * expanded it.
  4603. \**************************************************************************/
  4604. int
  4605. APIENTRY
  4606. NtGdiGetRgnBox(
  4607. HRGN hrgn,
  4608. LPRECT prcOut
  4609. )
  4610. {
  4611. RECT rc;
  4612. int iRet;
  4613. iRet = GreGetRgnBox(hrgn,&rc);
  4614. if (iRet)
  4615. {
  4616. try
  4617. {
  4618. ProbeAndWriteStructure(prcOut,rc,RECT);
  4619. }
  4620. except(EXCEPTION_EXECUTE_HANDLER)
  4621. {
  4622. WARNINGX(53);
  4623. // SetLastError(GetExceptionCode());
  4624. iRet = 0;
  4625. }
  4626. }
  4627. return(iRet);
  4628. }
  4629. /******************************Public*Routine******************************\
  4630. * NtGdiRectInRegion()
  4631. *
  4632. * History:
  4633. * 01-Nov-1994 -by- Eric Kutter [erick]
  4634. * Wrote it.
  4635. \**************************************************************************/
  4636. BOOL
  4637. APIENTRY
  4638. NtGdiRectInRegion(
  4639. HRGN hrgn,
  4640. LPRECT prcl
  4641. )
  4642. {
  4643. RECT rc;
  4644. BOOL bRet;
  4645. if (prcl)
  4646. {
  4647. RECT rclTmp;
  4648. bRet = TRUE;
  4649. try
  4650. {
  4651. rclTmp = ProbeAndReadStructure(prcl,RECT);
  4652. //
  4653. // Order the rectangle
  4654. //
  4655. if (rclTmp.left > rclTmp.right)
  4656. {
  4657. rc.left = rclTmp.right;
  4658. rc.right = rclTmp.left;
  4659. }
  4660. else
  4661. {
  4662. rc.left = rclTmp.left;
  4663. rc.right = rclTmp.right;
  4664. }
  4665. if (rclTmp.top > rclTmp.bottom)
  4666. {
  4667. rc.top = rclTmp.bottom;
  4668. rc.bottom = rclTmp.top;
  4669. }
  4670. else
  4671. {
  4672. rc.top = rclTmp.top;
  4673. rc.bottom = rclTmp.bottom;
  4674. }
  4675. }
  4676. except(EXCEPTION_EXECUTE_HANDLER)
  4677. {
  4678. WARNINGX(54);
  4679. // SetLastError(GetExceptionCode());
  4680. bRet = FALSE;
  4681. }
  4682. if (bRet)
  4683. {
  4684. bRet = GreRectInRegion(hrgn,&rc);
  4685. if (bRet)
  4686. {
  4687. try
  4688. {
  4689. ProbeAndWriteStructure(prcl,rc,RECT);
  4690. }
  4691. except(EXCEPTION_EXECUTE_HANDLER)
  4692. {
  4693. WARNINGX(55);
  4694. // SetLastError(GetExceptionCode());
  4695. bRet = FALSE;
  4696. }
  4697. }
  4698. }
  4699. }
  4700. else
  4701. {
  4702. bRet = FALSE;
  4703. }
  4704. return bRet;
  4705. }
  4706. /******************************Public*Routine******************************\
  4707. * NtGdiPtInRegion()
  4708. *
  4709. * History:
  4710. * 01-Nov-1994 -by- Eric Kutter [erick]
  4711. * Wrote it.
  4712. \**************************************************************************/
  4713. BOOL
  4714. APIENTRY
  4715. NtGdiPtInRegion(
  4716. HRGN hrgn,
  4717. int x,
  4718. int y
  4719. )
  4720. {
  4721. return(GrePtInRegion(hrgn,x,y));
  4722. }
  4723. /******************************Public*Routine******************************\
  4724. * NtGdiGetDIBitsInternal()
  4725. *
  4726. * History:
  4727. * 01-Nov-1994 -by- Eric Kutter [erick]
  4728. * Wrote it.
  4729. \**************************************************************************/
  4730. int
  4731. APIENTRY
  4732. NtGdiGetDIBitsInternal(
  4733. HDC hdc,
  4734. HBITMAP hbm,
  4735. UINT iStartScan,
  4736. UINT cScans,
  4737. LPBYTE pBits,
  4738. LPBITMAPINFO pbmi,
  4739. UINT iUsage,
  4740. UINT cjMaxBits,
  4741. UINT cjMaxInfo
  4742. )
  4743. {
  4744. int iRet = 0;
  4745. ULONG cjHeader = 0;
  4746. BOOL bNullWidth = TRUE;
  4747. HANDLE hSecure = 0;
  4748. union
  4749. {
  4750. BITMAPINFOHEADER bmih;
  4751. BITMAPCOREHEADER bmch;
  4752. } bmihTmp;
  4753. PBITMAPINFO pbmiTmp = (PBITMAPINFO)&bmihTmp.bmih;
  4754. // do some up front validation
  4755. if (((iUsage != DIB_RGB_COLORS) &&
  4756. (iUsage != DIB_PAL_COLORS) &&
  4757. (iUsage != DIB_PAL_INDICES)) ||
  4758. (pbmi == NULL) ||
  4759. (hbm == NULL))
  4760. {
  4761. return(0);
  4762. }
  4763. if (cScans == 0)
  4764. pBits = (PVOID) NULL;
  4765. try
  4766. {
  4767. //
  4768. // pbmi might not be aligned.
  4769. // First probe to get the size of the structure
  4770. // located in the first DWORD. Later, probe the
  4771. // actual structure size
  4772. //
  4773. ProbeForRead(pbmi,sizeof(DWORD),sizeof(BYTE));
  4774. // If the bitcount is zero, we will return only the bitmap info or core
  4775. // header without the color table. Otherwise, we always return the bitmap
  4776. // info with the color table.
  4777. {
  4778. ULONG StructureSize = pbmi->bmiHeader.biSize;
  4779. //
  4780. // probe the correct structure size,
  4781. // so that we can read/write entire of bitmap header.
  4782. //
  4783. ProbeForWrite(pbmi,StructureSize,sizeof(BYTE));
  4784. if (pBits == (PVOID) NULL)
  4785. {
  4786. if ((StructureSize == sizeof(BITMAPCOREHEADER)) &&
  4787. (((PBITMAPCOREINFO) pbmi)->bmciHeader.bcBitCount == 0))
  4788. {
  4789. cjHeader = sizeof(BITMAPCOREHEADER);
  4790. }
  4791. else if ((StructureSize >= sizeof(BITMAPINFOHEADER)) &&
  4792. (pbmi->bmiHeader.biBitCount == 0))
  4793. {
  4794. cjHeader = sizeof(BITMAPINFOHEADER);
  4795. }
  4796. }
  4797. }
  4798. // we just need the header so copy it.
  4799. if (cjHeader)
  4800. {
  4801. RtlCopyMemory(pbmiTmp,pbmi,cjHeader);
  4802. pbmiTmp->bmiHeader.biSize = cjHeader;
  4803. }
  4804. else
  4805. {
  4806. // We need to set biClrUsed to 0 so GreGetBitmapSize computes
  4807. // the correct values. biClrUsed is not a input, just output.
  4808. if (pbmi->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
  4809. {
  4810. // NOTE: We are going to modify bitmap header
  4811. // in user mode memory here
  4812. // that's why we need to do ProbeWrite()
  4813. pbmi->bmiHeader.biClrUsed = 0;
  4814. }
  4815. // We need more than just the header. This may include bits.
  4816. // Compute the the full size of the BITMAPINFO
  4817. cjHeader = GreGetBitmapSize(pbmi,iUsage);
  4818. if (cjHeader)
  4819. {
  4820. pbmiTmp = PALLOCMEM(cjHeader,'pmtG');
  4821. if (pbmiTmp)
  4822. {
  4823. // The earlier write probe does not probe all of the
  4824. // memory we might read in this case.
  4825. ProbeAndReadBuffer(pbmiTmp,pbmi,cjHeader);
  4826. // Now that it is safe, make sure it hasn't changed
  4827. if (GreGetBitmapSize(pbmiTmp,iUsage) != cjHeader)
  4828. {
  4829. cjHeader = 0;
  4830. }
  4831. else
  4832. {
  4833. // We need to set biClrUsed to 0 so GreGetBitmapSize computes
  4834. // the correct values. biClrUsed is not a input, just output.
  4835. if (pbmiTmp->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
  4836. {
  4837. pbmiTmp->bmiHeader.biClrUsed = 0;
  4838. }
  4839. // Get iStartScan and cNumScan in a valid range.
  4840. if (cScans)
  4841. {
  4842. if (pbmiTmp->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
  4843. {
  4844. ULONG ulHeight = ABS(pbmiTmp->bmiHeader.biHeight);
  4845. iStartScan = MIN(ulHeight, iStartScan);
  4846. cScans = MIN((ulHeight - iStartScan), cScans);
  4847. bNullWidth = (pbmiTmp->bmiHeader.biWidth == 0) ||
  4848. (pbmiTmp->bmiHeader.biPlanes == 0) ||
  4849. (pbmiTmp->bmiHeader.biBitCount == 0);
  4850. }
  4851. else
  4852. {
  4853. LPBITMAPCOREHEADER pbmc = (LPBITMAPCOREHEADER)pbmiTmp;
  4854. iStartScan = MIN((UINT)pbmc->bcHeight, iStartScan);
  4855. cScans = MIN((UINT)(pbmc->bcHeight - iStartScan), cScans);
  4856. bNullWidth = (pbmc->bcWidth == 0) ||
  4857. (pbmc->bcPlanes == 0) ||
  4858. (pbmc->bcBitCount == 0);
  4859. }
  4860. }
  4861. }
  4862. }
  4863. }
  4864. }
  4865. if (cjHeader && pBits && pbmiTmp)
  4866. {
  4867. // if they passed a buffer and it isn't BI_RGB,
  4868. // they must supply buffer size, 0 is an illegal value
  4869. if ((pbmiTmp->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
  4870. ((pbmiTmp->bmiHeader.biCompression == BI_RLE8) ||
  4871. (pbmiTmp->bmiHeader.biCompression == BI_RLE4)) &&
  4872. (pbmiTmp->bmiHeader.biSizeImage == 0))
  4873. {
  4874. cjHeader = 0;
  4875. }
  4876. else
  4877. {
  4878. if (cjMaxBits == 0)
  4879. cjMaxBits = GreGetBitmapBitsSize(pbmiTmp);
  4880. if (cjMaxBits)
  4881. {
  4882. ProbeForWrite(pBits,cjMaxBits,sizeof(DWORD));
  4883. hSecure = MmSecureVirtualMemory(pBits, cjMaxBits, PAGE_READWRITE);
  4884. }
  4885. if (hSecure == 0)
  4886. {
  4887. cjHeader = 0;
  4888. }
  4889. }
  4890. }
  4891. }
  4892. except(EXCEPTION_EXECUTE_HANDLER)
  4893. {
  4894. WARNINGX(56);
  4895. cjHeader = 0;
  4896. }
  4897. // did we have an error
  4898. if ((pBits && bNullWidth) || (cjHeader == 0) || (pbmiTmp == NULL))
  4899. {
  4900. //GdiSetLastError(ERROR_INVALID_PARAMETER);
  4901. iRet = 0;
  4902. }
  4903. else
  4904. {
  4905. // do the work
  4906. iRet = GreGetDIBitsInternal(
  4907. hdc,hbm,
  4908. iStartScan,cScans,
  4909. pBits,pbmiTmp,
  4910. iUsage,cjMaxBits,cjHeader
  4911. );
  4912. // copy out the header
  4913. if (iRet)
  4914. {
  4915. try
  4916. {
  4917. RtlCopyMemory(pbmi,pbmiTmp,cjHeader);
  4918. // WINBUG #83055 2-7-2000 bhouse Investigate need to unlock bits
  4919. // Old Comment:
  4920. // - we also need to unlock the bits
  4921. }
  4922. except(EXCEPTION_EXECUTE_HANDLER)
  4923. {
  4924. WARNINGX(57);
  4925. // SetLastError(GetExceptionCode());
  4926. iRet = 0;
  4927. }
  4928. }
  4929. }
  4930. if (hSecure)
  4931. {
  4932. MmUnsecureVirtualMemory(hSecure);
  4933. }
  4934. if (pbmiTmp && (pbmiTmp != (PBITMAPINFO)&bmihTmp.bmih))
  4935. VFREEMEM(pbmiTmp);
  4936. return(iRet);
  4937. }
  4938. /******************************Public*Routine******************************\
  4939. * NtGdiGetTextExtent(
  4940. *
  4941. * History:
  4942. * 07-Feb-1995 -by- Andre Vachon [andreva]
  4943. * Wrote it.
  4944. \**************************************************************************/
  4945. BOOL
  4946. APIENTRY
  4947. NtGdiGetTextExtent(
  4948. HDC hdc,
  4949. LPWSTR lpwsz,
  4950. int cwc,
  4951. LPSIZE psize,
  4952. UINT flOpts
  4953. )
  4954. {
  4955. SIZE size;
  4956. PWSZ pwszCapt = NULL;
  4957. WCHAR Localpwsz[LOCAL_CWC_MAX];
  4958. BOOL UseLocals;
  4959. BOOL bRet = FALSE;
  4960. if (cwc >= 0)
  4961. {
  4962. if (cwc == 0)
  4963. {
  4964. size.cx = 0;
  4965. size.cy = 0;
  4966. bRet = TRUE;
  4967. }
  4968. else
  4969. {
  4970. if ( cwc > LOCAL_CWC_MAX ) {
  4971. UseLocals = FALSE;
  4972. } else {
  4973. UseLocals = TRUE;
  4974. }
  4975. //
  4976. // capture the string
  4977. //
  4978. if (lpwsz != NULL)
  4979. {
  4980. try
  4981. {
  4982. if ( UseLocals )
  4983. {
  4984. pwszCapt = Localpwsz;
  4985. }
  4986. else
  4987. {
  4988. if (!BALLOC_OVERFLOW1(cwc,WCHAR))
  4989. {
  4990. pwszCapt = (PWSZ) AllocFreeTmpBuffer(cwc * sizeof(WCHAR));
  4991. }
  4992. }
  4993. if (pwszCapt)
  4994. {
  4995. ProbeAndReadAlignedBuffer(pwszCapt, lpwsz, cwc*sizeof(WCHAR), sizeof(WCHAR));
  4996. bRet = TRUE;
  4997. }
  4998. }
  4999. except(EXCEPTION_EXECUTE_HANDLER)
  5000. {
  5001. WARNINGX(58);
  5002. // SetLastError(GetExceptionCode());
  5003. bRet = FALSE;
  5004. }
  5005. }
  5006. if (bRet)
  5007. {
  5008. bRet = GreGetTextExtentW(hdc, pwszCapt, cwc, &size, flOpts);
  5009. }
  5010. if (!UseLocals && pwszCapt)
  5011. {
  5012. FreeTmpBuffer(pwszCapt);
  5013. }
  5014. }
  5015. //
  5016. // Write the value back into the user mode buffer
  5017. //
  5018. if (bRet)
  5019. {
  5020. try
  5021. {
  5022. ProbeAndWriteStructure(psize,size,SIZE);
  5023. }
  5024. except(EXCEPTION_EXECUTE_HANDLER)
  5025. {
  5026. WARNINGX(59);
  5027. // SetLastError(GetExceptionCode());
  5028. bRet = FALSE;
  5029. }
  5030. }
  5031. }
  5032. return (bRet);
  5033. }
  5034. /******************************Public*Routine******************************\
  5035. * NtGdiGetTextMetricsW()
  5036. *
  5037. * History:
  5038. * 01-Nov-1994 -by- Eric Kutter [erick]
  5039. * Wrote it.
  5040. \**************************************************************************/
  5041. BOOL
  5042. APIENTRY
  5043. NtGdiGetTextMetricsW(
  5044. HDC hdc,
  5045. TMW_INTERNAL * ptm,
  5046. ULONG cj
  5047. )
  5048. {
  5049. BOOL bRet = FALSE;
  5050. TMW_INTERNAL tmw;
  5051. if (cj <= sizeof(tmw))
  5052. {
  5053. bRet = GreGetTextMetricsW(hdc,&tmw);
  5054. if (bRet)
  5055. {
  5056. try
  5057. {
  5058. ProbeAndWriteAlignedBuffer(ptm,&tmw,cj, sizeof(DWORD));
  5059. }
  5060. except(EXCEPTION_EXECUTE_HANDLER)
  5061. {
  5062. WARNINGX(60);
  5063. // SetLastError(GetExceptionCode());
  5064. bRet = FALSE;
  5065. }
  5066. }
  5067. }
  5068. return(bRet);
  5069. }
  5070. /******************************Public*Routine******************************\
  5071. * NtGdiGetTextFaceW()
  5072. *
  5073. * History:
  5074. * 10-Mar-1995 -by- Mark Enstrom [marke]
  5075. * Wrote it.
  5076. \**************************************************************************/
  5077. int
  5078. APIENTRY
  5079. NtGdiGetTextFaceW(
  5080. HDC hdc,
  5081. int cChar,
  5082. LPWSTR pszOut,
  5083. BOOL bAliasName
  5084. )
  5085. {
  5086. int cRet = 0;
  5087. BOOL bStatus = TRUE;
  5088. PWCHAR pwsz_km = (PWCHAR)NULL;
  5089. if ((cChar > 0) && (pszOut))
  5090. {
  5091. if (!BALLOC_OVERFLOW1(cChar,WCHAR))
  5092. {
  5093. pwsz_km = AllocFreeTmpBuffer(cChar * sizeof(WCHAR));
  5094. }
  5095. if (pwsz_km == (PWCHAR)NULL)
  5096. {
  5097. bStatus = FALSE;
  5098. }
  5099. }
  5100. if (bStatus)
  5101. {
  5102. cRet = GreGetTextFaceW(hdc,cChar,pwsz_km, bAliasName);
  5103. if ((cRet > 0) && (pszOut))
  5104. {
  5105. ASSERTGDI(cRet <= cChar, "GreGetTextFaceW, cRet too big\n");
  5106. try
  5107. {
  5108. ProbeAndWriteBuffer(pszOut,pwsz_km,cRet * sizeof(WCHAR));
  5109. }
  5110. except(EXCEPTION_EXECUTE_HANDLER)
  5111. {
  5112. WARNINGX(61);
  5113. // SetLastError(GetExceptionCode());
  5114. cRet = 0;
  5115. }
  5116. }
  5117. if (pwsz_km != (PWCHAR)NULL)
  5118. {
  5119. FreeTmpBuffer(pwsz_km);
  5120. }
  5121. }
  5122. return(cRet);
  5123. }
  5124. /******************************Public*Routine******************************\
  5125. * NtGdiFontIsLinked()
  5126. *
  5127. * History:
  5128. * 9-July-1998 -by- Yung-Jen Tony Tsai [marke]
  5129. * Wrote it.
  5130. \**************************************************************************/
  5131. BOOL
  5132. APIENTRY
  5133. NtGdiFontIsLinked(
  5134. HDC hdc
  5135. )
  5136. {
  5137. return GreFontIsLinked(hdc);
  5138. }
  5139. /****************************************************************************
  5140. * NtGdiQueryFonts
  5141. *
  5142. * History:
  5143. * 5/24/1995 by Gerrit van Wingerden [gerritv]
  5144. * Wrote it.
  5145. *****************************************************************************/
  5146. INT NtGdiQueryFonts(
  5147. PUNIVERSAL_FONT_ID pufiFontList,
  5148. ULONG nBufferSize,
  5149. PLARGE_INTEGER pTimeStamp
  5150. )
  5151. {
  5152. INT iRet = 0;
  5153. PUNIVERSAL_FONT_ID pufi = NULL;
  5154. LARGE_INTEGER TimeStamp;
  5155. if( ( nBufferSize > 0 ) && ( pufiFontList != NULL ) )
  5156. {
  5157. if (!BALLOC_OVERFLOW1(nBufferSize,UNIVERSAL_FONT_ID))
  5158. {
  5159. pufi = AllocFreeTmpBuffer(nBufferSize * sizeof(UNIVERSAL_FONT_ID));
  5160. }
  5161. if( pufi == NULL )
  5162. {
  5163. iRet = -1 ;
  5164. }
  5165. }
  5166. if( iRet != -1 )
  5167. {
  5168. iRet = GreQueryFonts(pufi, nBufferSize, &TimeStamp );
  5169. if( iRet != -1 )
  5170. {
  5171. try
  5172. {
  5173. ProbeAndWriteStructure(pTimeStamp,TimeStamp,LARGE_INTEGER);
  5174. if( pufiFontList )
  5175. {
  5176. ProbeAndWriteAlignedBuffer(pufiFontList,pufi,
  5177. sizeof(UNIVERSAL_FONT_ID)*nBufferSize, sizeof(DWORD));
  5178. }
  5179. }
  5180. except(EXCEPTION_EXECUTE_HANDLER)
  5181. {
  5182. WARNINGX(62);
  5183. iRet = -1;
  5184. }
  5185. }
  5186. }
  5187. if( pufi != NULL )
  5188. {
  5189. FreeTmpBuffer( pufi );
  5190. }
  5191. if( iRet == -1 )
  5192. {
  5193. // We need to set the last error here to something because the spooler
  5194. // code that calls this relies on there being a non-zero error code
  5195. // in the case of failure. Since we really have no idea I will just
  5196. // set this to ERROR_NOT_ENOUGH_MEMORY which would be the most likely
  5197. // reason for a failure
  5198. EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  5199. }
  5200. return(iRet);
  5201. }
  5202. BOOL
  5203. GreExtTextOutRect(
  5204. HDC hdc,
  5205. LPRECT prcl
  5206. );
  5207. /******************************Public*Routine******************************\
  5208. * NtGdiExtTextOutW()
  5209. *
  5210. * History:
  5211. * 06-Feb-1995 -by- Andre Vachon [andreva]
  5212. * Wrote it.
  5213. \**************************************************************************/
  5214. BOOL NtGdiExtTextOutW
  5215. (
  5216. HDC hdc,
  5217. int x, // Initial x position
  5218. int y, // Initial y position
  5219. UINT flOpts, // Options
  5220. LPRECT prcl, // Clipping rectangle
  5221. LPWSTR pwsz, // UNICODE Character array
  5222. int cwc, // char count
  5223. LPINT pdx, // Character spacing
  5224. DWORD dwCodePage // Code page
  5225. )
  5226. {
  5227. RECT newRect;
  5228. BOOL bRet;
  5229. BYTE CaptureBuffer[TEXT_CAPTURE_BUFFER_SIZE];
  5230. BYTE *pjAlloc;
  5231. BYTE *pjCapture;
  5232. BYTE *pjStrobj;
  5233. LONG cjDx;
  5234. LONG cjStrobj;
  5235. LONG cjString;
  5236. LONG cj;
  5237. // huge values of cwc will lead to an overflow below causing the system to
  5238. // crash
  5239. if ((cwc < 0) || (cwc > 0xffff))
  5240. {
  5241. return(FALSE);
  5242. }
  5243. if (prcl)
  5244. {
  5245. if (flOpts & (ETO_OPAQUE | ETO_CLIPPED))
  5246. {
  5247. try
  5248. {
  5249. newRect = ProbeAndReadStructure(prcl,RECT);
  5250. prcl = &newRect;
  5251. }
  5252. except(EXCEPTION_EXECUTE_HANDLER)
  5253. {
  5254. WARNINGX(63);
  5255. // SetLastError(GetExceptionCode());
  5256. return FALSE;
  5257. }
  5258. }
  5259. else
  5260. prcl = NULL;
  5261. }
  5262. // 0 char case, pass off to special case code.
  5263. if (cwc == 0)
  5264. {
  5265. if ((prcl != NULL) && (flOpts & ETO_OPAQUE))
  5266. {
  5267. bRet = GreExtTextOutRect(hdc, prcl);
  5268. }
  5269. else
  5270. {
  5271. // Bug fix, we have to return TRUE here, MS Publisher
  5272. // doesn't work otherwise. Not really that bad, we
  5273. // did succeed to draw nothing.
  5274. bRet = TRUE;
  5275. }
  5276. }
  5277. else
  5278. {
  5279. //
  5280. // Make sure there is a rectangle or a string if we need them:
  5281. //
  5282. if ( ((flOpts & (ETO_CLIPPED | ETO_OPAQUE)) && (prcl == NULL)) ||
  5283. (pwsz == NULL) )
  5284. {
  5285. bRet = FALSE;
  5286. }
  5287. else
  5288. {
  5289. bRet = TRUE;
  5290. //
  5291. // We allocate a single buffer to hold the captured copy of
  5292. // the pdx array (if there is one), room for the STROBJ,
  5293. // and to hold the captured copy of the string (in that
  5294. // order).
  5295. //
  5296. // NOTE: With the appropriate exception handling in the
  5297. // body of ExtTextOutW, we might not need to copy
  5298. // these buffers:
  5299. //
  5300. //
  5301. // see if it is for a user mode printer driver
  5302. //
  5303. cjDx = 0; // dword sized
  5304. cjStrobj = SIZEOF_STROBJ_BUFFER(cwc); // dword sized
  5305. cjString = cwc * sizeof(WCHAR); // not dword sized
  5306. if (pdx)
  5307. {
  5308. cjDx = cwc * sizeof(INT); // dword sized
  5309. if (flOpts & ETO_PDY)
  5310. cjDx *= 2; // space for pdy array
  5311. }
  5312. cj = ALIGN_PTR(cjDx) + cjStrobj + cjString;
  5313. if (cj <= TEXT_CAPTURE_BUFFER_SIZE)
  5314. {
  5315. pjAlloc = NULL;
  5316. pjCapture = CaptureBuffer;
  5317. }
  5318. else
  5319. {
  5320. pjAlloc = AllocFreeTmpBuffer(cj);
  5321. pjCapture = pjAlloc;
  5322. if (pjAlloc == NULL)
  5323. return(FALSE);
  5324. }
  5325. if (pdx)
  5326. {
  5327. try
  5328. {
  5329. // NOTE: Works95 passes byte aligned pointers for
  5330. // this. Since we copy it any ways, this is not
  5331. // really a problem and it is compatible with NT 3.51.
  5332. ProbeForRead(pdx, cjDx, sizeof(BYTE));
  5333. RtlCopyMemory(pjCapture, pdx, cjDx);
  5334. }
  5335. except(EXCEPTION_EXECUTE_HANDLER)
  5336. {
  5337. WARNINGX(64);
  5338. bRet = FALSE;
  5339. }
  5340. pdx = (INT*) pjCapture;
  5341. pjCapture += ALIGN_PTR(cjDx);
  5342. }
  5343. pjStrobj = pjCapture;
  5344. pjCapture += cjStrobj;
  5345. ASSERTGDI((((ULONG_PTR) pjCapture) & (sizeof(PVOID)-1)) == 0,
  5346. "Buffers should be ptr aligned");
  5347. try
  5348. {
  5349. ProbeForRead(pwsz, cwc*sizeof(WCHAR), sizeof(WCHAR));
  5350. RtlCopyMemory(pjCapture, pwsz, cwc*sizeof(WCHAR));
  5351. }
  5352. except(EXCEPTION_EXECUTE_HANDLER)
  5353. {
  5354. WARNINGX(65);
  5355. bRet = FALSE;
  5356. }
  5357. if (bRet)
  5358. {
  5359. bRet = GreExtTextOutWInternal(hdc,
  5360. x,
  5361. y,
  5362. flOpts,
  5363. prcl,
  5364. (LPWSTR) pjCapture,
  5365. cwc,
  5366. pdx,
  5367. pjStrobj,
  5368. dwCodePage);
  5369. }
  5370. if (pjAlloc)
  5371. {
  5372. FREEALLOCTEMPBUFFER(pjAlloc);
  5373. }
  5374. }
  5375. }
  5376. return bRet;
  5377. }
  5378. /************************Public*Routine**************************\
  5379. * NtGdiConsoleTextOut()
  5380. *
  5381. * History:
  5382. * 23-Mar-1998 -by- Xudong Wu [TessieW]
  5383. * Wrote it.
  5384. \****************************************************************/
  5385. #define CONSOLE_BUFFER 128
  5386. BOOL NtGdiConsoleTextOut(
  5387. HDC hdc,
  5388. POLYTEXTW *lpto, // Ptr to array of polytext structures
  5389. UINT nStrings, // number of polytext structures
  5390. RECTL *prclBounds
  5391. )
  5392. {
  5393. BOOL bStatus = TRUE;
  5394. ULONG ulSize = nStrings * sizeof(POLYTEXTW);
  5395. POLYTEXTW *lptoTmp = NULL, *ppt;
  5396. RECTL rclBoundsTmp;
  5397. PBYTE pjBuffer, pjBufferEnd;
  5398. ULONG aulTmp[CONSOLE_BUFFER];
  5399. if (nStrings == 0)
  5400. return TRUE;
  5401. if (!lpto)
  5402. return FALSE;
  5403. if (prclBounds)
  5404. {
  5405. try
  5406. {
  5407. rclBoundsTmp = ProbeAndReadStructure(prclBounds, RECTL);
  5408. }
  5409. except(EXCEPTION_EXECUTE_HANDLER)
  5410. {
  5411. WARNING("NtGdiConsoleTextOut invalid prclBounds\n");
  5412. return FALSE;
  5413. }
  5414. }
  5415. if (!BALLOC_OVERFLOW1(nStrings,POLYTEXTW))
  5416. {
  5417. try
  5418. {
  5419. ProbeForRead(lpto, nStrings * sizeof(POLYTEXTW), sizeof(ULONG));
  5420. for (ppt = lpto; ppt < lpto + nStrings; ppt++)
  5421. {
  5422. int n = ppt->n;
  5423. ULONG ulTmp; // used to check for
  5424. // overflow of ulSize
  5425. //
  5426. // Pull count from each, also check for
  5427. // non-zero length and NULL string
  5428. //
  5429. ulTmp = ulSize;
  5430. ulSize += n * sizeof(WCHAR);
  5431. if (BALLOC_OVERFLOW1(n, WCHAR) ||
  5432. (ulSize < ulTmp) ||
  5433. (ppt->pdx != (int *)NULL) ||
  5434. ((n != 0) && (ppt->lpstr == NULL)))
  5435. {
  5436. bStatus = FALSE;
  5437. break;
  5438. }
  5439. }
  5440. }
  5441. except(EXCEPTION_EXECUTE_HANDLER)
  5442. {
  5443. bStatus = FALSE;
  5444. WARNING("NtGdiConsoleTextOut invalid lpto\n");
  5445. }
  5446. }
  5447. else
  5448. {
  5449. bStatus = FALSE;
  5450. }
  5451. if (bStatus)
  5452. {
  5453. if (ulSize > (CONSOLE_BUFFER * sizeof(ULONG)))
  5454. {
  5455. lptoTmp = AllocFreeTmpBuffer(ulSize);
  5456. }
  5457. else
  5458. {
  5459. lptoTmp = (POLYTEXTW *)aulTmp;
  5460. }
  5461. if (lptoTmp)
  5462. {
  5463. try
  5464. {
  5465. ProbeAndReadBuffer(lptoTmp, lpto, nStrings * sizeof(POLYTEXTW));
  5466. pjBuffer = ((BYTE*)lptoTmp) + nStrings * sizeof(POLYTEXTW);
  5467. pjBufferEnd = pjBuffer + ulSize;
  5468. for (ppt = lptoTmp; ppt < lptoTmp + nStrings; ppt++)
  5469. {
  5470. if (ppt->n)
  5471. {
  5472. ULONG StrSize = ppt->n * sizeof(WCHAR);
  5473. if (ppt->pdx || (ppt->lpstr == NULL))
  5474. {
  5475. bStatus = FALSE;
  5476. break;
  5477. }
  5478. if (BALLOC_OVERFLOW1(ppt->n, WCHAR) || ((pjBuffer + StrSize) > pjBufferEnd))
  5479. {
  5480. bStatus = FALSE;
  5481. break;
  5482. }
  5483. ProbeAndReadAlignedBuffer(pjBuffer, ppt->lpstr, StrSize, sizeof(WCHAR));
  5484. ppt->lpstr = (LPWSTR)pjBuffer;
  5485. pjBuffer += StrSize;
  5486. }
  5487. }
  5488. }
  5489. __except(EXCEPTION_EXECUTE_HANDLER)
  5490. {
  5491. bStatus = FALSE;
  5492. WARNING("NtGdiConsoleTextOut() failed to copy lpto\n");
  5493. }
  5494. if (bStatus)
  5495. {
  5496. bStatus = GreConsoleTextOut(hdc, lptoTmp, nStrings, prclBounds ? &rclBoundsTmp : NULL);
  5497. }
  5498. if (lptoTmp != (POLYTEXTW *)aulTmp)
  5499. FreeTmpBuffer(lptoTmp);
  5500. }
  5501. else
  5502. {
  5503. WARNING("NtGdiConsoleTextOut() failed to alloc mem\n");
  5504. }
  5505. }
  5506. return bStatus;
  5507. }
  5508. /******************************Public*Routine******************************\
  5509. *
  5510. * BOOL bCheckAndCapThePath, used in add/remove font resoruce
  5511. *
  5512. * History:
  5513. * 11-Apr-1996 -by- Bodin Dresevic [BodinD]
  5514. * Wrote it.
  5515. \**************************************************************************/
  5516. BOOL bCheckAndCapThePath (
  5517. WCHAR *pwszUcPath, // output
  5518. WCHAR *pwszFiles, // input
  5519. ULONG cwc,
  5520. ULONG cFiles
  5521. )
  5522. {
  5523. ULONG cFiles1 = 1; // for consistency checking
  5524. BOOL bRet = TRUE;
  5525. ULONG iwc;
  5526. ASSERTGDI(!BALLOC_OVERFLOW1(cwc,WCHAR),
  5527. "caller should check for overflow\n");
  5528. ProbeForRead(pwszFiles, cwc * sizeof(WCHAR), sizeof(CHAR));
  5529. if (pwszFiles[cwc - 1] == L'\0')
  5530. {
  5531. // this used to be done later, in gdi code which now expects capped string
  5532. cCapString(pwszUcPath, pwszFiles, cwc);
  5533. // replace separators by zeros, want zero terminated strings in
  5534. // the engine
  5535. for (iwc = 0; iwc < cwc; iwc++)
  5536. {
  5537. if (pwszUcPath[iwc] == PATH_SEPARATOR)
  5538. {
  5539. pwszUcPath[iwc] = L'\0';
  5540. cFiles1++;
  5541. }
  5542. }
  5543. // check consistency
  5544. if (cFiles != cFiles1)
  5545. bRet = FALSE;
  5546. }
  5547. else
  5548. {
  5549. bRet = FALSE;
  5550. }
  5551. return bRet;
  5552. }
  5553. // MISC FONT API's
  5554. /******************************Public*Routine******************************\
  5555. * NtGdiAddFontResourceW()
  5556. *
  5557. * History:
  5558. * Wed 11-Oct-1995 -by- Bodin Dresevic [BodinD]
  5559. * Rewrote it
  5560. \**************************************************************************/
  5561. #define CWC_PATH 80
  5562. int
  5563. APIENTRY
  5564. NtGdiAddFontResourceW(
  5565. WCHAR *pwszFiles,
  5566. ULONG cwc,
  5567. ULONG cFiles,
  5568. FLONG f,
  5569. DWORD dwPidTid,
  5570. DESIGNVECTOR *pdv
  5571. )
  5572. {
  5573. WCHAR awcPath[CWC_PATH];
  5574. WCHAR *pwszPath = NULL; // essential initialization
  5575. int iRet = 0;
  5576. ULONG iwc;
  5577. DESIGNVECTOR dvTmp;
  5578. DWORD cjDV = 0;
  5579. DWORD dvNumAxes = 0;
  5580. try
  5581. {
  5582. if (cwc > 1)
  5583. {
  5584. if (cwc <= CWC_PATH)
  5585. {
  5586. pwszPath = awcPath;
  5587. }
  5588. else if (cwc <= 4 * (MAX_PATH + 1))
  5589. {
  5590. pwszPath = AllocFreeTmpBuffer(cwc * sizeof(WCHAR));
  5591. }
  5592. else
  5593. {
  5594. iRet = 0;
  5595. WARNING("NtGdiAddFontResourceW: pwszFiles longer than 4*(MAX_PATH+1)\n");
  5596. }
  5597. if (pwszPath)
  5598. {
  5599. // RtlUpcaseUnicodeString() doesn't initialize the buffer
  5600. // if it is bigger than 0x7FFF
  5601. iRet = (int)bCheckAndCapThePath(pwszPath,pwszFiles,cwc,cFiles);
  5602. }
  5603. }
  5604. if (iRet && pdv)
  5605. {
  5606. // get the dvNumAxes first
  5607. ProbeForRead(pdv, offsetof(DESIGNVECTOR,dvValues) , sizeof(BYTE));
  5608. dvNumAxes = pdv->dvNumAxes;
  5609. if ((dvNumAxes > 0) && (dvNumAxes <= MM_MAX_NUMAXES))
  5610. {
  5611. cjDV = SIZEOFDV(dvNumAxes);
  5612. if (!BALLOC_OVERFLOW1(cjDV, BYTE))
  5613. {
  5614. ProbeAndReadBuffer(&dvTmp, pdv, cjDV);
  5615. pdv = &dvTmp;
  5616. }
  5617. else
  5618. iRet = 0;
  5619. }
  5620. else if (dvNumAxes == 0)
  5621. {
  5622. pdv = 0;
  5623. }
  5624. else
  5625. {
  5626. iRet = 0;
  5627. }
  5628. }
  5629. }
  5630. except(EXCEPTION_EXECUTE_HANDLER)
  5631. {
  5632. iRet = 0;
  5633. WARNINGX(95);
  5634. }
  5635. if (iRet)
  5636. iRet = GreAddFontResourceWInternal(pwszPath, cwc, cFiles,f,dwPidTid, pdv, cjDV);
  5637. if (iRet) //Increase global time stamp for realization info
  5638. (gpGdiSharedMemory->timeStamp)++;
  5639. if (pwszPath && (pwszPath != awcPath))
  5640. FreeTmpBuffer(pwszPath);
  5641. TRACE_FONT(("Leaving: NtGdiAddFontResourceW"));
  5642. return iRet;
  5643. }
  5644. /*************Public*Routine***************************\
  5645. * BOOL APIENTRY NtGdiUnmapMemFont *
  5646. * *
  5647. * History: *
  5648. * Jul-03-1996 -by- Xudong Wu [TessieW] *
  5649. * *
  5650. * Wrote it. *
  5651. *******************************************************/
  5652. BOOL APIENTRY NtGdiUnmapMemFont(PVOID pvView)
  5653. {
  5654. // we may need this if we ever figure out how to map the memory font to
  5655. // the application's address space
  5656. return 1;
  5657. }
  5658. /***************Public*Routine**************************\
  5659. * HANDLE NtGdiAddFontMemResourceEx() *
  5660. * *
  5661. * History: *
  5662. * 09-Jun-1996 -by- Xudong Wu [TessieW] *
  5663. * *
  5664. * Wrote it. *
  5665. ********************************************************/
  5666. HANDLE APIENTRY NtGdiAddFontMemResourceEx
  5667. (
  5668. PVOID pvBuffer,
  5669. ULONG cjBuffer,
  5670. DESIGNVECTOR *pdv,
  5671. DWORD cjDV,
  5672. DWORD *pNumFonts
  5673. )
  5674. {
  5675. BOOL bOK = TRUE;
  5676. HANDLE hMMFont = 0;
  5677. DESIGNVECTOR dvTmp;
  5678. // check the size and pointer
  5679. if ((cjBuffer == 0) || (pvBuffer == NULL) || (pNumFonts == NULL))
  5680. {
  5681. return 0;
  5682. }
  5683. __try
  5684. {
  5685. if (cjDV)
  5686. {
  5687. if (cjDV <= SIZEOFDV(MM_MAX_NUMAXES))
  5688. {
  5689. ProbeAndReadBuffer(&dvTmp, pdv, cjDV);
  5690. pdv = &dvTmp;
  5691. }
  5692. else
  5693. {
  5694. bOK = FALSE;
  5695. }
  5696. }
  5697. else
  5698. {
  5699. pdv = NULL;
  5700. }
  5701. }
  5702. __except(EXCEPTION_EXECUTE_HANDLER)
  5703. {
  5704. bOK = FALSE;
  5705. WARNING("NtGdiAddFontMemResource() try-except\n");
  5706. }
  5707. if (bOK)
  5708. {
  5709. DWORD cFonts;
  5710. if (hMMFont = GreAddFontMemResourceEx(pvBuffer, cjBuffer, pdv, cjDV, &cFonts))
  5711. {
  5712. __try
  5713. {
  5714. ProbeAndWriteUlong(pNumFonts, cFonts);
  5715. }
  5716. __except(EXCEPTION_EXECUTE_HANDLER)
  5717. {
  5718. GreRemoveFontMemResourceEx(hMMFont);
  5719. hMMFont = 0;
  5720. }
  5721. }
  5722. }
  5723. return hMMFont;
  5724. }
  5725. /******************************Public*Routine******************************\
  5726. * BOOL APIENTRY NtGdiRemoveFontResourceW
  5727. *
  5728. * History:
  5729. * 28-Mar-1996 -by- Bodin Dresevic [BodinD]
  5730. * Wrote it.
  5731. \**************************************************************************/
  5732. BOOL
  5733. APIENTRY
  5734. NtGdiRemoveFontResourceW(
  5735. WCHAR *pwszFiles,
  5736. ULONG cwc,
  5737. ULONG cFiles,
  5738. ULONG fl,
  5739. DWORD dwPidTid,
  5740. DESIGNVECTOR *pdv
  5741. )
  5742. {
  5743. WCHAR awcPath[CWC_PATH];
  5744. WCHAR *pwszPath = NULL; // essential initialization
  5745. BOOL bRet = FALSE;
  5746. DESIGNVECTOR dvTmp;
  5747. DWORD cjDV = 0, dvNumAxes = 0;
  5748. TRACE_FONT(("Entering: NtGdiRemoveFontResourceW(\"%ws\",%-#x,%-#x)\n",pwszFiles, cwc,cFiles));
  5749. try
  5750. {
  5751. if (cwc > 1)
  5752. {
  5753. if (cwc <= CWC_PATH)
  5754. {
  5755. pwszPath = awcPath;
  5756. }
  5757. else if (!BALLOC_OVERFLOW1(cwc,WCHAR))
  5758. {
  5759. pwszPath = AllocFreeTmpBuffer(cwc * sizeof(WCHAR));
  5760. }
  5761. if (pwszPath)
  5762. {
  5763. bRet = bCheckAndCapThePath(pwszPath, pwszFiles, cwc, cFiles);
  5764. }
  5765. }
  5766. if (bRet && pdv)
  5767. {
  5768. // get the dvNumAxes first
  5769. ProbeForRead(pdv, offsetof(DESIGNVECTOR,dvValues) , sizeof(BYTE));
  5770. dvNumAxes = pdv->dvNumAxes;
  5771. if ((dvNumAxes > 0) && (dvNumAxes <= MM_MAX_NUMAXES))
  5772. {
  5773. cjDV = SIZEOFDV(dvNumAxes);
  5774. if (!BALLOC_OVERFLOW1(cjDV, BYTE))
  5775. {
  5776. ProbeAndReadBuffer(&dvTmp, pdv, cjDV);
  5777. pdv = &dvTmp;
  5778. }
  5779. else
  5780. bRet = FALSE;
  5781. }
  5782. else if (dvNumAxes == 0)
  5783. {
  5784. pdv = 0;
  5785. }
  5786. else
  5787. {
  5788. bRet = FALSE;
  5789. }
  5790. }
  5791. }
  5792. except(EXCEPTION_EXECUTE_HANDLER)
  5793. {
  5794. bRet = FALSE;
  5795. WARNINGX(96);
  5796. }
  5797. if (bRet)
  5798. bRet = GreRemoveFontResourceW(pwszPath, cwc, cFiles, fl, dwPidTid, pdv, cjDV);
  5799. if (bRet) //Increase global time stamp for realization info
  5800. (gpGdiSharedMemory->timeStamp)++;
  5801. if (pwszPath && (pwszPath != awcPath))
  5802. FreeTmpBuffer(pwszPath);
  5803. TRACE_FONT(("Leaving: NtGdiRemoveFontResourceW"));
  5804. return bRet;
  5805. }
  5806. /***************Public*Routine**************************\
  5807. * NtGdiRemoveFontMemResourceEx() *
  5808. * *
  5809. * History: *
  5810. * 09-Jun-1996 -by- Xudong Wu [TessieW] *
  5811. * *
  5812. * Wrote it. *
  5813. ********************************************************/
  5814. BOOL
  5815. APIENTRY
  5816. NtGdiRemoveFontMemResourceEx(HANDLE hMMFont)
  5817. {
  5818. BOOL bRet = TRUE;
  5819. if (hMMFont == 0)
  5820. {
  5821. return FALSE;
  5822. }
  5823. if (bRet)
  5824. {
  5825. bRet = GreRemoveFontMemResourceEx(hMMFont);
  5826. }
  5827. return bRet;
  5828. }
  5829. /******************************Public*Routine******************************\
  5830. * NtGdiEnumFontClose()
  5831. *
  5832. * History:
  5833. * 01-Nov-1994 -by- Eric Kutter [erick]
  5834. * Wrote it.
  5835. \**************************************************************************/
  5836. BOOL
  5837. APIENTRY
  5838. NtGdiEnumFontClose(
  5839. ULONG_PTR idEnum
  5840. )
  5841. {
  5842. return(bEnumFontClose(idEnum));
  5843. }
  5844. /******************************Public*Routine******************************\
  5845. * NtGdiEnumFontChunk()
  5846. *
  5847. * History:
  5848. * 01-Nov-1994 -by- Eric Kutter [erick]
  5849. * Wrote it.
  5850. \**************************************************************************/
  5851. BOOL
  5852. APIENTRY
  5853. NtGdiEnumFontChunk(
  5854. HDC hdc,
  5855. ULONG_PTR idEnum,
  5856. ULONG cjEfdw,
  5857. ULONG *pcjEfdw,
  5858. PENUMFONTDATAW pefdw
  5859. )
  5860. {
  5861. HANDLE hSecure;
  5862. BOOL bRet = TRUE;
  5863. ULONG cjEfdwRet = 0;
  5864. try
  5865. {
  5866. ProbeForWrite(pefdw, cjEfdw, sizeof(DWORD));
  5867. hSecure = MmSecureVirtualMemory(pefdw, cjEfdw, PAGE_READWRITE);
  5868. if (!hSecure)
  5869. {
  5870. bRet = FALSE;
  5871. }
  5872. }
  5873. except(EXCEPTION_EXECUTE_HANDLER)
  5874. {
  5875. WARNINGX(66);
  5876. // SetLastError(GetExceptionCode());
  5877. bRet = FALSE;
  5878. }
  5879. if (bRet)
  5880. {
  5881. try
  5882. {
  5883. bRet = bEnumFontChunk(hdc,idEnum,cjEfdw,&cjEfdwRet,pefdw);
  5884. ProbeAndWriteUlong(pcjEfdw,cjEfdwRet);
  5885. }
  5886. except(EXCEPTION_EXECUTE_HANDLER)
  5887. {
  5888. WARNINGX(105);
  5889. bRet = FALSE;
  5890. }
  5891. MmUnsecureVirtualMemory(hSecure);
  5892. }
  5893. return (bRet);
  5894. }
  5895. /******************************Public*Routine******************************\
  5896. * NtGdiEnumFontOpen()
  5897. *
  5898. * History:
  5899. * 08-Mar-1995 Mark Enstrom [marke]
  5900. * Wrote it.
  5901. \**************************************************************************/
  5902. ULONG_PTR
  5903. APIENTRY
  5904. NtGdiEnumFontOpen(
  5905. HDC hdc,
  5906. ULONG iEnumType,
  5907. FLONG flWin31Compat,
  5908. ULONG cwchMax,
  5909. LPWSTR pwszFaceName,
  5910. ULONG lfCharSet,
  5911. ULONG *pulCount
  5912. )
  5913. {
  5914. ULONG cwchFaceName;
  5915. PWSTR pwszKmFaceName = NULL;
  5916. ULONG_PTR ulRet = 0;
  5917. BOOL bRet = TRUE;
  5918. ULONG ulCount = 0;
  5919. if (pwszFaceName != (PWSZ)NULL)
  5920. {
  5921. if ((cwchMax == 0) || (cwchMax > LF_FACESIZE))
  5922. return FALSE;
  5923. if (!BALLOC_OVERFLOW1(cwchMax,WCHAR))
  5924. {
  5925. pwszKmFaceName = (PWSZ)AllocFreeTmpBuffer(cwchMax * sizeof(WCHAR));
  5926. }
  5927. if (pwszKmFaceName != (PWSZ)NULL)
  5928. {
  5929. try
  5930. {
  5931. ProbeAndReadAlignedBuffer(pwszKmFaceName,pwszFaceName, cwchMax * sizeof(WCHAR), sizeof(WCHAR));
  5932. // GreEnumFontOpen expects zero terminated sting
  5933. pwszKmFaceName[cwchMax-1] = 0;
  5934. }
  5935. except(EXCEPTION_EXECUTE_HANDLER)
  5936. {
  5937. WARNINGX(66);
  5938. // SetLastError(GetExceptionCode());
  5939. bRet = FALSE;
  5940. }
  5941. }
  5942. else
  5943. {
  5944. // SetLastError(GetExceptionCode());
  5945. bRet = FALSE;
  5946. }
  5947. }
  5948. else
  5949. {
  5950. pwszKmFaceName = (PWSZ)NULL;
  5951. cwchMax = 0;
  5952. }
  5953. if (bRet)
  5954. {
  5955. ulRet = GreEnumFontOpen(hdc,iEnumType,flWin31Compat,cwchMax,
  5956. (PWSZ)pwszKmFaceName, lfCharSet,&ulCount);
  5957. if (ulRet)
  5958. {
  5959. try
  5960. {
  5961. ProbeAndWriteUlong(pulCount,ulCount);
  5962. }
  5963. except(EXCEPTION_EXECUTE_HANDLER)
  5964. {
  5965. WARNINGX(67);
  5966. // SetLastError(GetExceptionCode());
  5967. bRet = FALSE;
  5968. }
  5969. }
  5970. }
  5971. if (pwszKmFaceName != (PWSTR)NULL)
  5972. {
  5973. FreeTmpBuffer(pwszKmFaceName);
  5974. }
  5975. return(ulRet);
  5976. }
  5977. /******************************Public*Routine******************************\
  5978. * NtGdiGetFontResourceInfoInternalW()
  5979. *
  5980. * History:
  5981. * 01-Nov-1994 -by- Eric Kutter [erick]
  5982. * Wrote it.
  5983. \**************************************************************************/
  5984. BOOL
  5985. APIENTRY
  5986. NtGdiGetFontResourceInfoInternalW(
  5987. LPWSTR pwszFiles,
  5988. ULONG cwc,
  5989. ULONG cFiles,
  5990. UINT cjIn,
  5991. LPDWORD pdwBytes,
  5992. LPVOID pvBuf,
  5993. DWORD iType
  5994. )
  5995. {
  5996. WCHAR awcPath[CWC_PATH];
  5997. WCHAR *pwszPath = NULL; // essential initialization
  5998. BOOL bRet = FALSE;
  5999. SIZE_T dwBytesTmp;
  6000. LOGFONTW lfw;
  6001. LPVOID pvBufTmp = NULL;
  6002. TRACE_FONT(("Entering: NtGdiGetFontResourceInfoInternalW(\"%ws\",%-#x,%-#x)\n",pwszFiles, cwc,cFiles));
  6003. try
  6004. {
  6005. if (cwc > 1)
  6006. {
  6007. if (cwc <= CWC_PATH)
  6008. {
  6009. pwszPath = awcPath;
  6010. }
  6011. else if (!BALLOC_OVERFLOW1(cwc,WCHAR))
  6012. {
  6013. pwszPath = AllocFreeTmpBuffer(cwc * sizeof(WCHAR));
  6014. }
  6015. if (pwszPath)
  6016. {
  6017. bRet = bCheckAndCapThePath(pwszPath, pwszFiles, cwc, cFiles);
  6018. }
  6019. }
  6020. }
  6021. except(EXCEPTION_EXECUTE_HANDLER)
  6022. {
  6023. WARNINGX(97);
  6024. }
  6025. if (cjIn > sizeof(LOGFONTW))
  6026. {
  6027. if (!BALLOC_OVERFLOW1(cjIn, BYTE))
  6028. {
  6029. pvBufTmp = PALLOCMEM(cjIn, 'pmtG');
  6030. if (!pvBufTmp)
  6031. {
  6032. WARNING("NtGdiGetFontResourceInfoInternalW: failed to allocate memory\n");
  6033. bRet = FALSE;
  6034. }
  6035. }
  6036. }
  6037. else
  6038. {
  6039. pvBufTmp = (PVOID)&lfw;
  6040. }
  6041. if (bRet && (bRet = GetFontResourceInfoInternalW(pwszPath,cwc, cFiles, cjIn,
  6042. &dwBytesTmp, pvBufTmp, iType)))
  6043. {
  6044. try
  6045. {
  6046. ProbeAndWriteUlong(pdwBytes, (ULONG) dwBytesTmp);
  6047. if (cjIn)
  6048. {
  6049. ProbeAndWriteBuffer(pvBuf, pvBufTmp, cjIn);
  6050. }
  6051. }
  6052. except(EXCEPTION_EXECUTE_HANDLER)
  6053. {
  6054. WARNINGX(110);
  6055. }
  6056. }
  6057. if (pwszPath && (pwszPath != awcPath))
  6058. FreeTmpBuffer(pwszPath);
  6059. if (pvBufTmp && (pvBufTmp != (PVOID)&lfw))
  6060. {
  6061. VFREEMEM(pvBufTmp);
  6062. }
  6063. TRACE_FONT(("Leaving: NtGdiGetFontResourceInfoInternalW\n"));
  6064. return bRet;
  6065. }
  6066. ULONG
  6067. APIENTRY
  6068. NtGdiGetEmbedFonts()
  6069. {
  6070. return GreGetEmbedFonts();
  6071. }
  6072. BOOL
  6073. APIENTRY
  6074. NtGdiChangeGhostFont(KERNEL_PVOID *pfontID, BOOL bLoad)
  6075. {
  6076. BOOL bRet = TRUE;
  6077. VOID *fontID;
  6078. try
  6079. {
  6080. ProbeAndReadBuffer(&fontID, pfontID, sizeof(VOID*));
  6081. }
  6082. except(EXCEPTION_EXECUTE_HANDLER)
  6083. {
  6084. WARNINGX(68);
  6085. // SetLastError(GetExceptionCode());
  6086. bRet = FALSE;
  6087. }
  6088. bRet = bRet && GreChangeGhostFont(fontID, bLoad);
  6089. return bRet;
  6090. }
  6091. /******************************Public*Routine******************************\
  6092. * NtGdiGetUFI()
  6093. *
  6094. * History:
  6095. * 02-Feb-1995 -by- Andre Vachon [andreva]
  6096. * Wrote it.
  6097. * 01-Mar-1995 -by- Lingyun Wang [lingyunw]
  6098. * Expanded it.
  6099. \**************************************************************************/
  6100. BOOL
  6101. APIENTRY
  6102. NtGdiGetUFI(
  6103. HDC hdc,
  6104. PUNIVERSAL_FONT_ID pufi,
  6105. DESIGNVECTOR *pdv, ULONG *pcjDV, ULONG *pulBaseCheckSum,
  6106. FLONG *pfl
  6107. )
  6108. {
  6109. UNIVERSAL_FONT_ID ufiTmp;
  6110. BOOL bRet = TRUE;
  6111. FLONG flTmp;
  6112. DESIGNVECTOR dvTmp;
  6113. ULONG cjDVTmp;
  6114. ULONG ulBaseCheckSum = 0;
  6115. bRet = GreGetUFI(hdc, &ufiTmp, &dvTmp, &cjDVTmp, &ulBaseCheckSum, &flTmp, NULL);
  6116. try
  6117. {
  6118. if (bRet)
  6119. {
  6120. ProbeAndWriteStructure(pufi,ufiTmp,UNIVERSAL_FONT_ID);
  6121. ProbeAndWriteUlong(pfl, flTmp);
  6122. if ((flTmp & FL_UFI_DESIGNVECTOR_PFF) && pdv)
  6123. {
  6124. ProbeAndWriteBuffer(pdv, &dvTmp, cjDVTmp);
  6125. ProbeAndWriteUlong(pcjDV, cjDVTmp);
  6126. ProbeAndWriteUlong(pulBaseCheckSum, ulBaseCheckSum);
  6127. }
  6128. }
  6129. }
  6130. except(EXCEPTION_EXECUTE_HANDLER)
  6131. {
  6132. WARNINGX(68);
  6133. // SetLastError(GetExceptionCode());
  6134. bRet = FALSE;
  6135. }
  6136. return (bRet);
  6137. }
  6138. BOOL
  6139. APIENTRY
  6140. NtGdiGetEmbUFI(
  6141. HDC hdc,
  6142. PUNIVERSAL_FONT_ID pufi,
  6143. DESIGNVECTOR *pdv, ULONG *pcjDV, ULONG *pulBaseCheckSum,
  6144. FLONG *pfl,
  6145. KERNEL_PVOID *pEmbFontID
  6146. )
  6147. {
  6148. UNIVERSAL_FONT_ID ufiTmp;
  6149. BOOL bRet = TRUE;
  6150. FLONG flTmp;
  6151. DESIGNVECTOR dvTmp;
  6152. ULONG cjDVTmp;
  6153. ULONG ulBaseCheckSum = 0;
  6154. VOID *fontID;
  6155. bRet = GreGetUFI(hdc, &ufiTmp, &dvTmp, &cjDVTmp, &ulBaseCheckSum, &flTmp, &fontID);
  6156. try
  6157. {
  6158. if (bRet)
  6159. {
  6160. ProbeAndWriteStructure(pufi,ufiTmp,UNIVERSAL_FONT_ID);
  6161. ProbeAndWriteUlong(pfl, flTmp);
  6162. ProbeAndWriteBuffer(pEmbFontID, &fontID, sizeof(VOID*));
  6163. if ((flTmp & FL_UFI_DESIGNVECTOR_PFF) && pdv)
  6164. {
  6165. ProbeAndWriteBuffer(pdv, &dvTmp, cjDVTmp);
  6166. ProbeAndWriteUlong(pcjDV, cjDVTmp);
  6167. ProbeAndWriteUlong(pulBaseCheckSum, ulBaseCheckSum);
  6168. }
  6169. }
  6170. }
  6171. except(EXCEPTION_EXECUTE_HANDLER)
  6172. {
  6173. WARNINGX(68);
  6174. // SetLastError(GetExceptionCode());
  6175. bRet = FALSE;
  6176. }
  6177. return (bRet);
  6178. }
  6179. /**************************Public*Routine**************************\
  6180. * NtGdiGetUFIPathname()
  6181. *
  6182. * Return the font file path name according to the input ufi.
  6183. *
  6184. * History:
  6185. * Feb-04-1997 Xudong Wu [tessiew]
  6186. * Wrote it.
  6187. *
  6188. \*******************************************************************/
  6189. BOOL
  6190. APIENTRY
  6191. NtGdiGetUFIPathname
  6192. (
  6193. PUNIVERSAL_FONT_ID pufi,
  6194. ULONG* pcwc,
  6195. LPWSTR pwszPathname,
  6196. ULONG* pcNumFiles,
  6197. FLONG fl,
  6198. BOOL *pbMemFont,
  6199. ULONG *pcjView,
  6200. PVOID pvView,
  6201. BOOL *pbTTC,
  6202. ULONG *piTTC
  6203. )
  6204. {
  6205. UNIVERSAL_FONT_ID ufiTmp;
  6206. WCHAR awszTmp[MAX_PATH], *pwszTmp = NULL;
  6207. COUNT cwcTmp, cNumFilesTmp;
  6208. BOOL bRet = TRUE;
  6209. BOOL bMemFontTmp;
  6210. PVOID pvViewTmp = pvView;
  6211. ULONG cjViewTmp;
  6212. BOOL bTTC;
  6213. ULONG iTTC;
  6214. try
  6215. {
  6216. ufiTmp = ProbeAndReadStructure(pufi, UNIVERSAL_FONT_ID);
  6217. }
  6218. except(EXCEPTION_EXECUTE_HANDLER)
  6219. {
  6220. WARNINGX(105);
  6221. bRet = FALSE;
  6222. }
  6223. if (bRet && (bRet = GreGetUFIPathname(&ufiTmp,
  6224. &cwcTmp,
  6225. NULL, // just ask for the size
  6226. &cNumFilesTmp,
  6227. fl,
  6228. &bMemFontTmp,
  6229. &cjViewTmp,
  6230. pvViewTmp,
  6231. pbTTC ? &bTTC : NULL,
  6232. piTTC ? &iTTC : NULL)))
  6233. {
  6234. if (cwcTmp <= MAX_PATH)
  6235. {
  6236. pwszTmp = awszTmp;
  6237. }
  6238. else
  6239. {
  6240. if (!BALLOC_OVERFLOW1(cwcTmp,WCHAR))
  6241. {
  6242. pwszTmp = AllocFreeTmpBuffer(cwcTmp * sizeof(WCHAR));
  6243. }
  6244. if (!pwszTmp)
  6245. bRet = FALSE;
  6246. }
  6247. }
  6248. if (bRet && (!bMemFontTmp) && pwszTmp)
  6249. {
  6250. bRet = GreGetUFIPathname(&ufiTmp,
  6251. &cwcTmp,
  6252. pwszTmp,
  6253. &cNumFilesTmp,
  6254. fl,
  6255. NULL,
  6256. NULL,
  6257. NULL,
  6258. pbTTC ? &bTTC : NULL,
  6259. piTTC ? &iTTC : NULL
  6260. );
  6261. }
  6262. if (bRet)
  6263. {
  6264. try
  6265. {
  6266. if (pcwc)
  6267. {
  6268. ProbeAndWriteStructure(pcwc, cwcTmp, ULONG);
  6269. }
  6270. if (pwszPathname)
  6271. {
  6272. ProbeAndWriteBuffer(pwszPathname, pwszTmp, cwcTmp * sizeof(WCHAR));
  6273. }
  6274. if (pcNumFiles)
  6275. {
  6276. ProbeAndWriteStructure(pcNumFiles, cNumFilesTmp, ULONG);
  6277. }
  6278. if (bMemFontTmp)
  6279. {
  6280. if (pbMemFont)
  6281. {
  6282. ProbeAndWriteStructure(pbMemFont, bMemFontTmp, BOOL);
  6283. }
  6284. if (pcjView)
  6285. {
  6286. ProbeAndWriteUlong(pcjView, cjViewTmp);
  6287. }
  6288. }
  6289. if (pbTTC)
  6290. {
  6291. ProbeAndWriteStructure(pbTTC, bTTC, BOOL);
  6292. }
  6293. if (piTTC)
  6294. {
  6295. ProbeAndWriteUlong(piTTC, iTTC);
  6296. }
  6297. }
  6298. except(EXCEPTION_EXECUTE_HANDLER)
  6299. {
  6300. WARNINGX(107);
  6301. bRet = FALSE;
  6302. }
  6303. }
  6304. if (pwszTmp && (pwszTmp != awszTmp))
  6305. {
  6306. FreeTmpBuffer(pwszTmp);
  6307. }
  6308. return (bRet);
  6309. }
  6310. /******************************Public*Routine******************************\
  6311. * NtGdiSetLayout
  6312. *
  6313. * History:
  6314. * 29-Oct-1997 -by- Mohamed Hassanin [mhamid]
  6315. * Wrote it.
  6316. \**************************************************************************/
  6317. DWORD
  6318. APIENTRY
  6319. NtGdiSetLayout(
  6320. HDC hdc,
  6321. LONG wox,
  6322. DWORD dwLayout)
  6323. {
  6324. return GreSetLayout(hdc, wox, dwLayout);
  6325. }
  6326. BOOL
  6327. APIENTRY
  6328. NtGdiMirrorWindowOrg(
  6329. HDC hdc)
  6330. {
  6331. return GreMirrorWindowOrg(hdc);
  6332. }
  6333. LONG
  6334. APIENTRY
  6335. NtGdiGetDeviceWidth(
  6336. HDC hdc)
  6337. {
  6338. return GreGetDeviceWidth(hdc);
  6339. }
  6340. /******************************Public*Routine******************************\
  6341. * NtGdiGetDCPoint()
  6342. *
  6343. * History:
  6344. * 01-Nov-1994 -by- Eric Kutter [erick]
  6345. * Wrote it.
  6346. \**************************************************************************/
  6347. BOOL
  6348. APIENTRY
  6349. NtGdiGetDCPoint(
  6350. HDC hdc,
  6351. UINT iPoint,
  6352. PPOINTL pptOut
  6353. )
  6354. {
  6355. BOOL bRet;
  6356. POINTL pt;
  6357. if (bRet = GreGetDCPoint(hdc,iPoint,&pt))
  6358. {
  6359. // modify *pptOut only if successful
  6360. try
  6361. {
  6362. ProbeAndWriteStructure(pptOut,pt,POINT);
  6363. }
  6364. except(EXCEPTION_EXECUTE_HANDLER)
  6365. {
  6366. WARNINGX(71);
  6367. // SetLastError(GetExceptionCode());
  6368. bRet = FALSE;
  6369. }
  6370. }
  6371. return(bRet);
  6372. }
  6373. /******************************Public*Routine******************************\
  6374. * NtGdiScaleWindowExtEx()
  6375. *
  6376. * History:
  6377. * 01-Nov-1994 -by- Eric Kutter [erick]
  6378. * Wrote it.
  6379. \**************************************************************************/
  6380. BOOL
  6381. APIENTRY
  6382. NtGdiScaleWindowExtEx(
  6383. HDC hdc,
  6384. int xNum,
  6385. int xDenom,
  6386. int yNum,
  6387. int yDenom,
  6388. LPSIZE pszOut
  6389. )
  6390. {
  6391. BOOL bRet;
  6392. SIZE sz;
  6393. bRet = GreScaleWindowExtEx(hdc,xNum,xDenom,yNum,yDenom,&sz);
  6394. if (bRet && pszOut)
  6395. {
  6396. try
  6397. {
  6398. ProbeAndWriteStructure(pszOut,sz,SIZE);
  6399. }
  6400. except(EXCEPTION_EXECUTE_HANDLER)
  6401. {
  6402. WARNINGX(73);
  6403. // SetLastError(GetExceptionCode());
  6404. bRet = FALSE;
  6405. }
  6406. }
  6407. return(bRet);
  6408. }
  6409. /******************************Public*Routine******************************\
  6410. * NtGdiGetTransform()
  6411. *
  6412. * History:
  6413. * 01-Nov-1994 -by- Eric Kutter [erick]
  6414. * Wrote it.
  6415. \**************************************************************************/
  6416. BOOL
  6417. APIENTRY
  6418. NtGdiGetTransform(
  6419. HDC hdc,
  6420. DWORD iXform,
  6421. LPXFORM pxf
  6422. )
  6423. {
  6424. BOOL bRet;
  6425. XFORM xf;
  6426. bRet = GreGetTransform(hdc,iXform,(XFORML *)&xf);
  6427. if (bRet)
  6428. {
  6429. try
  6430. {
  6431. ProbeAndWriteStructure(pxf,xf,XFORM);
  6432. }
  6433. except(EXCEPTION_EXECUTE_HANDLER)
  6434. {
  6435. WARNINGX(74);
  6436. // SetLastError(GetExceptionCode());
  6437. bRet = FALSE;
  6438. }
  6439. }
  6440. return(bRet);
  6441. }
  6442. /******************************Public*Routine******************************\
  6443. * NtGdiCombineTransform()
  6444. *
  6445. * History:
  6446. * 01-Nov-1994 -by- Eric Kutter [erick]
  6447. * Wrote it.
  6448. \**************************************************************************/
  6449. BOOL
  6450. APIENTRY
  6451. NtGdiCombineTransform(
  6452. LPXFORM pxfDst,
  6453. LPXFORM pxfSrc1,
  6454. LPXFORM pxfSrc2
  6455. )
  6456. {
  6457. BOOL bRet;
  6458. XFORM xfSrc1;
  6459. XFORM xfSrc2;
  6460. XFORM xfDst;
  6461. bRet = ProbeAndConvertXFORM ((XFORML *)pxfSrc1, (XFORML *)&xfSrc1)
  6462. && ProbeAndConvertXFORM ((XFORML *)pxfSrc2, (XFORML *)&xfSrc2);
  6463. if (bRet)
  6464. {
  6465. bRet = GreCombineTransform((XFORML *)&xfDst,(XFORML *)&xfSrc1,(XFORML *)&xfSrc2);
  6466. if (bRet)
  6467. {
  6468. try
  6469. {
  6470. ProbeAndWriteStructure(pxfDst,xfDst,XFORM);
  6471. }
  6472. except(EXCEPTION_EXECUTE_HANDLER)
  6473. {
  6474. WARNINGX(76);
  6475. // SetLastError(GetExceptionCode());
  6476. bRet = FALSE;
  6477. }
  6478. }
  6479. }
  6480. return(bRet);
  6481. }
  6482. /******************************Public*Routine******************************\
  6483. * NtGdiTransformPoints()
  6484. *
  6485. * History:
  6486. * 01-Nov-1994 -by- Eric Kutter [erick]
  6487. * Wrote it.
  6488. \**************************************************************************/
  6489. BOOL
  6490. APIENTRY
  6491. NtGdiTransformPoints(
  6492. HDC hdc,
  6493. PPOINT pptIn,
  6494. PPOINT pptOut,
  6495. int c,
  6496. int iMode
  6497. )
  6498. {
  6499. BOOL bRet = TRUE;
  6500. POINT apt[10];
  6501. PPOINT pptTmp = apt;
  6502. //
  6503. // validate
  6504. //
  6505. if (c <= 0)
  6506. {
  6507. //
  6508. // GetTransformPoints returns TRUE for this condition, as does
  6509. // the DPtoLP and LPtoDP APIs.
  6510. //
  6511. return bRet;
  6512. }
  6513. //
  6514. // we will just use the the stack if there are less than 10 points
  6515. // otherwise allocate mem from heap
  6516. //
  6517. if (c > 10)
  6518. {
  6519. //
  6520. // local stack is not enough, invalidate pointer and try to allocate.
  6521. //
  6522. pptTmp = NULL;
  6523. if (!BALLOC_OVERFLOW1(c,POINT))
  6524. {
  6525. pptTmp = AllocFreeTmpBuffer(c * sizeof(POINT));
  6526. }
  6527. }
  6528. //
  6529. // copy pptIn into pptTmp
  6530. //
  6531. if (pptTmp)
  6532. {
  6533. try
  6534. {
  6535. ProbeForRead(pptIn,c * sizeof(POINT), sizeof(BYTE));
  6536. RtlCopyMemory(pptTmp,pptIn,c*sizeof(POINT));
  6537. }
  6538. except(EXCEPTION_EXECUTE_HANDLER)
  6539. {
  6540. WARNINGX(77);
  6541. // SetLastError(GetExceptionCode());
  6542. bRet = FALSE;
  6543. }
  6544. }
  6545. else
  6546. {
  6547. bRet = FALSE;
  6548. }
  6549. if (bRet)
  6550. {
  6551. bRet = GreTransformPoints(hdc,pptTmp,pptTmp,c,iMode);
  6552. }
  6553. //
  6554. // copy pptTmp out to pptOut
  6555. //
  6556. if (bRet)
  6557. {
  6558. try
  6559. {
  6560. ProbeAndWriteBuffer(pptOut,pptTmp,c*sizeof(POINT));
  6561. }
  6562. except(EXCEPTION_EXECUTE_HANDLER)
  6563. {
  6564. WARNINGX(77);
  6565. // SetLastError(GetExceptionCode());
  6566. bRet = FALSE;
  6567. }
  6568. }
  6569. if (pptTmp && (pptTmp != apt))
  6570. FreeTmpBuffer(pptTmp);
  6571. return(bRet);
  6572. }
  6573. /******************************Public*Routine******************************\
  6574. * NtGdiGetTextCharsetInfo()
  6575. *
  6576. * History:
  6577. * Thu 23-Mar-1995 -by- Bodin Dresevic [BodinD]
  6578. * update: fixed it.
  6579. * 01-Nov-1994 -by- Eric Kutter [erick]
  6580. * Wrote it.
  6581. \**************************************************************************/
  6582. int
  6583. APIENTRY
  6584. NtGdiGetTextCharsetInfo(
  6585. HDC hdc,
  6586. LPFONTSIGNATURE lpSig,
  6587. DWORD dwFlags
  6588. )
  6589. {
  6590. FONTSIGNATURE fsig;
  6591. int iRet = GDI_ERROR;
  6592. fsig.fsUsb[0] = 0;
  6593. fsig.fsUsb[1] = 0;
  6594. fsig.fsUsb[2] = 0;
  6595. fsig.fsUsb[3] = 0;
  6596. fsig.fsCsb[0] = 0;
  6597. fsig.fsCsb[1] = 0;
  6598. iRet = GreGetTextCharsetInfo(hdc, lpSig ? &fsig : NULL , dwFlags);
  6599. if (iRet != GDI_ERROR)
  6600. {
  6601. if (lpSig)
  6602. {
  6603. try
  6604. {
  6605. ProbeAndWriteStructure(lpSig, fsig, FONTSIGNATURE);
  6606. }
  6607. except(EXCEPTION_EXECUTE_HANDLER)
  6608. {
  6609. WARNINGX(78);
  6610. // SetLastError(GetExceptionCode());
  6611. // look into gtc.c win95 source file, this is what they return
  6612. // in case of bad write pointer [bodind],
  6613. // cant return 0 - that's ANSI_CHARSET!
  6614. iRet = DEFAULT_CHARSET;
  6615. }
  6616. }
  6617. }
  6618. return iRet;
  6619. }
  6620. /******************************Public*Routine******************************\
  6621. * NtGdiGetBitmapDimension()
  6622. *
  6623. * History:
  6624. * 23-Feb-1995 -by- Lingyun Wang [lingyunw]
  6625. * Wrote it.
  6626. \**************************************************************************/
  6627. BOOL
  6628. APIENTRY
  6629. NtGdiGetBitmapDimension(
  6630. HBITMAP hbm,
  6631. LPSIZE psize
  6632. )
  6633. {
  6634. BOOL bRet;
  6635. SIZE tmpsize;
  6636. // check for null handle
  6637. if (hbm == 0)
  6638. {
  6639. bRet = FALSE;
  6640. }
  6641. // do the real work
  6642. else
  6643. {
  6644. bRet = GreGetBitmapDimension(hbm,&tmpsize);
  6645. // if Gre call is successful do this, otherwise
  6646. // we don't bother
  6647. if (bRet)
  6648. {
  6649. try
  6650. {
  6651. ProbeAndWriteStructure(psize,tmpsize,SIZE);
  6652. }
  6653. except(EXCEPTION_EXECUTE_HANDLER)
  6654. {
  6655. WARNINGX(81);
  6656. // SetLastError(GetExceptionCode());
  6657. bRet = FALSE;
  6658. }
  6659. }
  6660. }
  6661. return (bRet);
  6662. }
  6663. /******************************Public*Routine******************************\
  6664. * NtGdiSetBitmapDimension()
  6665. *
  6666. * History:
  6667. * 23-Feb-1995 -by- Lingyun Wang [lingyunw]
  6668. * Wrote it.
  6669. \**************************************************************************/
  6670. BOOL
  6671. APIENTRY
  6672. NtGdiSetBitmapDimension(
  6673. HBITMAP hbm,
  6674. int cx,
  6675. int cy,
  6676. LPSIZE psizeOut
  6677. )
  6678. {
  6679. BOOL bRet;
  6680. SIZE tmpsize;
  6681. // check for null handle
  6682. if (hbm == 0)
  6683. {
  6684. bRet = FALSE;
  6685. }
  6686. // do the real work
  6687. else
  6688. {
  6689. bRet = GreSetBitmapDimension(hbm,cx, cy, &tmpsize);
  6690. // if the Gre call is successful, we copy out
  6691. // the original size
  6692. if (bRet && psizeOut)
  6693. {
  6694. try
  6695. {
  6696. ProbeAndWriteStructure(psizeOut,tmpsize,SIZE);
  6697. }
  6698. except(EXCEPTION_EXECUTE_HANDLER)
  6699. {
  6700. WARNINGX(82);
  6701. // SetLastError(GetExceptionCode());
  6702. bRet = FALSE;
  6703. }
  6704. }
  6705. }
  6706. return (bRet);
  6707. }
  6708. BOOL
  6709. APIENTRY
  6710. NtGdiForceUFIMapping(
  6711. HDC hdc,
  6712. PUNIVERSAL_FONT_ID pufi
  6713. )
  6714. {
  6715. BOOL bRet = FALSE;
  6716. if( pufi )
  6717. {
  6718. try
  6719. {
  6720. UNIVERSAL_FONT_ID ufi;
  6721. ufi = ProbeAndReadStructure( pufi, UNIVERSAL_FONT_ID);
  6722. bRet = GreForceUFIMapping( hdc, &ufi);
  6723. }
  6724. except(EXCEPTION_EXECUTE_HANDLER)
  6725. {
  6726. WARNINGX(87);
  6727. bRet = FALSE;
  6728. }
  6729. }
  6730. return bRet;
  6731. }
  6732. typedef LONG (*NTGDIPALFUN)(HPALETTE,UINT,UINT,PPALETTEENTRY);
  6733. NTGDIPALFUN palfun[] =
  6734. {
  6735. (NTGDIPALFUN)GreAnimatePalette,
  6736. (NTGDIPALFUN)GreSetPaletteEntries,
  6737. (NTGDIPALFUN)GreGetPaletteEntries,
  6738. (NTGDIPALFUN)GreGetSystemPaletteEntries,
  6739. (NTGDIPALFUN)GreGetDIBColorTable,
  6740. (NTGDIPALFUN)GreSetDIBColorTable
  6741. };
  6742. /******************************Public*Routine******************************\
  6743. * NtGdiDoPalette
  6744. *
  6745. * History:
  6746. * 08-Mar-1995 Mark Enstrom [marke]
  6747. * Wrote it.
  6748. \**************************************************************************/
  6749. LONG
  6750. APIENTRY
  6751. NtGdiDoPalette(
  6752. HPALETTE hpal,
  6753. WORD iStart,
  6754. WORD cEntries,
  6755. PALETTEENTRY *pPalEntries,
  6756. DWORD iFunc,
  6757. BOOL bInbound)
  6758. {
  6759. LONG lRet = 0;
  6760. BOOL bStatus = TRUE;
  6761. PALETTEENTRY *ppalBuffer = (PALETTEENTRY*)NULL;
  6762. if (iFunc <= 5)
  6763. {
  6764. if (bInbound)
  6765. {
  6766. //
  6767. // copy pal entries to temp buffer if needed
  6768. //
  6769. if ((cEntries > 0))
  6770. {
  6771. if (!BALLOC_OVERFLOW1(cEntries,PALETTEENTRY))
  6772. {
  6773. ppalBuffer = (PALETTEENTRY *)AllocFreeTmpBuffer(cEntries * sizeof(PALETTEENTRY));
  6774. }
  6775. if (ppalBuffer == NULL)
  6776. {
  6777. bStatus = FALSE;
  6778. }
  6779. else
  6780. {
  6781. try
  6782. {
  6783. ProbeAndReadBuffer(ppalBuffer,pPalEntries,cEntries * sizeof(PALETTEENTRY));
  6784. }
  6785. except(EXCEPTION_EXECUTE_HANDLER)
  6786. {
  6787. WARNINGX(88);
  6788. bStatus = FALSE;
  6789. //SetLastError(GetExceptionCode());
  6790. }
  6791. }
  6792. }
  6793. if (bStatus)
  6794. {
  6795. lRet = (*palfun[iFunc])(
  6796. hpal,
  6797. iStart,
  6798. cEntries,
  6799. ppalBuffer);
  6800. }
  6801. }
  6802. else
  6803. {
  6804. LONG lRetEntries;
  6805. //
  6806. // Query of palette information
  6807. //
  6808. if (pPalEntries != (PALETTEENTRY*)NULL)
  6809. {
  6810. if (cEntries == 0)
  6811. {
  6812. // if there is a buffer but no entries, we're done.
  6813. bStatus = FALSE;
  6814. lRet = 0;
  6815. }
  6816. else
  6817. {
  6818. if (!BALLOC_OVERFLOW1(cEntries,PALETTEENTRY))
  6819. {
  6820. ppalBuffer = (PALETTEENTRY *)AllocFreeTmpBuffer(cEntries * sizeof(PALETTEENTRY));
  6821. }
  6822. if (ppalBuffer == NULL)
  6823. {
  6824. bStatus = FALSE;
  6825. }
  6826. }
  6827. }
  6828. if (bStatus)
  6829. {
  6830. lRet = (*palfun[iFunc])(
  6831. hpal,
  6832. iStart,
  6833. cEntries,
  6834. ppalBuffer);
  6835. //
  6836. // copy data back (if there is a buffer)
  6837. //
  6838. lRetEntries = min((LONG)cEntries,lRet);
  6839. if ((lRetEntries > 0) && (pPalEntries != (PALETTEENTRY*)NULL))
  6840. {
  6841. try
  6842. {
  6843. ProbeAndWriteBuffer(pPalEntries, ppalBuffer, lRetEntries * sizeof(PALETTEENTRY));
  6844. }
  6845. except(EXCEPTION_EXECUTE_HANDLER)
  6846. {
  6847. WARNINGX(89);
  6848. // SetLastError(GetExceptionCode());
  6849. lRet = 0;
  6850. }
  6851. }
  6852. }
  6853. }
  6854. if (ppalBuffer != (PALETTEENTRY*)NULL)
  6855. {
  6856. FreeTmpBuffer(ppalBuffer);
  6857. }
  6858. }
  6859. return(lRet);
  6860. }
  6861. /******************************Public*Routine******************************\
  6862. * NtGdiGetSpoolMessage()
  6863. *
  6864. * History:
  6865. * 21-Feb-1995 -by- Eric Kutter [erick]
  6866. * Wrote it.
  6867. \**************************************************************************/
  6868. ULONG NtGdiGetSpoolMessage(
  6869. PSPOOLESC psesc,
  6870. ULONG cjMsg,
  6871. PULONG pulOut,
  6872. ULONG cjOut
  6873. )
  6874. {
  6875. ULONG ulRet = 0;
  6876. HANDLE hSecure = 0;
  6877. // psesc contains two pieces. The header which includes data going
  6878. // in and out and the variable length data which is only output. We
  6879. // divide the message into two pieces here since we only need to validate
  6880. // the header up front. We just put a try/except around the output buffer
  6881. // when we copy it in later.
  6882. if (psesc && (cjMsg >= offsetof(SPOOLESC,ajData)))
  6883. {
  6884. try
  6885. {
  6886. ProbeForWrite(psesc,cjMsg,PROBE_ALIGNMENT(SPOOLESC));
  6887. hSecure = MmSecureVirtualMemory (psesc, cjMsg, PAGE_READWRITE);
  6888. }
  6889. except(EXCEPTION_EXECUTE_HANDLER)
  6890. {
  6891. WARNINGX(90);
  6892. }
  6893. if (hSecure)
  6894. {
  6895. ulRet = GreGetSpoolMessage(
  6896. psesc,
  6897. psesc->ajData,
  6898. cjMsg - offsetof(SPOOLESC,ajData),
  6899. pulOut,
  6900. cjOut );
  6901. MmUnsecureVirtualMemory (hSecure);
  6902. }
  6903. }
  6904. return(ulRet);
  6905. }
  6906. /******************************Public*Routine******************************\
  6907. * NtGdiUnloadPrinterDriver()
  6908. *
  6909. * This function is called by the spooler when the printer driver has to be
  6910. * unloaded for upgrade purposes. The driver will be marked to be unloaded when
  6911. * the DC count goes to zero.
  6912. *
  6913. * History:
  6914. * 11/18/97 Ramanathan Venkatapathy
  6915. * Wrote it.
  6916. \**************************************************************************/
  6917. BOOL APIENTRY NtGdiUnloadPrinterDriver(
  6918. LPWSTR pDriverName,
  6919. ULONG cbDriverName)
  6920. {
  6921. BOOL bReturn = FALSE;
  6922. WCHAR pDriverFile[MAX_PATH + 1];
  6923. RtlZeroMemory(pDriverFile, (MAX_PATH + 1) * sizeof(WCHAR));
  6924. // Check for invalid driver name.
  6925. if (cbDriverName > (MAX_PATH * sizeof(WCHAR)))
  6926. {
  6927. return bReturn;
  6928. }
  6929. __try
  6930. {
  6931. ProbeAndReadAlignedBuffer(pDriverFile, pDriverName, cbDriverName, sizeof(WCHAR) );
  6932. }
  6933. __except(EXCEPTION_EXECUTE_HANDLER)
  6934. {
  6935. WARNING("NtGdiUnloadPrinterDriver: bad driver file name.\n");
  6936. return bReturn;
  6937. }
  6938. bReturn = ldevArtificialDecrement(pDriverFile);
  6939. return bReturn;
  6940. }
  6941. /******************************Public*Routine******************************\
  6942. *
  6943. * NtGdiDescribePixelFormat
  6944. *
  6945. * Returns information about pixel formats for driver-managed surfaces
  6946. *
  6947. * History:
  6948. * Thu Nov 02 18:16:26 1995 -by- Drew Bliss [drewb]
  6949. * Created
  6950. *
  6951. \**************************************************************************/
  6952. int NtGdiDescribePixelFormat(HDC hdc, int ipfd, UINT cjpfd,
  6953. PPIXELFORMATDESCRIPTOR ppfd)
  6954. {
  6955. PIXELFORMATDESCRIPTOR pfdLocal;
  6956. int iRet;
  6957. if (cjpfd > 0 && ppfd == NULL)
  6958. {
  6959. return 0;
  6960. }
  6961. // Make sure we cannot overrun our local structure.
  6962. cjpfd = min(cjpfd, sizeof(pfdLocal));
  6963. // Retrieve information into a local copy because the
  6964. // devlock is held when the driver fills it in. If there
  6965. // was an access violation then the lock wouldn't be cleaned
  6966. // up
  6967. iRet = GreDescribePixelFormat(hdc, ipfd, cjpfd, &pfdLocal);
  6968. // Copy data back if necessary
  6969. if (iRet != 0 && cjpfd > 0)
  6970. {
  6971. try
  6972. {
  6973. ProbeAndWriteAlignedBuffer(ppfd, &pfdLocal, cjpfd, sizeof(ULONG));
  6974. }
  6975. except(EXCEPTION_EXECUTE_HANDLER)
  6976. {
  6977. WARNINGX(92);
  6978. iRet = 0;
  6979. }
  6980. }
  6981. return iRet;
  6982. }
  6983. /******************************Public*Routine******************************\
  6984. * NtGdiFlush: Stub onle
  6985. *
  6986. * Arguments:
  6987. *
  6988. * None
  6989. *
  6990. * Return Value:
  6991. *
  6992. * None
  6993. *
  6994. * History:
  6995. *
  6996. * 1-Nov-1995 -by- Mark Enstrom [marke]
  6997. *
  6998. \**************************************************************************/
  6999. VOID
  7000. NtGdiFlush()
  7001. {
  7002. GreFlush();
  7003. }
  7004. /******************************Public*Routine*****************************\
  7005. * NtGdiGetCharWidthInfo
  7006. *
  7007. * Get the lMaxNegA lMaxNegC and lMinWidthD
  7008. *
  7009. * History:
  7010. * 14-Feb-1996 -by- Xudong Wu [tessiew]
  7011. * Wrote it.
  7012. \*************************************************************************/
  7013. BOOL
  7014. APIENTRY
  7015. NtGdiGetCharWidthInfo(
  7016. HDC hdc,
  7017. PCHWIDTHINFO pChWidthInfo
  7018. )
  7019. {
  7020. BOOL bRet = FALSE;
  7021. CHWIDTHINFO tempChWidthInfo;
  7022. bRet = GreGetCharWidthInfo( hdc, &tempChWidthInfo );
  7023. if (bRet)
  7024. {
  7025. try
  7026. {
  7027. ProbeAndWriteBuffer( pChWidthInfo, &tempChWidthInfo, sizeof(CHWIDTHINFO) );
  7028. }
  7029. except( EXCEPTION_EXECUTE_HANDLER )
  7030. {
  7031. WARNINGX(93);
  7032. bRet = FALSE;
  7033. }
  7034. }
  7035. return ( bRet );
  7036. }
  7037. ULONG
  7038. APIENTRY
  7039. NtGdiMakeFontDir(
  7040. FLONG flEmbed, // mark file as "hidden"
  7041. PBYTE pjFontDir, // pointer to structure to fill
  7042. unsigned cjFontDir, // >= CJ_FONTDIR
  7043. PWSZ pwszPathname, // path of font file to use
  7044. unsigned cjPathname // <= sizeof(WCHAR) * (MAX_PATH+1)
  7045. )
  7046. {
  7047. ULONG ulRet;
  7048. WCHAR awcPathname[MAX_PATH+1]; // safe buffer for path name
  7049. BYTE ajFontDir[CJ_FONTDIR]; // safe buffer for return data
  7050. ulRet = 0;
  7051. if ( (cjPathname <= (sizeof(WCHAR) * (MAX_PATH+1))) &&
  7052. (cjFontDir >= CJ_FONTDIR) )
  7053. {
  7054. ulRet = 1;
  7055. __try
  7056. {
  7057. ProbeAndReadAlignedBuffer( awcPathname, pwszPathname, cjPathname, sizeof(*pwszPathname));
  7058. }
  7059. __except(EXCEPTION_EXECUTE_HANDLER)
  7060. {
  7061. WARNING("NtGdiMakeFondDir: bad pwszPathname\n");
  7062. ulRet = 0;
  7063. }
  7064. if ( ulRet )
  7065. {
  7066. awcPathname[MAX_PATH] = 0;
  7067. ulRet = GreMakeFontDir( flEmbed, ajFontDir, awcPathname );
  7068. if ( ulRet )
  7069. {
  7070. __try
  7071. {
  7072. ProbeAndWriteBuffer( pjFontDir, ajFontDir, CJ_FONTDIR );
  7073. }
  7074. __except(EXCEPTION_EXECUTE_HANDLER)
  7075. {
  7076. WARNING("NtGdiMakeFondDir: bad pjFontDir\n");
  7077. ulRet = 0;
  7078. }
  7079. }
  7080. }
  7081. }
  7082. return( ulRet );
  7083. }
  7084. DWORD APIENTRY NtGdiGetGlyphIndicesWInternal(
  7085. HDC hdc,
  7086. LPWSTR pwc,
  7087. int cwc,
  7088. LPWORD pgi,
  7089. DWORD iMode,
  7090. BOOL bSubset
  7091. )
  7092. {
  7093. WORD awBuffer[2*LOCAL_CWC_MAX];
  7094. LPWSTR pwcTmp;
  7095. LPWORD pgiTmp = NULL;
  7096. DWORD dwRet = GDI_ERROR;
  7097. if (cwc < 0)
  7098. return dwRet;
  7099. // test for important special case
  7100. if ((cwc == 0) && (pwc == NULL) && (pgi == NULL) && (iMode == 0))
  7101. return GreGetGlyphIndicesW(hdc, NULL, 0, NULL, 0, bSubset);
  7102. if (cwc <= LOCAL_CWC_MAX)
  7103. {
  7104. pgiTmp = awBuffer;
  7105. }
  7106. else
  7107. {
  7108. if (!BALLOC_OVERFLOW2(cwc,WORD,WCHAR))
  7109. {
  7110. pgiTmp = (LPWORD)AllocFreeTmpBuffer(cwc * (sizeof(WORD)+sizeof(WCHAR)));
  7111. }
  7112. }
  7113. if (pgiTmp)
  7114. {
  7115. // make a temp buffer for the string in the same buffer, after the indices
  7116. pwcTmp = &pgiTmp[cwc];
  7117. try
  7118. {
  7119. ProbeAndReadBuffer(pwcTmp, pwc, cwc * sizeof(WCHAR));
  7120. dwRet = cwc; // indicate that we did not hit the exception
  7121. }
  7122. except(EXCEPTION_EXECUTE_HANDLER)
  7123. {
  7124. WARNINGX(98);
  7125. dwRet = GDI_ERROR;
  7126. }
  7127. if (dwRet != GDI_ERROR)
  7128. dwRet = GreGetGlyphIndicesW(hdc, pwcTmp, cwc, pgiTmp, iMode, bSubset);
  7129. if (dwRet != GDI_ERROR)
  7130. {
  7131. try
  7132. {
  7133. ProbeAndWriteBuffer(pgi, pgiTmp, cwc * sizeof(WORD));
  7134. }
  7135. except(EXCEPTION_EXECUTE_HANDLER)
  7136. {
  7137. WARNINGX(99);
  7138. dwRet = GDI_ERROR;
  7139. }
  7140. }
  7141. if (pgiTmp != awBuffer)
  7142. FreeTmpBuffer(pgiTmp);
  7143. }
  7144. return dwRet;
  7145. }
  7146. DWORD APIENTRY NtGdiGetGlyphIndicesW(
  7147. HDC hdc,
  7148. LPWSTR pwc,
  7149. int cwc,
  7150. LPWORD pgi,
  7151. DWORD iMode
  7152. )
  7153. {
  7154. return NtGdiGetGlyphIndicesWInternal(hdc, pwc, cwc, pgi, iMode, FALSE);
  7155. }
  7156. /******************************Public*Routine******************************\
  7157. *
  7158. * NtGdi stub for GetFontUnicodeRanges
  7159. *
  7160. * History:
  7161. * 09-Sep-1996 -by- Bodin Dresevic [BodinD]
  7162. * Wrote it.
  7163. \**************************************************************************/
  7164. DWORD NtGdiGetFontUnicodeRanges(HDC hdc, LPGLYPHSET pgs)
  7165. {
  7166. DWORD dwRet, dwRet1;
  7167. LPGLYPHSET pgsTmp = NULL;
  7168. dwRet = GreGetFontUnicodeRanges(hdc, NULL);
  7169. if (dwRet && pgs)
  7170. {
  7171. if (pgsTmp = (LPGLYPHSET)AllocFreeTmpBuffer(dwRet))
  7172. {
  7173. dwRet1 = GreGetFontUnicodeRanges(hdc, pgsTmp);
  7174. if (dwRet1 && (dwRet == dwRet1)) // consistency check
  7175. {
  7176. try
  7177. {
  7178. ProbeAndWriteBuffer(pgs, pgsTmp, dwRet);
  7179. }
  7180. except(EXCEPTION_EXECUTE_HANDLER)
  7181. {
  7182. WARNINGX(102);
  7183. dwRet = 0;
  7184. }
  7185. }
  7186. else
  7187. {
  7188. WARNINGX(101);
  7189. dwRet = 0;
  7190. }
  7191. FreeTmpBuffer(pgsTmp);
  7192. }
  7193. else
  7194. {
  7195. WARNINGX(100);
  7196. dwRet = 0;
  7197. }
  7198. }
  7199. return dwRet;
  7200. }
  7201. #ifdef LANGPACK
  7202. BOOL
  7203. APIENTRY
  7204. NtGdiGetRealizationInfo(
  7205. HDC hdc,
  7206. PREALIZATION_INFO pri,
  7207. KHFONT hf
  7208. )
  7209. {
  7210. REALIZATION_INFO riTmp;
  7211. BOOL bRet = TRUE;
  7212. int ii;
  7213. bRet = GreGetRealizationInfo(hdc, &riTmp);
  7214. try
  7215. {
  7216. if (bRet)
  7217. {
  7218. ProbeAndWriteStructure(pri,riTmp,REALIZATION_INFO);
  7219. }
  7220. if (bRet)
  7221. {
  7222. if (hf)
  7223. {
  7224. // Find CFONT Location
  7225. for (ii = 0; ii < MAX_PUBLIC_CFONT; ++ii)
  7226. if (gpGdiSharedMemory->acfPublic[ii].hf == (HFONT)hf)
  7227. break;
  7228. if (ii < MAX_PUBLIC_CFONT){
  7229. CFONT* pcf = &gpGdiSharedMemory->acfPublic[ii];
  7230. pcf->ri = riTmp;
  7231. pcf->fl |= CFONT_CACHED_RI;
  7232. pcf->timeStamp = gpGdiSharedMemory->timeStamp;
  7233. }
  7234. }
  7235. }
  7236. }
  7237. except(EXCEPTION_EXECUTE_HANDLER)
  7238. {
  7239. WARNINGX(104);
  7240. // SetLastError(GetExceptionCode());
  7241. bRet = FALSE;
  7242. }
  7243. return (bRet);
  7244. }
  7245. #endif
  7246. /******************************Public*Routine******************************\
  7247. * NtGdiDrawStream
  7248. *
  7249. * Arguments:
  7250. *
  7251. * hdc - handle to primary destination device context
  7252. * cjIn - size, in bytes, of input draw stream
  7253. * pjIn - address of input draw stream
  7254. *
  7255. * Return Value:
  7256. *
  7257. * TRUE : success
  7258. * FALSE : faiure
  7259. *
  7260. * History:
  7261. *
  7262. * 3-19-2001 bhouse Created it
  7263. *
  7264. \**************************************************************************/
  7265. #define DS_STACKBUFLENGTH 256
  7266. BOOL
  7267. APIENTRY
  7268. NtGdiDrawStream(
  7269. HDC hdcDst,
  7270. ULONG cjIn,
  7271. PVOID pvIn
  7272. )
  7273. {
  7274. BYTE pbScratchBuf[DS_STACKBUFLENGTH];
  7275. BOOL bRet = FALSE;
  7276. PVOID pvScratch = NULL;
  7277. if(cjIn > sizeof(pbScratchBuf))
  7278. {
  7279. if (BALLOC_OVERFLOW1(cjIn,BYTE))
  7280. {
  7281. WARNING("NtGdiDrawStream: input stream is too large\n");
  7282. goto exit;
  7283. }
  7284. pvScratch = AllocFreeTmpBuffer(cjIn);
  7285. if (pvScratch == NULL)
  7286. {
  7287. WARNING("NtGdiDrawStream: unable to allocate temp buffer\n");
  7288. goto exit;
  7289. }
  7290. }
  7291. else
  7292. {
  7293. pvScratch = (PVOID) pbScratchBuf;
  7294. }
  7295. // copy the stream from user mode
  7296. // NOTE: we can get rid of the copy if we try/except in all appropriate
  7297. // places during the handling of the stream.
  7298. try
  7299. {
  7300. ProbeAndReadBuffer(pvScratch, pvIn,cjIn);
  7301. }
  7302. except(EXCEPTION_EXECUTE_HANDLER)
  7303. {
  7304. WARNING("NtGdiDrawStream: exception occured reading stream\n");
  7305. goto exit;
  7306. }
  7307. bRet = GreDrawStream(hdcDst, cjIn, pvScratch);
  7308. exit:
  7309. if(pvScratch != NULL && pvScratch != pbScratchBuf)
  7310. {
  7311. FreeTmpBuffer(pvScratch);
  7312. }
  7313. return bRet;
  7314. }