|
|
/******************************Module*Header*******************************\
* Module Name: meta.cxx * * This contains the code to create metafiles in the kernel * * Created: 26-Mar-1997 * Author: Andre Vachon [andreva] * * Copyright (c) 1992-1999 Microsoft Corporation \**************************************************************************/
#include "precomp.hxx"
#if DBG
LONG cSrvMetaFile = 0; LONG cMaxSrvMetaFile = 0; #endif
class META : public OBJECT { public: DWORD iType; // MFPICT_IDENTIFIER or MFEN_IDENTIFIER
DWORD mm; // used by MFPICT_IDENTIFIER only
DWORD xExt; // used by MFPICT_IDENTIFIER only
DWORD yExt; // used by MFPICT_IDENTIFIER only
ULONG cbData; // Number of bytes in abData[]
BYTE abData[1]; // Metafile bits
};
typedef META *PMETA;
/******************************Public*Routine******************************\
* NtGdiCreateServerMetaFile() * * History: * 26-Mar-1997 -by- Andre Vachon [andreva] * Wrote it. \**************************************************************************/
HANDLE APIENTRY NtGdiCreateServerMetaFile( DWORD iType, ULONG cjData, LPBYTE pjData, DWORD mm, DWORD xExt, DWORD yExt ) { PMETA pMeta; HANDLE hRet = NULL;
if ((iType != MFEN_IDENTIFIER) && (iType != MFPICT_IDENTIFIER)) { ASSERTGDI(FALSE, "GreCreateServerMetaFile: unknown type\n"); return NULL; }
if (pjData == NULL) { WARNING("GreCreateServerMetaFile: No metafile bits\n"); return NULL; }
if (cjData > (MAXULONG - sizeof(META))) { WARNING("GreCreateServerMetaFile: overflow\n"); return NULL; }
pMeta = (PMETA) HmgAlloc(cjData + sizeof(META), META_TYPE, HMGR_ALLOC_LOCK | HMGR_MAKE_PUBLIC);
if (pMeta) { hRet = pMeta->hGet();
pMeta->iType = iType; pMeta->mm = mm; pMeta->xExt = xExt; pMeta->yExt = yExt; pMeta->cbData = cjData;
if (cjData) { __try { //
// Probe and Read the structure
//
ProbeForRead(pjData, cjData, sizeof(DWORD));
RtlCopyMemory((PVOID) pMeta->abData, (PVOID) pjData, cjData);
#if DBG
InterlockedIncrement(&cSrvMetaFile); if (cMaxSrvMetaFile < cSrvMetaFile) { cMaxSrvMetaFile = cSrvMetaFile; }
if (cSrvMetaFile >= 100) { DbgPrint("GreCreateServerMetaFile: Number of server metafiles is %ld\n", cSrvMetaFile); } #endif
} __except(EXCEPTION_EXECUTE_HANDLER) { WARNINGX(14); hRet = 0; }
}
if (hRet == 0) { HmgFree((HOBJ) pMeta->hGet()); } else { DEC_EXCLUSIVE_REF_CNT(pMeta); } }
if (hRet == 0) { WARNING("NtGdiCreateServerMetaFile: unable to create metafile\n"); }
return (hRet); }
/******************************Public*Routine******************************\
* NtGdiGetServerMetaFileBits() * * History: * 26-Mar-1997 -by- Andre Vachon [andreva] * Wrote it. \**************************************************************************/
ULONG APIENTRY NtGdiGetServerMetaFileBits( HANDLE hmo, ULONG cjData, LPBYTE pjData, PDWORD piType, PDWORD pmm, PDWORD pxExt, PDWORD pyExt ) { ULONG ulRet = 0;
PMETA pMeta = (PMETA) HmgLock((HOBJ)hmo, META_TYPE);
if (pMeta) { if (pMeta->iType == MFPICT_IDENTIFIER || pMeta->iType == MFEN_IDENTIFIER) { //
// How much data is (or should be) returned.
//
ulRet = pMeta->cbData;
if (cjData) { if (cjData != pMeta->cbData) { ASSERTGDI(FALSE, "GreGetServerMetaFileBits: sizes do no match"); ulRet = 0; } else { __try { ProbeAndWriteUlong(pxExt,pMeta->xExt); ProbeAndWriteUlong(pyExt,pMeta->yExt); ProbeAndWriteUlong(piType,pMeta->iType); ProbeAndWriteUlong(pmm,pMeta->mm);
ProbeForWrite(pjData, cjData, sizeof(DWORD));
RtlCopyMemory(pjData, (PVOID) pMeta->abData, pMeta->cbData);
} __except(EXCEPTION_EXECUTE_HANDLER) { WARNINGX(20); ulRet = 0; } } } }
DEC_EXCLUSIVE_REF_CNT(pMeta); }
return (ulRet); }
/******************************Public*Routine******************************\
* GreDeleteServerMetaFile() * * History: * 26-Mar-1997 -by- Andre Vachon [andreva] * Wrote it. \**************************************************************************/
BOOL GreDeleteServerMetaFile( HANDLE hmo ) { PMETA pMeta = (PMETA) HmgLock((HOBJ)hmo, META_TYPE);
if (pMeta) { if (pMeta->iType == MFPICT_IDENTIFIER || pMeta->iType == MFEN_IDENTIFIER) { HmgFree((HOBJ) pMeta->hGet()); #if DBG
InterlockedDecrement(&cSrvMetaFile); if (cSrvMetaFile < 0) { ASSERTGDI(FALSE, "GreDeleteServerMetaFile: cSrvMetaFile < 0"); } #endif
return TRUE; } else { DEC_EXCLUSIVE_REF_CNT(pMeta); } }
WARNING("GreDeleteServerMetaFile: bad metafile handle");
return FALSE; }
|