winedump: Add print_string() helper.
[wine.git] / tools / winedump / tlb.c
blobd2883598d7b44aa3418c53d0d1d710df535e4bdb
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[15];
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 unsigned 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;
176 for(i=0; i<indent; i++)
177 printf(" ");
180 static void print_begin_block(const char *name)
182 print_offset();
183 printf("%s {\n", name);
184 indent++;
187 static void print_begin_block_id(const char *name, int id)
189 char buf[64];
190 sprintf(buf, "%s %d", name, id);
191 print_begin_block(buf);
194 static void print_end_block(void)
196 indent--;
197 print_offset();
198 printf("}\n");
199 print_offset();
200 printf("\n");
203 static int print_hex(const char *name)
205 int ret;
206 print_offset();
207 printf("%s = %08xh\n", name, ret=tlb_read_int());
208 return ret;
211 static int print_hex_id(const char *name, int id)
213 char buf[64];
214 sprintf(buf, name, id);
215 return print_hex(buf);
218 static int print_short_hex(const char *name)
220 int ret;
221 print_offset();
222 printf("%s = %04xh\n", name, ret=tlb_read_short());
223 return ret;
226 static int print_dec(const char *name)
228 int ret;
229 print_offset();
230 printf("%s = %d\n", name, ret=tlb_read_int());
231 return ret;
234 static void print_guid(const char *name)
236 GUID guid = *(const GUID*)tlb_read(sizeof(guid));
238 print_offset();
240 printf("%s = {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", name,
241 guid.Data1, guid.Data2, guid.Data3, guid.Data4[0],
242 guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4],
243 guid.Data4[5], guid.Data4[6], guid.Data4[7]);
246 static void print_vartype(int vartype)
248 static const char *vartypes[VT_LPWSTR+1] = {
249 "VT_EMPTY", "VT_NULL", "VT_I2", "VT_I4", "VT_R4",
250 "VT_R8", "VT_CY", "VT_DATE", "VT_BSTR", "VT_DISPATCH",
251 "VT_ERROR", "VT_BOOL", "VT_VARIANT", "VT_UNKNOWN","VT_DECIMAL",
252 "unk 15", "VT_I1", "VT_UI1", "VT_UI2", "VT_UI4",
253 "VT_I8", "VT_UI8", "VT_INT", "VT_UINT", "VT_VOID",
254 "VT_HRESULT", "VT_PTR", "VT_SAFEARRAY","VT_CARRAY", "VT_USERDEFINED",
255 "VT_LPSTR", "VT_LPWSTR"
258 vartype &= VT_TYPEMASK;
259 if (vartype >= VT_EMPTY && vartype <= VT_LPWSTR)
260 printf("%s\n", vartypes[vartype]);
261 else
262 printf("unk %d\n", vartype);
265 static void print_ctl2(const char *name)
267 int len;
268 const char *buf;
270 print_offset();
272 len = tlb_read_short();
274 printf("%s = %d \"", name, len);
275 len >>= 2;
276 buf = tlb_read(len);
277 fwrite(buf, len, 1, stdout);
278 printf("\"");
279 len += 2;
281 while(len++ & 3)
282 printf("\\%02x", tlb_read_byte());
283 printf("\n");
286 static void dump_binary(int n)
288 int i;
290 for(i = 1; i <= n; i++) {
291 switch(i & 0x0f) {
292 case 0:
293 printf("%02x\n", tlb_read_byte());
294 break;
295 case 1:
296 print_offset();
297 /* fall through */
298 default:
299 printf("%02x ", tlb_read_byte());
303 if(n&0x0f)
304 printf("\n");
307 static int dump_msft_varflags(void)
309 static const char *syskind[] = {
310 "SYS_WIN16", "SYS_WIN32", "SYS_MAC", "SYS_WIN64", "unknown"
312 int kind, flags;
314 print_offset();
315 flags = tlb_read_int();
316 kind = flags & 0xf;
317 if (kind > 3) kind = 4;
318 printf("varflags = %08x, syskind = %s\n", flags, syskind[kind]);
319 return flags;
322 static void dump_msft_version(void)
324 unsigned version;
325 print_offset();
326 version = tlb_read_int();
327 printf("version = %u.%u\n", version & 0xffff, version >> 16);
330 static void dump_msft_header(void)
332 print_begin_block("Header");
334 print_hex("magic1");
335 print_hex("magic2");
336 print_hex("posguid");
337 print_hex("lcid");
338 print_hex("lcid2");
339 header_flags = dump_msft_varflags();
340 dump_msft_version();
341 print_hex("flags");
342 typeinfo_cnt = print_dec("ntypeinfos");
343 print_dec("helpstring");
344 print_dec("helpstringcontext");
345 print_dec("helpcontext");
346 print_dec("nametablecount");
347 print_dec("nametablechars");
348 print_hex("NameOffset");
349 print_hex("helpfile");
350 print_hex("CustomDataOffset");
351 print_hex("res44");
352 print_hex("res48");
353 print_hex("dispatchpos");
354 print_hex("res50");
356 print_end_block();
359 static int dump_msft_typekind(void)
361 static const char *tkind[TKIND_MAX] = {
362 "TKIND_ENUM", "TKIND_RECORD", "TKIND_MODULE",
363 "TKIND_INTERFACE", "TKIND_DISPATCH", "TKIND_COCLASS",
364 "TKIND_ALIAS", "TKIND_UNION"
366 int ret, typekind;
368 print_offset();
369 ret = tlb_read_int();
370 typekind = ret & 0xf;
371 printf("typekind = %s, align = %d\n", typekind < TKIND_MAX ? tkind[typekind] : "unknown", (ret >> 11) & 0x1f);
372 return ret;
375 static void dump_msft_typeinfobase(void)
377 print_begin_block_id("TypeInfoBase", msft_typeinfo_cnt);
379 msft_typeinfo_kind[msft_typeinfo_cnt] = dump_msft_typekind();
380 msft_typeinfo_offs[msft_typeinfo_cnt] = print_hex("memoffset");
381 print_hex("res2");
382 print_hex("res3");
383 print_hex("res4");
384 print_hex("res5");
385 msft_typeinfo_elemcnt[msft_typeinfo_cnt] = print_hex("cElement");
386 print_hex("res7");
387 print_hex("res8");
388 print_hex("res9");
389 print_hex("resA");
390 print_hex("posguid");
391 print_hex("flags");
392 print_hex("NameOffset");
393 print_hex("version");
394 print_hex("docstringoffs");
395 print_hex("docstringcontext");
396 print_hex("helpcontext");
397 print_hex("oCustData");
398 msft_typeinfo_impltypes[msft_typeinfo_cnt++] = print_short_hex("cImplTypes");
399 print_short_hex("bSizeVftt");
400 print_dec("size");
401 print_hex("datatype1");
402 print_hex("datatype2");
403 print_hex("res18");
404 print_hex("res19");
406 print_end_block();
409 static BOOL dump_msft_typeinfobases(seg_t *seg)
411 int i;
413 for(i = 0; offset < seg->offset+seg->length; i++)
414 dump_msft_typeinfobase();
416 assert(offset == seg->offset+seg->length);
417 return TRUE;
420 static void dump_msft_impinfo(int n)
422 print_begin_block_id("ImpInfo", n);
424 print_hex("flags");
425 print_hex("oImpInfo");
426 print_hex("oGuid");
428 print_end_block();
431 static BOOL dump_msft_impinfos(seg_t *seg)
433 int i;
435 for(i = 0; offset < seg->offset+seg->length; i++)
436 dump_msft_impinfo(i);
438 assert(offset == seg->offset+seg->length);
439 return TRUE;
442 static void dump_msft_impfile(int n)
444 print_begin_block_id("ImpFile", n);
446 print_hex("guid");
447 print_hex("lcid");
448 print_hex("version");
449 print_ctl2("impfile");
451 print_end_block();
454 static BOOL dump_msft_impfiles(seg_t *seg)
456 int i;
458 for(i = 0; offset < seg->offset+seg->length; i++)
459 dump_msft_impfile(i);
461 assert(offset == seg->offset+seg->length);
462 return TRUE;
465 static BOOL dump_msft_reftabs(seg_t *seg)
467 print_begin_block("RefTab");
469 dump_binary(seg->length); /* FIXME */
471 print_end_block();
473 return TRUE;
476 static BOOL dump_msft_guidhashtab(seg_t *seg)
478 print_begin_block("GuidHashTab");
480 dump_binary(seg->length); /* FIXME */
482 print_end_block();
484 assert(offset == seg->offset+seg->length);
485 return TRUE;
488 static void dump_msft_guidentry(int n)
490 print_begin_block_id("GuidEntry", n);
492 print_guid("guid");
493 print_hex("hreftype");
494 print_hex("next_hash");
496 print_end_block();
499 static BOOL dump_msft_guidtab(seg_t *seg)
501 int i;
503 for(i = 0; offset < seg->offset+seg->length; i++)
504 dump_msft_guidentry(i);
506 assert(offset == seg->offset+seg->length);
507 return TRUE;
510 static BOOL dump_msft_namehashtab(seg_t *seg)
512 print_begin_block("NameHashTab");
514 dump_binary(seg->length); /* FIXME */
516 print_end_block();
517 return TRUE;
520 static void print_string(int len)
522 printf("\"");
523 fwrite(tlb_read(len), len, 1, stdout);
524 printf("\"");
527 static void dump_string(int len, int align_off)
529 print_string(len);
530 printf(" ");
531 while((len++ + align_off) & 3)
532 printf("\\%2.2x", tlb_read_byte());
535 static void dump_msft_name(int base, int n)
537 int len;
539 print_begin_block_id("Name", n);
541 print_hex("hreftype");
542 print_hex("next_hash");
543 len = print_hex("namelen")&0xff;
545 print_offset();
546 printf("name = ");
547 dump_string(len, 0);
548 printf("\n");
550 print_end_block();
553 static BOOL dump_msft_nametab(seg_t *seg)
555 int i, base = offset;
557 for(i = 0; offset < seg->offset+seg->length; i++)
558 dump_msft_name(base, i);
560 assert(offset == seg->offset+seg->length);
561 return TRUE;
564 static void dump_msft_string(int n)
566 int len;
568 print_begin_block_id("String", n);
570 len = print_short_hex("stringlen");
572 print_offset();
573 printf("string = ");
574 dump_string(len, 2);
576 if(len < 3) {
577 for(len = 0; len < 4; len++)
578 printf("\\%2.2x", tlb_read_byte());
580 printf("\n");
582 print_end_block();
585 static BOOL dump_msft_stringtab(seg_t *seg)
587 int i;
589 for(i = 0; offset < seg->offset+seg->length; i++)
590 dump_msft_string(i);
592 assert(offset == seg->offset+seg->length);
593 return TRUE;
596 static void dump_msft_typedesc(int n)
598 print_begin_block_id("TYPEDESC", n);
600 print_hex("hreftype");
601 print_hex("vt");
603 print_end_block();
606 static BOOL dump_msft_typedesctab(seg_t *seg)
608 int i;
610 print_begin_block("TypedescTab");
612 for(i = 0; offset < seg->offset+seg->length; i++)
613 dump_msft_typedesc(i);
615 print_end_block();
617 assert(offset == seg->offset+seg->length);
618 return TRUE;
621 static BOOL dump_msft_arraydescs(seg_t *seg)
623 print_begin_block("ArrayDescriptions");
625 dump_binary(seg->length); /* FIXME */
627 print_end_block();
628 return TRUE;
631 static BOOL dump_msft_custdata(seg_t *seg)
633 unsigned short vt;
634 unsigned i, n;
636 print_begin_block("CustData");
638 for(i=0; offset < seg->offset+seg->length; i++) {
639 print_offset();
641 vt = tlb_read_short();
642 printf("vt %d", vt);
643 n = tlb_read_int();
645 switch(vt) {
646 case VT_BSTR:
647 printf(" len %d: ", n);
648 dump_string(n, 2);
649 printf("\n");
650 break;
651 default:
652 printf(": %x ", n);
653 printf("\\%2.2x ", tlb_read_byte());
654 printf("\\%2.2x\n", tlb_read_byte());
658 print_end_block();
659 return TRUE;
662 static void dump_msft_cdguid(int n)
664 print_begin_block_id("CGUid", n);
666 print_hex("GuidOffset");
667 print_hex("DataOffset");
668 print_hex("next");
670 print_end_block();
673 static BOOL dump_msft_cdguids(seg_t *seg)
675 int i;
677 for(i = 0; offset < seg->offset+seg->length; i++)
678 dump_msft_cdguid(i);
680 assert(offset == seg->offset+seg->length);
681 return TRUE;
684 static BOOL dump_msft_res0e(seg_t *seg)
686 print_begin_block("res0e");
687 dump_binary(seg->length);
688 print_end_block();
690 return TRUE;
693 static BOOL dump_msft_res0f(seg_t *seg)
695 print_begin_block("res0f");
696 dump_binary(seg->length);
697 print_end_block();
699 return TRUE;
702 /* Used for function return value and arguments type */
703 static void dump_msft_datatype(const char *name)
705 int datatype;
707 print_offset();
708 datatype = tlb_read_int();
709 printf("%s = %08x", name, datatype);
710 if (datatype < 0) {
711 printf(", ");
712 print_vartype(datatype);
714 else {
715 const short *vt;
717 if (datatype > segdir[SEGDIR_TYPEDESC].length) {
718 printf(", invalid offset\n");
719 return;
722 /* FIXME: in case of VT_USERDEFINED use hreftype */
723 vt = PRD(segdir[SEGDIR_TYPEDESC].offset + datatype, 4*sizeof(short));
724 datatype = vt[0] & VT_TYPEMASK;
725 if (datatype == VT_PTR) {
726 printf(", VT_PTR -> ");
727 if (vt[3] < 0)
728 datatype = vt[2];
729 else {
730 vt = PRD(segdir[SEGDIR_TYPEDESC].offset + vt[2], 4*sizeof(short));
731 datatype = *vt;
734 else {
735 printf(", ");
736 datatype = *vt;
739 print_vartype(datatype);
743 static void dump_defaultvalue(int id)
745 int offset;
747 print_offset();
748 offset = tlb_read_int();
750 printf("default value[%d] = %08x", id, offset);
751 if (offset == -1)
752 printf("\n");
753 else if (offset < 0) {
754 printf(", ");
755 print_vartype((offset & 0x7c000000) >> 26);
757 else {
758 const unsigned short *vt;
760 if (offset > segdir[SEGDIR_CUSTDATA].length) {
761 printf(", invalid offset\n");
762 return;
765 vt = PRD(segdir[SEGDIR_CUSTDATA].offset + offset, sizeof(*vt));
766 printf(", ");
767 print_vartype(*vt);
771 static void dump_msft_func(int n)
773 int size, args_cnt, i, extra_attr, fkccic;
775 print_begin_block_id("FuncRecord", n);
777 size = print_short_hex("size");
778 print_short_hex("index");
779 dump_msft_datatype("retval type");
780 print_hex("flags");
781 print_short_hex("VtableOffset");
782 print_short_hex("funcdescsize");
783 fkccic = print_hex("FKCCIC");
784 args_cnt = print_short_hex("nrargs");
785 print_short_hex("noptargs");
787 extra_attr = size/sizeof(INT) - 6 - args_cnt*(fkccic&0x1000 ? 4 : 3);
789 if(extra_attr)
790 print_hex("helpcontext");
791 if(extra_attr >= 2)
792 print_hex("oHelpString");
793 if(extra_attr >= 3)
794 print_hex("toEntry");
795 if(extra_attr >= 4)
796 print_hex("res9");
797 if(extra_attr >= 5)
798 print_hex("resA");
799 if(extra_attr >= 6)
800 print_hex("HelpStringContext");
801 if(extra_attr >= 7)
802 print_hex("oCustData");
803 for(i = 0; i < extra_attr-7; i++)
804 print_hex_id("oArgCustData", i);
806 if(fkccic & 0x1000) {
807 for(i=0; i < args_cnt; i++)
808 dump_defaultvalue(i);
811 for(i=0; i < args_cnt; i++) {
812 print_begin_block_id("param", i);
814 /* FIXME: Handle default values */
815 dump_msft_datatype("datatype");
816 print_hex("name");
817 print_hex("paramflags");
819 print_end_block();
822 print_end_block();
825 static void dump_msft_var(int n)
827 INT size;
829 print_begin_block_id("VarRecord", n);
831 size = print_hex("recsize")&0x1ff;
832 print_hex("DataType");
833 print_hex("flags");
834 print_short_hex("VarKind");
835 print_short_hex("vardescsize");
836 print_hex("OffsValue");
838 if(size > 5*sizeof(INT))
839 dump_binary(size - 5*sizeof(INT));
841 print_end_block();
844 static void dump_msft_ref(int n)
846 print_begin_block_id("RefRecord", n);
848 print_hex("reftype");
849 print_hex("flags");
850 print_hex("oCustData");
851 print_hex("onext");
853 print_end_block();
856 static void dump_msft_coclass(int n)
858 int i;
860 print_dec("size");
862 for(i=0; i < msft_typeinfo_impltypes[n]; i++)
863 dump_msft_ref(i);
866 static BOOL dump_msft_typeinfo(int n)
868 int i;
870 print_begin_block_id("TypeInfo", n);
872 if((msft_typeinfo_kind[n] & 0xf) == TKIND_COCLASS) {
873 dump_msft_coclass(n);
874 print_end_block();
875 return TRUE;
878 print_dec("size");
880 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
881 dump_msft_func(i);
883 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
884 dump_msft_var(i);
886 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
887 print_hex_id("func %d id", i);
889 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
890 print_hex_id("var %d id", i);
892 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
893 print_hex_id("func %d name", i);
895 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
896 print_hex_id("var %d name", i);
898 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
899 print_hex_id("func %d offset", i);
901 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
902 print_hex_id("var %d offset", i);
904 print_end_block();
906 return TRUE;
909 static seg_t segdir[] = {
910 {"TypeInfoTab", dump_msft_typeinfobases, -1, -1},
911 {"ImpInfo", dump_msft_impinfos, -1, -1},
912 {"ImpFiles", dump_msft_impfiles, -1, -1},
913 {"RefTab", dump_msft_reftabs, -1, -1},
914 {"GuidHashTab", dump_msft_guidhashtab, -1, -1},
915 {"GuidTab", dump_msft_guidtab, -1, -1},
916 {"NameHashTab", dump_msft_namehashtab, -1, -1},
917 {"pNameTab", dump_msft_nametab, -1, -1},
918 {"pStringTab", dump_msft_stringtab, -1, -1},
919 {"TypedescTab", dump_msft_typedesctab, -1, -1},
920 {"ArrayDescriptions", dump_msft_arraydescs, -1, -1},
921 {"CustData", dump_msft_custdata, -1, -1},
922 {"CDGuid", dump_msft_cdguids, -1, -1},
923 {"res0e", dump_msft_res0e, -1, -1},
924 {"res0f", dump_msft_res0f, -1, -1}
927 static void dump_msft_seg(seg_t *seg)
929 print_begin_block(seg->name);
931 seg->offset = print_hex("offset");
932 seg->length = print_dec("length");
933 print_hex("res08");
934 print_hex("res0c");
936 print_end_block();
939 static void dump_msft_segdir(void)
941 int i;
943 print_begin_block("SegDir");
945 for(i=0; i < sizeof(segdir)/sizeof(segdir[0]); i++)
946 dump_msft_seg(segdir+i);
948 print_end_block();
951 static BOOL dump_offset(void)
953 int i;
955 for(i=0; i < sizeof(segdir)/sizeof(segdir[0]); i++)
956 if(segdir[i].offset == offset)
957 return segdir[i].func(segdir+i);
959 for(i=0; i < msft_typeinfo_cnt; i++)
960 if(msft_typeinfo_offs[i] == offset)
961 return dump_msft_typeinfo(i);
963 return FALSE;
966 enum FileSig get_kind_msft(void)
968 const DWORD *sig = PRD(0, sizeof(DWORD));
969 return sig && *sig == MSFT_MAGIC ? SIG_MSFT : SIG_UNKNOWN;
972 void msft_dump(void)
974 int i;
976 dump_msft_header();
978 for(i=0; i < typeinfo_cnt; i++)
979 print_hex_id("typeinfo %d offset", i);
981 if(header_flags & HELPDLLFLAG)
982 print_hex("help dll offset");
983 print_offset();
984 printf("\n");
986 dump_msft_segdir();
988 while(!msft_eof) {
989 if(!dump_offset())
990 print_hex("unknown");