Zhiyi Zhang : winedump: Support dumping Windows Metafiles.
Alexandre Julliard
julliard at winehq.org
Tue Apr 20 16:27:47 CDT 2021
Module: wine
Branch: master
Commit: 788fd4ee44fc9877b01888fdd3cd72b9ac88228e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=788fd4ee44fc9877b01888fdd3cd72b9ac88228e
Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date: Mon Apr 19 15:17:48 2021 +0800
winedump: Support dumping Windows Metafiles.
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
tools/winedump/Makefile.in | 1 +
tools/winedump/dump.c | 1 +
tools/winedump/mf.c | 219 +++++++++++++++++++++++++++++++++++++++++++++
tools/winedump/winedump.h | 4 +-
4 files changed, 224 insertions(+), 1 deletion(-)
diff --git a/tools/winedump/Makefile.in b/tools/winedump/Makefile.in
index 43e200ab6ed..54028024b0d 100644
--- a/tools/winedump/Makefile.in
+++ b/tools/winedump/Makefile.in
@@ -12,6 +12,7 @@ C_SRCS = \
lib.c \
lnk.c \
main.c \
+ mf.c \
minidump.c \
misc.c \
msc.c \
diff --git a/tools/winedump/dump.c b/tools/winedump/dump.c
index 412880c4bd6..d2e920ef6cb 100644
--- a/tools/winedump/dump.c
+++ b/tools/winedump/dump.c
@@ -265,6 +265,7 @@ dumpers[] =
{SIG_MDMP, get_kind_mdmp, mdmp_dump},
{SIG_LNK, get_kind_lnk, lnk_dump},
{SIG_EMF, get_kind_emf, emf_dump},
+ {SIG_MF, get_kind_mf, mf_dump},
{SIG_FNT, get_kind_fnt, fnt_dump},
{SIG_TLB, get_kind_tlb, tlb_dump},
{SIG_NLS, get_kind_nls, nls_dump},
diff --git a/tools/winedump/mf.c b/tools/winedump/mf.c
new file mode 100644
index 00000000000..37869d3bb8a
--- /dev/null
+++ b/tools/winedump/mf.c
@@ -0,0 +1,219 @@
+/*
+ * Dump a Windows Metafile
+ *
+ * Copyright 2021 Zhiyi Zhang for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include "winedump.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+
+#define META_EOF 0
+#define METAFILE_MEMORY 1
+#define METAFILE_DISK 2
+
+static unsigned offset = 0;
+
+static unsigned short read_word(const unsigned char *buffer)
+{
+ return buffer[0] + (buffer[1] << 8);
+}
+
+static unsigned int read_int(const unsigned char *buffer)
+{
+ return buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24);
+}
+
+static int dump_mfrecord(void)
+{
+ unsigned int type, size, i;
+ const unsigned char *ptr;
+
+ ptr = PRD(offset, 6);
+ if (!ptr)
+ return -1;
+
+ /* METAHEADER */
+ if (offset == 0)
+ {
+ type = read_word(ptr);
+ /* mtHeaderSize is in words */
+ size = read_word(ptr + 2) * 2;
+ }
+ /* METARECORD */
+ else
+ {
+ /* rdSize is in words */
+ size = read_int(ptr) * 2;
+ type = read_word(ptr + 4);
+ }
+
+#define MRCASE(x) \
+ case x: \
+ printf("%-20s %08x\n", #x, size); \
+ break
+
+ switch (type)
+ {
+ case METAFILE_MEMORY:
+ case METAFILE_DISK:
+ {
+ const METAHEADER *header = PRD(offset, sizeof(*header));
+
+ printf("%-20s %08x\n", "METAHEADER", size);
+ printf("type %d header_size %#x version %#x size %#x object_count %d max_record_size %#x "
+ "parameter_count %d\n",
+ header->mtType, header->mtHeaderSize * 2, header->mtVersion, header->mtSize * 2,
+ header->mtNoObjects, header->mtMaxRecord * 2, header->mtNoParameters);
+ break;
+ }
+ MRCASE(META_SETBKCOLOR);
+ MRCASE(META_SETBKMODE);
+ MRCASE(META_SETMAPMODE);
+ MRCASE(META_SETROP2);
+ MRCASE(META_SETRELABS);
+ MRCASE(META_SETPOLYFILLMODE);
+ MRCASE(META_SETSTRETCHBLTMODE);
+ MRCASE(META_SETTEXTCHAREXTRA);
+ MRCASE(META_SETTEXTCOLOR);
+ MRCASE(META_SETTEXTJUSTIFICATION);
+ MRCASE(META_SETWINDOWORG);
+ MRCASE(META_SETWINDOWEXT);
+ MRCASE(META_SETVIEWPORTORG);
+ MRCASE(META_SETVIEWPORTEXT);
+ MRCASE(META_OFFSETWINDOWORG);
+ MRCASE(META_SCALEWINDOWEXT);
+ MRCASE(META_OFFSETVIEWPORTORG);
+ MRCASE(META_SCALEVIEWPORTEXT);
+ MRCASE(META_LINETO);
+ MRCASE(META_MOVETO);
+ MRCASE(META_EXCLUDECLIPRECT);
+ MRCASE(META_INTERSECTCLIPRECT);
+ MRCASE(META_ARC);
+ MRCASE(META_ELLIPSE);
+ MRCASE(META_FLOODFILL);
+ MRCASE(META_PIE);
+ MRCASE(META_RECTANGLE);
+ MRCASE(META_ROUNDRECT);
+ MRCASE(META_PATBLT);
+ MRCASE(META_SAVEDC);
+ MRCASE(META_SETPIXEL);
+ MRCASE(META_OFFSETCLIPRGN);
+ MRCASE(META_TEXTOUT);
+ MRCASE(META_BITBLT);
+ MRCASE(META_STRETCHBLT);
+ MRCASE(META_POLYGON);
+ MRCASE(META_POLYLINE);
+ MRCASE(META_ESCAPE);
+ MRCASE(META_RESTOREDC);
+ MRCASE(META_FILLREGION);
+ MRCASE(META_FRAMEREGION);
+ MRCASE(META_INVERTREGION);
+ MRCASE(META_PAINTREGION);
+ MRCASE(META_SELECTCLIPREGION);
+ MRCASE(META_SELECTOBJECT);
+ MRCASE(META_SETTEXTALIGN);
+ MRCASE(META_DRAWTEXT);
+ MRCASE(META_CHORD);
+ MRCASE(META_SETMAPPERFLAGS);
+ MRCASE(META_EXTTEXTOUT);
+ MRCASE(META_SETDIBTODEV);
+ MRCASE(META_SELECTPALETTE);
+ MRCASE(META_REALIZEPALETTE);
+ MRCASE(META_ANIMATEPALETTE);
+ MRCASE(META_SETPALENTRIES);
+ MRCASE(META_POLYPOLYGON);
+ MRCASE(META_RESIZEPALETTE);
+ MRCASE(META_DIBBITBLT);
+ MRCASE(META_DIBSTRETCHBLT);
+ MRCASE(META_DIBCREATEPATTERNBRUSH);
+ MRCASE(META_STRETCHDIB);
+ MRCASE(META_EXTFLOODFILL);
+ MRCASE(META_RESETDC);
+ MRCASE(META_STARTDOC);
+ MRCASE(META_STARTPAGE);
+ MRCASE(META_ENDPAGE);
+ MRCASE(META_ABORTDOC);
+ MRCASE(META_ENDDOC);
+ MRCASE(META_SETLAYOUT);
+ MRCASE(META_DELETEOBJECT);
+ MRCASE(META_CREATEPALETTE);
+ MRCASE(META_CREATEBRUSH);
+ MRCASE(META_CREATEPATTERNBRUSH);
+ MRCASE(META_CREATEPENINDIRECT);
+ MRCASE(META_CREATEFONTINDIRECT);
+ MRCASE(META_CREATEBRUSHINDIRECT);
+ MRCASE(META_CREATEBITMAPINDIRECT);
+ MRCASE(META_CREATEBITMAP);
+ MRCASE(META_CREATEREGION);
+ MRCASE(META_UNKNOWN);
+ MRCASE(META_EOF);
+
+ default:
+ printf("%u %08x\n", type, size);
+ break;
+ }
+
+#undef MRCASE
+
+ if ((size < 6) || (size % 2))
+ return -1;
+
+ /* METARECORD */
+ if (offset)
+ {
+ size -= 6;
+ offset += 6;
+ }
+
+ for (i = 0; i < size; i += 2)
+ {
+ if (i % 16 == 0)
+ printf(" ");
+ if (!(ptr = PRD(offset, 2)))
+ return -1;
+ offset += 2;
+ printf("%04x ", read_word(ptr));
+ if ((i % 16 == 14) || (i + 2 == size))
+ printf("\n");
+ }
+
+ return 0;
+}
+
+enum FileSig get_kind_mf(void)
+{
+ const METAHEADER *hdr;
+
+ hdr = PRD(0, sizeof(*hdr));
+ if (hdr && (hdr->mtType == METAFILE_MEMORY || hdr->mtType == METAFILE_DISK)
+ && hdr->mtHeaderSize == sizeof(METAHEADER) / sizeof(WORD)
+ && (hdr->mtVersion == 0x0100 || hdr->mtVersion == 0x0300))
+ return SIG_MF;
+ return SIG_UNKNOWN;
+}
+
+void mf_dump(void)
+{
+ offset = 0;
+ while (!dump_mfrecord())
+ ;
+}
diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h
index 240f31d2f2d..16b9cdc7cf8 100644
--- a/tools/winedump/winedump.h
+++ b/tools/winedump/winedump.h
@@ -216,7 +216,7 @@ const char *get_machine_str(int mach);
/* file dumping functions */
enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_PDB, SIG_NE, SIG_LE, SIG_MDMP, SIG_COFFLIB, SIG_LNK,
- SIG_EMF, SIG_FNT, SIG_TLB, SIG_NLS};
+ SIG_EMF, SIG_MF, SIG_FNT, SIG_TLB, SIG_NLS};
const void* PRD(unsigned long prd, unsigned long len);
unsigned long Offset(const void* ptr);
@@ -251,6 +251,8 @@ enum FileSig get_kind_lnk(void);
void lnk_dump( void );
enum FileSig get_kind_emf(void);
void emf_dump( void );
+enum FileSig get_kind_mf(void);
+void mf_dump(void);
enum FileSig get_kind_pdb(void);
void pdb_dump(void);
enum FileSig get_kind_fnt(void);
More information about the wine-cvs
mailing list