write_msft.c 93 KB

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