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