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