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
22 #include "wine/port.h"
32 #define MSFT_MAGIC 0x5446534d
33 #define HELPDLLFLAG 0x0100
49 typedef int (*dump_seg_t
)(struct seg_t
*);
51 typedef struct seg_t
{
58 extern seg_t segdir
[];
62 static int typeinfo_cnt
;
63 static int header_flags
= 0;
64 static int msft_eof
= 0;
66 static int msft_typeinfo_offs
[1000];
67 static int msft_typeinfo_kind
[1000];
68 static int msft_typeinfo_impltypes
[1000];
69 static int msft_typeinfo_elemcnt
[1000];
70 static int msft_typeinfo_cnt
= 0;
72 static const void *tlb_read(int size
) {
73 const void *ret
= PRD(offset
, size
);
83 static int tlb_read_int(void)
85 const int *ret
= (const int*)tlb_read(sizeof(int));
86 return ret
? *ret
: -1;
89 static int tlb_read_short(void)
91 const short *ret
= (const short*)tlb_read(sizeof(short));
92 return ret
? *ret
: -1;
95 static int tlb_read_byte(void)
97 const unsigned char *ret
= (const unsigned char*)tlb_read(sizeof(char));
98 return ret
? *ret
: -1;
101 static void print_offset(void)
105 printf("%04x: ", offset
);
107 for(i
=0; i
<indent
; i
++)
111 static void print_begin_block(const char *name
)
114 printf("%s {\n", name
);
118 static void print_begin_block_id(const char *name
, int id
)
121 sprintf(buf
, "%s %d", name
, id
);
122 print_begin_block(buf
);
125 static void print_end_block(void)
134 static int print_hex(const char *name
)
138 printf("%s = %08x\n", name
, ret
=tlb_read_int());
142 static int print_hex_id(const char *name
, int id
)
145 sprintf(buf
, name
, id
);
146 return print_hex(buf
);
149 static int print_short_hex(const char *name
)
153 printf("%s = %xh\n", name
, ret
=tlb_read_short());
157 static int print_dec(const char *name
)
161 printf("%s = %d\n", name
, ret
=tlb_read_int());
165 static void print_guid(const char *name
)
167 GUID guid
= *(const GUID
*)tlb_read(sizeof(guid
));
171 printf("%s = {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", name
,
172 guid
.Data1
, guid
.Data2
, guid
.Data3
, guid
.Data4
[0],
173 guid
.Data4
[1], guid
.Data4
[2], guid
.Data4
[3], guid
.Data4
[4],
174 guid
.Data4
[5], guid
.Data4
[6], guid
.Data4
[7]);
177 static void print_ctl2(const char *name
)
184 len
= tlb_read_short();
186 printf("%s = %d \"", name
, len
);
189 fwrite(buf
, len
, 1, stdout
);
194 printf("\\%02x", tlb_read_byte());
198 static void dump_binary(int n
)
202 for(i
= 1; i
<= n
; i
++) {
205 printf("%02x\n", tlb_read_byte());
211 printf("%02x ", tlb_read_byte());
219 static void dump_msft_header(void)
221 print_begin_block("Header");
225 print_hex("posguid");
228 header_flags
= print_hex("varflags");
229 print_hex("version");
231 typeinfo_cnt
= print_dec("ntypeinfos");
232 print_hex("helpstring");
233 print_hex("helpstringcontext");
234 print_hex("helpcontext");
235 print_dec("nametablecont");
236 print_dec("nametablechars");
237 print_hex("NameOffset");
238 print_hex("helpfile");
239 print_hex("CustomDataOffset");
242 print_hex("dispatchpos");
248 static void dump_msft_typeinfobase(void)
250 print_begin_block_id("TypeInfoBase", msft_typeinfo_cnt
);
252 msft_typeinfo_kind
[msft_typeinfo_cnt
] = print_hex("typekind");
253 msft_typeinfo_offs
[msft_typeinfo_cnt
] = print_hex("memoffset");
258 msft_typeinfo_elemcnt
[msft_typeinfo_cnt
] = print_hex("cElement");
263 print_hex("posguid");
265 print_hex("NameOffset");
266 print_hex("version");
267 print_hex("docstringoffs");
268 print_hex("docstringcontext");
269 print_hex("helpcontext");
270 print_hex("oCustData");
271 msft_typeinfo_impltypes
[msft_typeinfo_cnt
++] = print_short_hex("cImplTypes");
272 print_short_hex("bSizeVftt");
274 print_hex("datatype1");
275 print_hex("datatype2");
282 static int dump_msft_typeinfobases(seg_t
*seg
)
286 for(i
= 0; offset
< seg
->offset
+seg
->length
; i
++)
287 dump_msft_typeinfobase();
289 assert(offset
== seg
->offset
+seg
->length
);
293 static void dump_msft_impinfo(int n
)
295 print_begin_block_id("ImpInfo", n
);
298 print_hex("oImpInfo");
304 static int dump_msft_impinfos(seg_t
*seg
)
308 for(i
= 0; offset
< seg
->offset
+seg
->length
; i
++)
309 dump_msft_impinfo(i
);
311 assert(offset
== seg
->offset
+seg
->length
);
315 static void dump_msft_impfile(int n
)
317 print_begin_block_id("ImpFile", n
);
321 print_hex("version");
322 print_ctl2("impfile");
327 static int dump_msft_impfiles(seg_t
*seg
)
331 for(i
= 0; offset
< seg
->offset
+seg
->length
; i
++)
332 dump_msft_impfile(i
);
334 assert(offset
== seg
->offset
+seg
->length
);
338 static int dump_msft_reftabs(seg_t
*seg
)
340 print_begin_block("RefTab");
342 dump_binary(seg
->length
); /* FIXME */
349 static int dump_msft_libtab(seg_t
*seg
)
351 print_begin_block("LibTab");
353 dump_binary(seg
->length
); /* FIXME */
357 assert(offset
== seg
->offset
+seg
->length
);
361 static void dump_msft_guidentry(int n
)
363 print_begin_block_id("GuidEntry", n
);
366 print_hex("hreftype");
367 print_hex("next_hash");
372 static int dump_msft_guidtab(seg_t
*seg
)
376 for(i
= 0; offset
< seg
->offset
+seg
->length
; i
++)
377 dump_msft_guidentry(i
);
379 assert(offset
== seg
->offset
+seg
->length
);
383 static int dump_msft_res07(seg_t
*seg
)
385 print_begin_block("res07");
387 dump_binary(seg
->length
); /* FIXME */
393 static void dump_msft_name(int base
, int n
)
397 print_begin_block_id("Name", n
);
399 print_hex("hreftype");
400 print_hex("next_hash");
401 len
= print_hex("namelen")&0xff;
405 fwrite(tlb_read(len
), len
, 1, stdout
);
408 printf("\\%2.2x", tlb_read_byte());
414 static int dump_msft_nametab(seg_t
*seg
)
416 int i
, base
= offset
;
418 for(i
= 0; offset
< seg
->offset
+seg
->length
; i
++)
419 dump_msft_name(base
, i
);
421 assert(offset
== seg
->offset
+seg
->length
);
425 static int dump_msft_stringtab(seg_t
*seg
)
427 print_begin_block("StringTab");
429 dump_binary(seg
->length
); /* FIXME */
436 static void dump_msft_typedesc(int n
)
438 print_begin_block_id("TYPEDESC", n
);
440 print_hex("hreftype");
446 static int dump_msft_typedesctab(seg_t
*seg
)
450 print_begin_block("TypedescTab");
452 for(i
= 0; offset
< seg
->offset
+seg
->length
; i
++)
453 dump_msft_typedesc(i
);
457 assert(offset
== seg
->offset
+seg
->length
);
461 static int dump_msft_arraydescs(seg_t
*seg
)
463 print_begin_block("ArrayDescriptions");
465 dump_binary(seg
->length
); /* FIXME */
471 static int dump_msft_custdata(seg_t
*seg
)
473 print_begin_block("CustData");
475 dump_binary(seg
->length
); /* FIXME */
481 static void dump_msft_cdguid(int n
)
483 print_begin_block_id("CGUid", n
);
485 print_hex("GuidOffset");
486 print_hex("DataOffset");
492 static int dump_msft_cdguids(seg_t
*seg
)
496 for(i
= 0; offset
< seg
->offset
+seg
->length
; i
++)
499 assert(offset
== seg
->offset
+seg
->length
);
503 static int dump_msft_res0e(seg_t
*seg
)
505 print_begin_block("res0e");
506 dump_binary(seg
->length
);
512 static int dump_msft_res0f(seg_t
*seg
)
514 print_begin_block("res0f");
515 dump_binary(seg
->length
);
521 static void dump_msft_func(int n
)
523 int size
, args_cnt
, i
, extra_attr
, fkccic
;
525 print_begin_block_id("FuncRecord", n
);
527 size
= print_short_hex("size");
528 print_short_hex("index");
529 print_hex("DataType");
531 print_short_hex("VtableOffset");
532 print_short_hex("funcdescsize");
533 fkccic
= print_hex("FKCCIC");
534 args_cnt
= print_short_hex("nrargs");
535 print_short_hex("noptargs");
537 extra_attr
= size
/sizeof(INT
) - 6 - args_cnt
*(fkccic
&0x1000 ? 4 : 3);
540 print_hex("helpcontext");
542 print_hex("oHelpString");
544 print_hex("toEntry");
550 print_hex("HelpStringContext");
552 print_hex("oCustData");
554 if(fkccic
& 0x1000) {
555 for(i
=0; i
< args_cnt
; i
++)
556 print_hex_id("default value[%d]", i
);
559 for(i
=0; i
< args_cnt
; i
++) {
560 print_begin_block_id("param", i
);
562 /* FIXME: Handle default values */
563 print_hex("data[0]");
564 print_hex("paramflags");
565 print_hex("data[2]");
573 static void dump_msft_var(int n
)
577 print_begin_block_id("VarRecord", n
);
579 size
= print_hex("recsize")&0x1ff;
580 print_hex("DataType");
582 print_short_hex("VarKind");
583 print_short_hex("vardescsize");
584 print_hex("OffsValue");
586 if(size
> 5*sizeof(INT
))
587 dump_binary(size
- 5*sizeof(INT
));
592 static void dump_msft_ref(int n
)
594 print_begin_block_id("RefRecord", n
);
596 print_hex("reftype");
598 print_hex("oCustData");
604 static void dump_msft_coclass(int n
)
610 for(i
=0; i
< msft_typeinfo_impltypes
[n
]; i
++)
614 static int dump_msft_typeinfo(int n
)
618 print_begin_block_id("TypeInfo", n
);
620 if((msft_typeinfo_kind
[n
] & 0xf) == TKIND_COCLASS
) {
621 dump_msft_coclass(n
);
628 for(i
= 0; i
< LOWORD(msft_typeinfo_elemcnt
[n
]); i
++)
631 for(i
= 0; i
< HIWORD(msft_typeinfo_elemcnt
[n
]); i
++)
634 for(i
= 0; i
< LOWORD(msft_typeinfo_elemcnt
[n
]); i
++)
635 print_hex_id("func %d id", i
);
637 for(i
= 0; i
< HIWORD(msft_typeinfo_elemcnt
[n
]); i
++)
638 print_hex_id("var %d id", i
);
640 for(i
= 0; i
< LOWORD(msft_typeinfo_elemcnt
[n
]); i
++)
641 print_hex_id("func %d name", i
);
643 for(i
= 0; i
< HIWORD(msft_typeinfo_elemcnt
[n
]); i
++)
644 print_hex_id("var %d name", i
);
646 for(i
= 0; i
< LOWORD(msft_typeinfo_elemcnt
[n
]); i
++)
647 print_hex_id("func %d offset", i
);
649 for(i
= 0; i
< HIWORD(msft_typeinfo_elemcnt
[n
]); i
++)
650 print_hex_id("var %d offset", i
);
658 {"TypeInfoTab", dump_msft_typeinfobases
, -1, -1},
659 {"ImpInfo", dump_msft_impinfos
, -1, -1},
660 {"ImpFiles", dump_msft_impfiles
, -1, -1},
661 {"RefTab", dump_msft_reftabs
, -1, -1},
662 {"LibTab", dump_msft_libtab
, -1, -1},
663 {"GuidTab", dump_msft_guidtab
, -1, -1},
664 {"res07", dump_msft_res07
, -1, -1},
665 {"pNameTab", dump_msft_nametab
, -1, -1},
666 {"pStringTab", dump_msft_stringtab
, -1, -1},
667 {"TypedescTab", dump_msft_typedesctab
, -1, -1},
668 {"ArrayDescriptions", dump_msft_arraydescs
, -1, -1},
669 {"CustData", dump_msft_custdata
, -1, -1},
670 {"CDGuid", dump_msft_cdguids
, -1, -1},
671 {"res0e", dump_msft_res0e
, -1, -1},
672 {"res0f", dump_msft_res0f
, -1, -1}
675 static void dump_msft_seg(seg_t
*seg
)
677 print_begin_block(seg
->name
);
679 seg
->offset
= print_hex("offset");
680 seg
->length
= print_dec("length");
687 static void dump_msft_segdir(void)
691 print_begin_block("SegDir");
693 for(i
=0; i
< sizeof(segdir
)/sizeof(segdir
[0]); i
++)
694 dump_msft_seg(segdir
+i
);
699 static int dump_offset(void)
703 for(i
=0; i
< sizeof(segdir
)/sizeof(segdir
[0]); i
++)
704 if(segdir
[i
].offset
== offset
)
705 return segdir
[i
].func(segdir
+i
);
707 for(i
=0; i
< msft_typeinfo_cnt
; i
++)
708 if(msft_typeinfo_offs
[i
] == offset
)
709 return dump_msft_typeinfo(i
);
714 enum FileSig
get_kind_msft(void)
716 const DWORD
*sig
= PRD(0, sizeof(DWORD
));
717 return sig
&& *sig
== MSFT_MAGIC
? SIG_MSFT
: SIG_UNKNOWN
;
726 for(i
=0; i
< typeinfo_cnt
; i
++)
727 print_hex_id("typeinfo %d offset", i
);
729 if(header_flags
& HELPDLLFLAG
)
730 print_hex("help dll offset");
738 print_hex("unknown");