write_msft.c 93 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845
  1. /*
  2. * Typelib v2 (MSFT) generation
  3. *
  4. * Copyright 2004 Alastair Bridgewater
  5. * 2004, 2005 Huw Davies
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  20. *
  21. * --------------------------------------------------------------------------------------
  22. * Known problems:
  23. *
  24. * Badly incomplete.
  25. *
  26. * Only works on little-endian systems.
  27. *
  28. */
  29. #include "config.h"
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <stdarg.h>
  33. #include <stdio.h>
  34. #include <ctype.h>
  35. #include <time.h>
  36. #define NONAMELESSUNION
  37. #include "widl.h"
  38. #include "winerror.h"
  39. #include "windef.h"
  40. #include "winbase.h"
  41. #include "winnls.h"
  42. #include "typelib.h"
  43. #include "typelib_struct.h"
  44. #include "utils.h"
  45. #include "header.h"
  46. #include "hash.h"
  47. #include "typetree.h"
  48. #include "parser.h"
  49. #include "typegen.h"
  50. enum MSFT_segment_index {
  51. MSFT_SEG_TYPEINFO = 0, /* type information */
  52. MSFT_SEG_IMPORTINFO, /* import information */
  53. MSFT_SEG_IMPORTFILES, /* import filenames */
  54. MSFT_SEG_REFERENCES, /* references (?) */
  55. MSFT_SEG_GUIDHASH, /* hash table for guids? */
  56. MSFT_SEG_GUID, /* guid storage */
  57. MSFT_SEG_NAMEHASH, /* hash table for names */
  58. MSFT_SEG_NAME, /* name storage */
  59. MSFT_SEG_STRING, /* string storage */
  60. MSFT_SEG_TYPEDESC, /* type descriptions */
  61. MSFT_SEG_ARRAYDESC, /* array descriptions */
  62. MSFT_SEG_CUSTDATA, /* custom data */
  63. MSFT_SEG_CUSTDATAGUID, /* custom data guids */
  64. MSFT_SEG_UNKNOWN, /* ??? */
  65. MSFT_SEG_UNKNOWN2, /* ??? */
  66. MSFT_SEG_MAX /* total number of segments */
  67. };
  68. typedef struct tagMSFT_ImpFile {
  69. int guid;
  70. LCID lcid;
  71. int version;
  72. char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */
  73. } MSFT_ImpFile;
  74. typedef struct _msft_typelib_t
  75. {
  76. typelib_t *typelib;
  77. MSFT_Header typelib_header;
  78. MSFT_pSeg typelib_segdir[MSFT_SEG_MAX];
  79. unsigned char *typelib_segment_data[MSFT_SEG_MAX];
  80. int typelib_segment_block_length[MSFT_SEG_MAX];
  81. INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */
  82. INT *typelib_namehash_segment;
  83. INT *typelib_guidhash_segment;
  84. INT help_string_dll_offset;
  85. struct _msft_typeinfo_t *typeinfos;
  86. struct _msft_typeinfo_t *last_typeinfo;
  87. } msft_typelib_t;
  88. typedef struct _msft_typeinfo_t
  89. {
  90. msft_typelib_t *typelib;
  91. MSFT_TypeInfoBase *typeinfo;
  92. int typekind;
  93. unsigned int var_data_allocated;
  94. int *var_data;
  95. unsigned int func_data_allocated;
  96. int *func_data;
  97. int vars_allocated;
  98. int *var_indices;
  99. int *var_names;
  100. int *var_offsets;
  101. int funcs_allocated;
  102. int *func_indices;
  103. int *func_names;
  104. int *func_offsets;
  105. int datawidth;
  106. struct _msft_typeinfo_t *next_typeinfo;
  107. } msft_typeinfo_t;
  108. /*================== Internal functions ===================================*/
  109. /****************************************************************************
  110. * ctl2_init_header
  111. *
  112. * Initializes the type library header of a new typelib.
  113. */
  114. static void ctl2_init_header(
  115. msft_typelib_t *typelib) /* [I] The typelib to initialize. */
  116. {
  117. typelib->typelib_header.magic1 = 0x5446534d;
  118. typelib->typelib_header.magic2 = 0x00010002;
  119. typelib->typelib_header.posguid = -1;
  120. typelib->typelib_header.lcid = 0x0409;
  121. typelib->typelib_header.lcid2 = 0x0;
  122. typelib->typelib_header.varflags = 0x40;
  123. typelib->typelib_header.version = 0;
  124. typelib->typelib_header.flags = 0;
  125. typelib->typelib_header.nrtypeinfos = 0;
  126. typelib->typelib_header.helpstring = -1;
  127. typelib->typelib_header.helpstringcontext = 0;
  128. typelib->typelib_header.helpcontext = 0;
  129. typelib->typelib_header.nametablecount = 0;
  130. typelib->typelib_header.nametablechars = 0;
  131. typelib->typelib_header.NameOffset = -1;
  132. typelib->typelib_header.helpfile = -1;
  133. typelib->typelib_header.CustomDataOffset = -1;
  134. typelib->typelib_header.res44 = 0x20;
  135. typelib->typelib_header.res48 = 0x80;
  136. typelib->typelib_header.dispatchpos = -1;
  137. typelib->typelib_header.nimpinfos = 0;
  138. }
  139. /****************************************************************************
  140. * ctl2_init_segdir
  141. *
  142. * Initializes the segment directory of a new typelib.
  143. */
  144. static void ctl2_init_segdir(
  145. msft_typelib_t *typelib) /* [I] The typelib to initialize. */
  146. {
  147. int i;
  148. MSFT_pSeg *segdir;
  149. segdir = &typelib->typelib_segdir[MSFT_SEG_TYPEINFO];
  150. for (i = 0; i < MSFT_SEG_MAX; i++) {
  151. segdir[i].offset = -1;
  152. segdir[i].length = 0;
  153. segdir[i].res08 = -1;
  154. segdir[i].res0c = 0x0f;
  155. }
  156. }
  157. /****************************************************************************
  158. * ctl2_hash_guid
  159. *
  160. * Generates a hash key from a GUID.
  161. *
  162. * RETURNS
  163. *
  164. * The hash key for the GUID.
  165. */
  166. static int ctl2_hash_guid(
  167. REFGUID guid) /* [I] The guid to hash. */
  168. {
  169. int hash;
  170. int i;
  171. hash = 0;
  172. for (i = 0; i < 8; i ++) {
  173. hash ^= ((const short *)guid)[i];
  174. }
  175. return hash & 0x1f;
  176. }
  177. /****************************************************************************
  178. * ctl2_find_guid
  179. *
  180. * Locates a guid in a type library.
  181. *
  182. * RETURNS
  183. *
  184. * The offset into the GUID segment of the guid, or -1 if not found.
  185. */
  186. static int ctl2_find_guid(
  187. msft_typelib_t *typelib, /* [I] The typelib to operate against. */
  188. int hash_key, /* [I] The hash key for the guid. */
  189. REFGUID guid) /* [I] The guid to find. */
  190. {
  191. int offset;
  192. MSFT_GuidEntry *guidentry;
  193. offset = typelib->typelib_guidhash_segment[hash_key];
  194. while (offset != -1) {
  195. guidentry = (MSFT_GuidEntry *)&typelib->typelib_segment_data[MSFT_SEG_GUID][offset];
  196. if (!memcmp(guidentry, guid, sizeof(GUID))) return offset;
  197. offset = guidentry->next_hash;
  198. }
  199. return offset;
  200. }
  201. /****************************************************************************
  202. * ctl2_find_name
  203. *
  204. * Locates a name in a type library.
  205. *
  206. * RETURNS
  207. *
  208. * The offset into the NAME segment of the name, or -1 if not found.
  209. *
  210. * NOTES
  211. *
  212. * The name must be encoded as with ctl2_encode_name().
  213. */
  214. static int ctl2_find_name(
  215. msft_typelib_t *typelib, /* [I] The typelib to operate against. */
  216. char *name) /* [I] The encoded name to find. */
  217. {
  218. int offset;
  219. int *namestruct;
  220. offset = typelib->typelib_namehash_segment[name[2] & 0x7f];
  221. while (offset != -1) {
  222. namestruct = (int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][offset];
  223. if (!((namestruct[2] ^ *((int *)name)) & 0xffff00ff)) {
  224. /* hash codes and lengths match, final test */
  225. if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break;
  226. }
  227. /* move to next item in hash bucket */
  228. offset = namestruct[1];
  229. }
  230. return offset;
  231. }
  232. /****************************************************************************
  233. * ctl2_encode_name
  234. *
  235. * Encodes a name string to a form suitable for storing into a type library
  236. * or comparing to a name stored in a type library.
  237. *
  238. * RETURNS
  239. *
  240. * The length of the encoded name, including padding and length+hash fields.
  241. *
  242. * NOTES
  243. *
  244. * Will throw an exception if name or result are NULL. Is not multithread
  245. * safe in the slightest.
  246. */
  247. static int ctl2_encode_name(
  248. msft_typelib_t *typelib, /* [I] The typelib to operate against (used for LCID only). */
  249. const char *name, /* [I] The name string to encode. */
  250. char **result) /* [O] A pointer to a pointer to receive the encoded name. */
  251. {
  252. char *converted_name;
  253. size_t length, size;
  254. int offset;
  255. int value;
  256. length = strlen(name);
  257. size = (length + 7) & ~3;
  258. converted_name = xmalloc(size + 1);
  259. memcpy(converted_name + 4, name, length);
  260. converted_name[length + 4] = 0;
  261. value = lhash_val_of_name_sys(typelib->typelib_header.varflags & 0x0f, typelib->typelib_header.lcid, converted_name + 4);
  262. converted_name[0] = length & 0xff;
  263. converted_name[1] = length >> 8;
  264. converted_name[2] = value;
  265. converted_name[3] = value >> 8;
  266. for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57;
  267. *result = converted_name;
  268. return size;
  269. }
  270. /****************************************************************************
  271. * ctl2_encode_string
  272. *
  273. * Encodes a string to a form suitable for storing into a type library or
  274. * comparing to a string stored in a type library.
  275. *
  276. * RETURNS
  277. *
  278. * The length of the encoded string, including padding and length fields.
  279. *
  280. * NOTES
  281. *
  282. * Will throw an exception if string or result are NULL. Is not multithread
  283. * safe in the slightest.
  284. */
  285. static int ctl2_encode_string(
  286. const char *string, /* [I] The string to encode. */
  287. char **result) /* [O] A pointer to a pointer to receive the encoded string. */
  288. {
  289. char *converted_string;
  290. size_t length, size;
  291. int offset;
  292. length = strlen(string);
  293. size = (length + 5) & ~3;
  294. if (length < 3) size += 4;
  295. converted_string = xmalloc(size);
  296. memcpy(converted_string + 2, string, length);
  297. converted_string[0] = length & 0xff;
  298. converted_string[1] = (length >> 8) & 0xff;
  299. if(length < 3) { /* strings of this length are padded with up to 8 bytes incl the 2 byte length */
  300. for(offset = 0; offset < 4; offset++)
  301. converted_string[length + offset + 2] = 0x57;
  302. length += 4;
  303. }
  304. for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57;
  305. *result = converted_string;
  306. return size;
  307. }
  308. /****************************************************************************
  309. * ctl2_alloc_segment
  310. *
  311. * Allocates memory from a segment in a type library.
  312. *
  313. * RETURNS
  314. *
  315. * Success: The offset within the segment of the new data area.
  316. *
  317. * BUGS
  318. *
  319. * Does not (yet) handle the case where the allocated segment memory needs to grow.
  320. */
  321. static int ctl2_alloc_segment(
  322. msft_typelib_t *typelib, /* [I] The type library in which to allocate. */
  323. enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */
  324. int size, /* [I] The amount to allocate. */
  325. int block_size) /* [I] Initial allocation block size, or 0 for default. */
  326. {
  327. int offset;
  328. if(!typelib->typelib_segment_data[segment]) {
  329. if (!block_size) block_size = 0x2000;
  330. typelib->typelib_segment_block_length[segment] = block_size;
  331. typelib->typelib_segment_data[segment] = xmalloc(block_size);
  332. if (!typelib->typelib_segment_data[segment]) return -1;
  333. memset(typelib->typelib_segment_data[segment], 0x57, block_size);
  334. }
  335. while ((typelib->typelib_segdir[segment].length + size) > typelib->typelib_segment_block_length[segment]) {
  336. unsigned char *block;
  337. block_size = typelib->typelib_segment_block_length[segment];
  338. block = xrealloc(typelib->typelib_segment_data[segment], block_size << 1);
  339. if (segment == MSFT_SEG_TYPEINFO) {
  340. /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */
  341. msft_typeinfo_t *typeinfo;
  342. for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
  343. typeinfo->typeinfo = (void *)&block[((unsigned char *)typeinfo->typeinfo) - typelib->typelib_segment_data[segment]];
  344. }
  345. }
  346. memset(block + block_size, 0x57, block_size);
  347. typelib->typelib_segment_block_length[segment] = block_size << 1;
  348. typelib->typelib_segment_data[segment] = block;
  349. }
  350. offset = typelib->typelib_segdir[segment].length;
  351. typelib->typelib_segdir[segment].length += size;
  352. return offset;
  353. }
  354. /****************************************************************************
  355. * ctl2_alloc_typeinfo
  356. *
  357. * Allocates and initializes a typeinfo structure in a type library.
  358. *
  359. * RETURNS
  360. *
  361. * Success: The offset of the new typeinfo.
  362. * Failure: -1 (this is invariably an out of memory condition).
  363. */
  364. static int ctl2_alloc_typeinfo(
  365. msft_typelib_t *typelib, /* [I] The type library to allocate in. */
  366. int nameoffset) /* [I] The offset of the name for this typeinfo. */
  367. {
  368. int offset;
  369. MSFT_TypeInfoBase *typeinfo;
  370. offset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0);
  371. typelib->typelib_typeinfo_offsets[typelib->typelib_header.nrtypeinfos++] = offset;
  372. typeinfo = (void *)(typelib->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset);
  373. typeinfo->typekind = (typelib->typelib_header.nrtypeinfos - 1) << 16;
  374. typeinfo->memoffset = -1; /* should be EOF if no elements */
  375. typeinfo->res2 = 0;
  376. typeinfo->res3 = -1;
  377. typeinfo->res4 = 3;
  378. typeinfo->res5 = 0;
  379. typeinfo->cElement = 0;
  380. typeinfo->res7 = 0;
  381. typeinfo->res8 = 0;
  382. typeinfo->res9 = 0;
  383. typeinfo->resA = 0;
  384. typeinfo->posguid = -1;
  385. typeinfo->flags = 0;
  386. typeinfo->NameOffset = nameoffset;
  387. typeinfo->version = 0;
  388. typeinfo->docstringoffs = -1;
  389. typeinfo->helpstringcontext = 0;
  390. typeinfo->helpcontext = 0;
  391. typeinfo->oCustData = -1;
  392. typeinfo->cbSizeVft = 0;
  393. typeinfo->cImplTypes = 0;
  394. typeinfo->size = 0;
  395. typeinfo->datatype1 = -1;
  396. typeinfo->datatype2 = 0;
  397. typeinfo->res18 = 0;
  398. typeinfo->res19 = -1;
  399. return offset;
  400. }
  401. /****************************************************************************
  402. * ctl2_alloc_guid
  403. *
  404. * Allocates and initializes a GUID structure in a type library. Also updates
  405. * the GUID hash table as needed.
  406. *
  407. * RETURNS
  408. *
  409. * Success: The offset of the new GUID.
  410. */
  411. static int ctl2_alloc_guid(
  412. msft_typelib_t *typelib, /* [I] The type library to allocate in. */
  413. MSFT_GuidEntry *guid) /* [I] The GUID to store. */
  414. {
  415. int offset;
  416. MSFT_GuidEntry *guid_space;
  417. int hash_key;
  418. chat("adding uuid {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
  419. guid->guid.Data1, guid->guid.Data2, guid->guid.Data3,
  420. guid->guid.Data4[0], guid->guid.Data4[1], guid->guid.Data4[2], guid->guid.Data4[3],
  421. guid->guid.Data4[4], guid->guid.Data4[5], guid->guid.Data4[6], guid->guid.Data4[7]);
  422. hash_key = ctl2_hash_guid(&guid->guid);
  423. offset = ctl2_find_guid(typelib, hash_key, &guid->guid);
  424. if (offset != -1)
  425. {
  426. if (is_warning_enabled(2368))
  427. warning("duplicate uuid {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
  428. guid->guid.Data1, guid->guid.Data2, guid->guid.Data3,
  429. guid->guid.Data4[0], guid->guid.Data4[1], guid->guid.Data4[2], guid->guid.Data4[3],
  430. guid->guid.Data4[4], guid->guid.Data4[5], guid->guid.Data4[6], guid->guid.Data4[7]);
  431. return -1;
  432. }
  433. offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0);
  434. guid_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_GUID] + offset);
  435. *guid_space = *guid;
  436. guid_space->next_hash = typelib->typelib_guidhash_segment[hash_key];
  437. typelib->typelib_guidhash_segment[hash_key] = offset;
  438. return offset;
  439. }
  440. /****************************************************************************
  441. * ctl2_alloc_name
  442. *
  443. * Allocates and initializes a name within a type library. Also updates the
  444. * name hash table as needed.
  445. *
  446. * RETURNS
  447. *
  448. * Success: The offset within the segment of the new name.
  449. * Failure: -1 (this is invariably an out of memory condition).
  450. */
  451. static int ctl2_alloc_name(
  452. msft_typelib_t *typelib, /* [I] The type library to allocate in. */
  453. const char *name) /* [I] The name to store. */
  454. {
  455. int length;
  456. int offset;
  457. MSFT_NameIntro *name_space;
  458. char *encoded_name;
  459. length = ctl2_encode_name(typelib, name, &encoded_name);
  460. offset = ctl2_find_name(typelib, encoded_name);
  461. if (offset != -1)
  462. {
  463. free(encoded_name);
  464. return offset;
  465. }
  466. offset = ctl2_alloc_segment(typelib, MSFT_SEG_NAME, length + 8, 0);
  467. name_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_NAME] + offset);
  468. name_space->hreftype = -1;
  469. name_space->next_hash = -1;
  470. memcpy(&name_space->namelen, encoded_name, length);
  471. if (typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1)
  472. name_space->next_hash = typelib->typelib_namehash_segment[encoded_name[2] & 0x7f];
  473. typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset;
  474. typelib->typelib_header.nametablecount += 1;
  475. typelib->typelib_header.nametablechars += *encoded_name;
  476. free(encoded_name);
  477. return offset;
  478. }
  479. /****************************************************************************
  480. * ctl2_alloc_string
  481. *
  482. * Allocates and initializes a string in a type library.
  483. *
  484. * RETURNS
  485. *
  486. * Success: The offset within the segment of the new string.
  487. * Failure: -1 (this is invariably an out of memory condition).
  488. */
  489. static int ctl2_alloc_string(
  490. msft_typelib_t *typelib, /* [I] The type library to allocate in. */
  491. const char *string) /* [I] The string to store. */
  492. {
  493. int length;
  494. int offset;
  495. unsigned char *string_space;
  496. char *encoded_string;
  497. length = ctl2_encode_string(string, &encoded_string);
  498. for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_STRING].length;
  499. offset += (((typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) |
  500. typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 0]) + 5) & ~3) {
  501. if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset;
  502. }
  503. offset = ctl2_alloc_segment(typelib, MSFT_SEG_STRING, length, 0);
  504. string_space = typelib->typelib_segment_data[MSFT_SEG_STRING] + offset;
  505. memcpy(string_space, encoded_string, length);
  506. free(encoded_string);
  507. return offset;
  508. }
  509. /****************************************************************************
  510. * alloc_msft_importinfo
  511. *
  512. * Allocates and initializes an import information structure in a type library.
  513. *
  514. * RETURNS
  515. *
  516. * Success: The offset of the new importinfo.
  517. * Failure: -1 (this is invariably an out of memory condition).
  518. */
  519. static int alloc_msft_importinfo(
  520. msft_typelib_t *typelib, /* [I] The type library to allocate in. */
  521. MSFT_ImpInfo *impinfo) /* [I] The import information to store. */
  522. {
  523. int offset;
  524. MSFT_ImpInfo *impinfo_space;
  525. for (offset = 0;
  526. offset < typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
  527. offset += sizeof(MSFT_ImpInfo)) {
  528. if (!memcmp(&(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]),
  529. impinfo, sizeof(MSFT_ImpInfo))) {
  530. return offset;
  531. }
  532. }
  533. impinfo->flags |= typelib->typelib_header.nimpinfos++;
  534. offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0);
  535. impinfo_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset);
  536. *impinfo_space = *impinfo;
  537. return offset;
  538. }
  539. /****************************************************************************
  540. * alloc_importfile
  541. *
  542. * Allocates and initializes an import file definition in a type library.
  543. *
  544. * RETURNS
  545. *
  546. * Success: The offset of the new importinfo.
  547. * Failure: -1 (this is invariably an out of memory condition).
  548. */
  549. static int alloc_importfile(
  550. msft_typelib_t *typelib, /* [I] The type library to allocate in. */
  551. int guidoffset, /* [I] The offset to the GUID for the imported library. */
  552. int major_version, /* [I] The major version number of the imported library. */
  553. int minor_version, /* [I] The minor version number of the imported library. */
  554. const char *filename) /* [I] The filename of the imported library. */
  555. {
  556. int length;
  557. int offset;
  558. MSFT_ImpFile *importfile;
  559. char *encoded_string;
  560. length = ctl2_encode_string(filename, &encoded_string);
  561. encoded_string[0] <<= 2;
  562. encoded_string[0] |= 1;
  563. for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length;
  564. offset += (((typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) |
  565. typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc]) >> 2) + 0xc) {
  566. if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset;
  567. }
  568. offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTFILES, length + 0xc, 0);
  569. importfile = (MSFT_ImpFile *)&typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset];
  570. importfile->guid = guidoffset;
  571. importfile->lcid = typelib->typelib_header.lcid2;
  572. importfile->version = major_version | (minor_version << 16);
  573. memcpy(&importfile->filename, encoded_string, length);
  574. free(encoded_string);
  575. return offset;
  576. }
  577. static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo)
  578. {
  579. importlib_t *importlib = importinfo->importlib;
  580. chat("alloc_importinfo: %s\n", importinfo->name);
  581. if(!importlib->allocated) {
  582. MSFT_GuidEntry guid;
  583. int guid_idx;
  584. chat("allocating importlib %s\n", importlib->name);
  585. importlib->allocated = -1;
  586. memcpy(&guid.guid, &importlib->guid, sizeof(GUID));
  587. guid.hreftype = 2;
  588. guid_idx = ctl2_alloc_guid(typelib, &guid);
  589. importlib->offset = alloc_importfile(typelib, guid_idx, importlib->version & 0xffff,
  590. importlib->version >> 16, importlib->name);
  591. }
  592. if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) {
  593. MSFT_ImpInfo impinfo;
  594. impinfo.flags = importinfo->flags;
  595. impinfo.oImpFile = importlib->offset;
  596. if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
  597. MSFT_GuidEntry guid;
  598. guid.hreftype = 0;
  599. memcpy(&guid.guid, &importinfo->guid, sizeof(GUID));
  600. impinfo.oGuid = ctl2_alloc_guid(typelib, &guid);
  601. importinfo->offset = alloc_msft_importinfo(typelib, &impinfo);
  602. typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo.oGuid+sizeof(GUID)]
  603. = importinfo->offset+1;
  604. if(!strcmp(importinfo->name, "IDispatch"))
  605. typelib->typelib_header.dispatchpos = importinfo->offset+1;
  606. }else {
  607. impinfo.oGuid = importinfo->id;
  608. importinfo->offset = alloc_msft_importinfo(typelib, &impinfo);
  609. }
  610. }
  611. }
  612. static importinfo_t *find_importinfo(msft_typelib_t *typelib, const char *name)
  613. {
  614. importlib_t *importlib;
  615. int i;
  616. chat("search importlib %s\n", name);
  617. if(!name)
  618. return NULL;
  619. LIST_FOR_EACH_ENTRY( importlib, &typelib->typelib->importlibs, importlib_t, entry )
  620. {
  621. for(i=0; i < importlib->ntypeinfos; i++) {
  622. if(!strcmp(name, importlib->importinfos[i].name)) {
  623. chat("Found %s in importlib.\n", name);
  624. return importlib->importinfos+i;
  625. }
  626. }
  627. }
  628. return NULL;
  629. }
  630. static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure);
  631. static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface);
  632. static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration);
  633. static void add_union_typeinfo(msft_typelib_t *typelib, type_t *tunion);
  634. static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls);
  635. static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface);
  636. static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *dispinterface);
  637. /****************************************************************************
  638. * encode_type
  639. *
  640. * Encodes a type, storing information in the TYPEDESC and ARRAYDESC
  641. * segments as needed.
  642. *
  643. * RETURNS
  644. *
  645. * Success: 0.
  646. * Failure: -1.
  647. */
  648. static int encode_type(
  649. msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */
  650. int vt, /* [I] vt to encode */
  651. type_t *type, /* [I] type */
  652. int *encoded_type, /* [O] The encoded type description. */
  653. int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
  654. {
  655. int default_type;
  656. int scratch;
  657. int typeoffset;
  658. int *typedata;
  659. int target_type;
  660. int child_size = 0;
  661. chat("encode_type vt %d type %p\n", vt, type);
  662. default_type = 0x80000000 | (vt << 16) | vt;
  663. if (!decoded_size) decoded_size = &scratch;
  664. *decoded_size = 0;
  665. switch (vt) {
  666. case VT_I1:
  667. case VT_UI1:
  668. *encoded_type = default_type;
  669. break;
  670. case VT_INT:
  671. *encoded_type = 0x80000000 | (VT_I4 << 16) | VT_INT;
  672. break;
  673. case VT_UINT:
  674. *encoded_type = 0x80000000 | (VT_UI4 << 16) | VT_UINT;
  675. break;
  676. case VT_UI2:
  677. case VT_I2:
  678. case VT_BOOL:
  679. *encoded_type = default_type;
  680. break;
  681. case VT_I4:
  682. case VT_UI4:
  683. case VT_R4:
  684. case VT_ERROR:
  685. case VT_HRESULT:
  686. *encoded_type = default_type;
  687. break;
  688. case VT_R8:
  689. case VT_I8:
  690. case VT_UI8:
  691. *encoded_type = default_type;
  692. break;
  693. case VT_CY:
  694. case VT_DATE:
  695. *encoded_type = default_type;
  696. break;
  697. case VT_DECIMAL:
  698. *encoded_type = default_type;
  699. break;
  700. case VT_VOID:
  701. *encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt;
  702. break;
  703. case VT_UNKNOWN:
  704. case VT_DISPATCH:
  705. case VT_BSTR:
  706. *encoded_type = default_type;
  707. break;
  708. case VT_VARIANT:
  709. *encoded_type = default_type;
  710. break;
  711. case VT_LPSTR:
  712. case VT_LPWSTR:
  713. *encoded_type = 0xfffe0000 | vt;
  714. break;
  715. case VT_PTR:
  716. {
  717. int next_vt;
  718. for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref_type(type)) {
  719. next_vt = get_type_vt(type_pointer_get_ref_type(type));
  720. if (next_vt != 0)
  721. break;
  722. }
  723. /* if no type found then it must be void */
  724. if (next_vt == 0)
  725. next_vt = VT_VOID;
  726. encode_type(typelib, next_vt, type_pointer_get_ref_type(type),
  727. &target_type, &child_size);
  728. /* these types already have an implicit pointer, so we don't need to
  729. * add another */
  730. if(next_vt == VT_DISPATCH || next_vt == VT_UNKNOWN) {
  731. chat("encode_type: skipping ptr\n");
  732. *encoded_type = target_type;
  733. *decoded_size = child_size;
  734. break;
  735. }
  736. for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
  737. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  738. if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break;
  739. }
  740. if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
  741. int mix_field;
  742. if (target_type & 0x80000000) {
  743. mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
  744. } else {
  745. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
  746. mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe;
  747. }
  748. typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
  749. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  750. typedata[0] = (mix_field << 16) | VT_PTR;
  751. typedata[1] = target_type;
  752. }
  753. *encoded_type = typeoffset;
  754. *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
  755. break;
  756. }
  757. case VT_SAFEARRAY:
  758. {
  759. type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(type));
  760. int next_vt = get_type_vt(element_type);
  761. encode_type(typelib, next_vt, type_alias_get_aliasee_type(type_array_get_element_type(type)),
  762. &target_type, &child_size);
  763. for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
  764. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  765. if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break;
  766. }
  767. if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
  768. int mix_field;
  769. if (target_type & 0x80000000) {
  770. mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY;
  771. } else {
  772. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
  773. mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe;
  774. }
  775. typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
  776. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  777. typedata[0] = (mix_field << 16) | VT_SAFEARRAY;
  778. typedata[1] = target_type;
  779. }
  780. *encoded_type = typeoffset;
  781. *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
  782. break;
  783. }
  784. case VT_USERDEFINED:
  785. {
  786. importinfo_t *importinfo;
  787. int typeinfo_offset;
  788. if (type->typelib_idx > -1)
  789. {
  790. chat("encode_type: VT_USERDEFINED - found already defined type %s at %d\n",
  791. type->name, type->typelib_idx);
  792. typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
  793. }
  794. else if ((importinfo = find_importinfo(typelib, type->name)))
  795. {
  796. chat("encode_type: VT_USERDEFINED - found imported type %s in %s\n",
  797. type->name, importinfo->importlib->name);
  798. alloc_importinfo(typelib, importinfo);
  799. typeinfo_offset = importinfo->offset | 0x1;
  800. }
  801. else
  802. {
  803. /* Typedefs without the [public] attribute aren't included in the
  804. * typelib, unless the aliasee is an anonymous UDT or the typedef
  805. * is wire-marshalled. In the latter case the wire-marshal type,
  806. * which may be a non-public alias, is used instead. */
  807. while (type_is_alias(type))
  808. {
  809. if (is_attr(type->attrs, ATTR_WIREMARSHAL))
  810. {
  811. type = get_attrp(type->attrs, ATTR_WIREMARSHAL);
  812. break;
  813. }
  814. else if (!is_attr(type->attrs, ATTR_PUBLIC))
  815. type = type_alias_get_aliasee_type(type);
  816. else
  817. break;
  818. }
  819. chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n",
  820. type->name, type_get_type(type));
  821. switch (type_get_type_detect_alias(type))
  822. {
  823. case TYPE_STRUCT:
  824. case TYPE_ENCAPSULATED_UNION:
  825. add_structure_typeinfo(typelib, type);
  826. break;
  827. case TYPE_INTERFACE:
  828. add_interface_typeinfo(typelib, type);
  829. break;
  830. case TYPE_ENUM:
  831. add_enum_typeinfo(typelib, type);
  832. break;
  833. case TYPE_UNION:
  834. add_union_typeinfo(typelib, type);
  835. break;
  836. case TYPE_COCLASS:
  837. add_coclass_typeinfo(typelib, type);
  838. break;
  839. case TYPE_ALIAS:
  840. add_typedef_typeinfo(typelib, type);
  841. break;
  842. default:
  843. error("encode_type: VT_USERDEFINED - unhandled type %d\n",
  844. type_get_type(type));
  845. }
  846. typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
  847. }
  848. for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
  849. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  850. if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break;
  851. }
  852. if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
  853. typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
  854. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  855. typedata[0] = (0x7fff << 16) | VT_USERDEFINED;
  856. typedata[1] = typeinfo_offset;
  857. }
  858. *encoded_type = typeoffset;
  859. break;
  860. }
  861. default:
  862. error("encode_type: unrecognized type %d.\n", vt);
  863. *encoded_type = default_type;
  864. break;
  865. }
  866. return 0;
  867. }
  868. static void dump_type(type_t *t)
  869. {
  870. chat("dump_type: %p name %s type %d attrs %p\n", t, t->name, type_get_type(t), t->attrs);
  871. }
  872. static int encode_var(
  873. msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */
  874. type_t *type, /* [I] The type description to encode. */
  875. var_t *var, /* [I] The var to encode. */
  876. int *encoded_type, /* [O] The encoded type description. */
  877. int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
  878. {
  879. int typeoffset;
  880. int *typedata;
  881. int target_type;
  882. int child_size;
  883. int vt;
  884. int scratch;
  885. if (!decoded_size) decoded_size = &scratch;
  886. *decoded_size = 0;
  887. chat("encode_var: var %p type %p type->name %s\n",
  888. var, type, type->name ? type->name : "NULL");
  889. if (is_array(type) && !type_array_is_decl_as_ptr(type)) {
  890. int num_dims, elements = 1, arrayoffset;
  891. type_t *atype;
  892. int *arraydata;
  893. num_dims = 0;
  894. for (atype = type;
  895. is_array(atype) && !type_array_is_decl_as_ptr(atype);
  896. atype = type_array_get_element_type(atype))
  897. ++num_dims;
  898. chat("array with %d dimensions\n", num_dims);
  899. encode_var(typelib, atype, var, &target_type, NULL);
  900. arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
  901. arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
  902. arraydata[0] = target_type;
  903. arraydata[1] = num_dims;
  904. arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16);
  905. arraydata += 2;
  906. for (atype = type;
  907. is_array(atype) && !type_array_is_decl_as_ptr(atype);
  908. atype = type_array_get_element_type(atype))
  909. {
  910. arraydata[0] = type_array_get_dim(atype);
  911. arraydata[1] = 0;
  912. arraydata += 2;
  913. elements *= type_array_get_dim(atype);
  914. }
  915. typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
  916. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  917. typedata[0] = (0x7ffe << 16) | VT_CARRAY;
  918. typedata[1] = arrayoffset;
  919. *encoded_type = typeoffset;
  920. *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/;
  921. return 0;
  922. }
  923. vt = get_type_vt(type);
  924. if (vt == VT_PTR) {
  925. type_t *ref = is_ptr(type) ?
  926. type_pointer_get_ref_type(type) : type_array_get_element_type(type);
  927. int skip_ptr = encode_var(typelib, ref, var, &target_type, &child_size);
  928. if(skip_ptr == 2) {
  929. chat("encode_var: skipping ptr\n");
  930. *encoded_type = target_type;
  931. *decoded_size = child_size;
  932. return 0;
  933. }
  934. for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
  935. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  936. if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break;
  937. }
  938. if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
  939. int mix_field;
  940. if (target_type & 0x80000000) {
  941. mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
  942. } else if (get_type_vt(ref) == VT_SAFEARRAY) {
  943. type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(ref));
  944. mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF;
  945. } else {
  946. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
  947. mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe;
  948. }
  949. typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
  950. typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
  951. typedata[0] = (mix_field << 16) | VT_PTR;
  952. typedata[1] = target_type;
  953. }
  954. *encoded_type = typeoffset;
  955. *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
  956. return 0;
  957. }
  958. dump_type(type);
  959. encode_type(typelib, vt, type, encoded_type, decoded_size);
  960. /* these types already have an implicit pointer, so we don't need to
  961. * add another */
  962. if(vt == VT_DISPATCH || vt == VT_UNKNOWN) return 2;
  963. return 0;
  964. }
  965. static unsigned int get_ulong_val(unsigned int val, int vt)
  966. {
  967. switch(vt) {
  968. case VT_I2:
  969. case VT_BOOL:
  970. case VT_UI2:
  971. return val & 0xffff;
  972. case VT_I1:
  973. case VT_UI1:
  974. return val & 0xff;
  975. }
  976. return val;
  977. }
  978. static void write_int_value(msft_typelib_t *typelib, int *out, int vt, int value)
  979. {
  980. const unsigned int lv = get_ulong_val(value, vt);
  981. if ((lv & 0x3ffffff) == lv) {
  982. *out = 0x80000000;
  983. *out |= vt << 26;
  984. *out |= lv;
  985. } else {
  986. int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0);
  987. *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
  988. memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &value, 4);
  989. *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757;
  990. *out = offset;
  991. }
  992. }
  993. static void write_string_value(msft_typelib_t *typelib, int *out, const char *value)
  994. {
  995. int len = strlen(value), seg_len = (len + 6 + 3) & ~0x3;
  996. int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0);
  997. *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = VT_BSTR;
  998. memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &len, sizeof(len));
  999. memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6], value, len);
  1000. len += 6;
  1001. while(len < seg_len) {
  1002. *((char *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+len]) = 0x57;
  1003. len++;
  1004. }
  1005. *out = offset;
  1006. }
  1007. static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *expr, int *out)
  1008. {
  1009. int vt;
  1010. if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT) {
  1011. vt = get_type_vt(type);
  1012. if (vt != VT_BSTR && vt != VT_VARIANT)
  1013. error("string default value applied to non-string type\n");
  1014. chat("default value '%s'\n", expr->u.sval);
  1015. write_string_value(typelib, out, expr->u.sval);
  1016. return;
  1017. }
  1018. if (type_get_type(type) == TYPE_ENUM) {
  1019. vt = VT_I4;
  1020. } else if (is_ptr(type)) {
  1021. vt = get_type_vt(type_pointer_get_ref_type(type));
  1022. if (vt == VT_USERDEFINED)
  1023. vt = VT_I4;
  1024. if (expr->cval)
  1025. warning("non-null pointer default value\n");
  1026. } else {
  1027. vt = get_type_vt(type);
  1028. switch(vt) {
  1029. case VT_I2:
  1030. case VT_I4:
  1031. case VT_R4:
  1032. case VT_BOOL:
  1033. case VT_I1:
  1034. case VT_UI1:
  1035. case VT_UI2:
  1036. case VT_UI4:
  1037. case VT_INT:
  1038. case VT_UINT:
  1039. case VT_HRESULT:
  1040. break;
  1041. case VT_VARIANT: {
  1042. switch (expr->type) {
  1043. case EXPR_DOUBLE:
  1044. vt = VT_R4;
  1045. break;
  1046. case EXPR_NUM:
  1047. vt = VT_I4;
  1048. break;
  1049. default:
  1050. warning("can't write default VT_VARIANT value for expression type %d.\n", expr->type);
  1051. return;
  1052. }
  1053. break;
  1054. }
  1055. default:
  1056. warning("can't write value of type %d yet\n", vt);
  1057. return;
  1058. }
  1059. }
  1060. write_int_value(typelib, out, vt, expr->cval);
  1061. }
  1062. static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
  1063. int vt, const void *value, int *offset)
  1064. {
  1065. int guidoffset;
  1066. int custoffset;
  1067. int *custdata;
  1068. int data_out;
  1069. int hash_key;
  1070. hash_key = ctl2_hash_guid(guid);
  1071. guidoffset = ctl2_find_guid(typelib, hash_key, guid);
  1072. if(guidoffset == -1) {
  1073. /* add GUID that was not already present */
  1074. MSFT_GuidEntry guidentry;
  1075. guidentry.guid = *guid;
  1076. guidentry.hreftype = -1;
  1077. guidentry.next_hash = -1;
  1078. guidoffset = ctl2_alloc_guid(typelib, &guidentry);
  1079. }
  1080. if(vt == VT_BSTR)
  1081. /* TODO midl appears to share a single reference if the same string is used as custdata in multiple places */
  1082. write_string_value(typelib, &data_out, value);
  1083. else
  1084. write_int_value(typelib, &data_out, vt, *(int*)value);
  1085. custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0);
  1086. custdata = (int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset];
  1087. custdata[0] = guidoffset;
  1088. custdata[1] = data_out;
  1089. custdata[2] = *offset;
  1090. *offset = custoffset;
  1091. return S_OK;
  1092. }
  1093. static HRESULT set_custdata_attr(msft_typelib_t *typelib, attr_custdata_t *custdata, int *offset)
  1094. {
  1095. switch(custdata->pval->type) {
  1096. case EXPR_STRLIT:
  1097. case EXPR_WSTRLIT:
  1098. set_custdata(typelib, &custdata->id, VT_BSTR, custdata->pval->u.sval, offset);
  1099. break;
  1100. case EXPR_HEXNUM:
  1101. case EXPR_NUM:
  1102. set_custdata(typelib, &custdata->id, VT_I4, &custdata->pval->u.lval, offset);
  1103. break;
  1104. default:
  1105. error("custom() attribute with unknown type\n");
  1106. break;
  1107. }
  1108. return S_OK;
  1109. }
  1110. static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
  1111. {
  1112. int offset, name_offset;
  1113. int *typedata, typedata_size;
  1114. int i, id, next_idx;
  1115. int decoded_size, extra_attr = 0;
  1116. int num_params = 0, num_optional = 0, num_defaults = 0;
  1117. int has_arg_custdata = 0;
  1118. var_t *arg;
  1119. unsigned char *namedata;
  1120. const attr_t *attr;
  1121. unsigned int funcflags = 0, callconv = 4 /* CC_STDCALL */;
  1122. unsigned int funckind, invokekind = 1 /* INVOKE_FUNC */;
  1123. int help_context = 0, help_string_context = 0, help_string_offset = -1;
  1124. int func_custdata_offset = -1;
  1125. int entry = -1, entry_is_ord = 0;
  1126. int lcid_retval_count = 0;
  1127. chat("add_func_desc(%p,%d)\n", typeinfo, index);
  1128. id = ((0x6000 | (typeinfo->typeinfo->datatype2 & 0xffff)) << 16) | index;
  1129. switch(typeinfo->typekind) {
  1130. case TKIND_DISPATCH:
  1131. funckind = 0x4; /* FUNC_DISPATCH */
  1132. break;
  1133. case TKIND_MODULE:
  1134. funckind = 0x3; /* FUNC_STATIC */
  1135. break;
  1136. default:
  1137. funckind = 0x1; /* FUNC_PUREVIRTUAL */
  1138. break;
  1139. }
  1140. if (is_local( func->attrs )) {
  1141. chat("add_func_desc: skipping local function\n");
  1142. return S_FALSE;
  1143. }
  1144. if (type_function_get_args(func->declspec.type))
  1145. LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
  1146. {
  1147. num_params++;
  1148. if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
  1149. if(attr->type == ATTR_DEFAULTVALUE)
  1150. num_defaults++;
  1151. else if(attr->type == ATTR_OPTIONAL)
  1152. num_optional++;
  1153. else if(attr->type == ATTR_CUSTOM)
  1154. has_arg_custdata = 1;
  1155. }
  1156. }
  1157. chat("add_func_desc: num of params %d\n", num_params);
  1158. name_offset = ctl2_alloc_name(typeinfo->typelib, func->name);
  1159. if (func->attrs) LIST_FOR_EACH_ENTRY( attr, func->attrs, const attr_t, entry ) {
  1160. expr_t *expr = attr->u.pval;
  1161. switch(attr->type) {
  1162. case ATTR_BINDABLE:
  1163. funcflags |= 0x4; /* FUNCFLAG_FBINDABLE */
  1164. break;
  1165. case ATTR_CUSTOM:
  1166. set_custdata_attr(typeinfo->typelib, attr->u.pval, &func_custdata_offset);
  1167. break;
  1168. case ATTR_DEFAULTBIND:
  1169. funcflags |= 0x20; /* FUNCFLAG_FDEFAULTBIND */
  1170. break;
  1171. case ATTR_DEFAULTCOLLELEM:
  1172. funcflags |= 0x100; /* FUNCFLAG_FDEFAULTCOLLELEM */
  1173. break;
  1174. case ATTR_DISPLAYBIND:
  1175. funcflags |= 0x10; /* FUNCFLAG_FDISPLAYBIND */
  1176. break;
  1177. case ATTR_ENTRY:
  1178. extra_attr = max(extra_attr, 3);
  1179. if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT)
  1180. entry = ctl2_alloc_string(typeinfo->typelib, attr->u.pval);
  1181. else {
  1182. entry = expr->cval;
  1183. entry_is_ord = 1;
  1184. }
  1185. break;
  1186. case ATTR_HELPCONTEXT:
  1187. extra_attr = max(extra_attr, 1);
  1188. help_context = expr->u.lval;
  1189. break;
  1190. case ATTR_HELPSTRING:
  1191. extra_attr = max(extra_attr, 2);
  1192. help_string_offset = ctl2_alloc_string(typeinfo->typelib, attr->u.pval);
  1193. break;
  1194. case ATTR_HELPSTRINGCONTEXT:
  1195. extra_attr = max(extra_attr, 6);
  1196. help_string_context = expr->u.lval;
  1197. break;
  1198. case ATTR_HIDDEN:
  1199. funcflags |= 0x40; /* FUNCFLAG_FHIDDEN */
  1200. break;
  1201. case ATTR_ID:
  1202. id = expr->cval;
  1203. break;
  1204. case ATTR_IMMEDIATEBIND:
  1205. funcflags |= 0x1000; /* FUNCFLAG_FIMMEDIATEBIND */
  1206. break;
  1207. case ATTR_NONBROWSABLE:
  1208. funcflags |= 0x400; /* FUNCFLAG_FNONBROWSABLE */
  1209. break;
  1210. case ATTR_OUT:
  1211. break;
  1212. case ATTR_PROPGET:
  1213. invokekind = 0x2; /* INVOKE_PROPERTYGET */
  1214. break;
  1215. case ATTR_PROPPUT:
  1216. invokekind = 0x4; /* INVOKE_PROPERTYPUT */
  1217. break;
  1218. case ATTR_PROPPUTREF:
  1219. invokekind = 0x8; /* INVOKE_PROPERTYPUTREF */
  1220. break;
  1221. /* FIXME: FUNCFLAG_FREPLACEABLE */
  1222. case ATTR_REQUESTEDIT:
  1223. funcflags |= 0x8; /* FUNCFLAG_FREQUESTEDIT */
  1224. break;
  1225. case ATTR_RESTRICTED:
  1226. funcflags |= 0x1; /* FUNCFLAG_FRESTRICTED */
  1227. break;
  1228. case ATTR_SOURCE:
  1229. funcflags |= 0x2; /* FUNCFLAG_FSOURCE */
  1230. break;
  1231. case ATTR_UIDEFAULT:
  1232. funcflags |= 0x200; /* FUNCFLAG_FUIDEFAULT */
  1233. break;
  1234. case ATTR_USESGETLASTERROR:
  1235. funcflags |= 0x80; /* FUNCFLAG_FUSESGETLASTERROR */
  1236. break;
  1237. case ATTR_VARARG:
  1238. if (num_optional || num_defaults)
  1239. warning("add_func_desc: ignoring vararg in function with optional or defaultvalue params\n");
  1240. else
  1241. num_optional = -1;
  1242. break;
  1243. default:
  1244. break;
  1245. }
  1246. }
  1247. if(has_arg_custdata || func_custdata_offset != -1) {
  1248. extra_attr = max(extra_attr, 7 + num_params);
  1249. }
  1250. /* allocate type data space for us */
  1251. typedata_size = 0x18 + extra_attr * sizeof(int) + (num_params * (num_defaults ? 16 : 12));
  1252. if (!typeinfo->func_data) {
  1253. typeinfo->func_data = xmalloc(0x100);
  1254. typeinfo->func_data_allocated = 0x100;
  1255. typeinfo->func_data[0] = 0;
  1256. }
  1257. if(typeinfo->func_data[0] + typedata_size + sizeof(int) > typeinfo->func_data_allocated) {
  1258. typeinfo->func_data_allocated = max(typeinfo->func_data_allocated * 2,
  1259. typeinfo->func_data[0] + typedata_size + sizeof(int));
  1260. typeinfo->func_data = xrealloc(typeinfo->func_data, typeinfo->func_data_allocated);
  1261. }
  1262. offset = typeinfo->func_data[0];
  1263. typeinfo->func_data[0] += typedata_size;
  1264. typedata = typeinfo->func_data + (offset >> 2) + 1;
  1265. /* find func with the same name - if it exists use its id */
  1266. for(i = 0; i < (typeinfo->typeinfo->cElement & 0xffff); i++) {
  1267. if(name_offset == typeinfo->func_names[i]) {
  1268. id = typeinfo->func_indices[i];
  1269. break;
  1270. }
  1271. }
  1272. /* find the first func with the same id and link via the hiword of typedata[4] */
  1273. next_idx = index;
  1274. for(i = 0; i < (typeinfo->typeinfo->cElement & 0xffff); i++) {
  1275. if(id == typeinfo->func_indices[i]) {
  1276. next_idx = typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] >> 16;
  1277. typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] &= 0xffff;
  1278. typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] |= (index << 16);
  1279. break;
  1280. }
  1281. }
  1282. /* fill out the basic type information */
  1283. typedata[0] = typedata_size | (index << 16);
  1284. encode_var(typeinfo->typelib, type_function_get_rettype(func->declspec.type), func,
  1285. &typedata[1], &decoded_size);
  1286. typedata[2] = funcflags;
  1287. typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
  1288. typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind;
  1289. if(has_arg_custdata || func_custdata_offset != -1) typedata[4] |= 0x0080;
  1290. if(num_defaults) typedata[4] |= 0x1000;
  1291. if(entry_is_ord) typedata[4] |= 0x2000;
  1292. typedata[5] = (num_optional << 16) | num_params;
  1293. /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */
  1294. /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */
  1295. typedata[3] += (16 /*sizeof(ELEMDESC)*/ * num_params) << 16;
  1296. typedata[3] += (24 /*sizeof(PARAMDESCEX)*/ * num_defaults) << 16;
  1297. switch(extra_attr) {
  1298. default:
  1299. if(extra_attr > 7 + num_params) warning("unknown number of optional attrs\n");
  1300. /* typedata[13..+num_params] = arg_custdata_offset handled in below loop */
  1301. case 7: typedata[12] = func_custdata_offset;
  1302. case 6: typedata[11] = help_string_context;
  1303. case 5: typedata[10] = -1;
  1304. case 4: typedata[9] = -1;
  1305. case 3: typedata[8] = entry;
  1306. case 2: typedata[7] = help_string_offset;
  1307. case 1: typedata[6] = help_context;
  1308. case 0:
  1309. break;
  1310. }
  1311. if (type_function_get_args(func->declspec.type))
  1312. {
  1313. i = 0;
  1314. LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
  1315. {
  1316. int paramflags = 0;
  1317. int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
  1318. int *defaultdata = num_defaults ? typedata + 6 + extra_attr + i : NULL;
  1319. int arg_custdata_offset = -1;
  1320. if(defaultdata) *defaultdata = -1;
  1321. encode_var(typeinfo->typelib, arg->declspec.type, arg, paramdata, &decoded_size);
  1322. if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
  1323. switch(attr->type) {
  1324. case ATTR_CUSTOM:
  1325. set_custdata_attr(typeinfo->typelib, attr->u.pval, &arg_custdata_offset);
  1326. break;
  1327. case ATTR_DEFAULTVALUE:
  1328. {
  1329. paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
  1330. write_default_value(typeinfo->typelib, arg->declspec.type, (expr_t *)attr->u.pval, defaultdata);
  1331. break;
  1332. }
  1333. case ATTR_IN:
  1334. paramflags |= 0x01; /* PARAMFLAG_FIN */
  1335. break;
  1336. case ATTR_OPTIONAL:
  1337. paramflags |= 0x10; /* PARAMFLAG_FOPT */
  1338. break;
  1339. case ATTR_OUT:
  1340. paramflags |= 0x02; /* PARAMFLAG_FOUT */
  1341. break;
  1342. case ATTR_PARAMLCID:
  1343. paramflags |= 0x04; /* PARAMFLAG_LCID */
  1344. lcid_retval_count++;
  1345. break;
  1346. case ATTR_RETVAL:
  1347. paramflags |= 0x08; /* PARAMFLAG_FRETVAL */
  1348. lcid_retval_count++;
  1349. break;
  1350. default:
  1351. chat("unhandled param attr %d\n", attr->type);
  1352. break;
  1353. }
  1354. if(extra_attr > 7 + i) {
  1355. typedata[13+i] = arg_custdata_offset;
  1356. }
  1357. }
  1358. paramdata[1] = -1;
  1359. paramdata[2] = paramflags;
  1360. typedata[3] += decoded_size << 16;
  1361. i++;
  1362. }
  1363. }
  1364. if(lcid_retval_count == 1)
  1365. typedata[4] |= 0x4000;
  1366. else if(lcid_retval_count == 2)
  1367. typedata[4] |= 0x8000;
  1368. if(typeinfo->funcs_allocated == 0) {
  1369. typeinfo->funcs_allocated = 10;
  1370. typeinfo->func_indices = xmalloc(typeinfo->funcs_allocated * sizeof(int));
  1371. typeinfo->func_names = xmalloc(typeinfo->funcs_allocated * sizeof(int));
  1372. typeinfo->func_offsets = xmalloc(typeinfo->funcs_allocated * sizeof(int));
  1373. }
  1374. if(typeinfo->funcs_allocated == (typeinfo->typeinfo->cElement & 0xffff)) {
  1375. typeinfo->funcs_allocated *= 2;
  1376. typeinfo->func_indices = xrealloc(typeinfo->func_indices, typeinfo->funcs_allocated * sizeof(int));
  1377. typeinfo->func_names = xrealloc(typeinfo->func_names, typeinfo->funcs_allocated * sizeof(int));
  1378. typeinfo->func_offsets = xrealloc(typeinfo->func_offsets, typeinfo->funcs_allocated * sizeof(int));
  1379. }
  1380. /* update the index data */
  1381. typeinfo->func_indices[typeinfo->typeinfo->cElement & 0xffff] = id;
  1382. typeinfo->func_offsets[typeinfo->typeinfo->cElement & 0xffff] = offset;
  1383. typeinfo->func_names[typeinfo->typeinfo->cElement & 0xffff] = name_offset;
  1384. /* ??? */
  1385. if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x20;
  1386. typeinfo->typeinfo->res2 <<= 1;
  1387. /* ??? */
  1388. if (index < 2) typeinfo->typeinfo->res2 += num_params << 4;
  1389. if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0;
  1390. typeinfo->typeinfo->res3 += 0x38 + num_params * 0x10;
  1391. if(num_defaults) typeinfo->typeinfo->res3 += num_params * 0x4;
  1392. /* adjust size of VTBL */
  1393. if(funckind != 0x3 /* FUNC_STATIC */)
  1394. typeinfo->typeinfo->cbSizeVft += pointer_size;
  1395. /* Increment the number of function elements */
  1396. typeinfo->typeinfo->cElement += 1;
  1397. namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + name_offset;
  1398. if (*((INT *)namedata) == -1) {
  1399. *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16];
  1400. if(typeinfo->typekind == TKIND_MODULE)
  1401. namedata[9] |= 0x10;
  1402. } else
  1403. namedata[9] &= ~0x10;
  1404. if(typeinfo->typekind == TKIND_MODULE)
  1405. namedata[9] |= 0x20;
  1406. if (type_function_get_args(func->declspec.type))
  1407. {
  1408. i = 0;
  1409. LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
  1410. {
  1411. /* don't give the last arg of a [propput*] func a name */
  1412. if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */))
  1413. {
  1414. int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
  1415. offset = ctl2_alloc_name(typeinfo->typelib, arg->name);
  1416. paramdata[1] = offset;
  1417. }
  1418. i++;
  1419. }
  1420. }
  1421. return S_OK;
  1422. }
  1423. static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
  1424. {
  1425. int offset, id;
  1426. unsigned int typedata_size;
  1427. int extra_attr = 0;
  1428. INT *typedata;
  1429. unsigned int var_datawidth, var_alignment = 0;
  1430. int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */;
  1431. int alignment;
  1432. int varflags = 0;
  1433. const attr_t *attr;
  1434. unsigned char *namedata;
  1435. int var_num = (typeinfo->typeinfo->cElement >> 16) & 0xffff;
  1436. int var_custdata_offset = -1;
  1437. if (!var->name)
  1438. var->name = gen_name();
  1439. chat("add_var_desc(%d, %s)\n", index, var->name);
  1440. id = 0x40000000 + index;
  1441. if (var->attrs) LIST_FOR_EACH_ENTRY( attr, var->attrs, const attr_t, entry ) {
  1442. expr_t *expr = attr->u.pval;
  1443. switch(attr->type) {
  1444. case ATTR_BINDABLE:
  1445. varflags |= 0x04; /* VARFLAG_FBINDABLE */
  1446. break;
  1447. case ATTR_CUSTOM:
  1448. extra_attr = max(extra_attr,4);
  1449. set_custdata_attr(typeinfo->typelib, attr->u.pval, &var_custdata_offset);
  1450. break;
  1451. case ATTR_DEFAULTBIND:
  1452. varflags |= 0x20; /* VARFLAG_FDEFAULTBIND */
  1453. break;
  1454. case ATTR_DEFAULTCOLLELEM:
  1455. varflags |= 0x100; /* VARFLAG_FDEFAULTCOLLELEM */
  1456. break;
  1457. case ATTR_DISPLAYBIND:
  1458. varflags |= 0x10; /* VARFLAG_FDISPLAYBIND */
  1459. break;
  1460. case ATTR_HIDDEN:
  1461. varflags |= 0x40; /* VARFLAG_FHIDDEN */
  1462. break;
  1463. case ATTR_ID:
  1464. id = expr->cval;
  1465. break;
  1466. case ATTR_IMMEDIATEBIND:
  1467. varflags |= 0x1000; /* VARFLAG_FIMMEDIATEBIND */
  1468. break;
  1469. case ATTR_NONBROWSABLE:
  1470. varflags |= 0x400; /* VARFLAG_FNONBROWSABLE */
  1471. break;
  1472. case ATTR_READONLY:
  1473. varflags |= 0x01; /* VARFLAG_FREADONLY */
  1474. break;
  1475. /* FIXME: VARFLAG_FREPLACEABLE */
  1476. case ATTR_REQUESTEDIT:
  1477. varflags |= 0x08; /* VARFLAG_FREQUESTEDIT */
  1478. break;
  1479. case ATTR_RESTRICTED:
  1480. varflags |= 0x80; /* VARFLAG_FRESTRICTED */
  1481. break;
  1482. case ATTR_SOURCE:
  1483. varflags |= 0x02; /* VARFLAG_FSOURCE */
  1484. break;
  1485. case ATTR_UIDEFAULT:
  1486. varflags |= 0x0200; /* VARFLAG_FUIDEFAULT */
  1487. break;
  1488. default:
  1489. break;
  1490. }
  1491. }
  1492. /* allocate type data space for us */
  1493. typedata_size = 0x14 + extra_attr * sizeof(int);
  1494. if (!typeinfo->var_data) {
  1495. typeinfo->var_data = xmalloc(0x100);
  1496. typeinfo->var_data_allocated = 0x100;
  1497. typeinfo->var_data[0] = 0;
  1498. }
  1499. if(typeinfo->var_data[0] + typedata_size + sizeof(int) > typeinfo->var_data_allocated) {
  1500. typeinfo->var_data_allocated = max(typeinfo->var_data_allocated * 2,
  1501. typeinfo->var_data[0] + typedata_size + sizeof(int));
  1502. typeinfo->var_data = xrealloc(typeinfo->var_data, typeinfo->var_data_allocated);
  1503. }
  1504. offset = typeinfo->var_data[0];
  1505. typeinfo->var_data[0] += typedata_size;
  1506. typedata = typeinfo->var_data + (offset >> 2) + 1;
  1507. /* fill out the basic type information */
  1508. typedata[0] = typedata_size | (index << 16);
  1509. typedata[2] = varflags;
  1510. typedata[3] = (36 /*sizeof(VARDESC)*/ << 16) | 0;
  1511. if(typeinfo->vars_allocated == 0) {
  1512. typeinfo->vars_allocated = 10;
  1513. typeinfo->var_indices = xmalloc(typeinfo->vars_allocated * sizeof(int));
  1514. typeinfo->var_names = xmalloc(typeinfo->vars_allocated * sizeof(int));
  1515. typeinfo->var_offsets = xmalloc(typeinfo->vars_allocated * sizeof(int));
  1516. }
  1517. if(typeinfo->vars_allocated == var_num) {
  1518. typeinfo->vars_allocated *= 2;
  1519. typeinfo->var_indices = xrealloc(typeinfo->var_indices, typeinfo->vars_allocated * sizeof(int));
  1520. typeinfo->var_names = xrealloc(typeinfo->var_names, typeinfo->vars_allocated * sizeof(int));
  1521. typeinfo->var_offsets = xrealloc(typeinfo->var_offsets, typeinfo->vars_allocated * sizeof(int));
  1522. }
  1523. /* update the index data */
  1524. typeinfo->var_indices[var_num] = id;
  1525. typeinfo->var_names[var_num] = -1;
  1526. typeinfo->var_offsets[var_num] = offset;
  1527. /* figure out type widths and whatnot */
  1528. var_datawidth = type_memsize_and_alignment(var->declspec.type, &var_alignment);
  1529. encode_var(typeinfo->typelib, var->declspec.type, var, &typedata[1], &var_type_size);
  1530. /* pad out starting position to data width */
  1531. typeinfo->datawidth += var_alignment - 1;
  1532. typeinfo->datawidth &= ~(var_alignment - 1);
  1533. switch(typeinfo->typekind) {
  1534. case TKIND_ENUM:
  1535. write_int_value(typeinfo->typelib, &typedata[4], VT_I4, var->eval->cval);
  1536. var_kind = 2; /* VAR_CONST */
  1537. var_type_size += 16; /* sizeof(VARIANT) */
  1538. typeinfo->datawidth = var_datawidth;
  1539. break;
  1540. case TKIND_RECORD:
  1541. typedata[4] = typeinfo->datawidth;
  1542. typeinfo->datawidth += var_datawidth;
  1543. break;
  1544. case TKIND_UNION:
  1545. typedata[4] = 0;
  1546. typeinfo->datawidth = max(typeinfo->datawidth, var_datawidth);
  1547. break;
  1548. case TKIND_DISPATCH:
  1549. var_kind = 3; /* VAR_DISPATCH */
  1550. typedata[4] = 0;
  1551. typeinfo->datawidth = pointer_size;
  1552. break;
  1553. default:
  1554. error("add_var_desc: unhandled type kind %d\n", typeinfo->typekind);
  1555. break;
  1556. }
  1557. /* add type description size to total required allocation */
  1558. typedata[3] += var_type_size << 16 | var_kind;
  1559. switch(extra_attr) {
  1560. case 5: typedata[9] = -1 /*help_string_context*/;
  1561. case 4: typedata[8] = var_custdata_offset;
  1562. case 3: typedata[7] = -1;
  1563. case 2: typedata[6] = -1 /*help_string_offset*/;
  1564. case 1: typedata[5] = -1 /*help_context*/;
  1565. case 0:
  1566. break;
  1567. default:
  1568. warning("unknown number of optional attrs\n");
  1569. }
  1570. /* fix type alignment */
  1571. alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f;
  1572. if (alignment < var_alignment) {
  1573. alignment = var_alignment;
  1574. typeinfo->typeinfo->typekind &= ~0xffc0;
  1575. typeinfo->typeinfo->typekind |= alignment << 11 | alignment << 6;
  1576. }
  1577. /* ??? */
  1578. if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x1a;
  1579. if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) {
  1580. typeinfo->typeinfo->res2 <<= 1;
  1581. }
  1582. /* ??? */
  1583. if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0;
  1584. typeinfo->typeinfo->res3 += 0x2c;
  1585. /* increment the number of variable elements */
  1586. typeinfo->typeinfo->cElement += 0x10000;
  1587. /* pad data width to alignment */
  1588. typeinfo->typeinfo->size = (typeinfo->datawidth + (alignment - 1)) & ~(alignment - 1);
  1589. offset = ctl2_alloc_name(typeinfo->typelib, var->name);
  1590. if (offset == -1) return E_OUTOFMEMORY;
  1591. namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
  1592. if (*((INT *)namedata) == -1) {
  1593. *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16];
  1594. if(typeinfo->typekind != TKIND_DISPATCH)
  1595. namedata[9] |= 0x10;
  1596. } else
  1597. namedata[9] &= ~0x10;
  1598. if (typeinfo->typekind == TKIND_ENUM) {
  1599. namedata[9] |= 0x20;
  1600. }
  1601. typeinfo->var_names[var_num] = offset;
  1602. return S_OK;
  1603. }
  1604. static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref, importinfo_t *importinfo)
  1605. {
  1606. if(importinfo) {
  1607. alloc_importinfo(typeinfo->typelib, importinfo);
  1608. typeinfo->typeinfo->datatype1 = importinfo->offset+1;
  1609. }else {
  1610. if(ref->typelib_idx == -1)
  1611. add_interface_typeinfo(typeinfo->typelib, ref);
  1612. if(ref->typelib_idx == -1)
  1613. error("add_impl_type: unable to add inherited interface\n");
  1614. typeinfo->typeinfo->datatype1 = typeinfo->typelib->typelib_typeinfo_offsets[ref->typelib_idx];
  1615. }
  1616. typeinfo->typeinfo->cImplTypes++;
  1617. return S_OK;
  1618. }
  1619. static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_kind kind,
  1620. const char *name, const attr_list_t *attrs)
  1621. {
  1622. const attr_t *attr;
  1623. msft_typeinfo_t *msft_typeinfo;
  1624. int nameoffset;
  1625. int typeinfo_offset;
  1626. MSFT_TypeInfoBase *typeinfo;
  1627. MSFT_GuidEntry guidentry;
  1628. chat("create_msft_typeinfo: name %s kind %d index %d\n", name, kind, typelib->typelib_header.nrtypeinfos);
  1629. msft_typeinfo = xmalloc(sizeof(*msft_typeinfo));
  1630. memset( msft_typeinfo, 0, sizeof(*msft_typeinfo) );
  1631. msft_typeinfo->typelib = typelib;
  1632. nameoffset = ctl2_alloc_name(typelib, name);
  1633. typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset);
  1634. typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset];
  1635. typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38;
  1636. *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset;
  1637. msft_typeinfo->typekind = kind;
  1638. msft_typeinfo->typeinfo = typeinfo;
  1639. typeinfo->typekind |= kind | 0x20;
  1640. if(kind == TKIND_COCLASS)
  1641. typeinfo->flags |= 0x2; /* TYPEFLAG_FCANCREATE */
  1642. if (attrs) LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) {
  1643. switch(attr->type) {
  1644. case ATTR_AGGREGATABLE:
  1645. if (kind == TKIND_COCLASS)
  1646. typeinfo->flags |= 0x400; /* TYPEFLAG_FAGGREGATABLE */
  1647. break;
  1648. case ATTR_APPOBJECT:
  1649. if (kind == TKIND_COCLASS)
  1650. typeinfo->flags |= 0x1; /* TYPEFLAG_FAPPOBJECT */
  1651. break;
  1652. case ATTR_CONTROL:
  1653. if (kind == TKIND_COCLASS)
  1654. typeinfo->flags |= 0x20; /* TYPEFLAG_FCONTROL */
  1655. break;
  1656. case ATTR_CUSTOM:
  1657. set_custdata_attr(typelib, attr->u.pval, &typeinfo->oCustData);
  1658. break;
  1659. case ATTR_DLLNAME:
  1660. {
  1661. int offset = ctl2_alloc_string(typelib, attr->u.pval);
  1662. typeinfo->datatype1 = offset;
  1663. break;
  1664. }
  1665. case ATTR_DUAL:
  1666. /* FIXME: check interface is compatible */
  1667. typeinfo->typekind = (typeinfo->typekind & ~0xff) | 0x34;
  1668. typeinfo->flags |= 0x140; /* TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION */
  1669. break;
  1670. case ATTR_HELPCONTEXT:
  1671. {
  1672. expr_t *expr = (expr_t*)attr->u.pval;
  1673. typeinfo->helpcontext = expr->cval;
  1674. break;
  1675. }
  1676. case ATTR_HELPSTRING:
  1677. {
  1678. int offset = ctl2_alloc_string(typelib, attr->u.pval);
  1679. if (offset == -1) break;
  1680. typeinfo->docstringoffs = offset;
  1681. break;
  1682. }
  1683. case ATTR_HELPSTRINGCONTEXT:
  1684. {
  1685. expr_t *expr = (expr_t*)attr->u.pval;
  1686. typeinfo->helpstringcontext = expr->cval;
  1687. break;
  1688. }
  1689. case ATTR_HIDDEN:
  1690. typeinfo->flags |= 0x10; /* TYPEFLAG_FHIDDEN */
  1691. break;
  1692. case ATTR_LICENSED:
  1693. typeinfo->flags |= 0x04; /* TYPEFLAG_FLICENSED */
  1694. break;
  1695. case ATTR_NONCREATABLE:
  1696. typeinfo->flags &= ~0x2; /* TYPEFLAG_FCANCREATE */
  1697. break;
  1698. case ATTR_NONEXTENSIBLE:
  1699. typeinfo->flags |= 0x80; /* TYPEFLAG_FNONEXTENSIBLE */
  1700. break;
  1701. case ATTR_OLEAUTOMATION:
  1702. typeinfo->flags |= 0x100; /* TYPEFLAG_FOLEAUTOMATION */
  1703. break;
  1704. /* FIXME: TYPEFLAG_FPREDCLID */
  1705. case ATTR_PROXY:
  1706. typeinfo->flags |= 0x4000; /* TYPEFLAG_FPROXY */
  1707. break;
  1708. /* FIXME: TYPEFLAG_FREPLACEABLE */
  1709. case ATTR_RESTRICTED:
  1710. typeinfo->flags |= 0x200; /* TYPEFLAG_FRESTRICTED */
  1711. break;
  1712. case ATTR_UUID:
  1713. guidentry.guid = *(GUID*)attr->u.pval;
  1714. guidentry.hreftype = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16];
  1715. guidentry.next_hash = -1;
  1716. typeinfo->posguid = ctl2_alloc_guid(typelib, &guidentry);
  1717. #if 0
  1718. if (IsEqualIID(guid, &IID_IDispatch)) {
  1719. typelib->typelib_header.dispatchpos = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16];
  1720. }
  1721. #endif
  1722. break;
  1723. case ATTR_VERSION:
  1724. typeinfo->version = attr->u.ival;
  1725. break;
  1726. default:
  1727. break;
  1728. }
  1729. }
  1730. if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = msft_typeinfo;
  1731. typelib->last_typeinfo = msft_typeinfo;
  1732. if (!typelib->typeinfos) typelib->typeinfos = msft_typeinfo;
  1733. return msft_typeinfo;
  1734. }
  1735. static void add_dispatch(msft_typelib_t *typelib)
  1736. {
  1737. int guid_offset, impfile_offset, hash_key;
  1738. MSFT_GuidEntry guidentry;
  1739. MSFT_ImpInfo impinfo;
  1740. GUID stdole = {0x00020430,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  1741. GUID iid_idispatch = {0x00020400,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
  1742. if(typelib->typelib_header.dispatchpos != -1) return;
  1743. guidentry.guid = stdole;
  1744. guidentry.hreftype = 2;
  1745. guidentry.next_hash = -1;
  1746. hash_key = ctl2_hash_guid(&guidentry.guid);
  1747. guid_offset = ctl2_find_guid(typelib, hash_key, &guidentry.guid);
  1748. if (guid_offset == -1)
  1749. guid_offset = ctl2_alloc_guid(typelib, &guidentry);
  1750. impfile_offset = alloc_importfile(typelib, guid_offset, 2, 0, "stdole2.tlb");
  1751. guidentry.guid = iid_idispatch;
  1752. guidentry.hreftype = 1;
  1753. guidentry.next_hash = -1;
  1754. impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID;
  1755. impinfo.oImpFile = impfile_offset;
  1756. hash_key = ctl2_hash_guid(&guidentry.guid);
  1757. guid_offset = ctl2_find_guid(typelib, hash_key, &guidentry.guid);
  1758. if (guid_offset == -1)
  1759. guid_offset = ctl2_alloc_guid(typelib, &guidentry);
  1760. impinfo.oGuid = guid_offset;
  1761. typelib->typelib_header.dispatchpos = alloc_msft_importinfo(typelib, &impinfo) | 0x01;
  1762. }
  1763. static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface)
  1764. {
  1765. int num_parents = 0, num_funcs = 0;
  1766. importinfo_t *importinfo = NULL;
  1767. const statement_t *stmt_func;
  1768. type_t *inherit, *ref;
  1769. int idx = 0;
  1770. var_t *func;
  1771. var_t *var;
  1772. msft_typeinfo_t *msft_typeinfo;
  1773. if (-1 < dispinterface->typelib_idx)
  1774. return;
  1775. inherit = type_dispiface_get_inherit(dispinterface);
  1776. if (inherit)
  1777. {
  1778. importinfo = find_importinfo(typelib, inherit->name);
  1779. if (!importinfo && type_iface_get_inherit(inherit) && inherit->typelib_idx == -1)
  1780. add_interface_typeinfo(typelib, inherit);
  1781. }
  1782. /* check typelib_idx again, it could have been added while resolving the parent interface */
  1783. if (-1 < dispinterface->typelib_idx)
  1784. return;
  1785. dispinterface->typelib_idx = typelib->typelib_header.nrtypeinfos;
  1786. msft_typeinfo = create_msft_typeinfo(typelib, TKIND_DISPATCH, dispinterface->name,
  1787. dispinterface->attrs);
  1788. msft_typeinfo->typeinfo->size = pointer_size;
  1789. msft_typeinfo->typeinfo->typekind |= pointer_size << 11 | pointer_size << 6;
  1790. msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */
  1791. add_dispatch(typelib);
  1792. if (inherit)
  1793. {
  1794. add_impl_type(msft_typeinfo, inherit, importinfo);
  1795. msft_typeinfo->typeinfo->typekind |= 0x10;
  1796. }
  1797. /* count the number of inherited interfaces and non-local functions */
  1798. for (ref = inherit; ref; ref = type_iface_get_inherit(ref))
  1799. {
  1800. num_parents++;
  1801. STATEMENTS_FOR_EACH_FUNC( stmt_func, type_iface_get_stmts(ref) )
  1802. {
  1803. var_t *func = stmt_func->u.var;
  1804. if (!is_local(func->attrs)) num_funcs++;
  1805. }
  1806. }
  1807. msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents;
  1808. msft_typeinfo->typeinfo->cbSizeVft = num_funcs * pointer_size;
  1809. msft_typeinfo->typeinfo->cImplTypes = 1; /* IDispatch */
  1810. /* count the no of methods, as the variable indices come after the funcs */
  1811. if (dispinterface->details.iface->disp_methods)
  1812. LIST_FOR_EACH_ENTRY( func, dispinterface->details.iface->disp_methods, var_t, entry )
  1813. idx++;
  1814. if (type_dispiface_get_props(dispinterface))
  1815. LIST_FOR_EACH_ENTRY( var, type_dispiface_get_props(dispinterface), var_t, entry )
  1816. add_var_desc(msft_typeinfo, idx++, var);
  1817. if (type_dispiface_get_methods(dispinterface))
  1818. {
  1819. idx = 0;
  1820. LIST_FOR_EACH_ENTRY( func, type_dispiface_get_methods(dispinterface), var_t, entry )
  1821. if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
  1822. idx++;
  1823. }
  1824. typelib->typelib->reg_ifaces = xrealloc(typelib->typelib->reg_ifaces,
  1825. (typelib->typelib->reg_iface_count + 1) * sizeof(dispinterface));
  1826. typelib->typelib->reg_ifaces[typelib->typelib->reg_iface_count++] = dispinterface;
  1827. }
  1828. static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
  1829. {
  1830. int idx = 0;
  1831. const statement_t *stmt_func;
  1832. type_t *ref;
  1833. msft_typeinfo_t *msft_typeinfo;
  1834. importinfo_t *ref_importinfo = NULL;
  1835. int num_parents = 0, num_funcs = 0;
  1836. type_t *inherit;
  1837. const type_t *derived;
  1838. if (-1 < interface->typelib_idx)
  1839. return;
  1840. if (!interface->details.iface)
  1841. {
  1842. error( "interface %s is referenced but not defined\n", interface->name );
  1843. return;
  1844. }
  1845. if (is_attr(interface->attrs, ATTR_DISPINTERFACE)) {
  1846. add_dispinterface_typeinfo(typelib, interface);
  1847. return;
  1848. }
  1849. /* midl adds the parent interface first, unless the parent itself
  1850. has no parent (i.e. it stops before IUnknown). */
  1851. inherit = type_iface_get_inherit(interface);
  1852. if(inherit) {
  1853. ref_importinfo = find_importinfo(typelib, inherit->name);
  1854. if(!ref_importinfo && type_iface_get_inherit(inherit) &&
  1855. inherit->typelib_idx == -1)
  1856. add_interface_typeinfo(typelib, inherit);
  1857. }
  1858. /* check typelib_idx again, it could have been added while resolving the parent interface */
  1859. if (-1 < interface->typelib_idx)
  1860. return;
  1861. interface->typelib_idx = typelib->typelib_header.nrtypeinfos;
  1862. msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs);
  1863. msft_typeinfo->typeinfo->size = pointer_size;
  1864. msft_typeinfo->typeinfo->typekind |= 0x0200;
  1865. msft_typeinfo->typeinfo->typekind |= pointer_size << 11;
  1866. for (derived = inherit; derived; derived = type_iface_get_inherit(derived))
  1867. if (derived->name && !strcmp(derived->name, "IDispatch"))
  1868. msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */
  1869. if(type_iface_get_inherit(interface))
  1870. add_impl_type(msft_typeinfo, type_iface_get_inherit(interface),
  1871. ref_importinfo);
  1872. /* count the number of inherited interfaces and non-local functions */
  1873. for(ref = inherit; ref; ref = type_iface_get_inherit(ref)) {
  1874. num_parents++;
  1875. STATEMENTS_FOR_EACH_FUNC( stmt_func, type_iface_get_stmts(ref) ) {
  1876. var_t *func = stmt_func->u.var;
  1877. if (!is_local(func->attrs)) num_funcs++;
  1878. }
  1879. }
  1880. msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents;
  1881. msft_typeinfo->typeinfo->cbSizeVft = num_funcs * pointer_size;
  1882. STATEMENTS_FOR_EACH_FUNC( stmt_func, type_iface_get_stmts(interface) ) {
  1883. var_t *func = stmt_func->u.var;
  1884. if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
  1885. idx++;
  1886. }
  1887. if (is_attr(interface->attrs, ATTR_OLEAUTOMATION) || is_attr(interface->attrs, ATTR_DUAL))
  1888. {
  1889. typelib->typelib->reg_ifaces = xrealloc(typelib->typelib->reg_ifaces,
  1890. (typelib->typelib->reg_iface_count + 1) * sizeof(interface));
  1891. typelib->typelib->reg_ifaces[typelib->typelib->reg_iface_count++] = interface;
  1892. }
  1893. }
  1894. static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure)
  1895. {
  1896. var_list_t *fields;
  1897. int idx = 0;
  1898. var_t *cur;
  1899. msft_typeinfo_t *msft_typeinfo;
  1900. if (-1 < structure->typelib_idx)
  1901. return;
  1902. structure->typelib_idx = typelib->typelib_header.nrtypeinfos;
  1903. msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs);
  1904. msft_typeinfo->typeinfo->size = 0;
  1905. if (type_get_type(structure) == TYPE_STRUCT)
  1906. fields = type_struct_get_fields(structure);
  1907. else
  1908. fields = type_encapsulated_union_get_fields(structure);
  1909. if (fields)
  1910. {
  1911. LIST_FOR_EACH_ENTRY( cur, fields, var_t, entry )
  1912. add_var_desc(msft_typeinfo, idx++, cur);
  1913. }
  1914. }
  1915. static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration)
  1916. {
  1917. int idx = 0;
  1918. var_t *cur;
  1919. msft_typeinfo_t *msft_typeinfo;
  1920. if (-1 < enumeration->typelib_idx)
  1921. return;
  1922. enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos;
  1923. msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs);
  1924. msft_typeinfo->typeinfo->size = 0;
  1925. if (type_enum_get_values(enumeration))
  1926. LIST_FOR_EACH_ENTRY( cur, type_enum_get_values(enumeration), var_t, entry )
  1927. add_var_desc(msft_typeinfo, idx++, cur);
  1928. }
  1929. static void add_union_typeinfo(msft_typelib_t *typelib, type_t *tunion)
  1930. {
  1931. int idx = 0;
  1932. var_t *cur;
  1933. msft_typeinfo_t *msft_typeinfo;
  1934. if (-1 < tunion->typelib_idx)
  1935. return;
  1936. if (!tunion->name)
  1937. tunion->name = gen_name();
  1938. tunion->typelib_idx = typelib->typelib_header.nrtypeinfos;
  1939. msft_typeinfo = create_msft_typeinfo(typelib, TKIND_UNION, tunion->name, tunion->attrs);
  1940. msft_typeinfo->typeinfo->size = 0;
  1941. if (type_union_get_cases(tunion))
  1942. LIST_FOR_EACH_ENTRY(cur, type_union_get_cases(tunion), var_t, entry)
  1943. add_var_desc(msft_typeinfo, idx++, cur);
  1944. }
  1945. static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
  1946. {
  1947. msft_typeinfo_t *msft_typeinfo = NULL;
  1948. int datatype1, datatype2, duplicate = 0;
  1949. unsigned int size, alignment = 0;
  1950. type_t *type;
  1951. if (-1 < tdef->typelib_idx)
  1952. return;
  1953. type = type_alias_get_aliasee_type(tdef);
  1954. if (!type->name || strcmp(tdef->name, type->name) != 0)
  1955. {
  1956. tdef->typelib_idx = typelib->typelib_header.nrtypeinfos;
  1957. msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->attrs);
  1958. }
  1959. else
  1960. duplicate = 1;
  1961. encode_type(typelib, get_type_vt(type), type, &datatype1, &datatype2);
  1962. size = type_memsize_and_alignment(type, &alignment);
  1963. if (msft_typeinfo)
  1964. {
  1965. msft_typeinfo->typeinfo->datatype1 = datatype1;
  1966. msft_typeinfo->typeinfo->size = size;
  1967. msft_typeinfo->typeinfo->datatype2 = datatype2;
  1968. msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6);
  1969. }
  1970. /* avoid adding duplicate type definitions */
  1971. if (duplicate)
  1972. tdef->typelib_idx = type->typelib_idx;
  1973. }
  1974. static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls)
  1975. {
  1976. msft_typeinfo_t *msft_typeinfo;
  1977. typeref_t *iref;
  1978. int num_ifaces = 0, offset, i;
  1979. MSFT_RefRecord *ref, *first = NULL, *first_source = NULL;
  1980. int have_default = 0, have_default_source = 0;
  1981. const attr_t *attr;
  1982. typeref_list_t *ifaces;
  1983. if (-1 < cls->typelib_idx)
  1984. return;
  1985. cls->typelib_idx = typelib->typelib_header.nrtypeinfos;
  1986. msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs);
  1987. ifaces = type_coclass_get_ifaces(cls);
  1988. if (ifaces) LIST_FOR_EACH_ENTRY( iref, ifaces, typeref_t, entry ) num_ifaces++;
  1989. offset = msft_typeinfo->typeinfo->datatype1 = ctl2_alloc_segment(typelib, MSFT_SEG_REFERENCES,
  1990. num_ifaces * sizeof(*ref), 0);
  1991. i = 0;
  1992. if (ifaces) LIST_FOR_EACH_ENTRY( iref, ifaces, typeref_t, entry ) {
  1993. if(iref->type->typelib_idx == -1)
  1994. add_interface_typeinfo(typelib, iref->type);
  1995. ref = (MSFT_RefRecord*) (typelib->typelib_segment_data[MSFT_SEG_REFERENCES] + offset + i * sizeof(*ref));
  1996. ref->reftype = typelib->typelib_typeinfo_offsets[iref->type->typelib_idx];
  1997. ref->flags = 0;
  1998. ref->oCustData = -1;
  1999. ref->onext = -1;
  2000. if(i < num_ifaces - 1)
  2001. ref->onext = offset + (i + 1) * sizeof(*ref);
  2002. if (iref->attrs) LIST_FOR_EACH_ENTRY( attr, iref->attrs, const attr_t, entry ) {
  2003. switch(attr->type) {
  2004. case ATTR_DEFAULT:
  2005. ref->flags |= 0x1; /* IMPLTYPEFLAG_FDEFAULT */
  2006. break;
  2007. case ATTR_DEFAULTVTABLE:
  2008. ref->flags |= 0x8; /* IMPLTYPEFLAG_FDEFAULTVTABLE */
  2009. break;
  2010. case ATTR_RESTRICTED:
  2011. ref->flags |= 0x4; /* IMPLTYPEFLAG_FRESTRICTED */
  2012. break;
  2013. case ATTR_SOURCE:
  2014. ref->flags |= 0x2; /* IMPLTYPEFLAG_FSOURCE */
  2015. break;
  2016. default:
  2017. warning("add_coclass_typeinfo: unhandled attr %d\n", attr->type);
  2018. }
  2019. }
  2020. if(ref->flags & 0x1) { /* IMPLTYPEFLAG_FDEFAULT */
  2021. if(ref->flags & 0x2) /* IMPLTYPEFLAG_SOURCE */
  2022. have_default_source = 1;
  2023. else
  2024. have_default = 1;
  2025. }
  2026. /* If the interface is non-restricted and we haven't already had one then
  2027. remember it so that we can use it as a default later */
  2028. if((ref->flags & 0x4) == 0) { /* IMPLTYPEFLAG_FRESTRICTED */
  2029. if(ref->flags & 0x2) { /* IMPLTYPEFLAG_FSOURCE */
  2030. if(!first_source)
  2031. first_source = ref;
  2032. }
  2033. else if(!first)
  2034. first = ref;
  2035. }
  2036. i++;
  2037. }
  2038. /* If we haven't had a default interface, then set the default flags on the
  2039. first ones */
  2040. if(!have_default && first)
  2041. first->flags |= 0x1;
  2042. if(!have_default_source && first_source)
  2043. first_source->flags |= 0x1;
  2044. msft_typeinfo->typeinfo->cImplTypes = num_ifaces;
  2045. msft_typeinfo->typeinfo->size = pointer_size;
  2046. msft_typeinfo->typeinfo->typekind |= 0x2200;
  2047. }
  2048. static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
  2049. {
  2050. int idx = 0;
  2051. const statement_t *stmt;
  2052. msft_typeinfo_t *msft_typeinfo;
  2053. if (-1 < module->typelib_idx)
  2054. return;
  2055. module->typelib_idx = typelib->typelib_header.nrtypeinfos;
  2056. msft_typeinfo = create_msft_typeinfo(typelib, TKIND_MODULE, module->name, module->attrs);
  2057. msft_typeinfo->typeinfo->typekind |= 0x0a00;
  2058. STATEMENTS_FOR_EACH_FUNC( stmt, module->details.module->stmts ) {
  2059. var_t *func = stmt->u.var;
  2060. if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
  2061. idx++;
  2062. }
  2063. msft_typeinfo->typeinfo->size = idx;
  2064. }
  2065. static void add_type_typeinfo(msft_typelib_t *typelib, type_t *type)
  2066. {
  2067. switch (type_get_type(type)) {
  2068. case TYPE_INTERFACE:
  2069. add_interface_typeinfo(typelib, type);
  2070. break;
  2071. case TYPE_STRUCT:
  2072. case TYPE_ENCAPSULATED_UNION:
  2073. add_structure_typeinfo(typelib, type);
  2074. break;
  2075. case TYPE_ENUM:
  2076. add_enum_typeinfo(typelib, type);
  2077. break;
  2078. case TYPE_UNION:
  2079. add_union_typeinfo(typelib, type);
  2080. break;
  2081. case TYPE_COCLASS:
  2082. add_coclass_typeinfo(typelib, type);
  2083. break;
  2084. case TYPE_BASIC:
  2085. case TYPE_POINTER:
  2086. case TYPE_ARRAY:
  2087. break;
  2088. default:
  2089. error("add_entry: unhandled type 0x%x for %s\n",
  2090. type_get_type(type), type->name);
  2091. break;
  2092. }
  2093. }
  2094. static void add_entry(msft_typelib_t *typelib, const statement_t *stmt)
  2095. {
  2096. switch(stmt->type) {
  2097. case STMT_LIBRARY:
  2098. case STMT_IMPORT:
  2099. case STMT_PRAGMA:
  2100. case STMT_CPPQUOTE:
  2101. case STMT_DECLARATION:
  2102. /* not included in typelib */
  2103. break;
  2104. case STMT_IMPORTLIB:
  2105. /* not processed here */
  2106. break;
  2107. case STMT_TYPEDEF:
  2108. {
  2109. typeref_t *ref;
  2110. if (stmt->u.type_list) LIST_FOR_EACH_ENTRY(ref, stmt->u.type_list, typeref_t, entry) {
  2111. /* if the type is public then add the typedef, otherwise attempt
  2112. * to add the aliased type */
  2113. if (is_attr(ref->type->attrs, ATTR_PUBLIC))
  2114. add_typedef_typeinfo(typelib, ref->type);
  2115. else
  2116. add_type_typeinfo(typelib, type_alias_get_aliasee_type(ref->type));
  2117. }
  2118. break;
  2119. }
  2120. case STMT_MODULE:
  2121. add_module_typeinfo(typelib, stmt->u.type);
  2122. break;
  2123. case STMT_TYPE:
  2124. case STMT_TYPEREF:
  2125. {
  2126. type_t *type = stmt->u.type;
  2127. add_type_typeinfo(typelib, type);
  2128. break;
  2129. }
  2130. }
  2131. }
  2132. static void set_name(msft_typelib_t *typelib)
  2133. {
  2134. int offset;
  2135. offset = ctl2_alloc_name(typelib, typelib->typelib->name);
  2136. if (offset == -1) return;
  2137. typelib->typelib_header.NameOffset = offset;
  2138. return;
  2139. }
  2140. static void set_version(msft_typelib_t *typelib)
  2141. {
  2142. typelib->typelib_header.version = get_attrv( typelib->typelib->attrs, ATTR_VERSION );
  2143. }
  2144. static void set_guid(msft_typelib_t *typelib)
  2145. {
  2146. MSFT_GuidEntry guidentry;
  2147. int offset;
  2148. void *ptr;
  2149. GUID guid = {0,0,0,{0,0,0,0,0,0}};
  2150. guidentry.guid = guid;
  2151. guidentry.hreftype = -2;
  2152. guidentry.next_hash = -1;
  2153. ptr = get_attrp( typelib->typelib->attrs, ATTR_UUID );
  2154. if (ptr) guidentry.guid = *(GUID *)ptr;
  2155. offset = ctl2_alloc_guid(typelib, &guidentry);
  2156. typelib->typelib_header.posguid = offset;
  2157. return;
  2158. }
  2159. static void set_doc_string(msft_typelib_t *typelib)
  2160. {
  2161. char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRING );
  2162. if (str)
  2163. {
  2164. int offset = ctl2_alloc_string(typelib, str);
  2165. if (offset != -1) typelib->typelib_header.helpstring = offset;
  2166. }
  2167. }
  2168. static void set_help_file_name(msft_typelib_t *typelib)
  2169. {
  2170. char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPFILE );
  2171. if (str)
  2172. {
  2173. int offset = ctl2_alloc_string(typelib, str);
  2174. if (offset != -1)
  2175. {
  2176. typelib->typelib_header.helpfile = offset;
  2177. typelib->typelib_header.varflags |= 0x10;
  2178. }
  2179. }
  2180. }
  2181. static void set_help_context(msft_typelib_t *typelib)
  2182. {
  2183. const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPCONTEXT );
  2184. if (expr) typelib->typelib_header.helpcontext = expr->cval;
  2185. }
  2186. static void set_help_string_dll(msft_typelib_t *typelib)
  2187. {
  2188. char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGDLL );
  2189. if (str)
  2190. {
  2191. int offset = ctl2_alloc_string(typelib, str);
  2192. if (offset != -1)
  2193. {
  2194. typelib->help_string_dll_offset = offset;
  2195. typelib->typelib_header.varflags |= 0x100;
  2196. }
  2197. }
  2198. }
  2199. static void set_help_string_context(msft_typelib_t *typelib)
  2200. {
  2201. const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGCONTEXT );
  2202. if (expr) typelib->typelib_header.helpstringcontext = expr->cval;
  2203. }
  2204. static void set_lcid(msft_typelib_t *typelib)
  2205. {
  2206. const expr_t *lcid_expr = get_attrp( typelib->typelib->attrs, ATTR_LIBLCID );
  2207. if(lcid_expr)
  2208. {
  2209. typelib->typelib_header.lcid = lcid_expr->cval;
  2210. typelib->typelib_header.lcid2 = lcid_expr->cval;
  2211. }
  2212. }
  2213. static void set_lib_flags(msft_typelib_t *typelib)
  2214. {
  2215. const attr_t *attr;
  2216. typelib->typelib_header.flags = 0;
  2217. if (!typelib->typelib->attrs) return;
  2218. LIST_FOR_EACH_ENTRY( attr, typelib->typelib->attrs, const attr_t, entry )
  2219. {
  2220. switch(attr->type) {
  2221. case ATTR_CONTROL:
  2222. typelib->typelib_header.flags |= 0x02; /* LIBFLAG_FCONTROL */
  2223. break;
  2224. case ATTR_HIDDEN:
  2225. typelib->typelib_header.flags |= 0x04; /* LIBFLAG_FHIDDEN */
  2226. break;
  2227. case ATTR_RESTRICTED:
  2228. typelib->typelib_header.flags |= 0x01; /* LIBFLAG_FRESTRICTED */
  2229. break;
  2230. default:
  2231. break;
  2232. }
  2233. }
  2234. return;
  2235. }
  2236. static void ctl2_write_segment(msft_typelib_t *typelib, int segment)
  2237. {
  2238. if (typelib->typelib_segment_data[segment])
  2239. put_data(typelib->typelib_segment_data[segment], typelib->typelib_segdir[segment].length);
  2240. }
  2241. static void ctl2_finalize_typeinfos(msft_typelib_t *typelib, int filesize)
  2242. {
  2243. msft_typeinfo_t *typeinfo;
  2244. for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
  2245. typeinfo->typeinfo->memoffset = filesize;
  2246. if (typeinfo->func_data)
  2247. filesize += typeinfo->func_data[0] + ((typeinfo->typeinfo->cElement & 0xffff) * 12);
  2248. if (typeinfo->var_data)
  2249. filesize += typeinfo->var_data[0] + (((typeinfo->typeinfo->cElement >> 16) & 0xffff) * 12);
  2250. if (typeinfo->func_data || typeinfo->var_data)
  2251. filesize += 4;
  2252. }
  2253. }
  2254. static int ctl2_finalize_segment(msft_typelib_t *typelib, int filepos, int segment)
  2255. {
  2256. if (typelib->typelib_segdir[segment].length) {
  2257. typelib->typelib_segdir[segment].offset = filepos;
  2258. } else {
  2259. typelib->typelib_segdir[segment].offset = -1;
  2260. }
  2261. return typelib->typelib_segdir[segment].length;
  2262. }
  2263. static void ctl2_write_typeinfos(msft_typelib_t *typelib)
  2264. {
  2265. msft_typeinfo_t *typeinfo;
  2266. int typedata_size;
  2267. for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
  2268. if (!typeinfo->func_data && !typeinfo->var_data) continue;
  2269. typedata_size = 0;
  2270. if (typeinfo->func_data)
  2271. typedata_size = typeinfo->func_data[0];
  2272. if (typeinfo->var_data)
  2273. typedata_size += typeinfo->var_data[0];
  2274. put_data(&typedata_size, sizeof(int));
  2275. if (typeinfo->func_data)
  2276. put_data(typeinfo->func_data + 1, typeinfo->func_data[0]);
  2277. if (typeinfo->var_data)
  2278. put_data(typeinfo->var_data + 1, typeinfo->var_data[0]);
  2279. if (typeinfo->func_indices)
  2280. put_data(typeinfo->func_indices, (typeinfo->typeinfo->cElement & 0xffff) * 4);
  2281. if (typeinfo->var_indices)
  2282. put_data(typeinfo->var_indices, (typeinfo->typeinfo->cElement >> 16) * 4);
  2283. if (typeinfo->func_names)
  2284. put_data(typeinfo->func_names, (typeinfo->typeinfo->cElement & 0xffff) * 4);
  2285. if (typeinfo->var_names)
  2286. put_data(typeinfo->var_names, (typeinfo->typeinfo->cElement >> 16) * 4);
  2287. if (typeinfo->func_offsets)
  2288. put_data(typeinfo->func_offsets, (typeinfo->typeinfo->cElement & 0xffff) * 4);
  2289. if (typeinfo->var_offsets) {
  2290. int add = 0, i, offset;
  2291. if(typeinfo->func_data)
  2292. add = typeinfo->func_data[0];
  2293. for(i = 0; i < (typeinfo->typeinfo->cElement >> 16); i++) {
  2294. offset = typeinfo->var_offsets[i];
  2295. offset += add;
  2296. put_data(&offset, 4);
  2297. }
  2298. }
  2299. }
  2300. }
  2301. static void save_all_changes(msft_typelib_t *typelib)
  2302. {
  2303. int filepos;
  2304. chat("save_all_changes(%p)\n", typelib);
  2305. filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir);
  2306. if(typelib->typelib_header.varflags & 0x100) filepos += 4; /* helpstringdll */
  2307. filepos += typelib->typelib_header.nrtypeinfos * 4;
  2308. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEINFO);
  2309. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUIDHASH);
  2310. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUID);
  2311. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_REFERENCES);
  2312. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTINFO);
  2313. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTFILES);
  2314. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAMEHASH);
  2315. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAME);
  2316. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_STRING);
  2317. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEDESC);
  2318. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_ARRAYDESC);
  2319. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATA);
  2320. filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATAGUID);
  2321. ctl2_finalize_typeinfos(typelib, filepos);
  2322. init_output_buffer();
  2323. put_data(&typelib->typelib_header, sizeof(typelib->typelib_header));
  2324. if(typelib->typelib_header.varflags & 0x100)
  2325. put_data(&typelib->help_string_dll_offset, sizeof(typelib->help_string_dll_offset));
  2326. put_data(typelib->typelib_typeinfo_offsets, typelib->typelib_header.nrtypeinfos * 4);
  2327. put_data(&typelib->typelib_segdir, sizeof(typelib->typelib_segdir));
  2328. ctl2_write_segment( typelib, MSFT_SEG_TYPEINFO );
  2329. ctl2_write_segment( typelib, MSFT_SEG_GUIDHASH );
  2330. ctl2_write_segment( typelib, MSFT_SEG_GUID );
  2331. ctl2_write_segment( typelib, MSFT_SEG_REFERENCES );
  2332. ctl2_write_segment( typelib, MSFT_SEG_IMPORTINFO );
  2333. ctl2_write_segment( typelib, MSFT_SEG_IMPORTFILES );
  2334. ctl2_write_segment( typelib, MSFT_SEG_NAMEHASH );
  2335. ctl2_write_segment( typelib, MSFT_SEG_NAME );
  2336. ctl2_write_segment( typelib, MSFT_SEG_STRING );
  2337. ctl2_write_segment( typelib, MSFT_SEG_TYPEDESC );
  2338. ctl2_write_segment( typelib, MSFT_SEG_ARRAYDESC );
  2339. ctl2_write_segment( typelib, MSFT_SEG_CUSTDATA );
  2340. ctl2_write_segment( typelib, MSFT_SEG_CUSTDATAGUID );
  2341. ctl2_write_typeinfos(typelib);
  2342. if (strendswith( typelib_name, ".res" )) /* create a binary resource file */
  2343. {
  2344. char typelib_id[13] = "#1";
  2345. expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_ID );
  2346. if (expr)
  2347. sprintf( typelib_id, "#%d", expr->cval );
  2348. add_output_to_resources( "TYPELIB", typelib_id );
  2349. if (strendswith( typelib_name, "_t.res" )) /* add typelib registration */
  2350. output_typelib_regscript( typelib->typelib );
  2351. }
  2352. else flush_output_buffer( typelib_name );
  2353. }
  2354. int create_msft_typelib(typelib_t *typelib)
  2355. {
  2356. msft_typelib_t *msft;
  2357. int failed = 0;
  2358. const statement_t *stmt;
  2359. const attr_t *attr;
  2360. time_t cur_time;
  2361. char *time_override;
  2362. unsigned int version = 7 << 24 | 555; /* 7.00.0555 */
  2363. GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
  2364. GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
  2365. GUID midl_info_guid = {0xde77ba65,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
  2366. char info_string[128];
  2367. msft = xmalloc(sizeof(*msft));
  2368. memset(msft, 0, sizeof(*msft));
  2369. msft->typelib = typelib;
  2370. ctl2_init_header(msft);
  2371. ctl2_init_segdir(msft);
  2372. msft->typelib_header.varflags |= (pointer_size == 8) ? SYS_WIN64 : SYS_WIN32;
  2373. /*
  2374. * The following two calls return an offset or -1 if out of memory. We
  2375. * specifically need an offset of 0, however, so...
  2376. */
  2377. if (ctl2_alloc_segment(msft, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; }
  2378. if (ctl2_alloc_segment(msft, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; }
  2379. if(failed)
  2380. {
  2381. free(msft);
  2382. return 0;
  2383. }
  2384. msft->typelib_guidhash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_GUIDHASH];
  2385. msft->typelib_namehash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_NAMEHASH];
  2386. memset(msft->typelib_guidhash_segment, 0xff, 0x80);
  2387. memset(msft->typelib_namehash_segment, 0xff, 0x200);
  2388. set_lib_flags(msft);
  2389. set_lcid(msft);
  2390. set_help_file_name(msft);
  2391. set_doc_string(msft);
  2392. set_guid(msft);
  2393. set_version(msft);
  2394. set_name(msft);
  2395. set_help_context(msft);
  2396. set_help_string_dll(msft);
  2397. set_help_string_context(msft);
  2398. if (typelib->attrs) LIST_FOR_EACH_ENTRY( attr, typelib->attrs, const attr_t, entry ) {
  2399. switch(attr->type) {
  2400. case ATTR_CUSTOM:
  2401. set_custdata_attr(msft, attr->u.pval, &msft->typelib_header.CustomDataOffset);
  2402. break;
  2403. default:
  2404. break;
  2405. }
  2406. }
  2407. /* midl adds two sets of custom data to the library: the current unix time
  2408. and midl's version number */
  2409. time_override = getenv( "WIDL_TIME_OVERRIDE");
  2410. cur_time = time_override ? atol( time_override) : time(NULL);
  2411. sprintf(info_string, "Created by WIDL version %s at %s", PACKAGE_VERSION, ctime(&cur_time));
  2412. set_custdata(msft, &midl_info_guid, VT_BSTR, info_string, &msft->typelib_header.CustomDataOffset);
  2413. set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset);
  2414. set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset);
  2415. if (typelib->stmts)
  2416. LIST_FOR_EACH_ENTRY( stmt, typelib->stmts, const statement_t, entry )
  2417. add_entry(msft, stmt);
  2418. save_all_changes(msft);
  2419. free(msft);
  2420. return 1;
  2421. }