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.

508 lines
16 KiB

  1. /*****************************************************************************
  2. *
  3. * apientry.c - This module contains the API entry points for the
  4. * Win32 to Win16 metafile converter.
  5. *
  6. * Date: 8/29/91
  7. * Author: Jeffrey Newman (c-jeffn)
  8. *
  9. * Copyright 1991 Microsoft Corp
  10. *****************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. BOOL bMemUpdateCheckSum(PLOCALDC pLocalDC) ;
  14. PLOCALDC pldcInitLocalDC(HDC hdcRef, INT iMapMode, DWORD flags) ;
  15. VOID vFreeLocalDC(PLOCALDC pLocalDC);
  16. extern VOID __cdecl _cfltcvt_init(VOID) ;
  17. // This critical section structure is shared by all the threads of a given
  18. // process.
  19. CRITICAL_SECTION CriticalSection ;
  20. // Constant definition for internal static string(s).
  21. BYTE szDisplay[] = "DISPLAY" ;
  22. /*****************************************************************************
  23. * Entry point for translation
  24. *****************************************************************************/
  25. UINT ConvertEmfToWmf(PVOID pht, PBYTE pMetafileBits, UINT cDest, PBYTE pDest,
  26. INT iMapMode, HDC hdcRef, UINT flags)
  27. {
  28. BOOL b ;
  29. DWORD lret = 0;
  30. PLOCALDC pLocalDC ;
  31. // We funnel through one exit to make sure we leave the
  32. // critical section.
  33. EnterCriticalSection(&CriticalSection) ;
  34. // Check the requested map mode and if it's valid
  35. if (iMapMode < MM_MIN || iMapMode > MM_MAX)
  36. {
  37. RIP("MF3216:ConvertEmfToWmf - Invalid MapMode\n") ;
  38. goto ErrorExit;
  39. }
  40. // Check for a reference DC. If one is not supplied we fail.
  41. if (hdcRef == (HDC) 0)
  42. {
  43. RIP("MF3216:ConvertEmfToWmf - Invalid RefDC\n") ;
  44. goto ErrorExit;
  45. }
  46. // Check the validity of the flags.
  47. if ((flags & ~MF3216_INCLUDE_WIN32MF) != 0)
  48. {
  49. RIP("MF3216: ConvertEmfToWmf - Invalid flags\n") ;
  50. goto ErrorExit ;
  51. }
  52. // Allocate the LocalDC and initialize some of it's fields.
  53. pLocalDC = pldcInitLocalDC(hdcRef, iMapMode, flags) ;
  54. if (pLocalDC == (PLOCALDC) 0)
  55. {
  56. goto ErrorExit ;
  57. }
  58. // If pDest is NULL then we just return the size of the buffer required
  59. // to hold the Win16 metafile bits.
  60. pLocalDC->pht = pht;
  61. if (pDest == (PBYTE) 0)
  62. {
  63. pLocalDC->flags |= SIZE_ONLY ;
  64. b = bParseWin32Metafile(pMetafileBits, pLocalDC) ;
  65. if (b == TRUE)
  66. {
  67. lret = pLocalDC->ulBytesEmitted ;
  68. }
  69. else
  70. {
  71. PUTS("MF3216: ConvertEmfToWmf - Size Only failed\n") ;
  72. }
  73. }
  74. else
  75. {
  76. // Put the user specified Win16 buffer pointer and buffer length
  77. // into the localDC.
  78. pLocalDC->pMf16Bits = pDest ;
  79. pLocalDC->cMf16Dest = cDest ;
  80. // Translate the Win32 metafile to a Win16 metafile.
  81. b = bParseWin32Metafile(pMetafileBits, pLocalDC) ;
  82. if (b == TRUE)
  83. {
  84. // Update the Win16 metafile header.
  85. b = bUpdateMf16Header(pLocalDC) ;
  86. if (b == TRUE)
  87. {
  88. // Only acknowledge that we have translated some bits
  89. // if everything has gone well.
  90. lret = pLocalDC->ulBytesEmitted ;
  91. // If we're including the Win32 metafile then update the
  92. // checksum field in the "Win32Comment header" record.
  93. if (pLocalDC->flags & INCLUDE_W32MF_COMMENT)
  94. bMemUpdateCheckSum(pLocalDC) ;
  95. }
  96. }
  97. else
  98. {
  99. PUTS("MF3216: ConvertEmfToWmf - Metafile conversion failed\n") ;
  100. }
  101. }
  102. // Free the LocalDC and its resources.
  103. vFreeLocalDC(pLocalDC);
  104. ErrorExit:
  105. LeaveCriticalSection(&CriticalSection) ;
  106. return (lret) ;
  107. }
  108. /*****************************************************************************
  109. * pldcInitLocalDC - Initialize the Local DC.
  110. *****************************************************************************/
  111. PLOCALDC pldcInitLocalDC(HDC hdcRef, INT iMapMode, DWORD flags)
  112. {
  113. PLOCALDC pLocalDC;
  114. PLOCALDC pldcRet = (PLOCALDC) NULL; // assume error
  115. // Allocate and initialize memory for the LocalDC.
  116. pLocalDC = (PLOCALDC) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
  117. sizeof(LOCALDC));
  118. if (!pLocalDC)
  119. {
  120. PUTS("MF3216:pldcInitLocalDC - LocalAlloc failure\n") ;
  121. return((PLOCALDC) NULL);
  122. }
  123. // Record the size of the DC.
  124. pLocalDC->nSize = sizeof(LOCALDC) ;
  125. // Set the LocalDC boolean that controls whether or not we include
  126. // the Win32 metafile as one or more comment records.
  127. if (flags & MF3216_INCLUDE_WIN32MF)
  128. pLocalDC->flags |= INCLUDE_W32MF_COMMENT ;
  129. #if 0
  130. // Need to create a hdc for the display.
  131. // Initially this will be used by the bitblt translation code
  132. // to get a reasonable set of palette entries.
  133. // The reference DC only has a black & white palette.
  134. pLocalDC->hdcDisp = CreateDCA((LPCSTR)szDisplay, (LPCSTR)NULL, (LPCSTR)NULL, (CONST DEVMODEA *)NULL) ;
  135. if (pLocalDC->hdcDisp == (HDC) 0)
  136. {
  137. RIP("MF3216:pldcInitLocalDC - CreateDCA(hdcDisp) failed\n") ;
  138. goto pldcInitLocalDC_exit;
  139. }
  140. #endif // 0
  141. // Create the HelperDC.
  142. pLocalDC->hdcHelper = CreateICA((LPCSTR) szDisplay,
  143. (LPCSTR) NULL,
  144. (LPCSTR) NULL,
  145. (LPDEVMODEA) NULL) ;
  146. if (pLocalDC->hdcHelper == (HDC)0)
  147. {
  148. PUTS("MF3216: pldcInitLocalDC, Create Helper DC failed\n") ;
  149. goto pldcInitLocalDC_exit;
  150. }
  151. // Initialize the counters we need to keep for updating the header,
  152. // and keeping track of the object table.
  153. pLocalDC->nObjectHighWaterMark = -1;
  154. // Get the play-time device dimensions in millimeters and in pels.
  155. pLocalDC->cxPlayDevMM = GetDeviceCaps(hdcRef, HORZSIZE) ;
  156. pLocalDC->cyPlayDevMM = GetDeviceCaps(hdcRef, VERTSIZE) ;
  157. pLocalDC->cxPlayDevPels = GetDeviceCaps(hdcRef, HORZRES) ;
  158. pLocalDC->cyPlayDevPels = GetDeviceCaps(hdcRef, VERTRES) ;
  159. // Record the requested map mode and reference DC.
  160. pLocalDC->iMapMode = iMapMode ;
  161. pLocalDC->hdcRef = hdcRef ;
  162. // Init Arc Direction.
  163. pLocalDC->iArcDirection = AD_COUNTERCLOCKWISE ;
  164. // Make current position invalid so that a moveto will be
  165. // emitted when it is first used. See comments in DoMoveTo.
  166. pLocalDC->ptCP.x = MAXLONG ;
  167. pLocalDC->ptCP.y = MAXLONG ;
  168. // Default pen is a black pen.
  169. pLocalDC->lhpn32 = BLACK_PEN | ENHMETA_STOCK_OBJECT;
  170. // Default brush is a white brush.
  171. pLocalDC->lhbr32 = WHITE_BRUSH | ENHMETA_STOCK_OBJECT;
  172. // Default palette.
  173. pLocalDC->ihpal32 = DEFAULT_PALETTE | ENHMETA_STOCK_OBJECT;
  174. pLocalDC->ihpal16 = (DWORD) -1; // no W16 palette created yet
  175. pLocalDC->crBkColor = RGB(0xFF,0xFF,0xFF);
  176. // pLocalDC->pW16ObjHndlSlotStatus = NULL;
  177. // pLocalDC->cW16ObjHndlSlotStatus = 0;
  178. // pLocalDC->piW32ToW16ObjectMap = NULL;
  179. // pLocalDC->cW32ToW16ObjectMap = 0;
  180. // pLocalDC->crTextColor = RGB(0x0,0x0,0x0);
  181. // pLocalDC->iLevel = 0;
  182. // pLocalDC->pLocalDCSaved = NULL;
  183. // pLocalDC->ulBytesEmitted = 0;
  184. // pLocalDC->ulMaxRecord = 0;
  185. // pLocalDC->pW32hPal = NULL;
  186. // Set the advanced graphics mode in the helper DC. This is needed
  187. // to notify the helper DC that rectangles and ellipses are
  188. // inclusive-inclusive etc., especially when rendering them in a path.
  189. // Also, the world transform can only be set in the advanced mode.
  190. (void) SetGraphicsMode(pLocalDC->hdcHelper, GM_ADVANCED);
  191. // We are golden.
  192. pldcRet = pLocalDC;
  193. pldcInitLocalDC_exit:
  194. if (!pldcRet)
  195. vFreeLocalDC(pLocalDC);
  196. return(pldcRet) ;
  197. }
  198. /*****************************************************************************
  199. * vFreeLocalDC - Free the Local DC and its resources.
  200. *****************************************************************************/
  201. VOID vFreeLocalDC(PLOCALDC pLocalDC)
  202. {
  203. UINT i;
  204. // Free the helper DCs.
  205. if (pLocalDC->hdcHelper)
  206. if (!DeleteDC(pLocalDC->hdcHelper))
  207. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, DeleteDC failed");
  208. #if 0
  209. if (pLocalDC->hdcDisp)
  210. if (!DeleteDC(pLocalDC->hdcDisp))
  211. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, DeleteDC failed");
  212. #endif // 0
  213. // Free the storage for the object translation map.
  214. if (pLocalDC->piW32ToW16ObjectMap)
  215. {
  216. #if 0
  217. for (i = 0 ; i < pLocalDC->cW32ToW16ObjectMap ; i++)
  218. {
  219. if (pLocalDC->piW32ToW16ObjectMap[i] != UNMAPPED)
  220. if (i > STOCK_LAST)
  221. PUTS1("MF3216: vFreeLocalDC, object32 %ld is not freed\n", i - STOCK_LAST - 1);
  222. else
  223. PUTS1("MF3216: vFreeLocalDC, stock object32 %ld is mapped\n",i);
  224. }
  225. #endif // 0
  226. if (LocalFree(pLocalDC->piW32ToW16ObjectMap))
  227. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, LocalFree failed");
  228. }
  229. // Free the W32 palette handles.
  230. if (pLocalDC->pW32hPal)
  231. {
  232. for (i = 0; i < pLocalDC->cW32hPal; i++)
  233. {
  234. if (pLocalDC->pW32hPal[i])
  235. if (!DeleteObject(pLocalDC->pW32hPal[i]))
  236. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, delete palette failed");
  237. }
  238. if (LocalFree(pLocalDC->pW32hPal))
  239. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, LocalFree failed");
  240. }
  241. // Free the w32 handles in the pW16ObjHndlSlotStatus array.
  242. // We free the handles after we have deleted the helper DC so that
  243. // the w32 handles are not selected into any DC.
  244. if (pLocalDC->pW16ObjHndlSlotStatus)
  245. {
  246. for (i = 0 ; i < pLocalDC->cW16ObjHndlSlotStatus ; i++)
  247. {
  248. #if 0
  249. if (pLocalDC->pW16ObjHndlSlotStatus[i].use
  250. != OPEN_AVAILABLE_SLOT)
  251. PUTS1("MF3216: vFreeLocalDC, object16 %ld is not freed\n", i);
  252. #endif // 0
  253. if (pLocalDC->pW16ObjHndlSlotStatus[i].w32Handle)
  254. {
  255. ASSERTGDI(pLocalDC->pW16ObjHndlSlotStatus[i].use
  256. != OPEN_AVAILABLE_SLOT,
  257. "MF3216: error in object handle table");
  258. if (!DeleteObject(pLocalDC->pW16ObjHndlSlotStatus[i].w32Handle))
  259. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, DeleteObject failed");
  260. }
  261. }
  262. if (LocalFree(pLocalDC->pW16ObjHndlSlotStatus))
  263. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, LocalFree failed");
  264. }
  265. // The DC level should be balanced.
  266. if (pLocalDC->pLocalDCSaved != NULL)
  267. {
  268. PLOCALDC pNext, pTmp;
  269. for (pNext = pLocalDC->pLocalDCSaved; pNext; )
  270. {
  271. PUTS("MF3216: vFreeLocalDC, unbalanced DC level\n");
  272. pTmp = pNext->pLocalDCSaved;
  273. if (LocalFree(pNext))
  274. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, LocalFree failed");
  275. pNext = pTmp;
  276. }
  277. }
  278. // Finally, free the LocalDC.
  279. if (LocalFree(pLocalDC))
  280. ASSERTGDI(FALSE, "MF3216: vFreeLocalDC, LocalFree failed");
  281. }
  282. /***************************************************************************
  283. * Handle emitting the Win32 metafile comment record(s).
  284. **************************************************************************/
  285. BOOL bHandleWin32Comment(PLOCALDC pLocalDC)
  286. {
  287. INT i;
  288. BOOL b ;
  289. META_ESCAPE_ENHANCED_METAFILE mfeEnhMF;
  290. // Win30 may have problems with large (over 8K) escape records.
  291. // We will limit the size of each Win32 Comment record to
  292. // MAX_WIN32_COMMENT_REC_SIZE.
  293. // Initialize the record header.
  294. mfeEnhMF.rdFunction = META_ESCAPE;
  295. mfeEnhMF.wEscape = MFCOMMENT;
  296. mfeEnhMF.ident = MFCOMMENT_IDENTIFIER;
  297. mfeEnhMF.iComment = MFCOMMENT_ENHANCED_METAFILE;
  298. mfeEnhMF.nVersion = ((PENHMETAHEADER) pLocalDC->pMf32Bits)->nVersion;
  299. mfeEnhMF.wChecksum = 0; // updated by bMemUpdateCheckSum
  300. mfeEnhMF.fFlags = 0;
  301. mfeEnhMF.nCommentRecords
  302. = (pLocalDC->cMf32Bits + MAX_WIN32_COMMENT_REC_SIZE - 1)
  303. / MAX_WIN32_COMMENT_REC_SIZE;
  304. mfeEnhMF.cbEnhMetaFile = pLocalDC->cMf32Bits;
  305. mfeEnhMF.cbRemainder = pLocalDC->cMf32Bits;
  306. i = 0 ;
  307. while (mfeEnhMF.cbRemainder)
  308. {
  309. mfeEnhMF.cbCurrent = min(mfeEnhMF.cbRemainder, MAX_WIN32_COMMENT_REC_SIZE);
  310. mfeEnhMF.rdSize = (sizeof(mfeEnhMF) + mfeEnhMF.cbCurrent) / 2;
  311. mfeEnhMF.wCount = (WORD)(sizeof(mfeEnhMF) + mfeEnhMF.cbCurrent - sizeof(METARECORD_ESCAPE));
  312. mfeEnhMF.cbRemainder -= mfeEnhMF.cbCurrent;
  313. b = bEmitWin16EscapeEnhMetaFile(pLocalDC,
  314. (PMETARECORD_ESCAPE) &mfeEnhMF, &pLocalDC->pMf32Bits[i]);
  315. if (!b)
  316. break;
  317. i += mfeEnhMF.cbCurrent;
  318. }
  319. return(b) ;
  320. }
  321. /*****************************************************************************
  322. * bMemUpdateCheckSum - Update the checksum
  323. *****************************************************************************/
  324. BOOL bMemUpdateCheckSum(PLOCALDC pLocalDC)
  325. {
  326. INT i, k ;
  327. PWORD pword ;
  328. WORD CheckSum ;
  329. PMETA_ESCAPE_ENHANCED_METAFILE pmfeEnhMF;
  330. // CheckSum the file.
  331. // Do a 16 bit checksum
  332. pword = (PWORD) pLocalDC->pMf16Bits ;
  333. k = pLocalDC->ulBytesEmitted / 2 ;
  334. CheckSum = 0 ;
  335. for (i = 0 ; i < k ; i++)
  336. CheckSum += pword[i] ;
  337. // Update the checksum record value with the real checksum.
  338. pmfeEnhMF = (PMETA_ESCAPE_ENHANCED_METAFILE)
  339. &pLocalDC->pMf16Bits[sizeof(METAHEADER)];
  340. ASSERTGDI(IS_META_ESCAPE_ENHANCED_METAFILE(pmfeEnhMF)
  341. && pmfeEnhMF->wChecksum == 0
  342. && pmfeEnhMF->fFlags == 0,
  343. "MF3216: bMemUpdateCheckSum: Bad pmfeEnhMF");
  344. pmfeEnhMF->wChecksum = -CheckSum;
  345. #if DBG
  346. // Now test the checksum. The checksum of the entire file
  347. // should be 0.
  348. CheckSum = 0 ;
  349. pword = (PWORD) pLocalDC->pMf16Bits ;
  350. for (i = 0 ; i < k ; i++)
  351. CheckSum += pword[i] ;
  352. if (CheckSum != 0)
  353. {
  354. RIP("MF3216: MemUpdateCheckSum, (CheckSum != 0)\n") ;
  355. }
  356. #endif
  357. return (TRUE) ;
  358. }
  359. /******************************Public*Routine******************************\
  360. * Mf3216DllInitialize *
  361. * *
  362. * This is the init procedure for MF3216.DLL, *
  363. * which is called each time a new *
  364. * process links to it. *
  365. \**************************************************************************/
  366. BOOL Mf3216DllInitialize(PVOID pvDllHandle, DWORD ulReason, PCONTEXT pcontext)
  367. {
  368. NOTUSED(pvDllHandle) ;
  369. NOTUSED(pcontext) ;
  370. if ( ulReason == DLL_PROCESS_ATTACH )
  371. {
  372. // This does the critical section initialization for a single
  373. // process. Each process does this. The CriticalSection data
  374. // structure is one of the very few (if not the only one) data
  375. // structures in the data segment.
  376. InitializeCriticalSection(&CriticalSection) ;
  377. }
  378. else if ( ulReason == DLL_PROCESS_DETACH )
  379. {
  380. DeleteCriticalSection(&CriticalSection) ;
  381. }
  382. return(TRUE);
  383. }