oleaut32: Update TypeInfo flags when object inherits IDispatch.
[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     if(pTypeAttr)
3145         HeapFree(GetProcessHeap(), 0, pTypeAttr);
3146 }
3147
3148 /******************************************************************************
3149  * ITypeInfo2_ReleaseFuncDesc {OLEAUT32}
3150  *
3151  *  See ITypeInfo_ReleaseFuncDesc.
3152  */
3153 static void WINAPI ITypeInfo2_fnReleaseFuncDesc(
3154         ITypeInfo2* iface,
3155         FUNCDESC* pFuncDesc)
3156 {
3157     FIXME("(%p,%p), stub!\n", iface, pFuncDesc);
3158 }
3159
3160 /******************************************************************************
3161  * ITypeInfo2_ReleaseVarDesc {OLEAUT32}
3162  *
3163  *  See ITypeInfo_ReleaseVarDesc.
3164  */
3165 static void WINAPI ITypeInfo2_fnReleaseVarDesc(
3166         ITypeInfo2* iface,
3167         VARDESC* pVarDesc)
3168 {
3169     FIXME("(%p,%p), stub!\n", iface, pVarDesc);
3170 }
3171
3172 /******************************************************************************
3173  * ITypeInfo2_GetTypeKind {OLEAUT32}
3174  *
3175  *  Get the TYPEKIND value for a TypeInfo.
3176  *
3177  * RETURNS
3178  *
3179  *  Success: S_OK.
3180  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3181  */
3182 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind(
3183         ITypeInfo2* iface,   /* [I] The TypeInfo to obtain the typekind for. */
3184         TYPEKIND* pTypeKind) /* [O] The typekind for this TypeInfo. */
3185 {
3186     FIXME("(%p,%p), stub!\n", iface, pTypeKind);
3187     return E_OUTOFMEMORY;
3188 }
3189
3190 /******************************************************************************
3191  * ITypeInfo2_GetTypeFlags {OLEAUT32}
3192  *
3193  *  Get the Type Flags for a TypeInfo.
3194  *
3195  * RETURNS
3196  *
3197  *  Success: S_OK.
3198  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3199  */
3200 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags(
3201         ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typeflags for. */
3202         ULONG* pTypeFlags) /* [O] The type flags for this TypeInfo. */
3203 {
3204     FIXME("(%p,%p), stub!\n", iface, pTypeFlags);
3205     return E_OUTOFMEMORY;
3206 }
3207
3208 /******************************************************************************
3209  * ITypeInfo2_GetFuncIndexOfMemId {OLEAUT32}
3210  *
3211  *  Gets the index of a function given its member id.
3212  *
3213  * RETURNS
3214  *
3215  *  Success: S_OK.
3216  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3217  */
3218 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId(
3219         ITypeInfo2* iface,  /* [I] The TypeInfo in which to find the function. */
3220         MEMBERID memid,     /* [I] The member id for the function. */
3221         INVOKEKIND invKind, /* [I] The invocation kind for the function. */
3222         UINT* pFuncIndex)   /* [O] The index of the function. */
3223 {
3224     FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex);
3225     return E_OUTOFMEMORY;
3226 }
3227
3228 /******************************************************************************
3229  * ITypeInfo2_GetVarIndexOfMemId {OLEAUT32}
3230  *
3231  *  Gets the index of a variable given its member id.
3232  *
3233  * RETURNS
3234  *
3235  *  Success: S_OK.
3236  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3237  */
3238 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId(
3239         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the variable. */
3240         MEMBERID memid,    /* [I] The member id for the variable. */
3241         UINT* pVarIndex)   /* [O] The index of the variable. */
3242 {
3243     FIXME("(%p,%d,%p), stub!\n", iface, memid, pVarIndex);
3244     return E_OUTOFMEMORY;
3245 }
3246
3247 /******************************************************************************
3248  * ITypeInfo2_GetCustData {OLEAUT32}
3249  *
3250  *  Gets a custom data element from a TypeInfo.
3251  *
3252  * RETURNS
3253  *
3254  *  Success: S_OK.
3255  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3256  */
3257 static HRESULT WINAPI ITypeInfo2_fnGetCustData(
3258         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3259         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3260         VARIANT* pVarVal)  /* [O] The custom data. */
3261 {
3262     FIXME("(%p,%s,%p), stub!\n", iface, debugstr_guid(guid), pVarVal);
3263     return E_OUTOFMEMORY;
3264 }
3265
3266 /******************************************************************************
3267  * ITypeInfo2_GetFuncCustData {OLEAUT32}
3268  *
3269  *  Gets a custom data element from a function.
3270  *
3271  * RETURNS
3272  *
3273  *  Success: S_OK.
3274  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3275  */
3276 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
3277         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3278         UINT index,        /* [I] The index of the function for which to retrieve the custom data. */
3279         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3280         VARIANT* pVarVal)  /* [O] The custom data. */
3281 {
3282     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3283     return E_OUTOFMEMORY;
3284 }
3285
3286 /******************************************************************************
3287  * ITypeInfo2_GetParamCustData {OLEAUT32}
3288  *
3289  *  Gets a custom data element from a parameter.
3290  *
3291  * RETURNS
3292  *
3293  *  Success: S_OK.
3294  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3295  */
3296 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
3297         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3298         UINT indexFunc,    /* [I] The index of the function for which to retrieve the custom data. */
3299         UINT indexParam,   /* [I] The index of the parameter for which to retrieve the custom data. */
3300         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3301         VARIANT* pVarVal)  /* [O] The custom data. */
3302 {
3303     FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
3304     return E_OUTOFMEMORY;
3305 }
3306
3307 /******************************************************************************
3308  * ITypeInfo2_GetVarCustData {OLEAUT32}
3309  *
3310  *  Gets a custom data element from a variable.
3311  *
3312  * RETURNS
3313  *
3314  *  Success: S_OK.
3315  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3316  */
3317 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
3318         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3319         UINT index,        /* [I] The index of the variable for which to retrieve the custom data. */
3320         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3321         VARIANT* pVarVal)  /* [O] The custom data. */
3322 {
3323     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3324     return E_OUTOFMEMORY;
3325 }
3326
3327 /******************************************************************************
3328  * ITypeInfo2_GetImplTypeCustData {OLEAUT32}
3329  *
3330  *  Gets a custom data element from an implemented type of a TypeInfo.
3331  *
3332  * RETURNS
3333  *
3334  *  Success: S_OK.
3335  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3336  */
3337 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
3338         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3339         UINT index,        /* [I] The index of the implemented type for which to retrieve the custom data. */
3340         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3341         VARIANT* pVarVal)  /* [O] The custom data. */
3342 {
3343     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3344     return E_OUTOFMEMORY;
3345 }
3346
3347 /******************************************************************************
3348  * ITypeInfo2_GetDocumentation2 {OLEAUT32}
3349  *
3350  *  Gets some documentation from a TypeInfo in a locale-aware fashion.
3351  *
3352  * RETURNS
3353  *
3354  *  Success: S_OK.
3355  *  Failure: One of STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
3356  */
3357 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
3358         ITypeInfo2* iface,           /* [I] The TypeInfo to retrieve the documentation from. */
3359         MEMBERID memid,              /* [I] The member id (why?). */
3360         LCID lcid,                   /* [I] The locale (why?). */
3361         BSTR* pbstrHelpString,       /* [O] The help string. */
3362         DWORD* pdwHelpStringContext, /* [O] The help string context. */
3363         BSTR* pbstrHelpStringDll)    /* [O] The help file name. */
3364 {
3365     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
3366     return E_OUTOFMEMORY;
3367 }
3368
3369 /******************************************************************************
3370  * ITypeInfo2_GetAllCustData {OLEAUT32}
3371  *
3372  *  Gets all of the custom data associated with a TypeInfo.
3373  *
3374  * RETURNS
3375  *
3376  *  Success: S_OK.
3377  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3378  */
3379 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
3380         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3381         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3382 {
3383     FIXME("(%p,%p), stub!\n", iface, pCustData);
3384     return E_OUTOFMEMORY;
3385 }
3386
3387 /******************************************************************************
3388  * ITypeInfo2_GetAllFuncCustData {OLEAUT32}
3389  *
3390  *  Gets all of the custom data associated with a function.
3391  *
3392  * RETURNS
3393  *
3394  *  Success: S_OK.
3395  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3396  */
3397 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
3398         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3399         UINT index,          /* [I] The index of the function for which to retrieve the custom data. */
3400         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3401 {
3402     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
3403     return E_OUTOFMEMORY;
3404 }
3405
3406 /******************************************************************************
3407  * ITypeInfo2_GetAllParamCustData {OLEAUT32}
3408  *
3409  *  Gets all of the custom data associated with a parameter.
3410  *
3411  * RETURNS
3412  *
3413  *  Success: S_OK.
3414  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3415  */
3416 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData(
3417         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3418         UINT indexFunc,      /* [I] The index of the function for which to retrieve the custom data. */
3419         UINT indexParam,     /* [I] The index of the parameter for which to retrieve the custom data. */
3420         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3421 {
3422     FIXME("(%p,%d,%d,%p), stub!\n", iface, indexFunc, indexParam, pCustData);
3423     return E_OUTOFMEMORY;
3424 }
3425
3426 /******************************************************************************
3427  * ITypeInfo2_GetAllVarCustData {OLEAUT32}
3428  *
3429  *  Gets all of the custom data associated with a variable.
3430  *
3431  * RETURNS
3432  *
3433  *  Success: S_OK.
3434  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3435  */
3436 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData(
3437         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3438         UINT index,          /* [I] The index of the variable for which to retrieve the custom data. */
3439         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3440 {
3441     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
3442     return E_OUTOFMEMORY;
3443 }
3444
3445 /******************************************************************************
3446  * ITypeInfo2_GetAllImplTypeCustData {OLEAUT32}
3447  *
3448  *  Gets all of the custom data associated with an implemented type.
3449  *
3450  * RETURNS
3451  *
3452  *  Success: S_OK.
3453  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3454  */
3455 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
3456         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3457         UINT index,          /* [I] The index of the implemented type for which to retrieve the custom data. */
3458         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3459 {
3460     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
3461     return E_OUTOFMEMORY;
3462 }
3463
3464
3465 /*================== ICreateTypeInfo2 & ITypeInfo2 VTABLEs And Creation ===================================*/
3466
3467 static const ICreateTypeInfo2Vtbl ctypeinfo2vt =
3468 {
3469
3470     ICreateTypeInfo2_fnQueryInterface,
3471     ICreateTypeInfo2_fnAddRef,
3472     ICreateTypeInfo2_fnRelease,
3473
3474     ICreateTypeInfo2_fnSetGuid,
3475     ICreateTypeInfo2_fnSetTypeFlags,
3476     ICreateTypeInfo2_fnSetDocString,
3477     ICreateTypeInfo2_fnSetHelpContext,
3478     ICreateTypeInfo2_fnSetVersion,
3479     ICreateTypeInfo2_fnAddRefTypeInfo,
3480     ICreateTypeInfo2_fnAddFuncDesc,
3481     ICreateTypeInfo2_fnAddImplType,
3482     ICreateTypeInfo2_fnSetImplTypeFlags,
3483     ICreateTypeInfo2_fnSetAlignment,
3484     ICreateTypeInfo2_fnSetSchema,
3485     ICreateTypeInfo2_fnAddVarDesc,
3486     ICreateTypeInfo2_fnSetFuncAndParamNames,
3487     ICreateTypeInfo2_fnSetVarName,
3488     ICreateTypeInfo2_fnSetTypeDescAlias,
3489     ICreateTypeInfo2_fnDefineFuncAsDllEntry,
3490     ICreateTypeInfo2_fnSetFuncDocString,
3491     ICreateTypeInfo2_fnSetVarDocString,
3492     ICreateTypeInfo2_fnSetFuncHelpContext,
3493     ICreateTypeInfo2_fnSetVarHelpContext,
3494     ICreateTypeInfo2_fnSetMops,
3495     ICreateTypeInfo2_fnSetTypeIdldesc,
3496     ICreateTypeInfo2_fnLayOut,
3497
3498     ICreateTypeInfo2_fnDeleteFuncDesc,
3499     ICreateTypeInfo2_fnDeleteFuncDescByMemId,
3500     ICreateTypeInfo2_fnDeleteVarDesc,
3501     ICreateTypeInfo2_fnDeleteVarDescByMemId,
3502     ICreateTypeInfo2_fnDeleteImplType,
3503     ICreateTypeInfo2_fnSetCustData,
3504     ICreateTypeInfo2_fnSetFuncCustData,
3505     ICreateTypeInfo2_fnSetParamCustData,
3506     ICreateTypeInfo2_fnSetVarCustData,
3507     ICreateTypeInfo2_fnSetImplTypeCustData,
3508     ICreateTypeInfo2_fnSetHelpStringContext,
3509     ICreateTypeInfo2_fnSetFuncHelpStringContext,
3510     ICreateTypeInfo2_fnSetVarHelpStringContext,
3511     ICreateTypeInfo2_fnInvalidate,
3512     ICreateTypeInfo2_fnSetName
3513 };
3514
3515 static const ITypeInfo2Vtbl typeinfo2vt =
3516 {
3517
3518     ITypeInfo2_fnQueryInterface,
3519     ITypeInfo2_fnAddRef,
3520     ITypeInfo2_fnRelease,
3521
3522     ITypeInfo2_fnGetTypeAttr,
3523     ITypeInfo2_fnGetTypeComp,
3524     ITypeInfo2_fnGetFuncDesc,
3525     ITypeInfo2_fnGetVarDesc,
3526     ITypeInfo2_fnGetNames,
3527     ITypeInfo2_fnGetRefTypeOfImplType,
3528     ITypeInfo2_fnGetImplTypeFlags,
3529     ITypeInfo2_fnGetIDsOfNames,
3530     ITypeInfo2_fnInvoke,
3531     ITypeInfo2_fnGetDocumentation,
3532     ITypeInfo2_fnGetDllEntry,
3533     ITypeInfo2_fnGetRefTypeInfo,
3534     ITypeInfo2_fnAddressOfMember,
3535     ITypeInfo2_fnCreateInstance,
3536     ITypeInfo2_fnGetMops,
3537     ITypeInfo2_fnGetContainingTypeLib,
3538     ITypeInfo2_fnReleaseTypeAttr,
3539     ITypeInfo2_fnReleaseFuncDesc,
3540     ITypeInfo2_fnReleaseVarDesc,
3541
3542     ITypeInfo2_fnGetTypeKind,
3543     ITypeInfo2_fnGetTypeFlags,
3544     ITypeInfo2_fnGetFuncIndexOfMemId,
3545     ITypeInfo2_fnGetVarIndexOfMemId,
3546     ITypeInfo2_fnGetCustData,
3547     ITypeInfo2_fnGetFuncCustData,
3548     ITypeInfo2_fnGetParamCustData,
3549     ITypeInfo2_fnGetVarCustData,
3550     ITypeInfo2_fnGetImplTypeCustData,
3551     ITypeInfo2_fnGetDocumentation2,
3552     ITypeInfo2_fnGetAllCustData,
3553     ITypeInfo2_fnGetAllFuncCustData,
3554     ITypeInfo2_fnGetAllParamCustData,
3555     ITypeInfo2_fnGetAllVarCustData,
3556     ITypeInfo2_fnGetAllImplTypeCustData,
3557 };
3558
3559 static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typelib, WCHAR *szName, TYPEKIND tkind)
3560 {
3561     ICreateTypeInfo2Impl *pCreateTypeInfo2Impl;
3562
3563     int nameoffset;
3564     int typeinfo_offset;
3565     MSFT_TypeInfoBase *typeinfo;
3566
3567     TRACE("Constructing ICreateTypeInfo2 for %s with tkind %d\n", debugstr_w(szName), tkind);
3568
3569     pCreateTypeInfo2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeInfo2Impl));
3570     if (!pCreateTypeInfo2Impl) return NULL;
3571
3572     pCreateTypeInfo2Impl->lpVtbl = &ctypeinfo2vt;
3573     pCreateTypeInfo2Impl->lpVtblTypeInfo2 = &typeinfo2vt;
3574     pCreateTypeInfo2Impl->ref = 1;
3575
3576     pCreateTypeInfo2Impl->typelib = typelib;
3577     typelib->ref++;
3578
3579     nameoffset = ctl2_alloc_name(typelib, szName);
3580     typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset);
3581     typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset];
3582
3583     typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38;
3584     *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset;
3585
3586     pCreateTypeInfo2Impl->typeinfo = typeinfo;
3587
3588     typeinfo->typekind |= tkind | 0x20;
3589     ICreateTypeInfo2_SetAlignment((ICreateTypeInfo2 *)pCreateTypeInfo2Impl, 4);
3590
3591     switch (tkind) {
3592     case TKIND_ENUM:
3593     case TKIND_INTERFACE:
3594     case TKIND_DISPATCH:
3595     case TKIND_COCLASS:
3596         typeinfo->size = 4;
3597         break;
3598
3599     case TKIND_RECORD:
3600     case TKIND_UNION:
3601         typeinfo->size = 0;
3602         break;
3603
3604     case TKIND_MODULE:
3605         typeinfo->size = 2;
3606         break;
3607
3608     case TKIND_ALIAS:
3609         typeinfo->size = -0x75;
3610         break;
3611
3612     default:
3613         FIXME("(%s,%d), unrecognized typekind %d\n", debugstr_w(szName), tkind, tkind);
3614         typeinfo->size = 0xdeadbeef;
3615         break;
3616     }
3617
3618     if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = pCreateTypeInfo2Impl;
3619     typelib->last_typeinfo = pCreateTypeInfo2Impl;
3620     if (!typelib->typeinfos) typelib->typeinfos = pCreateTypeInfo2Impl;
3621
3622     TRACE(" -- %p\n", pCreateTypeInfo2Impl);
3623
3624     return (ICreateTypeInfo2 *)pCreateTypeInfo2Impl;
3625 }
3626
3627
3628 /*================== ICreateTypeLib2 Implementation ===================================*/
3629
3630 /******************************************************************************
3631  * ICreateTypeLib2_QueryInterface {OLEAUT32}
3632  *
3633  *  See IUnknown_QueryInterface.
3634  */
3635 static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(
3636         ICreateTypeLib2 * iface,
3637         REFIID riid,
3638         VOID **ppvObject)
3639 {
3640     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3641
3642     TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
3643
3644     *ppvObject=NULL;
3645     if(IsEqualIID(riid, &IID_IUnknown) ||
3646        IsEqualIID(riid,&IID_ICreateTypeLib)||
3647        IsEqualIID(riid,&IID_ICreateTypeLib2))
3648     {
3649         *ppvObject = This;
3650     } else if (IsEqualIID(riid, &IID_ITypeLib) ||
3651                IsEqualIID(riid, &IID_ITypeLib2)) {
3652         *ppvObject = &This->lpVtblTypeLib2;
3653     }
3654
3655     if(*ppvObject)
3656     {
3657         ICreateTypeLib2_AddRef(iface);
3658         TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
3659         return S_OK;
3660     }
3661     TRACE("-- Interface: E_NOINTERFACE\n");
3662     return E_NOINTERFACE;
3663 }
3664
3665 /******************************************************************************
3666  * ICreateTypeLib2_AddRef {OLEAUT32}
3667  *
3668  *  See IUnknown_AddRef.
3669  */
3670 static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
3671 {
3672     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3673     ULONG ref = InterlockedIncrement(&This->ref);
3674
3675     TRACE("(%p)->ref was %u\n",This, ref - 1);
3676
3677     return ref;
3678 }
3679
3680 /******************************************************************************
3681  * ICreateTypeLib2_Release {OLEAUT32}
3682  *
3683  *  See IUnknown_Release.
3684  */
3685 static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
3686 {
3687     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3688     ULONG ref = InterlockedDecrement(&This->ref);
3689
3690     TRACE("(%p)->(%u)\n",This, ref);
3691
3692     if (!ref) {
3693         int i;
3694
3695         for (i = 0; i < MSFT_SEG_MAX; i++) {
3696             HeapFree(GetProcessHeap(), 0, This->typelib_segment_data[i]);
3697             This->typelib_segment_data[i] = NULL;
3698         }
3699
3700         HeapFree(GetProcessHeap(), 0, This->filename);
3701         This->filename = NULL;
3702
3703         while (This->typeinfos) {
3704             ICreateTypeInfo2Impl *typeinfo = This->typeinfos;
3705             This->typeinfos = typeinfo->next_typeinfo;
3706             if(typeinfo->typedata) {
3707                 CyclicList *iter, *rem;
3708
3709                 rem = typeinfo->typedata->next;
3710                 typeinfo->typedata->next = NULL;
3711                 iter = rem->next;
3712                 HeapFree(GetProcessHeap(), 0, rem);
3713
3714                 while(iter) {
3715                     rem = iter;
3716                     iter = iter->next;
3717                     HeapFree(GetProcessHeap(), 0, rem->u.data);
3718                     HeapFree(GetProcessHeap(), 0, rem);
3719                 }
3720             }
3721             HeapFree(GetProcessHeap(), 0, typeinfo);
3722         }
3723
3724         HeapFree(GetProcessHeap(),0,This);
3725         return 0;
3726     }
3727
3728     return ref;
3729 }
3730
3731
3732 /******************************************************************************
3733  * ICreateTypeLib2_CreateTypeInfo {OLEAUT32}
3734  *
3735  *  See ICreateTypeLib_CreateTypeInfo.
3736  */
3737 static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(
3738         ICreateTypeLib2 * iface,
3739         LPOLESTR szName,
3740         TYPEKIND tkind,
3741         ICreateTypeInfo **ppCTInfo)
3742 {
3743     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3744     char *name;
3745
3746     TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo);
3747
3748     ctl2_encode_name(This, szName, &name);
3749     if(ctl2_find_name(This, name) != -1)
3750         return TYPE_E_NAMECONFLICT;
3751
3752     *ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind);
3753
3754     if (!*ppCTInfo) return E_OUTOFMEMORY;
3755
3756     return S_OK;
3757 }
3758
3759 /******************************************************************************
3760  * ICreateTypeLib2_SetName {OLEAUT32}
3761  *
3762  *  See ICreateTypeLib_SetName.
3763  */
3764 static HRESULT WINAPI ICreateTypeLib2_fnSetName(
3765         ICreateTypeLib2 * iface,
3766         LPOLESTR szName)
3767 {
3768     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3769
3770     int offset;
3771
3772     TRACE("(%p,%s)\n", iface, debugstr_w(szName));
3773
3774     offset = ctl2_alloc_name(This, szName);
3775     if (offset == -1) return E_OUTOFMEMORY;
3776     This->typelib_header.NameOffset = offset;
3777     return S_OK;
3778 }
3779
3780 /******************************************************************************
3781  * ICreateTypeLib2_SetVersion {OLEAUT32}
3782  *
3783  *  See ICreateTypeLib_SetVersion.
3784  */
3785 static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD wMajorVerNum, WORD wMinorVerNum)
3786 {
3787     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3788
3789     TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);
3790
3791     This->typelib_header.version = wMajorVerNum | (wMinorVerNum << 16);
3792     return S_OK;
3793 }
3794
3795 /******************************************************************************
3796  * ICreateTypeLib2_SetGuid {OLEAUT32}
3797  *
3798  *  See ICreateTypeLib_SetGuid.
3799  */
3800 static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID guid)
3801 {
3802     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3803
3804     MSFT_GuidEntry guidentry;
3805     int offset;
3806
3807     TRACE("(%p,%s)\n", iface, debugstr_guid(guid));
3808
3809     guidentry.guid = *guid;
3810     guidentry.hreftype = -2;
3811     guidentry.next_hash = -1;
3812
3813     offset = ctl2_alloc_guid(This, &guidentry);
3814     
3815     if (offset == -1) return E_OUTOFMEMORY;
3816
3817     This->typelib_header.posguid = offset;
3818
3819     return S_OK;
3820 }
3821
3822 /******************************************************************************
3823  * ICreateTypeLib2_SetDocString {OLEAUT32}
3824  *
3825  *  See ICreateTypeLib_SetDocString.
3826  */
3827 static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LPOLESTR szDoc)
3828 {
3829     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3830
3831     int offset;
3832
3833     TRACE("(%p,%s)\n", iface, debugstr_w(szDoc));
3834     if (!szDoc)
3835         return E_INVALIDARG;
3836
3837     offset = ctl2_alloc_string(This, szDoc);
3838     if (offset == -1) return E_OUTOFMEMORY;
3839     This->typelib_header.helpstring = offset;
3840     return S_OK;
3841 }
3842
3843 /******************************************************************************
3844  * ICreateTypeLib2_SetHelpFileName {OLEAUT32}
3845  *
3846  *  See ICreateTypeLib_SetHelpFileName.
3847  */
3848 static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, LPOLESTR szHelpFileName)
3849 {
3850     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3851
3852     int offset;
3853
3854     TRACE("(%p,%s)\n", iface, debugstr_w(szHelpFileName));
3855
3856     offset = ctl2_alloc_string(This, szHelpFileName);
3857     if (offset == -1) return E_OUTOFMEMORY;
3858     This->typelib_header.helpfile = offset;
3859     This->typelib_header.varflags |= 0x10;
3860     return S_OK;
3861 }
3862
3863 /******************************************************************************
3864  * ICreateTypeLib2_SetHelpContext {OLEAUT32}
3865  *
3866  *  See ICreateTypeLib_SetHelpContext.
3867  */
3868 static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext)
3869 {
3870     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3871
3872     TRACE("(%p,%d)\n", iface, dwHelpContext);
3873     This->typelib_header.helpcontext = dwHelpContext;
3874     return S_OK;
3875 }
3876
3877 /******************************************************************************
3878  * ICreateTypeLib2_SetLcid {OLEAUT32}
3879  *
3880  * Sets both the lcid and lcid2 members in the header to lcid.
3881  *
3882  * As a special case if lcid == LOCALE_NEUTRAL (0), then the first header lcid
3883  * is set to US English while the second one is set to 0.
3884  */
3885 static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lcid)
3886 {
3887     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3888
3889     TRACE("(%p,%d)\n", iface, lcid);
3890
3891     This->typelib_header.lcid = This->typelib_header.lcid2 = lcid;
3892
3893     if(lcid == LOCALE_NEUTRAL) This->typelib_header.lcid = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
3894
3895     return S_OK;
3896 }
3897
3898 /******************************************************************************
3899  * ICreateTypeLib2_SetLibFlags {OLEAUT32}
3900  *
3901  *  See ICreateTypeLib_SetLibFlags.
3902  */
3903 static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 * iface, UINT uLibFlags)
3904 {
3905     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3906
3907     TRACE("(%p,0x%x)\n", iface, uLibFlags);
3908
3909     This->typelib_header.flags = uLibFlags;
3910
3911     return S_OK;
3912 }
3913
3914 static int ctl2_write_chunk(HANDLE hFile, const void *segment, int length)
3915 {
3916     DWORD dwWritten;
3917     if (!WriteFile(hFile, segment, length, &dwWritten, 0)) {
3918         CloseHandle(hFile);
3919         return 0;
3920     }
3921     return -1;
3922 }
3923
3924 static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segment)
3925 {
3926     DWORD dwWritten;
3927     if (!WriteFile(hFile, This->typelib_segment_data[segment],
3928                    This->typelib_segdir[segment].length, &dwWritten, 0)) {
3929         CloseHandle(hFile);
3930         return 0;
3931     }
3932
3933     return -1;
3934 }
3935
3936 static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
3937 {
3938     ICreateTypeInfo2Impl *typeinfo;
3939     HRESULT hres;
3940
3941     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
3942         typeinfo->typeinfo->memoffset = filesize;
3943
3944         hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
3945         if(FAILED(hres))
3946             return hres;
3947
3948         if (typeinfo->typedata)
3949             filesize += typeinfo->typedata->next->u.val
3950                 + ((typeinfo->typeinfo->cElement >> 16) * 12)
3951                 + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
3952     }
3953
3954     return S_OK;
3955 }
3956
3957 static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment)
3958 {
3959     if (This->typelib_segdir[segment].length) {
3960         This->typelib_segdir[segment].offset = filepos;
3961     } else {
3962         This->typelib_segdir[segment].offset = -1;
3963     }
3964
3965     return This->typelib_segdir[segment].length;
3966 }
3967
3968 static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile)
3969 {
3970     ICreateTypeInfo2Impl *typeinfo;
3971
3972     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
3973         CyclicList *iter;
3974         int offset = 0;
3975
3976         if (!typeinfo->typedata) continue;
3977
3978         iter = typeinfo->typedata->next;
3979         ctl2_write_chunk(hFile, &iter->u.val, sizeof(int));
3980         for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next)
3981             ctl2_write_chunk(hFile, iter->u.data, iter->u.data[0] & 0xffff);
3982
3983         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
3984             ctl2_write_chunk(hFile, &iter->indice, sizeof(int));
3985
3986         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
3987             ctl2_write_chunk(hFile, &iter->name, sizeof(int));
3988
3989         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) {
3990             ctl2_write_chunk(hFile, &offset, sizeof(int));
3991             offset += iter->u.data[0] & 0xffff;
3992         }
3993     }
3994 }
3995
3996 /******************************************************************************
3997  * ICreateTypeLib2_SaveAllChanges {OLEAUT32}
3998  *
3999  *  See ICreateTypeLib_SaveAllChanges.
4000  */
4001 static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
4002 {
4003     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4004
4005     int retval;
4006     int filepos;
4007     HANDLE hFile;
4008     HRESULT hres;
4009
4010     TRACE("(%p)\n", iface);
4011
4012     retval = TYPE_E_IOERROR;
4013
4014     hFile = CreateFileW(This->filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
4015     if (hFile == INVALID_HANDLE_VALUE) return retval;
4016
4017     filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir);
4018     filepos += This->typelib_header.nrtypeinfos * 4;
4019
4020     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO);
4021     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH);
4022     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID);
4023     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
4024     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO);
4025     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES);
4026     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH);
4027     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME);
4028     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING);
4029     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEDESC);
4030     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_ARRAYDESC);
4031     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA);
4032     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID);
4033
4034     hres = ctl2_finalize_typeinfos(This, filepos);
4035     if(FAILED(hres)) {
4036         CloseHandle(hFile);
4037         return hres;
4038     }
4039
4040     if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval;
4041     if (This->typelib_header.varflags & HELPDLLFLAG)
4042         if (!ctl2_write_chunk(hFile, &This->helpStringDll, sizeof(This->helpStringDll))) return retval;
4043     if (!ctl2_write_chunk(hFile, This->typelib_typeinfo_offsets, This->typelib_header.nrtypeinfos * 4)) return retval;
4044     if (!ctl2_write_chunk(hFile, This->typelib_segdir, sizeof(This->typelib_segdir))) return retval;
4045     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO    )) return retval;
4046     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH    )) return retval;
4047     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID        )) return retval;
4048     if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES  )) return retval;
4049     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO  )) return retval;
4050     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval;
4051     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH    )) return retval;
4052     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME        )) return retval;
4053     if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING      )) return retval;
4054     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEDESC    )) return retval;
4055     if (!ctl2_write_segment(This, hFile, MSFT_SEG_ARRAYDESC   )) return retval;
4056     if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATA    )) return retval;
4057     if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATAGUID)) return retval;
4058
4059     ctl2_write_typeinfos(This, hFile);
4060
4061     if (!CloseHandle(hFile)) return retval;
4062
4063     return S_OK;
4064 }
4065
4066
4067 /******************************************************************************
4068  * ICreateTypeLib2_DeleteTypeInfo {OLEAUT32}
4069  *
4070  *  Deletes a named TypeInfo from a type library.
4071  *
4072  * RETURNS
4073  *
4074  *  Success: S_OK
4075  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4076  */
4077 static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(
4078         ICreateTypeLib2 * iface, /* [I] The type library to delete from. */
4079         LPOLESTR szName)         /* [I] The name of the typeinfo to delete. */
4080 {
4081     FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
4082     return E_OUTOFMEMORY;
4083 }
4084
4085 /******************************************************************************
4086  * ICreateTypeLib2_SetCustData {OLEAUT32}
4087  *
4088  *  Sets custom data for a type library.
4089  *
4090  * RETURNS
4091  *
4092  *  Success: S_OK
4093  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4094  */
4095 static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(
4096         ICreateTypeLib2 * iface, /* [I] The type library to store the custom data in. */
4097         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
4098         VARIANT *pVarVal)        /* [I] The custom data itself. */
4099 {
4100     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4101
4102     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal);
4103
4104     return ctl2_set_custdata(This, guid, pVarVal, &This->typelib_header.CustomDataOffset);
4105 }
4106
4107 /******************************************************************************
4108  * ICreateTypeLib2_SetHelpStringContext {OLEAUT32}
4109  *
4110  *  Sets a context number for the library help string.
4111  *
4112  * PARAMS
4113  *  iface     [I] The type library to set the help string context for.
4114  *  dwContext [I] The help string context.
4115  *
4116  * RETURNS
4117  *  Success: S_OK
4118  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4119  */
4120 static
4121 HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 * iface,
4122                                                       ULONG dwContext)
4123 {
4124     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4125
4126     TRACE("(%p,%d)\n", iface, dwContext);
4127
4128     This->typelib_header.helpstringcontext = dwContext;
4129     return S_OK;
4130 }
4131
4132 /******************************************************************************
4133  * ICreateTypeLib2_SetHelpStringDll {OLEAUT32}
4134  *
4135  *  Set the DLL used to look up localized help strings.
4136  *
4137  * PARAMS
4138  *  iface     [I] The type library to set the help DLL for.
4139  *  szDllName [I] The name of the help DLL.
4140  *
4141  * RETURNS
4142  *  Success: S_OK
4143  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4144  */
4145 static
4146 HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 * iface,
4147                                                   LPOLESTR szDllName)
4148 {
4149     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4150     int offset;
4151
4152     TRACE("(%p,%s)\n", iface, debugstr_w(szDllName));
4153     if (!szDllName)
4154         return E_INVALIDARG;
4155
4156     offset = ctl2_alloc_string(This, szDllName);
4157     if (offset == -1)
4158         return E_OUTOFMEMORY;
4159     This->typelib_header.varflags |= HELPDLLFLAG;
4160     This->helpStringDll = offset;
4161     return S_OK;
4162 }
4163
4164 /*================== ITypeLib2 Implementation ===================================*/
4165
4166 /******************************************************************************
4167  * ITypeLib2_QueryInterface {OLEAUT32}
4168  *
4169  *  See IUnknown_QueryInterface.
4170  */
4171 static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 * iface, REFIID riid, LPVOID * ppv)
4172 {
4173     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4174
4175     return ICreateTypeLib2_QueryInterface((ICreateTypeLib2 *)This, riid, ppv);
4176 }
4177
4178 /******************************************************************************
4179  * ITypeLib2_AddRef {OLEAUT32}
4180  *
4181  *  See IUnknown_AddRef.
4182  */
4183 static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 * iface)
4184 {
4185     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4186
4187     return ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This);
4188 }
4189
4190 /******************************************************************************
4191  * ITypeLib2_Release {OLEAUT32}
4192  *
4193  *  See IUnknown_Release.
4194  */
4195 static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 * iface)
4196 {
4197     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4198
4199     return ICreateTypeLib2_Release((ICreateTypeLib2 *)This);
4200 }
4201
4202 /******************************************************************************
4203  * ITypeLib2_GetTypeInfoCount {OLEAUT32}
4204  *
4205  *  See ITypeLib_GetTypeInfoCount.
4206  */
4207 static UINT WINAPI ITypeLib2_fnGetTypeInfoCount(
4208         ITypeLib2 * iface)
4209 {
4210     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4211
4212     TRACE("(%p)\n", iface);
4213
4214     return This->typelib_header.nrtypeinfos;
4215 }
4216
4217 /******************************************************************************
4218  * ITypeLib2_GetTypeInfo {OLEAUT32}
4219  *
4220  *  See ITypeLib_GetTypeInfo.
4221  */
4222 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
4223         ITypeLib2 * iface,
4224         UINT index,
4225         ITypeInfo** ppTInfo)
4226 {
4227     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4228
4229     TRACE("(%p,%d,%p)\n", iface, index, ppTInfo);
4230
4231     if (index >= This->typelib_header.nrtypeinfos) {
4232         return TYPE_E_ELEMENTNOTFOUND;
4233     }
4234
4235     return ctl2_find_typeinfo_from_offset(This, This->typelib_typeinfo_offsets[index], ppTInfo);
4236 }
4237
4238 /******************************************************************************
4239  * ITypeLib2_GetTypeInfoType {OLEAUT32}
4240  *
4241  *  See ITypeLib_GetTypeInfoType.
4242  */
4243 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
4244         ITypeLib2 * iface,
4245         UINT index,
4246         TYPEKIND* pTKind)
4247 {
4248     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4249
4250     TRACE("(%p,%d,%p)\n", iface, index, pTKind);
4251
4252     if (index >= This->typelib_header.nrtypeinfos) {
4253         return TYPE_E_ELEMENTNOTFOUND;
4254     }
4255
4256     *pTKind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 15;
4257
4258     return S_OK;
4259 }
4260
4261 /******************************************************************************
4262  * ITypeLib2_GetTypeInfoOfGuid {OLEAUT32}
4263  *
4264  *  See ITypeLib_GetTypeInfoOfGuid.
4265  */
4266 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
4267         ITypeLib2 * iface,
4268         REFGUID guid,
4269         ITypeInfo** ppTinfo)
4270 {
4271     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4272
4273     int guidoffset;
4274     int typeinfo;
4275
4276     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), ppTinfo);
4277
4278     guidoffset = ctl2_find_guid(This, ctl2_hash_guid(guid), guid);
4279     if (guidoffset == -1) return TYPE_E_ELEMENTNOTFOUND;
4280
4281     typeinfo = ((MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][guidoffset])->hreftype;
4282     if (typeinfo < 0) return TYPE_E_ELEMENTNOTFOUND;
4283
4284     return ctl2_find_typeinfo_from_offset(This, typeinfo, ppTinfo);
4285 }
4286
4287 /******************************************************************************
4288  * ITypeLib2_GetLibAttr {OLEAUT32}
4289  *
4290  *  See ITypeLib_GetLibAttr.
4291  */
4292 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
4293         ITypeLib2 * iface,
4294         TLIBATTR** ppTLibAttr)
4295 {
4296     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4297
4298     TRACE("(%p,%p)\n", This, ppTLibAttr);
4299
4300     if(!ppTLibAttr)
4301         return E_INVALIDARG;
4302
4303     *ppTLibAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TLIBATTR));
4304     if(!*ppTLibAttr)
4305         return E_OUTOFMEMORY;
4306
4307     if(This->typelib_header.posguid != -1) {
4308         MSFT_GuidEntry *guid;
4309
4310         guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid];
4311         (*ppTLibAttr)->guid = guid->guid;
4312     }
4313
4314     (*ppTLibAttr)->lcid = This->typelib_header.lcid;
4315     (*ppTLibAttr)->syskind = This->typelib_header.varflags&0x3;
4316     (*ppTLibAttr)->wMajorVerNum = This->typelib_header.version&0xffff;
4317     (*ppTLibAttr)->wMinorVerNum = This->typelib_header.version>>16;
4318     (*ppTLibAttr)->wLibFlags = This->typelib_header.flags;
4319     return S_OK;
4320 }
4321
4322 /******************************************************************************
4323  * ITypeLib2_GetTypeComp {OLEAUT32}
4324  *
4325  *  See ITypeLib_GetTypeComp.
4326  */
4327 static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
4328         ITypeLib2 * iface,
4329         ITypeComp** ppTComp)
4330 {
4331     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4332
4333     FIXME("(%p,%p), stub!\n", This, ppTComp);
4334
4335     return E_OUTOFMEMORY;
4336 }
4337
4338 /******************************************************************************
4339  * ITypeLib2_GetDocumentation {OLEAUT32}
4340  *
4341  *  See ITypeLib_GetDocumentation.
4342  */
4343 static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
4344         ITypeLib2 * iface,
4345         INT index,
4346         BSTR* pBstrName,
4347         BSTR* pBstrDocString,
4348         DWORD* pdwHelpContext,
4349         BSTR* pBstrHelpFile)
4350 {
4351     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4352     WCHAR *string;
4353
4354     TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
4355
4356     if(index != -1) {
4357         ICreateTypeInfo2Impl *iter;
4358
4359         for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo)
4360             index--;
4361
4362         if(!iter)
4363             return TYPE_E_ELEMENTNOTFOUND;
4364
4365         return ITypeInfo_GetDocumentation((ITypeInfo*)iter->lpVtblTypeInfo2,
4366                 -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
4367     }
4368
4369     if(pBstrName) {
4370         if(This->typelib_header.NameOffset == -1)
4371             *pBstrName = NULL;
4372         else {
4373             MSFT_NameIntro *name = (MSFT_NameIntro*)&This->
4374                 typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset];
4375
4376             ctl2_decode_name((char*)&name->namelen, &string);
4377
4378             *pBstrName = SysAllocString(string);
4379             if(!*pBstrName)
4380                 return E_OUTOFMEMORY;
4381         }
4382     }
4383
4384     if(pBstrDocString) {
4385         if(This->typelib_header.helpstring == -1)
4386             *pBstrDocString = NULL;
4387         else {
4388             ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string);
4389
4390             *pBstrDocString = SysAllocString(string);
4391             if(!*pBstrDocString) {
4392                 if(pBstrName) SysFreeString(*pBstrName);
4393                 return E_OUTOFMEMORY;
4394             }
4395         }
4396     }
4397
4398     if(pdwHelpContext)
4399         *pdwHelpContext = This->typelib_header.helpcontext;
4400
4401     if(pBstrHelpFile) {
4402         if(This->typelib_header.helpfile == -1)
4403             *pBstrHelpFile = NULL;
4404         else {
4405             ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string);
4406
4407             *pBstrHelpFile = SysAllocString(string);
4408             if(!*pBstrHelpFile) {
4409                 if(pBstrName) SysFreeString(*pBstrName);
4410                 if(pBstrDocString) SysFreeString(*pBstrDocString);
4411                 return E_OUTOFMEMORY;
4412             }
4413         }
4414     }
4415
4416     return S_OK;
4417 }
4418
4419 /******************************************************************************
4420  * ITypeLib2_IsName {OLEAUT32}
4421  *
4422  *  See ITypeLib_IsName.
4423  */
4424 static HRESULT WINAPI ITypeLib2_fnIsName(
4425         ITypeLib2 * iface,
4426         LPOLESTR szNameBuf,
4427         ULONG lHashVal,
4428         BOOL* pfName)
4429 {
4430     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4431
4432     char *encoded_name;
4433     int nameoffset;
4434     MSFT_NameIntro *nameintro;
4435
4436     TRACE("(%p,%s,%x,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName);
4437
4438     ctl2_encode_name(This, szNameBuf, &encoded_name);
4439     nameoffset = ctl2_find_name(This, encoded_name);
4440
4441     *pfName = 0;
4442
4443     if (nameoffset == -1) return S_OK;
4444
4445     nameintro = (MSFT_NameIntro *)(&This->typelib_segment_data[MSFT_SEG_NAME][nameoffset]);
4446     if (nameintro->hreftype == -1) return S_OK;
4447
4448     *pfName = 1;
4449
4450     FIXME("Should be decoding our copy of the name over szNameBuf.\n");
4451
4452     return S_OK;
4453 }
4454
4455 /******************************************************************************
4456  * ITypeLib2_FindName {OLEAUT32}
4457  *
4458  *  See ITypeLib_FindName.
4459  */
4460 static HRESULT WINAPI ITypeLib2_fnFindName(
4461         ITypeLib2 * iface,
4462         LPOLESTR szNameBuf,
4463         ULONG lHashVal,
4464         ITypeInfo** ppTInfo,
4465         MEMBERID* rgMemId,
4466         USHORT* pcFound)
4467 {
4468     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4469
4470     FIXME("(%p,%s,%x,%p,%p,%p), stub!\n", This, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound);
4471
4472     return E_OUTOFMEMORY;
4473 }
4474
4475 /******************************************************************************
4476  * ITypeLib2_ReleaseTLibAttr {OLEAUT32}
4477  *
4478  *  See ITypeLib_ReleaseTLibAttr.
4479  */
4480 static void WINAPI ITypeLib2_fnReleaseTLibAttr(
4481         ITypeLib2 * iface,
4482         TLIBATTR* pTLibAttr)
4483 {
4484     TRACE("(%p,%p)\n", iface, pTLibAttr);
4485
4486     HeapFree(GetProcessHeap(), 0, pTLibAttr);
4487 }
4488
4489 /******************************************************************************
4490  * ICreateTypeLib2_GetCustData {OLEAUT32}
4491  *
4492  *  Retrieves a custom data value stored on a type library.
4493  *
4494  * RETURNS
4495  *
4496  *  Success: S_OK
4497  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4498  */
4499 static HRESULT WINAPI ITypeLib2_fnGetCustData(
4500         ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */
4501         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
4502         VARIANT* pVarVal)  /* [O] The custom data. */
4503 {
4504     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4505
4506     FIXME("(%p,%s,%p), stub!\n", This, debugstr_guid(guid), pVarVal);
4507
4508     return E_OUTOFMEMORY;
4509 }
4510
4511 /******************************************************************************
4512  * ICreateTypeLib2_GetLibStatistics {OLEAUT32}
4513  *
4514  *  Retrieves some statistics about names in a type library, supposedly for
4515  *  hash table optimization purposes.
4516  *
4517  * RETURNS
4518  *
4519  *  Success: S_OK
4520  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4521  */
4522 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
4523         ITypeLib2 * iface,      /* [I] The type library to get statistics about. */
4524         ULONG* pcUniqueNames,   /* [O] The number of unique names in the type library. */
4525         ULONG* pcchUniqueNames) /* [O] The number of changed (?) characters in names in the type library. */
4526 {
4527     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4528
4529     FIXME("(%p,%p,%p), stub!\n", This, pcUniqueNames, pcchUniqueNames);
4530
4531     return E_OUTOFMEMORY;
4532 }
4533
4534 /******************************************************************************
4535  * ICreateTypeLib2_GetDocumentation2 {OLEAUT32}
4536  *
4537  *  Obtain locale-aware help string information.
4538  *
4539  * RETURNS
4540  *
4541  *  Success: S_OK
4542  *  Failure: STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
4543  */
4544 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
4545         ITypeLib2 * iface,
4546         INT index,
4547         LCID lcid,
4548         BSTR* pbstrHelpString,
4549         DWORD* pdwHelpStringContext,
4550         BSTR* pbstrHelpStringDll)
4551 {
4552     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4553
4554     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", This, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
4555
4556     return E_OUTOFMEMORY;
4557 }
4558
4559 /******************************************************************************
4560  * ICreateTypeLib2_GetAllCustData {OLEAUT32}
4561  *
4562  *  Retrieve all of the custom data for a type library.
4563  *
4564  * RETURNS
4565  *
4566  *  Success: S_OK
4567  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4568  */
4569 static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
4570         ITypeLib2 * iface,   /* [I] The type library in which to find the custom data. */
4571         CUSTDATA* pCustData) /* [O] The structure in which to place the custom data. */
4572 {
4573     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4574
4575     FIXME("(%p,%p), stub!\n", This, pCustData);
4576
4577     return E_OUTOFMEMORY;
4578 }
4579
4580
4581 /*================== ICreateTypeLib2 & ITypeLib2 VTABLEs And Creation ===================================*/
4582
4583 static const ICreateTypeLib2Vtbl ctypelib2vt =
4584 {
4585
4586     ICreateTypeLib2_fnQueryInterface,
4587     ICreateTypeLib2_fnAddRef,
4588     ICreateTypeLib2_fnRelease,
4589
4590     ICreateTypeLib2_fnCreateTypeInfo,
4591     ICreateTypeLib2_fnSetName,
4592     ICreateTypeLib2_fnSetVersion,
4593     ICreateTypeLib2_fnSetGuid,
4594     ICreateTypeLib2_fnSetDocString,
4595     ICreateTypeLib2_fnSetHelpFileName,
4596     ICreateTypeLib2_fnSetHelpContext,
4597     ICreateTypeLib2_fnSetLcid,
4598     ICreateTypeLib2_fnSetLibFlags,
4599     ICreateTypeLib2_fnSaveAllChanges,
4600
4601     ICreateTypeLib2_fnDeleteTypeInfo,
4602     ICreateTypeLib2_fnSetCustData,
4603     ICreateTypeLib2_fnSetHelpStringContext,
4604     ICreateTypeLib2_fnSetHelpStringDll
4605 };
4606
4607 static const ITypeLib2Vtbl typelib2vt =
4608 {
4609
4610     ITypeLib2_fnQueryInterface,
4611     ITypeLib2_fnAddRef,
4612     ITypeLib2_fnRelease,
4613
4614     ITypeLib2_fnGetTypeInfoCount,
4615     ITypeLib2_fnGetTypeInfo,
4616     ITypeLib2_fnGetTypeInfoType,
4617     ITypeLib2_fnGetTypeInfoOfGuid,
4618     ITypeLib2_fnGetLibAttr,
4619     ITypeLib2_fnGetTypeComp,
4620     ITypeLib2_fnGetDocumentation,
4621     ITypeLib2_fnIsName,
4622     ITypeLib2_fnFindName,
4623     ITypeLib2_fnReleaseTLibAttr,
4624
4625     ITypeLib2_fnGetCustData,
4626     ITypeLib2_fnGetLibStatistics,
4627     ITypeLib2_fnGetDocumentation2,
4628     ITypeLib2_fnGetAllCustData,
4629 };
4630
4631 static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR szFile)
4632 {
4633     ICreateTypeLib2Impl *pCreateTypeLib2Impl;
4634     int failed = 0;
4635
4636     TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(szFile));
4637
4638     pCreateTypeLib2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeLib2Impl));
4639     if (!pCreateTypeLib2Impl) return NULL;
4640
4641     pCreateTypeLib2Impl->filename = HeapAlloc(GetProcessHeap(), 0, (strlenW(szFile) + 1) * sizeof(WCHAR));
4642     if (!pCreateTypeLib2Impl->filename) {
4643         HeapFree(GetProcessHeap(), 0, pCreateTypeLib2Impl);
4644         return NULL;
4645     }
4646     strcpyW(pCreateTypeLib2Impl->filename, szFile);
4647
4648     ctl2_init_header(pCreateTypeLib2Impl);
4649     ctl2_init_segdir(pCreateTypeLib2Impl);
4650
4651     pCreateTypeLib2Impl->typelib_header.varflags |= syskind;
4652
4653     /*
4654      * The following two calls return an offset or -1 if out of memory. We
4655      * specifically need an offset of 0, however, so...
4656      */
4657     if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; }
4658     if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; }
4659
4660     pCreateTypeLib2Impl->typelib_guidhash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_GUIDHASH];
4661     pCreateTypeLib2Impl->typelib_namehash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_NAMEHASH];
4662
4663     memset(pCreateTypeLib2Impl->typelib_guidhash_segment, 0xff, 0x80);
4664     memset(pCreateTypeLib2Impl->typelib_namehash_segment, 0xff, 0x200);
4665
4666     pCreateTypeLib2Impl->lpVtbl = &ctypelib2vt;
4667     pCreateTypeLib2Impl->lpVtblTypeLib2 = &typelib2vt;
4668     pCreateTypeLib2Impl->ref = 1;
4669
4670     if (failed) {
4671         ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)pCreateTypeLib2Impl);
4672         return 0;
4673     }
4674
4675     return (ICreateTypeLib2 *)pCreateTypeLib2Impl;
4676 }
4677
4678 /******************************************************************************
4679  * CreateTypeLib2 [OLEAUT32.180]
4680  *
4681  *  Obtains an ICreateTypeLib2 object for creating a new-style (MSFT) type
4682  *  library.
4683  *
4684  * NOTES
4685  *
4686  *  See also CreateTypeLib.
4687  *
4688  * RETURNS
4689  *    Success: S_OK
4690  *    Failure: Status
4691  */
4692 HRESULT WINAPI CreateTypeLib2(
4693         SYSKIND syskind,           /* [I] System type library is for */
4694         LPCOLESTR szFile,          /* [I] Type library file name */
4695         ICreateTypeLib2** ppctlib) /* [O] Storage for object returned */
4696 {
4697     TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib);
4698
4699     if (!szFile) return E_INVALIDARG;
4700     *ppctlib = ICreateTypeLib2_Constructor(syskind, szFile);
4701     return (*ppctlib)? S_OK: E_OUTOFMEMORY;
4702 }
4703
4704 /******************************************************************************
4705  * ClearCustData (OLEAUT32.171)
4706  *
4707  * Clear a custom data types' data.
4708  *
4709  * PARAMS
4710  *  lpCust [I] The custom data type instance
4711  *
4712  * RETURNS
4713  *  Nothing.
4714  */
4715 void WINAPI ClearCustData(LPCUSTDATA lpCust)
4716 {
4717     if (lpCust && lpCust->cCustData)
4718     {
4719         if (lpCust->prgCustData)
4720         {
4721             DWORD i;
4722
4723             for (i = 0; i < lpCust->cCustData; i++)
4724                 VariantClear(&lpCust->prgCustData[i].varValue);
4725
4726             /* FIXME - Should be using a per-thread IMalloc */
4727             HeapFree(GetProcessHeap(), 0, lpCust->prgCustData);
4728             lpCust->prgCustData = NULL;
4729         }
4730         lpCust->cCustData = 0;
4731     }
4732 }