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