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