2 * typelib.h internal wine data structures
3 * used to decode typelib's
5 * Copyright 1999 Rein KLazes
8 #ifndef _WINE_TYPELIB_H
9 #define _WINE_TYPELIB_H
12 #include "wine/windef16.h"
14 #define TLBMAGIC2 "MSFT"
15 #define TLBMAGIC1 "SLTG"
16 #define HELPDLLFLAG (0x0100)
17 #define DO_NOT_SEEK (-1)
19 #define MSFT_HREFTYPE_INTHISFILE(href) (!((href) & 3))
20 #define MSFT_HREFTYPE_INDEX(href) ((href) /sizeof(MSFT_TypeInfoBase))
22 /*-------------------------FILE STRUCTURES-----------------------------------*/
24 /* There are two known file formats, those created with ICreateTypeLib
25 * have the signature "SLTG" as their first four bytes, while those created
26 * with ICreateTypeLib2 have "MSFT".
29 /*****************************************************
32 * These are TypeLibs created with ICreateTypeLib2
37 * structure of the typelib type2 header
38 * it is at the beginning of a type lib file
41 typedef struct tagMSFT_Header {
42 /*0x00*/INT magic1; /* 0x5446534D "MSFT" */
43 INT magic2; /* 0x00010002 version nr? */
44 INT posguid; /* position of libid in guid table */
45 /* (should be, else -1) */
46 INT lcid; /* locale id */
48 INT varflags; /* (largely) unknown flags ,seems to be always 41 */
49 /* becomes 0x51 with a helpfile defined */
50 /* if help dll defined it's 0x151 */
51 /* update : the lower nibble is syskind */
52 INT version; /* set with SetVersion() */
53 INT flags; /* set with SetFlags() */
54 /*0x20*/INT nrtypeinfos; /* number of typeinfo's (till so far) */
55 INT helpstring; /* position of help string in stringtable */
56 INT helpstringcontext;
58 /*0x30*/INT nametablecount; /* number of names in name table */
59 INT nametablechars; /* nr of characters in name table */
60 INT NameOffset; /* offset of name in name table */
61 INT helpfile; /* position of helpfile in stringtable */
62 /*0x40*/INT CustomDataOffset; /* if -1 no custom data, else it is offset */
63 /* in customer data/guid offset table */
64 INT res44; /* unknown always: 0x20 */
65 INT res48; /* unknown always: 0x80 */
66 INT dispatchpos; /* gets a value (1+n*0x0c) with Idispatch interfaces */
67 /*0x50*/INT res50; /* is zero becomes one when an interface is derived */
70 /* segments in the type lib file have a structure like this: */
71 typedef struct tagMSFT_pSeg {
72 INT offset; /* absolute offset in file */
73 INT length; /* length of segment */
74 INT res08; /* unknown always -1 */
75 INT res0c; /* unknown always 0x0f in the header */
76 /* 0x03 in the typeinfo_data */
79 /* layout of the main segment directory */
80 typedef struct tagMSFT_SegDir {
81 /*1*/MSFT_pSeg pTypeInfoTab; /* each type info get an entry of 0x64 bytes */
83 /*2*/MSFT_pSeg pImpInfo; /* table with info for imported types */
84 /*3*/MSFT_pSeg pImpFiles; /* import libaries */
85 /*4*/MSFT_pSeg pRefTab; /* References table */
86 /*5*/MSFT_pSeg pLibtab; /* always exists, alway same size (0x80) */
87 /* hash table w offsets to guid????? */
88 /*6*/MSFT_pSeg pGuidTab; /* all guids are stored here together with */
89 /* offset in some table???? */
90 /*7*/MSFT_pSeg res07; /* always created, alway same size (0x200) */
91 /* purpose largely unknown */
92 /*8*/MSFT_pSeg pNametab; /* name tables */
93 /*9*/MSFT_pSeg pStringtab; /* string table */
94 /*A*/MSFT_pSeg pTypdescTab; /* table with type descriptors */
95 /*B*/MSFT_pSeg pArrayDescriptions;
96 /*C*/MSFT_pSeg pCustData; /* data table, used for custom data and default */
97 /* parameter values */
98 /*D*/MSFT_pSeg pCDGuids; /* table with offsets for the guids and into */
99 /* the customer data table */
100 /*E*/MSFT_pSeg res0e; /* unknown */
101 /*F*/MSFT_pSeg res0f; /* unknown */
105 /* base type info data */
106 typedef struct tagMSFT_TypeInfoBase {
107 /*000*/ INT typekind; /* it is the TKIND_xxx */
108 /* some byte alignment stuf */
109 INT memoffset; /* points past the file, if no elements */
110 INT res2; /* zero if no element, N*0x40 */
111 INT res3; /* -1 if no lement, (N-1)*0x38 */
112 /*010*/ INT res4; /* always? 3 */
113 INT res5; /* always? zero */
114 INT cElement; /* counts elements, HI=cVars, LO=cFuncs */
115 INT res7; /* always? zero */
116 /*020*/ INT res8; /* always? zero */
117 INT res9; /* always? zero */
118 INT resA; /* always? zero */
119 INT posguid; /* position in guid table */
120 /*030*/ INT flags; /* Typeflags */
121 INT NameOffset; /* offset in name table */
122 INT version; /* element version */
123 INT docstringoffs; /* offset of docstring in string tab */
124 /*040*/ INT helpstringcontext; /* */
125 INT helpcontext; /* */
126 INT oCustData; /* offset in customer data table */
127 INT16 cImplTypes; /* nr of implemented interfaces */
128 INT16 cbSizeVft; /* virtual table size, not including inherits */
129 /*050*/ INT size; /* size in bytes, at least for structures */
130 /* fixme: name of this field */
131 INT datatype1; /* position in type description table */
132 /* or in base intefaces */
133 /* if coclass: offset in reftable */
134 /* if interface: reference to inherited if */
135 INT datatype2; /* if 0x8000, entry above is valid */
137 /* else it is zero? */
138 INT res18; /* always? 0 */
139 /*060*/ INT res19; /* always? -1 */
142 /* layout of an entry with information on imported types */
143 typedef struct tagMSFT_ImpInfo {
144 INT res0; /* unknown */
145 INT oImpFile; /* offset inthe Import File table */
146 INT oGuid; /* offset in Guid table */
149 /* function description data */
151 /* INT recsize; record size including some xtra stuff */
152 INT DataType; /* data type of the memeber, eg return of function */
153 INT Flags; /* something to do with attribute flags (LOWORD) */
154 INT16 VtableOffset; /* offset in vtable */
155 INT16 res3; /* some offset into dunno what */
156 INT FKCCIC; /* bit string with the following */
157 /* meaning (bit 0 is the msb): */
158 /* bit 2 indicates that oEntry is numeric */
159 /* bit 3 that parameter has default values */
160 /* calling convention (bits 4-7 ) */
161 /* bit 8 indicates that custom data is present */
162 /* Invokation kind (bits 9-12 ) */
163 /* function kind (eg virtual), bits 13-15 */
164 INT16 nrargs; /* number of arguments (including optional ????) */
165 INT16 nroargs; /* nr of optional arguments */
166 /* optional attribute fields, the number of them is variable */
171 2* INT oEntry; // either offset in string table or numeric as it is //
172 3* INT res9; // unknown (-1) //
173 4* INT resA; // unknown (-1) //
174 5* INT HelpStringContext;
175 // these are controlled by a bit set in the FKCCIC field //
176 6* INT oCustData; // custom data for function //
177 7* INT oArgCustData[1]; // custom data per argument //
181 /* after this may follow an array with default value pointers if the
182 * appropriate bit in the FKCCIC field has been set:
183 * INT oDefautlValue[nrargs];
186 /* Parameter info one per argument*/
191 } MSFT_ParameterInfo;
193 /* Variable description data */
195 /* INT recsize; // record size including some xtra stuff */
196 INT DataType; /* data type of the variable */
197 INT Flags; /* VarFlags (LOWORD) */
198 INT16 VarKind; /* VarKind */
199 INT16 res3; /* some offset into dunno what */
200 INT OffsValue; /* value of the variable or the offset */
201 /* in the data structure */
202 /* optional attribute fields, the number of them is variable */
203 /* controlled by record length */
206 INT res9; /* unknown (-1) */
207 INT oCustData; /* custom data for variable */
208 INT HelpStringContext;
212 /* Structure of the reference data */
214 INT reftype; /* either offset in type info table, then it's */
215 /* a multiple of 64 */
216 /* or offset in the external reference table */
217 /* with an offset of 1 */
219 INT oCustData; /* custom data */
220 INT onext; /* next offset, -1 if last */
223 /* this is how a guid is stored */
226 INT unk10; /* differntiate with libid, classid etc? */
227 /* it's -2 for a libary */
228 /* it's 0 for an interface */
229 INT unk14; /* always? -1 */
231 /* some data preceding entries in the name table */
233 INT unk00; /* sometimes -1 (lib, parameter) ,
234 sometimes 0 (interface, func) */
235 INT unk10; /* sometimes -1 (lib) , sometimes 0 (interface, func),
236 sometimes 0x10 (par) */
237 INT namelen; /* only lower 8 bits are valid */
239 /* the custom data table directory has enties like this */
243 INT next; /* next offset in the table, -1 if it's the last */
247 /***********************************************************
251 * These are created with ICreateTypeLib
255 #include "pshpack1.h"
258 /*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */
259 /*04*/ WORD nrOfFileBlks; /* no of SLTG_BlkEntry's + 1 */
260 /*06*/ WORD res06; /* ?? always 9 */
261 /*08*/ WORD res08; /* some kind of len/offset ?? */
262 /*0a*/ WORD first_blk; /* 1 based index into blk entries that
263 corresponds to first block in file */
264 /*0c*/ DWORD res0c; /* always 0x000204ff */
265 /*10*/ DWORD res10; /* always 0x00000000 */
266 /*14*/ DWORD res14; /* always 0x000000c0 */
267 /*18*/ DWORD res18; /* always 0x46000000 */
268 /*1c*/ DWORD res1c; /* always 0x00000044 */
269 /*20*/ DWORD res20; /* always 0xffff0000 */
272 /* This gets followed by a list of block entries */
275 /*04*/ WORD index_string; /* offs from start of SLTG_Magic to index string */
279 /* The order of the blocks in the file is given by starting at Block
280 entry firt_blk and stepping through using the next pointer */
282 /* These then get followed by this magic */
284 /*00*/ BYTE res00; /* always 0x01 */
285 /*01*/ CHAR CompObj_magic[8]; /* always "CompObj" */
286 /*09*/ CHAR dir_magic[4]; /* always "dir" */
289 #define SLTG_COMPOBJ_MAGIC "CompObj"
290 #define SLTG_DIR_MAGIC "dir"
292 /* Next we have SLTG_Header.nrOfFileBlks - 2 of Index strings. These
293 are persumbably unique to within the file and look something like
294 "AAAAAAAAAA" with the first character incremented from 'A' to ensure
295 uniqueness. I guess successive chars increment when we need to wrap
299 /*00*/ CHAR string[11];
303 /* This is followed by SLTG_pad9 */
305 /*00*/ CHAR pad[9]; /* 9 '\0's */
309 /* Now we have the noOfFileBlks - 1 worth of blocks. The length of
310 each block is given by its entry in SLTG_BlkEntry. */
312 /* type SLTG_NAME in rather like a BSTR except that the length in
313 bytes is given by the first WORD and the string contains 8bit chars */
315 typedef WORD SLTG_Name;
317 /* The main library block looks like this. This one seems to come last */
320 /*00*/ WORD magic; /* 0x51cc */
321 /*02*/ WORD res02; /* 0x0003, 0x0004 */
322 /*04*/ WORD name; /* offset to name in name table */
323 /*06*/ SLTG_Name res06; /* maybe this is just WORD == 0xffff */
324 SLTG_Name helpstring;
327 WORD syskind; /* == 1 for win32, 0 for win16 */
328 WORD lcid; /* == 0x409, 0x809 etc */
329 DWORD res12; /* == 0 */
330 WORD libflags; /* LIBFLAG_* */
336 #define SLTG_LIBBLK_MAGIC 0x51cc
338 /* we then get 0x40 bytes worth of 0xffff or small numbers followed by
339 nrOfFileBlks - 2 of these */
342 SLTG_Name index_name; /* This refers to a name in the directory */
343 SLTG_Name other_name; /* Another one of these weird names */
344 WORD res1a; /* 0xffff */
345 WORD name_offs; /* offset to name in name table */
346 WORD more_bytes; /* if this is non-zero we get this many
347 bytes before the next element, which seem
348 to reference the docstring of the type ? */
349 WORD res20; /* 0xffff */
351 WORD res26; /* 0xffff */
353 } SLTG_OtherTypeInfo;
355 /* Next we get WORD 0x0003 followed by a DWORD which if we add to
356 0x216 gives the offset to the name table from the start of the LibBlk
360 /*00*/ WORD magic; /* 0x0501 */
361 /*02*/ DWORD href_table; /* if not 0xffffffff, then byte offset from
362 beginning of struct to href table */
363 /*06*/ DWORD res06; /* 0xffffffff */
364 /*0a*/ DWORD elem_table; /* offset to members */
365 /*0e*/ DWORD res0e; /* 0xffffffff */
366 /*12*/ WORD major_version; /* major version number */
367 /*14*/ WORD minor_version; /* minor version number */
368 /*16*/ DWORD res16; /* 0xfffe0000 */
369 /*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */
370 /*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */
371 /*1c*/ BYTE typeflags3;/* 0x02*/
372 /*1d*/ BYTE typekind; /* 0x03 == TKIND_INTERFACE etc. */
373 /*1e*/ DWORD res1e; /* 0x00000000 or 0xffffffff */
374 } SLTG_TypeInfoHeader;
376 #define SLTG_TIHEADER_MAGIC 0x0501
381 /*04*/ WORD cImplTypes;
395 /*20*/ WORD cbSizeInstance;
396 /*22*/ WORD cbAlignment;
399 /*28*/ WORD cbSizeVft;
409 /*00*/ WORD res00; /* 0x0001 sometimes 0x0003 ?? */
410 /*02*/ WORD res02; /* 0xffff */
411 /*04*/ BYTE res04; /* 0x01 */
412 /*05*/ DWORD cbExtra; /* No of bytes that follow */
416 /*00*/ WORD magic; /* 0x120a */
417 /*02*/ WORD next; /* offset in bytes to next block from start of block
418 group, 0xffff if last item */
419 /*04*/ WORD name; /* offset to name within name table */
420 /*06*/ WORD value; /* offset to value from start of block group */
421 /*08*/ WORD res08; /* 0x56 */
422 /*0a*/ DWORD memid; /* memid */
423 /*0e*/ WORD helpcontext;/* 0xfffe == no context, 0x0001 == stored in EnumInfo struct, else offset
424 to value from start of block group */
425 /*10*/ WORD helpstring;/* offset from start of block group to string offset */
428 #define SLTG_ENUMITEM_MAGIC 0x120a
432 BYTE magic; /* 0x4c or 0x6c */
433 BYTE inv; /* high nibble is INVOKE_KIND, low nibble = 2 */
434 WORD next; /* byte offset from beginning of group to next fn */
435 WORD name; /* Offset within name table to name */
436 DWORD dispid; /* dispid */
437 WORD helpcontext; /* helpcontext (again 1 is special) */
438 WORD helpstring;/* helpstring offset to offset */
439 WORD arg_off; /* offset to args from start of block */
440 BYTE nacc; /* lowest 3bits are CALLCONV, rest are no of args */
441 BYTE retnextopt;/* if 0x80 bit set ret type follows else next WORD
442 is offset to ret type. No of optional args is
444 WORD rettype; /* return type VT_?? or offset to ret type */
445 WORD vtblpos; /* position in vtbl? */
446 WORD funcflags; /* present if magic == 0x6c */
447 /* Param list starts, repeat next two as required */
449 WORD name; /* offset to 2nd letter of name */
450 WORD+ type; /* VT_ of param */
454 #define SLTG_FUNCTION_MAGIC 0x4c
455 #define SLTG_FUNCTION_WITH_FLAGS_MAGIC 0x6c
458 /*00*/ BYTE magic; /* 0xdf */
459 /*01*/ BYTE res01; /* 0x00 */
460 /*02*/ DWORD res02; /* 0xffffffff */
461 /*06*/ DWORD res06; /* 0xffffffff */
462 /*0a*/ DWORD res0a; /* 0xffffffff */
463 /*0e*/ DWORD res0e; /* 0xffffffff */
464 /*12*/ DWORD res12; /* 0xffffffff */
465 /*16*/ DWORD res16; /* 0xffffffff */
466 /*1a*/ DWORD res1a; /* 0xffffffff */
467 /*1e*/ DWORD res1e; /* 0xffffffff */
468 /*22*/ DWORD res22; /* 0xffffffff */
469 /*26*/ DWORD res26; /* 0xffffffff */
470 /*2a*/ DWORD res2a; /* 0xffffffff */
471 /*2e*/ DWORD res2e; /* 0xffffffff */
472 /*32*/ DWORD res32; /* 0xffffffff */
473 /*36*/ DWORD res36; /* 0xffffffff */
474 /*3a*/ DWORD res3a; /* 0xffffffff */
475 /*3e*/ DWORD res3e; /* 0xffffffff */
476 /*42*/ WORD res42; /* 0xffff */
477 /*44*/ DWORD number; /* this is 8 times the number of refs */
478 /*48*/ /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */
480 /*50*/ WORD res50; /* 0xffff */
481 /*52*/ BYTE res52; /* 0x01 */
482 /*53*/ DWORD res53; /* 0x00000000 */
483 /*57*/ SLTG_Name names[1];
484 /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii
485 * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the
486 * ref refers to the nth type listed in this library (0 based). Else
487 * the xxxx (which maybe fewer than 4 digits) is the offset into the name
488 * table to a string "*\G{<guid>}#1.0#0#C:\WINNT\System32\stdole32.tlb#"
489 * The guid is the typelib guid; the ref again refers to the nth type of
490 * the imported typelib.
493 /*xx*/ BYTE resxx; /* 0xdf */
497 #define SLTG_REF_MAGIC 0xdf
500 WORD res00; /* 0x0001 */
501 BYTE res02; /* 0x02 */
502 BYTE res03; /* 0x40 if internal ref, 0x00 if external ? */
503 WORD res04; /* 0xffff */
504 WORD res06; /* 0x0000, 0x0013 or 0xffff ?? */
505 } SLTG_UnknownRefInfo;
508 WORD res00; /* 0x004a */
509 WORD next; /* byte offs to next interface */
510 WORD res04; /* 0xffff */
511 BYTE impltypeflags; /* IMPLTYPEFLAG_* */
512 BYTE res07; /* 0x80 */
513 WORD res08; /* 0x0012, 0x0028 ?? */
514 WORD ref; /* number in ref table ? */
515 WORD res0c; /* 0x4000 */
516 WORD res0e; /* 0xfffe */
517 WORD res10; /* 0xffff */
518 WORD res12; /* 0x001d */
519 WORD pos_in_table; /* 0x0, 0x4, ? */
522 #define SLTG_IMPL_MAGIC 0x004a
525 BYTE magic; /* 0x0a */
529 WORD byte_offs; /* pos in struct */
530 WORD type; /* if typepos == 0x02 this is the type, else offset to type */
532 WORD helpcontext; /* ?? */
533 WORD helpstring; /* ?? */
536 #define SLTG_RECORD_MAGIC 0x0a
539 /* CARRAYs look like this
540 WORD type == VT_CARRAY
541 WORD offset from start of block to SAFEARRAY
547 /*---------------------------END--------------------------------------------*/