wine.inf: Install msdaps.dll into the correct directory.
[wine/multimedia.git] / tools / winedump / tlb.c
blob9ca20b85cc91afdb9ef717fc0feb5f537b6486b3
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 struct seg_t;
49 typedef int (*dump_seg_t)(struct seg_t*);
51 typedef struct seg_t {
52 const char *name;
53 dump_seg_t func;
54 int offset;
55 int length;
56 } seg_t;
58 extern seg_t segdir[];
60 static int offset=0;
61 static int indent;
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);
75 if(ret)
76 offset += size;
77 else
78 msft_eof = -1;
80 return ret;
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)
103 int i;
105 printf("%04x: ", offset);
107 for(i=0; i<indent; i++)
108 printf(" ");
111 static void print_begin_block(const char *name)
113 print_offset();
114 printf("%s {\n", name);
115 indent++;
118 static void print_begin_block_id(const char *name, int id)
120 char buf[64];
121 sprintf(buf, "%s %d", name, id);
122 print_begin_block(buf);
125 static void print_end_block(void)
127 indent--;
128 print_offset();
129 printf("}\n");
130 print_offset();
131 printf("\n");
134 static int print_hex(const char *name)
136 int ret;
137 print_offset();
138 printf("%s = %08x\n", name, ret=tlb_read_int());
139 return ret;
142 static int print_hex_id(const char *name, int id)
144 char buf[64];
145 sprintf(buf, name, id);
146 return print_hex(buf);
149 static int print_short_hex(const char *name)
151 int ret;
152 print_offset();
153 printf("%s = %xh\n", name, ret=tlb_read_short());
154 return ret;
157 static int print_dec(const char *name)
159 int ret;
160 print_offset();
161 printf("%s = %d\n", name, ret=tlb_read_int());
162 return ret;
165 static void print_guid(const char *name)
167 GUID guid = *(const GUID*)tlb_read(sizeof(guid));
169 print_offset();
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)
179 int len;
180 const char *buf;
182 print_offset();
184 len = tlb_read_short();
186 printf("%s = %d \"", name, len);
187 len >>= 2;
188 buf = tlb_read(len);
189 fwrite(buf, len, 1, stdout);
190 printf("\"");
191 len += 2;
193 while(len++ & 3)
194 printf("\\%02x", tlb_read_byte());
195 printf("\n");
198 static void dump_binary(int n)
200 int i;
202 for(i = 1; i <= n; i++) {
203 switch(i & 0x0f) {
204 case 0:
205 printf("%02x\n", tlb_read_byte());
206 break;
207 case 1:
208 print_offset();
209 /* fall through */
210 default:
211 printf("%02x ", tlb_read_byte());
215 if(n&0x0f)
216 printf("\n");
219 static void dump_msft_header(void)
221 print_begin_block("Header");
223 print_hex("magic1");
224 print_hex("magic2");
225 print_hex("posguid");
226 print_hex("lcid");
227 print_hex("lsid2");
228 header_flags = print_hex("varflags");
229 print_hex("version");
230 print_hex("flags");
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");
240 print_hex("res44");
241 print_hex("res48");
242 print_hex("dispatchpos");
243 print_hex("res50");
245 print_end_block();
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");
254 print_hex("res2");
255 print_hex("res3");
256 print_hex("res4");
257 print_hex("res5");
258 msft_typeinfo_elemcnt[msft_typeinfo_cnt] = print_hex("cElement");
259 print_hex("res7");
260 print_hex("res8");
261 print_hex("res9");
262 print_hex("resA");
263 print_hex("posguid");
264 print_hex("flags");
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");
273 print_dec("size");
274 print_hex("datatype1");
275 print_hex("datatype2");
276 print_hex("res18");
277 print_hex("res19");
279 print_end_block();
282 static int dump_msft_typeinfobases(seg_t *seg)
284 int i;
286 for(i = 0; offset < seg->offset+seg->length; i++)
287 dump_msft_typeinfobase();
289 assert(offset == seg->offset+seg->length);
290 return -1;
293 static void dump_msft_impinfo(int n)
295 print_begin_block_id("ImpInfo", n);
297 print_hex("flags");
298 print_hex("oImpInfo");
299 print_hex("oGuid");
301 print_end_block();
304 static int dump_msft_impinfos(seg_t *seg)
306 int i;
308 for(i = 0; offset < seg->offset+seg->length; i++)
309 dump_msft_impinfo(i);
311 assert(offset == seg->offset+seg->length);
312 return -1;
315 static void dump_msft_impfile(int n)
317 print_begin_block_id("ImpFile", n);
319 print_hex("guid");
320 print_hex("lcid");
321 print_hex("version");
322 print_ctl2("impfile");
324 print_end_block();
327 static int dump_msft_impfiles(seg_t *seg)
329 int i;
331 for(i = 0; offset < seg->offset+seg->length; i++)
332 dump_msft_impfile(i);
334 assert(offset == seg->offset+seg->length);
335 return -1;
338 static int dump_msft_reftabs(seg_t *seg)
340 print_begin_block("RefTab");
342 dump_binary(seg->length); /* FIXME */
344 print_end_block();
346 return -1;
349 static int dump_msft_libtab(seg_t *seg)
351 print_begin_block("LibTab");
353 dump_binary(seg->length); /* FIXME */
355 print_end_block();
357 assert(offset == seg->offset+seg->length);
358 return -1;
361 static void dump_msft_guidentry(int n)
363 print_begin_block_id("GuidEntry", n);
365 print_guid("guid");
366 print_hex("hreftype");
367 print_hex("next_hash");
369 print_end_block();
372 static int dump_msft_guidtab(seg_t *seg)
374 int i;
376 for(i = 0; offset < seg->offset+seg->length; i++)
377 dump_msft_guidentry(i);
379 assert(offset == seg->offset+seg->length);
380 return -1;
383 static int dump_msft_res07(seg_t *seg)
385 print_begin_block("res07");
387 dump_binary(seg->length); /* FIXME */
389 print_end_block();
390 return -1;
393 static void dump_msft_name(int base, int n)
395 int len;
397 print_begin_block_id("Name", n);
399 print_hex("hreftype");
400 print_hex("next_hash");
401 len = print_hex("namelen")&0xff;
403 print_offset();
404 printf("name = \"");
405 fwrite(tlb_read(len), len, 1, stdout);
406 printf("\" ");
407 while(len++ & 3)
408 printf("\\%2.2x", tlb_read_byte());
409 printf("\n");
411 print_end_block();
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);
422 return -1;
425 static int dump_msft_stringtab(seg_t *seg)
427 print_begin_block("StringTab");
429 dump_binary(seg->length); /* FIXME */
431 print_end_block();
433 return -1;
436 static void dump_msft_typedesc(int n)
438 print_begin_block_id("TYPEDESC", n);
440 print_hex("hreftype");
441 print_hex("vt");
443 print_end_block();
446 static int dump_msft_typedesctab(seg_t *seg)
448 int i;
450 print_begin_block("TypedescTab");
452 for(i = 0; offset < seg->offset+seg->length; i++)
453 dump_msft_typedesc(i);
455 print_end_block();
457 assert(offset == seg->offset+seg->length);
458 return -1;
461 static int dump_msft_arraydescs(seg_t *seg)
463 print_begin_block("ArrayDescriptions");
465 dump_binary(seg->length); /* FIXME */
467 print_end_block();
468 return -1;
471 static int dump_msft_custdata(seg_t *seg)
473 print_begin_block("CustData");
475 dump_binary(seg->length); /* FIXME */
477 print_end_block();
478 return -1;
481 static void dump_msft_cdguid(int n)
483 print_begin_block_id("CGUid", n);
485 print_hex("GuidOffset");
486 print_hex("DataOffset");
487 print_hex("next");
489 print_end_block();
492 static int dump_msft_cdguids(seg_t *seg)
494 int i;
496 for(i = 0; offset < seg->offset+seg->length; i++)
497 dump_msft_cdguid(i);
499 assert(offset == seg->offset+seg->length);
500 return -1;
503 static int dump_msft_res0e(seg_t *seg)
505 print_begin_block("res0e");
506 dump_binary(seg->length);
507 print_end_block();
509 return -1;
512 static int dump_msft_res0f(seg_t *seg)
514 print_begin_block("res0f");
515 dump_binary(seg->length);
516 print_end_block();
518 return -1;
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");
530 print_hex("flags");
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);
539 if(extra_attr)
540 print_hex("helpcontext");
541 if(extra_attr >= 2)
542 print_hex("oHelpString");
543 if(extra_attr >= 3)
544 print_hex("toEntry");
545 if(extra_attr >= 4)
546 print_hex("res9");
547 if(extra_attr >= 5)
548 print_hex("resA");
549 if(extra_attr >= 6)
550 print_hex("HelpStringContext");
551 if(extra_attr >= 7)
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]");
567 print_end_block();
570 print_end_block();
573 static void dump_msft_var(int n)
575 INT size;
577 print_begin_block_id("VarRecord", n);
579 size = print_hex("recsize")&0x1ff;
580 print_hex("DataType");
581 print_hex("flags");
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));
589 print_end_block();
592 static void dump_msft_ref(int n)
594 print_begin_block_id("RefRecord", n);
596 print_hex("reftype");
597 print_hex("flags");
598 print_hex("oCustData");
599 print_hex("onext");
601 print_end_block();
604 static void dump_msft_coclass(int n)
606 int i;
608 print_dec("size");
610 for(i=0; i < msft_typeinfo_impltypes[n]; i++)
611 dump_msft_ref(i);
614 static int dump_msft_typeinfo(int n)
616 int i;
618 print_begin_block_id("TypeInfo", n);
620 if((msft_typeinfo_kind[n] & 0xf) == TKIND_COCLASS) {
621 dump_msft_coclass(n);
622 print_end_block();
623 return -1;
626 print_dec("size");
628 for(i = 0; i < LOWORD(msft_typeinfo_elemcnt[n]); i++)
629 dump_msft_func(i);
631 for(i = 0; i < HIWORD(msft_typeinfo_elemcnt[n]); i++)
632 dump_msft_var(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);
652 print_end_block();
654 return -1;
657 seg_t segdir[] = {
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");
681 print_hex("res08");
682 print_hex("res0c");
684 print_end_block();
687 static void dump_msft_segdir(void)
689 int i;
691 print_begin_block("SegDir");
693 for(i=0; i < sizeof(segdir)/sizeof(segdir[0]); i++)
694 dump_msft_seg(segdir+i);
696 print_end_block();
699 static int dump_offset(void)
701 int i;
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);
711 return 0;
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;
720 void msft_dump(void)
722 int i;
724 dump_msft_header();
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");
731 print_offset();
732 printf("\n");
734 dump_msft_segdir();
736 while(!msft_eof) {
737 if(!dump_offset())
738 print_hex("unknown");