TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / tools / winedump / tlb.c
blobdf1ea4b57631be6d10282c202fa36f918a31fba9
1 /*
2 * Dump a typelib (tlb) file
4 * Copyright 2006 Jacek Caban
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.
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.
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
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
28 #include "windef.h"
30 #include "winedump.h"
32 #define MSFT_MAGIC 0x5446534d
33 #define HELPDLLFLAG 0x0100
35 enum TYPEKIND {
36 TKIND_ENUM = 0,
37 TKIND_RECORD,
38 TKIND_MODULE,
39 TKIND_INTERFACE,
40 TKIND_DISPATCH,
41 TKIND_COCLASS,
42 TKIND_ALIAS,
43 TKIND_UNION,
44 TKIND_MAX
47 enum VARENUM {
48 VT_EMPTY = 0,
49 VT_NULL = 1,
50 VT_I2 = 2,
51 VT_I4 = 3,
52 VT_R4 = 4,
53 VT_R8 = 5,
54 VT_CY = 6,
55 VT_DATE = 7,
56 VT_BSTR = 8,
57 VT_DISPATCH = 9,
58 VT_ERROR = 10,
59 VT_BOOL = 11,
60 VT_VARIANT = 12,
61 VT_UNKNOWN = 13,
62 VT_DECIMAL = 14,
63 VT_I1 = 16,
64 VT_UI1 = 17,
65 VT_UI2 = 18,
66 VT_UI4 = 19,
67 VT_I8 = 20,
68 VT_UI8 = 21,
69 VT_INT = 22,
70 VT_UINT = 23,
71 VT_VOID = 24,
72 VT_HRESULT = 25,
73 VT_PTR = 26,
74 VT_SAFEARRAY = 27,
75 VT_CARRAY = 28,
76 VT_USERDEFINED = 29,
77 VT_LPSTR = 30,
78 VT_LPWSTR = 31,
79 VT_RECORD = 36,
80 VT_INT_PTR = 37,
81 VT_UINT_PTR = 38,
82 VT_FILETIME = 64,
83 VT_BLOB = 65,
84 VT_STREAM = 66,
85 VT_STORAGE = 67,
86 VT_STREAMED_OBJECT = 68,
87 VT_STORED_OBJECT = 69,
88 VT_BLOB_OBJECT = 70,
89 VT_CF = 71,
90 VT_CLSID = 72,
91 VT_VERSIONED_STREAM = 73,
92 VT_BSTR_BLOB = 0xfff,
93 VT_VECTOR = 0x1000,
94 VT_ARRAY = 0x2000,
95 VT_BYREF = 0x4000,
96 VT_RESERVED = 0x8000,
97 VT_ILLEGAL = 0xffff,
98 VT_ILLEGALMASKED = 0xfff,
99 VT_TYPEMASK = 0xfff
102 struct seg_t;
104 typedef BOOL (*dump_seg_t)(struct seg_t*);
106 typedef struct seg_t {
107 const char *name;
108 dump_seg_t func;
109 int offset;
110 int length;
111 } seg_t;
112 static seg_t segdir[];
114 enum SEGDIRTYPE {
115 SEGDIR_TYPEINFO,
116 SEGDIR_IMPINFO,
117 SEGDIR_IMPFILES,
118 SEGDIR_REF,
119 SEGDIR_GUIDHASH,
120 SEGDIR_GUID,
121 SEGDIR_NAMEHASH,
122 SEGDIR_NAME,
123 SEGDIR_STRING,
124 SEGDIR_TYPEDESC,
125 SEGDIR_ARRAYDESC,
126 SEGDIR_CUSTDATA,
127 SEGDIR_CDGUID,
128 SEGDIR_res0e,
129 SEGDIR_res0f
132 static int offset=0;
133 static int indent;
134 static int typeinfo_cnt;
135 static int header_flags = 0;
136 static BOOL msft_eof = FALSE;
138 static int msft_typeinfo_offs[1000];
139 static int msft_typeinfo_kind[1000];
140 static int msft_typeinfo_impltypes[1000];
141 static int msft_typeinfo_elemcnt[1000];
142 static int msft_typeinfo_cnt = 0;
144 static const void *tlb_read(int size) {
145 const void *ret = PRD(offset, size);
147 if(ret)
148 offset += size;
149 else
150 msft_eof = TRUE;
152 return ret;
155 static int tlb_read_int(void)
157 const int *ret = tlb_read(sizeof(int));
158 return ret ? *ret : -1;
161 static int tlb_read_short(void)
163 const short *ret = tlb_read(sizeof(short));
164 return ret ? *ret : -1;
167 static int tlb_read_byte(void)
169 const unsigned char *ret = tlb_read(sizeof(char));
170 return ret ? *ret : -1;
173 static void print_offset(void)
175 int i;
177 printf("%04x: ", offset);
179 for(i=0; i<indent; i++)
180 printf(" ");
183 static void print_begin_block(const char *name)
185 print_offset();
186 printf("%s {\n", name);
187 indent++;
190 static void print_begin_block_id(const char *name, int id)
192 char buf[64];
193 sprintf(buf, "%s %d", name, id);
194 print_begin_block(buf);
197 static void print_end_block(void)
199 indent--;
200 print_offset();
201 printf("}\n");
202 print_offset();
203 printf("\n");
206 static int print_hex(const char *name)
208 int ret;
209 print_offset();
210 printf("%s = %08x\n", name, ret=tlb_read_int());
211 return ret;
214 static int print_hex_id(const char *name, int id)
216 char buf[64];
217 sprintf(buf, name, id);
218 return print_hex(buf);
221 static int print_short_hex(const char *name)
223 int ret;
224 print_offset();
225 printf("%s = %xh\n", name, ret=tlb_read_short());
226 return ret;
229 static int print_dec(const char *name)
231 int ret;
232 print_offset();
233 printf("%s = %d\n", name, ret=tlb_read_int());
234 return ret;
237 static void print_guid(const char *name)
239 GUID guid = *(const GUID*)tlb_read(sizeof(guid));
241 print_offset();
243 printf("%s = {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", name,
244 guid.Data1, guid.Data2, guid.Data3, guid.Data4[0],
245 guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4],
246 guid.Data4[5], guid.Data4[6], guid.Data4[7]);
249 static void print_vartype(int vartype)
251 static const char *vartypes[VT_LPWSTR+1] = {
252 "VT_EMPTY", "VT_NULL", "VT_I2", "VT_I4", "VT_R4",
253 "VT_R8", "VT_CY", "VT_DATE", "VT_BSTR", "VT_DISPATCH",
254 "VT_ERROR", "VT_BOOL", "VT_VARIANT", "VT_UNKNOWN","VT_DECIMAL",
255 "unk 15", "VT_I1", "VT_UI1", "VT_UI2", "VT_UI4",
256 "VT_I8", "VT_UI8", "VT_INT", "VT_UINT", "VT_VOID",
257 "VT_HRESULT", "VT_PTR", "VT_SAFEARRAY","VT_CARRAY", "VT_USERDEFINED",
258 "VT_LPSTR", "VT_LPWSTR"
261 vartype &= VT_TYPEMASK;
262 if (vartype >= VT_EMPTY && vartype <= VT_LPWSTR)
263 printf("%s\n", vartypes[vartype]);
264 else
265 printf("unk %d\n", vartype);
268 static void print_ctl2(const char *name)
270 int len;
271 const char *buf;
273 print_offset();
275 len = tlb_read_short();
277 printf("%s = %d \"", name, len);
278 len >>= 2;
279 buf = tlb_read(len);
280 fwrite(buf, len, 1, stdout);
281 printf("\"");
282 len += 2;
284 while(len++ & 3)
285 printf("\\%02x", tlb_read_byte());
286 printf("\n");
289 static void dump_binary(int n)
291 int i;
293 for(i = 1; i <= n; i++) {
294 switch(i & 0x0f) {
295 case 0:
296 printf("%02x\n", tlb_read_byte());
297 break;
298 case 1:
299 print_offset();
300 /* fall through */
301 default:
302 printf("%02x ", tlb_read_byte());
306 if(n&0x0f)
307 printf("\n");
310 static int dump_msft_varflags(void)
312 static const char *syskind[] = {
313 "SYS_WIN16", "SYS_WIN32", "SYS_MAC", "SYS_WIN64", "unknown"
315 int kind, flags;
317 print_offset();
318 flags = tlb_read_int();
319 kind = flags & 0xf;
320 if (kind > 3) kind = 4;
321 printf("varflags = %08x, syskind = %s\n", flags, syskind[kind]);
322 return flags;
325 static void dump_msft_version(void)
327 int version;
328 print_offset();
329 version = tlb_read_int();
330 printf("version = %d.%d\n", version & 0xff, version >> 16);
333 static void dump_msft_header(void)
335 print_begin_block("Header");
337 print_hex("magic1");
338 print_hex("magic2");
339 print_hex("posguid");
340 print_hex("lcid");
341 print_hex("lcid2");
342 header_flags = dump_msft_varflags();
343 dump_msft_version();
344 print_hex("flags");
345 typeinfo_cnt = print_dec("ntypeinfos");
346 print_dec("helpstring");
347 print_dec("helpstringcontext");
348 print_dec("helpcontext");
349 print_dec("nametablecount");
350 print_dec("nametablechars");
351 print_hex("NameOffset");
352 print_hex("helpfile");
353 print_hex("CustomDataOffset");
354 print_hex("res44");
355 print_hex("res48");
356 print_hex("dispatchpos");
357 print_hex("res50");
359 print_end_block();
362 static int dump_msft_typekind(void)
364 static const char *tkind[TKIND_MAX] = {
365 "TKIND_ENUM", "TKIND_RECORD", "TKIND_MODULE",
366 "TKIND_INTERFACE", "TKIND_DISPATCH", "TKIND_COCLASS",
367 "TKIND_ALIAS", "TKIND_UNION"
369 int ret, typekind;
371 print_offset();
372 ret = tlb_read_int();
373 typekind = ret & 0xf;
374 printf("typekind = %s, align = %d\n", typekind < TKIND_MAX ? tkind[typekind] : "unknown", (ret >> 11) & 0x1f);
375 return ret;
378 static void dump_msft_typeinfobase(void)
380 print_begin_block_id("TypeInfoBase", msft_typeinfo_cnt);
382 msft_typeinfo_kind[msft_typeinfo_cnt] = dump_msft_typekind();
383 msft_typeinfo_offs[msft_typeinfo_cnt] = print_hex("memoffset");
384 print_hex("res2");
385 print_hex("res3");
386 print_hex("res4");
387 print_hex("res5");
388 msft_typeinfo_elemcnt[msft_typeinfo_cnt] = print_hex("cElement");
389 print_hex("res7");
390 print_hex("res8");
391 print_hex("res9");
392 print_hex("resA");
393 print_hex("posguid");
394 print_hex("flags");
395 print_hex("NameOffset");
396 print_hex("version");
397 print_hex("docstringoffs");
398 print_hex("docstringcontext");
399 print_hex("helpcontext");
400 print_hex("oCustData");
401 msft_typeinfo_impltypes[msft_typeinfo_cnt++] = print_short_hex("cImplTypes");
402 print_short_hex("bSizeVftt");
403 print_dec("size");
404 print_hex("datatype1");
405 print_hex("datatype2");
406 print_hex("res18");
407 print_hex("res19");
409 print_end_block();
412 static BOOL dump_msft_typeinfobases(seg_t *seg)
414 int i;
416 for(i = 0; offset < seg->offset+seg->length; i++)
417 dump_msft_typeinfobase();
419 assert(offset == seg->offset+seg->length);
420 return TRUE;
423 static void dump_msft_impinfo(int n)
425 print_begin_block_id("ImpInfo", n);
427 print_hex("flags");
428 print_hex("oImpInfo");
429 print_hex("oGuid");
431 print_end_block();
434 static BOOL dump_msft_impinfos(seg_t *seg)
436 int i;
438 for(i = 0; offset < seg->offset+seg->length; i++)
439 dump_msft_impinfo(i);
441 assert(offset == seg->offset+seg->length);
442 return TRUE;
445 static void dump_msft_impfile(int n)
447 print_begin_block_id("ImpFile", n);
449 print_hex("guid");
450 print_hex("lcid");
451 print_hex("version");
452 print_ctl2("impfile");
454 print_end_block();
457 static BOOL dump_msft_impfiles(seg_t *seg)
459 int i;
461 for(i = 0; offset < seg->offset+seg->length; i++)
462 dump_msft_impfile(i);
464 assert(offset == seg->offset+seg->length);
465 return TRUE;
468 static BOOL dump_msft_reftabs(seg_t *seg)
470 print_begin_block("RefTab");
472 dump_binary(seg->length); /* FIXME */
474 print_end_block();
476 return TRUE;
479 static BOOL dump_msft_guidhashtab(seg_t *seg)
481 print_begin_block("GuidHashTab");
483 dump_binary(seg->length); /* FIXME */
485 print_end_block();
487 assert(offset == seg->offset+seg->length);
488 return TRUE;
491 static void dump_msft_guidentry(int n)
493 print_begin_block_id("GuidEntry", n);
495 print_guid("guid");
496 print_hex("hreftype");
497 print_hex("next_hash");
499 print_end_block();
502 static BOOL dump_msft_guidtab(seg_t *seg)
504 int i;
506 for(i = 0; offset < seg->offset+seg->length; i++)
507 dump_msft_guidentry(i);
509 assert(offset == seg->offset+seg->length);
510 return TRUE;
513 static BOOL dump_msft_namehashtab(seg_t *seg)
515 print_begin_block("NameHashTab");
517 dump_binary(seg->length); /* FIXME */
519 print_end_block();
520 return TRUE;
523 static void dump_string(int len, int align_off)
525 printf("\"");
526 fwrite(tlb_read(len), len, 1, stdout);
527 printf("\" ");
528 while((len++ + align_off) & 3)
529 printf("\\%2.2x", tlb_read_byte());
532 static void dump_msft_name(int base, int n)
534 int len;
536 print_begin_block_id("Name", n);
538 print_hex("hreftype");
539 print_hex("next_hash");
540 len = print_hex("namelen")&0xff;
542 print_offset();
543 printf("name = ");
544 dump_string(len, 0);
545 printf("\n");
547 print_end_block();
550 static BOOL dump_msft_nametab(seg_t *seg)
552 int i, base = offset;
554 for(i = 0; offset < seg->offset+seg->length; i++)
555 dump_msft_name(base, i);
557 assert(offset == seg->offset+seg->length);
558 return TRUE;
561 static void dump_msft_string(int n)
563 int len;
565 print_begin_block_id("String", n);
567 len = print_short_hex("stringlen");
569 print_offset();
570 printf("string = ");
571 dump_string(len, 2);
573 if(len < 3) {
574 for(len = 0; len < 4; len++)
575 printf("\\%2.2x", tlb_read_byte());
577 printf("\n");
579 print_end_block();
582 static BOOL dump_msft_stringtab(seg_t *seg)
584 int i;
586 for(i = 0; offset < seg->offset+seg->length; i++)
587 dump_msft_string(i);
589 assert(offset == seg->offset+seg->length);
590 return TRUE;
593 static void dump_msft_typedesc(int n)
595 print_begin_block_id("TYPEDESC", n);
597 print_hex("hreftype");
598 print_hex("vt");
600 print_end_block();
603 static BOOL dump_msft_typedesctab(seg_t *seg)
605 int i;
607 print_begin_block("TypedescTab");
609 for(i = 0; offset < seg->offset+seg->length; i++)
610 dump_msft_typedesc(i);
612 print_end_block();
614 assert(offset == seg->offset+seg->length);
615 return TRUE;
618 static BOOL dump_msft_arraydescs(seg_t *seg)
620 print_begin_block("ArrayDescriptions");
622 dump_binary(seg->length); /* FIXME */
624 print_end_block();
625 return TRUE;
628 static BOOL dump_msft_custdata(seg_t *seg)
630 unsigned short vt;
631 unsigned i, n;
633 print_begin_block("CustData");
635 for(i=0; offset < seg->offset+seg->length; i++) {
636 print_offset();
638 vt = tlb_read_short();
639 printf("vt %d", vt);
640 n = tlb_read_int();
642 switch(vt) {
643 case VT_BSTR:
644 printf(" len %d: ", n);
645 dump_string(n, 2);
646 printf("\n");
647 break;
648 default:
649 printf(": %x ", n);
650 printf("\\%2.2x ", tlb_read_byte());
651 printf("\\%2.2x\n", tlb_read_byte());
655 print_end_block();
656 return TRUE;
659 static void dump_msft_cdguid(int n)
661 print_begin_block_id("CGUid", n);
663 print_hex("GuidOffset");
664 print_hex("DataOffset");
665 print_hex("next");
667 print_end_block();
670 static BOOL dump_msft_cdguids(seg_t *seg)
672 int i;
674 for(i = 0; offset < seg->offset+seg->length; i++)
675 dump_msft_cdguid(i);
677 assert(offset == seg->offset+seg->length);
678 return TRUE;
681 static BOOL dump_msft_res0e(seg_t *seg)
683 print_begin_block("res0e");
684 dump_binary(seg->length);
685 print_end_block();
687 return TRUE;
690 static BOOL dump_msft_res0f(seg_t *seg)
692 print_begin_block("res0f");
693 dump_binary(seg->length);
694 print_end_block();
696 return TRUE;
699 /* Used for function return value and arguments type */
700 static void dump_msft_datatype(const char *name)
702 int datatype;
704 print_offset();
705 datatype = tlb_read_int();
706 printf("%s = %08x", name, datatype);
707 if (datatype < 0) {
708 printf(", ");
709 print_vartype(datatype);
711 else {
712 const short *vt;
714 if (datatype > segdir[SEGDIR_TYPEDESC].length) {
715 printf(", invalid offset\n");
716 return;
719 /* FIXME: in case of VT_USERDEFINED use hreftype */
720 vt = PRD(segdir[SEGDIR_TYPEDESC].offset + datatype, 4*sizeof(short));
721 datatype = vt[0] & VT_TYPEMASK;
722 if (datatype == VT_PTR) {
723 printf(", VT_PTR -> ");
724 if (vt[3] < 0)
725 datatype = vt[2];
726 else {
727 vt = PRD(segdir[SEGDIR_TYPEDESC].offset + vt[2], 4*sizeof(short));
728 datatype = *vt;
731 else {
732 printf(", ");
733 datatype = *vt;
736 print_vartype(datatype);
740 static void dump_defaultvalue(int id)
742 int offset;
744 print_offset();
745 offset = tlb_read_int();
747 printf("default value[%d] = %08x", id, offset);
748 if (offset == -1)
749 printf("\n");
750 else if (offset < 0) {
751 printf(", ");
752 print_vartype((offset & 0x7c000000) >> 26);
754 else {
755 const unsigned short *vt;
757 if (offset > segdir[SEGDIR_CUSTDATA].length) {
758 printf(", invalid offset\n");
759 return;
762 vt = PRD(segdir[SEGDIR_CUSTDATA].offset + offset, sizeof(*vt));
763 printf(", ");
764 print_vartype(*vt);
768 static void dump_msft_func(int n)
770 int size, args_cnt, i, extra_attr, fkccic;
772 print_begin_block_id("FuncRecord", n);
774 size = print_short_hex("size");
775 print_short_hex("index");
776 dump_msft_datatype("retval type");
777 print_hex("flags");
778 print_short_hex("VtableOffset");
779 print_short_hex("funcdescsize");
780 fkccic = print_hex("FKCCIC");
781 args_cnt = print_short_hex("nrargs");
782 print_short_hex("noptargs");
784 extra_attr = size/sizeof(INT) - 6 - args_cnt*(fkccic&0x1000 ? 4 : 3);
786 if(extra_attr)
787 print_hex("helpcontext");
788 if(extra_attr >= 2)
789 print_hex("oHelpString");
790 if(extra_attr >= 3)
791 print_hex("toEntry");
792 if(extra_attr >= 4)
793 print_hex("res9");
794 if(extra_attr >= 5)
795 print_hex("resA");
796 if(extra_attr >= 6)
797 print_hex("HelpStringContext");
798 if(extra_attr >= 7)
799 print_hex("oCustData");
800 for(i = 0; i < extra_attr-7; i++)
801 print_hex_id("oArgCustData", i);
803 if(fkccic & 0x1000) {
804 for(i=0; i < args_cnt; i++)
805 dump_defaultvalue(i);
808 for(i=0; i < args_cnt; i++) {
809 print_begin_block_id("param", i);
811 /* FIXME: Handle default values */
812 dump_msft_datatype("datatype");
813 print_hex("name");
814 print_hex("paramflags");
816 print_end_block();
819 print_end_block();
822 static void dump_msft_var(int n)
824 INT size;
826 print_begin_block_id("VarRecord", n);
828 size = print_hex("recsize")&0x1ff;
829 print_hex("DataType");
830 print_hex("flags");
831 print_short_hex("VarKind");
832 print_short_hex("vardescsize");
833 print_hex("OffsValue");
835 if(size > 5*sizeof(INT))
836 dump_binary(size - 5*sizeof(INT));
838 print_end_block();
841 static void dump_msft_ref(int n)
843 print_begin_block_id("RefRecord", n);
845 print_hex("reftype");
846 print_hex("flags");
847 print_hex("oCustData");
848 print_hex("onext");
850 print_end_block();
853 static void dump_msft_coclass(int n)
855 int i;
857 print_dec("size");
859 for(i=0; i < msft_typeinfo_impltypes[n]; i++)
860 dump_msft_ref(i);
863 static BOOL dump_msft_typeinfo(int n)
865 int i;
867 print_begin_block_id("TypeInfo", n);
869 if((msft_typeinfo_kind[n] & 0xf) == TKIND_COCLASS) {
870 dump_msft_coclass(n);
871 print_end_block();
872 return TRUE;
875 print_dec("size");
877 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
878 dump_msft_func(i);
880 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
881 dump_msft_var(i);
883 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
884 print_hex_id("func %d id", i);
886 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
887 print_hex_id("var %d id", i);
889 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
890 print_hex_id("func %d name", i);
892 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
893 print_hex_id("var %d name", i);
895 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
896 print_hex_id("func %d offset", i);
898 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
899 print_hex_id("var %d offset", i);
901 print_end_block();
903 return TRUE;
906 static seg_t segdir[] = {
907 {"TypeInfoTab", dump_msft_typeinfobases, -1, -1},
908 {"ImpInfo", dump_msft_impinfos, -1, -1},
909 {"ImpFiles", dump_msft_impfiles, -1, -1},
910 {"RefTab", dump_msft_reftabs, -1, -1},
911 {"GuidHashTab", dump_msft_guidhashtab, -1, -1},
912 {"GuidTab", dump_msft_guidtab, -1, -1},
913 {"NameHashTab", dump_msft_namehashtab, -1, -1},
914 {"pNameTab", dump_msft_nametab, -1, -1},
915 {"pStringTab", dump_msft_stringtab, -1, -1},
916 {"TypedescTab", dump_msft_typedesctab, -1, -1},
917 {"ArrayDescriptions", dump_msft_arraydescs, -1, -1},
918 {"CustData", dump_msft_custdata, -1, -1},
919 {"CDGuid", dump_msft_cdguids, -1, -1},
920 {"res0e", dump_msft_res0e, -1, -1},
921 {"res0f", dump_msft_res0f, -1, -1}
924 static void dump_msft_seg(seg_t *seg)
926 print_begin_block(seg->name);
928 seg->offset = print_hex("offset");
929 seg->length = print_dec("length");
930 print_hex("res08");
931 print_hex("res0c");
933 print_end_block();
936 static void dump_msft_segdir(void)
938 int i;
940 print_begin_block("SegDir");
942 for(i=0; i < sizeof(segdir)/sizeof(segdir[0]); i++)
943 dump_msft_seg(segdir+i);
945 print_end_block();
948 static BOOL dump_offset(void)
950 int i;
952 for(i=0; i < sizeof(segdir)/sizeof(segdir[0]); i++)
953 if(segdir[i].offset == offset)
954 return segdir[i].func(segdir+i);
956 for(i=0; i < msft_typeinfo_cnt; i++)
957 if(msft_typeinfo_offs[i] == offset)
958 return dump_msft_typeinfo(i);
960 return FALSE;
963 enum FileSig get_kind_msft(void)
965 const DWORD *sig = PRD(0, sizeof(DWORD));
966 return sig && *sig == MSFT_MAGIC ? SIG_MSFT : SIG_UNKNOWN;
969 void msft_dump(void)
971 int i;
973 dump_msft_header();
975 for(i=0; i < typeinfo_cnt; i++)
976 print_hex_id("typeinfo %d offset", i);
978 if(header_flags & HELPDLLFLAG)
979 print_hex("help dll offset");
980 print_offset();
981 printf("\n");
983 dump_msft_segdir();
985 while(!msft_eof) {
986 if(!dump_offset())
987 print_hex("unknown");