Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/tools/winedump/mf.c
4389 views
1
/*
2
* Dump a Windows Metafile
3
*
4
* Copyright 2021 Zhiyi Zhang for CodeWeavers
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include "config.h"
22
23
#include "winedump.h"
24
#include "windef.h"
25
#include "winbase.h"
26
#include "wingdi.h"
27
28
#define META_EOF 0
29
#define METAFILE_MEMORY 1
30
#define METAFILE_DISK 2
31
32
static unsigned offset = 0;
33
34
static unsigned short read_word(const unsigned char *buffer)
35
{
36
return buffer[0] + (buffer[1] << 8);
37
}
38
39
static unsigned int read_int(const unsigned char *buffer)
40
{
41
return buffer[0] + (buffer[1] << 8) + (buffer[2] << 16) + (buffer[3] << 24);
42
}
43
44
static int dump_mfrecord(void)
45
{
46
unsigned int type, size, i;
47
const unsigned char *ptr;
48
49
ptr = PRD(offset, 6);
50
if (!ptr)
51
return -1;
52
53
/* METAHEADER */
54
if (offset == 0)
55
{
56
type = read_word(ptr);
57
/* mtHeaderSize is in words */
58
size = read_word(ptr + 2) * 2;
59
}
60
/* METARECORD */
61
else
62
{
63
/* rdSize is in words */
64
size = read_int(ptr) * 2;
65
type = read_word(ptr + 4);
66
}
67
68
#define MRCASE(x) \
69
case x: \
70
printf("%-20s %08x\n", #x, size); \
71
break
72
73
switch (type)
74
{
75
case METAFILE_MEMORY:
76
case METAFILE_DISK:
77
{
78
const METAHEADER *header = PRD(offset, sizeof(*header));
79
80
printf("%-20s %08x\n", "METAHEADER", size);
81
printf("type %d header_size %#x version %#x size %#x object_count %d max_record_size %#x "
82
"parameter_count %d\n",
83
header->mtType, header->mtHeaderSize * 2, header->mtVersion, (UINT)header->mtSize * 2,
84
header->mtNoObjects, (UINT)header->mtMaxRecord * 2, header->mtNoParameters);
85
break;
86
}
87
MRCASE(META_SETBKCOLOR);
88
MRCASE(META_SETBKMODE);
89
MRCASE(META_SETMAPMODE);
90
MRCASE(META_SETROP2);
91
MRCASE(META_SETRELABS);
92
MRCASE(META_SETPOLYFILLMODE);
93
MRCASE(META_SETSTRETCHBLTMODE);
94
MRCASE(META_SETTEXTCHAREXTRA);
95
MRCASE(META_SETTEXTCOLOR);
96
MRCASE(META_SETTEXTJUSTIFICATION);
97
MRCASE(META_SETWINDOWORG);
98
MRCASE(META_SETWINDOWEXT);
99
MRCASE(META_SETVIEWPORTORG);
100
MRCASE(META_SETVIEWPORTEXT);
101
MRCASE(META_OFFSETWINDOWORG);
102
MRCASE(META_SCALEWINDOWEXT);
103
MRCASE(META_OFFSETVIEWPORTORG);
104
MRCASE(META_SCALEVIEWPORTEXT);
105
MRCASE(META_LINETO);
106
MRCASE(META_MOVETO);
107
MRCASE(META_EXCLUDECLIPRECT);
108
MRCASE(META_INTERSECTCLIPRECT);
109
MRCASE(META_ARC);
110
MRCASE(META_ELLIPSE);
111
MRCASE(META_FLOODFILL);
112
MRCASE(META_PIE);
113
MRCASE(META_RECTANGLE);
114
MRCASE(META_ROUNDRECT);
115
MRCASE(META_PATBLT);
116
MRCASE(META_SAVEDC);
117
MRCASE(META_SETPIXEL);
118
MRCASE(META_OFFSETCLIPRGN);
119
MRCASE(META_TEXTOUT);
120
MRCASE(META_BITBLT);
121
MRCASE(META_STRETCHBLT);
122
MRCASE(META_POLYGON);
123
MRCASE(META_POLYLINE);
124
MRCASE(META_ESCAPE);
125
MRCASE(META_RESTOREDC);
126
MRCASE(META_FILLREGION);
127
MRCASE(META_FRAMEREGION);
128
MRCASE(META_INVERTREGION);
129
MRCASE(META_PAINTREGION);
130
MRCASE(META_SELECTCLIPREGION);
131
MRCASE(META_SELECTOBJECT);
132
MRCASE(META_SETTEXTALIGN);
133
MRCASE(META_DRAWTEXT);
134
MRCASE(META_CHORD);
135
MRCASE(META_SETMAPPERFLAGS);
136
MRCASE(META_EXTTEXTOUT);
137
MRCASE(META_SETDIBTODEV);
138
MRCASE(META_SELECTPALETTE);
139
MRCASE(META_REALIZEPALETTE);
140
MRCASE(META_ANIMATEPALETTE);
141
MRCASE(META_SETPALENTRIES);
142
MRCASE(META_POLYPOLYGON);
143
MRCASE(META_RESIZEPALETTE);
144
MRCASE(META_DIBBITBLT);
145
MRCASE(META_DIBSTRETCHBLT);
146
MRCASE(META_DIBCREATEPATTERNBRUSH);
147
MRCASE(META_STRETCHDIB);
148
MRCASE(META_EXTFLOODFILL);
149
MRCASE(META_RESETDC);
150
MRCASE(META_STARTDOC);
151
MRCASE(META_STARTPAGE);
152
MRCASE(META_ENDPAGE);
153
MRCASE(META_ABORTDOC);
154
MRCASE(META_ENDDOC);
155
MRCASE(META_SETLAYOUT);
156
MRCASE(META_DELETEOBJECT);
157
MRCASE(META_CREATEPALETTE);
158
MRCASE(META_CREATEBRUSH);
159
MRCASE(META_CREATEPATTERNBRUSH);
160
MRCASE(META_CREATEPENINDIRECT);
161
MRCASE(META_CREATEFONTINDIRECT);
162
MRCASE(META_CREATEBRUSHINDIRECT);
163
MRCASE(META_CREATEBITMAPINDIRECT);
164
MRCASE(META_CREATEBITMAP);
165
MRCASE(META_CREATEREGION);
166
MRCASE(META_UNKNOWN);
167
MRCASE(META_EOF);
168
169
default:
170
printf("%u %08x\n", type, size);
171
break;
172
}
173
174
#undef MRCASE
175
176
if ((size < 6) || (size % 2))
177
return -1;
178
179
/* METARECORD */
180
if (offset)
181
{
182
size -= 6;
183
offset += 6;
184
}
185
186
for (i = 0; i < size; i += 2)
187
{
188
if (i % 16 == 0)
189
printf(" ");
190
if (!(ptr = PRD(offset, 2)))
191
return -1;
192
offset += 2;
193
printf("%04x ", read_word(ptr));
194
if ((i % 16 == 14) || (i + 2 == size))
195
printf("\n");
196
}
197
198
return 0;
199
}
200
201
enum FileSig get_kind_mf(void)
202
{
203
const METAHEADER *hdr;
204
205
hdr = PRD(0, sizeof(*hdr));
206
if (hdr && (hdr->mtType == METAFILE_MEMORY || hdr->mtType == METAFILE_DISK)
207
&& hdr->mtHeaderSize == sizeof(METAHEADER) / sizeof(WORD)
208
&& (hdr->mtVersion == 0x0100 || hdr->mtVersion == 0x0300))
209
return SIG_MF;
210
return SIG_UNKNOWN;
211
}
212
213
void mf_dump(void)
214
{
215
offset = 0;
216
while (!dump_mfrecord())
217
;
218
}
219
220