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