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