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");