123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- /*
- * 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 "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())
- ;
- }
|