Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/tools/winedump/emfspool.c
4388 views
1
/*
2
* Dump an EMF Spool File
3
*
4
* Copyright 2022 Piotr Caban 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
#include "winedump.h"
23
24
#define EMFSPOOL_VERSION 0x10000
25
26
typedef enum
27
{
28
EMRI_METAFILE = 1,
29
EMRI_ENGINE_FONT,
30
EMRI_DEVMODE,
31
EMRI_TYPE1_FONT,
32
EMRI_PRESTARTPAGE,
33
EMRI_DESIGNVECTOR,
34
EMRI_SUBSET_FONT,
35
EMRI_DELTA_FONT,
36
EMRI_FORM_METAFILE,
37
EMRI_BW_METAFILE,
38
EMRI_BW_FORM_METAFILE,
39
EMRI_METAFILE_DATA,
40
EMRI_METAFILE_EXT,
41
EMRI_BW_METAFILE_EXT,
42
EMRI_ENGINE_FONT_EXT,
43
EMRI_TYPE1_FONT_EXT,
44
EMRI_DESIGNVECTOR_EXT,
45
EMRI_SUBSET_FONT_EXT,
46
EMRI_DELTA_FONT_EXT,
47
EMRI_PS_JOB_DATA,
48
EMRI_EMBED_FONT_EXT,
49
} record_type;
50
51
typedef struct
52
{
53
unsigned int dwVersion;
54
unsigned int cjSize;
55
unsigned int dpszDocName;
56
unsigned int dpszOutput;
57
} header;
58
59
typedef struct
60
{
61
unsigned int ulID;
62
unsigned int cjSize;
63
} record_hdr;
64
65
static inline void print_longlong(ULONGLONG value)
66
{
67
if (sizeof(value) > sizeof(unsigned long) && value >> 32)
68
printf("0x%lx%08lx", (unsigned long)(value >> 32), (unsigned long)value);
69
else
70
printf("0x%lx", (unsigned long)value);
71
}
72
73
static const WCHAR* read_wstr(unsigned long off)
74
{
75
const WCHAR *beg, *end;
76
77
if (!off)
78
return NULL;
79
80
beg = end = PRD(off, sizeof(WCHAR));
81
off += sizeof(WCHAR);
82
if (!beg)
83
fatal("can't read Unicode string, corrupted file\n");
84
85
while (*end)
86
{
87
end = PRD(off, sizeof(WCHAR));
88
off += sizeof(WCHAR);
89
if (!end)
90
fatal("can't read Unicode string, corrupted file\n");
91
}
92
return beg;
93
}
94
95
#define EMRICASE(x) case x: printf("%-24s %08x\n", #x, hdr->cjSize); break
96
static unsigned long dump_emfspool_record(unsigned long off)
97
{
98
const record_hdr *hdr;
99
100
hdr = PRD(off, sizeof(*hdr));
101
if (!hdr)
102
return 0;
103
104
switch (hdr->ulID)
105
{
106
EMRICASE(EMRI_METAFILE);
107
EMRICASE(EMRI_ENGINE_FONT);
108
EMRICASE(EMRI_DEVMODE);
109
EMRICASE(EMRI_TYPE1_FONT);
110
EMRICASE(EMRI_PRESTARTPAGE);
111
EMRICASE(EMRI_DESIGNVECTOR);
112
EMRICASE(EMRI_SUBSET_FONT);
113
EMRICASE(EMRI_DELTA_FONT);
114
EMRICASE(EMRI_FORM_METAFILE);
115
EMRICASE(EMRI_BW_METAFILE);
116
EMRICASE(EMRI_BW_FORM_METAFILE);
117
EMRICASE(EMRI_METAFILE_DATA);
118
EMRICASE(EMRI_METAFILE_EXT);
119
EMRICASE(EMRI_BW_METAFILE_EXT);
120
EMRICASE(EMRI_ENGINE_FONT_EXT);
121
EMRICASE(EMRI_TYPE1_FONT_EXT);
122
EMRICASE(EMRI_DESIGNVECTOR_EXT);
123
EMRICASE(EMRI_SUBSET_FONT_EXT);
124
EMRICASE(EMRI_DELTA_FONT_EXT);
125
EMRICASE(EMRI_PS_JOB_DATA);
126
EMRICASE(EMRI_EMBED_FONT_EXT);
127
default:
128
printf("%u %08x\n", hdr->ulID, hdr->cjSize);
129
break;
130
}
131
132
switch (hdr->ulID)
133
{
134
case EMRI_METAFILE:
135
case EMRI_FORM_METAFILE:
136
case EMRI_BW_METAFILE:
137
case EMRI_BW_FORM_METAFILE:
138
case EMRI_METAFILE_DATA:
139
{
140
unsigned long emf_off = off + sizeof(*hdr);
141
while ((emf_off = dump_emfrecord(" ", emf_off)) && emf_off < off + sizeof(*hdr) + hdr->cjSize);
142
break;
143
}
144
145
case EMRI_METAFILE_EXT:
146
case EMRI_BW_METAFILE_EXT:
147
{
148
const ULONGLONG *emf_off = PRD(off + sizeof(*hdr), sizeof(*emf_off));
149
if (!emf_off)
150
fatal("truncated file\n");
151
printf(" %-20s ", "offset");
152
print_longlong(*emf_off);
153
printf(" (absolute position ");
154
print_longlong(off - *emf_off);
155
printf(")\n");
156
break;
157
}
158
159
default:
160
dump_data((const unsigned char *)(hdr + 1), hdr->cjSize, "");
161
break;
162
}
163
164
return off + sizeof(*hdr) + hdr->cjSize;
165
}
166
167
enum FileSig get_kind_emfspool(void)
168
{
169
const header *hdr;
170
171
hdr = PRD(0, sizeof(*hdr));
172
if (hdr && hdr->dwVersion == EMFSPOOL_VERSION)
173
return SIG_EMFSPOOL;
174
return SIG_UNKNOWN;
175
}
176
177
void emfspool_dump(void)
178
{
179
const WCHAR *doc_name, *output;
180
unsigned long off;
181
const header *hdr;
182
183
hdr = PRD(0, sizeof(*hdr));
184
if(!hdr)
185
return;
186
doc_name = read_wstr(hdr->dpszDocName);
187
output = read_wstr(hdr->dpszOutput);
188
189
printf("File Header\n");
190
printf(" %-20s %#x\n", "dwVersion:", hdr->dwVersion);
191
printf(" %-20s %#x\n", "cjSize:", hdr->cjSize);
192
printf(" %-20s %#x %s\n", "dpszDocName:", hdr->dpszDocName, get_unicode_str(doc_name, -1));
193
printf(" %-20s %#x %s\n", "dpszOutput:", hdr->dpszOutput, get_unicode_str(output, -1));
194
printf("\n");
195
196
off = hdr->cjSize;
197
while ((off = dump_emfspool_record(off)));
198
}
199
200