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