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.

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