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.

610 lines
16 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WGMETA.C
  8. * WOW32 16-bit GDI API support
  9. *
  10. * History:
  11. * Created 07-Mar-1991 by Jeff Parsons (jeffpar)
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. MODNAME(wgmeta.c);
  16. typedef METAHEADER UNALIGNED *PMETAHEADER16;
  17. // WARNING: This function may cause 16-bit memory to move
  18. VOID CopyMetaFile16FromHMF32(HAND16 hMF16, HMETAFILE hMF32)
  19. {
  20. UINT cbMF32, cbMF16;
  21. VPVOID vp;
  22. PBYTE pMF16;
  23. if((vp = GlobalLock16(hMF16, &cbMF16)) && hMF32) {
  24. GETMISCPTR(vp, pMF16);
  25. cbMF32 = GetMetaFileBitsEx(hMF32, 0, NULL);
  26. // Verify these are the same size within the 16-bit kernel memory
  27. // allocation granularity
  28. WOW32WARNMSGF((abs(cbMF16 - cbMF32) < 32),
  29. ("WOW32: Size MF16 = %lu MF32 = %lu\n", cbMF16, cbMF32));
  30. // copy the bits from the 32-bit metafile to the 16-bit metafile memory
  31. cbMF32 = GetMetaFileBitsEx(hMF32, min(cbMF16, cbMF32), pMF16);
  32. GlobalUnlock16(hMF16);
  33. FLUSHVDMPTR(vp, cbMF32, pMF16);
  34. FREEMISCPTR(pMF16);
  35. }
  36. }
  37. // WARNING: This function may cause 16-bit memory to move
  38. HAND16 WinMetaFileFromHMF(HMETAFILE hmf, BOOL fFreeOriginal)
  39. {
  40. UINT cbMetaData;
  41. VPVOID vpMetaData;
  42. PBYTE pMetaData;
  43. HAND16 h16;
  44. /*
  45. * Under Windows Metafiles were merely Global Handle to memory
  46. * so we have to mimick that behavior because some apps "operate"
  47. * on metafile handles directly. (WinWord and PowerPoint to
  48. * GlobalSize and GlobalAlloc to size and create metafiles)
  49. */
  50. cbMetaData = GetMetaFileBitsEx(hmf, 0, NULL);
  51. if (!cbMetaData)
  52. return((HAND16)NULL);
  53. /*
  54. * Win 3.1 allocates extra space in MetaFile and OLE2 checks for this.
  55. * METAHEADER is defined to be the same size as the 16-bit structure.
  56. */
  57. cbMetaData += sizeof(METAHEADER);
  58. vpMetaData = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_DDESHARE, cbMetaData, &h16);
  59. if (!vpMetaData)
  60. return((HAND16)NULL);
  61. GETOPTPTR(vpMetaData, 0, pMetaData);
  62. if (GetMetaFileBitsEx(hmf, cbMetaData, pMetaData)) {
  63. GlobalUnlock16(h16);
  64. } else {
  65. GlobalUnlockFree16(vpMetaData);
  66. return((HAND16)NULL);
  67. }
  68. if (fFreeOriginal)
  69. DeleteMetaFile(hmf);
  70. return(h16);
  71. }
  72. HMETAFILE HMFFromWinMetaFile(HAND16 h16, BOOL fFreeOriginal)
  73. {
  74. INT cb;
  75. VPVOID vp;
  76. HMETAFILE hmf = (HMETAFILE)0;
  77. PMETAHEADER16 pMFH16;
  78. vp = GlobalLock16(h16, &cb);
  79. if (vp) {
  80. GETMISCPTR(vp, pMFH16);
  81. hmf = SetMetaFileBitsEx(cb, (LPBYTE)pMFH16);
  82. if (fFreeOriginal)
  83. GlobalUnlockFree16(vp);
  84. else
  85. GlobalUnlock16(h16);
  86. FREEMISCPTR(pMFH16);
  87. }
  88. return(hmf);
  89. }
  90. ULONG FASTCALL WG32CloseMetaFile(PVDMFRAME pFrame)
  91. {
  92. HMETAFILE hmf;
  93. ULONG ulRet = 0;
  94. HAND16 hdc16;
  95. HANDLE hdc32;
  96. register PCLOSEMETAFILE16 parg16;
  97. GETARGPTR(pFrame, sizeof(CLOSEMETAFILE16), parg16);
  98. hdc16 = (HAND16)parg16->f1;
  99. hdc32 = HDC32(hdc16);
  100. hmf = CloseMetaFile(hdc32);
  101. // update our GDI handle mapping table
  102. DeleteWOWGdiHandle(hdc32, hdc16);
  103. if (hmf)
  104. ulRet = (ULONG)WinMetaFileFromHMF(hmf, TRUE);
  105. // WARNING: 16-bit memory may have moved - invalidate flat pointers now
  106. FREEVDMPTR(pFrame);
  107. FREEARGPTR(parg16);
  108. RETURN(ulRet);
  109. }
  110. ULONG FASTCALL WG32CopyMetaFile(PVDMFRAME pFrame)
  111. {
  112. ULONG ul;
  113. PSZ psz2;
  114. HMETAFILE hmfNew;
  115. HMETAFILE hmf;
  116. register PCOPYMETAFILE16 parg16;
  117. GETARGPTR(pFrame, sizeof(COPYMETAFILE16), parg16);
  118. GETPSZPTR(parg16->f2, psz2);
  119. if (psz2) {
  120. hmf = HMFFromWinMetaFile(parg16->f1, FALSE);
  121. hmfNew = CopyMetaFile(hmf, psz2);
  122. DeleteMetaFile(hmf);
  123. ul = (ULONG)WinMetaFileFromHMF(hmfNew, TRUE);
  124. // WARNING: 16-bit memory may have moved - invalidate flat pointers now
  125. FREEVDMPTR(pFrame);
  126. FREEARGPTR(parg16);
  127. FREEPSZPTR(psz2);
  128. } else {
  129. UINT cb;
  130. VPVOID vp, vpNew;
  131. PBYTE pMF, pMFNew;
  132. HAND16 h16New, h16;
  133. h16 = (HAND16)parg16->f1;
  134. ul = (ULONG) NULL;
  135. vp = GlobalLock16(h16, &cb);
  136. if (vp) {
  137. /*
  138. * Windows app such as WinWord uses GlobalSize to determine
  139. * the size of the metafile. However, this size can be larger
  140. * than the true size of a metafile. We have to make sure that
  141. * both source and destination sizes are identical so that
  142. * WinWord doesn't crash.
  143. */
  144. vpNew = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_DDESHARE, cb, &h16New);
  145. // 16-bit memory may have moved - invalidate flat pointers now
  146. FREEVDMPTR(pFrame);
  147. FREEARGPTR(parg16);
  148. FREEPSZPTR(psz2);
  149. if (vpNew) {
  150. GETMISCPTR(vp, pMF);
  151. GETOPTPTR(vpNew, 0, pMFNew);
  152. RtlCopyMemory(pMFNew, pMF, cb);
  153. GlobalUnlock16(h16New);
  154. FLUSHVDMPTR(vpNew, cb, pMFNew);
  155. FREEOPTPTR(pMFNew);
  156. ul = h16New;
  157. }
  158. GlobalUnlock16(h16);
  159. FREEMISCPTR(pMF);
  160. }
  161. }
  162. FREEPSZPTR(psz2);
  163. FREEARGPTR(parg16);
  164. RETURN(ul);
  165. }
  166. ULONG FASTCALL WG32CreateMetaFile(PVDMFRAME pFrame)
  167. {
  168. ULONG ul;
  169. PSZ psz1;
  170. register PCREATEMETAFILE16 parg16;
  171. GETARGPTR(pFrame, sizeof(CREATEMETAFILE16), parg16);
  172. GETPSZPTR(parg16->f1, psz1);
  173. ul = GETHDC16(CreateMetaFile(psz1));
  174. FREEPSZPTR(psz1);
  175. FREEARGPTR(parg16);
  176. RETURN(ul);
  177. }
  178. //
  179. // This routine does what the 16-bit parameter validation layer would
  180. // normally do for metafile handles, but since it is currently disabled,
  181. // we'll do it here to fix WordPerfect that relies on it. Once true
  182. // win31-style parameter validation has been re-enabled for metafile
  183. // handles, all code within the ifndefs here and in WG32DeleteMetaFile
  184. // can be removed.
  185. //
  186. #ifndef PARAMETER_VALIDATION_16_RE_ENABLED
  187. #define MEMORYMETAFILE 1
  188. #define DISKMETAFILE 2
  189. #define HEADERSIZE (sizeof(METAHEADER)/sizeof(WORD))
  190. #define METAVERSION 0x0300
  191. #define METAVERSION100 0x0100
  192. BOOL IsValidMetaFile16(PMETAHEADER16 lpMetaData)
  193. {
  194. BOOL sts = FALSE;
  195. sts = (lpMetaData->mtType == MEMORYMETAFILE ||
  196. lpMetaData->mtType == DISKMETAFILE) &&
  197. (lpMetaData->mtHeaderSize == HEADERSIZE) &&
  198. ((lpMetaData->mtVersion ==METAVERSION) ||
  199. (lpMetaData->mtVersion ==METAVERSION100)) ;
  200. return sts;
  201. }
  202. #endif
  203. ULONG FASTCALL WG32DeleteMetaFile(PVDMFRAME pFrame)
  204. {
  205. ULONG ul = FALSE;
  206. VPVOID vp;
  207. #ifndef PARAMETER_VALIDATION_16_RE_ENABLED
  208. PMETAHEADER16 lpMetaData;
  209. #endif
  210. register PDELETEMETAFILE16 parg16;
  211. GETARGPTR(pFrame, sizeof(DELETEMETAFILE16), parg16);
  212. if (vp = GlobalLock16(parg16->f1,NULL)) {
  213. #ifdef PARAMETER_VALIDATION_16_RE_ENABLED
  214. GlobalUnlockFree16(vp);
  215. ul = TRUE;
  216. #else
  217. GETVDMPTR(vp, 1, lpMetaData);
  218. if (IsValidMetaFile16(lpMetaData)) {
  219. GlobalUnlockFree16(vp);
  220. ul = TRUE;
  221. }
  222. FREEVDMPTR(lpMetaData);
  223. #endif
  224. }
  225. // If this metafile was in DDE conversation, then DDE cleanup code
  226. // needs to free its 32 bit counter part. So give DDE clean up
  227. // code a chance.
  228. // ChandanC
  229. W32DdeFreeHandle16 (parg16->f1);
  230. FREEARGPTR(parg16);
  231. RETURN(ul);
  232. }
  233. INT WG32EnumMetaFileCallBack(HDC hdc, LPHANDLETABLE lpht, LPMETARECORD lpMR, LONG nObj, PMETADATA pMetaData )
  234. {
  235. INT iReturn;
  236. DWORD nWords;
  237. // update object table if we have one
  238. if (pMetaData->parmemp.vpHandleTable)
  239. PUTHANDLETABLE16(pMetaData->parmemp.vpHandleTable, nObj, lpht);
  240. // update MetaRecord
  241. // don't trash the heap with a bogus record, halt the enumeration
  242. nWords = lpMR->rdSize;
  243. if (nWords > pMetaData->mtMaxRecordSize) {
  244. LOGDEBUG(0,("WOW:bad metafile record during enumeration\n"));
  245. WOW32ASSERT(FALSE); // contact barryb
  246. return 0; // all done
  247. }
  248. putstr16(pMetaData->parmemp.vpMetaRecord, (LPSZ)lpMR, nWords*sizeof(WORD));
  249. CallBack16(RET_ENUMMETAFILEPROC, (PPARM16)&pMetaData->parmemp, pMetaData->vpfnEnumMetaFileProc, (PVPVOID)&iReturn);
  250. // update the metarec in case the app altered it (Approach does)
  251. getstr16(pMetaData->parmemp.vpMetaRecord, (LPSZ)lpMR, nWords*sizeof(WORD));
  252. // update object table if we have one
  253. if (pMetaData->parmemp.vpHandleTable)
  254. GETHANDLETABLE16(pMetaData->parmemp.vpHandleTable,nObj,lpht);
  255. return (SHORT)iReturn;
  256. hdc; // quiet the compilier; we already know the DC
  257. }
  258. ULONG FASTCALL WG32EnumMetaFile(PVDMFRAME pFrame)
  259. {
  260. ULONG ul = 0;
  261. register PENUMMETAFILE16 parg16;
  262. METADATA metadata;
  263. VPVOID vpMetaFile = (VPVOID) NULL;
  264. PBYTE pMetaFile;
  265. HMETAFILE hmf = (HMETAFILE) 0;
  266. HAND16 hMetaFile16;
  267. HDC hDC = 0;
  268. HDC hDC2 = 0;
  269. GETARGPTR(pFrame, sizeof(ENUMMETAFILE16), parg16);
  270. hMetaFile16 = parg16->f2;
  271. metadata.vpfnEnumMetaFileProc = DWORD32(parg16->f3);
  272. metadata.parmemp.vpData = (VPVOID)DWORD32(parg16->f4);
  273. metadata.parmemp.vpMetaRecord = (VPVOID) NULL;
  274. metadata.parmemp.vpHandleTable = (VPVOID) NULL;
  275. metadata.parmemp.hdc = parg16->f1;
  276. // WinWord never calls SetMetaFileBits; they peeked and know that
  277. // a metafile is really a GlobalHandle in Windows so we have
  278. // to look for that case.
  279. hmf = HMFFromWinMetaFile(hMetaFile16, FALSE);
  280. if (!hmf)
  281. goto EMF_Exit;
  282. // Get the metafile bits so we can get max record size and number of objects
  283. vpMetaFile = GlobalLock16(hMetaFile16, NULL);
  284. FREEARGPTR(parg16); // memory may have moved
  285. FREEVDMPTR(pFrame);
  286. if (!vpMetaFile)
  287. goto EMF_Exit;
  288. GETOPTPTR(vpMetaFile, 0, pMetaFile);
  289. if (!pMetaFile)
  290. goto EMF_Exit;
  291. metadata.parmemp.nObjects = ((PMETAHEADER16)pMetaFile)->mtNoObjects;
  292. metadata.mtMaxRecordSize = ((PMETAHEADER16)pMetaFile)->mtMaxRecord;
  293. if (metadata.parmemp.nObjects)
  294. {
  295. PBYTE pHT;
  296. DWORD cb = ((PMETAHEADER16)pMetaFile)->mtNoObjects*sizeof(HAND16);
  297. metadata.parmemp.vpHandleTable =
  298. GlobalAllocLock16(GMEM_MOVEABLE, cb, NULL);
  299. FREEOPTPTR(pMetaFile); // memory may have moved
  300. FREEARGPTR(parg16);
  301. FREEVDMPTR(pFrame);
  302. if (!metadata.parmemp.vpHandleTable)
  303. goto EMF_Exit;
  304. GETOPTPTR(metadata.parmemp.vpHandleTable, 0, pHT);
  305. RtlZeroMemory(pHT, cb);
  306. }
  307. metadata.parmemp.vpMetaRecord = GlobalAllocLock16(GMEM_MOVEABLE, metadata.mtMaxRecordSize*sizeof(WORD), NULL);
  308. FREEOPTPTR(pMetaFile); // memory may have moved
  309. FREEARGPTR(parg16);
  310. FREEVDMPTR(pFrame);
  311. if (!metadata.parmemp.vpMetaRecord)
  312. goto EMF_Exit;
  313. hDC = HDC32(metadata.parmemp.hdc);
  314. // Corel Draw passes a NULL hDC, we'll create a dummy to keep GDI32 happy.
  315. if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_GETDUMMYDC) {
  316. if (hDC == 0) {
  317. hDC = CreateMetaFile(NULL);
  318. hDC2 = hDC;
  319. }
  320. }
  321. // When processing metafile, access2.0 faults while receiving
  322. // WM_DEVMODECHANGE so we block that particular message when
  323. // in EnumMetaFile
  324. if ( CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_EATDEVMODEMSG) {
  325. CURRENTPTD()->dwFlags |= TDF_EATDEVMODEMSG;
  326. }
  327. ul = GETBOOL16(EnumMetaFile(hDC,
  328. hmf,
  329. (MFENUMPROC)WG32EnumMetaFileCallBack,
  330. ((LPARAM)(LPVOID)&metadata)));
  331. CURRENTPTD()->dwFlags &= ~TDF_EATDEVMODEMSG;
  332. // 16-bit memory may have moved - nothing to do as no flat ptrs exist now
  333. // copy the 32-bit metafile back to 16-bit land (the app may have altered
  334. // some of the metarecs in its MetaRecCallBackFunc -- Approach does)
  335. CopyMetaFile16FromHMF32(hMetaFile16, hmf);
  336. // Cleanup the dummy hDC created for Corel Draw 5.0.
  337. if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_GETDUMMYDC) {
  338. if (hDC2 != 0) {
  339. DeleteMetaFile(CloseMetaFile(hDC2));
  340. }
  341. }
  342. EMF_Exit:
  343. if (vpMetaFile)
  344. GlobalUnlock16(hMetaFile16);
  345. if (hmf)
  346. DeleteMetaFile(hmf);
  347. if (metadata.parmemp.vpHandleTable)
  348. GlobalUnlockFree16(metadata.parmemp.vpHandleTable);
  349. if (metadata.parmemp.vpMetaRecord)
  350. GlobalUnlockFree16(metadata.parmemp.vpMetaRecord);
  351. FREEARGPTR(parg16);
  352. RETURN(ul);
  353. }
  354. ULONG FASTCALL WG32GetMetaFile(PVDMFRAME pFrame)
  355. {
  356. ULONG ul;
  357. PSZ psz1;
  358. HMETAFILE hmf;
  359. register PGETMETAFILE16 parg16;
  360. GETARGPTR(pFrame, sizeof(GETMETAFILE16), parg16);
  361. GETPSZPTR(parg16->f1, psz1);
  362. hmf = GetMetaFile(psz1);
  363. if (hmf)
  364. ul = WinMetaFileFromHMF(hmf, TRUE);
  365. else
  366. ul = 0;
  367. FREEPSZPTR(psz1);
  368. FREEARGPTR(parg16);
  369. RETURN(ul);
  370. }
  371. ULONG FASTCALL WG32PlayMetaFile(PVDMFRAME pFrame)
  372. {
  373. ULONG ul;
  374. HMETAFILE hmf;
  375. register PPLAYMETAFILE16 parg16;
  376. GETARGPTR(pFrame, sizeof(PLAYMETAFILE16), parg16);
  377. hmf = HMFFromWinMetaFile(parg16->f2, FALSE);
  378. ul = GETBOOL16(PlayMetaFile(HDC32(parg16->f1), hmf));
  379. if (hmf)
  380. DeleteMetaFile(hmf);
  381. FREEARGPTR(parg16);
  382. RETURN(ul);
  383. }
  384. ULONG FASTCALL WG32PlayMetaFileRecord(PVDMFRAME pFrame)
  385. {
  386. ULONG ul = FALSE;
  387. LPHANDLETABLE pHT = NULL;
  388. PBYTE pMetaData;
  389. PMETARECORD pMetaRec;
  390. HANDLE hDeleteObject32 = NULL;
  391. HAND16 hDeleteObject16 = 0;
  392. WORD wHandles;
  393. VPHANDLETABLE16 vpHT;
  394. register PPLAYMETAFILERECORD16 parg16;
  395. GETARGPTR(pFrame, sizeof(PLAYMETAFILERECORD16), parg16);
  396. wHandles = parg16->f4;
  397. vpHT = parg16->f2;
  398. if (wHandles && vpHT) {
  399. ALLOCHANDLETABLE16(wHandles, pHT);
  400. if (!pHT)
  401. goto PMFR_Exit;
  402. GETHANDLETABLE16(vpHT, wHandles, pHT);
  403. }
  404. GETOPTPTR(parg16->f3, 0, pMetaData);
  405. // If the record is a DeleteObject record, save the index into the metafile
  406. // handle table.
  407. pMetaRec = (PMETARECORD)pMetaData;
  408. if(pMetaRec) {
  409. if(pMetaRec->rdFunction == META_DELETEOBJECT) {
  410. hDeleteObject32 = pHT->objectHandle[pMetaRec->rdParm[0]];
  411. hDeleteObject16 = GDI16(hDeleteObject32);
  412. }
  413. }
  414. ul = (ULONG) PlayMetaFileRecord(HDC32(parg16->f1),
  415. pHT,
  416. (LPMETARECORD)pMetaData,
  417. (UINT)wHandles);
  418. if (wHandles && vpHT) {
  419. // This will cause any handles that were created implicitly by the call
  420. // PlayMetaFileRecord() & added to the metafile handle table (pHT) to be
  421. // added to our GDI handle mapping table.
  422. PUTHANDLETABLE16(vpHT, wHandles, pHT);
  423. FREEHANDLETABLE16(pHT);
  424. }
  425. // Remove the handle associated with this DeleteObject record from the GDI
  426. // handle mapping table.
  427. if(hDeleteObject16) {
  428. DeleteWOWGdiHandle((HANDLE)hDeleteObject32, hDeleteObject16);
  429. }
  430. PMFR_Exit:
  431. FREEARGPTR(parg16);
  432. RETURN(ul);
  433. }
  434. #if 0 // implemented in gdi.exe
  435. ULONG FASTCALL WG32GetMetaFileBits(PVDMFRAME pFrame)
  436. {
  437. ULONG ul = 0;
  438. register PGETMETAFILEBITS16 parg16;
  439. GETARGPTR(pFrame, sizeof(GETMETAFILEBITS16), parg16);
  440. if (GlobalLock16(parg16->f1,NULL))
  441. {
  442. GlobalUnlock16(parg16->f1);
  443. ul = parg16->f1;
  444. }
  445. FREEARGPTR(parg16);
  446. RETURN(ul);
  447. }
  448. ULONG FASTCALL WG32SetMetaFileBits(PVDMFRAME pFrame)
  449. {
  450. ULONG ul;
  451. register PSETMETAFILEBITS16 parg16;
  452. GETARGPTR(pFrame, sizeof(SETMETAFILEBITS16), parg16);
  453. ul = parg16->f1;
  454. FREEARGPTR(parg16);
  455. RETURN(ul);
  456. }
  457. #endif