/* * typelib.h internal wine data structures * used to decode typelib's * * Copyright 1999 Rein KLazes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _WINE_TYPELIB_H #define _WINE_TYPELIB_H #include "oleauto.h" #include "wine/windef16.h" #define TLBMAGIC2 "MSFT" #define TLBMAGIC1 "SLTG" #define HELPDLLFLAG (0x0100) #define DO_NOT_SEEK (-1) #define MSFT_HREFTYPE_INTHISFILE(href) (!((href) & 3)) #define MSFT_HREFTYPE_INDEX(href) ((href) /sizeof(MSFT_TypeInfoBase)) /*-------------------------FILE STRUCTURES-----------------------------------*/ /* There are two known file formats, those created with ICreateTypeLib * have the signature "SLTG" as their first four bytes, while those created * with ICreateTypeLib2 have "MSFT". */ /***************************************************** * MSFT typelibs * * These are TypeLibs created with ICreateTypeLib2 * */ /* * structure of the typelib type2 header * it is at the beginning of a type lib file * */ typedef struct tagMSFT_Header { /*0x00*/INT magic1; /* 0x5446534D "MSFT" */ INT magic2; /* 0x00010002 version nr? */ INT posguid; /* position of libid in guid table */ /* (should be, else -1) */ INT lcid; /* locale id */ /*0x10*/INT lcid2; INT varflags; /* (largely) unknown flags ,seems to be always 41 */ /* becomes 0x51 with a helpfile defined */ /* if help dll defined it's 0x151 */ /* update : the lower nibble is syskind */ INT version; /* set with SetVersion() */ INT flags; /* set with SetFlags() */ /*0x20*/INT nrtypeinfos; /* number of typeinfo's (till so far) */ INT helpstring; /* position of help string in stringtable */ INT helpstringcontext; INT helpcontext; /*0x30*/INT nametablecount; /* number of names in name table */ INT nametablechars; /* nr of characters in name table */ INT NameOffset; /* offset of name in name table */ INT helpfile; /* position of helpfile in stringtable */ /*0x40*/INT CustomDataOffset; /* if -1 no custom data, else it is offset */ /* in customer data/guid offset table */ INT res44; /* unknown always: 0x20 */ INT res48; /* unknown always: 0x80 */ INT dispatchpos; /* gets a value (1+n*0x0c) with Idispatch interfaces */ /*0x50*/INT res50; /* is zero becomes one when an interface is derived */ } MSFT_Header; /* segments in the type lib file have a structure like this: */ typedef struct tagMSFT_pSeg { INT offset; /* absolute offset in file */ INT length; /* length of segment */ INT res08; /* unknown always -1 */ INT res0c; /* unknown always 0x0f in the header */ /* 0x03 in the typeinfo_data */ } MSFT_pSeg; /* layout of the main segment directory */ typedef struct tagMSFT_SegDir { /*1*/MSFT_pSeg pTypeInfoTab; /* each type info get an entry of 0x64 bytes */ /* (25 ints) */ /*2*/MSFT_pSeg pImpInfo; /* table with info for imported types */ /*3*/MSFT_pSeg pImpFiles; /* import libaries */ /*4*/MSFT_pSeg pRefTab; /* References table */ /*5*/MSFT_pSeg pLibtab; /* always exists, alway same size (0x80) */ /* hash table w offsets to guid????? */ /*6*/MSFT_pSeg pGuidTab; /* all guids are stored here together with */ /* offset in some table???? */ /*7*/MSFT_pSeg res07; /* always created, alway same size (0x200) */ /* purpose largely unknown */ /*8*/MSFT_pSeg pNametab; /* name tables */ /*9*/MSFT_pSeg pStringtab; /* string table */ /*A*/MSFT_pSeg pTypdescTab; /* table with type descriptors */ /*B*/MSFT_pSeg pArrayDescriptions; /*C*/MSFT_pSeg pCustData; /* data table, used for custom data and default */ /* parameter values */ /*D*/MSFT_pSeg pCDGuids; /* table with offsets for the guids and into */ /* the customer data table */ /*E*/MSFT_pSeg res0e; /* unknown */ /*F*/MSFT_pSeg res0f; /* unknown */ } MSFT_SegDir; /* base type info data */ typedef struct tagMSFT_TypeInfoBase { /*000*/ INT typekind; /* it is the TKIND_xxx */ /* some byte alignment stuf */ INT memoffset; /* points past the file, if no elements */ INT res2; /* zero if no element, N*0x40 */ INT res3; /* -1 if no lement, (N-1)*0x38 */ /*010*/ INT res4; /* always? 3 */ INT res5; /* always? zero */ INT cElement; /* counts elements, HI=cVars, LO=cFuncs */ INT res7; /* always? zero */ /*020*/ INT res8; /* always? zero */ INT res9; /* always? zero */ INT resA; /* always? zero */ INT posguid; /* position in guid table */ /*030*/ INT flags; /* Typeflags */ INT NameOffset; /* offset in name table */ INT version; /* element version */ INT docstringoffs; /* offset of docstring in string tab */ /*040*/ INT helpstringcontext; /* */ INT helpcontext; /* */ INT oCustData; /* offset in customer data table */ INT16 cImplTypes; /* nr of implemented interfaces */ INT16 cbSizeVft; /* virtual table size, not including inherits */ /*050*/ INT size; /* size in bytes, at least for structures */ /* FIXME: name of this field */ INT datatype1; /* position in type description table */ /* or in base intefaces */ /* if coclass: offset in reftable */ /* if interface: reference to inherited if */ INT datatype2; /* if 0x8000, entry above is valid */ /* actually dunno */ /* else it is zero? */ INT res18; /* always? 0 */ /*060*/ INT res19; /* always? -1 */ } MSFT_TypeInfoBase; /* layout of an entry with information on imported types */ typedef struct tagMSFT_ImpInfo { INT res0; /* unknown */ INT oImpFile; /* offset inthe Import File table */ INT oGuid; /* offset in Guid table */ } MSFT_ImpInfo; /* function description data */ typedef struct { /* INT recsize; record size including some xtra stuff */ INT DataType; /* data type of the memeber, eg return of function */ INT Flags; /* something to do with attribute flags (LOWORD) */ INT16 VtableOffset; /* offset in vtable */ INT16 res3; /* some offset into dunno what */ INT FKCCIC; /* bit string with the following */ /* meaning (bit 0 is the msb): */ /* bit 2 indicates that oEntry is numeric */ /* bit 3 that parameter has default values */ /* calling convention (bits 4-7 ) */ /* bit 8 indicates that custom data is present */ /* Invokation kind (bits 9-12 ) */ /* function kind (eg virtual), bits 13-15 */ INT16 nrargs; /* number of arguments (including optional ????) */ INT16 nroargs; /* nr of optional arguments */ /* optional attribute fields, the number of them is variable */ INT OptAttr[1]; /* 0* INT helpcontext; 1* INT oHelpString; 2* INT oEntry; // either offset in string table or numeric as it is // 3* INT res9; // unknown (-1) // 4* INT resA; // unknown (-1) // 5* INT HelpStringContext; // these are controlled by a bit set in the FKCCIC field // 6* INT oCustData; // custom data for function // 7* INT oArgCustData[1]; // custom data per argument // */ } MSFT_FuncRecord; /* after this may follow an array with default value pointers if the * appropriate bit in the FKCCIC field has been set: * INT oDefautlValue[nrargs]; */ /* Parameter info one per argument*/ typedef struct { INT DataType; INT oName; INT Flags; } MSFT_ParameterInfo; /* Variable description data */ typedef struct { /* INT recsize; // record size including some xtra stuff */ INT DataType; /* data type of the variable */ INT Flags; /* VarFlags (LOWORD) */ INT16 VarKind; /* VarKind */ INT16 res3; /* some offset into dunno what */ INT OffsValue; /* value of the variable or the offset */ /* in the data structure */ /* optional attribute fields, the number of them is variable */ /* controlled by record length */ INT HelpContext; INT oHelpString; INT res9; /* unknown (-1) */ INT oCustData; /* custom data for variable */ INT HelpStringContext; } MSFT_VarRecord; /* Structure of the reference data */ typedef struct { INT reftype; /* either offset in type info table, then it's */ /* a multiple of 64 */ /* or offset in the external reference table */ /* with an offset of 1 */ INT flags; INT oCustData; /* custom data */ INT onext; /* next offset, -1 if last */ } MSFT_RefRecord; /* this is how a guid is stored */ typedef struct { GUID guid; INT unk10; /* differntiate with libid, classid etc? */ /* it's -2 for a libary */ /* it's 0 for an interface */ INT unk14; /* always? -1 */ } MSFT_GuidEntry; /* some data preceding entries in the name table */ typedef struct { INT unk00; /* sometimes -1 (lib, parameter) , sometimes 0 (interface, func) */ INT unk10; /* sometimes -1 (lib) , sometimes 0 (interface, func), sometimes 0x10 (par) */ INT namelen; /* only lower 8 bits are valid */ } MSFT_NameIntro; /* the custom data table directory has enties like this */ typedef struct { INT GuidOffset; INT DataOffset; INT next; /* next offset in the table, -1 if it's the last */ } MSFT_CDGuid; /*********************************************************** * * SLTG typelibs. * * These are created with ICreateTypeLib * */ #include "pshpack1.h" typedef struct { /*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */ /*04*/ WORD nrOfFileBlks; /* no of SLTG_BlkEntry's + 1 */ /*06*/ WORD res06; /* ?? always 9 */ /*08*/ WORD res08; /* some kind of len/offset ?? */ /*0a*/ WORD first_blk; /* 1 based index into blk entries that corresponds to first block in file */ /*0c*/ DWORD res0c; /* always 0x000204ff */ /*10*/ DWORD res10; /* always 0x00000000 */ /*14*/ DWORD res14; /* always 0x000000c0 */ /*18*/ DWORD res18; /* always 0x46000000 */ /*1c*/ DWORD res1c; /* always 0x00000044 */ /*20*/ DWORD res20; /* always 0xffff0000 */ } SLTG_Header; /* This gets followed by a list of block entries */ typedef struct { /*00*/ DWORD len; /*04*/ WORD index_string; /* offs from start of SLTG_Magic to index string */ /*06*/ WORD next; } SLTG_BlkEntry; /* The order of the blocks in the file is given by starting at Block entry firt_blk and stepping through using the next pointer */ /* These then get followed by this magic */ typedef struct { /*00*/ BYTE res00; /* always 0x01 */ /*01*/ CHAR CompObj_magic[8]; /* always "CompObj" */ /*09*/ CHAR dir_magic[4]; /* always "dir" */ } SLTG_Magic; #define SLTG_COMPOBJ_MAGIC "CompObj" #define SLTG_DIR_MAGIC "dir" /* Next we have SLTG_Header.nrOfFileBlks - 2 of Index strings. These are persumbably unique to within the file and look something like "AAAAAAAAAA" with the first character incremented from 'A' to ensure uniqueness. I guess successive chars increment when we need to wrap the first one. */ typedef struct { /*00*/ CHAR string[11]; } SLTG_Index; /* This is followed by SLTG_pad9 */ typedef struct { /*00*/ CHAR pad[9]; /* 9 '\0's */ } SLTG_Pad9; /* Now we have the noOfFileBlks - 1 worth of blocks. The length of each block is given by its entry in SLTG_BlkEntry. */ /* type SLTG_NAME in rather like a BSTR except that the length in bytes is given by the first WORD and the string contains 8bit chars */ typedef WORD SLTG_Name; /* The main library block looks like this. This one seems to come last */ typedef struct { /*00*/ WORD magic; /* 0x51cc */ /*02*/ WORD res02; /* 0x0003, 0x0004 */ /*04*/ WORD name; /* offset to name in name table */ /*06*/ SLTG_Name res06; /* maybe this is just WORD == 0xffff */ SLTG_Name helpstring; SLTG_Name helpfile; DWORD helpcontext; WORD syskind; /* == 1 for win32, 0 for win16 */ WORD lcid; /* == 0x409, 0x809 etc */ DWORD res12; /* == 0 */ WORD libflags; /* LIBFLAG_* */ WORD maj_vers; WORD min_vers; GUID uuid; } SLTG_LibBlk; #define SLTG_LIBBLK_MAGIC 0x51cc /* we then get 0x40 bytes worth of 0xffff or small numbers followed by nrOfFileBlks - 2 of these */ typedef struct { WORD small_no; SLTG_Name index_name; /* This refers to a name in the directory */ SLTG_Name other_name; /* Another one of these weird names */ WORD res1a; /* 0xffff */ WORD name_offs; /* offset to name in name table */ WORD more_bytes; /* if this is non-zero we get this many bytes before the next element, which seem to reference the docstring of the type ? */ WORD res20; /* 0xffff */ DWORD helpcontext; WORD res26; /* 0xffff */ GUID uuid; } SLTG_OtherTypeInfo; /* Next we get WORD 0x0003 followed by a DWORD which if we add to 0x216 gives the offset to the name table from the start of the LibBlk struct */ typedef struct { /*00*/ WORD magic; /* 0x0501 */ /*02*/ DWORD href_table; /* if not 0xffffffff, then byte offset from beginning of struct to href table */ /*06*/ DWORD res06; /* 0xffffffff */ /*0a*/ DWORD elem_table; /* offset to members */ /*0e*/ DWORD res0e; /* 0xffffffff */ /*12*/ WORD major_version; /* major version number */ /*14*/ WORD minor_version; /* minor version number */ /*16*/ DWORD res16; /* 0xfffe0000 */ /*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */ /*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */ /*1c*/ BYTE typeflags3;/* 0x02*/ /*1d*/ BYTE typekind; /* 0x03 == TKIND_INTERFACE etc. */ /*1e*/ DWORD res1e; /* 0x00000000 or 0xffffffff */ } SLTG_TypeInfoHeader; #define SLTG_TIHEADER_MAGIC 0x0501 typedef struct { /*00*/ WORD cFuncs; /*02*/ WORD cVars; /*04*/ WORD cImplTypes; /*06*/ WORD res06; /*08*/ WORD res08; /*0a*/ WORD res0a; /*0c*/ WORD res0c; /*0e*/ WORD res0e; /*10*/ WORD res10; /*12*/ WORD res12; /*14*/ WORD res14; /*16*/ WORD res16; /*18*/ WORD res18; /*1a*/ WORD res1a; /*1c*/ WORD res1c; /*1e*/ WORD res1e; /*20*/ WORD cbSizeInstance; /*22*/ WORD cbAlignment; /*24*/ WORD res24; /*26*/ WORD res26; /*28*/ WORD cbSizeVft; /*2a*/ WORD res2a; /*2c*/ WORD res2c; /*2e*/ WORD res2e; /*30*/ WORD res30; /*32*/ WORD res32; /*34*/ WORD res34; } SLTG_TypeInfoTail; typedef struct { /*00*/ WORD res00; /* 0x0001 sometimes 0x0003 ?? */ /*02*/ WORD res02; /* 0xffff */ /*04*/ BYTE res04; /* 0x01 */ /*05*/ DWORD cbExtra; /* No of bytes that follow */ } SLTG_MemberHeader; typedef struct { /*00*/ WORD magic; /* 0x120a */ /*02*/ WORD next; /* offset in bytes to next block from start of block group, 0xffff if last item */ /*04*/ WORD name; /* offset to name within name table */ /*06*/ WORD value; /* offset to value from start of block group */ /*08*/ WORD res08; /* 0x56 */ /*0a*/ DWORD memid; /* memid */ /*0e*/ WORD helpcontext;/* 0xfffe == no context, 0x0001 == stored in EnumInfo struct, else offset to value from start of block group */ /*10*/ WORD helpstring;/* offset from start of block group to string offset */ } SLTG_EnumItem; #define SLTG_ENUMITEM_MAGIC 0x120a typedef struct { BYTE magic; /* 0x4c or 0x6c */ BYTE inv; /* high nibble is INVOKE_KIND, low nibble = 2 */ WORD next; /* byte offset from beginning of group to next fn */ WORD name; /* Offset within name table to name */ DWORD dispid; /* dispid */ WORD helpcontext; /* helpcontext (again 1 is special) */ WORD helpstring;/* helpstring offset to offset */ WORD arg_off; /* offset to args from start of block */ BYTE nacc; /* lowest 3bits are CALLCONV, rest are no of args */ BYTE retnextopt;/* if 0x80 bit set ret type follows else next WORD is offset to ret type. No of optional args is middle 6 bits */ WORD rettype; /* return type VT_?? or offset to ret type */ WORD vtblpos; /* position in vtbl? */ WORD funcflags; /* present if magic == 0x6c */ /* Param list starts, repeat next two as required */ #if 0 WORD name; /* offset to 2nd letter of name */ WORD+ type; /* VT_ of param */ #endif } SLTG_Function; #define SLTG_FUNCTION_MAGIC 0x4c #define SLTG_FUNCTION_WITH_FLAGS_MAGIC 0x6c typedef struct { /*00*/ BYTE magic; /* 0xdf */ /*01*/ BYTE res01; /* 0x00 */ /*02*/ DWORD res02; /* 0xffffffff */ /*06*/ DWORD res06; /* 0xffffffff */ /*0a*/ DWORD res0a; /* 0xffffffff */ /*0e*/ DWORD res0e; /* 0xffffffff */ /*12*/ DWORD res12; /* 0xffffffff */ /*16*/ DWORD res16; /* 0xffffffff */ /*1a*/ DWORD res1a; /* 0xffffffff */ /*1e*/ DWORD res1e; /* 0xffffffff */ /*22*/ DWORD res22; /* 0xffffffff */ /*26*/ DWORD res26; /* 0xffffffff */ /*2a*/ DWORD res2a; /* 0xffffffff */ /*2e*/ DWORD res2e; /* 0xffffffff */ /*32*/ DWORD res32; /* 0xffffffff */ /*36*/ DWORD res36; /* 0xffffffff */ /*3a*/ DWORD res3a; /* 0xffffffff */ /*3e*/ DWORD res3e; /* 0xffffffff */ /*42*/ WORD res42; /* 0xffff */ /*44*/ DWORD number; /* this is 8 times the number of refs */ /*48*/ /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */ /*50*/ WORD res50; /* 0xffff */ /*52*/ BYTE res52; /* 0x01 */ /*53*/ DWORD res53; /* 0x00000000 */ /*57*/ SLTG_Name names[1]; /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the * ref refers to the nth type listed in this library (0 based). Else * the xxxx (which maybe fewer than 4 digits) is the offset into the name * table to a string "*\G{}#1.0#0#C:\WINNT\System32\stdole32.tlb#" * The guid is the typelib guid; the ref again refers to the nth type of * the imported typelib. */ /*xx*/ BYTE resxx; /* 0xdf */ } SLTG_RefInfo; #define SLTG_REF_MAGIC 0xdf typedef struct { WORD res00; /* 0x0001 */ BYTE res02; /* 0x02 */ BYTE res03; /* 0x40 if internal ref, 0x00 if external ? */ WORD res04; /* 0xffff */ WORD res06; /* 0x0000, 0x0013 or 0xffff ?? */ } SLTG_UnknownRefInfo; typedef struct { WORD res00; /* 0x004a */ WORD next; /* byte offs to next interface */ WORD res04; /* 0xffff */ BYTE impltypeflags; /* IMPLTYPEFLAG_* */ BYTE res07; /* 0x80 */ WORD res08; /* 0x0012, 0x0028 ?? */ WORD ref; /* number in ref table ? */ WORD res0c; /* 0x4000 */ WORD res0e; /* 0xfffe */ WORD res10; /* 0xffff */ WORD res12; /* 0x001d */ WORD pos_in_table; /* 0x0, 0x4, ? */ } SLTG_ImplInfo; #define SLTG_IMPL_MAGIC 0x004a typedef struct { BYTE magic; /* 0x0a */ BYTE typepos; WORD next; WORD name; WORD byte_offs; /* pos in struct */ WORD type; /* if typepos == 0x02 this is the type, else offset to type */ DWORD memid; WORD helpcontext; /* ?? */ WORD helpstring; /* ?? */ } SLTG_RecordItem; #define SLTG_RECORD_MAGIC 0x0a /* CARRAYs look like this WORD type == VT_CARRAY WORD offset from start of block to SAFEARRAY WORD typeofarray */ extern DWORD _invoke(LPVOID func,CALLCONV callconv, int nrargs, DWORD *args); #include "poppack.h" /*---------------------------END--------------------------------------------*/ #endif