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