https://git.reactos.org/?p=reactos.git;a=commitdiff;h=268b21c2f919baf5d0318…
commit 268b21c2f919baf5d0318bdb02d796532e653439
Author: jimtabor <james.tabor(a)reactos.org>
AuthorDate: Thu May 30 16:36:33 2019 -0500
Commit: jimtabor <james.tabor(a)reactos.org>
CommitDate: Thu May 30 16:36:33 2019 -0500
[NtGDI] Support Clipboard Metafile
Fuctions that help transfer meta file data from one process to the next.
See CORE-12143.
---
win32ss/gdi/ntgdi/metafile.c | 178 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 149 insertions(+), 29 deletions(-)
diff --git a/win32ss/gdi/ntgdi/metafile.c b/win32ss/gdi/ntgdi/metafile.c
index 4bdf574583..63d5a241d6 100644
--- a/win32ss/gdi/ntgdi/metafile.c
+++ b/win32ss/gdi/ntgdi/metafile.c
@@ -2,7 +2,7 @@
* PROJECT: ReactOS Win32k Subsystem
* LICENSE: GPL - See COPYING in the top level directory
* FILE: win32ss/gdi/ntgdi/metafile.c
- * PURPOSE: Metafile Implementation
+ * PURPOSE: Metafile Implementations, Metafile Clipboard Data Xfers
* PROGRAMMERS: ...
*/
@@ -13,20 +13,37 @@
#define NDEBUG
#include <debug.h>
-/* System Service Calls ******************************************************/
+// Need to move this to NtGdiTyp.h
+#define GDITAG_TYPE_EMF 'XEFM' // EnhMetaFile
+#define GDITAG_TYPE_MFP '_PFM' // MetaFile Picture
-/*
- * @unimplemented
- */
-LONG
-APIENTRY
-NtGdiConvertMetafileRect(IN HDC hDC,
- IN OUT PRECTL pRect)
+// Internal Use
+typedef struct _METATYPEOBJ
{
- UNIMPLEMENTED;
- return 0;
+ BASEOBJECT BaseObject;
+ DWORD iType;
+ DWORD mm;
+ DWORD xExt;
+ DWORD yExt;
+ ULONG cjData;
+ PBYTE pjData[4];
+} METATYPEOBJ, *PMETATYPEOBJ;
+
+
+//
+// Plug Me in Somewhere? Clipboard cleanup?
+//
+VOID
+FASTCALL
+METATYPEOBJ__vCleanup(PVOID ObjectBody)
+{
+ PMETATYPEOBJ pmto = (PMETATYPEOBJ)ObjectBody;
+ GDIOBJ_hInsertObject(&pmto->BaseObject, GDI_OBJ_HMGR_POWNED);
+ GDIOBJ_vDeleteObject(&pmto->BaseObject);
}
+/* System Service Calls ******************************************************/
+
/*
* @implemented
*/
@@ -34,38 +51,141 @@ HDC
APIENTRY
NtGdiCreateMetafileDC(IN HDC hdc)
{
- /* Call the internal function to create an alternative info DC */
- return GreCreateCompatibleDC(hdc, TRUE);
+ //if (hdc)
+ /* Call the internal function to create an alternative info DC */
+ return GreCreateCompatibleDC(hdc, TRUE);
+ // No HDC call NtUser.
+ //return UserGetDesktopDC(DCTYPE_INFO, TRUE, FALSE);
}
/*
- * @unimplemented
+ * @implemented
*/
HANDLE
APIENTRY
-NtGdiCreateServerMetaFile(IN DWORD iType,
- IN ULONG cjData,
- IN PBYTE pjData,
- IN DWORD mm,
- IN DWORD xExt,
- IN DWORD yExt)
+NtGdiCreateServerMetaFile(
+ IN DWORD iType,
+ IN ULONG cjData,
+ IN PBYTE pjData,
+ IN DWORD mm,
+ IN DWORD xExt,
+ IN DWORD yExt
+)
{
- UNIMPLEMENTED;
+ BOOL Pass = TRUE;
+ PMETATYPEOBJ pmto;
+
+ if ( ( iType == GDITAG_TYPE_EMF || iType == GDITAG_TYPE_MFP ) &&
+ cjData &&
+ pjData )
+ {
+ pmto = (PMETATYPEOBJ)GDIOBJ_AllocObjWithHandle(GDIObjType_META_TYPE,
sizeof(METATYPEOBJ) + cjData);
+ if ( pmto )
+ {
+ pmto->iType = iType;
+ pmto->mm = mm;
+ pmto->xExt = xExt;
+ pmto->yExt = yExt;
+ pmto->cjData = cjData;
+
+ _SEH2_TRY
+ {
+ ProbeForRead( pjData, cjData, 1 );
+ RtlCopyMemory( pmto->pjData, pjData, cjData) ;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Pass = FALSE;
+ }
+ _SEH2_END;
+
+ if (Pass)
+ {
+ GDIOBJ_vSetObjectOwner(&pmto->BaseObject, GDI_OBJ_HMGR_PUBLIC);
+ GDIOBJ_vDereferenceObject ((POBJ)pmto);
+ return pmto->BaseObject.hHmgr;
+ }
+ else
+ {
+ GDIOBJ_vDeleteObject(&pmto->BaseObject);
+ }
+ }
+ }
return NULL;
}
/*
- * @unimplemented
+ * @implemented
*/
ULONG
APIENTRY
-NtGdiGetServerMetaFileBits(IN HANDLE hmo,
- IN ULONG cjData,
- OUT OPTIONAL PBYTE pjData,
- OUT PDWORD piType,
- OUT PDWORD pmm,
- OUT PDWORD pxExt,
- OUT PDWORD pyExt)
+NtGdiGetServerMetaFileBits(
+ IN HANDLE hmo,
+ IN ULONG cjData,
+ OUT OPTIONAL PBYTE pjData,
+ OUT PDWORD piType,
+ OUT PDWORD pmm,
+ OUT PDWORD pxExt,
+ OUT PDWORD pyExt
+)
+{
+ ULONG cjRet = 0;
+ PMETATYPEOBJ pmto;
+
+ pmto = (PMETATYPEOBJ) GDIOBJ_ShareLockObj ((HGDIOBJ) hmo, GDIObjType_META_TYPE);
+
+ if (!pmto)
+ return 0;
+
+ if ( pmto->iType == GDITAG_TYPE_EMF || pmto->iType == GDITAG_TYPE_MFP )
+ {
+ cjRet = pmto->cjData;
+
+ if ( cjData )
+ {
+ if (cjData == pmto->cjData)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite( piType, sizeof(DWORD), 1);
+ *piType = pmto->iType;
+
+ ProbeForWrite( pmm, sizeof(DWORD), 1);
+ *pmm = pmto->mm;
+
+ ProbeForWrite( pxExt, sizeof(DWORD), 1);
+ *pxExt = pmto->xExt;
+
+ ProbeForWrite( pyExt, sizeof(DWORD), 1);
+ *pyExt = pmto->yExt;
+
+ ProbeForWrite( pjData, cjData, 1 );
+ RtlCopyMemory( pjData, pmto->pjData, cjData) ;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ cjRet = 0;
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ cjRet = 0;
+ }
+ }
+ }
+
+ GDIOBJ_vDereferenceObject ((POBJ)pmto);
+ return cjRet;
+}
+
+/*
+ * @unimplemented
+ */
+LONG
+APIENTRY
+NtGdiConvertMetafileRect(IN HDC hDC,
+ IN OUT PRECTL pRect)
{
UNIMPLEMENTED;
return 0;