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