diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/wow32/wgmeta.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/mvdm/wow32/wgmeta.c')
-rw-r--r-- | private/mvdm/wow32/wgmeta.c | 562 |
1 files changed, 562 insertions, 0 deletions
diff --git a/private/mvdm/wow32/wgmeta.c b/private/mvdm/wow32/wgmeta.c new file mode 100644 index 000000000..44fa11e8f --- /dev/null +++ b/private/mvdm/wow32/wgmeta.c @@ -0,0 +1,562 @@ +/*++ + * + * WOW v1.0 + * + * Copyright (c) 1991, Microsoft Corporation + * + * WGMETA.C + * WOW32 16-bit GDI API support + * + * History: + * Created 07-Mar-1991 by Jeff Parsons (jeffpar) +--*/ + + +#include "precomp.h" +#pragma hdrstop + +MODNAME(wgmeta.c); + +typedef METAHEADER UNALIGNED *PMETAHEADER16; + + + + +// WARNING: This function may cause 16-bit memory to move +VOID CopyMetaFile16FromHMF32(HAND16 hMF16, HMETAFILE hMF32) +{ + UINT cbMF32, cbMF16; + VPVOID vp; + PBYTE pMF16; + + + if((vp = GlobalLock16(hMF16, &cbMF16)) && hMF32) { + + GETMISCPTR(vp, pMF16); + + cbMF32 = GetMetaFileBitsEx(hMF32, 0, NULL); + + // Verify these are the same size within the 16-bit kernel memory + // allocation granularity + WOW32WARNMSGF((abs(cbMF16 - cbMF32) < 32), + ("WOW32: Size MF16 = %lu MF32 = %lu\n", cbMF16, cbMF32)); + + // copy the bits from the 32-bit metafile to the 16-bit metafile memory + cbMF32 = GetMetaFileBitsEx(hMF32, min(cbMF16, cbMF32), pMF16); + + GlobalUnlock16(hMF16); + FLUSHVDMPTR(vp, cbMF32, pMF16); + FREEMISCPTR(pMF16); + } +} + + + + +// WARNING: This function may cause 16-bit memory to move +HAND16 WinMetaFileFromHMF(HMETAFILE hmf, BOOL fFreeOriginal) +{ + UINT cbMetaData; + VPVOID vpMetaData; + PBYTE pMetaData; + HAND16 h16; + + /* + * Under Windows Metafiles were merely Global Handle to memory + * so we have to mimick that behavior because some apps "operate" + * on metafile handles directly. (WinWord and PowerPoint to + * GlobalSize and GlobalAlloc to size and create metafiles) + */ + + cbMetaData = GetMetaFileBitsEx(hmf, 0, NULL); + + if (!cbMetaData) + return((HAND16)NULL); + + /* + * Win 3.1 allocates extra space in MetaFile and OLE2 checks for this. + * METAHEADER is defined to be the same size as the 16-bit structure. + */ + + cbMetaData += sizeof(METAHEADER); + + vpMetaData = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_DDESHARE, cbMetaData, &h16); + + if (!vpMetaData) + return((HAND16)NULL); + + + GETOPTPTR(vpMetaData, 0, pMetaData); + + if (GetMetaFileBitsEx(hmf, cbMetaData, pMetaData)) { + GlobalUnlock16(h16); + } else { + GlobalUnlockFree16(vpMetaData); + return((HAND16)NULL); + } + + if (fFreeOriginal) + DeleteMetaFile(hmf); + + return(h16); +} + +HMETAFILE HMFFromWinMetaFile(HAND16 h16, BOOL fFreeOriginal) +{ + INT cb; + VPVOID vp; + HMETAFILE hmf = (HMETAFILE)0; + PMETAHEADER16 pMFH16; + + vp = GlobalLock16(h16, &cb); + + if (vp) { + GETMISCPTR(vp, pMFH16); + + hmf = SetMetaFileBitsEx(cb, (LPBYTE)pMFH16); + + if (fFreeOriginal) + GlobalUnlockFree16(vp); + else + GlobalUnlock16(h16); + + FREEMISCPTR(pMFH16); + } + + return(hmf); +} + + +ULONG FASTCALL WG32CloseMetaFile(PVDMFRAME pFrame) +{ + HMETAFILE hmf; + ULONG ulRet = 0; + register PCLOSEMETAFILE16 parg16; + + GETARGPTR(pFrame, sizeof(CLOSEMETAFILE16), parg16); + + hmf = CloseMetaFile(HDC32(parg16->f1)); + + if (hmf) + ulRet = (ULONG)WinMetaFileFromHMF(hmf, TRUE); + // WARNING: 16-bit memory may have moved - invalidate flat pointers now + FREEVDMPTR(pFrame); + FREEARGPTR(parg16); + RETURN(ulRet); +} + + +ULONG FASTCALL WG32CopyMetaFile(PVDMFRAME pFrame) +{ + ULONG ul; + PSZ psz2; + HMETAFILE hmfNew; + HMETAFILE hmf; + register PCOPYMETAFILE16 parg16; + + GETARGPTR(pFrame, sizeof(COPYMETAFILE16), parg16); + GETPSZPTR(parg16->f2, psz2); + + if (psz2) { + hmf = HMFFromWinMetaFile(parg16->f1, FALSE); + hmfNew = CopyMetaFile(hmf, psz2); + DeleteMetaFile(hmf); + ul = (ULONG)WinMetaFileFromHMF(hmfNew, TRUE); + // WARNING: 16-bit memory may have moved - invalidate flat pointers now + FREEVDMPTR(pFrame); + FREEARGPTR(parg16); + FREEPSZPTR(psz2); + } else { + UINT cb; + VPVOID vp, vpNew; + PBYTE pMF, pMFNew; + HAND16 h16New, h16; + + h16 = (HAND16)parg16->f1; + + ul = (ULONG) NULL; + + vp = GlobalLock16(h16, &cb); + if (vp) { + + /* + * Windows app such as WinWord uses GlobalSize to determine + * the size of the metafile. However, this size can be larger + * than the true size of a metafile. We have to make sure that + * both source and destination sizes are identical so that + * WinWord doesn't crash. + */ + + vpNew = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_DDESHARE, cb, &h16New); + + // 16-bit memory may have moved - invalidate flat pointers now + FREEVDMPTR(pFrame); + FREEARGPTR(parg16); + FREEPSZPTR(psz2); + + if (vpNew) { + GETMISCPTR(vp, pMF); + GETOPTPTR(vpNew, 0, pMFNew); + + RtlCopyMemory(pMFNew, pMF, cb); + + GlobalUnlock16(h16New); + FLUSHVDMPTR(vpNew, cb, pMFNew); + FREEOPTPTR(pMFNew); + ul = h16New; + } + + GlobalUnlock16(h16); + FREEMISCPTR(pMF); + } + } + + FREEPSZPTR(psz2); + FREEARGPTR(parg16); + RETURN(ul); +} + + +ULONG FASTCALL WG32CreateMetaFile(PVDMFRAME pFrame) +{ + ULONG ul; + PSZ psz1; + register PCREATEMETAFILE16 parg16; + + GETARGPTR(pFrame, sizeof(CREATEMETAFILE16), parg16); + GETPSZPTR(parg16->f1, psz1); + + ul = GETHDC16(CreateMetaFile(psz1)); + + FREEPSZPTR(psz1); + FREEARGPTR(parg16); + RETURN(ul); +} + +// +// This routine does what the 16-bit parameter validation layer would +// normally do for metafile handles, but since it is currently disabled, +// we'll do it here to fix WordPerfect that relies on it. Once true +// win31-style parameter validation has been re-enabled for metafile +// handles, all code within the ifndefs here and in WG32DeleteMetaFile +// can be removed. +// +#ifndef PARAMETER_VALIDATION_16_RE_ENABLED +#define MEMORYMETAFILE 1 +#define DISKMETAFILE 2 +#define HEADERSIZE (sizeof(METAHEADER)/sizeof(WORD)) +#define METAVERSION 0x0300 +#define METAVERSION100 0x0100 + +BOOL IsValidMetaFile16(PMETAHEADER16 lpMetaData) +{ + BOOL sts = FALSE; + + sts = (lpMetaData->mtType == MEMORYMETAFILE || + lpMetaData->mtType == DISKMETAFILE) && + (lpMetaData->mtHeaderSize == HEADERSIZE) && + ((lpMetaData->mtVersion ==METAVERSION) || + (lpMetaData->mtVersion ==METAVERSION100)) ; + return sts; +} +#endif + +ULONG FASTCALL WG32DeleteMetaFile(PVDMFRAME pFrame) +{ + ULONG ul = FALSE; + VPVOID vp; +#ifndef PARAMETER_VALIDATION_16_RE_ENABLED + PMETAHEADER16 lpMetaData; +#endif + + register PDELETEMETAFILE16 parg16; + + GETARGPTR(pFrame, sizeof(DELETEMETAFILE16), parg16); + + if (vp = GlobalLock16(parg16->f1,NULL)) { +#ifdef PARAMETER_VALIDATION_16_RE_ENABLED + GlobalUnlockFree16(vp); + ul = TRUE; +#else + GETVDMPTR(vp, 1, lpMetaData); + + if (IsValidMetaFile16(lpMetaData)) { + GlobalUnlockFree16(vp); + ul = TRUE; + } + + FREEVDMPTR(lpMetaData); +#endif + } + + + // If this metafile was in DDE conversation, then DDE cleanup code + // needs to free its 32 bit counter part. So give DDE clean up + // code a chance. + // ChandanC + + W32DdeFreeHandle16 (parg16->f1); + + FREEARGPTR(parg16); + RETURN(ul); +} + +INT WG32EnumMetaFileCallBack(HDC hdc, LPHANDLETABLE lpht, LPMETARECORD lpMR, LONG nObj, PMETADATA pMetaData ) +{ + INT iReturn; + DWORD nWords; + + // update object table if we have one + if (pMetaData->parmemp.vpHandleTable) + PUTHANDLETABLE16(pMetaData->parmemp.vpHandleTable,nObj,lpht); + + // update MetaRecord + + // don't trash the heap with a bogus record, halt the enumeration + nWords = lpMR->rdSize; + if (nWords > pMetaData->mtMaxRecordSize) { + LOGDEBUG(0,("WOW:bad metafile record during enumeration\n")); + WOW32ASSERT(FALSE); // contact barryb + return 0; // all done + } + putstr16(pMetaData->parmemp.vpMetaRecord, (LPSZ)lpMR, nWords*sizeof(WORD)); + + CallBack16(RET_ENUMMETAFILEPROC, (PPARM16)&pMetaData->parmemp, pMetaData->vpfnEnumMetaFileProc, (PVPVOID)&iReturn); + + // update the metarec in case the app altered it (Approach does) + getstr16(pMetaData->parmemp.vpMetaRecord, (LPSZ)lpMR, nWords*sizeof(WORD)); + + // update object table if we have one + if (pMetaData->parmemp.vpHandleTable) + GETHANDLETABLE16(pMetaData->parmemp.vpHandleTable,nObj,lpht); + + return (SHORT)iReturn; + + hdc; // quiet the compilier; we already know the DC +} + +ULONG FASTCALL WG32EnumMetaFile(PVDMFRAME pFrame) +{ + ULONG ul = 0; + register PENUMMETAFILE16 parg16; + METADATA metadata; + VPVOID vpMetaFile = (VPVOID) NULL; + PBYTE pMetaFile; + HMETAFILE hmf = (HMETAFILE) 0; + HAND16 hMetaFile16; + HDC hDC = 0; + + GETARGPTR(pFrame, sizeof(ENUMMETAFILE16), parg16); + + hMetaFile16 = parg16->f2; + + metadata.vpfnEnumMetaFileProc = DWORD32(parg16->f3); + metadata.parmemp.vpData = (VPVOID)DWORD32(parg16->f4); + metadata.parmemp.vpMetaRecord = (VPVOID) NULL; + metadata.parmemp.vpHandleTable = (VPVOID) NULL; + metadata.parmemp.hdc = parg16->f1; + + // WinWord never calls SetMetaFileBits; they peeked and know that + // a metafile is really a GlobalHandle in Windows so we have + // to look for that case. + + hmf = HMFFromWinMetaFile(hMetaFile16, FALSE); + if (!hmf) + goto EMF_Exit; + + // Get the metafile bits so we can get max record size and number of objects + + vpMetaFile = GlobalLock16(hMetaFile16, NULL); + FREEARGPTR(parg16); // memory may have moved + FREEVDMPTR(pFrame); + if (!vpMetaFile) + goto EMF_Exit; + + GETOPTPTR(vpMetaFile, 0, pMetaFile); + if (!pMetaFile) + goto EMF_Exit; + + metadata.parmemp.nObjects = ((PMETAHEADER16)pMetaFile)->mtNoObjects; + metadata.mtMaxRecordSize = ((PMETAHEADER16)pMetaFile)->mtMaxRecord; + + if (metadata.parmemp.nObjects) + { + PBYTE pHT; + DWORD cb = ((PMETAHEADER16)pMetaFile)->mtNoObjects*sizeof(HAND16); + + metadata.parmemp.vpHandleTable = GlobalAllocLock16(GMEM_MOVEABLE, cb, NULL); + FREEOPTPTR(pMetaFile); // memory may have moved + FREEARGPTR(parg16); + FREEVDMPTR(pFrame); + if (!metadata.parmemp.vpHandleTable) + goto EMF_Exit; + + GETOPTPTR(metadata.parmemp.vpHandleTable, 0, pHT); + RtlZeroMemory(pHT, cb); + } + + metadata.parmemp.vpMetaRecord = GlobalAllocLock16(GMEM_MOVEABLE, metadata.mtMaxRecordSize*sizeof(WORD), NULL); + FREEOPTPTR(pMetaFile); // memory may have moved + FREEARGPTR(parg16); + FREEVDMPTR(pFrame); + if (!metadata.parmemp.vpMetaRecord) + goto EMF_Exit; + + // Corel Draw passes a NULL hDC, we'll create a dummy to keep GDI32 happy. + if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_GETDUMMYDC) { + if ((hDC = HDC32(metadata.parmemp.hdc)) == 0) { + hDC = CreateMetaFile(NULL); + } + } + else { + hDC = HDC32(metadata.parmemp.hdc); + } + + ul = GETBOOL16(EnumMetaFile(hDC, + hmf, + (MFENUMPROC)WG32EnumMetaFileCallBack, + ((LPARAM)(LPVOID)&metadata))); + // 16-bit memory may have moved - nothing to do as no flat ptrs exist now + + // copy the 32-bit metafile back to 16-bit land (the app may have altered + // some of the metarecs in its MetaRecCallBackFunc -- Approach does) + CopyMetaFile16FromHMF32(hMetaFile16, hmf); + + // Cleanup the dummy hDC created for Corel Draw 5.0. + if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_GETDUMMYDC) { + if (HDC32(metadata.parmemp.hdc) == 0) { + DeleteMetaFile(CloseMetaFile(hDC)); + } + } + +EMF_Exit: + if (vpMetaFile) + GlobalUnlock16(hMetaFile16); + + if (hmf) + DeleteMetaFile(hmf); + + if (metadata.parmemp.vpHandleTable) + GlobalUnlockFree16(metadata.parmemp.vpHandleTable); + + if (metadata.parmemp.vpMetaRecord) + GlobalUnlockFree16(metadata.parmemp.vpMetaRecord); + + FREEARGPTR(parg16); + RETURN(ul); +} + + +ULONG FASTCALL WG32GetMetaFile(PVDMFRAME pFrame) +{ + ULONG ul; + PSZ psz1; + HMETAFILE hmf; + register PGETMETAFILE16 parg16; + + GETARGPTR(pFrame, sizeof(GETMETAFILE16), parg16); + GETPSZPTR(parg16->f1, psz1); + + hmf = GetMetaFile(psz1); + + if (hmf) + ul = WinMetaFileFromHMF(hmf, TRUE); + else + ul = 0; + + FREEPSZPTR(psz1); + FREEARGPTR(parg16); + RETURN(ul); +} + + +ULONG FASTCALL WG32PlayMetaFile(PVDMFRAME pFrame) +{ + ULONG ul; + HMETAFILE hmf; + register PPLAYMETAFILE16 parg16; + + GETARGPTR(pFrame, sizeof(PLAYMETAFILE16), parg16); + + hmf = HMFFromWinMetaFile(parg16->f2, FALSE); + + ul = GETBOOL16(PlayMetaFile(HDC32(parg16->f1), hmf)); + + if (hmf) + DeleteMetaFile(hmf); + + FREEARGPTR(parg16); + RETURN(ul); +} + + +ULONG FASTCALL WG32PlayMetaFileRecord(PVDMFRAME pFrame) +{ + ULONG ul = FALSE; + LPHANDLETABLE pHT = NULL; + PBYTE pMetaData; + WORD wHandles; + VPHANDLETABLE16 vpHT; + register PPLAYMETAFILERECORD16 parg16; + + GETARGPTR(pFrame, sizeof(PLAYMETAFILERECORD16), parg16); + + wHandles = parg16->f4; + vpHT = parg16->f2; + if (wHandles && vpHT) { + ALLOCHANDLETABLE16(wHandles, pHT); + if (!pHT) + goto PMFR_Exit; + + GETHANDLETABLE16(vpHT, wHandles, pHT); + } + GETOPTPTR(parg16->f3, 0, pMetaData); + + ul = (ULONG) PlayMetaFileRecord(HDC32(parg16->f1), + pHT, + (LPMETARECORD)pMetaData, + (UINT)wHandles); + + + if (wHandles && vpHT) { + PUTHANDLETABLE16(vpHT, wHandles, pHT); + FREEHANDLETABLE16(pHT); + } +PMFR_Exit: + FREEARGPTR(parg16); + RETURN(ul); +} + +#if 0 // implemented in gdi.exe + +ULONG FASTCALL WG32GetMetaFileBits(PVDMFRAME pFrame) +{ + ULONG ul = 0; + register PGETMETAFILEBITS16 parg16; + + GETARGPTR(pFrame, sizeof(GETMETAFILEBITS16), parg16); + + if (GlobalLock16(parg16->f1,NULL)) + { + GlobalUnlock16(parg16->f1); + ul = parg16->f1; + } + + FREEARGPTR(parg16); + RETURN(ul); +} + +ULONG FASTCALL WG32SetMetaFileBits(PVDMFRAME pFrame) +{ + ULONG ul; + register PSETMETAFILEBITS16 parg16; + + GETARGPTR(pFrame, sizeof(SETMETAFILEBITS16), parg16); + + ul = parg16->f1; + + FREEARGPTR(parg16); + RETURN(ul); +} + +#endif |