include/msvcrt: Define more CPU control word flags.
[wine] / dlls / oleaut32 / typelib2.c
1 /*
2  *      TYPELIB2
3  *
4  *      Copyright 2004  Alastair Bridgewater
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * --------------------------------------------------------------------------------------
21  *  Known problems:
22  *
23  *    Badly incomplete.
24  *
25  *    Only works on little-endian systems.
26  *
27  */
28
29 #include "config.h"
30 #include "wine/port.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <ctype.h>
37
38 #define COBJMACROS
39 #define NONAMELESSUNION
40 #define NONAMELESSSTRUCT
41
42 #include "winerror.h"
43 #include "windef.h"
44 #include "winbase.h"
45 #include "winnls.h"
46 #include "winreg.h"
47 #include "winuser.h"
48
49 #include "wine/unicode.h"
50 #include "objbase.h"
51 #include "typelib.h"
52 #include "wine/debug.h"
53
54 WINE_DEFAULT_DEBUG_CHANNEL(typelib2);
55 /* WINE_DEFAULT_DEBUG_CHANNEL(ole); */
56
57
58 /******************************************************************************
59  * ICreateTypeLib2 {OLEAUT32}
60  *
61  * NOTES
62  *  The ICreateTypeLib2 interface provides an interface whereby one may create
63  *  new type library (.tlb) files.
64  *
65  *  This interface inherits from ICreateTypeLib, and can be freely cast back
66  *  and forth between an ICreateTypeLib and an ICreateTypeLib2 on local clients.
67  *  This dispensation applies only to ICreateTypeLib objects obtained on MSFT
68  *  format type libraries (those made through CreateTypeLib2).
69  *
70  * METHODS
71  */
72
73 /******************************************************************************
74  * ICreateTypeInfo2 {OLEAUT32}
75  *
76  * NOTES
77  *  The ICreateTypeInfo2 interface provides an interface whereby one may add
78  *  type information to type library (.tlb) files.
79  *
80  *  This interface inherits from ICreateTypeInfo, and can be freely cast back
81  *  and forth between an ICreateTypeInfo and an ICreateTypeInfo2 on local clients.
82  *  This dispensation applies only to ICreateTypeInfo objects obtained on MSFT
83  *  format type libraries (those made through CreateTypeLib2).
84  *
85  * METHODS
86  */
87
88 /******************************************************************************
89  * ITypeLib2 {OLEAUT32}
90  *
91  * NOTES
92  *  The ITypeLib2 interface provides an interface whereby one may query MSFT
93  *  format type library (.tlb) files.
94  *
95  *  This interface inherits from ITypeLib, and can be freely cast back and
96  *  forth between an ITypeLib and an ITypeLib2 on local clients. This
97  *  dispensation applies only to ITypeLib objects obtained on MSFT format type
98  *  libraries (those made through CreateTypeLib2).
99  *
100  * METHODS
101  */
102
103 /******************************************************************************
104  * ITypeInfo2 {OLEAUT32}
105  *
106  * NOTES
107  *  The ITypeInfo2 interface provides an interface whereby one may query type
108  *  information stored in MSFT format type library (.tlb) files.
109  *
110  *  This interface inherits from ITypeInfo, and can be freely cast back and
111  *  forth between an ITypeInfo and an ITypeInfo2 on local clients. This
112  *  dispensation applies only to ITypeInfo objects obtained on MSFT format type
113  *  libraries (those made through CreateTypeLib2).
114  *
115  * METHODS
116  */
117
118 /*================== Implementation Structures ===================================*/
119
120 /* Used for storing cyclic list. Tail address is kept */
121 typedef enum tagCyclicListElementType {
122     CyclicListSentinel,
123     CyclicListFunc,
124     CyclicListVar
125 } CyclicListElementType;
126 typedef struct tagCyclicList {
127     struct tagCyclicList *next;
128     int indice;
129     int name;
130     CyclicListElementType type;
131
132     union {
133         int val;
134         int *data;
135     }u;
136 } CyclicList;
137
138 enum MSFT_segment_index {
139     MSFT_SEG_TYPEINFO = 0,  /* type information */
140     MSFT_SEG_IMPORTINFO,    /* import information */
141     MSFT_SEG_IMPORTFILES,   /* import filenames */
142     MSFT_SEG_REFERENCES,    /* references (?) */
143     MSFT_SEG_GUIDHASH,      /* hash table for guids? */
144     MSFT_SEG_GUID,          /* guid storage */
145     MSFT_SEG_NAMEHASH,      /* hash table for names */
146     MSFT_SEG_NAME,          /* name storage */
147     MSFT_SEG_STRING,        /* string storage */
148     MSFT_SEG_TYPEDESC,      /* type descriptions */
149     MSFT_SEG_ARRAYDESC,     /* array descriptions */
150     MSFT_SEG_CUSTDATA,      /* custom data */
151     MSFT_SEG_CUSTDATAGUID,  /* custom data guids */
152     MSFT_SEG_UNKNOWN,       /* ??? */
153     MSFT_SEG_UNKNOWN2,      /* ??? */
154     MSFT_SEG_MAX            /* total number of segments */
155 };
156
157 typedef struct tagMSFT_ImpFile {
158     int guid;
159     LCID lcid;
160     int version;
161     char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */
162 } MSFT_ImpFile;
163
164 typedef struct tagICreateTypeLib2Impl
165 {
166     const ICreateTypeLib2Vtbl *lpVtbl;
167     const ITypeLib2Vtbl       *lpVtblTypeLib2;
168
169     LONG ref;
170
171     WCHAR *filename;
172
173     MSFT_Header typelib_header;
174     INT helpStringDll;
175     MSFT_pSeg typelib_segdir[MSFT_SEG_MAX];
176     char *typelib_segment_data[MSFT_SEG_MAX];
177     int typelib_segment_block_length[MSFT_SEG_MAX];
178
179     int typelib_guids; /* Number of defined typelib guids */
180     int typeinfo_guids; /* Number of defined typeinfo guids */
181
182     INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */
183
184     INT *typelib_namehash_segment;
185     INT *typelib_guidhash_segment;
186
187     struct tagICreateTypeInfo2Impl *typeinfos;
188     struct tagICreateTypeInfo2Impl *last_typeinfo;
189 } ICreateTypeLib2Impl;
190
191 static inline ICreateTypeLib2Impl *impl_from_ITypeLib2( ITypeLib2 *iface )
192 {
193     return (ICreateTypeLib2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeLib2Impl, lpVtblTypeLib2));
194 }
195
196 typedef struct tagICreateTypeInfo2Impl
197 {
198     const ICreateTypeInfo2Vtbl *lpVtbl;
199     const ITypeInfo2Vtbl       *lpVtblTypeInfo2;
200
201     LONG ref;
202
203     ICreateTypeLib2Impl *typelib;
204     MSFT_TypeInfoBase *typeinfo;
205
206     struct tagCyclicList *typedata; /* tail of cyclic list */
207
208     TYPEKIND typekind;
209     int datawidth;
210
211     struct tagICreateTypeInfo2Impl *next_typeinfo;
212     struct tagICreateTypeInfo2Impl *dual;
213 } ICreateTypeInfo2Impl;
214
215 static inline ICreateTypeInfo2Impl *impl_from_ITypeInfo2( ITypeInfo2 *iface )
216 {
217     return (ICreateTypeInfo2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeInfo2Impl, lpVtblTypeInfo2));
218 }
219
220 static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface);
221
222 static CyclicList *alloc_cyclic_list_item(CyclicListElementType type)
223 {
224     CyclicList *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CyclicList));
225     if (!ret)
226         return NULL;
227     ret->type = type;
228     return ret;
229 }
230
231 /*================== Internal functions ===================================*/
232
233 /****************************************************************************
234  *      ctl2_init_header
235  *
236  *  Initializes the type library header of a new typelib.
237  */
238 static void ctl2_init_header(
239         ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */
240 {
241     This->typelib_header.magic1 = 0x5446534d;
242     This->typelib_header.magic2 = 0x00010002;
243     This->typelib_header.posguid = -1;
244     This->typelib_header.lcid = This->typelib_header.lcid2 = GetUserDefaultLCID();
245     This->typelib_header.varflags = 0x40;
246     This->typelib_header.version = 0;
247     This->typelib_header.flags = 0;
248     This->typelib_header.nrtypeinfos = 0;
249     This->typelib_header.helpstring = -1;
250     This->typelib_header.helpstringcontext = 0;
251     This->typelib_header.helpcontext = 0;
252     This->typelib_header.nametablecount = 0;
253     This->typelib_header.nametablechars = 0;
254     This->typelib_header.NameOffset = -1;
255     This->typelib_header.helpfile = -1;
256     This->typelib_header.CustomDataOffset = -1;
257     This->typelib_header.res44 = 0x20;
258     This->typelib_header.res48 = 0x80;
259     This->typelib_header.dispatchpos = -1;
260     This->typelib_header.nimpinfos = 0;
261     This->helpStringDll = -1;
262 }
263
264 /****************************************************************************
265  *      ctl2_init_segdir
266  *
267  *  Initializes the segment directory of a new typelib.
268  */
269 static void ctl2_init_segdir(
270         ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */
271 {
272     int i;
273     MSFT_pSeg *segdir;
274
275     segdir = &This->typelib_segdir[MSFT_SEG_TYPEINFO];
276
277     for (i = 0; i < 15; i++) {
278         segdir[i].offset = -1;
279         segdir[i].length = 0;
280         segdir[i].res08 = -1;
281         segdir[i].res0c = 0x0f;
282     }
283 }
284
285 /****************************************************************************
286  *      ctl2_hash_guid
287  *
288  *  Generates a hash key from a GUID.
289  *
290  * RETURNS
291  *
292  *  The hash key for the GUID.
293  */
294 static int ctl2_hash_guid(
295         REFGUID guid)                /* [I] The guid to find. */
296 {
297     int hash;
298     int i;
299
300     hash = 0;
301     for (i = 0; i < 8; i ++) {
302         hash ^= ((const short *)guid)[i];
303     }
304
305     return hash & 0x1f;
306 }
307
308 /****************************************************************************
309  *      ctl2_find_guid
310  *
311  *  Locates a guid in a type library.
312  *
313  * RETURNS
314  *
315  *  The offset into the GUID segment of the guid, or -1 if not found.
316  */
317 static int ctl2_find_guid(
318         ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */
319         int hash_key,              /* [I] The hash key for the guid. */
320         REFGUID guid)                /* [I] The guid to find. */
321 {
322     int offset;
323     MSFT_GuidEntry *guidentry;
324
325     offset = This->typelib_guidhash_segment[hash_key];
326     while (offset != -1) {
327         guidentry = (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][offset];
328
329         if (IsEqualGUID(guidentry, guid)) return offset;
330
331         offset = guidentry->next_hash;
332     }
333
334     return offset;
335 }
336
337 /****************************************************************************
338  *      ctl2_find_name
339  *
340  *  Locates a name in a type library.
341  *
342  * RETURNS
343  *
344  *  The offset into the NAME segment of the name, or -1 if not found.
345  *
346  * NOTES
347  *
348  *  The name must be encoded as with ctl2_encode_name().
349  */
350 static int ctl2_find_name(
351         ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */
352         const char *name)          /* [I] The encoded name to find. */
353 {
354     int offset;
355     int *namestruct;
356
357     offset = This->typelib_namehash_segment[name[2] & 0x7f];
358     while (offset != -1) {
359         namestruct = (int *)&This->typelib_segment_data[MSFT_SEG_NAME][offset];
360
361         if (!((namestruct[2] ^ *((const int *)name)) & 0xffff00ff)) {
362             /* hash codes and lengths match, final test */
363             if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break;
364         }
365
366         /* move to next item in hash bucket */
367         offset = namestruct[1];
368     }
369
370     return offset;
371 }
372
373 /****************************************************************************
374  *      ctl2_encode_name
375  *
376  *  Encodes a name string to a form suitable for storing into a type library
377  *  or comparing to a name stored in a type library.
378  *
379  * RETURNS
380  *
381  *  The length of the encoded name, including padding and length+hash fields.
382  *
383  * NOTES
384  *
385  *  Will throw an exception if name or result are NULL. Is not multithread
386  *  safe in the slightest.
387  */
388 static int ctl2_encode_name(
389         ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (used for LCID only). */
390         const WCHAR *name,         /* [I] The name string to encode. */
391         char **result)             /* [O] A pointer to a pointer to receive the encoded name. */
392 {
393     int length;
394     static char converted_name[0x104];
395     int offset;
396     int value;
397
398     length = WideCharToMultiByte(CP_ACP, 0, name, strlenW(name), converted_name+4, 0x100, NULL, NULL);
399     converted_name[0] = length & 0xff;
400
401     converted_name[length + 4] = 0;
402
403     converted_name[1] = 0x00;
404
405     value = LHashValOfNameSysA(This->typelib_header.varflags & 0x0f, This->typelib_header.lcid, converted_name + 4);
406
407     converted_name[2] = value;
408     converted_name[3] = value >> 8;
409
410     for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57;
411
412     *result = converted_name;
413
414     return (length + 7) & ~3;
415 }
416
417 /****************************************************************************
418  *      ctl2_decode_name
419  *
420  * Converts string stored in typelib data to unicode.
421  */
422 static void ctl2_decode_name(
423         char *data,         /* [I] String to be decoded */
424         WCHAR **string)     /* [O] Decoded string */
425 {
426     int i, length;
427     static WCHAR converted_string[0x104];
428
429     length = data[0];
430
431     for(i=0; i<length; i++)
432         converted_string[i] = data[i+4];
433     converted_string[length] = '\0';
434
435     *string = converted_string;
436 }
437
438 /****************************************************************************
439  *      ctl2_encode_string
440  *
441  *  Encodes a string to a form suitable for storing into a type library or
442  *  comparing to a string stored in a type library.
443  *
444  * RETURNS
445  *
446  *  The length of the encoded string, including padding and length fields.
447  *
448  * NOTES
449  *
450  *  Will throw an exception if string or result are NULL. Is not multithread
451  *  safe in the slightest.
452  */
453 static int ctl2_encode_string(
454         ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (not used?). */
455         const WCHAR *string,       /* [I] The string to encode. */
456         char **result)             /* [O] A pointer to a pointer to receive the encoded string. */
457 {
458     int length;
459     static char converted_string[0x104];
460     int offset;
461
462     length = WideCharToMultiByte(CP_ACP, 0, string, strlenW(string), converted_string+2, 0x102, NULL, NULL);
463     converted_string[0] = length & 0xff;
464     converted_string[1] = (length >> 8) & 0xff;
465
466     for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57;
467
468     *result = converted_string;
469
470     return (length + 5) & ~3;
471 }
472
473 /****************************************************************************
474  *      ctl2_decode_string
475  *
476  * Converts string stored in typelib data to unicode.
477  */
478 static void ctl2_decode_string(
479         char *data,         /* [I] String to be decoded */
480         WCHAR **string)     /* [O] Decoded string */
481 {
482     int i, length;
483     static WCHAR converted_string[0x104];
484
485     length = data[0] + (data[1]<<8);
486     if((length&0x3) == 1)
487         length >>= 2;
488
489     for(i=0; i<length; i++)
490         converted_string[i] = data[i+2];
491     converted_string[length] = '\0';
492
493     *string = converted_string;
494 }
495
496 /****************************************************************************
497  *      ctl2_alloc_segment
498  *
499  *  Allocates memory from a segment in a type library.
500  *
501  * RETURNS
502  *
503  *  Success: The offset within the segment of the new data area.
504  *  Failure: -1 (this is invariably an out of memory condition).
505  *
506  * BUGS
507  *
508  *  Does not (yet) handle the case where the allocated segment memory needs to grow.
509  */
510 static int ctl2_alloc_segment(
511         ICreateTypeLib2Impl *This,       /* [I] The type library in which to allocate. */
512         enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */
513         int size,                        /* [I] The amount to allocate. */
514         int block_size)                  /* [I] Initial allocation block size, or 0 for default. */
515 {
516     int offset;
517
518     if(!This->typelib_segment_data[segment]) {
519         if (!block_size) block_size = 0x2000;
520
521         This->typelib_segment_block_length[segment] = block_size;
522         This->typelib_segment_data[segment] = HeapAlloc(GetProcessHeap(), 0, block_size);
523         if (!This->typelib_segment_data[segment]) return -1;
524         memset(This->typelib_segment_data[segment], 0x57, block_size);
525     }
526
527     while ((This->typelib_segdir[segment].length + size) > This->typelib_segment_block_length[segment]) {
528         char *block;
529
530         block_size = This->typelib_segment_block_length[segment];
531         block = HeapReAlloc(GetProcessHeap(), 0, This->typelib_segment_data[segment], block_size << 1);
532         if (!block) return -1;
533
534         if (segment == MSFT_SEG_TYPEINFO) {
535             /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */
536             ICreateTypeInfo2Impl *typeinfo;
537
538             for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
539                 typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - This->typelib_segment_data[segment]];
540             }
541         }
542
543         memset(block + block_size, 0x57, block_size);
544         This->typelib_segment_block_length[segment] = block_size << 1;
545         This->typelib_segment_data[segment] = block;
546     }
547
548     offset = This->typelib_segdir[segment].length;
549     This->typelib_segdir[segment].length += size;
550
551     return offset;
552 }
553
554 /****************************************************************************
555  *      ctl2_alloc_typeinfo
556  *
557  *  Allocates and initializes a typeinfo structure in a type library.
558  *
559  * RETURNS
560  *
561  *  Success: The offset of the new typeinfo.
562  *  Failure: -1 (this is invariably an out of memory condition).
563  */
564 static int ctl2_alloc_typeinfo(
565         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
566         int nameoffset)            /* [I] The offset of the name for this typeinfo. */
567 {
568     int offset;
569     MSFT_TypeInfoBase *typeinfo;
570
571     offset = ctl2_alloc_segment(This, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0);
572     if (offset == -1) return -1;
573
574     This->typelib_typeinfo_offsets[This->typelib_header.nrtypeinfos++] = offset;
575
576     typeinfo = (void *)(This->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset);
577
578     typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16;
579     typeinfo->memoffset = -1; /* should be EOF if no elements */
580     typeinfo->res2 = 0;
581     typeinfo->res3 = 0;
582     typeinfo->res4 = 3;
583     typeinfo->res5 = 0;
584     typeinfo->cElement = 0;
585     typeinfo->res7 = 0;
586     typeinfo->res8 = 0;
587     typeinfo->res9 = 0;
588     typeinfo->resA = 0;
589     typeinfo->posguid = -1;
590     typeinfo->flags = 0;
591     typeinfo->NameOffset = nameoffset;
592     typeinfo->version = 0;
593     typeinfo->docstringoffs = -1;
594     typeinfo->helpstringcontext = 0;
595     typeinfo->helpcontext = 0;
596     typeinfo->oCustData = -1;
597     typeinfo->cbSizeVft = 0;
598     typeinfo->cImplTypes = 0;
599     typeinfo->size = 0;
600     typeinfo->datatype1 = -1;
601     typeinfo->datatype2 = 0;
602     typeinfo->res18 = 0;
603     typeinfo->res19 = -1;
604
605     return offset;
606 }
607
608 /****************************************************************************
609  *      ctl2_alloc_guid
610  *
611  *  Allocates and initializes a GUID structure in a type library. Also updates
612  *  the GUID hash table as needed.
613  *
614  * RETURNS
615  *
616  *  Success: The offset of the new GUID.
617  *  Failure: -1 (this is invariably an out of memory condition).
618  */
619 static int ctl2_alloc_guid(
620         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
621         MSFT_GuidEntry *guid)      /* [I] The GUID to store. */
622 {
623     int offset;
624     MSFT_GuidEntry *guid_space;
625     int hash_key;
626
627     hash_key = ctl2_hash_guid(&guid->guid);
628
629     offset = ctl2_find_guid(This, hash_key, &guid->guid);
630     if (offset != -1) return offset;
631
632     offset = ctl2_alloc_segment(This, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0);
633     if (offset == -1) return -1;
634
635     guid_space = (void *)(This->typelib_segment_data[MSFT_SEG_GUID] + offset);
636     *guid_space = *guid;
637
638     guid_space->next_hash = This->typelib_guidhash_segment[hash_key];
639     This->typelib_guidhash_segment[hash_key] = offset;
640
641     return offset;
642 }
643
644 /****************************************************************************
645  *      ctl2_alloc_name
646  *
647  *  Allocates and initializes a name within a type library. Also updates the
648  *  name hash table as needed.
649  *
650  * RETURNS
651  *
652  *  Success: The offset within the segment of the new name.
653  *  Failure: -1 (this is invariably an out of memory condition).
654  */
655 static int ctl2_alloc_name(
656         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
657         const WCHAR *name)         /* [I] The name to store. */
658 {
659     int length;
660     int offset;
661     MSFT_NameIntro *name_space;
662     char *encoded_name;
663
664     length = ctl2_encode_name(This, name, &encoded_name);
665
666     offset = ctl2_find_name(This, encoded_name);
667     if (offset != -1) return offset;
668
669     offset = ctl2_alloc_segment(This, MSFT_SEG_NAME, length + 8, 0);
670     if (offset == -1) return -1;
671
672     name_space = (void *)(This->typelib_segment_data[MSFT_SEG_NAME] + offset);
673     name_space->hreftype = -1;
674     name_space->next_hash = -1;
675     memcpy(&name_space->namelen, encoded_name, length);
676
677     if (This->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1)
678         name_space->next_hash = This->typelib_namehash_segment[encoded_name[2] & 0x7f];
679
680     This->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset;
681
682     This->typelib_header.nametablecount += 1;
683     This->typelib_header.nametablechars += *encoded_name;
684
685     return offset;
686 }
687
688 /****************************************************************************
689  *      ctl2_alloc_string
690  *
691  *  Allocates and initializes a string in a type library.
692  *
693  * RETURNS
694  *
695  *  Success: The offset within the segment of the new string.
696  *  Failure: -1 (this is invariably an out of memory condition).
697  */
698 static int ctl2_alloc_string(
699         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
700         const WCHAR *string)       /* [I] The string to store. */
701 {
702     int length;
703     int offset;
704     char *string_space;
705     char *encoded_string;
706
707     length = ctl2_encode_string(This, string, &encoded_string);
708
709     for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_STRING].length;
710          offset += ((((This->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff)
711              | (This->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) {
712         if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset;
713     }
714
715     offset = ctl2_alloc_segment(This, MSFT_SEG_STRING, length, 0);
716     if (offset == -1) return -1;
717
718     string_space = This->typelib_segment_data[MSFT_SEG_STRING] + offset;
719     memcpy(string_space, encoded_string, length);
720
721     return offset;
722 }
723
724 /****************************************************************************
725  *      ctl2_alloc_importinfo
726  *
727  *  Allocates and initializes an import information structure in a type library.
728  *
729  * RETURNS
730  *
731  *  Success: The offset of the new importinfo.
732  *  Failure: -1 (this is invariably an out of memory condition).
733  */
734 static int ctl2_alloc_importinfo(
735         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
736         MSFT_ImpInfo *impinfo)     /* [I] The import information to store. */
737 {
738     int offset;
739     MSFT_ImpInfo *impinfo_space;
740
741     impinfo_space = (MSFT_ImpInfo*)&This->typelib_segment_data[MSFT_SEG_IMPORTINFO][0];
742     for (offset=0; offset<This->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
743             offset+=sizeof(MSFT_ImpInfo)) {
744         if(impinfo_space->oImpFile == impinfo->oImpFile
745                 && impinfo_space->oGuid == impinfo->oGuid)
746             return offset;
747
748         impinfo_space += 1;
749     }
750
751     impinfo->flags |= This->typelib_header.nimpinfos++;
752
753     offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0);
754     if (offset == -1) return -1;
755
756     impinfo_space = (void *)(This->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset);
757     *impinfo_space = *impinfo;
758
759     return offset;
760 }
761
762 /****************************************************************************
763  *      ctl2_alloc_importfile
764  *
765  *  Allocates and initializes an import file definition in a type library.
766  *
767  * RETURNS
768  *
769  *  Success: The offset of the new importinfo.
770  *  Failure: -1 (this is invariably an out of memory condition).
771  */
772 static int ctl2_alloc_importfile(
773         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
774         int guidoffset,            /* [I] The offset to the GUID for the imported library. */
775         LCID lcid,                 /* [I] The LCID of imported library. */
776         int major_version,         /* [I] The major version number of the imported library. */
777         int minor_version,         /* [I] The minor version number of the imported library. */
778         const WCHAR *filename)     /* [I] The filename of the imported library. */
779 {
780     int length;
781     int offset;
782     MSFT_ImpFile *importfile;
783     char *encoded_string;
784
785     length = ctl2_encode_string(This, filename, &encoded_string);
786
787     encoded_string[0] <<= 2;
788     encoded_string[0] |= 1;
789
790     for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_IMPORTFILES].length;
791          offset += ((((((This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff00)
792              | (This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 5) & 0xfffc) + 0xc) {
793         if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset;
794     }
795
796     offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTFILES, length + 0xc, 0);
797     if (offset == -1) return -1;
798
799     importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset];
800     importfile->guid = guidoffset;
801     importfile->lcid = lcid;
802     importfile->version = major_version | (minor_version << 16);
803     memcpy(importfile->filename, encoded_string, length);
804
805     return offset;
806 }
807
808 /****************************************************************************
809  *      ctl2_encode_variant
810  *
811  *  Encodes a variant, inline if possible or in custom data segment
812  *
813  * RETURNS
814  *
815  *  Success: S_OK
816  *  Failure: Error code from winerror.h
817  */
818 static HRESULT ctl2_encode_variant(
819         ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */
820         int *encoded_value,        /* [O] The encoded default value or data offset */
821         VARIANT *value,            /* [I] Default value to be encoded */
822         VARTYPE arg_type)          /* [I] Argument type */
823 {
824     VARIANT v;
825     HRESULT hres;
826     int mask = 0;
827
828     TRACE("%p %d %d\n", This, V_VT(value), arg_type);
829
830     if(arg_type == VT_INT)
831         arg_type = VT_I4;
832     if(arg_type == VT_UINT)
833         arg_type = VT_UI4;
834
835     v = *value;
836     if(V_VT(value) != arg_type) {
837         hres = VariantChangeType(&v, value, 0, arg_type);
838         if(FAILED(hres))
839             return hres;
840     }
841
842     /* Check if default value can be stored in encoded_value */
843     switch(arg_type) {
844     case VT_I4:
845     case VT_UI4:
846         mask = 0x3ffffff;
847         if(V_UI4(&v)>0x3ffffff)
848             break;
849     case VT_I1:
850     case VT_UI1:
851     case VT_BOOL:
852          if(!mask)
853              mask = 0xff;
854     case VT_I2:
855     case VT_UI2:
856         if(!mask)
857             mask = 0xffff;
858         *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24);
859         return S_OK;
860     }
861
862     switch(arg_type) {
863     case VT_I4:
864     case VT_R4:
865     case VT_UI4:
866     case VT_INT:
867     case VT_UINT:
868     case VT_HRESULT:
869     case VT_PTR: {
870         /* Construct the data to be allocated */
871         int data[2];
872         data[0] = arg_type + (V_UI4(&v)<<16);
873         data[1] = (V_UI4(&v)>>16) + 0x57570000;
874
875         /* Check if the data was already allocated */
876         /* Currently the structures doesn't allow to do it in a nice way */
877         for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-8; *encoded_value+=4)
878             if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8))
879                 return S_OK;
880
881         /* Allocate the data */
882         *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0);
883         if(*encoded_value == -1)
884             return E_OUTOFMEMORY;
885
886         memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8);
887         return S_OK;
888     }
889     case VT_BSTR: {
890         /* Construct the data */
891         int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3;
892         char *data = HeapAlloc(GetProcessHeap(), 0, len);
893
894         if(!data)
895             return E_OUTOFMEMORY;
896
897         *((unsigned short*)data) = arg_type;
898         *((unsigned*)(data+2)) = SysStringLen(V_BSTR(&v));
899         for(i=0; i<SysStringLen(V_BSTR(&v)); i++) {
900             if(V_BSTR(&v)[i] <= 0x7f)
901                 data[i+6] = V_BSTR(&v)[i];
902             else
903                 data[i+6] = '?';
904         }
905         WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), SysStringLen(V_BSTR(&v)), &data[6], len-6, NULL, NULL);
906         for(i=6+SysStringLen(V_BSTR(&v)); i<len; i++)
907             data[i] = 0x57;
908
909         /* Check if the data was already allocated */
910         for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4)
911             if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) {
912                 HeapFree(GetProcessHeap(), 0, data);
913                 return S_OK;
914             }
915
916         /* Allocate the data */
917         *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0);
918         if(*encoded_value == -1) {
919             HeapFree(GetProcessHeap(), 0, data);
920             return E_OUTOFMEMORY;
921         }
922
923         memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len);
924         HeapFree(GetProcessHeap(), 0, data);
925         return S_OK;
926     }
927     default:
928         FIXME("Argument type not yet handled\n");
929         return E_NOTIMPL;
930     }
931 }
932
933 static int ctl2_find_custdata(
934     ICreateTypeLib2Impl *This,
935     REFGUID guid,
936     int offset)
937 {
938     while (offset != -1) {
939         MSFT_CDGuid *cdentry =
940             (MSFT_CDGuid *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset];
941         MSFT_GuidEntry *guidentry =
942             (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][cdentry->GuidOffset];
943
944         if (IsEqualGUID(guidentry, guid))
945             return offset;
946
947         offset = cdentry->next;
948     }
949
950     return -1;
951 }
952
953 /****************************************************************************
954  *      ctl2_decode_variant
955  *
956  *  Decodes a variant
957  *
958  * RETURNS
959  *
960  *  Success: S_OK
961  *  Failure: Error code from winerror.h
962  */
963 static HRESULT ctl2_decode_variant(
964         ICreateTypeLib2Impl *This, /* [I] The typelib that contains the variant */
965         int data_offs,             /* [I] Offset within the data array, or the encoded value itself */
966         VARIANT *value)            /* [O] Decoded value */
967 {
968     char *encoded_data;
969     VARTYPE type;
970
971     if (data_offs & 0x80000000) {
972         /* data_offs contains the encoded value */
973         V_VT(value) = (data_offs & ~0x80000000) >> 26;
974         V_UI4(value) = data_offs & ~0xFF000000;
975         return S_OK;
976     }
977
978     encoded_data = &This->typelib_segment_data[MSFT_SEG_CUSTDATA][data_offs];
979     type = *encoded_data;
980
981     switch(type) {
982     case VT_I4:
983     case VT_R4:
984     case VT_UI4:
985     case VT_INT:
986     case VT_UINT:
987     case VT_HRESULT:
988     case VT_PTR: {
989         V_VT(value) = type;
990         V_UI4(value) = *(unsigned*)(encoded_data + 2);
991         return S_OK;
992     }
993     case VT_BSTR: {
994         unsigned len, i;
995
996         len = *(unsigned*)(encoded_data + 2);
997
998         V_VT(value) = type;
999         V_BSTR(value) = SysAllocStringByteLen(NULL, len * sizeof(OLECHAR));
1000         for (i = 0; i < len; ++i)
1001             V_BSTR(value)[i] = *(encoded_data + 6 + i);
1002
1003         return S_OK;
1004     }
1005     default:
1006         FIXME("Don't yet have decoder for this VARTYPE: %u\n", type);
1007         return E_NOTIMPL;
1008     }
1009 }
1010
1011 /****************************************************************************
1012  *      ctl2_set_custdata
1013  *
1014  *  Adds a custom data element to an object in a type library.
1015  *
1016  * RETURNS
1017  *
1018  *  Success: S_OK.
1019  *  Failure: One of E_INVALIDARG or E_OUTOFMEMORY.
1020  */
1021 static HRESULT ctl2_set_custdata(
1022         ICreateTypeLib2Impl *This, /* [I] The type library to store the custom data in. */
1023         REFGUID guid,              /* [I] The GUID used as a key to retrieve the custom data. */
1024         VARIANT *pVarVal,          /* [I] The custom data itself. */
1025         int *offset)               /* [I/O] The list of custom data to prepend to. */
1026 {
1027     MSFT_GuidEntry guidentry;
1028     HRESULT status;
1029     int dataoffset;
1030     int guidoffset;
1031     int custoffset;
1032     int *custdata;
1033     BOOL new_segment = FALSE;
1034
1035     switch(V_VT(pVarVal))
1036     {
1037     case VT_I4:
1038     case VT_R4:
1039     case VT_UI4:
1040     case VT_INT:
1041     case VT_UINT:
1042     case VT_HRESULT:
1043     case VT_BSTR:
1044         /* empty */
1045         break;
1046     default:
1047         return DISP_E_BADVARTYPE;
1048     }
1049
1050     guidentry.guid = *guid;
1051
1052     guidentry.hreftype = -1;
1053     guidentry.next_hash = -1;
1054
1055     guidoffset = ctl2_alloc_guid(This, &guidentry);
1056     if (guidoffset == -1) return E_OUTOFMEMORY;
1057
1058     status = ctl2_encode_variant(This, &dataoffset, pVarVal, V_VT(pVarVal));
1059     if (status)
1060         return status;
1061
1062     custoffset = ctl2_find_custdata(This, guid, *offset);
1063     if (custoffset == -1) {
1064         custoffset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATAGUID, 12, 0);
1065         if (custoffset == -1)
1066             return E_OUTOFMEMORY;
1067         new_segment = TRUE;
1068     }
1069
1070     custdata = (int *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset];
1071     custdata[0] = guidoffset;
1072     custdata[1] = dataoffset;
1073     if (new_segment) {
1074         custdata[2] = *offset;
1075         *offset = custoffset;
1076     }
1077
1078     return S_OK;
1079 }
1080
1081 /****************************************************************************
1082  *      ctl2_encode_typedesc
1083  *
1084  *  Encodes a type description, storing information in the TYPEDESC and ARRAYDESC
1085  *  segments as needed.
1086  *
1087  * RETURNS
1088  *
1089  *  Success: 0.
1090  *  Failure: -1.
1091  */
1092 static int ctl2_encode_typedesc(
1093         ICreateTypeLib2Impl *This, /* [I] The type library in which to encode the TYPEDESC. */
1094         const TYPEDESC *tdesc,     /* [I] The type description to encode. */
1095         int *encoded_tdesc,        /* [O] The encoded type description. */
1096         int *width,                /* [O] The width of the type, or NULL. */
1097         int *alignment,            /* [O] The alignment of the type, or NULL. */
1098         int *decoded_size)         /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
1099 {
1100     int default_tdesc;
1101     int scratch;
1102     int typeoffset;
1103     int arrayoffset;
1104     int *typedata;
1105     int *arraydata;
1106     int target_type;
1107     int child_size;
1108
1109     default_tdesc = 0x80000000 | (tdesc->vt << 16) | tdesc->vt;
1110     if (!width) width = &scratch;
1111     if (!alignment) alignment = &scratch;
1112     if (!decoded_size) decoded_size = &scratch;
1113
1114     *decoded_size = 0;
1115
1116     switch (tdesc->vt) {
1117     case VT_UI1:
1118     case VT_I1:
1119         *encoded_tdesc = default_tdesc;
1120         *width = 1;
1121         *alignment = 1;
1122         break;
1123
1124     case VT_INT:
1125         *encoded_tdesc = 0x80000000 | (VT_I4 << 16) | VT_INT;
1126         if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) {
1127             *width = 2;
1128             *alignment = 2;
1129         } else {
1130             *width = 4;
1131             *alignment = 4;
1132         }
1133         break;
1134
1135     case VT_UINT:
1136         *encoded_tdesc = 0x80000000 | (VT_UI4 << 16) | VT_UINT;
1137         if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) {
1138             *width = 2;
1139             *alignment = 2;
1140         } else {
1141             *width = 4;
1142             *alignment = 4;
1143         }
1144         break;
1145
1146     case VT_UI2:
1147     case VT_I2:
1148     case VT_BOOL:
1149         *encoded_tdesc = default_tdesc;
1150         *width = 2;
1151         *alignment = 2;
1152         break;
1153
1154     case VT_I4:
1155     case VT_UI4:
1156     case VT_R4:
1157     case VT_ERROR:
1158     case VT_BSTR:
1159     case VT_HRESULT:
1160         *encoded_tdesc = default_tdesc;
1161         *width = 4;
1162         *alignment = 4;
1163         break;
1164
1165     case VT_CY:
1166         *encoded_tdesc = default_tdesc;
1167         *width = 8;
1168         *alignment = 4; /* guess? */
1169         break;
1170
1171     case VT_VOID:
1172         *encoded_tdesc = 0x80000000 | (VT_EMPTY << 16) | tdesc->vt;
1173         *width = 0;
1174         *alignment = 1;
1175         break;
1176
1177     case VT_PTR:
1178     case VT_SAFEARRAY:
1179         /* FIXME: Make with the error checking. */
1180         FIXME("PTR or SAFEARRAY vartype, may not work correctly.\n");
1181
1182         ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);
1183
1184         for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
1185             typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1186             if (((typedata[0] & 0xffff) == tdesc->vt) && (typedata[1] == target_type)) break;
1187         }
1188
1189         if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
1190             int mix_field;
1191             
1192             if (target_type & 0x80000000) {
1193                 mix_field = (target_type >> 16) & VT_TYPEMASK;
1194             } else {
1195                 typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
1196                 switch((typedata[0]>>16) & ~VT_ARRAY)
1197                 {
1198                     case VT_UI1:
1199                     case VT_I1:
1200                     case VT_UI2:
1201                     case VT_I2:
1202                     case VT_I4:
1203                     case VT_UI4:
1204                         mix_field = typedata[0]>>16;
1205                         break;
1206                     default:
1207                         mix_field = ((typedata[0] >> 16) == 0x7fff) ? 0x7fff : 0x7ffe;
1208                         break;
1209                 }
1210             }
1211
1212             if (tdesc->vt == VT_PTR)
1213                 mix_field |= VT_BYREF;
1214             else if (tdesc->vt == VT_SAFEARRAY)
1215                 mix_field |= VT_ARRAY;
1216
1217             typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
1218             typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1219
1220             typedata[0] = (mix_field << 16) | tdesc->vt;
1221             typedata[1] = target_type;
1222         }
1223
1224         *encoded_tdesc = typeoffset;
1225
1226         *width = 4;
1227         *alignment = 4;
1228         *decoded_size = sizeof(TYPEDESC) + child_size;
1229         break;
1230
1231     case VT_CARRAY:
1232       {
1233         /* FIXME: Make with the error checking. */
1234         int num_dims = tdesc->u.lpadesc->cDims, elements = 1, dim;
1235
1236         ctl2_encode_typedesc(This, &tdesc->u.lpadesc->tdescElem, &target_type, width, alignment, NULL);
1237         arrayoffset = ctl2_alloc_segment(This, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
1238         arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
1239
1240         arraydata[0] = target_type;
1241         arraydata[1] = num_dims;
1242         arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16);
1243         arraydata += 2;
1244
1245         for(dim = 0; dim < num_dims; dim++) {
1246             arraydata[0] = tdesc->u.lpadesc->rgbounds[dim].cElements;
1247             arraydata[1] = tdesc->u.lpadesc->rgbounds[dim].lLbound;
1248             elements *= tdesc->u.lpadesc->rgbounds[dim].cElements;
1249             arraydata += 2;
1250         }
1251         typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
1252         typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1253
1254         typedata[0] = (0x7ffe << 16) | VT_CARRAY;
1255         typedata[1] = arrayoffset;
1256
1257         *encoded_tdesc = typeoffset;
1258         *width = *width * elements;
1259         *decoded_size = sizeof(ARRAYDESC) + (num_dims - 1) * sizeof(SAFEARRAYBOUND);
1260
1261         break;
1262       }
1263     case VT_USERDEFINED:
1264       {
1265         const MSFT_TypeInfoBase *basetype;
1266         INT basevt = 0x7fff;
1267
1268         TRACE("USERDEFINED.\n");
1269         if (tdesc->u.hreftype % sizeof(*basetype) == 0 && tdesc->u.hreftype < This->typelib_segdir[MSFT_SEG_TYPEINFO].length)
1270         {
1271             basetype = (MSFT_TypeInfoBase*)&(This->typelib_segment_data[MSFT_SEG_TYPEINFO][tdesc->u.hreftype]);
1272             switch(basetype->typekind & 0xf)
1273             {
1274                 case TKIND_ENUM:
1275                     basevt = VT_I4;
1276                     break;
1277                 default:
1278                     FIXME("USERDEFINED basetype %d not handled\n", basetype->typekind & 0xf);
1279                     break;
1280             }
1281         }
1282         for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
1283             typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1284             if ((typedata[0] == ((basevt << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break;
1285         }
1286
1287         if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
1288             typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
1289             typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1290
1291             typedata[0] = (basevt << 16) | VT_USERDEFINED;
1292             typedata[1] = tdesc->u.hreftype;
1293         }
1294
1295         *encoded_tdesc = typeoffset;
1296         *width = 0;
1297         *alignment = 1;
1298         break;
1299       }
1300
1301     default:
1302         FIXME("Unrecognized type %d.\n", tdesc->vt);
1303         *encoded_tdesc = default_tdesc;
1304         *width = 0;
1305         *alignment = 1;
1306         break;
1307     }
1308
1309     return 0;
1310 }
1311
1312 /****************************************************************************
1313  *      ctl2_decode_typedesc
1314  *
1315  *  Decodes a type description from an ICreateTypeLib2Impl.
1316  *
1317  * RETURNS
1318  *
1319  *  Success: S_OK.
1320  *  Failure: HRESULT error code.
1321  */
1322 static HRESULT ctl2_decode_typedesc(
1323         ICreateTypeLib2Impl *This, /* [I] The type library from which to decode the TYPEDESC. */
1324         int encoded_tdesc,         /* [I] The encoded type description. */
1325         TYPEDESC *tdesc)           /* [O] The decoded type description. */
1326 {
1327     int *typedata, i;
1328     HRESULT hres;
1329
1330     if (encoded_tdesc & 0x80000000) {
1331         tdesc->vt = encoded_tdesc & VT_TYPEMASK;
1332         tdesc->u.lptdesc = NULL;
1333         return S_OK;
1334     }
1335
1336     typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][encoded_tdesc];
1337
1338     tdesc->vt = typedata[0] & 0xFFFF;
1339
1340     switch(tdesc->vt) {
1341     case VT_PTR:
1342     case VT_SAFEARRAY:
1343         tdesc->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEDESC));
1344         if (!tdesc->u.lptdesc)
1345             return E_OUTOFMEMORY;
1346
1347         hres = ctl2_decode_typedesc(This, typedata[1], tdesc->u.lptdesc);
1348         if (FAILED(hres)) {
1349             HeapFree(GetProcessHeap(), 0, tdesc->u.lptdesc);
1350             return hres;
1351         }
1352
1353         return S_OK;
1354
1355     case VT_CARRAY: {
1356         int arrayoffset, *arraydata, num_dims;
1357
1358         arrayoffset = typedata[1];
1359         arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
1360         num_dims = arraydata[1] & 0xFFFF;
1361
1362         tdesc->u.lpadesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1363                 sizeof(ARRAYDESC) + sizeof(SAFEARRAYBOUND) * (num_dims - 1));
1364         if (!tdesc->u.lpadesc)
1365             return E_OUTOFMEMORY;
1366
1367         hres = ctl2_decode_typedesc(This, arraydata[0], &tdesc->u.lpadesc->tdescElem);
1368         if (FAILED(hres)) {
1369             HeapFree(GetProcessHeap(), 0, tdesc->u.lpadesc);
1370             return E_OUTOFMEMORY;
1371         }
1372
1373         for (i = 0; i < num_dims; ++i) {
1374             tdesc->u.lpadesc->rgbounds[i].cElements = arraydata[2 + i * 2];
1375             tdesc->u.lpadesc->rgbounds[i].lLbound = arraydata[3 + i * 2];
1376         }
1377
1378         return S_OK;
1379     }
1380     case VT_USERDEFINED:
1381         tdesc->u.hreftype = typedata[1];
1382         return S_OK;
1383     default:
1384         FIXME("unable to decode typedesc (%08x): unknown VT: %d\n", encoded_tdesc, tdesc->vt);
1385         return E_NOTIMPL;
1386     }
1387 }
1388
1389 /****************************************************************************
1390  *      ctl2_find_nth_reference
1391  *
1392  *  Finds a reference by index into the linked list of reference records.
1393  *
1394  * RETURNS
1395  *
1396  *  Success: Offset of the desired reference record.
1397  *  Failure: -1.
1398  */
1399 static int ctl2_find_nth_reference(
1400         ICreateTypeLib2Impl *This, /* [I] The type library in which to search. */
1401         int offset,                /* [I] The starting offset of the reference list. */
1402         int index)                 /* [I] The index of the reference to find. */
1403 {
1404     MSFT_RefRecord *ref;
1405
1406     for (; index && (offset != -1); index--) {
1407         ref = (MSFT_RefRecord *)&This->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
1408         offset = ref->onext;
1409     }
1410
1411     return offset;
1412 }
1413
1414 /****************************************************************************
1415  *      ctl2_find_typeinfo_from_offset
1416  *
1417  *  Finds an ITypeInfo given an offset into the TYPEINFO segment.
1418  *
1419  * RETURNS
1420  *
1421  *  Success: S_OK.
1422  *  Failure: TYPE_E_ELEMENTNOTFOUND.
1423  */
1424 static HRESULT ctl2_find_typeinfo_from_offset(
1425         ICreateTypeLib2Impl *This, /* [I] The typelib to find the typeinfo in. */
1426         int offset,                /* [I] The offset of the desired typeinfo. */
1427         ITypeInfo **ppTinfo)       /* [I] The typeinfo found. */
1428 {
1429     void *typeinfodata;
1430     ICreateTypeInfo2Impl *typeinfo;
1431
1432     typeinfodata = &This->typelib_segment_data[MSFT_SEG_TYPEINFO][offset];
1433
1434     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
1435         if (typeinfo->typeinfo == typeinfodata) {
1436             *ppTinfo = (ITypeInfo *)&typeinfo->lpVtblTypeInfo2;
1437             ITypeInfo2_AddRef(*ppTinfo);
1438             return S_OK;
1439         }
1440     }
1441
1442     ERR("Failed to find typeinfo, invariant varied.\n");
1443
1444     return TYPE_E_ELEMENTNOTFOUND;
1445 }
1446
1447 /****************************************************************************
1448  *      funcrecord_reallochdr
1449  *
1450  *  Ensure FuncRecord data block contains header of required size
1451  *
1452  *  PARAMS
1453  *
1454  *   typedata [IO] - reference to pointer to data block
1455  *   need     [I]  - required size of block in bytes
1456  *
1457  * RETURNS
1458  *
1459  *  Number of additionally allocated bytes
1460  */
1461 static INT funcrecord_reallochdr(INT **typedata, int need)
1462 {
1463     int tail = (*typedata)[5]*((*typedata)[4]&0x1000?16:12);
1464     int hdr = (*typedata)[0] - tail;
1465     int i;
1466
1467     if (hdr >= need)
1468         return 0;
1469
1470     *typedata = HeapReAlloc(GetProcessHeap(), 0, *typedata, need + tail);
1471     if (!*typedata)
1472         return -1;
1473
1474     if (tail)
1475         memmove((char*)*typedata + need, (const char*)*typedata + hdr, tail);
1476     (*typedata)[0] = need + tail;
1477
1478     /* fill in default values */
1479     for(i = (hdr+3)/4; (i+1)*4 <= need; i++)
1480     {
1481         switch(i)
1482         {
1483             case 2:
1484                 (*typedata)[i] = 0;
1485                 break;
1486             case 7:
1487                 (*typedata)[i] = -1;
1488                 break;
1489             case 8:
1490                 (*typedata)[i] = -1;
1491                 break;
1492             case 9:
1493                 (*typedata)[i] = -1;
1494                 break;
1495             case 10:
1496                 (*typedata)[i] = -1;
1497                 break;
1498             case 11:
1499                 (*typedata)[i] = 0;
1500                 break;
1501             case 12:
1502                 (*typedata)[i] = -1;
1503                 break;
1504         }
1505     }
1506
1507     return need - hdr;
1508 }
1509
1510 /*================== ICreateTypeInfo2 Implementation ===================================*/
1511
1512 /******************************************************************************
1513  * ICreateTypeInfo2_QueryInterface {OLEAUT32}
1514  *
1515  *  See IUnknown_QueryInterface.
1516  */
1517 static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(
1518         ICreateTypeInfo2 * iface,
1519         REFIID riid,
1520         VOID **ppvObject)
1521 {
1522     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1523
1524     TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
1525
1526     *ppvObject=NULL;
1527     if(IsEqualIID(riid, &IID_IUnknown) ||
1528        IsEqualIID(riid,&IID_ICreateTypeInfo)||
1529        IsEqualIID(riid,&IID_ICreateTypeInfo2))
1530     {
1531         *ppvObject = This;
1532     } else if (IsEqualIID(riid, &IID_ITypeInfo) ||
1533                IsEqualIID(riid, &IID_ITypeInfo2)) {
1534         *ppvObject = &This->lpVtblTypeInfo2;
1535     }
1536
1537     if(*ppvObject)
1538     {
1539         ICreateTypeInfo2_AddRef(iface);
1540         TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1541         return S_OK;
1542     }
1543     TRACE("-- Interface: E_NOINTERFACE\n");
1544     return E_NOINTERFACE;
1545 }
1546
1547 /******************************************************************************
1548  * ICreateTypeInfo2_AddRef {OLEAUT32}
1549  *
1550  *  See IUnknown_AddRef.
1551  */
1552 static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
1553 {
1554     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1555     ULONG ref = InterlockedIncrement(&This->ref);
1556
1557     TRACE("(%p)->ref was %u\n",This, ref - 1);
1558
1559     if(ref==1 && This->typelib)
1560         ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This->typelib);
1561
1562     return ref;
1563 }
1564
1565 /******************************************************************************
1566  * ICreateTypeInfo2_Release {OLEAUT32}
1567  *
1568  *  See IUnknown_Release.
1569  */
1570 static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
1571 {
1572     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1573     ULONG ref = InterlockedDecrement(&This->ref);
1574
1575     TRACE("(%p)->(%u)\n",This, ref);
1576
1577     if (!ref) {
1578         if (This->typelib) {
1579             ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib);
1580             /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */
1581             /* This->typelib = NULL; */
1582         }
1583
1584         /* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
1585         /* HeapFree(GetProcessHeap(),0,This); */
1586         return 0;
1587     }
1588
1589     return ref;
1590 }
1591
1592
1593 /******************************************************************************
1594  * ICreateTypeInfo2_SetGuid {OLEAUT32}
1595  *
1596  *  See ICreateTypeInfo_SetGuid.
1597  */
1598 static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid)
1599 {
1600     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1601
1602     MSFT_GuidEntry guidentry;
1603     int offset;
1604
1605     TRACE("(%p,%s)\n", iface, debugstr_guid(guid));
1606
1607     guidentry.guid = *guid;
1608     guidentry.hreftype = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
1609     guidentry.next_hash = -1;
1610
1611     offset = ctl2_alloc_guid(This->typelib, &guidentry);
1612     
1613     if (offset == -1) return E_OUTOFMEMORY;
1614
1615     This->typeinfo->posguid = offset;
1616
1617     if (IsEqualIID(guid, &IID_IDispatch)) {
1618         This->typelib->typelib_header.dispatchpos = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
1619     }
1620
1621     return S_OK;
1622 }
1623
1624 /******************************************************************************
1625  * ICreateTypeInfo2_SetTypeFlags {OLEAUT32}
1626  *
1627  *  See ICreateTypeInfo_SetTypeFlags.
1628  */
1629 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT uTypeFlags)
1630 {
1631     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1632
1633     TRACE("(%p,0x%x)\n", iface, uTypeFlags);
1634
1635     if(uTypeFlags & TYPEFLAG_FDUAL) {
1636         This->typeinfo->typekind |= 0x10;
1637         This->typeinfo->typekind &= ~0x0f;
1638         This->typeinfo->typekind |= TKIND_DISPATCH;
1639
1640         if(!This->dual) {
1641             This->dual = HeapAlloc(GetProcessHeap(), 0, sizeof(ICreateTypeInfo2Impl));
1642             if(!This->dual)
1643                 return E_OUTOFMEMORY;
1644
1645             memcpy(This->dual, This, sizeof(ICreateTypeInfo2Impl));
1646             This->dual->ref = 0;
1647             This->dual->typekind = This->typekind==TKIND_DISPATCH ?
1648                 TKIND_INTERFACE : TKIND_DISPATCH;
1649             This->dual->dual = This;
1650         }
1651
1652         /* Make sure dispatch is in typeinfos queue */
1653         if(This->typekind != TKIND_DISPATCH) {
1654             if(This->typelib->last_typeinfo == This)
1655                 This->typelib->last_typeinfo = This->dual;
1656
1657             if(This->typelib->typeinfos == This)
1658                 This->typelib->typeinfos = This->dual;
1659             else {
1660                 ICreateTypeInfo2Impl *iter;
1661
1662                 for(iter=This->typelib->typeinfos; iter->next_typeinfo!=This; iter=iter->next_typeinfo);
1663                 iter->next_typeinfo = This->dual;
1664             }
1665         } else
1666             iface = (ICreateTypeInfo2*)&This->dual->lpVtbl;
1667     }
1668
1669     if (uTypeFlags & (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL)) {
1670         static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 };
1671         ITypeLib *stdole;
1672         ITypeInfo *dispatch;
1673         HREFTYPE hreftype;
1674         HRESULT hres;
1675
1676         hres = LoadTypeLib(stdole2tlb, &stdole);
1677         if(FAILED(hres))
1678             return hres;
1679
1680         hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch);
1681         ITypeLib_Release(stdole);
1682         if(FAILED(hres))
1683             return hres;
1684
1685         hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype);
1686         ITypeInfo_Release(dispatch);
1687         if(FAILED(hres))
1688             return hres;
1689     }
1690
1691     This->typeinfo->flags = uTypeFlags;
1692     return S_OK;
1693 }
1694
1695 /******************************************************************************
1696  * ICreateTypeInfo2_SetDocString {OLEAUT32}
1697  *
1698  *  See ICreateTypeInfo_SetDocString.
1699  */
1700 static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(
1701         ICreateTypeInfo2* iface,
1702         LPOLESTR pStrDoc)
1703 {
1704     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1705
1706     int offset;
1707
1708     TRACE("(%p,%s)\n", iface, debugstr_w(pStrDoc));
1709     if (!pStrDoc)
1710         return E_INVALIDARG;
1711
1712     offset = ctl2_alloc_string(This->typelib, pStrDoc);
1713     if (offset == -1) return E_OUTOFMEMORY;
1714     This->typeinfo->docstringoffs = offset;
1715     return S_OK;
1716 }
1717
1718 /******************************************************************************
1719  * ICreateTypeInfo2_SetHelpContext {OLEAUT32}
1720  *
1721  *  See ICreateTypeInfo_SetHelpContext.
1722  */
1723 static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(
1724         ICreateTypeInfo2* iface,
1725         DWORD dwHelpContext)
1726 {
1727     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1728
1729     TRACE("(%p,%d)\n", iface, dwHelpContext);
1730
1731     This->typeinfo->helpcontext = dwHelpContext;
1732
1733     return S_OK;
1734 }
1735
1736 /******************************************************************************
1737  * ICreateTypeInfo2_SetVersion {OLEAUT32}
1738  *
1739  *  See ICreateTypeInfo_SetVersion.
1740  */
1741 static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(
1742         ICreateTypeInfo2* iface,
1743         WORD wMajorVerNum,
1744         WORD wMinorVerNum)
1745 {
1746     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1747
1748     TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);
1749
1750     This->typeinfo->version = wMajorVerNum | (wMinorVerNum << 16);
1751     return S_OK;
1752 }
1753
1754 /******************************************************************************
1755  * ICreateTypeInfo2_AddRefTypeInfo {OLEAUT32}
1756  *
1757  *  See ICreateTypeInfo_AddRefTypeInfo.
1758  */
1759 static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(
1760         ICreateTypeInfo2* iface,
1761         ITypeInfo* pTInfo,
1762         HREFTYPE* phRefType)
1763 {
1764     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1765
1766     ITypeLib *container;
1767     UINT index;
1768     HRESULT res;
1769
1770     TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType);
1771
1772     if(!pTInfo || !phRefType)
1773         return E_INVALIDARG;
1774
1775     /*
1776      * Unfortunately, we can't rely on the passed-in TypeInfo even having the
1777      * same internal structure as one of ours. It could be from another
1778      * implementation of ITypeInfo. So we need to do the following...
1779      */
1780     res = ITypeInfo_GetContainingTypeLib(pTInfo, &container, &index);
1781     if (FAILED(res)) {
1782         TRACE("failed to find containing typelib.\n");
1783         return res;
1784     }
1785
1786     if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) {
1787         /* Process locally defined TypeInfo */
1788         *phRefType = This->typelib->typelib_typeinfo_offsets[index];
1789     } else {
1790         BSTR name;
1791         TLIBATTR *tlibattr;
1792         TYPEATTR *typeattr;
1793         TYPEKIND typekind;
1794         MSFT_GuidEntry guid, *check_guid;
1795         MSFT_ImpInfo impinfo;
1796         int guid_offset, import_offset;
1797         HRESULT hres;
1798
1799         /* Allocate container GUID */
1800         hres = ITypeLib_GetLibAttr(container, &tlibattr);
1801         if(FAILED(hres)) {
1802             ITypeLib_Release(container);
1803             return hres;
1804         }
1805
1806         guid.guid = tlibattr->guid;
1807         guid.hreftype = This->typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length+2;
1808         guid.next_hash = -1;
1809
1810         guid_offset = ctl2_alloc_guid(This->typelib, &guid);
1811         if(guid_offset == -1) {
1812             ITypeLib_ReleaseTLibAttr(container, tlibattr);
1813             ITypeLib_Release(container);
1814             return E_OUTOFMEMORY;
1815         }
1816
1817         check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
1818         if(check_guid->hreftype == guid.hreftype)
1819             This->typelib->typelib_guids++;
1820
1821         /* Get import file name */
1822         hres = QueryPathOfRegTypeLib(&guid.guid, tlibattr->wMajorVerNum,
1823                 tlibattr->wMinorVerNum, tlibattr->lcid, &name);
1824         if(FAILED(hres)) {
1825             ITypeLib_ReleaseTLibAttr(container, tlibattr);
1826             ITypeLib_Release(container);
1827             return hres;
1828         }
1829
1830         /* Import file */
1831         import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, tlibattr->lcid,
1832                 tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, strrchrW(name, '\\')+1);
1833         ITypeLib_ReleaseTLibAttr(container, tlibattr);
1834         SysFreeString(name);
1835
1836         if(import_offset == -1) {
1837             ITypeLib_Release(container);
1838             return E_OUTOFMEMORY;
1839         }
1840
1841         /* Allocate referenced guid */
1842         hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr);
1843         if(FAILED(hres)) {
1844             ITypeLib_Release(container);
1845             return hres;
1846         }
1847
1848         guid.guid = typeattr->guid;
1849         guid.hreftype = This->typelib->typeinfo_guids*12+1;
1850         guid.next_hash = -1;
1851         typekind = typeattr->typekind;
1852         ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr);
1853
1854         guid_offset = ctl2_alloc_guid(This->typelib, &guid);
1855         if(guid_offset == -1) {
1856             ITypeLib_Release(container);
1857             return E_OUTOFMEMORY;
1858         }
1859
1860         check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
1861         if(check_guid->hreftype == guid.hreftype)
1862             This->typelib->typeinfo_guids++;
1863
1864         /* Allocate importinfo */
1865         impinfo.flags = (typekind<<24) | MSFT_IMPINFO_OFFSET_IS_GUID;
1866         impinfo.oImpFile = import_offset;
1867         impinfo.oGuid = guid_offset;
1868         *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1;
1869
1870         if(IsEqualGUID(&guid.guid, &IID_IDispatch))
1871             This->typelib->typelib_header.dispatchpos = *phRefType;
1872     }
1873
1874     ITypeLib_Release(container);
1875     return S_OK;
1876 }
1877
1878 /******************************************************************************
1879  * ICreateTypeInfo2_AddFuncDesc {OLEAUT32}
1880  *
1881  *  See ICreateTypeInfo_AddFuncDesc.
1882  */
1883 static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
1884         ICreateTypeInfo2* iface,
1885         UINT index,
1886         FUNCDESC* pFuncDesc)
1887 {
1888     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1889
1890     CyclicList *iter, *insert;
1891     int *typedata;
1892     int i, num_defaults = 0, num_retval = 0;
1893     int decoded_size;
1894     HRESULT hres;
1895
1896     TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);
1897
1898     if(!pFuncDesc || pFuncDesc->oVft&3)
1899         return E_INVALIDARG;
1900
1901     TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid,
1902             pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind,
1903             pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams,
1904             pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes,
1905             pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
1906
1907     if(pFuncDesc->cParamsOpt || pFuncDesc->cScodes)
1908         FIXME("Unimplemented parameter - created typelib will be incorrect\n");
1909
1910     switch(This->typekind) {
1911     case TKIND_MODULE:
1912         if(pFuncDesc->funckind != FUNC_STATIC)
1913             return TYPE_E_BADMODULEKIND;
1914         break;
1915     case TKIND_DISPATCH:
1916         if(pFuncDesc->funckind != FUNC_DISPATCH)
1917             return TYPE_E_BADMODULEKIND;
1918         break;
1919     default:
1920         if(pFuncDesc->funckind != FUNC_PUREVIRTUAL)
1921             return TYPE_E_BADMODULEKIND;
1922     }
1923
1924     if(This->typeinfo->cElement<index)
1925         return TYPE_E_ELEMENTNOTFOUND;
1926
1927     if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) &&
1928         !pFuncDesc->cParams)
1929         return TYPE_E_INCONSISTENTPROPFUNCS;
1930
1931     /* get number of arguments with default values specified */
1932     for (i = 0; i < pFuncDesc->cParams; i++) {
1933         if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
1934             num_defaults++;
1935         if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
1936             num_retval++;
1937     }
1938
1939     if (!This->typedata) {
1940         This->typedata = alloc_cyclic_list_item(CyclicListSentinel);
1941         if(!This->typedata)
1942             return E_OUTOFMEMORY;
1943
1944         This->typedata->next = This->typedata;
1945
1946         if(This->dual)
1947             This->dual->typedata = This->typedata;
1948     }
1949
1950     /* allocate type data space for us */
1951     insert = alloc_cyclic_list_item(CyclicListFunc);
1952     if(!insert)
1953         return E_OUTOFMEMORY;
1954     insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[6])+sizeof(int[(num_defaults?4:3)])*pFuncDesc->cParams);
1955     if(!insert->u.data) {
1956         HeapFree(GetProcessHeap(), 0, insert);
1957         return E_OUTOFMEMORY;
1958     }
1959
1960     /* fill out the basic type information */
1961     typedata = insert->u.data;
1962     typedata[0] = 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
1963     ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size);
1964     typedata[2] = pFuncDesc->wFuncFlags;
1965     typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | (unsigned short)(pFuncDesc->oVft?pFuncDesc->oVft+1:0);
1966     typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind;
1967     if(num_defaults) typedata[4] |= 0x1000;
1968     if (num_retval) typedata[4] |= 0x4000;
1969     typedata[5] = pFuncDesc->cParams;
1970
1971     /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */
1972     /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */
1973     typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16;
1974     typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16;
1975
1976     /* add default values */
1977     if(num_defaults) {
1978         for (i = 0; i < pFuncDesc->cParams; i++)
1979             if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
1980                 hres = ctl2_encode_variant(This->typelib, typedata+6+i,
1981                         &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue,
1982                         pFuncDesc->lprgelemdescParam[i].tdesc.vt);
1983
1984                 if(FAILED(hres)) {
1985                     HeapFree(GetProcessHeap(), 0, insert->u.data);
1986                     HeapFree(GetProcessHeap(), 0, insert);
1987                     return hres;
1988                 }
1989             } else
1990                 typedata[6+i] = 0xffffffff;
1991
1992         num_defaults = pFuncDesc->cParams;
1993     }
1994
1995     /* add arguments */
1996     for (i = 0; i < pFuncDesc->cParams; i++) {
1997         ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc,
1998                 &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size);
1999         typedata[7+num_defaults+(i*3)] = -1;
2000         typedata[8+num_defaults+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
2001         typedata[3] += decoded_size << 16;
2002     }
2003
2004     /* update the index data */
2005     insert->indice = pFuncDesc->memid;
2006     insert->name = -1;
2007
2008     /* insert type data to list */
2009     if(index == This->typeinfo->cElement) {
2010         insert->next = This->typedata->next;
2011         This->typedata->next = insert;
2012         This->typedata = insert;
2013
2014         if(This->dual)
2015             This->dual->typedata = This->typedata;
2016     } else {
2017         iter = This->typedata->next;
2018         for(i=0; i<index; i++)
2019             iter = iter->next;
2020
2021         insert->next = iter->next;
2022         iter->next = insert;
2023     }
2024
2025     /* update type data size */
2026     This->typedata->next->u.val += 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
2027
2028     /* Increment the number of function elements */
2029     This->typeinfo->cElement += 1;
2030
2031     return S_OK;
2032 }
2033
2034 /******************************************************************************
2035  * ICreateTypeInfo2_AddImplType {OLEAUT32}
2036  *
2037  *  See ICreateTypeInfo_AddImplType.
2038  */
2039 static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
2040         ICreateTypeInfo2* iface,
2041         UINT index,
2042         HREFTYPE hRefType)
2043 {
2044     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2045
2046     TRACE("(%p,%d,%d)\n", iface, index, hRefType);
2047
2048     if (This->typekind == TKIND_COCLASS) {
2049         int offset;
2050         MSFT_RefRecord *ref;
2051
2052         if (index == 0) {
2053             if (This->typeinfo->datatype1 != -1) return TYPE_E_ELEMENTNOTFOUND;
2054
2055             offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
2056             if (offset == -1) return E_OUTOFMEMORY;
2057
2058             This->typeinfo->datatype1 = offset;
2059         } else {
2060             int lastoffset;
2061
2062             lastoffset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index - 1);
2063             if (lastoffset == -1) return TYPE_E_ELEMENTNOTFOUND;
2064
2065             ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][lastoffset];
2066             if (ref->onext != -1) return TYPE_E_ELEMENTNOTFOUND;
2067
2068             offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
2069             if (offset == -1) return E_OUTOFMEMORY;
2070
2071             ref->onext = offset;
2072         }
2073
2074         ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
2075
2076         ref->reftype = hRefType;
2077         ref->flags = 0;
2078         ref->oCustData = -1;
2079         ref->onext = -1;
2080         This->typeinfo->cImplTypes++;
2081     } else if (This->typekind == TKIND_INTERFACE) {
2082         if (This->typeinfo->cImplTypes && index==1)
2083             return TYPE_E_BADMODULEKIND;
2084
2085         if( index != 0)  return TYPE_E_ELEMENTNOTFOUND;
2086
2087         This->typeinfo->datatype1 = hRefType;
2088         This->typeinfo->cImplTypes = 1;
2089     } else if (This->typekind == TKIND_DISPATCH) {
2090         if(index != 0) return TYPE_E_ELEMENTNOTFOUND;
2091
2092         /* FIXME: Check if referenced typeinfo is IDispatch */
2093         This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
2094         This->typeinfo->cImplTypes = 1;
2095     } else {
2096         FIXME("AddImplType unsupported on typekind %d\n", This->typekind);
2097         return E_OUTOFMEMORY;
2098     }
2099
2100     return S_OK;
2101 }
2102
2103 /******************************************************************************
2104  * ICreateTypeInfo2_SetImplTypeFlags {OLEAUT32}
2105  *
2106  *  See ICreateTypeInfo_SetImplTypeFlags.
2107  */
2108 static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(
2109         ICreateTypeInfo2* iface,
2110         UINT index,
2111         INT implTypeFlags)
2112 {
2113     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2114     int offset;
2115     MSFT_RefRecord *ref;
2116
2117     TRACE("(%p,%d,0x%x)\n", iface, index, implTypeFlags);
2118
2119     if (This->typekind != TKIND_COCLASS) {
2120         return TYPE_E_BADMODULEKIND;
2121     }
2122
2123     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
2124     if (offset == -1) return TYPE_E_ELEMENTNOTFOUND;
2125
2126     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
2127     ref->flags = implTypeFlags;
2128
2129     return S_OK;
2130 }
2131
2132 /******************************************************************************
2133  * ICreateTypeInfo2_SetAlignment {OLEAUT32}
2134  *
2135  *  See ICreateTypeInfo_SetAlignment.
2136  */
2137 static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(
2138         ICreateTypeInfo2* iface,
2139         WORD cbAlignment)
2140 {
2141     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2142
2143     TRACE("(%p,%d)\n", iface, cbAlignment);
2144
2145     if (!cbAlignment) return E_INVALIDARG;
2146     if (cbAlignment > 16) return E_INVALIDARG;
2147
2148     This->typeinfo->typekind &= ~0xffc0;
2149     This->typeinfo->typekind |= cbAlignment << 6;
2150
2151     /* FIXME: There's probably some way to simplify this. */
2152     switch (This->typekind) {
2153     case TKIND_ALIAS:
2154     default:
2155         break;
2156
2157     case TKIND_ENUM:
2158     case TKIND_INTERFACE:
2159     case TKIND_DISPATCH:
2160     case TKIND_COCLASS:
2161         if (cbAlignment > 4) cbAlignment = 4;
2162         break;
2163
2164     case TKIND_RECORD:
2165     case TKIND_MODULE:
2166     case TKIND_UNION:
2167         cbAlignment = 1;
2168         break;
2169     }
2170
2171     This->typeinfo->typekind |= cbAlignment << 11;
2172
2173     return S_OK;
2174 }
2175
2176 /******************************************************************************
2177  * ICreateTypeInfo2_SetSchema {OLEAUT32}
2178  *
2179  *  See ICreateTypeInfo_SetSchema.
2180  */
2181 static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(
2182         ICreateTypeInfo2* iface,
2183         LPOLESTR pStrSchema)
2184 {
2185     FIXME("(%p,%s), stub!\n", iface, debugstr_w(pStrSchema));
2186     return E_OUTOFMEMORY;
2187 }
2188
2189 /******************************************************************************
2190  * ICreateTypeInfo2_AddVarDesc {OLEAUT32}
2191  *
2192  *  See ICreateTypeInfo_AddVarDesc.
2193  */
2194 static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
2195         ICreateTypeInfo2* iface,
2196         UINT index,
2197         VARDESC* pVarDesc)
2198 {
2199     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2200
2201     HRESULT status = S_OK;
2202     CyclicList *insert;
2203     INT *typedata;
2204     int var_datawidth;
2205     int var_alignment;
2206     int var_type_size;
2207     int alignment;
2208
2209     TRACE("(%p,%d,%p), stub!\n", iface, index, pVarDesc);
2210     TRACE("%d, %p, %d, {{%x, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst,
2211           pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt,
2212           pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags,
2213           pVarDesc->wVarFlags, pVarDesc->varkind);
2214
2215     if ((This->typeinfo->cElement >> 16) != index) {
2216         TRACE("Out-of-order element.\n");
2217         return TYPE_E_ELEMENTNOTFOUND;
2218     }
2219
2220     if (!This->typedata) {
2221         This->typedata = alloc_cyclic_list_item(CyclicListSentinel);
2222         if(!This->typedata)
2223             return E_OUTOFMEMORY;
2224
2225         This->typedata->next = This->typedata;
2226
2227         if(This->dual)
2228             This->dual->typedata = This->typedata;
2229     }
2230
2231     /* allocate type data space for us */
2232     insert = alloc_cyclic_list_item(CyclicListVar);
2233     if(!insert)
2234         return E_OUTOFMEMORY;
2235     insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[5]));
2236     if(!insert->u.data) {
2237         HeapFree(GetProcessHeap(), 0, insert);
2238         return E_OUTOFMEMORY;
2239     }
2240
2241     insert->next = This->typedata->next;
2242     This->typedata->next = insert;
2243     This->typedata = insert;
2244
2245     if(This->dual)
2246         This->dual->typedata = This->typedata;
2247
2248     This->typedata->next->u.val += 0x14;
2249     typedata = This->typedata->u.data;
2250
2251     /* fill out the basic type information */
2252     typedata[0] = 0x14 | (index << 16);
2253     typedata[2] = pVarDesc->wVarFlags;
2254     typedata[3] = (sizeof(VARDESC) << 16) | pVarDesc->varkind;
2255
2256     /* update the index data */
2257     insert->indice = 0x40000000 + index;
2258     insert->name = -1;
2259
2260     /* figure out type widths and whatnot */
2261     ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc,
2262                          &typedata[1], &var_datawidth, &var_alignment,
2263                          &var_type_size);
2264
2265     if (pVarDesc->varkind != VAR_CONST)
2266     {
2267         /* pad out starting position to data width */
2268         This->datawidth += var_alignment - 1;
2269         This->datawidth &= ~(var_alignment - 1);
2270         typedata[4] = This->datawidth;
2271
2272         /* add the new variable to the total data width */
2273         This->datawidth += var_datawidth;
2274         if(This->dual)
2275             This->dual->datawidth = This->datawidth;
2276
2277         /* add type description size to total required allocation */
2278         typedata[3] += var_type_size << 16;
2279
2280         /* fix type alignment */
2281         alignment = (This->typeinfo->typekind >> 11) & 0x1f;
2282         if (alignment < var_alignment) {
2283             alignment = var_alignment;
2284             This->typeinfo->typekind &= ~0xf800;
2285             This->typeinfo->typekind |= alignment << 11;
2286         }
2287
2288         /* ??? */
2289         if (!This->typeinfo->res2) This->typeinfo->res2 = 0x1a;
2290         if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) {
2291             This->typeinfo->res2 <<= 1;
2292         }
2293
2294         /* ??? */
2295         if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0;
2296         This->typeinfo->res3 += 0x2c;
2297
2298         /* pad data width to alignment */
2299         This->typeinfo->size = (This->datawidth + (alignment - 1)) & ~(alignment - 1);
2300     } else {
2301         VARIANT *value = pVarDesc->DUMMYUNIONNAME.lpvarValue;
2302         status = ctl2_encode_variant(This->typelib, typedata+4, value, V_VT(value));
2303         /* ??? native sets size 0x34 */
2304         typedata[3] += 0x10 << 16;
2305     }
2306
2307     /* increment the number of variable elements */
2308     This->typeinfo->cElement += 0x10000;
2309
2310     return status;
2311 }
2312
2313 /******************************************************************************
2314  * ICreateTypeInfo2_SetFuncAndParamNames {OLEAUT32}
2315  *
2316  *  See ICreateTypeInfo_SetFuncAndParamNames.
2317  */
2318 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(
2319         ICreateTypeInfo2* iface,
2320         UINT index,
2321         LPOLESTR* rgszNames,
2322         UINT cNames)
2323 {
2324     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2325     CyclicList *iter = NULL, *iter2;
2326     int offset, len, i=0;
2327     char *namedata;
2328
2329     TRACE("(%p %d %p %d)\n", iface, index, rgszNames, cNames);
2330
2331     if(!rgszNames)
2332         return E_INVALIDARG;
2333
2334     if(index >= (This->typeinfo->cElement&0xFFFF) || !cNames)
2335         return TYPE_E_ELEMENTNOTFOUND;
2336
2337     for(iter=This->typedata->next->next, i=0; /* empty */; iter=iter->next)
2338         if (iter->type == CyclicListFunc)
2339             if (i++ >= index)
2340                 break;
2341
2342     /* cNames == cParams for put or putref accessor, cParams+1 otherwise */
2343     if(cNames != iter->u.data[5] + ((iter->u.data[4]>>3)&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1))
2344         return TYPE_E_ELEMENTNOTFOUND;
2345
2346     len = ctl2_encode_name(This->typelib, rgszNames[0], &namedata);
2347     for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
2348         if(iter2->name!=-1 && !memcmp(namedata,
2349                     This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len)) {
2350             /* getters/setters can have a same name */
2351             if (iter2->type == CyclicListFunc) {
2352                 INT inv1 = iter2->u.data[4] >> 3;
2353                 INT inv2 = iter->u.data[4] >> 3;
2354                 if (((inv1&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && (inv2&INVOKE_PROPERTYGET)) ||
2355                     ((inv2&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && (inv1&INVOKE_PROPERTYGET)))
2356                     continue;
2357             }
2358
2359             return TYPE_E_AMBIGUOUSNAME;
2360         }
2361     }
2362
2363     offset = ctl2_alloc_name(This->typelib, rgszNames[0]);
2364     if(offset == -1)
2365         return E_OUTOFMEMORY;
2366
2367     iter->name = offset;
2368
2369     namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
2370     if (*((INT*)namedata) == -1)
2371             *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
2372
2373     len = (iter->u.data[0]&0xFFFF)/4 - iter->u.data[5]*3;
2374
2375     for (i = 1; i < cNames; i++) {
2376         offset = ctl2_alloc_name(This->typelib, rgszNames[i]);
2377         iter->u.data[len + ((i-1)*3) + 1] = offset;
2378     }
2379
2380     return S_OK;
2381 }
2382
2383 /******************************************************************************
2384  * ICreateTypeInfo2_SetVarName {OLEAUT32}
2385  *
2386  *  See ICreateTypeInfo_SetVarName.
2387  */
2388 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(
2389         ICreateTypeInfo2* iface,
2390         UINT index,
2391         LPOLESTR szName)
2392 {
2393     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2394     CyclicList *iter;
2395     int offset, i;
2396     char *namedata;
2397
2398     TRACE("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szName));
2399
2400     if ((This->typeinfo->cElement >> 16) <= index) {
2401         TRACE("Out-of-order element.\n");
2402         return TYPE_E_ELEMENTNOTFOUND;
2403     }
2404
2405     offset = ctl2_alloc_name(This->typelib, szName);
2406     if (offset == -1) return E_OUTOFMEMORY;
2407
2408     namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
2409     if (*((INT *)namedata) == -1) {
2410         *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
2411         namedata[9] |= 0x10;
2412     }
2413     if (This->typekind == TKIND_ENUM) {
2414         namedata[9] |= 0x20;
2415     }
2416
2417     for(iter = This->typedata->next->next, i = 0; /* empty */; iter = iter->next)
2418         if (iter->type == CyclicListVar)
2419             if (i++ >= index)
2420                 break;
2421
2422     iter->name = offset;
2423     return S_OK;
2424 }
2425
2426 /******************************************************************************
2427  * ICreateTypeInfo2_SetTypeDescAlias {OLEAUT32}
2428  *
2429  *  See ICreateTypeInfo_SetTypeDescAlias.
2430  */
2431 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(
2432         ICreateTypeInfo2* iface,
2433         TYPEDESC* pTDescAlias)
2434 {
2435     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2436
2437     int encoded_typedesc;
2438     int width;
2439
2440     if (This->typekind != TKIND_ALIAS) {
2441         return TYPE_E_WRONGTYPEKIND;
2442     }
2443
2444     FIXME("(%p,%p), hack!\n", iface, pTDescAlias);
2445
2446     if (ctl2_encode_typedesc(This->typelib, pTDescAlias, &encoded_typedesc, &width, NULL, NULL) == -1) {
2447         return E_OUTOFMEMORY;
2448     }
2449
2450     This->typeinfo->size = width;
2451     This->typeinfo->datatype1 = encoded_typedesc;
2452
2453     return S_OK;
2454 }
2455
2456 /******************************************************************************
2457  * ICreateTypeInfo2_DefineFuncAsDllEntry {OLEAUT32}
2458  *
2459  *  See ICreateTypeInfo_DefineFuncAsDllEntry.
2460  */
2461 static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(
2462         ICreateTypeInfo2* iface,
2463         UINT index,
2464         LPOLESTR szDllName,
2465         LPOLESTR szProcName)
2466 {
2467     FIXME("(%p,%d,%s,%s), stub!\n", iface, index, debugstr_w(szDllName), debugstr_w(szProcName));
2468     return E_OUTOFMEMORY;
2469 }
2470
2471 /******************************************************************************
2472  * ICreateTypeInfo2_SetFuncDocString {OLEAUT32}
2473  *
2474  *  See ICreateTypeInfo_SetFuncDocString.
2475  */
2476 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(
2477         ICreateTypeInfo2* iface,
2478         UINT index,
2479         LPOLESTR szDocString)
2480 {
2481     FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString));
2482     return E_OUTOFMEMORY;
2483 }
2484
2485 /******************************************************************************
2486  * ICreateTypeInfo2_SetVarDocString {OLEAUT32}
2487  *
2488  *  See ICreateTypeInfo_SetVarDocString.
2489  */
2490 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(
2491         ICreateTypeInfo2* iface,
2492         UINT index,
2493         LPOLESTR szDocString)
2494 {
2495     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2496
2497     FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString));
2498
2499     ctl2_alloc_string(This->typelib, szDocString);
2500
2501     return E_OUTOFMEMORY;
2502 }
2503
2504 /******************************************************************************
2505  * ICreateTypeInfo2_SetFuncHelpContext {OLEAUT32}
2506  *
2507  *  See ICreateTypeInfo_SetFuncHelpContext.
2508  */
2509 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(
2510         ICreateTypeInfo2* iface,
2511         UINT index,
2512         DWORD dwHelpContext)
2513 {
2514     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2515     CyclicList *func;
2516
2517     TRACE("(%p,%d,%d)\n", iface, index, dwHelpContext);
2518
2519     if(This->typeinfo->cElement<index)
2520         return TYPE_E_ELEMENTNOTFOUND;
2521
2522     if(This->typeinfo->cElement == index && This->typedata->type == CyclicListFunc)
2523         func = This->typedata;
2524     else
2525         for(func=This->typedata->next->next; func!=This->typedata; func=func->next)
2526             if (func->type == CyclicListFunc)
2527                 if(index-- == 0)
2528                     break;
2529
2530     This->typedata->next->u.val += funcrecord_reallochdr(&func->u.data, 7*sizeof(int));
2531     if(!func->u.data)
2532         return E_OUTOFMEMORY;
2533
2534     func->u.data[6] = dwHelpContext;
2535     return S_OK;
2536 }
2537
2538 /******************************************************************************
2539  * ICreateTypeInfo2_SetVarHelpContext {OLEAUT32}
2540  *
2541  *  See ICreateTypeInfo_SetVarHelpContext.
2542  */
2543 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(
2544         ICreateTypeInfo2* iface,
2545         UINT index,
2546         DWORD dwHelpContext)
2547 {
2548     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpContext);
2549     return E_OUTOFMEMORY;
2550 }
2551
2552 /******************************************************************************
2553  * ICreateTypeInfo2_SetMops {OLEAUT32}
2554  *
2555  *  See ICreateTypeInfo_SetMops.
2556  */
2557 static HRESULT WINAPI ICreateTypeInfo2_fnSetMops(
2558         ICreateTypeInfo2* iface,
2559         UINT index,
2560         BSTR bstrMops)
2561 {
2562     FIXME("(%p,%d,%p), stub!\n", iface, index, bstrMops);
2563     return E_OUTOFMEMORY;
2564 }
2565
2566 /******************************************************************************
2567  * ICreateTypeInfo2_SetTypeIdldesc {OLEAUT32}
2568  *
2569  *  See ICreateTypeInfo_SetTypeIdldesc.
2570  */
2571 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(
2572         ICreateTypeInfo2* iface,
2573         IDLDESC* pIdlDesc)
2574 {
2575     FIXME("(%p,%p), stub!\n", iface, pIdlDesc);
2576     return E_OUTOFMEMORY;
2577 }
2578
2579 /******************************************************************************
2580  * ICreateTypeInfo2_LayOut {OLEAUT32}
2581  *
2582  *  See ICreateTypeInfo_LayOut.
2583  */
2584 static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
2585         ICreateTypeInfo2* iface)
2586 {
2587     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2588     CyclicList *iter, *iter2, *last = NULL, **typedata;
2589     HREFTYPE hreftype;
2590     HRESULT hres;
2591     unsigned user_vft = 0;
2592     int i;
2593
2594     TRACE("(%p)\n", iface);
2595
2596     /* FIXME: LayOut should be run on all ImplTypes */
2597     if(This->typekind == TKIND_COCLASS)
2598         return S_OK;
2599
2600     /* Validate inheritance */
2601     This->typeinfo->datatype2 = 0;
2602     hreftype = This->typeinfo->datatype1;
2603
2604     /* Process internally defined interfaces */
2605     for(i=0; i<This->typelib->typelib_header.nrtypeinfos; i++) {
2606         MSFT_TypeInfoBase *header;
2607
2608         if(hreftype&1)
2609             break;
2610
2611         header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]);
2612         This->typeinfo->datatype2 += (header->cElement<<16) + 1;
2613         hreftype = header->datatype1;
2614     }
2615     if(i == This->typelib->typelib_header.nrtypeinfos)
2616         return TYPE_E_CIRCULARTYPE;
2617
2618     /* Process externally defined interfaces */
2619     if(hreftype != -1) {
2620         ITypeInfo *cur, *next;
2621         TYPEATTR *typeattr;
2622
2623         hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next);
2624         if(FAILED(hres))
2625             return hres;
2626
2627         hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur);
2628         ITypeInfo_Release(next);
2629         if(FAILED(hres))
2630             return hres;
2631
2632
2633         while(1) {
2634             hres = ITypeInfo_GetTypeAttr(cur, &typeattr);
2635             if(FAILED(hres)) {
2636                 ITypeInfo_Release(cur);
2637                 return hres;
2638             }
2639
2640             if(IsEqualGUID(&typeattr->guid, &IID_IDispatch))
2641                 This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
2642
2643             This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1;
2644             ITypeInfo_ReleaseTypeAttr(cur, typeattr);
2645
2646             hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype);
2647             if(hres == TYPE_E_ELEMENTNOTFOUND)
2648                 break;
2649             if(FAILED(hres)) {
2650                 ITypeInfo_Release(cur);
2651                 return hres;
2652             }
2653
2654             hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next);
2655             if(FAILED(hres)) {
2656                 ITypeInfo_Release(cur);
2657                 return hres;
2658             }
2659
2660             ITypeInfo_Release(cur);
2661             cur = next;
2662         }
2663         ITypeInfo_Release(cur);
2664     }
2665
2666     /* Get cbSizeVft of inherited interface */
2667     /* Makes LayOut running recursively */
2668     if(This->typeinfo->datatype1 != -1) {
2669         ITypeInfo *cur, *inherited;
2670         TYPEATTR *typeattr;
2671
2672         hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&cur);
2673         if(FAILED(hres))
2674             return hres;
2675
2676         hres = ITypeInfo_GetRefTypeInfo(cur, This->typeinfo->datatype1, &inherited);
2677         ITypeInfo_Release(cur);
2678         if(FAILED(hres))
2679             return hres;
2680
2681         hres = ITypeInfo_GetTypeAttr(inherited, &typeattr);
2682         if(FAILED(hres)) {
2683             ITypeInfo_Release(inherited);
2684             return hres;
2685         }
2686
2687         This->typeinfo->cbSizeVft = typeattr->cbSizeVft * 4 / sizeof(void *);
2688
2689         ITypeInfo_ReleaseTypeAttr(inherited, typeattr);
2690         ITypeInfo_Release(inherited);
2691     } else
2692         This->typeinfo->cbSizeVft = 0;
2693
2694     if(!This->typedata)
2695         return S_OK;
2696
2697     typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff));
2698     if(!typedata)
2699         return E_OUTOFMEMORY;
2700
2701     /* Assign IDs and VTBL entries */
2702     for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next)
2703         if (iter->type == CyclicListFunc)
2704             last = iter;
2705
2706     if(last && last->u.data[3]&1)
2707         user_vft = last->u.data[3]&0xffff;
2708
2709     i = 0;
2710     for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
2711         /* Assign MEMBERID if MEMBERID_NIL was specified */
2712         if(iter->indice == MEMBERID_NIL) {
2713             iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16);
2714
2715             for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
2716                 if(iter == iter2) continue;
2717                 if(iter2->indice == iter->indice) {
2718                     iter->indice = 0x60000000 + This->typeinfo->cElement + (This->typeinfo->datatype2<<16);
2719
2720                     for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
2721                         if(iter == iter2) continue;
2722                         if(iter2->indice == iter->indice) {
2723                             ++iter->indice;
2724                             iter2 = This->typedata->next;
2725                         }
2726                     }
2727
2728                     break;
2729                 }
2730             }
2731         }
2732
2733         if (iter->type != CyclicListFunc)
2734             continue;
2735
2736         typedata[i] = iter;
2737
2738         iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16);
2739
2740         if((iter->u.data[3]&1) != (user_vft&1)) {
2741             HeapFree(GetProcessHeap(), 0, typedata);
2742             return TYPE_E_INVALIDID;
2743         }
2744
2745         if(user_vft&1) {
2746             if(user_vft < (iter->u.data[3]&0xffff))
2747                 user_vft = (iter->u.data[3]&0xffff);
2748
2749             if((iter->u.data[3]&0xffff) < This->typeinfo->cbSizeVft) {
2750                 HeapFree(GetProcessHeap(), 0, typedata);
2751                 return TYPE_E_INVALIDID;
2752             }
2753         } else if(This->typekind != TKIND_MODULE) {
2754             iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft;
2755             This->typeinfo->cbSizeVft += 4;
2756         }
2757
2758         /* Construct a list of elements with the same memberid */
2759         iter->u.data[4] = (iter->u.data[4]&0xffff) | (i<<16);
2760         for(iter2=This->typedata->next->next; iter2!=iter; iter2=iter2->next) {
2761             if(iter->indice == iter2->indice) {
2762                 int v1, v2;
2763
2764                 v1 = iter->u.data[4] >> 16;
2765                 v2 = iter2->u.data[4] >> 16;
2766
2767                 iter->u.data[4] = (iter->u.data[4]&0xffff) | (v2<<16);
2768                 iter2->u.data[4] = (iter2->u.data[4]&0xffff) | (v1<<16);
2769                 break;
2770             }
2771         }
2772
2773         i++;
2774     }
2775
2776     if(user_vft)
2777         This->typeinfo->cbSizeVft = user_vft+3;
2778
2779     for(i=0; i<(This->typeinfo->cElement&0xffff); i++) {
2780         if(typedata[i]->u.data[4]>>16 > i) {
2781             int inv;
2782
2783             inv = (typedata[i]->u.data[4]>>3) & 0xf;
2784             i = typedata[i]->u.data[4] >> 16;
2785
2786             while(i > typedata[i]->u.data[4]>>16) {
2787                 int invkind = (typedata[i]->u.data[4]>>3) & 0xf;
2788
2789                 if(inv & invkind) {
2790                     HeapFree(GetProcessHeap(), 0, typedata);
2791                     return TYPE_E_DUPLICATEID;
2792                 }
2793
2794                 i = typedata[i]->u.data[4] >> 16;
2795                 inv |= invkind;
2796             }
2797
2798             if(inv & INVOKE_FUNC) {
2799                 HeapFree(GetProcessHeap(), 0, typedata);
2800                 return TYPE_E_INCONSISTENTPROPFUNCS;
2801             }
2802         }
2803     }
2804
2805     HeapFree(GetProcessHeap(), 0, typedata);
2806     return S_OK;
2807 }
2808
2809 /******************************************************************************
2810  * ICreateTypeInfo2_DeleteFuncDesc {OLEAUT32}
2811  *
2812  *  Delete a function description from a type.
2813  *
2814  * RETURNS
2815  *
2816  *  Success: S_OK.
2817  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2818  */
2819 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(
2820         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */
2821         UINT index)              /* [I] The index of the function to delete. */
2822 {
2823     FIXME("(%p,%d), stub!\n", iface, index);
2824     return E_OUTOFMEMORY;
2825 }
2826
2827 /******************************************************************************
2828  * ICreateTypeInfo2_DeleteFuncDescByMemId {OLEAUT32}
2829  *
2830  *  Delete a function description from a type.
2831  *
2832  * RETURNS
2833  *
2834  *  Success: S_OK.
2835  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2836  */
2837 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(
2838         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */
2839         MEMBERID memid,          /* [I] The member id of the function to delete. */
2840         INVOKEKIND invKind)      /* [I] The invocation type of the function to delete. (?) */
2841 {
2842     FIXME("(%p,%d,%d), stub!\n", iface, memid, invKind);
2843     return E_OUTOFMEMORY;
2844 }
2845
2846 /******************************************************************************
2847  * ICreateTypeInfo2_DeleteVarDesc {OLEAUT32}
2848  *
2849  *  Delete a variable description from a type.
2850  *
2851  * RETURNS
2852  *
2853  *  Success: S_OK.
2854  *  Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR,
2855  *  TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE.
2856  */
2857 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc(
2858         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
2859         UINT index)              /* [I] The index of the variable description to delete. */
2860 {
2861     FIXME("(%p,%d), stub!\n", iface, index);
2862     return E_OUTOFMEMORY;
2863 }
2864
2865 /******************************************************************************
2866  * ICreateTypeInfo2_DeleteVarDescByMemId {OLEAUT32}
2867  *
2868  *  Delete a variable description from a type.
2869  *
2870  * RETURNS
2871  *
2872  *  Success: S_OK.
2873  *  Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR,
2874  *  TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE.
2875  */
2876 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(
2877         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
2878         MEMBERID memid)          /* [I] The member id of the variable description to delete. */
2879 {
2880     FIXME("(%p,%d), stub!\n", iface, memid);
2881     return E_OUTOFMEMORY;
2882 }
2883
2884 /******************************************************************************
2885  * ICreateTypeInfo2_DeleteImplType {OLEAUT32}
2886  *
2887  *  Delete an interface implementation from a type. (?)
2888  *
2889  * RETURNS
2890  *
2891  *  Success: S_OK.
2892  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2893  */
2894 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(
2895         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete. */
2896         UINT index)              /* [I] The index of the interface to delete. */
2897 {
2898     FIXME("(%p,%d), stub!\n", iface, index);
2899     return E_OUTOFMEMORY;
2900 }
2901
2902 /******************************************************************************
2903  * ICreateTypeInfo2_SetCustData {OLEAUT32}
2904  *
2905  *  Set the custom data for a type.
2906  *
2907  * RETURNS
2908  *
2909  *  Success: S_OK.
2910  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2911  */
2912 static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(
2913         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
2914         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2915         VARIANT* pVarVal)        /* [I] The custom data. */
2916 {
2917     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2918
2919     TRACE("(%p,%s,%p)!\n", iface, debugstr_guid(guid), pVarVal);
2920
2921     if (!pVarVal)
2922             return E_INVALIDARG;
2923
2924     return ctl2_set_custdata(This->typelib, guid, pVarVal, &This->typeinfo->oCustData);
2925 }
2926
2927 /******************************************************************************
2928  * ICreateTypeInfo2_SetFuncCustData {OLEAUT32}
2929  *
2930  *  Set the custom data for a function.
2931  *
2932  * RETURNS
2933  *
2934  *  Success: S_OK.
2935  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2936  */
2937 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(
2938         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
2939         UINT index,              /* [I] The index of the function for which to set the custom data. */
2940         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2941         VARIANT* pVarVal)        /* [I] The custom data. */
2942 {
2943     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2944     CyclicList *iter;
2945
2946     TRACE("(%p,%d,%s,%p)\n", iface, index, debugstr_guid(guid), pVarVal);
2947
2948     if(index >= (This->typeinfo->cElement&0xFFFF))
2949         return TYPE_E_ELEMENTNOTFOUND;
2950
2951     for(iter=This->typedata->next->next; /* empty */; iter=iter->next)
2952         if (iter->type == CyclicListFunc)
2953             if (index-- == 0)
2954                 break;
2955
2956     This->typedata->next->u.val += funcrecord_reallochdr(&iter->u.data, 13*sizeof(int));
2957     if(!iter->u.data)
2958         return E_OUTOFMEMORY;
2959
2960     iter->u.data[4] |= 0x80;
2961     return ctl2_set_custdata(This->typelib, guid, pVarVal, &iter->u.data[12]);
2962 }
2963
2964 /******************************************************************************
2965  * ICreateTypeInfo2_SetParamCustData {OLEAUT32}
2966  *
2967  *  Set the custom data for a function parameter.
2968  *
2969  * RETURNS
2970  *
2971  *  Success: S_OK.
2972  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2973  */
2974 static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(
2975         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
2976         UINT indexFunc,          /* [I] The index of the function on which the parameter resides. */
2977         UINT indexParam,         /* [I] The index of the parameter on which to set the custom data. */
2978         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2979         VARIANT* pVarVal)        /* [I] The custom data. */
2980 {
2981     FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
2982     return E_OUTOFMEMORY;
2983 }
2984
2985 /******************************************************************************
2986  * ICreateTypeInfo2_SetVarCustData {OLEAUT32}
2987  *
2988  *  Set the custom data for a variable.
2989  *
2990  * RETURNS
2991  *
2992  *  Success: S_OK.
2993  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2994  */
2995 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData(
2996         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
2997         UINT index,              /* [I] The index of the variable on which to set the custom data. */
2998         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2999         VARIANT* pVarVal)        /* [I] The custom data. */
3000 {
3001     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3002     return E_OUTOFMEMORY;
3003 }
3004
3005 /******************************************************************************
3006  * ICreateTypeInfo2_SetImplTypeCustData {OLEAUT32}
3007  *
3008  *  Set the custom data for an implemented interface.
3009  *
3010  * RETURNS
3011  *
3012  *  Success: S_OK.
3013  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3014  */
3015 static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData(
3016         ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the custom data. */
3017         UINT index,              /* [I] The index of the implemented interface on which to set the custom data. */
3018         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
3019         VARIANT* pVarVal)        /* [I] The custom data. */
3020 {
3021     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3022     return E_OUTOFMEMORY;
3023 }
3024
3025 /******************************************************************************
3026  * ICreateTypeInfo2_SetHelpStringContext {OLEAUT32}
3027  *
3028  *  Set the help string context for the typeinfo.
3029  *
3030  * RETURNS
3031  *
3032  *  Success: S_OK.
3033  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3034  */
3035 static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(
3036         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
3037         ULONG dwHelpStringContext) /* [I] The help string context. */
3038 {
3039     FIXME("(%p,%d), stub!\n", iface, dwHelpStringContext);
3040     return E_OUTOFMEMORY;
3041 }
3042
3043 /******************************************************************************
3044  * ICreateTypeInfo2_SetFuncHelpStringContext {OLEAUT32}
3045  *
3046  *  Set the help string context for a function.
3047  *
3048  * RETURNS
3049  *
3050  *  Success: S_OK.
3051  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3052  */
3053 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(
3054         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
3055         UINT index,                /* [I] The index for the function on which to set the help string context. */
3056         ULONG dwHelpStringContext) /* [I] The help string context. */
3057 {
3058     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
3059     return E_OUTOFMEMORY;
3060 }
3061
3062 /******************************************************************************
3063  * ICreateTypeInfo2_SetVarHelpStringContext {OLEAUT32}
3064  *
3065  *  Set the help string context for a variable.
3066  *
3067  * RETURNS
3068  *
3069  *  Success: S_OK.
3070  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3071  */
3072 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(
3073         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
3074         UINT index,                /* [I] The index of the variable on which to set the help string context. */
3075         ULONG dwHelpStringContext) /* [I] The help string context */
3076 {
3077     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
3078     return E_OUTOFMEMORY;
3079 }
3080
3081 /******************************************************************************
3082  * ICreateTypeInfo2_Invalidate {OLEAUT32}
3083  *
3084  *  Undocumented function. (!)
3085  */
3086 static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate(
3087         ICreateTypeInfo2* iface)
3088 {
3089     FIXME("(%p), stub!\n", iface);
3090     return E_OUTOFMEMORY;
3091 }
3092
3093 /******************************************************************************
3094  * ICreateTypeInfo2_SetName {OLEAUT32}
3095  *
3096  *  Set the name for a typeinfo.
3097  *
3098  * RETURNS
3099  *
3100  *  Success: S_OK.
3101  *  Failure: One of STG_E_INSUFFICIENTMEMORY, E_OUTOFMEMORY, E_INVALIDARG or TYPE_E_INVALIDSTATE.
3102  */
3103 static HRESULT WINAPI ICreateTypeInfo2_fnSetName(
3104         ICreateTypeInfo2* iface,
3105         LPOLESTR szName)
3106 {
3107     FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
3108     return E_OUTOFMEMORY;
3109 }
3110
3111 /*================== ITypeInfo2 Implementation ===================================*/
3112
3113 /******************************************************************************
3114  * ITypeInfo2_QueryInterface {OLEAUT32}
3115  *
3116  *  See IUnknown_QueryInterface.
3117  */
3118 static HRESULT WINAPI ITypeInfo2_fnQueryInterface(ITypeInfo2 * iface, REFIID riid, LPVOID * ppv)
3119 {
3120     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3121
3122     return ICreateTypeInfo2_QueryInterface((ICreateTypeInfo2 *)This, riid, ppv);
3123 }
3124
3125 /******************************************************************************
3126  * ITypeInfo2_AddRef {OLEAUT32}
3127  *
3128  *  See IUnknown_AddRef.
3129  */
3130 static ULONG WINAPI ITypeInfo2_fnAddRef(ITypeInfo2 * iface)
3131 {
3132     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3133
3134     return ICreateTypeInfo2_AddRef((ICreateTypeInfo2 *)This);
3135 }
3136
3137 /******************************************************************************
3138  * ITypeInfo2_Release {OLEAUT32}
3139  *
3140  *  See IUnknown_Release.
3141  */
3142 static ULONG WINAPI ITypeInfo2_fnRelease(ITypeInfo2 * iface)
3143 {
3144     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3145
3146     return ICreateTypeInfo2_Release((ICreateTypeInfo2 *)This);
3147 }
3148
3149 /******************************************************************************
3150  * ITypeInfo2_GetTypeAttr {OLEAUT32}
3151  *
3152  *  See ITypeInfo_GetTypeAttr.
3153  */
3154 static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr(
3155         ITypeInfo2* iface,
3156         TYPEATTR** ppTypeAttr)
3157 {
3158     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3159     HRESULT hres;
3160
3161     TRACE("(%p,%p)\n", iface, ppTypeAttr);
3162
3163     if(!ppTypeAttr)
3164         return E_INVALIDARG;
3165
3166     hres = ICreateTypeInfo_LayOut((ICreateTypeInfo*)This);
3167     if(FAILED(hres))
3168         return hres;
3169
3170     *ppTypeAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEATTR));
3171     if(!*ppTypeAttr)
3172         return E_OUTOFMEMORY;
3173
3174     if(This->typeinfo->posguid != -1) {
3175         MSFT_GuidEntry *guid;
3176
3177         guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][This->typeinfo->posguid];
3178         (*ppTypeAttr)->guid = guid->guid;
3179     }
3180
3181     (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid;
3182     (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size;
3183     (*ppTypeAttr)->typekind = This->typekind;
3184     (*ppTypeAttr)->cFuncs = This->typeinfo->cElement&0xffff;
3185     if(This->typeinfo->flags&TYPEFLAG_FDUAL && This->typekind==TKIND_DISPATCH)
3186         (*ppTypeAttr)->cFuncs += 7;
3187     (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16;
3188     (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes;
3189     (*ppTypeAttr)->cbSizeVft = This->typekind==TKIND_DISPATCH ? 7 * sizeof(void*) : This->typeinfo->cbSizeVft;
3190     (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f;
3191     (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags;
3192     (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff;
3193     (*ppTypeAttr)->wMinorVerNum = This->typeinfo->version>>16;
3194
3195     if((*ppTypeAttr)->typekind == TKIND_ALIAS)
3196         FIXME("TKIND_ALIAS handling not implemented\n");
3197
3198     return S_OK;
3199 }
3200
3201 /******************************************************************************
3202  * ITypeInfo2_GetTypeComp {OLEAUT32}
3203  *
3204  *  See ITypeInfo_GetTypeComp.
3205  */
3206 static HRESULT WINAPI ITypeInfo2_fnGetTypeComp(
3207         ITypeInfo2* iface,
3208         ITypeComp** ppTComp)
3209 {
3210     FIXME("(%p,%p), stub!\n", iface, ppTComp);
3211     return E_OUTOFMEMORY;
3212 }
3213
3214 /******************************************************************************
3215  * ITypeInfo2_GetFuncDesc {OLEAUT32}
3216  *
3217  *  See ITypeInfo_GetFuncDesc.
3218  */
3219 static HRESULT WINAPI ITypeInfo2_fnGetFuncDesc(
3220         ITypeInfo2* iface,
3221         UINT index,
3222         FUNCDESC** ppFuncDesc)
3223 {
3224     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3225     int i, *typedata, num_defaults = 0, hdr_len, tail, has_defaults;
3226     CyclicList *desc;
3227     HRESULT hres;
3228
3229     TRACE("(%p,%d,%p), semi-stub\n", iface, index, ppFuncDesc);
3230
3231     if (!ppFuncDesc)
3232         return E_INVALIDARG;
3233
3234     if (index >= This->typeinfo->cElement)
3235         return TYPE_E_ELEMENTNOTFOUND;
3236
3237     hres = ICreateTypeInfo2_LayOut((ICreateTypeInfo2*)This);
3238     if (FAILED(hres))
3239         return hres;
3240
3241     desc = This->typedata->next;
3242     for (i = index; i >= 0; ) {
3243         desc = desc->next;
3244         if (desc->type == CyclicListFunc)
3245             --i;
3246     }
3247
3248     typedata = desc->u.data;
3249
3250     *ppFuncDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FUNCDESC));
3251     if (!*ppFuncDesc)
3252         return E_OUTOFMEMORY;
3253
3254     (*ppFuncDesc)->memid = desc->indice;
3255     (*ppFuncDesc)->lprgscode = NULL; /* FIXME: Unimplemented */
3256     (*ppFuncDesc)->funckind = typedata[4] & 0x7;
3257     (*ppFuncDesc)->invkind = (typedata[4] >> 3) & 0xF;
3258     (*ppFuncDesc)->callconv = (typedata[4] >> 8) & 0xF;
3259     (*ppFuncDesc)->cParams = typedata[5];
3260     (*ppFuncDesc)->cParamsOpt = 0; /* FIXME: Unimplemented*/
3261     (*ppFuncDesc)->oVft = typedata[3] & 0xFFFF;
3262     if ((*ppFuncDesc)->oVft)
3263         --(*ppFuncDesc)->oVft;
3264     (*ppFuncDesc)->cScodes = 0; /* FIXME: Unimplemented*/
3265     hres = ctl2_decode_typedesc(This->typelib, typedata[1],
3266             &(*ppFuncDesc)->elemdescFunc.tdesc);
3267     if (FAILED(hres)) {
3268         HeapFree(GetProcessHeap(), 0, *ppFuncDesc);
3269         return hres;
3270     }
3271     (*ppFuncDesc)->wFuncFlags = typedata[2];
3272
3273     has_defaults = typedata[4] & 0x1000;
3274     tail = typedata[5] * (has_defaults ? 16 : 12);
3275     hdr_len = ((typedata[0] & 0xFFFF) - tail) / sizeof(int);
3276
3277     if ((*ppFuncDesc)->cParams > 0) {
3278         (*ppFuncDesc)->lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (*ppFuncDesc)->cParams * sizeof(ELEMDESC));
3279         if (!(*ppFuncDesc)->lprgelemdescParam) {
3280             HeapFree(GetProcessHeap(), 0, *ppFuncDesc);
3281             return E_OUTOFMEMORY;
3282         }
3283         if (has_defaults) {
3284             num_defaults = (*ppFuncDesc)->cParams;
3285
3286             for (i = 0; i < num_defaults; ++i) {
3287                 if (typedata[hdr_len + i] != 0xFFFFFFFF) {
3288                     (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags |= PARAMFLAG_FHASDEFAULT;
3289
3290                     (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex = HeapAlloc(GetProcessHeap(), 0, sizeof(PARAMDESCEX));
3291                     if (!(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex) {
3292                         ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
3293                         return E_OUTOFMEMORY;
3294                     }
3295
3296                     (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->cBytes = sizeof(PARAMDESCEX);
3297                     hres = ctl2_decode_variant(This->typelib, typedata[hdr_len + i],
3298                             &(*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
3299                     if (FAILED(hres)) {
3300                         ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
3301                         return hres;
3302                     }
3303                 }
3304             }
3305         }
3306
3307         for (i = 0; i < (*ppFuncDesc)->cParams; ++i) {
3308             hres = ctl2_decode_typedesc(This->typelib, typedata[hdr_len + num_defaults + (i * 3)],
3309                     &((*ppFuncDesc)->lprgelemdescParam + i)->tdesc);
3310             if (FAILED(hres)) {
3311                 ITypeInfo2_ReleaseFuncDesc(iface, *ppFuncDesc);
3312                 return hres;
3313             }
3314             (*ppFuncDesc)->lprgelemdescParam[i].u.paramdesc.wParamFlags = typedata[hdr_len + num_defaults + (i * 3) + 2];
3315         }
3316     }
3317
3318     return S_OK;
3319 }
3320
3321 /******************************************************************************
3322  * ITypeInfo2_GetVarDesc {OLEAUT32}
3323  *
3324  *  See ITypeInfo_GetVarDesc.
3325  */
3326 static HRESULT WINAPI ITypeInfo2_fnGetVarDesc(
3327         ITypeInfo2* iface,
3328         UINT index,
3329         VARDESC** ppVarDesc)
3330 {
3331     FIXME("(%p,%d,%p), stub!\n", iface, index, ppVarDesc);
3332     return E_OUTOFMEMORY;
3333 }
3334
3335 /******************************************************************************
3336  * ITypeInfo2_GetNames {OLEAUT32}
3337  *
3338  *  See ITypeInfo_GetNames.
3339  */
3340 static HRESULT WINAPI ITypeInfo2_fnGetNames(
3341         ITypeInfo2* iface,
3342         MEMBERID memid,
3343         BSTR* rgBstrNames,
3344         UINT cMaxNames,
3345         UINT* pcNames)
3346 {
3347     FIXME("(%p,%d,%p,%d,%p), stub!\n", iface, memid, rgBstrNames, cMaxNames, pcNames);
3348     return E_OUTOFMEMORY;
3349 }
3350
3351 /******************************************************************************
3352  * ITypeInfo2_GetRefTypeOfImplType {OLEAUT32}
3353  *
3354  *  See ITypeInfo_GetRefTypeOfImplType.
3355  */
3356 static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType(
3357         ITypeInfo2* iface,
3358         UINT index,
3359         HREFTYPE* pRefType)
3360 {
3361     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3362     MSFT_RefRecord *ref;
3363     int offset;
3364
3365     TRACE("(%p,%d,%p)\n", iface, index, pRefType);
3366
3367     if(!pRefType)
3368         return E_INVALIDARG;
3369
3370     if(This->typeinfo->flags&TYPEFLAG_FDUAL) {
3371         if(index == -1) {
3372             *pRefType = -2;
3373             return S_OK;
3374         }
3375
3376         if(This->typekind == TKIND_DISPATCH)
3377             return ITypeInfo2_GetRefTypeOfImplType((ITypeInfo2*)&This->dual->lpVtblTypeInfo2,
3378                     index, pRefType);
3379     }
3380
3381     if(index>=This->typeinfo->cImplTypes)
3382         return TYPE_E_ELEMENTNOTFOUND;
3383
3384     if(This->typekind == TKIND_INTERFACE) {
3385         *pRefType = This->typeinfo->datatype1 + 2;
3386         return S_OK;
3387     }
3388
3389     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
3390     if(offset == -1)
3391         return TYPE_E_ELEMENTNOTFOUND;
3392
3393     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
3394     *pRefType = ref->reftype;
3395     return S_OK;
3396 }
3397
3398 /******************************************************************************
3399  * ITypeInfo2_GetImplTypeFlags {OLEAUT32}
3400  *
3401  *  See ITypeInfo_GetImplTypeFlags.
3402  */
3403 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags(
3404         ITypeInfo2* iface,
3405         UINT index,
3406         INT* pImplTypeFlags)
3407 {
3408     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3409     int offset;
3410     MSFT_RefRecord *ref;
3411
3412     TRACE("(%p,%d,%p)\n", iface, index, pImplTypeFlags);
3413
3414     if(!pImplTypeFlags)
3415         return E_INVALIDARG;
3416
3417     if(index >= This->typeinfo->cImplTypes)
3418         return TYPE_E_ELEMENTNOTFOUND;
3419
3420     if(This->typekind != TKIND_COCLASS) {
3421         *pImplTypeFlags = 0;
3422         return S_OK;
3423     }
3424
3425     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
3426     if(offset == -1)
3427         return TYPE_E_ELEMENTNOTFOUND;
3428
3429     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
3430     *pImplTypeFlags = ref->flags;
3431     return S_OK;
3432 }
3433
3434 /******************************************************************************
3435  * ITypeInfo2_GetIDsOfNames {OLEAUT32}
3436  *
3437  *  See ITypeInfo_GetIDsOfNames.
3438  */
3439 static HRESULT WINAPI ITypeInfo2_fnGetIDsOfNames(
3440         ITypeInfo2* iface,
3441         LPOLESTR* rgszNames,
3442         UINT cNames,
3443         MEMBERID* pMemId)
3444 {
3445     FIXME("(%p,%p,%d,%p), stub!\n", iface, rgszNames, cNames, pMemId);
3446     return E_OUTOFMEMORY;
3447 }
3448
3449 /******************************************************************************
3450  * ITypeInfo2_Invoke {OLEAUT32}
3451  *
3452  *  See ITypeInfo_Invoke.
3453  */
3454 static HRESULT WINAPI ITypeInfo2_fnInvoke(
3455         ITypeInfo2* iface,
3456         PVOID pvInstance,
3457         MEMBERID memid,
3458         WORD wFlags,
3459         DISPPARAMS* pDispParams,
3460         VARIANT* pVarResult,
3461         EXCEPINFO* pExcepInfo,
3462         UINT* puArgErr)
3463 {
3464     FIXME("(%p,%p,%d,%x,%p,%p,%p,%p), stub!\n", iface, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3465     return E_OUTOFMEMORY;
3466 }
3467
3468 /******************************************************************************
3469  * ITypeInfo2_GetDocumentation {OLEAUT32}
3470  *
3471  *  See ITypeInfo_GetDocumentation.
3472  */
3473 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation(
3474         ITypeInfo2* iface,
3475         MEMBERID memid,
3476         BSTR* pBstrName,
3477         BSTR* pBstrDocString,
3478         DWORD* pdwHelpContext,
3479         BSTR* pBstrHelpFile)
3480 {
3481     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3482     HRESULT status = TYPE_E_ELEMENTNOTFOUND;
3483     INT nameoffset, docstringoffset, helpcontext;
3484
3485     TRACE("(%p,%d,%p,%p,%p,%p)\n", iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
3486
3487     if (memid == -1)
3488     {
3489         nameoffset = This->typeinfo->NameOffset;
3490         docstringoffset = This->typeinfo->docstringoffs;
3491         helpcontext = This->typeinfo->helpcontext;
3492         status = S_OK;
3493     } else {
3494         CyclicList *iter;
3495         if (This->typedata) {
3496             for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
3497                 if (iter->indice == memid) {
3498                     if (iter->type == CyclicListFunc) {
3499                         const int *typedata = iter->u.data;
3500                         int   size = (typedata[0]&0xFFFF) - typedata[5]*(typedata[4]&0x1000?16:12);
3501
3502                         nameoffset = iter->name;
3503                         /* FIXME implement this once SetFuncDocString is implemented */
3504                         docstringoffset = -1;
3505                         helpcontext = (size < 7*sizeof(int)) ? 0 : typedata[6];
3506
3507                         status = S_OK;
3508                     } else {
3509                         FIXME("Not implemented for variable members\n");
3510                     }
3511
3512                     break;
3513                 }
3514             }
3515         }
3516     }
3517
3518     if (!status) {
3519         WCHAR *string;
3520         if (pBstrName) {
3521             if (nameoffset == -1)
3522                 *pBstrName = NULL;
3523             else {
3524                 MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib->
3525                         typelib_segment_data[MSFT_SEG_NAME][nameoffset];
3526                 ctl2_decode_name((char*)&name->namelen, &string);
3527                 *pBstrName = SysAllocString(string);
3528                 if(!*pBstrName)
3529                     return E_OUTOFMEMORY;
3530             }
3531         }
3532
3533         if (pBstrDocString) {
3534             if (docstringoffset == -1)
3535                 *pBstrDocString = NULL;
3536             else {
3537                 MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib->
3538                         typelib_segment_data[MSFT_SEG_NAME][docstringoffset];
3539                 ctl2_decode_name((char*)&name->namelen, &string);
3540                 *pBstrDocString = SysAllocString(string);
3541                 if(!*pBstrDocString) {
3542                     if (pBstrName) SysFreeString(*pBstrName);
3543                     return E_OUTOFMEMORY;
3544                 }
3545             }
3546         }
3547
3548         if (pdwHelpContext) {
3549             *pdwHelpContext = helpcontext;
3550         }
3551
3552         if (pBstrHelpFile) {
3553             status = ITypeLib_GetDocumentation((ITypeLib*)&This->typelib->lpVtblTypeLib2,
3554                     -1, NULL, NULL, NULL, pBstrHelpFile);
3555             if (status) {
3556                 if (pBstrName) SysFreeString(*pBstrName);
3557                 if (pBstrDocString) SysFreeString(*pBstrDocString);
3558             }
3559         }
3560     }
3561
3562     return status;
3563 }
3564
3565 /******************************************************************************
3566  * ITypeInfo2_GetDllEntry {OLEAUT32}
3567  *
3568  *  See ITypeInfo_GetDllEntry.
3569  */
3570 static HRESULT WINAPI ITypeInfo2_fnGetDllEntry(
3571         ITypeInfo2* iface,
3572         MEMBERID memid,
3573         INVOKEKIND invKind,
3574         BSTR* pBstrDllName,
3575         BSTR* pBstrName,
3576         WORD* pwOrdinal)
3577 {
3578     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
3579     return E_OUTOFMEMORY;
3580 }
3581
3582 /******************************************************************************
3583  * ITypeInfo2_GetRefTypeInfo {OLEAUT32}
3584  *
3585  *  See ITypeInfo_GetRefTypeInfo.
3586  */
3587 static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo(
3588         ITypeInfo2* iface,
3589         HREFTYPE hRefType,
3590         ITypeInfo** ppTInfo)
3591 {
3592     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3593
3594     TRACE("(%p,%d,%p)\n", iface, hRefType, ppTInfo);
3595
3596     if(!ppTInfo)
3597         return E_INVALIDARG;
3598
3599     if(hRefType==-2 && This->dual) {
3600         *ppTInfo = (ITypeInfo*)&This->dual->lpVtblTypeInfo2;
3601         ITypeInfo_AddRef(*ppTInfo);
3602         return S_OK;
3603     }
3604
3605     if(hRefType&1) {
3606         ITypeLib *tl;
3607         MSFT_ImpInfo *impinfo;
3608         MSFT_ImpFile *impfile;
3609         MSFT_GuidEntry *guid;
3610         WCHAR *filename;
3611         HRESULT hres;
3612
3613         if((hRefType&(~0x3)) >= This->typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length)
3614             return E_FAIL;
3615
3616         impinfo = (MSFT_ImpInfo*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][hRefType&(~0x3)];
3617         impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile];
3618         guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid];
3619
3620         ctl2_decode_string(impfile->filename, &filename);
3621
3622         hres = LoadTypeLib(filename, &tl);
3623         if(FAILED(hres))
3624             return hres;
3625
3626         hres = ITypeLib_GetTypeInfoOfGuid(tl, &guid->guid, ppTInfo);
3627
3628         ITypeLib_Release(tl);
3629         return hres;
3630     } else {
3631         ICreateTypeInfo2Impl *iter;
3632         int i = 0;
3633
3634         for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) {
3635             if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) {
3636                 *ppTInfo = (ITypeInfo*)&iter->lpVtblTypeInfo2;
3637
3638                 ITypeLib_AddRef(*ppTInfo);
3639                 return S_OK;
3640             }
3641             i++;
3642         }
3643     }
3644
3645     return E_FAIL;
3646 }
3647
3648 /******************************************************************************
3649  * ITypeInfo2_AddressOfMember {OLEAUT32}
3650  *
3651  *  See ITypeInfo_AddressOfMember.
3652  */
3653 static HRESULT WINAPI ITypeInfo2_fnAddressOfMember(
3654         ITypeInfo2* iface,
3655         MEMBERID memid,
3656         INVOKEKIND invKind,
3657         PVOID* ppv)
3658 {
3659     FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, ppv);
3660     return E_OUTOFMEMORY;
3661 }
3662
3663 /******************************************************************************
3664  * ITypeInfo2_CreateInstance {OLEAUT32}
3665  *
3666  *  See ITypeInfo_CreateInstance.
3667  */
3668 static HRESULT WINAPI ITypeInfo2_fnCreateInstance(
3669         ITypeInfo2* iface,
3670         IUnknown* pUnkOuter,
3671         REFIID riid,
3672         PVOID* ppvObj)
3673 {
3674     FIXME("(%p,%p,%s,%p), stub!\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj);
3675     return E_OUTOFMEMORY;
3676 }
3677
3678 /******************************************************************************
3679  * ITypeInfo2_GetMops {OLEAUT32}
3680  *
3681  *  See ITypeInfo_GetMops.
3682  */
3683 static HRESULT WINAPI ITypeInfo2_fnGetMops(
3684         ITypeInfo2* iface,
3685         MEMBERID memid,
3686         BSTR* pBstrMops)
3687 {
3688     FIXME("(%p,%d,%p), stub!\n", iface, memid, pBstrMops);
3689     return E_OUTOFMEMORY;
3690 }
3691
3692 /******************************************************************************
3693  * ITypeInfo2_GetContainingTypeLib {OLEAUT32}
3694  *
3695  *  See ITypeInfo_GetContainingTypeLib.
3696  */
3697 static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib(
3698         ITypeInfo2* iface,
3699         ITypeLib** ppTLib,
3700         UINT* pIndex)
3701 {
3702     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3703
3704     TRACE("(%p,%p,%p)\n", iface, ppTLib, pIndex);
3705     
3706     *ppTLib = (ITypeLib *)&This->typelib->lpVtblTypeLib2;
3707     ICreateTypeLib_AddRef((ICreateTypeLib*)This->typelib);
3708     *pIndex = This->typeinfo->typekind >> 16;
3709
3710     return S_OK;
3711 }
3712
3713 static void release_typedesc(TYPEDESC *tdesc)
3714 {
3715     while (tdesc) {
3716         TYPEDESC *next;
3717         if (tdesc->vt == VT_USERDEFINED)
3718             next = NULL;
3719         else
3720             next = tdesc->u.lptdesc;
3721         HeapFree(GetProcessHeap(), 0, tdesc);
3722         tdesc = next;
3723     }
3724 }
3725
3726 /******************************************************************************
3727  * ITypeInfo2_ReleaseTypeAttr {OLEAUT32}
3728  *
3729  *  See ITypeInfo_ReleaseTypeAttr.
3730  */
3731 static void WINAPI ITypeInfo2_fnReleaseTypeAttr(
3732         ITypeInfo2* iface,
3733         TYPEATTR* pTypeAttr)
3734 {
3735     TRACE("(%p,%p)\n", iface, pTypeAttr);
3736
3737     if (pTypeAttr->tdescAlias.vt != VT_USERDEFINED)
3738         release_typedesc(pTypeAttr->tdescAlias.u.lptdesc);
3739
3740     HeapFree(GetProcessHeap(), 0, pTypeAttr);
3741 }
3742
3743 /******************************************************************************
3744  * ITypeInfo2_ReleaseFuncDesc {OLEAUT32}
3745  *
3746  *  See ITypeInfo_ReleaseFuncDesc.
3747  */
3748 static void WINAPI ITypeInfo2_fnReleaseFuncDesc(
3749         ITypeInfo2* iface,
3750         FUNCDESC* pFuncDesc)
3751 {
3752     int i;
3753
3754     TRACE("(%p,%p)\n", iface, pFuncDesc);
3755
3756     HeapFree(GetProcessHeap(), 0, pFuncDesc->lprgscode);
3757
3758     if (pFuncDesc->lprgelemdescParam) {
3759         for (i = 0; i < pFuncDesc->cParams; ++i) {
3760             if (pFuncDesc->lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED)
3761                 release_typedesc(pFuncDesc->lprgelemdescParam[i].tdesc.u.lptdesc);
3762
3763             HeapFree(GetProcessHeap(), 0, pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex);
3764         }
3765         HeapFree(GetProcessHeap(), 0, pFuncDesc->lprgelemdescParam);
3766     }
3767
3768     HeapFree(GetProcessHeap(), 0, pFuncDesc->elemdescFunc.u.paramdesc.pparamdescex);
3769
3770     if (pFuncDesc->elemdescFunc.tdesc.vt != VT_USERDEFINED)
3771         release_typedesc(pFuncDesc->elemdescFunc.tdesc.u.lptdesc);
3772
3773     HeapFree(GetProcessHeap(), 0, pFuncDesc);
3774 }
3775
3776 /******************************************************************************
3777  * ITypeInfo2_ReleaseVarDesc {OLEAUT32}
3778  *
3779  *  See ITypeInfo_ReleaseVarDesc.
3780  */
3781 static void WINAPI ITypeInfo2_fnReleaseVarDesc(
3782         ITypeInfo2* iface,
3783         VARDESC* pVarDesc)
3784 {
3785     FIXME("(%p,%p), stub!\n", iface, pVarDesc);
3786 }
3787
3788 /******************************************************************************
3789  * ITypeInfo2_GetTypeKind {OLEAUT32}
3790  *
3791  *  Get the TYPEKIND value for a TypeInfo.
3792  *
3793  * RETURNS
3794  *
3795  *  Success: S_OK.
3796  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3797  */
3798 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind(
3799         ITypeInfo2* iface,   /* [I] The TypeInfo to obtain the typekind for. */
3800         TYPEKIND* pTypeKind) /* [O] The typekind for this TypeInfo. */
3801 {
3802     FIXME("(%p,%p), stub!\n", iface, pTypeKind);
3803     return E_OUTOFMEMORY;
3804 }
3805
3806 /******************************************************************************
3807  * ITypeInfo2_GetTypeFlags {OLEAUT32}
3808  *
3809  *  Get the Type Flags for a TypeInfo.
3810  *
3811  * RETURNS
3812  *
3813  *  Success: S_OK.
3814  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3815  */
3816 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags(
3817         ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typeflags for. */
3818         ULONG* pTypeFlags) /* [O] The type flags for this TypeInfo. */
3819 {
3820     FIXME("(%p,%p), stub!\n", iface, pTypeFlags);
3821     return E_OUTOFMEMORY;
3822 }
3823
3824 /******************************************************************************
3825  * ITypeInfo2_GetFuncIndexOfMemId {OLEAUT32}
3826  *
3827  *  Gets the index of a function given its member id.
3828  *
3829  * RETURNS
3830  *
3831  *  Success: S_OK.
3832  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3833  */
3834 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId(
3835         ITypeInfo2* iface,  /* [I] The TypeInfo in which to find the function. */
3836         MEMBERID memid,     /* [I] The member id for the function. */
3837         INVOKEKIND invKind, /* [I] The invocation kind for the function. */
3838         UINT* pFuncIndex)   /* [O] The index of the function. */
3839 {
3840     FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex);
3841     return E_OUTOFMEMORY;
3842 }
3843
3844 /******************************************************************************
3845  * ITypeInfo2_GetVarIndexOfMemId {OLEAUT32}
3846  *
3847  *  Gets the index of a variable given its member id.
3848  *
3849  * RETURNS
3850  *
3851  *  Success: S_OK.
3852  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3853  */
3854 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId(
3855         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the variable. */
3856         MEMBERID memid,    /* [I] The member id for the variable. */
3857         UINT* pVarIndex)   /* [O] The index of the variable. */
3858 {
3859     FIXME("(%p,%d,%p), stub!\n", iface, memid, pVarIndex);
3860     return E_OUTOFMEMORY;
3861 }
3862
3863 /******************************************************************************
3864  * ITypeInfo2_GetCustData {OLEAUT32}
3865  *
3866  *  Gets a custom data element from a TypeInfo.
3867  *
3868  * RETURNS
3869  *
3870  *  Success: S_OK.
3871  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3872  */
3873 static HRESULT WINAPI ITypeInfo2_fnGetCustData(
3874         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3875         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3876         VARIANT* pVarVal)  /* [O] The custom data. */
3877 {
3878     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3879     MSFT_CDGuid *cdentry;
3880     int offset;
3881
3882     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal);
3883
3884     if (!guid || !pVarVal)
3885         return E_INVALIDARG;
3886
3887     VariantClear(pVarVal);
3888
3889     offset = ctl2_find_custdata(This->typelib, guid, This->typeinfo->oCustData);
3890     if (offset == -1)
3891         return S_OK;
3892
3893     cdentry = (MSFT_CDGuid *)&This->typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][offset];
3894     return ctl2_decode_variant(This->typelib, cdentry->DataOffset, pVarVal);
3895 }
3896
3897 /******************************************************************************
3898  * ITypeInfo2_GetFuncCustData {OLEAUT32}
3899  *
3900  *  Gets a custom data element from a function.
3901  *
3902  * RETURNS
3903  *
3904  *  Success: S_OK.
3905  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3906  */
3907 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
3908         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3909         UINT index,        /* [I] The index of the function for which to retrieve the custom data. */
3910         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3911         VARIANT* pVarVal)  /* [O] The custom data. */
3912 {
3913     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3914     return E_OUTOFMEMORY;
3915 }
3916
3917 /******************************************************************************
3918  * ITypeInfo2_GetParamCustData {OLEAUT32}
3919  *
3920  *  Gets a custom data element from a parameter.
3921  *
3922  * RETURNS
3923  *
3924  *  Success: S_OK.
3925  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3926  */
3927 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
3928         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3929         UINT indexFunc,    /* [I] The index of the function for which to retrieve the custom data. */
3930         UINT indexParam,   /* [I] The index of the parameter for which to retrieve the custom data. */
3931         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3932         VARIANT* pVarVal)  /* [O] The custom data. */
3933 {
3934     FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
3935     return E_OUTOFMEMORY;
3936 }
3937
3938 /******************************************************************************
3939  * ITypeInfo2_GetVarCustData {OLEAUT32}
3940  *
3941  *  Gets a custom data element from a variable.
3942  *
3943  * RETURNS
3944  *
3945  *  Success: S_OK.
3946  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3947  */
3948 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
3949         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3950         UINT index,        /* [I] The index of the variable for which to retrieve the custom data. */
3951         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3952         VARIANT* pVarVal)  /* [O] The custom data. */
3953 {
3954     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3955     return E_OUTOFMEMORY;
3956 }
3957
3958 /******************************************************************************
3959  * ITypeInfo2_GetImplTypeCustData {OLEAUT32}
3960  *
3961  *  Gets a custom data element from an implemented type of a TypeInfo.
3962  *
3963  * RETURNS
3964  *
3965  *  Success: S_OK.
3966  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3967  */
3968 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
3969         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3970         UINT index,        /* [I] The index of the implemented type for which to retrieve the custom data. */
3971         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3972         VARIANT* pVarVal)  /* [O] The custom data. */
3973 {
3974     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3975     return E_OUTOFMEMORY;
3976 }
3977
3978 /******************************************************************************
3979  * ITypeInfo2_GetDocumentation2 {OLEAUT32}
3980  *
3981  *  Gets some documentation from a TypeInfo in a locale-aware fashion.
3982  *
3983  * RETURNS
3984  *
3985  *  Success: S_OK.
3986  *  Failure: One of STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
3987  */
3988 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
3989         ITypeInfo2* iface,           /* [I] The TypeInfo to retrieve the documentation from. */
3990         MEMBERID memid,              /* [I] The member id (why?). */
3991         LCID lcid,                   /* [I] The locale (why?). */
3992         BSTR* pbstrHelpString,       /* [O] The help string. */
3993         DWORD* pdwHelpStringContext, /* [O] The help string context. */
3994         BSTR* pbstrHelpStringDll)    /* [O] The help file name. */
3995 {
3996     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
3997     return E_OUTOFMEMORY;
3998 }
3999
4000 /******************************************************************************
4001  * ITypeInfo2_GetAllCustData {OLEAUT32}
4002  *
4003  *  Gets all of the custom data associated with a TypeInfo.
4004  *
4005  * RETURNS
4006  *
4007  *  Success: S_OK.
4008  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
4009  */
4010 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
4011         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
4012         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
4013 {
4014     FIXME("(%p,%p), stub!\n", iface, pCustData);
4015     return E_OUTOFMEMORY;
4016 }
4017
4018 /******************************************************************************
4019  * ITypeInfo2_GetAllFuncCustData {OLEAUT32}
4020  *
4021  *  Gets all of the custom data associated with a function.
4022  *
4023  * RETURNS
4024  *
4025  *  Success: S_OK.
4026  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
4027  */
4028 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
4029         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
4030         UINT index,          /* [I] The index of the function for which to retrieve the custom data. */
4031         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
4032 {
4033     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
4034     return E_OUTOFMEMORY;
4035 }
4036
4037 /******************************************************************************
4038  * ITypeInfo2_GetAllParamCustData {OLEAUT32}
4039  *
4040  *  Gets all of the custom data associated with a parameter.
4041  *
4042  * RETURNS
4043  *
4044  *  Success: S_OK.
4045  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
4046  */
4047 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData(
4048         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
4049         UINT indexFunc,      /* [I] The index of the function for which to retrieve the custom data. */
4050         UINT indexParam,     /* [I] The index of the parameter for which to retrieve the custom data. */
4051         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
4052 {
4053     FIXME("(%p,%d,%d,%p), stub!\n", iface, indexFunc, indexParam, pCustData);
4054     return E_OUTOFMEMORY;
4055 }
4056
4057 /******************************************************************************
4058  * ITypeInfo2_GetAllVarCustData {OLEAUT32}
4059  *
4060  *  Gets all of the custom data associated with a variable.
4061  *
4062  * RETURNS
4063  *
4064  *  Success: S_OK.
4065  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
4066  */
4067 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData(
4068         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
4069         UINT index,          /* [I] The index of the variable for which to retrieve the custom data. */
4070         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
4071 {
4072     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
4073     return E_OUTOFMEMORY;
4074 }
4075
4076 /******************************************************************************
4077  * ITypeInfo2_GetAllImplTypeCustData {OLEAUT32}
4078  *
4079  *  Gets all of the custom data associated with an implemented type.
4080  *
4081  * RETURNS
4082  *
4083  *  Success: S_OK.
4084  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
4085  */
4086 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
4087         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
4088         UINT index,          /* [I] The index of the implemented type for which to retrieve the custom data. */
4089         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
4090 {
4091     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
4092     return E_OUTOFMEMORY;
4093 }
4094
4095
4096 /*================== ICreateTypeInfo2 & ITypeInfo2 VTABLEs And Creation ===================================*/
4097
4098 static const ICreateTypeInfo2Vtbl ctypeinfo2vt =
4099 {
4100
4101     ICreateTypeInfo2_fnQueryInterface,
4102     ICreateTypeInfo2_fnAddRef,
4103     ICreateTypeInfo2_fnRelease,
4104
4105     ICreateTypeInfo2_fnSetGuid,
4106     ICreateTypeInfo2_fnSetTypeFlags,
4107     ICreateTypeInfo2_fnSetDocString,
4108     ICreateTypeInfo2_fnSetHelpContext,
4109     ICreateTypeInfo2_fnSetVersion,
4110     ICreateTypeInfo2_fnAddRefTypeInfo,
4111     ICreateTypeInfo2_fnAddFuncDesc,
4112     ICreateTypeInfo2_fnAddImplType,
4113     ICreateTypeInfo2_fnSetImplTypeFlags,
4114     ICreateTypeInfo2_fnSetAlignment,
4115     ICreateTypeInfo2_fnSetSchema,
4116     ICreateTypeInfo2_fnAddVarDesc,
4117     ICreateTypeInfo2_fnSetFuncAndParamNames,
4118     ICreateTypeInfo2_fnSetVarName,
4119     ICreateTypeInfo2_fnSetTypeDescAlias,
4120     ICreateTypeInfo2_fnDefineFuncAsDllEntry,
4121     ICreateTypeInfo2_fnSetFuncDocString,
4122     ICreateTypeInfo2_fnSetVarDocString,
4123     ICreateTypeInfo2_fnSetFuncHelpContext,
4124     ICreateTypeInfo2_fnSetVarHelpContext,
4125     ICreateTypeInfo2_fnSetMops,
4126     ICreateTypeInfo2_fnSetTypeIdldesc,
4127     ICreateTypeInfo2_fnLayOut,
4128
4129     ICreateTypeInfo2_fnDeleteFuncDesc,
4130     ICreateTypeInfo2_fnDeleteFuncDescByMemId,
4131     ICreateTypeInfo2_fnDeleteVarDesc,
4132     ICreateTypeInfo2_fnDeleteVarDescByMemId,
4133     ICreateTypeInfo2_fnDeleteImplType,
4134     ICreateTypeInfo2_fnSetCustData,
4135     ICreateTypeInfo2_fnSetFuncCustData,
4136     ICreateTypeInfo2_fnSetParamCustData,
4137     ICreateTypeInfo2_fnSetVarCustData,
4138     ICreateTypeInfo2_fnSetImplTypeCustData,
4139     ICreateTypeInfo2_fnSetHelpStringContext,
4140     ICreateTypeInfo2_fnSetFuncHelpStringContext,
4141     ICreateTypeInfo2_fnSetVarHelpStringContext,
4142     ICreateTypeInfo2_fnInvalidate,
4143     ICreateTypeInfo2_fnSetName
4144 };
4145
4146 static const ITypeInfo2Vtbl typeinfo2vt =
4147 {
4148
4149     ITypeInfo2_fnQueryInterface,
4150     ITypeInfo2_fnAddRef,
4151     ITypeInfo2_fnRelease,
4152
4153     ITypeInfo2_fnGetTypeAttr,
4154     ITypeInfo2_fnGetTypeComp,
4155     ITypeInfo2_fnGetFuncDesc,
4156     ITypeInfo2_fnGetVarDesc,
4157     ITypeInfo2_fnGetNames,
4158     ITypeInfo2_fnGetRefTypeOfImplType,
4159     ITypeInfo2_fnGetImplTypeFlags,
4160     ITypeInfo2_fnGetIDsOfNames,
4161     ITypeInfo2_fnInvoke,
4162     ITypeInfo2_fnGetDocumentation,
4163     ITypeInfo2_fnGetDllEntry,
4164     ITypeInfo2_fnGetRefTypeInfo,
4165     ITypeInfo2_fnAddressOfMember,
4166     ITypeInfo2_fnCreateInstance,
4167     ITypeInfo2_fnGetMops,
4168     ITypeInfo2_fnGetContainingTypeLib,
4169     ITypeInfo2_fnReleaseTypeAttr,
4170     ITypeInfo2_fnReleaseFuncDesc,
4171     ITypeInfo2_fnReleaseVarDesc,
4172
4173     ITypeInfo2_fnGetTypeKind,
4174     ITypeInfo2_fnGetTypeFlags,
4175     ITypeInfo2_fnGetFuncIndexOfMemId,
4176     ITypeInfo2_fnGetVarIndexOfMemId,
4177     ITypeInfo2_fnGetCustData,
4178     ITypeInfo2_fnGetFuncCustData,
4179     ITypeInfo2_fnGetParamCustData,
4180     ITypeInfo2_fnGetVarCustData,
4181     ITypeInfo2_fnGetImplTypeCustData,
4182     ITypeInfo2_fnGetDocumentation2,
4183     ITypeInfo2_fnGetAllCustData,
4184     ITypeInfo2_fnGetAllFuncCustData,
4185     ITypeInfo2_fnGetAllParamCustData,
4186     ITypeInfo2_fnGetAllVarCustData,
4187     ITypeInfo2_fnGetAllImplTypeCustData,
4188 };
4189
4190 static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typelib, WCHAR *szName, TYPEKIND tkind)
4191 {
4192     ICreateTypeInfo2Impl *pCreateTypeInfo2Impl;
4193
4194     int nameoffset;
4195     int typeinfo_offset;
4196     MSFT_TypeInfoBase *typeinfo;
4197
4198     TRACE("Constructing ICreateTypeInfo2 for %s with tkind %d\n", debugstr_w(szName), tkind);
4199
4200     pCreateTypeInfo2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeInfo2Impl));
4201     if (!pCreateTypeInfo2Impl) return NULL;
4202
4203     pCreateTypeInfo2Impl->lpVtbl = &ctypeinfo2vt;
4204     pCreateTypeInfo2Impl->lpVtblTypeInfo2 = &typeinfo2vt;
4205     pCreateTypeInfo2Impl->ref = 1;
4206
4207     pCreateTypeInfo2Impl->typelib = typelib;
4208     ICreateTypeLib_AddRef((ICreateTypeLib*)typelib);
4209
4210     nameoffset = ctl2_alloc_name(typelib, szName);
4211     typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset);
4212     typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset];
4213
4214     typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38;
4215     *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset;
4216
4217     pCreateTypeInfo2Impl->typeinfo = typeinfo;
4218
4219     pCreateTypeInfo2Impl->typekind = tkind;
4220     typeinfo->typekind |= tkind | 0x20;
4221     ICreateTypeInfo2_SetAlignment((ICreateTypeInfo2 *)pCreateTypeInfo2Impl, 4);
4222
4223     switch (tkind) {
4224     case TKIND_ENUM:
4225     case TKIND_INTERFACE:
4226     case TKIND_DISPATCH:
4227     case TKIND_COCLASS:
4228         typeinfo->size = 4;
4229         break;
4230
4231     case TKIND_RECORD:
4232     case TKIND_UNION:
4233         typeinfo->size = 0;
4234         break;
4235
4236     case TKIND_MODULE:
4237         typeinfo->size = 2;
4238         break;
4239
4240     case TKIND_ALIAS:
4241         typeinfo->size = -0x75;
4242         break;
4243
4244     default:
4245         FIXME("(%s,%d), unrecognized typekind %d\n", debugstr_w(szName), tkind, tkind);
4246         typeinfo->size = 0xdeadbeef;
4247         break;
4248     }
4249
4250     if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = pCreateTypeInfo2Impl;
4251     typelib->last_typeinfo = pCreateTypeInfo2Impl;
4252     if (!typelib->typeinfos) typelib->typeinfos = pCreateTypeInfo2Impl;
4253
4254     TRACE(" -- %p\n", pCreateTypeInfo2Impl);
4255
4256     return (ICreateTypeInfo2 *)pCreateTypeInfo2Impl;
4257 }
4258
4259
4260 /*================== ICreateTypeLib2 Implementation ===================================*/
4261
4262 /******************************************************************************
4263  * ICreateTypeLib2_QueryInterface {OLEAUT32}
4264  *
4265  *  See IUnknown_QueryInterface.
4266  */
4267 static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(
4268         ICreateTypeLib2 * iface,
4269         REFIID riid,
4270         VOID **ppvObject)
4271 {
4272     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4273
4274     TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
4275
4276     *ppvObject=NULL;
4277     if(IsEqualIID(riid, &IID_IUnknown) ||
4278        IsEqualIID(riid,&IID_ICreateTypeLib)||
4279        IsEqualIID(riid,&IID_ICreateTypeLib2))
4280     {
4281         *ppvObject = This;
4282     } else if (IsEqualIID(riid, &IID_ITypeLib) ||
4283                IsEqualIID(riid, &IID_ITypeLib2)) {
4284         *ppvObject = &This->lpVtblTypeLib2;
4285     }
4286
4287     if(*ppvObject)
4288     {
4289         ICreateTypeLib2_AddRef(iface);
4290         TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
4291         return S_OK;
4292     }
4293     TRACE("-- Interface: E_NOINTERFACE\n");
4294     return E_NOINTERFACE;
4295 }
4296
4297 /******************************************************************************
4298  * ICreateTypeLib2_AddRef {OLEAUT32}
4299  *
4300  *  See IUnknown_AddRef.
4301  */
4302 static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
4303 {
4304     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4305     ULONG ref = InterlockedIncrement(&This->ref);
4306
4307     TRACE("(%p)->ref was %u\n",This, ref - 1);
4308
4309     return ref;
4310 }
4311
4312 /******************************************************************************
4313  * ICreateTypeLib2_Release {OLEAUT32}
4314  *
4315  *  See IUnknown_Release.
4316  */
4317 static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
4318 {
4319     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4320     ULONG ref = InterlockedDecrement(&This->ref);
4321
4322     TRACE("(%p)->(%u)\n",This, ref);
4323
4324     if (!ref) {
4325         int i;
4326
4327         for (i = 0; i < MSFT_SEG_MAX; i++) {
4328             HeapFree(GetProcessHeap(), 0, This->typelib_segment_data[i]);
4329             This->typelib_segment_data[i] = NULL;
4330         }
4331
4332         HeapFree(GetProcessHeap(), 0, This->filename);
4333         This->filename = NULL;
4334
4335         while (This->typeinfos) {
4336             ICreateTypeInfo2Impl *typeinfo = This->typeinfos;
4337             This->typeinfos = typeinfo->next_typeinfo;
4338             if(typeinfo->typedata) {
4339                 CyclicList *iter, *rem;
4340
4341                 rem = typeinfo->typedata->next;
4342                 typeinfo->typedata->next = NULL;
4343                 iter = rem->next;
4344                 HeapFree(GetProcessHeap(), 0, rem);
4345
4346                 while(iter) {
4347                     rem = iter;
4348                     iter = iter->next;
4349                     HeapFree(GetProcessHeap(), 0, rem->u.data);
4350                     HeapFree(GetProcessHeap(), 0, rem);
4351                 }
4352             }
4353
4354             HeapFree(GetProcessHeap(), 0, typeinfo->dual);
4355             HeapFree(GetProcessHeap(), 0, typeinfo);
4356         }
4357
4358         HeapFree(GetProcessHeap(),0,This);
4359         return 0;
4360     }
4361
4362     return ref;
4363 }
4364
4365
4366 /******************************************************************************
4367  * ICreateTypeLib2_CreateTypeInfo {OLEAUT32}
4368  *
4369  *  See ICreateTypeLib_CreateTypeInfo.
4370  */
4371 static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(
4372         ICreateTypeLib2 * iface,
4373         LPOLESTR szName,
4374         TYPEKIND tkind,
4375         ICreateTypeInfo **ppCTInfo)
4376 {
4377     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4378     char *name;
4379
4380     TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo);
4381
4382     ctl2_encode_name(This, szName, &name);
4383     if(ctl2_find_name(This, name) != -1)
4384         return TYPE_E_NAMECONFLICT;
4385
4386     *ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind);
4387
4388     if (!*ppCTInfo) return E_OUTOFMEMORY;
4389
4390     return S_OK;
4391 }
4392
4393 /******************************************************************************
4394  * ICreateTypeLib2_SetName {OLEAUT32}
4395  *
4396  *  See ICreateTypeLib_SetName.
4397  */
4398 static HRESULT WINAPI ICreateTypeLib2_fnSetName(
4399         ICreateTypeLib2 * iface,
4400         LPOLESTR szName)
4401 {
4402     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4403
4404     int offset;
4405
4406     TRACE("(%p,%s)\n", iface, debugstr_w(szName));
4407
4408     offset = ctl2_alloc_name(This, szName);
4409     if (offset == -1) return E_OUTOFMEMORY;
4410     This->typelib_header.NameOffset = offset;
4411     return S_OK;
4412 }
4413
4414 /******************************************************************************
4415  * ICreateTypeLib2_SetVersion {OLEAUT32}
4416  *
4417  *  See ICreateTypeLib_SetVersion.
4418  */
4419 static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD wMajorVerNum, WORD wMinorVerNum)
4420 {
4421     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4422
4423     TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);
4424
4425     This->typelib_header.version = wMajorVerNum | (wMinorVerNum << 16);
4426     return S_OK;
4427 }
4428
4429 /******************************************************************************
4430  * ICreateTypeLib2_SetGuid {OLEAUT32}
4431  *
4432  *  See ICreateTypeLib_SetGuid.
4433  */
4434 static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID guid)
4435 {
4436     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4437
4438     MSFT_GuidEntry guidentry;
4439     int offset;
4440
4441     TRACE("(%p,%s)\n", iface, debugstr_guid(guid));
4442
4443     guidentry.guid = *guid;
4444     guidentry.hreftype = -2;
4445     guidentry.next_hash = -1;
4446
4447     offset = ctl2_alloc_guid(This, &guidentry);
4448     
4449     if (offset == -1) return E_OUTOFMEMORY;
4450
4451     This->typelib_header.posguid = offset;
4452
4453     return S_OK;
4454 }
4455
4456 /******************************************************************************
4457  * ICreateTypeLib2_SetDocString {OLEAUT32}
4458  *
4459  *  See ICreateTypeLib_SetDocString.
4460  */
4461 static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LPOLESTR szDoc)
4462 {
4463     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4464
4465     int offset;
4466
4467     TRACE("(%p,%s)\n", iface, debugstr_w(szDoc));
4468     if (!szDoc)
4469         return E_INVALIDARG;
4470
4471     offset = ctl2_alloc_string(This, szDoc);
4472     if (offset == -1) return E_OUTOFMEMORY;
4473     This->typelib_header.helpstring = offset;
4474     return S_OK;
4475 }
4476
4477 /******************************************************************************
4478  * ICreateTypeLib2_SetHelpFileName {OLEAUT32}
4479  *
4480  *  See ICreateTypeLib_SetHelpFileName.
4481  */
4482 static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, LPOLESTR szHelpFileName)
4483 {
4484     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4485
4486     int offset;
4487
4488     TRACE("(%p,%s)\n", iface, debugstr_w(szHelpFileName));
4489
4490     offset = ctl2_alloc_string(This, szHelpFileName);
4491     if (offset == -1) return E_OUTOFMEMORY;
4492     This->typelib_header.helpfile = offset;
4493     This->typelib_header.varflags |= 0x10;
4494     return S_OK;
4495 }
4496
4497 /******************************************************************************
4498  * ICreateTypeLib2_SetHelpContext {OLEAUT32}
4499  *
4500  *  See ICreateTypeLib_SetHelpContext.
4501  */
4502 static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext)
4503 {
4504     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4505
4506     TRACE("(%p,%d)\n", iface, dwHelpContext);
4507     This->typelib_header.helpcontext = dwHelpContext;
4508     return S_OK;
4509 }
4510
4511 /******************************************************************************
4512  * ICreateTypeLib2_SetLcid {OLEAUT32}
4513  *
4514  * Sets both the lcid and lcid2 members in the header to lcid.
4515  *
4516  * As a special case if lcid == LOCALE_NEUTRAL (0), then the first header lcid
4517  * is set to US English while the second one is set to 0.
4518  */
4519 static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lcid)
4520 {
4521     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4522
4523     TRACE("(%p,%d)\n", iface, lcid);
4524
4525     This->typelib_header.lcid = This->typelib_header.lcid2 = lcid;
4526
4527     if(lcid == LOCALE_NEUTRAL) This->typelib_header.lcid = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
4528
4529     return S_OK;
4530 }
4531
4532 /******************************************************************************
4533  * ICreateTypeLib2_SetLibFlags {OLEAUT32}
4534  *
4535  *  See ICreateTypeLib_SetLibFlags.
4536  */
4537 static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 * iface, UINT uLibFlags)
4538 {
4539     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4540
4541     TRACE("(%p,0x%x)\n", iface, uLibFlags);
4542
4543     This->typelib_header.flags = uLibFlags;
4544
4545     return S_OK;
4546 }
4547
4548 static int ctl2_write_chunk(HANDLE hFile, const void *segment, int length)
4549 {
4550     DWORD dwWritten;
4551     if (!WriteFile(hFile, segment, length, &dwWritten, 0)) {
4552         CloseHandle(hFile);
4553         return 0;
4554     }
4555     return -1;
4556 }
4557
4558 static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segment)
4559 {
4560     DWORD dwWritten;
4561     if (!WriteFile(hFile, This->typelib_segment_data[segment],
4562                    This->typelib_segdir[segment].length, &dwWritten, 0)) {
4563         CloseHandle(hFile);
4564         return 0;
4565     }
4566
4567     return -1;
4568 }
4569
4570 static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
4571 {
4572     ICreateTypeInfo2Impl *typeinfo;
4573     HRESULT hres;
4574
4575     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
4576         typeinfo->typeinfo->memoffset = filesize;
4577
4578         hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
4579         if(FAILED(hres))
4580             return hres;
4581
4582         if (typeinfo->typedata)
4583             filesize += typeinfo->typedata->next->u.val
4584                 + ((typeinfo->typeinfo->cElement >> 16) * 12)
4585                 + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
4586     }
4587
4588     return S_OK;
4589 }
4590
4591 static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment)
4592 {
4593     if (This->typelib_segdir[segment].length) {
4594         This->typelib_segdir[segment].offset = filepos;
4595     } else {
4596         This->typelib_segdir[segment].offset = -1;
4597     }
4598
4599     return This->typelib_segdir[segment].length;
4600 }
4601
4602 static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile)
4603 {
4604     ICreateTypeInfo2Impl *typeinfo;
4605
4606     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
4607         CyclicList *iter;
4608         int offset = 0;
4609
4610         if (!typeinfo->typedata) continue;
4611
4612         iter = typeinfo->typedata->next;
4613         ctl2_write_chunk(hFile, &iter->u.val, sizeof(int));
4614         for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next)
4615             ctl2_write_chunk(hFile, iter->u.data, iter->u.data[0] & 0xffff);
4616
4617         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
4618             ctl2_write_chunk(hFile, &iter->indice, sizeof(int));
4619
4620         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
4621             ctl2_write_chunk(hFile, &iter->name, sizeof(int));
4622
4623         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) {
4624             ctl2_write_chunk(hFile, &offset, sizeof(int));
4625             offset += iter->u.data[0] & 0xffff;
4626         }
4627     }
4628 }
4629
4630 /******************************************************************************
4631  * ICreateTypeLib2_SaveAllChanges {OLEAUT32}
4632  *
4633  *  See ICreateTypeLib_SaveAllChanges.
4634  */
4635 static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
4636 {
4637     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4638
4639     int retval;
4640     int filepos;
4641     HANDLE hFile;
4642     HRESULT hres;
4643
4644     TRACE("(%p)\n", iface);
4645
4646     retval = TYPE_E_IOERROR;
4647
4648     hFile = CreateFileW(This->filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
4649     if (hFile == INVALID_HANDLE_VALUE) return retval;
4650
4651     filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir);
4652     filepos += This->typelib_header.nrtypeinfos * 4;
4653
4654     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO);
4655     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH);
4656     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID);
4657     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
4658     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO);
4659     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES);
4660     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH);
4661     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME);
4662     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING);
4663     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEDESC);
4664     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_ARRAYDESC);
4665     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA);
4666     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID);
4667
4668     hres = ctl2_finalize_typeinfos(This, filepos);
4669     if(FAILED(hres)) {
4670         CloseHandle(hFile);
4671         return hres;
4672     }
4673
4674     if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval;
4675     if (This->typelib_header.varflags & HELPDLLFLAG)
4676         if (!ctl2_write_chunk(hFile, &This->helpStringDll, sizeof(This->helpStringDll))) return retval;
4677     if (!ctl2_write_chunk(hFile, This->typelib_typeinfo_offsets, This->typelib_header.nrtypeinfos * 4)) return retval;
4678     if (!ctl2_write_chunk(hFile, This->typelib_segdir, sizeof(This->typelib_segdir))) return retval;
4679     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO    )) return retval;
4680     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH    )) return retval;
4681     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID        )) return retval;
4682     if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES  )) return retval;
4683     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO  )) return retval;
4684     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval;
4685     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH    )) return retval;
4686     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME        )) return retval;
4687     if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING      )) return retval;
4688     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEDESC    )) return retval;
4689     if (!ctl2_write_segment(This, hFile, MSFT_SEG_ARRAYDESC   )) return retval;
4690     if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATA    )) return retval;
4691     if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATAGUID)) return retval;
4692
4693     ctl2_write_typeinfos(This, hFile);
4694
4695     if (!CloseHandle(hFile)) return retval;
4696
4697     return S_OK;
4698 }
4699
4700
4701 /******************************************************************************
4702  * ICreateTypeLib2_DeleteTypeInfo {OLEAUT32}
4703  *
4704  *  Deletes a named TypeInfo from a type library.
4705  *
4706  * RETURNS
4707  *
4708  *  Success: S_OK
4709  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4710  */
4711 static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(
4712         ICreateTypeLib2 * iface, /* [I] The type library to delete from. */
4713         LPOLESTR szName)         /* [I] The name of the typeinfo to delete. */
4714 {
4715     FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
4716     return E_OUTOFMEMORY;
4717 }
4718
4719 /******************************************************************************
4720  * ICreateTypeLib2_SetCustData {OLEAUT32}
4721  *
4722  *  Sets custom data for a type library.
4723  *
4724  * RETURNS
4725  *
4726  *  Success: S_OK
4727  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4728  */
4729 static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(
4730         ICreateTypeLib2 * iface, /* [I] The type library to store the custom data in. */
4731         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
4732         VARIANT *pVarVal)        /* [I] The custom data itself. */
4733 {
4734     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4735
4736     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal);
4737
4738     return ctl2_set_custdata(This, guid, pVarVal, &This->typelib_header.CustomDataOffset);
4739 }
4740
4741 /******************************************************************************
4742  * ICreateTypeLib2_SetHelpStringContext {OLEAUT32}
4743  *
4744  *  Sets a context number for the library help string.
4745  *
4746  * PARAMS
4747  *  iface     [I] The type library to set the help string context for.
4748  *  dwContext [I] The help string context.
4749  *
4750  * RETURNS
4751  *  Success: S_OK
4752  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4753  */
4754 static
4755 HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 * iface,
4756                                                       ULONG dwContext)
4757 {
4758     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4759
4760     TRACE("(%p,%d)\n", iface, dwContext);
4761
4762     This->typelib_header.helpstringcontext = dwContext;
4763     return S_OK;
4764 }
4765
4766 /******************************************************************************
4767  * ICreateTypeLib2_SetHelpStringDll {OLEAUT32}
4768  *
4769  *  Set the DLL used to look up localized help strings.
4770  *
4771  * PARAMS
4772  *  iface     [I] The type library to set the help DLL for.
4773  *  szDllName [I] The name of the help DLL.
4774  *
4775  * RETURNS
4776  *  Success: S_OK
4777  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4778  */
4779 static
4780 HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 * iface,
4781                                                   LPOLESTR szDllName)
4782 {
4783     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4784     int offset;
4785
4786     TRACE("(%p,%s)\n", iface, debugstr_w(szDllName));
4787     if (!szDllName)
4788         return E_INVALIDARG;
4789
4790     offset = ctl2_alloc_string(This, szDllName);
4791     if (offset == -1)
4792         return E_OUTOFMEMORY;
4793     This->typelib_header.varflags |= HELPDLLFLAG;
4794     This->helpStringDll = offset;
4795     return S_OK;
4796 }
4797
4798 /*================== ITypeLib2 Implementation ===================================*/
4799
4800 /******************************************************************************
4801  * ITypeLib2_QueryInterface {OLEAUT32}
4802  *
4803  *  See IUnknown_QueryInterface.
4804  */
4805 static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 * iface, REFIID riid, LPVOID * ppv)
4806 {
4807     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4808
4809     return ICreateTypeLib2_QueryInterface((ICreateTypeLib2 *)This, riid, ppv);
4810 }
4811
4812 /******************************************************************************
4813  * ITypeLib2_AddRef {OLEAUT32}
4814  *
4815  *  See IUnknown_AddRef.
4816  */
4817 static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 * iface)
4818 {
4819     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4820
4821     return ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This);
4822 }
4823
4824 /******************************************************************************
4825  * ITypeLib2_Release {OLEAUT32}
4826  *
4827  *  See IUnknown_Release.
4828  */
4829 static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 * iface)
4830 {
4831     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4832
4833     return ICreateTypeLib2_Release((ICreateTypeLib2 *)This);
4834 }
4835
4836 /******************************************************************************
4837  * ITypeLib2_GetTypeInfoCount {OLEAUT32}
4838  *
4839  *  See ITypeLib_GetTypeInfoCount.
4840  */
4841 static UINT WINAPI ITypeLib2_fnGetTypeInfoCount(
4842         ITypeLib2 * iface)
4843 {
4844     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4845
4846     TRACE("(%p)\n", iface);
4847
4848     return This->typelib_header.nrtypeinfos;
4849 }
4850
4851 /******************************************************************************
4852  * ITypeLib2_GetTypeInfo {OLEAUT32}
4853  *
4854  *  See ITypeLib_GetTypeInfo.
4855  */
4856 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
4857         ITypeLib2 * iface,
4858         UINT index,
4859         ITypeInfo** ppTInfo)
4860 {
4861     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4862
4863     TRACE("(%p,%d,%p)\n", iface, index, ppTInfo);
4864
4865     if (index >= This->typelib_header.nrtypeinfos) {
4866         return TYPE_E_ELEMENTNOTFOUND;
4867     }
4868
4869     return ctl2_find_typeinfo_from_offset(This, This->typelib_typeinfo_offsets[index], ppTInfo);
4870 }
4871
4872 /******************************************************************************
4873  * ITypeLib2_GetTypeInfoType {OLEAUT32}
4874  *
4875  *  See ITypeLib_GetTypeInfoType.
4876  */
4877 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
4878         ITypeLib2 * iface,
4879         UINT index,
4880         TYPEKIND* pTKind)
4881 {
4882     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4883
4884     TRACE("(%p,%d,%p)\n", iface, index, pTKind);
4885
4886     if (index >= This->typelib_header.nrtypeinfos) {
4887         return TYPE_E_ELEMENTNOTFOUND;
4888     }
4889
4890     *pTKind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 15;
4891
4892     return S_OK;
4893 }
4894
4895 /******************************************************************************
4896  * ITypeLib2_GetTypeInfoOfGuid {OLEAUT32}
4897  *
4898  *  See ITypeLib_GetTypeInfoOfGuid.
4899  */
4900 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
4901         ITypeLib2 * iface,
4902         REFGUID guid,
4903         ITypeInfo** ppTinfo)
4904 {
4905     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4906
4907     int guidoffset;
4908     int typeinfo;
4909
4910     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), ppTinfo);
4911
4912     guidoffset = ctl2_find_guid(This, ctl2_hash_guid(guid), guid);
4913     if (guidoffset == -1) return TYPE_E_ELEMENTNOTFOUND;
4914
4915     typeinfo = ((MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][guidoffset])->hreftype;
4916     if (typeinfo < 0) return TYPE_E_ELEMENTNOTFOUND;
4917
4918     return ctl2_find_typeinfo_from_offset(This, typeinfo, ppTinfo);
4919 }
4920
4921 /******************************************************************************
4922  * ITypeLib2_GetLibAttr {OLEAUT32}
4923  *
4924  *  See ITypeLib_GetLibAttr.
4925  */
4926 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
4927         ITypeLib2 * iface,
4928         TLIBATTR** ppTLibAttr)
4929 {
4930     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4931
4932     TRACE("(%p,%p)\n", This, ppTLibAttr);
4933
4934     if(!ppTLibAttr)
4935         return E_INVALIDARG;
4936
4937     *ppTLibAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TLIBATTR));
4938     if(!*ppTLibAttr)
4939         return E_OUTOFMEMORY;
4940
4941     if(This->typelib_header.posguid != -1) {
4942         MSFT_GuidEntry *guid;
4943
4944         guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid];
4945         (*ppTLibAttr)->guid = guid->guid;
4946     }
4947
4948     (*ppTLibAttr)->lcid = This->typelib_header.lcid;
4949     (*ppTLibAttr)->syskind = This->typelib_header.varflags&0x3;
4950     (*ppTLibAttr)->wMajorVerNum = This->typelib_header.version&0xffff;
4951     (*ppTLibAttr)->wMinorVerNum = This->typelib_header.version>>16;
4952     (*ppTLibAttr)->wLibFlags = This->typelib_header.flags;
4953     return S_OK;
4954 }
4955
4956 /******************************************************************************
4957  * ITypeLib2_GetTypeComp {OLEAUT32}
4958  *
4959  *  See ITypeLib_GetTypeComp.
4960  */
4961 static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
4962         ITypeLib2 * iface,
4963         ITypeComp** ppTComp)
4964 {
4965     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4966
4967     FIXME("(%p,%p), stub!\n", This, ppTComp);
4968
4969     return E_OUTOFMEMORY;
4970 }
4971
4972 /******************************************************************************
4973  * ITypeLib2_GetDocumentation {OLEAUT32}
4974  *
4975  *  See ITypeLib_GetDocumentation.
4976  */
4977 static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
4978         ITypeLib2 * iface,
4979         INT index,
4980         BSTR* pBstrName,
4981         BSTR* pBstrDocString,
4982         DWORD* pdwHelpContext,
4983         BSTR* pBstrHelpFile)
4984 {
4985     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4986     WCHAR *string;
4987
4988     TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
4989
4990     if(index != -1) {
4991         ICreateTypeInfo2Impl *iter;
4992
4993         for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo)
4994             index--;
4995
4996         if(!iter)
4997             return TYPE_E_ELEMENTNOTFOUND;
4998
4999         return ITypeInfo_GetDocumentation((ITypeInfo*)&iter->lpVtblTypeInfo2,
5000                 -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
5001     }
5002
5003     if(pBstrName) {
5004         if(This->typelib_header.NameOffset == -1)
5005             *pBstrName = NULL;
5006         else {
5007             MSFT_NameIntro *name = (MSFT_NameIntro*)&This->
5008                 typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset];
5009
5010             ctl2_decode_name((char*)&name->namelen, &string);
5011
5012             *pBstrName = SysAllocString(string);
5013             if(!*pBstrName)
5014                 return E_OUTOFMEMORY;
5015         }
5016     }
5017
5018     if(pBstrDocString) {
5019         if(This->typelib_header.helpstring == -1)
5020             *pBstrDocString = NULL;
5021         else {
5022             ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string);
5023
5024             *pBstrDocString = SysAllocString(string);
5025             if(!*pBstrDocString) {
5026                 if(pBstrName) SysFreeString(*pBstrName);
5027                 return E_OUTOFMEMORY;
5028             }
5029         }
5030     }
5031
5032     if(pdwHelpContext)
5033         *pdwHelpContext = This->typelib_header.helpcontext;
5034
5035     if(pBstrHelpFile) {
5036         if(This->typelib_header.helpfile == -1)
5037             *pBstrHelpFile = NULL;
5038         else {
5039             ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string);
5040
5041             *pBstrHelpFile = SysAllocString(string);
5042             if(!*pBstrHelpFile) {
5043                 if(pBstrName) SysFreeString(*pBstrName);
5044                 if(pBstrDocString) SysFreeString(*pBstrDocString);
5045                 return E_OUTOFMEMORY;
5046             }
5047         }
5048     }
5049
5050     return S_OK;
5051 }
5052
5053 /******************************************************************************
5054  * ITypeLib2_IsName {OLEAUT32}
5055  *
5056  *  See ITypeLib_IsName.
5057  */
5058 static HRESULT WINAPI ITypeLib2_fnIsName(
5059         ITypeLib2 * iface,
5060         LPOLESTR szNameBuf,
5061         ULONG lHashVal,
5062         BOOL* pfName)
5063 {
5064     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
5065
5066     char *encoded_name;
5067     int nameoffset;
5068     MSFT_NameIntro *nameintro;
5069
5070     TRACE("(%p,%s,%x,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName);
5071
5072     ctl2_encode_name(This, szNameBuf, &encoded_name);
5073     nameoffset = ctl2_find_name(This, encoded_name);
5074
5075     *pfName = 0;
5076
5077     if (nameoffset == -1) return S_OK;
5078
5079     nameintro = (MSFT_NameIntro *)(&This->typelib_segment_data[MSFT_SEG_NAME][nameoffset]);
5080     if (nameintro->hreftype == -1) return S_OK;
5081
5082     *pfName = 1;
5083
5084     FIXME("Should be decoding our copy of the name over szNameBuf.\n");
5085
5086     return S_OK;
5087 }
5088
5089 /******************************************************************************
5090  * ITypeLib2_FindName {OLEAUT32}
5091  *
5092  *  See ITypeLib_FindName.
5093  */
5094 static HRESULT WINAPI ITypeLib2_fnFindName(
5095         ITypeLib2 * iface,
5096         LPOLESTR szNameBuf,
5097         ULONG lHashVal,
5098         ITypeInfo** ppTInfo,
5099         MEMBERID* rgMemId,
5100         USHORT* pcFound)
5101 {
5102     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
5103
5104     FIXME("(%p,%s,%x,%p,%p,%p), stub!\n", This, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound);
5105
5106     return E_OUTOFMEMORY;
5107 }
5108
5109 /******************************************************************************
5110  * ITypeLib2_ReleaseTLibAttr {OLEAUT32}
5111  *
5112  *  See ITypeLib_ReleaseTLibAttr.
5113  */
5114 static void WINAPI ITypeLib2_fnReleaseTLibAttr(
5115         ITypeLib2 * iface,
5116         TLIBATTR* pTLibAttr)
5117 {
5118     TRACE("(%p,%p)\n", iface, pTLibAttr);
5119
5120     HeapFree(GetProcessHeap(), 0, pTLibAttr);
5121 }
5122
5123 /******************************************************************************
5124  * ICreateTypeLib2_GetCustData {OLEAUT32}
5125  *
5126  *  Retrieves a custom data value stored on a type library.
5127  *
5128  * RETURNS
5129  *
5130  *  Success: S_OK
5131  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
5132  */
5133 static HRESULT WINAPI ITypeLib2_fnGetCustData(
5134         ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */
5135         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
5136         VARIANT* pVarVal)  /* [O] The custom data. */
5137 {
5138     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
5139
5140     FIXME("(%p,%s,%p), stub!\n", This, debugstr_guid(guid), pVarVal);
5141
5142     return E_OUTOFMEMORY;
5143 }
5144
5145 /******************************************************************************
5146  * ICreateTypeLib2_GetLibStatistics {OLEAUT32}
5147  *
5148  *  Retrieves some statistics about names in a type library, supposedly for
5149  *  hash table optimization purposes.
5150  *
5151  * RETURNS
5152  *
5153  *  Success: S_OK
5154  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
5155  */
5156 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
5157         ITypeLib2 * iface,      /* [I] The type library to get statistics about. */
5158         ULONG* pcUniqueNames,   /* [O] The number of unique names in the type library. */
5159         ULONG* pcchUniqueNames) /* [O] The number of changed (?) characters in names in the type library. */
5160 {
5161     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
5162
5163     FIXME("(%p,%p,%p), stub!\n", This, pcUniqueNames, pcchUniqueNames);
5164
5165     return E_OUTOFMEMORY;
5166 }
5167
5168 /******************************************************************************
5169  * ICreateTypeLib2_GetDocumentation2 {OLEAUT32}
5170  *
5171  *  Obtain locale-aware help string information.
5172  *
5173  * RETURNS
5174  *
5175  *  Success: S_OK
5176  *  Failure: STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
5177  */
5178 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
5179         ITypeLib2 * iface,
5180         INT index,
5181         LCID lcid,
5182         BSTR* pbstrHelpString,
5183         DWORD* pdwHelpStringContext,
5184         BSTR* pbstrHelpStringDll)
5185 {
5186     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
5187
5188     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", This, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
5189
5190     return E_OUTOFMEMORY;
5191 }
5192
5193 /******************************************************************************
5194  * ICreateTypeLib2_GetAllCustData {OLEAUT32}
5195  *
5196  *  Retrieve all of the custom data for a type library.
5197  *
5198  * RETURNS
5199  *
5200  *  Success: S_OK
5201  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
5202  */
5203 static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
5204         ITypeLib2 * iface,   /* [I] The type library in which to find the custom data. */
5205         CUSTDATA* pCustData) /* [O] The structure in which to place the custom data. */
5206 {
5207     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
5208
5209     FIXME("(%p,%p), stub!\n", This, pCustData);
5210
5211     return E_OUTOFMEMORY;
5212 }
5213
5214
5215 /*================== ICreateTypeLib2 & ITypeLib2 VTABLEs And Creation ===================================*/
5216
5217 static const ICreateTypeLib2Vtbl ctypelib2vt =
5218 {
5219
5220     ICreateTypeLib2_fnQueryInterface,
5221     ICreateTypeLib2_fnAddRef,
5222     ICreateTypeLib2_fnRelease,
5223
5224     ICreateTypeLib2_fnCreateTypeInfo,
5225     ICreateTypeLib2_fnSetName,
5226     ICreateTypeLib2_fnSetVersion,
5227     ICreateTypeLib2_fnSetGuid,
5228     ICreateTypeLib2_fnSetDocString,
5229     ICreateTypeLib2_fnSetHelpFileName,
5230     ICreateTypeLib2_fnSetHelpContext,
5231     ICreateTypeLib2_fnSetLcid,
5232     ICreateTypeLib2_fnSetLibFlags,
5233     ICreateTypeLib2_fnSaveAllChanges,
5234
5235     ICreateTypeLib2_fnDeleteTypeInfo,
5236     ICreateTypeLib2_fnSetCustData,
5237     ICreateTypeLib2_fnSetHelpStringContext,
5238     ICreateTypeLib2_fnSetHelpStringDll
5239 };
5240
5241 static const ITypeLib2Vtbl typelib2vt =
5242 {
5243
5244     ITypeLib2_fnQueryInterface,
5245     ITypeLib2_fnAddRef,
5246     ITypeLib2_fnRelease,
5247
5248     ITypeLib2_fnGetTypeInfoCount,
5249     ITypeLib2_fnGetTypeInfo,
5250     ITypeLib2_fnGetTypeInfoType,
5251     ITypeLib2_fnGetTypeInfoOfGuid,
5252     ITypeLib2_fnGetLibAttr,
5253     ITypeLib2_fnGetTypeComp,
5254     ITypeLib2_fnGetDocumentation,
5255     ITypeLib2_fnIsName,
5256     ITypeLib2_fnFindName,
5257     ITypeLib2_fnReleaseTLibAttr,
5258
5259     ITypeLib2_fnGetCustData,
5260     ITypeLib2_fnGetLibStatistics,
5261     ITypeLib2_fnGetDocumentation2,
5262     ITypeLib2_fnGetAllCustData,
5263 };
5264
5265 static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR szFile)
5266 {
5267     ICreateTypeLib2Impl *pCreateTypeLib2Impl;
5268     int failed = 0;
5269
5270     TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(szFile));
5271
5272     pCreateTypeLib2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeLib2Impl));
5273     if (!pCreateTypeLib2Impl) return NULL;
5274
5275     pCreateTypeLib2Impl->filename = HeapAlloc(GetProcessHeap(), 0, (strlenW(szFile) + 1) * sizeof(WCHAR));
5276     if (!pCreateTypeLib2Impl->filename) {
5277         HeapFree(GetProcessHeap(), 0, pCreateTypeLib2Impl);
5278         return NULL;
5279     }
5280     strcpyW(pCreateTypeLib2Impl->filename, szFile);
5281
5282     ctl2_init_header(pCreateTypeLib2Impl);
5283     ctl2_init_segdir(pCreateTypeLib2Impl);
5284
5285     pCreateTypeLib2Impl->typelib_header.varflags |= syskind;
5286
5287     /*
5288      * The following two calls return an offset or -1 if out of memory. We
5289      * specifically need an offset of 0, however, so...
5290      */
5291     if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; }
5292     if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; }
5293
5294     pCreateTypeLib2Impl->typelib_guidhash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_GUIDHASH];
5295     pCreateTypeLib2Impl->typelib_namehash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_NAMEHASH];
5296
5297     memset(pCreateTypeLib2Impl->typelib_guidhash_segment, 0xff, 0x80);
5298     memset(pCreateTypeLib2Impl->typelib_namehash_segment, 0xff, 0x200);
5299
5300     pCreateTypeLib2Impl->lpVtbl = &ctypelib2vt;
5301     pCreateTypeLib2Impl->lpVtblTypeLib2 = &typelib2vt;
5302     pCreateTypeLib2Impl->ref = 1;
5303
5304     if (failed) {
5305         ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)pCreateTypeLib2Impl);
5306         return 0;
5307     }
5308
5309     return (ICreateTypeLib2 *)pCreateTypeLib2Impl;
5310 }
5311
5312 /******************************************************************************
5313  * CreateTypeLib2 [OLEAUT32.180]
5314  *
5315  *  Obtains an ICreateTypeLib2 object for creating a new-style (MSFT) type
5316  *  library.
5317  *
5318  * NOTES
5319  *
5320  *  See also CreateTypeLib.
5321  *
5322  * RETURNS
5323  *    Success: S_OK
5324  *    Failure: Status
5325  */
5326 HRESULT WINAPI CreateTypeLib2(
5327         SYSKIND syskind,           /* [I] System type library is for */
5328         LPCOLESTR szFile,          /* [I] Type library file name */
5329         ICreateTypeLib2** ppctlib) /* [O] Storage for object returned */
5330 {
5331     TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib);
5332
5333     if (!szFile) return E_INVALIDARG;
5334     *ppctlib = ICreateTypeLib2_Constructor(syskind, szFile);
5335     return (*ppctlib)? S_OK: E_OUTOFMEMORY;
5336 }
5337
5338 /******************************************************************************
5339  * ClearCustData (OLEAUT32.171)
5340  *
5341  * Clear a custom data types' data.
5342  *
5343  * PARAMS
5344  *  lpCust [I] The custom data type instance
5345  *
5346  * RETURNS
5347  *  Nothing.
5348  */
5349 void WINAPI ClearCustData(LPCUSTDATA lpCust)
5350 {
5351     if (lpCust && lpCust->cCustData)
5352     {
5353         if (lpCust->prgCustData)
5354         {
5355             DWORD i;
5356
5357             for (i = 0; i < lpCust->cCustData; i++)
5358                 VariantClear(&lpCust->prgCustData[i].varValue);
5359
5360             /* FIXME - Should be using a per-thread IMalloc */
5361             HeapFree(GetProcessHeap(), 0, lpCust->prgCustData);
5362             lpCust->prgCustData = NULL;
5363         }
5364         lpCust->cCustData = 0;
5365     }
5366 }