gameux: Don't bother to output a "stub" FIXME in DllCanUnloadNow().
[wine] / dlls / oleaut32 / typelib2.c
1 /*
2  *      TYPELIB2
3  *
4  *      Copyright 2004  Alastair Bridgewater
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * --------------------------------------------------------------------------------------
21  *  Known problems:
22  *
23  *    Badly incomplete.
24  *
25  *    Only works on little-endian systems.
26  *
27  */
28
29 #include "config.h"
30 #include "wine/port.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <ctype.h>
37
38 #define COBJMACROS
39 #define NONAMELESSUNION
40 #define NONAMELESSSTRUCT
41
42 #include "winerror.h"
43 #include "windef.h"
44 #include "winbase.h"
45 #include "winnls.h"
46 #include "winreg.h"
47 #include "winuser.h"
48
49 #include "wine/unicode.h"
50 #include "objbase.h"
51 #include "typelib.h"
52 #include "wine/debug.h"
53
54 WINE_DEFAULT_DEBUG_CHANNEL(typelib2);
55 /* WINE_DEFAULT_DEBUG_CHANNEL(ole); */
56
57
58 /******************************************************************************
59  * ICreateTypeLib2 {OLEAUT32}
60  *
61  * NOTES
62  *  The ICreateTypeLib2 interface provides an interface whereby one may create
63  *  new type library (.tlb) files.
64  *
65  *  This interface inherits from ICreateTypeLib, and can be freely cast back
66  *  and forth between an ICreateTypeLib and an ICreateTypeLib2 on local clients.
67  *  This dispensation applies only to ICreateTypeLib objects obtained on MSFT
68  *  format type libraries (those made through CreateTypeLib2).
69  *
70  * METHODS
71  */
72
73 /******************************************************************************
74  * ICreateTypeInfo2 {OLEAUT32}
75  *
76  * NOTES
77  *  The ICreateTypeInfo2 interface provides an interface whereby one may add
78  *  type information to type library (.tlb) files.
79  *
80  *  This interface inherits from ICreateTypeInfo, and can be freely cast back
81  *  and forth between an ICreateTypeInfo and an ICreateTypeInfo2 on local clients.
82  *  This dispensation applies only to ICreateTypeInfo objects obtained on MSFT
83  *  format type libraries (those made through CreateTypeLib2).
84  *
85  * METHODS
86  */
87
88 /******************************************************************************
89  * ITypeLib2 {OLEAUT32}
90  *
91  * NOTES
92  *  The ITypeLib2 interface provides an interface whereby one may query MSFT
93  *  format type library (.tlb) files.
94  *
95  *  This interface inherits from ITypeLib, and can be freely cast back and
96  *  forth between an ITypeLib and an ITypeLib2 on local clients. This
97  *  dispensation applies only to ITypeLib objects obtained on MSFT format type
98  *  libraries (those made through CreateTypeLib2).
99  *
100  * METHODS
101  */
102
103 /******************************************************************************
104  * ITypeInfo2 {OLEAUT32}
105  *
106  * NOTES
107  *  The ITypeInfo2 interface provides an interface whereby one may query type
108  *  information stored in MSFT format type library (.tlb) files.
109  *
110  *  This interface inherits from ITypeInfo, and can be freely cast back and
111  *  forth between an ITypeInfo and an ITypeInfo2 on local clients. This
112  *  dispensation applies only to ITypeInfo objects obtained on MSFT format type
113  *  libraries (those made through CreateTypeLib2).
114  *
115  * METHODS
116  */
117
118 /*================== Implementation Structures ===================================*/
119
120 /* Used for storing cyclic list. Tail address is kept */
121 enum tagCyclicListElementType {
122     CyclicListFunc,
123     CyclicListVar
124 };
125 typedef struct tagCyclicList {
126     struct tagCyclicList *next;
127     int indice;
128     int name;
129     enum tagCyclicListElementType type;
130
131     union {
132         int val;
133         int *data;
134     }u;
135 } CyclicList;
136
137 enum MSFT_segment_index {
138     MSFT_SEG_TYPEINFO = 0,  /* type information */
139     MSFT_SEG_IMPORTINFO,    /* import information */
140     MSFT_SEG_IMPORTFILES,   /* import filenames */
141     MSFT_SEG_REFERENCES,    /* references (?) */
142     MSFT_SEG_GUIDHASH,      /* hash table for guids? */
143     MSFT_SEG_GUID,          /* guid storage */
144     MSFT_SEG_NAMEHASH,      /* hash table for names */
145     MSFT_SEG_NAME,          /* name storage */
146     MSFT_SEG_STRING,        /* string storage */
147     MSFT_SEG_TYPEDESC,      /* type descriptions */
148     MSFT_SEG_ARRAYDESC,     /* array descriptions */
149     MSFT_SEG_CUSTDATA,      /* custom data */
150     MSFT_SEG_CUSTDATAGUID,  /* custom data guids */
151     MSFT_SEG_UNKNOWN,       /* ??? */
152     MSFT_SEG_UNKNOWN2,      /* ??? */
153     MSFT_SEG_MAX            /* total number of segments */
154 };
155
156 typedef struct tagMSFT_ImpFile {
157     int guid;
158     LCID lcid;
159     int version;
160     char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */
161 } MSFT_ImpFile;
162
163 typedef struct tagICreateTypeLib2Impl
164 {
165     const ICreateTypeLib2Vtbl *lpVtbl;
166     const ITypeLib2Vtbl       *lpVtblTypeLib2;
167
168     LONG ref;
169
170     WCHAR *filename;
171
172     MSFT_Header typelib_header;
173     INT helpStringDll;
174     MSFT_pSeg typelib_segdir[MSFT_SEG_MAX];
175     char *typelib_segment_data[MSFT_SEG_MAX];
176     int typelib_segment_block_length[MSFT_SEG_MAX];
177
178     int typelib_guids; /* Number of defined typelib guids */
179     int typeinfo_guids; /* Number of defined typeinfo guids */
180
181     INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */
182
183     INT *typelib_namehash_segment;
184     INT *typelib_guidhash_segment;
185
186     struct tagICreateTypeInfo2Impl *typeinfos;
187     struct tagICreateTypeInfo2Impl *last_typeinfo;
188 } ICreateTypeLib2Impl;
189
190 static inline ICreateTypeLib2Impl *impl_from_ITypeLib2( ITypeLib2 *iface )
191 {
192     return (ICreateTypeLib2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeLib2Impl, lpVtblTypeLib2));
193 }
194
195 typedef struct tagICreateTypeInfo2Impl
196 {
197     const ICreateTypeInfo2Vtbl *lpVtbl;
198     const ITypeInfo2Vtbl       *lpVtblTypeInfo2;
199
200     LONG ref;
201
202     ICreateTypeLib2Impl *typelib;
203     MSFT_TypeInfoBase *typeinfo;
204
205     struct tagCyclicList *typedata; /* tail of cyclic list */
206
207     TYPEKIND typekind;
208     int datawidth;
209
210     struct tagICreateTypeInfo2Impl *next_typeinfo;
211     struct tagICreateTypeInfo2Impl *dual;
212 } ICreateTypeInfo2Impl;
213
214 static inline ICreateTypeInfo2Impl *impl_from_ITypeInfo2( ITypeInfo2 *iface )
215 {
216     return (ICreateTypeInfo2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeInfo2Impl, lpVtblTypeInfo2));
217 }
218
219 static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface);
220
221
222 /*================== Internal functions ===================================*/
223
224 /****************************************************************************
225  *      ctl2_init_header
226  *
227  *  Initializes the type library header of a new typelib.
228  */
229 static void ctl2_init_header(
230         ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */
231 {
232     This->typelib_header.magic1 = 0x5446534d;
233     This->typelib_header.magic2 = 0x00010002;
234     This->typelib_header.posguid = -1;
235     This->typelib_header.lcid = This->typelib_header.lcid2 = GetUserDefaultLCID();
236     This->typelib_header.varflags = 0x40;
237     This->typelib_header.version = 0;
238     This->typelib_header.flags = 0;
239     This->typelib_header.nrtypeinfos = 0;
240     This->typelib_header.helpstring = -1;
241     This->typelib_header.helpstringcontext = 0;
242     This->typelib_header.helpcontext = 0;
243     This->typelib_header.nametablecount = 0;
244     This->typelib_header.nametablechars = 0;
245     This->typelib_header.NameOffset = -1;
246     This->typelib_header.helpfile = -1;
247     This->typelib_header.CustomDataOffset = -1;
248     This->typelib_header.res44 = 0x20;
249     This->typelib_header.res48 = 0x80;
250     This->typelib_header.dispatchpos = -1;
251     This->typelib_header.nimpinfos = 0;
252     This->helpStringDll = -1;
253 }
254
255 /****************************************************************************
256  *      ctl2_init_segdir
257  *
258  *  Initializes the segment directory of a new typelib.
259  */
260 static void ctl2_init_segdir(
261         ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */
262 {
263     int i;
264     MSFT_pSeg *segdir;
265
266     segdir = &This->typelib_segdir[MSFT_SEG_TYPEINFO];
267
268     for (i = 0; i < 15; i++) {
269         segdir[i].offset = -1;
270         segdir[i].length = 0;
271         segdir[i].res08 = -1;
272         segdir[i].res0c = 0x0f;
273     }
274 }
275
276 /****************************************************************************
277  *      ctl2_hash_guid
278  *
279  *  Generates a hash key from a GUID.
280  *
281  * RETURNS
282  *
283  *  The hash key for the GUID.
284  */
285 static int ctl2_hash_guid(
286         REFGUID guid)                /* [I] The guid to find. */
287 {
288     int hash;
289     int i;
290
291     hash = 0;
292     for (i = 0; i < 8; i ++) {
293         hash ^= ((const short *)guid)[i];
294     }
295
296     return hash & 0x1f;
297 }
298
299 /****************************************************************************
300  *      ctl2_find_guid
301  *
302  *  Locates a guid in a type library.
303  *
304  * RETURNS
305  *
306  *  The offset into the GUID segment of the guid, or -1 if not found.
307  */
308 static int ctl2_find_guid(
309         ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */
310         int hash_key,              /* [I] The hash key for the guid. */
311         REFGUID guid)                /* [I] The guid to find. */
312 {
313     int offset;
314     MSFT_GuidEntry *guidentry;
315
316     offset = This->typelib_guidhash_segment[hash_key];
317     while (offset != -1) {
318         guidentry = (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][offset];
319
320         if (IsEqualGUID(guidentry, guid)) return offset;
321
322         offset = guidentry->next_hash;
323     }
324
325     return offset;
326 }
327
328 /****************************************************************************
329  *      ctl2_find_name
330  *
331  *  Locates a name in a type library.
332  *
333  * RETURNS
334  *
335  *  The offset into the NAME segment of the name, or -1 if not found.
336  *
337  * NOTES
338  *
339  *  The name must be encoded as with ctl2_encode_name().
340  */
341 static int ctl2_find_name(
342         ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */
343         const char *name)          /* [I] The encoded name to find. */
344 {
345     int offset;
346     int *namestruct;
347
348     offset = This->typelib_namehash_segment[name[2] & 0x7f];
349     while (offset != -1) {
350         namestruct = (int *)&This->typelib_segment_data[MSFT_SEG_NAME][offset];
351
352         if (!((namestruct[2] ^ *((const int *)name)) & 0xffff00ff)) {
353             /* hash codes and lengths match, final test */
354             if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break;
355         }
356
357         /* move to next item in hash bucket */
358         offset = namestruct[1];
359     }
360
361     return offset;
362 }
363
364 /****************************************************************************
365  *      ctl2_encode_name
366  *
367  *  Encodes a name string to a form suitable for storing into a type library
368  *  or comparing to a name stored in a type library.
369  *
370  * RETURNS
371  *
372  *  The length of the encoded name, including padding and length+hash fields.
373  *
374  * NOTES
375  *
376  *  Will throw an exception if name or result are NULL. Is not multithread
377  *  safe in the slightest.
378  */
379 static int ctl2_encode_name(
380         ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (used for LCID only). */
381         const WCHAR *name,         /* [I] The name string to encode. */
382         char **result)             /* [O] A pointer to a pointer to receive the encoded name. */
383 {
384     int length;
385     static char converted_name[0x104];
386     int offset;
387     int value;
388
389     length = WideCharToMultiByte(CP_ACP, 0, name, strlenW(name), converted_name+4, 0x100, NULL, NULL);
390     converted_name[0] = length & 0xff;
391
392     converted_name[length + 4] = 0;
393
394     converted_name[1] = 0x00;
395
396     value = LHashValOfNameSysA(This->typelib_header.varflags & 0x0f, This->typelib_header.lcid, converted_name + 4);
397
398     converted_name[2] = value;
399     converted_name[3] = value >> 8;
400
401     for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57;
402
403     *result = converted_name;
404
405     return (length + 7) & ~3;
406 }
407
408 /****************************************************************************
409  *      ctl2_decode_name
410  *
411  * Converts string stored in typelib data to unicode.
412  */
413 static void ctl2_decode_name(
414         char *data,         /* [I] String to be decoded */
415         WCHAR **string)     /* [O] Decoded string */
416 {
417     int i, length;
418     static WCHAR converted_string[0x104];
419
420     length = data[0];
421
422     for(i=0; i<length; i++)
423         converted_string[i] = data[i+4];
424     converted_string[length] = '\0';
425
426     *string = converted_string;
427 }
428
429 /****************************************************************************
430  *      ctl2_encode_string
431  *
432  *  Encodes a string to a form suitable for storing into a type library or
433  *  comparing to a string stored in a type library.
434  *
435  * RETURNS
436  *
437  *  The length of the encoded string, including padding and length fields.
438  *
439  * NOTES
440  *
441  *  Will throw an exception if string or result are NULL. Is not multithread
442  *  safe in the slightest.
443  */
444 static int ctl2_encode_string(
445         ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (not used?). */
446         const WCHAR *string,       /* [I] The string to encode. */
447         char **result)             /* [O] A pointer to a pointer to receive the encoded string. */
448 {
449     int length;
450     static char converted_string[0x104];
451     int offset;
452
453     length = WideCharToMultiByte(CP_ACP, 0, string, strlenW(string), converted_string+2, 0x102, NULL, NULL);
454     converted_string[0] = length & 0xff;
455     converted_string[1] = (length >> 8) & 0xff;
456
457     for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57;
458
459     *result = converted_string;
460
461     return (length + 5) & ~3;
462 }
463
464 /****************************************************************************
465  *      ctl2_decode_string
466  *
467  * Converts string stored in typelib data to unicode.
468  */
469 static void ctl2_decode_string(
470         char *data,         /* [I] String to be decoded */
471         WCHAR **string)     /* [O] Decoded string */
472 {
473     int i, length;
474     static WCHAR converted_string[0x104];
475
476     length = data[0] + (data[1]<<8);
477     if((length&0x3) == 1)
478         length >>= 2;
479
480     for(i=0; i<length; i++)
481         converted_string[i] = data[i+2];
482     converted_string[length] = '\0';
483
484     *string = converted_string;
485 }
486
487 /****************************************************************************
488  *      ctl2_alloc_segment
489  *
490  *  Allocates memory from a segment in a type library.
491  *
492  * RETURNS
493  *
494  *  Success: The offset within the segment of the new data area.
495  *  Failure: -1 (this is invariably an out of memory condition).
496  *
497  * BUGS
498  *
499  *  Does not (yet) handle the case where the allocated segment memory needs to grow.
500  */
501 static int ctl2_alloc_segment(
502         ICreateTypeLib2Impl *This,       /* [I] The type library in which to allocate. */
503         enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */
504         int size,                        /* [I] The amount to allocate. */
505         int block_size)                  /* [I] Initial allocation block size, or 0 for default. */
506 {
507     int offset;
508
509     if(!This->typelib_segment_data[segment]) {
510         if (!block_size) block_size = 0x2000;
511
512         This->typelib_segment_block_length[segment] = block_size;
513         This->typelib_segment_data[segment] = HeapAlloc(GetProcessHeap(), 0, block_size);
514         if (!This->typelib_segment_data[segment]) return -1;
515         memset(This->typelib_segment_data[segment], 0x57, block_size);
516     }
517
518     while ((This->typelib_segdir[segment].length + size) > This->typelib_segment_block_length[segment]) {
519         char *block;
520
521         block_size = This->typelib_segment_block_length[segment];
522         block = HeapReAlloc(GetProcessHeap(), 0, This->typelib_segment_data[segment], block_size << 1);
523         if (!block) return -1;
524
525         if (segment == MSFT_SEG_TYPEINFO) {
526             /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */
527             ICreateTypeInfo2Impl *typeinfo;
528
529             for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
530                 typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - This->typelib_segment_data[segment]];
531             }
532         }
533
534         memset(block + block_size, 0x57, block_size);
535         This->typelib_segment_block_length[segment] = block_size << 1;
536         This->typelib_segment_data[segment] = block;
537     }
538
539     offset = This->typelib_segdir[segment].length;
540     This->typelib_segdir[segment].length += size;
541
542     return offset;
543 }
544
545 /****************************************************************************
546  *      ctl2_alloc_typeinfo
547  *
548  *  Allocates and initializes a typeinfo structure in a type library.
549  *
550  * RETURNS
551  *
552  *  Success: The offset of the new typeinfo.
553  *  Failure: -1 (this is invariably an out of memory condition).
554  */
555 static int ctl2_alloc_typeinfo(
556         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
557         int nameoffset)            /* [I] The offset of the name for this typeinfo. */
558 {
559     int offset;
560     MSFT_TypeInfoBase *typeinfo;
561
562     offset = ctl2_alloc_segment(This, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0);
563     if (offset == -1) return -1;
564
565     This->typelib_typeinfo_offsets[This->typelib_header.nrtypeinfos++] = offset;
566
567     typeinfo = (void *)(This->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset);
568
569     typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16;
570     typeinfo->memoffset = -1; /* should be EOF if no elements */
571     typeinfo->res2 = 0;
572     typeinfo->res3 = 0;
573     typeinfo->res4 = 3;
574     typeinfo->res5 = 0;
575     typeinfo->cElement = 0;
576     typeinfo->res7 = 0;
577     typeinfo->res8 = 0;
578     typeinfo->res9 = 0;
579     typeinfo->resA = 0;
580     typeinfo->posguid = -1;
581     typeinfo->flags = 0;
582     typeinfo->NameOffset = nameoffset;
583     typeinfo->version = 0;
584     typeinfo->docstringoffs = -1;
585     typeinfo->helpstringcontext = 0;
586     typeinfo->helpcontext = 0;
587     typeinfo->oCustData = -1;
588     typeinfo->cbSizeVft = 0;
589     typeinfo->cImplTypes = 0;
590     typeinfo->size = 0;
591     typeinfo->datatype1 = -1;
592     typeinfo->datatype2 = 0;
593     typeinfo->res18 = 0;
594     typeinfo->res19 = -1;
595
596     return offset;
597 }
598
599 /****************************************************************************
600  *      ctl2_alloc_guid
601  *
602  *  Allocates and initializes a GUID structure in a type library. Also updates
603  *  the GUID hash table as needed.
604  *
605  * RETURNS
606  *
607  *  Success: The offset of the new GUID.
608  *  Failure: -1 (this is invariably an out of memory condition).
609  */
610 static int ctl2_alloc_guid(
611         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
612         MSFT_GuidEntry *guid)      /* [I] The GUID to store. */
613 {
614     int offset;
615     MSFT_GuidEntry *guid_space;
616     int hash_key;
617
618     hash_key = ctl2_hash_guid(&guid->guid);
619
620     offset = ctl2_find_guid(This, hash_key, &guid->guid);
621     if (offset != -1) return offset;
622
623     offset = ctl2_alloc_segment(This, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0);
624     if (offset == -1) return -1;
625
626     guid_space = (void *)(This->typelib_segment_data[MSFT_SEG_GUID] + offset);
627     *guid_space = *guid;
628
629     guid_space->next_hash = This->typelib_guidhash_segment[hash_key];
630     This->typelib_guidhash_segment[hash_key] = offset;
631
632     return offset;
633 }
634
635 /****************************************************************************
636  *      ctl2_alloc_name
637  *
638  *  Allocates and initializes a name within a type library. Also updates the
639  *  name hash table as needed.
640  *
641  * RETURNS
642  *
643  *  Success: The offset within the segment of the new name.
644  *  Failure: -1 (this is invariably an out of memory condition).
645  */
646 static int ctl2_alloc_name(
647         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
648         const WCHAR *name)         /* [I] The name to store. */
649 {
650     int length;
651     int offset;
652     MSFT_NameIntro *name_space;
653     char *encoded_name;
654
655     length = ctl2_encode_name(This, name, &encoded_name);
656
657     offset = ctl2_find_name(This, encoded_name);
658     if (offset != -1) return offset;
659
660     offset = ctl2_alloc_segment(This, MSFT_SEG_NAME, length + 8, 0);
661     if (offset == -1) return -1;
662
663     name_space = (void *)(This->typelib_segment_data[MSFT_SEG_NAME] + offset);
664     name_space->hreftype = -1;
665     name_space->next_hash = -1;
666     memcpy(&name_space->namelen, encoded_name, length);
667
668     if (This->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1)
669         name_space->next_hash = This->typelib_namehash_segment[encoded_name[2] & 0x7f];
670
671     This->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset;
672
673     This->typelib_header.nametablecount += 1;
674     This->typelib_header.nametablechars += *encoded_name;
675
676     return offset;
677 }
678
679 /****************************************************************************
680  *      ctl2_alloc_string
681  *
682  *  Allocates and initializes a string in a type library.
683  *
684  * RETURNS
685  *
686  *  Success: The offset within the segment of the new string.
687  *  Failure: -1 (this is invariably an out of memory condition).
688  */
689 static int ctl2_alloc_string(
690         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
691         const WCHAR *string)       /* [I] The string to store. */
692 {
693     int length;
694     int offset;
695     char *string_space;
696     char *encoded_string;
697
698     length = ctl2_encode_string(This, string, &encoded_string);
699
700     for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_STRING].length;
701          offset += ((((This->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff)
702              | (This->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) {
703         if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset;
704     }
705
706     offset = ctl2_alloc_segment(This, MSFT_SEG_STRING, length, 0);
707     if (offset == -1) return -1;
708
709     string_space = This->typelib_segment_data[MSFT_SEG_STRING] + offset;
710     memcpy(string_space, encoded_string, length);
711
712     return offset;
713 }
714
715 /****************************************************************************
716  *      ctl2_alloc_importinfo
717  *
718  *  Allocates and initializes an import information structure in a type library.
719  *
720  * RETURNS
721  *
722  *  Success: The offset of the new importinfo.
723  *  Failure: -1 (this is invariably an out of memory condition).
724  */
725 static int ctl2_alloc_importinfo(
726         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
727         MSFT_ImpInfo *impinfo)     /* [I] The import information to store. */
728 {
729     int offset;
730     MSFT_ImpInfo *impinfo_space;
731
732     impinfo_space = (MSFT_ImpInfo*)&This->typelib_segment_data[MSFT_SEG_IMPORTINFO][0];
733     for (offset=0; offset<This->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
734             offset+=sizeof(MSFT_ImpInfo)) {
735         if(impinfo_space->oImpFile == impinfo->oImpFile
736                 && impinfo_space->oGuid == impinfo->oGuid)
737             return offset;
738
739         impinfo_space += 1;
740     }
741
742     impinfo->flags |= This->typelib_header.nimpinfos++;
743
744     offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0);
745     if (offset == -1) return -1;
746
747     impinfo_space = (void *)(This->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset);
748     *impinfo_space = *impinfo;
749
750     return offset;
751 }
752
753 /****************************************************************************
754  *      ctl2_alloc_importfile
755  *
756  *  Allocates and initializes an import file definition in a type library.
757  *
758  * RETURNS
759  *
760  *  Success: The offset of the new importinfo.
761  *  Failure: -1 (this is invariably an out of memory condition).
762  */
763 static int ctl2_alloc_importfile(
764         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
765         int guidoffset,            /* [I] The offset to the GUID for the imported library. */
766         LCID lcid,                 /* [I] The LCID of imported library. */
767         int major_version,         /* [I] The major version number of the imported library. */
768         int minor_version,         /* [I] The minor version number of the imported library. */
769         const WCHAR *filename)     /* [I] The filename of the imported library. */
770 {
771     int length;
772     int offset;
773     MSFT_ImpFile *importfile;
774     char *encoded_string;
775
776     length = ctl2_encode_string(This, filename, &encoded_string);
777
778     encoded_string[0] <<= 2;
779     encoded_string[0] |= 1;
780
781     for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_IMPORTFILES].length;
782          offset += ((((((This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff00)
783              | (This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 5) & 0xfffc) + 0xc) {
784         if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset;
785     }
786
787     offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTFILES, length + 0xc, 0);
788     if (offset == -1) return -1;
789
790     importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset];
791     importfile->guid = guidoffset;
792     importfile->lcid = lcid;
793     importfile->version = major_version | (minor_version << 16);
794     memcpy(importfile->filename, encoded_string, length);
795
796     return offset;
797 }
798
799 /****************************************************************************
800  *      ctl2_encode_variant
801  *
802  *  Encodes a variant, inline if possible or in custom data segment
803  *
804  * RETURNS
805  *
806  *  Success: S_OK
807  *  Failure: Error code from winerror.h
808  */
809 static HRESULT ctl2_encode_variant(
810         ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */
811         int *encoded_value,        /* [O] The encoded default value or data offset */
812         VARIANT *value,            /* [I] Default value to be encoded */
813         VARTYPE arg_type)          /* [I] Argument type */
814 {
815     VARIANT v;
816     HRESULT hres;
817     int mask = 0;
818
819     TRACE("%p %d %d\n", This, V_VT(value), arg_type);
820
821     if(arg_type == VT_INT)
822         arg_type = VT_I4;
823     if(arg_type == VT_UINT)
824         arg_type = VT_UI4;
825
826     v = *value;
827     if(V_VT(value) != arg_type) {
828         hres = VariantChangeType(&v, value, 0, arg_type);
829         if(FAILED(hres))
830             return hres;
831     }
832
833     /* Check if default value can be stored in encoded_value */
834     switch(arg_type) {
835     case VT_I4:
836     case VT_UI4:
837         mask = 0x3ffffff;
838         if(V_UI4(&v)>0x3ffffff)
839             break;
840     case VT_I1:
841     case VT_UI1:
842     case VT_BOOL:
843          if(!mask)
844              mask = 0xff;
845     case VT_I2:
846     case VT_UI2:
847         if(!mask)
848             mask = 0xffff;
849         *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24);
850         return S_OK;
851     }
852
853     switch(arg_type) {
854     case VT_I4:
855     case VT_R4:
856     case VT_UI4:
857     case VT_INT:
858     case VT_UINT:
859     case VT_HRESULT:
860     case VT_PTR: {
861         /* Construct the data to be allocated */
862         int data[2];
863         data[0] = arg_type + (V_UI4(&v)<<16);
864         data[1] = (V_UI4(&v)>>16) + 0x57570000;
865
866         /* Check if the data was already allocated */
867         /* Currently the structures doesn't allow to do it in a nice way */
868         for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-8; *encoded_value+=4)
869             if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8))
870                 return S_OK;
871
872         /* Allocate the data */
873         *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0);
874         if(*encoded_value == -1)
875             return E_OUTOFMEMORY;
876
877         memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8);
878         return S_OK;
879     }
880     case VT_BSTR: {
881         /* Construct the data */
882         int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3;
883         char *data = HeapAlloc(GetProcessHeap(), 0, len);
884
885         if(!data)
886             return E_OUTOFMEMORY;
887
888         *((unsigned short*)data) = arg_type;
889         *((unsigned*)(data+2)) = SysStringLen(V_BSTR(&v));
890         for(i=0; i<SysStringLen(V_BSTR(&v)); i++) {
891             if(V_BSTR(&v)[i] <= 0x7f)
892                 data[i+6] = V_BSTR(&v)[i];
893             else
894                 data[i+6] = '?';
895         }
896         WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), SysStringLen(V_BSTR(&v)), &data[6], len-6, NULL, NULL);
897         for(i=6+SysStringLen(V_BSTR(&v)); i<len; i++)
898             data[i] = 0x57;
899
900         /* Check if the data was already allocated */
901         for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4)
902             if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) {
903                 HeapFree(GetProcessHeap(), 0, data);
904                 return S_OK;
905             }
906
907         /* Allocate the data */
908         *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0);
909         if(*encoded_value == -1) {
910             HeapFree(GetProcessHeap(), 0, data);
911             return E_OUTOFMEMORY;
912         }
913
914         memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len);
915         HeapFree(GetProcessHeap(), 0, data);
916         return S_OK;
917     }
918     default:
919         FIXME("Argument type not yet handled\n");
920         return E_NOTIMPL;
921     }
922 }
923
924 /****************************************************************************
925  *      ctl2_set_custdata
926  *
927  *  Adds a custom data element to an object in a type library.
928  *
929  * RETURNS
930  *
931  *  Success: S_OK.
932  *  Failure: One of E_INVALIDARG or E_OUTOFMEMORY.
933  */
934 static HRESULT ctl2_set_custdata(
935         ICreateTypeLib2Impl *This, /* [I] The type library to store the custom data in. */
936         REFGUID guid,              /* [I] The GUID used as a key to retrieve the custom data. */
937         VARIANT *pVarVal,          /* [I] The custom data itself. */
938         int *offset)               /* [I/O] The list of custom data to prepend to. */
939 {
940     MSFT_GuidEntry guidentry;
941     HRESULT status;
942     int dataoffset;
943     int guidoffset;
944     int custoffset;
945     int *custdata;
946
947     switch(V_VT(pVarVal))
948     {
949     case VT_I4:
950     case VT_R4:
951     case VT_UI4:
952     case VT_INT:
953     case VT_UINT:
954     case VT_HRESULT:
955     case VT_BSTR:
956         /* empty */
957         break;
958     default:
959         return DISP_E_BADVARTYPE;
960     }
961
962     guidentry.guid = *guid;
963
964     guidentry.hreftype = -1;
965     guidentry.next_hash = -1;
966
967     guidoffset = ctl2_alloc_guid(This, &guidentry);
968     if (guidoffset == -1) return E_OUTOFMEMORY;
969
970     status = ctl2_encode_variant(This, &dataoffset, pVarVal, V_VT(pVarVal));
971     if (status)
972         return status;
973
974     custoffset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATAGUID, 12, 0);
975     if (custoffset == -1) return E_OUTOFMEMORY;
976
977     custdata = (int *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset];
978     custdata[0] = guidoffset;
979     custdata[1] = dataoffset;
980     custdata[2] = *offset;
981     *offset = custoffset;
982
983     return S_OK;
984 }
985
986 /****************************************************************************
987  *      ctl2_encode_typedesc
988  *
989  *  Encodes a type description, storing information in the TYPEDESC and ARRAYDESC
990  *  segments as needed.
991  *
992  * RETURNS
993  *
994  *  Success: 0.
995  *  Failure: -1.
996  */
997 static int ctl2_encode_typedesc(
998         ICreateTypeLib2Impl *This, /* [I] The type library in which to encode the TYPEDESC. */
999         const TYPEDESC *tdesc,     /* [I] The type description to encode. */
1000         int *encoded_tdesc,        /* [O] The encoded type description. */
1001         int *width,                /* [O] The width of the type, or NULL. */
1002         int *alignment,            /* [O] The alignment of the type, or NULL. */
1003         int *decoded_size)         /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
1004 {
1005     int default_tdesc;
1006     int scratch;
1007     int typeoffset;
1008     int arrayoffset;
1009     int *typedata;
1010     int *arraydata;
1011     int target_type;
1012     int child_size;
1013
1014     default_tdesc = 0x80000000 | (tdesc->vt << 16) | tdesc->vt;
1015     if (!width) width = &scratch;
1016     if (!alignment) alignment = &scratch;
1017     if (!decoded_size) decoded_size = &scratch;
1018
1019     *decoded_size = 0;
1020
1021     switch (tdesc->vt) {
1022     case VT_UI1:
1023     case VT_I1:
1024         *encoded_tdesc = default_tdesc;
1025         *width = 1;
1026         *alignment = 1;
1027         break;
1028
1029     case VT_INT:
1030         *encoded_tdesc = 0x80000000 | (VT_I4 << 16) | VT_INT;
1031         if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) {
1032             *width = 2;
1033             *alignment = 2;
1034         } else {
1035             *width = 4;
1036             *alignment = 4;
1037         }
1038         break;
1039
1040     case VT_UINT:
1041         *encoded_tdesc = 0x80000000 | (VT_UI4 << 16) | VT_UINT;
1042         if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) {
1043             *width = 2;
1044             *alignment = 2;
1045         } else {
1046             *width = 4;
1047             *alignment = 4;
1048         }
1049         break;
1050
1051     case VT_UI2:
1052     case VT_I2:
1053     case VT_BOOL:
1054         *encoded_tdesc = default_tdesc;
1055         *width = 2;
1056         *alignment = 2;
1057         break;
1058
1059     case VT_I4:
1060     case VT_UI4:
1061     case VT_R4:
1062     case VT_ERROR:
1063     case VT_BSTR:
1064     case VT_HRESULT:
1065         *encoded_tdesc = default_tdesc;
1066         *width = 4;
1067         *alignment = 4;
1068         break;
1069
1070     case VT_CY:
1071         *encoded_tdesc = default_tdesc;
1072         *width = 8;
1073         *alignment = 4; /* guess? */
1074         break;
1075
1076     case VT_VOID:
1077         *encoded_tdesc = 0x80000000 | (VT_EMPTY << 16) | tdesc->vt;
1078         *width = 0;
1079         *alignment = 1;
1080         break;
1081
1082     case VT_PTR:
1083     case VT_SAFEARRAY:
1084         /* FIXME: Make with the error checking. */
1085         FIXME("PTR or SAFEARRAY vartype, may not work correctly.\n");
1086
1087         ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);
1088
1089         for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
1090             typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1091             if (((typedata[0] & 0xffff) == tdesc->vt) && (typedata[1] == target_type)) break;
1092         }
1093
1094         if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
1095             int mix_field;
1096             
1097             if (target_type & 0x80000000) {
1098                 mix_field = (target_type >> 16) & VT_TYPEMASK;
1099             } else {
1100                 typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
1101                 switch((typedata[0]>>16) & ~VT_ARRAY)
1102                 {
1103                     case VT_UI1:
1104                     case VT_I1:
1105                     case VT_UI2:
1106                     case VT_I2:
1107                     case VT_I4:
1108                     case VT_UI4:
1109                         mix_field = typedata[0]>>16;
1110                         break;
1111                     default:
1112                         mix_field = 0x7fff;
1113                         break;
1114                 }
1115             }
1116
1117             if (tdesc->vt == VT_PTR)
1118                 mix_field |= VT_BYREF;
1119             else if (tdesc->vt == VT_SAFEARRAY)
1120                 mix_field |= VT_ARRAY;
1121
1122             typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
1123             typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1124
1125             typedata[0] = (mix_field << 16) | tdesc->vt;
1126             typedata[1] = target_type;
1127         }
1128
1129         *encoded_tdesc = typeoffset;
1130
1131         *width = 4;
1132         *alignment = 4;
1133         *decoded_size = sizeof(TYPEDESC) + child_size;
1134         break;
1135
1136     case VT_CARRAY:
1137       {
1138         /* FIXME: Make with the error checking. */
1139         int num_dims = tdesc->u.lpadesc->cDims, elements = 1, dim;
1140
1141         ctl2_encode_typedesc(This, &tdesc->u.lpadesc->tdescElem, &target_type, width, alignment, NULL);
1142         arrayoffset = ctl2_alloc_segment(This, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
1143         arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
1144
1145         arraydata[0] = target_type;
1146         arraydata[1] = num_dims;
1147         arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16);
1148         arraydata += 2;
1149
1150         for(dim = 0; dim < num_dims; dim++) {
1151             arraydata[0] = tdesc->u.lpadesc->rgbounds[dim].cElements;
1152             arraydata[1] = tdesc->u.lpadesc->rgbounds[dim].lLbound;
1153             elements *= tdesc->u.lpadesc->rgbounds[dim].cElements;
1154             arraydata += 2;
1155         }
1156         typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
1157         typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1158
1159         typedata[0] = (0x7ffe << 16) | VT_CARRAY;
1160         typedata[1] = arrayoffset;
1161
1162         *encoded_tdesc = typeoffset;
1163         *width = *width * elements;
1164         *decoded_size = sizeof(ARRAYDESC) + (num_dims - 1) * sizeof(SAFEARRAYBOUND);
1165
1166         break;
1167       }
1168     case VT_USERDEFINED:
1169       {
1170         const MSFT_TypeInfoBase *basetype;
1171         INT basevt = 0x7fff;
1172
1173         TRACE("USERDEFINED.\n");
1174         if (tdesc->u.hreftype % sizeof(*basetype) == 0 && tdesc->u.hreftype < This->typelib_segdir[MSFT_SEG_TYPEINFO].length)
1175         {
1176             basetype = (MSFT_TypeInfoBase*)&(This->typelib_segment_data[MSFT_SEG_TYPEINFO][tdesc->u.hreftype]);
1177             switch(basetype->typekind & 0xf)
1178             {
1179                 case TKIND_ENUM:
1180                     basevt = VT_I4;
1181                     break;
1182                 default:
1183                     FIXME("USERDEFINED basetype %d not handled\n", basetype->typekind & 0xf);
1184                     break;
1185             }
1186         }
1187         for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
1188             typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1189             if ((typedata[0] == ((basevt << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break;
1190         }
1191
1192         if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
1193             typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
1194             typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
1195
1196             typedata[0] = (basevt << 16) | VT_USERDEFINED;
1197             typedata[1] = tdesc->u.hreftype;
1198         }
1199
1200         *encoded_tdesc = typeoffset;
1201         *width = 0;
1202         *alignment = 1;
1203         break;
1204       }
1205
1206     default:
1207         FIXME("Unrecognized type %d.\n", tdesc->vt);
1208         *encoded_tdesc = default_tdesc;
1209         *width = 0;
1210         *alignment = 1;
1211         break;
1212     }
1213
1214     return 0;
1215 }
1216
1217 /****************************************************************************
1218  *      ctl2_find_nth_reference
1219  *
1220  *  Finds a reference by index into the linked list of reference records.
1221  *
1222  * RETURNS
1223  *
1224  *  Success: Offset of the desired reference record.
1225  *  Failure: -1.
1226  */
1227 static int ctl2_find_nth_reference(
1228         ICreateTypeLib2Impl *This, /* [I] The type library in which to search. */
1229         int offset,                /* [I] The starting offset of the reference list. */
1230         int index)                 /* [I] The index of the reference to find. */
1231 {
1232     MSFT_RefRecord *ref;
1233
1234     for (; index && (offset != -1); index--) {
1235         ref = (MSFT_RefRecord *)&This->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
1236         offset = ref->onext;
1237     }
1238
1239     return offset;
1240 }
1241
1242 /****************************************************************************
1243  *      ctl2_find_typeinfo_from_offset
1244  *
1245  *  Finds an ITypeInfo given an offset into the TYPEINFO segment.
1246  *
1247  * RETURNS
1248  *
1249  *  Success: S_OK.
1250  *  Failure: TYPE_E_ELEMENTNOTFOUND.
1251  */
1252 static HRESULT ctl2_find_typeinfo_from_offset(
1253         ICreateTypeLib2Impl *This, /* [I] The typelib to find the typeinfo in. */
1254         int offset,                /* [I] The offset of the desired typeinfo. */
1255         ITypeInfo **ppTinfo)       /* [I] The typeinfo found. */
1256 {
1257     void *typeinfodata;
1258     ICreateTypeInfo2Impl *typeinfo;
1259
1260     typeinfodata = &This->typelib_segment_data[MSFT_SEG_TYPEINFO][offset];
1261
1262     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
1263         if (typeinfo->typeinfo == typeinfodata) {
1264             *ppTinfo = (ITypeInfo *)&typeinfo->lpVtblTypeInfo2;
1265             ITypeInfo2_AddRef(*ppTinfo);
1266             return S_OK;
1267         }
1268     }
1269
1270     ERR("Failed to find typeinfo, invariant varied.\n");
1271
1272     return TYPE_E_ELEMENTNOTFOUND;
1273 }
1274
1275 /****************************************************************************
1276  *      funcrecord_reallochdr
1277  *
1278  *  Ensure FuncRecord data block contains header of required size
1279  *
1280  *  PARAMS
1281  *
1282  *   typedata [IO] - reference to pointer to data block
1283  *   need     [I]  - required size of block in bytes
1284  *
1285  * RETURNS
1286  *
1287  *  Number of additionally allocated bytes
1288  */
1289 static INT funcrecord_reallochdr(INT **typedata, int need)
1290 {
1291     int tail = (*typedata)[5]*((*typedata)[4]&0x1000?16:12);
1292     int hdr = (*typedata)[0] - tail;
1293     int i;
1294
1295     if (hdr >= need)
1296         return 0;
1297
1298     *typedata = HeapReAlloc(GetProcessHeap(), 0, *typedata, need + tail);
1299     if (!*typedata)
1300         return -1;
1301
1302     if (tail)
1303         memmove((char*)*typedata + need, (const char*)*typedata + hdr, tail);
1304     (*typedata)[0] = need + tail;
1305
1306     /* fill in default values */
1307     for(i = (hdr+3)/4; (i+1)*4 <= need; i++)
1308     {
1309         switch(i)
1310         {
1311             case 2:
1312                 (*typedata)[i] = 0;
1313                 break;
1314             case 7:
1315                 (*typedata)[i] = -1;
1316                 break;
1317             case 8:
1318                 (*typedata)[i] = -1;
1319                 break;
1320             case 9:
1321                 (*typedata)[i] = -1;
1322                 break;
1323             case 10:
1324                 (*typedata)[i] = -1;
1325                 break;
1326             case 11:
1327                 (*typedata)[i] = 0;
1328                 break;
1329             case 12:
1330                 (*typedata)[i] = -1;
1331                 break;
1332         }
1333     }
1334
1335     return need - hdr;
1336 }
1337
1338 /*================== ICreateTypeInfo2 Implementation ===================================*/
1339
1340 /******************************************************************************
1341  * ICreateTypeInfo2_QueryInterface {OLEAUT32}
1342  *
1343  *  See IUnknown_QueryInterface.
1344  */
1345 static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(
1346         ICreateTypeInfo2 * iface,
1347         REFIID riid,
1348         VOID **ppvObject)
1349 {
1350     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1351
1352     TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
1353
1354     *ppvObject=NULL;
1355     if(IsEqualIID(riid, &IID_IUnknown) ||
1356        IsEqualIID(riid,&IID_ICreateTypeInfo)||
1357        IsEqualIID(riid,&IID_ICreateTypeInfo2))
1358     {
1359         *ppvObject = This;
1360     } else if (IsEqualIID(riid, &IID_ITypeInfo) ||
1361                IsEqualIID(riid, &IID_ITypeInfo2)) {
1362         *ppvObject = &This->lpVtblTypeInfo2;
1363     }
1364
1365     if(*ppvObject)
1366     {
1367         ICreateTypeInfo2_AddRef(iface);
1368         TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
1369         return S_OK;
1370     }
1371     TRACE("-- Interface: E_NOINTERFACE\n");
1372     return E_NOINTERFACE;
1373 }
1374
1375 /******************************************************************************
1376  * ICreateTypeInfo2_AddRef {OLEAUT32}
1377  *
1378  *  See IUnknown_AddRef.
1379  */
1380 static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
1381 {
1382     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1383     ULONG ref = InterlockedIncrement(&This->ref);
1384
1385     TRACE("(%p)->ref was %u\n",This, ref - 1);
1386
1387     if(ref==1 && This->typelib)
1388         ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This->typelib);
1389
1390     return ref;
1391 }
1392
1393 /******************************************************************************
1394  * ICreateTypeInfo2_Release {OLEAUT32}
1395  *
1396  *  See IUnknown_Release.
1397  */
1398 static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
1399 {
1400     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1401     ULONG ref = InterlockedDecrement(&This->ref);
1402
1403     TRACE("(%p)->(%u)\n",This, ref);
1404
1405     if (!ref) {
1406         if (This->typelib) {
1407             ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib);
1408             /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */
1409             /* This->typelib = NULL; */
1410         }
1411
1412         /* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
1413         /* HeapFree(GetProcessHeap(),0,This); */
1414         return 0;
1415     }
1416
1417     return ref;
1418 }
1419
1420
1421 /******************************************************************************
1422  * ICreateTypeInfo2_SetGuid {OLEAUT32}
1423  *
1424  *  See ICreateTypeInfo_SetGuid.
1425  */
1426 static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid)
1427 {
1428     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1429
1430     MSFT_GuidEntry guidentry;
1431     int offset;
1432
1433     TRACE("(%p,%s)\n", iface, debugstr_guid(guid));
1434
1435     guidentry.guid = *guid;
1436     guidentry.hreftype = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
1437     guidentry.next_hash = -1;
1438
1439     offset = ctl2_alloc_guid(This->typelib, &guidentry);
1440     
1441     if (offset == -1) return E_OUTOFMEMORY;
1442
1443     This->typeinfo->posguid = offset;
1444
1445     if (IsEqualIID(guid, &IID_IDispatch)) {
1446         This->typelib->typelib_header.dispatchpos = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
1447     }
1448
1449     return S_OK;
1450 }
1451
1452 /******************************************************************************
1453  * ICreateTypeInfo2_SetTypeFlags {OLEAUT32}
1454  *
1455  *  See ICreateTypeInfo_SetTypeFlags.
1456  */
1457 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT uTypeFlags)
1458 {
1459     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1460
1461     TRACE("(%p,0x%x)\n", iface, uTypeFlags);
1462
1463     if(uTypeFlags & TYPEFLAG_FDUAL) {
1464         This->typeinfo->typekind |= 0x10;
1465         This->typeinfo->typekind &= ~0x0f;
1466         This->typeinfo->typekind |= TKIND_DISPATCH;
1467
1468         if(!This->dual) {
1469             This->dual = HeapAlloc(GetProcessHeap(), 0, sizeof(ICreateTypeInfo2Impl));
1470             if(!This->dual)
1471                 return E_OUTOFMEMORY;
1472
1473             memcpy(This->dual, This, sizeof(ICreateTypeInfo2Impl));
1474             This->dual->ref = 0;
1475             This->dual->typekind = This->typekind==TKIND_DISPATCH ?
1476                 TKIND_INTERFACE : TKIND_DISPATCH;
1477             This->dual->dual = This;
1478         }
1479
1480         /* Make sure dispatch is in typeinfos queue */
1481         if(This->typekind != TKIND_DISPATCH) {
1482             if(This->typelib->last_typeinfo == This)
1483                 This->typelib->last_typeinfo = This->dual;
1484
1485             if(This->typelib->typeinfos == This)
1486                 This->typelib->typeinfos = This->dual;
1487             else {
1488                 ICreateTypeInfo2Impl *iter;
1489
1490                 for(iter=This->typelib->typeinfos; iter->next_typeinfo!=This; iter=iter->next_typeinfo);
1491                 iter->next_typeinfo = This->dual;
1492             }
1493         } else
1494             iface = (ICreateTypeInfo2*)&This->dual->lpVtbl;
1495     }
1496
1497     if (uTypeFlags & (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL)) {
1498         static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 };
1499         ITypeLib *stdole;
1500         ITypeInfo *dispatch;
1501         HREFTYPE hreftype;
1502         HRESULT hres;
1503
1504         hres = LoadTypeLib(stdole2tlb, &stdole);
1505         if(FAILED(hres))
1506             return hres;
1507
1508         hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch);
1509         ITypeLib_Release(stdole);
1510         if(FAILED(hres))
1511             return hres;
1512
1513         hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype);
1514         ITypeInfo_Release(dispatch);
1515         if(FAILED(hres))
1516             return hres;
1517     }
1518
1519     This->typeinfo->flags = uTypeFlags;
1520     return S_OK;
1521 }
1522
1523 /******************************************************************************
1524  * ICreateTypeInfo2_SetDocString {OLEAUT32}
1525  *
1526  *  See ICreateTypeInfo_SetDocString.
1527  */
1528 static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(
1529         ICreateTypeInfo2* iface,
1530         LPOLESTR pStrDoc)
1531 {
1532     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1533
1534     int offset;
1535
1536     TRACE("(%p,%s)\n", iface, debugstr_w(pStrDoc));
1537     if (!pStrDoc)
1538         return E_INVALIDARG;
1539
1540     offset = ctl2_alloc_string(This->typelib, pStrDoc);
1541     if (offset == -1) return E_OUTOFMEMORY;
1542     This->typeinfo->docstringoffs = offset;
1543     return S_OK;
1544 }
1545
1546 /******************************************************************************
1547  * ICreateTypeInfo2_SetHelpContext {OLEAUT32}
1548  *
1549  *  See ICreateTypeInfo_SetHelpContext.
1550  */
1551 static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(
1552         ICreateTypeInfo2* iface,
1553         DWORD dwHelpContext)
1554 {
1555     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1556
1557     TRACE("(%p,%d)\n", iface, dwHelpContext);
1558
1559     This->typeinfo->helpcontext = dwHelpContext;
1560
1561     return S_OK;
1562 }
1563
1564 /******************************************************************************
1565  * ICreateTypeInfo2_SetVersion {OLEAUT32}
1566  *
1567  *  See ICreateTypeInfo_SetVersion.
1568  */
1569 static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(
1570         ICreateTypeInfo2* iface,
1571         WORD wMajorVerNum,
1572         WORD wMinorVerNum)
1573 {
1574     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1575
1576     TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);
1577
1578     This->typeinfo->version = wMajorVerNum | (wMinorVerNum << 16);
1579     return S_OK;
1580 }
1581
1582 /******************************************************************************
1583  * ICreateTypeInfo2_AddRefTypeInfo {OLEAUT32}
1584  *
1585  *  See ICreateTypeInfo_AddRefTypeInfo.
1586  */
1587 static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(
1588         ICreateTypeInfo2* iface,
1589         ITypeInfo* pTInfo,
1590         HREFTYPE* phRefType)
1591 {
1592     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1593
1594     ITypeLib *container;
1595     UINT index;
1596     HRESULT res;
1597
1598     TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType);
1599
1600     if(!pTInfo || !phRefType)
1601         return E_INVALIDARG;
1602
1603     /*
1604      * Unfortunately, we can't rely on the passed-in TypeInfo even having the
1605      * same internal structure as one of ours. It could be from another
1606      * implementation of ITypeInfo. So we need to do the following...
1607      */
1608     res = ITypeInfo_GetContainingTypeLib(pTInfo, &container, &index);
1609     if (FAILED(res)) {
1610         TRACE("failed to find containing typelib.\n");
1611         return res;
1612     }
1613
1614     if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) {
1615         /* Process locally defined TypeInfo */
1616         *phRefType = This->typelib->typelib_typeinfo_offsets[index];
1617     } else {
1618         BSTR name;
1619         TLIBATTR *tlibattr;
1620         TYPEATTR *typeattr;
1621         TYPEKIND typekind;
1622         MSFT_GuidEntry guid, *check_guid;
1623         MSFT_ImpInfo impinfo;
1624         int guid_offset, import_offset;
1625         HRESULT hres;
1626
1627         /* Allocate container GUID */
1628         hres = ITypeLib_GetLibAttr(container, &tlibattr);
1629         if(FAILED(hres)) {
1630             ITypeLib_Release(container);
1631             return hres;
1632         }
1633
1634         guid.guid = tlibattr->guid;
1635         guid.hreftype = This->typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length+2;
1636         guid.next_hash = -1;
1637
1638         guid_offset = ctl2_alloc_guid(This->typelib, &guid);
1639         if(guid_offset == -1) {
1640             ITypeLib_ReleaseTLibAttr(container, tlibattr);
1641             ITypeLib_Release(container);
1642             return E_OUTOFMEMORY;
1643         }
1644
1645         check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
1646         if(check_guid->hreftype == guid.hreftype)
1647             This->typelib->typelib_guids++;
1648
1649         /* Get import file name */
1650         hres = QueryPathOfRegTypeLib(&guid.guid, tlibattr->wMajorVerNum,
1651                 tlibattr->wMinorVerNum, tlibattr->lcid, &name);
1652         if(FAILED(hres)) {
1653             ITypeLib_ReleaseTLibAttr(container, tlibattr);
1654             ITypeLib_Release(container);
1655             return hres;
1656         }
1657
1658         /* Import file */
1659         import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, tlibattr->lcid,
1660                 tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, strrchrW(name, '\\')+1);
1661         ITypeLib_ReleaseTLibAttr(container, tlibattr);
1662         SysFreeString(name);
1663
1664         if(import_offset == -1) {
1665             ITypeLib_Release(container);
1666             return E_OUTOFMEMORY;
1667         }
1668
1669         /* Allocate referenced guid */
1670         hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr);
1671         if(FAILED(hres)) {
1672             ITypeLib_Release(container);
1673             return hres;
1674         }
1675
1676         guid.guid = typeattr->guid;
1677         guid.hreftype = This->typelib->typeinfo_guids*12+1;
1678         guid.next_hash = -1;
1679         typekind = typeattr->typekind;
1680         ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr);
1681
1682         guid_offset = ctl2_alloc_guid(This->typelib, &guid);
1683         if(guid_offset == -1) {
1684             ITypeLib_Release(container);
1685             return E_OUTOFMEMORY;
1686         }
1687
1688         check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
1689         if(check_guid->hreftype == guid.hreftype)
1690             This->typelib->typeinfo_guids++;
1691
1692         /* Allocate importinfo */
1693         impinfo.flags = (typekind<<24) | MSFT_IMPINFO_OFFSET_IS_GUID;
1694         impinfo.oImpFile = import_offset;
1695         impinfo.oGuid = guid_offset;
1696         *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1;
1697
1698         if(IsEqualGUID(&guid.guid, &IID_IDispatch))
1699             This->typelib->typelib_header.dispatchpos = *phRefType;
1700     }
1701
1702     ITypeLib_Release(container);
1703     return S_OK;
1704 }
1705
1706 /******************************************************************************
1707  * ICreateTypeInfo2_AddFuncDesc {OLEAUT32}
1708  *
1709  *  See ICreateTypeInfo_AddFuncDesc.
1710  */
1711 static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
1712         ICreateTypeInfo2* iface,
1713         UINT index,
1714         FUNCDESC* pFuncDesc)
1715 {
1716     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1717
1718     CyclicList *iter, *insert;
1719     int *typedata;
1720     int i, num_defaults = 0, num_retval = 0;
1721     int decoded_size;
1722     HRESULT hres;
1723
1724     TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);
1725
1726     if(!pFuncDesc || pFuncDesc->oVft&3)
1727         return E_INVALIDARG;
1728
1729     TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid,
1730             pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind,
1731             pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams,
1732             pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes,
1733             pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
1734
1735     if(pFuncDesc->cParamsOpt || pFuncDesc->cScodes)
1736         FIXME("Unimplemented parameter - created typelib will be incorrect\n");
1737
1738     switch(This->typekind) {
1739     case TKIND_MODULE:
1740         if(pFuncDesc->funckind != FUNC_STATIC)
1741             return TYPE_E_BADMODULEKIND;
1742         break;
1743     case TKIND_DISPATCH:
1744         if(pFuncDesc->funckind != FUNC_DISPATCH)
1745             return TYPE_E_BADMODULEKIND;
1746         break;
1747     default:
1748         if(pFuncDesc->funckind != FUNC_PUREVIRTUAL)
1749             return TYPE_E_BADMODULEKIND;
1750     }
1751
1752     if(This->typeinfo->cElement<index)
1753         return TYPE_E_ELEMENTNOTFOUND;
1754
1755     if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) &&
1756         !pFuncDesc->cParams)
1757         return TYPE_E_INCONSISTENTPROPFUNCS;
1758
1759     /* get number of arguments with default values specified */
1760     for (i = 0; i < pFuncDesc->cParams; i++) {
1761         if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
1762             num_defaults++;
1763         if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
1764             num_retval++;
1765     }
1766
1767     if (!This->typedata) {
1768         This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
1769         if(!This->typedata)
1770             return E_OUTOFMEMORY;
1771
1772         This->typedata->next = This->typedata;
1773         This->typedata->u.val = 0;
1774
1775         if(This->dual)
1776             This->dual->typedata = This->typedata;
1777     }
1778
1779     /* allocate type data space for us */
1780     insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
1781     if(!insert)
1782         return E_OUTOFMEMORY;
1783     insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[6])+sizeof(int[(num_defaults?4:3)])*pFuncDesc->cParams);
1784     if(!insert->u.data) {
1785         HeapFree(GetProcessHeap(), 0, insert);
1786         return E_OUTOFMEMORY;
1787     }
1788
1789     /* fill out the basic type information */
1790     typedata = insert->u.data;
1791     typedata[0] = 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
1792     ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size);
1793     typedata[2] = pFuncDesc->wFuncFlags;
1794     typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | (unsigned short)(pFuncDesc->oVft?pFuncDesc->oVft+1:0);
1795     typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind;
1796     if(num_defaults) typedata[4] |= 0x1000;
1797     if (num_retval) typedata[4] |= 0x4000;
1798     typedata[5] = pFuncDesc->cParams;
1799
1800     /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */
1801     /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */
1802     typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16;
1803     typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16;
1804
1805     /* add default values */
1806     if(num_defaults) {
1807         for (i = 0; i < pFuncDesc->cParams; i++)
1808             if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
1809                 hres = ctl2_encode_variant(This->typelib, typedata+6+i,
1810                         &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue,
1811                         pFuncDesc->lprgelemdescParam[i].tdesc.vt);
1812
1813                 if(FAILED(hres)) {
1814                     HeapFree(GetProcessHeap(), 0, insert->u.data);
1815                     HeapFree(GetProcessHeap(), 0, insert);
1816                     return hres;
1817                 }
1818             } else
1819                 typedata[6+i] = 0xffffffff;
1820
1821         num_defaults = pFuncDesc->cParams;
1822     }
1823
1824     /* add arguments */
1825     for (i = 0; i < pFuncDesc->cParams; i++) {
1826         ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc,
1827                 &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size);
1828         typedata[7+num_defaults+(i*3)] = -1;
1829         typedata[8+num_defaults+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
1830         typedata[3] += decoded_size << 16;
1831     }
1832
1833     /* update the index data */
1834     insert->indice = pFuncDesc->memid;
1835     insert->name = -1;
1836     insert->type = CyclicListFunc;
1837
1838     /* insert type data to list */
1839     if(index == This->typeinfo->cElement) {
1840         insert->next = This->typedata->next;
1841         This->typedata->next = insert;
1842         This->typedata = insert;
1843
1844         if(This->dual)
1845             This->dual->typedata = This->typedata;
1846     } else {
1847         iter = This->typedata->next;
1848         for(i=0; i<index; i++)
1849             iter = iter->next;
1850
1851         insert->next = iter->next;
1852         iter->next = insert;
1853     }
1854
1855     /* update type data size */
1856     This->typedata->next->u.val += 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
1857
1858     /* Increment the number of function elements */
1859     This->typeinfo->cElement += 1;
1860
1861     return S_OK;
1862 }
1863
1864 /******************************************************************************
1865  * ICreateTypeInfo2_AddImplType {OLEAUT32}
1866  *
1867  *  See ICreateTypeInfo_AddImplType.
1868  */
1869 static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
1870         ICreateTypeInfo2* iface,
1871         UINT index,
1872         HREFTYPE hRefType)
1873 {
1874     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1875
1876     TRACE("(%p,%d,%d)\n", iface, index, hRefType);
1877
1878     if (This->typekind == TKIND_COCLASS) {
1879         int offset;
1880         MSFT_RefRecord *ref;
1881
1882         if (index == 0) {
1883             if (This->typeinfo->datatype1 != -1) return TYPE_E_ELEMENTNOTFOUND;
1884
1885             offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
1886             if (offset == -1) return E_OUTOFMEMORY;
1887
1888             This->typeinfo->datatype1 = offset;
1889         } else {
1890             int lastoffset;
1891
1892             lastoffset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index - 1);
1893             if (lastoffset == -1) return TYPE_E_ELEMENTNOTFOUND;
1894
1895             ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][lastoffset];
1896             if (ref->onext != -1) return TYPE_E_ELEMENTNOTFOUND;
1897
1898             offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
1899             if (offset == -1) return E_OUTOFMEMORY;
1900
1901             ref->onext = offset;
1902         }
1903
1904         ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
1905
1906         ref->reftype = hRefType;
1907         ref->flags = 0;
1908         ref->oCustData = -1;
1909         ref->onext = -1;
1910         This->typeinfo->cImplTypes++;
1911     } else if (This->typekind == TKIND_INTERFACE) {
1912         if (This->typeinfo->cImplTypes && index==1)
1913             return TYPE_E_BADMODULEKIND;
1914
1915         if( index != 0)  return TYPE_E_ELEMENTNOTFOUND;
1916
1917         This->typeinfo->datatype1 = hRefType;
1918         This->typeinfo->cImplTypes = 1;
1919     } else if (This->typekind == TKIND_DISPATCH) {
1920         if(index != 0) return TYPE_E_ELEMENTNOTFOUND;
1921
1922         /* FIXME: Check if referenced typeinfo is IDispatch */
1923         This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
1924         This->typeinfo->cImplTypes = 1;
1925     } else {
1926         FIXME("AddImplType unsupported on typekind %d\n", This->typekind);
1927         return E_OUTOFMEMORY;
1928     }
1929
1930     return S_OK;
1931 }
1932
1933 /******************************************************************************
1934  * ICreateTypeInfo2_SetImplTypeFlags {OLEAUT32}
1935  *
1936  *  See ICreateTypeInfo_SetImplTypeFlags.
1937  */
1938 static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(
1939         ICreateTypeInfo2* iface,
1940         UINT index,
1941         INT implTypeFlags)
1942 {
1943     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1944     int offset;
1945     MSFT_RefRecord *ref;
1946
1947     TRACE("(%p,%d,0x%x)\n", iface, index, implTypeFlags);
1948
1949     if (This->typekind != TKIND_COCLASS) {
1950         return TYPE_E_BADMODULEKIND;
1951     }
1952
1953     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
1954     if (offset == -1) return TYPE_E_ELEMENTNOTFOUND;
1955
1956     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
1957     ref->flags = implTypeFlags;
1958
1959     return S_OK;
1960 }
1961
1962 /******************************************************************************
1963  * ICreateTypeInfo2_SetAlignment {OLEAUT32}
1964  *
1965  *  See ICreateTypeInfo_SetAlignment.
1966  */
1967 static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(
1968         ICreateTypeInfo2* iface,
1969         WORD cbAlignment)
1970 {
1971     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
1972
1973     TRACE("(%p,%d)\n", iface, cbAlignment);
1974
1975     if (!cbAlignment) return E_INVALIDARG;
1976     if (cbAlignment > 16) return E_INVALIDARG;
1977
1978     This->typeinfo->typekind &= ~0xffc0;
1979     This->typeinfo->typekind |= cbAlignment << 6;
1980
1981     /* FIXME: There's probably some way to simplify this. */
1982     switch (This->typekind) {
1983     case TKIND_ALIAS:
1984     default:
1985         break;
1986
1987     case TKIND_ENUM:
1988     case TKIND_INTERFACE:
1989     case TKIND_DISPATCH:
1990     case TKIND_COCLASS:
1991         if (cbAlignment > 4) cbAlignment = 4;
1992         break;
1993
1994     case TKIND_RECORD:
1995     case TKIND_MODULE:
1996     case TKIND_UNION:
1997         cbAlignment = 1;
1998         break;
1999     }
2000
2001     This->typeinfo->typekind |= cbAlignment << 11;
2002
2003     return S_OK;
2004 }
2005
2006 /******************************************************************************
2007  * ICreateTypeInfo2_SetSchema {OLEAUT32}
2008  *
2009  *  See ICreateTypeInfo_SetSchema.
2010  */
2011 static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(
2012         ICreateTypeInfo2* iface,
2013         LPOLESTR pStrSchema)
2014 {
2015     FIXME("(%p,%s), stub!\n", iface, debugstr_w(pStrSchema));
2016     return E_OUTOFMEMORY;
2017 }
2018
2019 /******************************************************************************
2020  * ICreateTypeInfo2_AddVarDesc {OLEAUT32}
2021  *
2022  *  See ICreateTypeInfo_AddVarDesc.
2023  */
2024 static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
2025         ICreateTypeInfo2* iface,
2026         UINT index,
2027         VARDESC* pVarDesc)
2028 {
2029     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2030
2031     HRESULT status = S_OK;
2032     CyclicList *insert;
2033     INT *typedata;
2034     int var_datawidth;
2035     int var_alignment;
2036     int var_type_size;
2037     int alignment;
2038
2039     TRACE("(%p,%d,%p), stub!\n", iface, index, pVarDesc);
2040     TRACE("%d, %p, %d, {{%x, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst,
2041           pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt,
2042           pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags,
2043           pVarDesc->wVarFlags, pVarDesc->varkind);
2044
2045     if ((This->typeinfo->cElement >> 16) != index) {
2046         TRACE("Out-of-order element.\n");
2047         return TYPE_E_ELEMENTNOTFOUND;
2048     }
2049
2050     if (!This->typedata) {
2051         This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
2052         if(!This->typedata)
2053             return E_OUTOFMEMORY;
2054
2055         This->typedata->next = This->typedata;
2056         This->typedata->u.val = 0;
2057
2058         if(This->dual)
2059             This->dual->typedata = This->typedata;
2060     }
2061
2062     /* allocate type data space for us */
2063     insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
2064     if(!insert)
2065         return E_OUTOFMEMORY;
2066     insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[5]));
2067     if(!insert->u.data) {
2068         HeapFree(GetProcessHeap(), 0, insert);
2069         return E_OUTOFMEMORY;
2070     }
2071
2072     insert->next = This->typedata->next;
2073     This->typedata->next = insert;
2074     This->typedata = insert;
2075
2076     if(This->dual)
2077         This->dual->typedata = This->typedata;
2078
2079     This->typedata->next->u.val += 0x14;
2080     typedata = This->typedata->u.data;
2081
2082     /* fill out the basic type information */
2083     typedata[0] = 0x14 | (index << 16);
2084     typedata[2] = pVarDesc->wVarFlags;
2085     typedata[3] = (sizeof(VARDESC) << 16) | pVarDesc->varkind;
2086
2087     /* update the index data */
2088     insert->indice = 0x40000000 + index;
2089     insert->name = -1;
2090     insert->type = CyclicListVar;
2091
2092     /* figure out type widths and whatnot */
2093     ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc,
2094                          &typedata[1], &var_datawidth, &var_alignment,
2095                          &var_type_size);
2096
2097     if (pVarDesc->varkind != VAR_CONST)
2098     {
2099         /* pad out starting position to data width */
2100         This->datawidth += var_alignment - 1;
2101         This->datawidth &= ~(var_alignment - 1);
2102         typedata[4] = This->datawidth;
2103
2104         /* add the new variable to the total data width */
2105         This->datawidth += var_datawidth;
2106         if(This->dual)
2107             This->dual->datawidth = This->datawidth;
2108
2109         /* add type description size to total required allocation */
2110         typedata[3] += var_type_size << 16;
2111
2112         /* fix type alignment */
2113         alignment = (This->typeinfo->typekind >> 11) & 0x1f;
2114         if (alignment < var_alignment) {
2115             alignment = var_alignment;
2116             This->typeinfo->typekind &= ~0xf800;
2117             This->typeinfo->typekind |= alignment << 11;
2118         }
2119
2120         /* ??? */
2121         if (!This->typeinfo->res2) This->typeinfo->res2 = 0x1a;
2122         if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) {
2123             This->typeinfo->res2 <<= 1;
2124         }
2125
2126         /* ??? */
2127         if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0;
2128         This->typeinfo->res3 += 0x2c;
2129
2130         /* pad data width to alignment */
2131         This->typeinfo->size = (This->datawidth + (alignment - 1)) & ~(alignment - 1);
2132     } else {
2133         VARIANT *value = pVarDesc->DUMMYUNIONNAME.lpvarValue;
2134         status = ctl2_encode_variant(This->typelib, typedata+4, value, V_VT(value));
2135         /* ??? native sets size 0x34 */
2136         typedata[3] += 0x10 << 16;
2137     }
2138
2139     /* increment the number of variable elements */
2140     This->typeinfo->cElement += 0x10000;
2141
2142     return status;
2143 }
2144
2145 /******************************************************************************
2146  * ICreateTypeInfo2_SetFuncAndParamNames {OLEAUT32}
2147  *
2148  *  See ICreateTypeInfo_SetFuncAndParamNames.
2149  */
2150 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(
2151         ICreateTypeInfo2* iface,
2152         UINT index,
2153         LPOLESTR* rgszNames,
2154         UINT cNames)
2155 {
2156     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2157     CyclicList *iter = NULL, *iter2;
2158     int offset, len, i=0;
2159     char *namedata;
2160
2161     TRACE("(%p %d %p %d)\n", iface, index, rgszNames, cNames);
2162
2163     if(!rgszNames)
2164         return E_INVALIDARG;
2165
2166     if(index >= (This->typeinfo->cElement&0xFFFF) || !cNames)
2167         return TYPE_E_ELEMENTNOTFOUND;
2168
2169     for(iter=This->typedata->next->next, i=0; /* empty */; iter=iter->next)
2170         if (iter->type == CyclicListFunc)
2171             if (i++ >= index)
2172                 break;
2173
2174     /* cNames == cParams for put or putref accessor, cParams+1 otherwise */
2175     if(cNames != iter->u.data[5] + ((iter->u.data[4]>>3)&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1))
2176         return TYPE_E_ELEMENTNOTFOUND;
2177
2178     len = ctl2_encode_name(This->typelib, rgszNames[0], &namedata);
2179     for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
2180         if(iter2->name!=-1 && !memcmp(namedata,
2181                     This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len)) {
2182             /* getters/setters can have a same name */
2183             if (iter2->type == CyclicListFunc) {
2184                 INT inv1 = iter2->u.data[4] >> 3;
2185                 INT inv2 = iter->u.data[4] >> 3;
2186                 if (((inv1&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && (inv2&INVOKE_PROPERTYGET)) ||
2187                     ((inv2&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && (inv1&INVOKE_PROPERTYGET)))
2188                     continue;
2189             }
2190
2191             return TYPE_E_AMBIGUOUSNAME;
2192         }
2193     }
2194
2195     offset = ctl2_alloc_name(This->typelib, rgszNames[0]);
2196     if(offset == -1)
2197         return E_OUTOFMEMORY;
2198
2199     iter->name = offset;
2200
2201     namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
2202     if (*((INT*)namedata) == -1)
2203             *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
2204
2205     len = iter->u.data[0]/4 - iter->u.data[5]*3;
2206
2207     for (i = 1; i < cNames; i++) {
2208         offset = ctl2_alloc_name(This->typelib, rgszNames[i]);
2209         iter->u.data[len + ((i-1)*3) + 1] = offset;
2210     }
2211
2212     return S_OK;
2213 }
2214
2215 /******************************************************************************
2216  * ICreateTypeInfo2_SetVarName {OLEAUT32}
2217  *
2218  *  See ICreateTypeInfo_SetVarName.
2219  */
2220 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(
2221         ICreateTypeInfo2* iface,
2222         UINT index,
2223         LPOLESTR szName)
2224 {
2225     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2226     CyclicList *iter;
2227     int offset, i;
2228     char *namedata;
2229
2230     TRACE("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szName));
2231
2232     if ((This->typeinfo->cElement >> 16) <= index) {
2233         TRACE("Out-of-order element.\n");
2234         return TYPE_E_ELEMENTNOTFOUND;
2235     }
2236
2237     offset = ctl2_alloc_name(This->typelib, szName);
2238     if (offset == -1) return E_OUTOFMEMORY;
2239
2240     namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
2241     if (*((INT *)namedata) == -1) {
2242         *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
2243         namedata[9] |= 0x10;
2244     }
2245     if (This->typekind == TKIND_ENUM) {
2246         namedata[9] |= 0x20;
2247     }
2248
2249     for(iter = This->typedata->next->next, i = 0; /* empty */; iter = iter->next)
2250         if (iter->type == CyclicListVar)
2251             if (i++ >= index)
2252                 break;
2253
2254     iter->name = offset;
2255     return S_OK;
2256 }
2257
2258 /******************************************************************************
2259  * ICreateTypeInfo2_SetTypeDescAlias {OLEAUT32}
2260  *
2261  *  See ICreateTypeInfo_SetTypeDescAlias.
2262  */
2263 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(
2264         ICreateTypeInfo2* iface,
2265         TYPEDESC* pTDescAlias)
2266 {
2267     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2268
2269     int encoded_typedesc;
2270     int width;
2271
2272     if (This->typekind != TKIND_ALIAS) {
2273         return TYPE_E_WRONGTYPEKIND;
2274     }
2275
2276     FIXME("(%p,%p), hack!\n", iface, pTDescAlias);
2277
2278     if (ctl2_encode_typedesc(This->typelib, pTDescAlias, &encoded_typedesc, &width, NULL, NULL) == -1) {
2279         return E_OUTOFMEMORY;
2280     }
2281
2282     This->typeinfo->size = width;
2283     This->typeinfo->datatype1 = encoded_typedesc;
2284
2285     return S_OK;
2286 }
2287
2288 /******************************************************************************
2289  * ICreateTypeInfo2_DefineFuncAsDllEntry {OLEAUT32}
2290  *
2291  *  See ICreateTypeInfo_DefineFuncAsDllEntry.
2292  */
2293 static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(
2294         ICreateTypeInfo2* iface,
2295         UINT index,
2296         LPOLESTR szDllName,
2297         LPOLESTR szProcName)
2298 {
2299     FIXME("(%p,%d,%s,%s), stub!\n", iface, index, debugstr_w(szDllName), debugstr_w(szProcName));
2300     return E_OUTOFMEMORY;
2301 }
2302
2303 /******************************************************************************
2304  * ICreateTypeInfo2_SetFuncDocString {OLEAUT32}
2305  *
2306  *  See ICreateTypeInfo_SetFuncDocString.
2307  */
2308 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(
2309         ICreateTypeInfo2* iface,
2310         UINT index,
2311         LPOLESTR szDocString)
2312 {
2313     FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString));
2314     return E_OUTOFMEMORY;
2315 }
2316
2317 /******************************************************************************
2318  * ICreateTypeInfo2_SetVarDocString {OLEAUT32}
2319  *
2320  *  See ICreateTypeInfo_SetVarDocString.
2321  */
2322 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(
2323         ICreateTypeInfo2* iface,
2324         UINT index,
2325         LPOLESTR szDocString)
2326 {
2327     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2328
2329     FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString));
2330
2331     ctl2_alloc_string(This->typelib, szDocString);
2332
2333     return E_OUTOFMEMORY;
2334 }
2335
2336 /******************************************************************************
2337  * ICreateTypeInfo2_SetFuncHelpContext {OLEAUT32}
2338  *
2339  *  See ICreateTypeInfo_SetFuncHelpContext.
2340  */
2341 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(
2342         ICreateTypeInfo2* iface,
2343         UINT index,
2344         DWORD dwHelpContext)
2345 {
2346     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2347     CyclicList *func;
2348
2349     TRACE("(%p,%d,%d)\n", iface, index, dwHelpContext);
2350
2351     if(This->typeinfo->cElement<index)
2352         return TYPE_E_ELEMENTNOTFOUND;
2353
2354     if(This->typeinfo->cElement == index && This->typedata->type == CyclicListFunc)
2355         func = This->typedata;
2356     else
2357         for(func=This->typedata->next->next; func!=This->typedata; func=func->next)
2358             if (func->type == CyclicListFunc)
2359                 if(index-- == 0)
2360                     break;
2361
2362     This->typedata->next->u.val += funcrecord_reallochdr(&func->u.data, 7*sizeof(int));
2363     if(!func->u.data)
2364         return E_OUTOFMEMORY;
2365
2366     func->u.data[6] = dwHelpContext;
2367     return S_OK;
2368 }
2369
2370 /******************************************************************************
2371  * ICreateTypeInfo2_SetVarHelpContext {OLEAUT32}
2372  *
2373  *  See ICreateTypeInfo_SetVarHelpContext.
2374  */
2375 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(
2376         ICreateTypeInfo2* iface,
2377         UINT index,
2378         DWORD dwHelpContext)
2379 {
2380     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpContext);
2381     return E_OUTOFMEMORY;
2382 }
2383
2384 /******************************************************************************
2385  * ICreateTypeInfo2_SetMops {OLEAUT32}
2386  *
2387  *  See ICreateTypeInfo_SetMops.
2388  */
2389 static HRESULT WINAPI ICreateTypeInfo2_fnSetMops(
2390         ICreateTypeInfo2* iface,
2391         UINT index,
2392         BSTR bstrMops)
2393 {
2394     FIXME("(%p,%d,%p), stub!\n", iface, index, bstrMops);
2395     return E_OUTOFMEMORY;
2396 }
2397
2398 /******************************************************************************
2399  * ICreateTypeInfo2_SetTypeIdldesc {OLEAUT32}
2400  *
2401  *  See ICreateTypeInfo_SetTypeIdldesc.
2402  */
2403 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(
2404         ICreateTypeInfo2* iface,
2405         IDLDESC* pIdlDesc)
2406 {
2407     FIXME("(%p,%p), stub!\n", iface, pIdlDesc);
2408     return E_OUTOFMEMORY;
2409 }
2410
2411 /******************************************************************************
2412  * ICreateTypeInfo2_LayOut {OLEAUT32}
2413  *
2414  *  See ICreateTypeInfo_LayOut.
2415  */
2416 static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
2417         ICreateTypeInfo2* iface)
2418 {
2419     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2420     CyclicList *iter, *iter2, *last = NULL, **typedata;
2421     HREFTYPE hreftype;
2422     HRESULT hres;
2423     unsigned user_vft = 0;
2424     int i;
2425
2426     TRACE("(%p)\n", iface);
2427
2428     /* FIXME: LayOut should be run on all ImplTypes */
2429     if(This->typekind == TKIND_COCLASS)
2430         return S_OK;
2431
2432     /* Validate inheritance */
2433     This->typeinfo->datatype2 = 0;
2434     hreftype = This->typeinfo->datatype1;
2435
2436     /* Process internally defined interfaces */
2437     for(i=0; i<This->typelib->typelib_header.nrtypeinfos; i++) {
2438         MSFT_TypeInfoBase *header;
2439
2440         if(hreftype&1)
2441             break;
2442
2443         header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]);
2444         This->typeinfo->datatype2 += (header->cElement<<16) + 1;
2445         hreftype = header->datatype1;
2446     }
2447     if(i == This->typelib->typelib_header.nrtypeinfos)
2448         return TYPE_E_CIRCULARTYPE;
2449
2450     /* Process externally defined interfaces */
2451     if(hreftype != -1) {
2452         ITypeInfo *cur, *next;
2453         TYPEATTR *typeattr;
2454
2455         hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next);
2456         if(FAILED(hres))
2457             return hres;
2458
2459         hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur);
2460         ITypeInfo_Release(next);
2461         if(FAILED(hres))
2462             return hres;
2463
2464
2465         while(1) {
2466             hres = ITypeInfo_GetTypeAttr(cur, &typeattr);
2467             if(FAILED(hres)) {
2468                 ITypeInfo_Release(cur);
2469                 return hres;
2470             }
2471
2472             if(IsEqualGUID(&typeattr->guid, &IID_IDispatch))
2473                 This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
2474
2475             This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1;
2476             ITypeInfo_ReleaseTypeAttr(cur, typeattr);
2477
2478             hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype);
2479             if(hres == TYPE_E_ELEMENTNOTFOUND)
2480                 break;
2481             if(FAILED(hres)) {
2482                 ITypeInfo_Release(cur);
2483                 return hres;
2484             }
2485
2486             hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next);
2487             if(FAILED(hres)) {
2488                 ITypeInfo_Release(cur);
2489                 return hres;
2490             }
2491
2492             ITypeInfo_Release(cur);
2493             cur = next;
2494         }
2495         ITypeInfo_Release(cur);
2496     }
2497
2498     /* Get cbSizeVft of inherited interface */
2499     /* Makes LayOut running recursively */
2500     if(This->typeinfo->datatype1 != -1) {
2501         ITypeInfo *cur, *inherited;
2502         TYPEATTR *typeattr;
2503
2504         hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&cur);
2505         if(FAILED(hres))
2506             return hres;
2507
2508         hres = ITypeInfo_GetRefTypeInfo(cur, This->typeinfo->datatype1, &inherited);
2509         ITypeInfo_Release(cur);
2510         if(FAILED(hres))
2511             return hres;
2512
2513         hres = ITypeInfo_GetTypeAttr(inherited, &typeattr);
2514         if(FAILED(hres)) {
2515             ITypeInfo_Release(inherited);
2516             return hres;
2517         }
2518
2519         This->typeinfo->cbSizeVft = typeattr->cbSizeVft * 4 / sizeof(void *);
2520
2521         ITypeInfo_ReleaseTypeAttr(inherited, typeattr);
2522         ITypeInfo_Release(inherited);
2523     } else
2524         This->typeinfo->cbSizeVft = 0;
2525
2526     if(!This->typedata)
2527         return S_OK;
2528
2529     typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff));
2530     if(!typedata)
2531         return E_OUTOFMEMORY;
2532
2533     /* Assign IDs and VTBL entries */
2534     for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next)
2535         if (iter->type == CyclicListFunc)
2536             last = iter;
2537
2538     if(last && last->u.data[3]&1)
2539         user_vft = last->u.data[3]&0xffff;
2540
2541     i = 0;
2542     for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
2543         /* Assign MEMBERID if MEMBERID_NIL was specified */
2544         if(iter->indice == MEMBERID_NIL) {
2545             iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16);
2546
2547             for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
2548                 if(iter == iter2) continue;
2549                 if(iter2->indice == iter->indice) {
2550                     iter->indice = 0x5fffffff + This->typeinfo->cElement + i + (This->typeinfo->datatype2<<16);
2551
2552                     for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
2553                         if(iter == iter2) continue;
2554                         if(iter2->indice == iter->indice) {
2555                             HeapFree(GetProcessHeap(), 0, typedata);
2556                             return E_ACCESSDENIED;
2557                         }
2558                     }
2559
2560                     break;
2561                 }
2562             }
2563         }
2564
2565         if (iter->type != CyclicListFunc)
2566             continue;
2567
2568         typedata[i] = iter;
2569
2570         iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16);
2571
2572         if((iter->u.data[3]&1) != (user_vft&1)) {
2573             HeapFree(GetProcessHeap(), 0, typedata);
2574             return TYPE_E_INVALIDID;
2575         }
2576
2577         if(user_vft&1) {
2578             if(user_vft < (iter->u.data[3]&0xffff))
2579                 user_vft = (iter->u.data[3]&0xffff);
2580
2581             if((iter->u.data[3]&0xffff) < This->typeinfo->cbSizeVft) {
2582                 HeapFree(GetProcessHeap(), 0, typedata);
2583                 return TYPE_E_INVALIDID;
2584             }
2585         } else if(This->typekind != TKIND_MODULE) {
2586             iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft;
2587             This->typeinfo->cbSizeVft += 4;
2588         }
2589
2590         /* Construct a list of elements with the same memberid */
2591         iter->u.data[4] = (iter->u.data[4]&0xffff) | (i<<16);
2592         for(iter2=This->typedata->next->next; iter2!=iter; iter2=iter2->next) {
2593             if(iter->indice == iter2->indice) {
2594                 int v1, v2;
2595
2596                 v1 = iter->u.data[4] >> 16;
2597                 v2 = iter2->u.data[4] >> 16;
2598
2599                 iter->u.data[4] = (iter->u.data[4]&0xffff) | (v2<<16);
2600                 iter2->u.data[4] = (iter2->u.data[4]&0xffff) | (v1<<16);
2601                 break;
2602             }
2603         }
2604
2605         i++;
2606     }
2607
2608     if(user_vft)
2609         This->typeinfo->cbSizeVft = user_vft+3;
2610
2611     for(i=0; i<(This->typeinfo->cElement&0xffff); i++) {
2612         if(typedata[i]->u.data[4]>>16 > i) {
2613             int inv;
2614
2615             inv = (typedata[i]->u.data[4]>>3) & 0xf;
2616             i = typedata[i]->u.data[4] >> 16;
2617
2618             while(i > typedata[i]->u.data[4]>>16) {
2619                 int invkind = (typedata[i]->u.data[4]>>3) & 0xf;
2620
2621                 if(inv & invkind) {
2622                     HeapFree(GetProcessHeap(), 0, typedata);
2623                     return TYPE_E_DUPLICATEID;
2624                 }
2625
2626                 i = typedata[i]->u.data[4] >> 16;
2627                 inv |= invkind;
2628             }
2629
2630             if(inv & INVOKE_FUNC) {
2631                 HeapFree(GetProcessHeap(), 0, typedata);
2632                 return TYPE_E_INCONSISTENTPROPFUNCS;
2633             }
2634         }
2635     }
2636
2637     HeapFree(GetProcessHeap(), 0, typedata);
2638     return S_OK;
2639 }
2640
2641 /******************************************************************************
2642  * ICreateTypeInfo2_DeleteFuncDesc {OLEAUT32}
2643  *
2644  *  Delete a function description from a type.
2645  *
2646  * RETURNS
2647  *
2648  *  Success: S_OK.
2649  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2650  */
2651 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(
2652         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */
2653         UINT index)              /* [I] The index of the function to delete. */
2654 {
2655     FIXME("(%p,%d), stub!\n", iface, index);
2656     return E_OUTOFMEMORY;
2657 }
2658
2659 /******************************************************************************
2660  * ICreateTypeInfo2_DeleteFuncDescByMemId {OLEAUT32}
2661  *
2662  *  Delete a function description from a type.
2663  *
2664  * RETURNS
2665  *
2666  *  Success: S_OK.
2667  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2668  */
2669 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(
2670         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */
2671         MEMBERID memid,          /* [I] The member id of the function to delete. */
2672         INVOKEKIND invKind)      /* [I] The invocation type of the function to delete. (?) */
2673 {
2674     FIXME("(%p,%d,%d), stub!\n", iface, memid, invKind);
2675     return E_OUTOFMEMORY;
2676 }
2677
2678 /******************************************************************************
2679  * ICreateTypeInfo2_DeleteVarDesc {OLEAUT32}
2680  *
2681  *  Delete a variable description from a type.
2682  *
2683  * RETURNS
2684  *
2685  *  Success: S_OK.
2686  *  Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR,
2687  *  TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE.
2688  */
2689 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc(
2690         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
2691         UINT index)              /* [I] The index of the variable description to delete. */
2692 {
2693     FIXME("(%p,%d), stub!\n", iface, index);
2694     return E_OUTOFMEMORY;
2695 }
2696
2697 /******************************************************************************
2698  * ICreateTypeInfo2_DeleteVarDescByMemId {OLEAUT32}
2699  *
2700  *  Delete a variable description from a type.
2701  *
2702  * RETURNS
2703  *
2704  *  Success: S_OK.
2705  *  Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR,
2706  *  TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE.
2707  */
2708 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(
2709         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
2710         MEMBERID memid)          /* [I] The member id of the variable description to delete. */
2711 {
2712     FIXME("(%p,%d), stub!\n", iface, memid);
2713     return E_OUTOFMEMORY;
2714 }
2715
2716 /******************************************************************************
2717  * ICreateTypeInfo2_DeleteImplType {OLEAUT32}
2718  *
2719  *  Delete an interface implementation from a type. (?)
2720  *
2721  * RETURNS
2722  *
2723  *  Success: S_OK.
2724  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2725  */
2726 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(
2727         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete. */
2728         UINT index)              /* [I] The index of the interface to delete. */
2729 {
2730     FIXME("(%p,%d), stub!\n", iface, index);
2731     return E_OUTOFMEMORY;
2732 }
2733
2734 /******************************************************************************
2735  * ICreateTypeInfo2_SetCustData {OLEAUT32}
2736  *
2737  *  Set the custom data for a type.
2738  *
2739  * RETURNS
2740  *
2741  *  Success: S_OK.
2742  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2743  */
2744 static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(
2745         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
2746         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2747         VARIANT* pVarVal)        /* [I] The custom data. */
2748 {
2749     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2750
2751     TRACE("(%p,%s,%p)!\n", iface, debugstr_guid(guid), pVarVal);
2752
2753     if (!pVarVal)
2754             return E_INVALIDARG;
2755
2756     return ctl2_set_custdata(This->typelib, guid, pVarVal, &This->typeinfo->oCustData);
2757 }
2758
2759 /******************************************************************************
2760  * ICreateTypeInfo2_SetFuncCustData {OLEAUT32}
2761  *
2762  *  Set the custom data for a function.
2763  *
2764  * RETURNS
2765  *
2766  *  Success: S_OK.
2767  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2768  */
2769 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(
2770         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
2771         UINT index,              /* [I] The index of the function for which to set the custom data. */
2772         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2773         VARIANT* pVarVal)        /* [I] The custom data. */
2774 {
2775     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
2776     CyclicList *iter;
2777
2778     TRACE("(%p,%d,%s,%p)\n", iface, index, debugstr_guid(guid), pVarVal);
2779
2780     if(index >= (This->typeinfo->cElement&0xFFFF))
2781         return TYPE_E_ELEMENTNOTFOUND;
2782
2783     for(iter=This->typedata->next->next; /* empty */; iter=iter->next)
2784         if (iter->type == CyclicListFunc)
2785             if (index-- == 0)
2786                 break;
2787
2788     This->typedata->next->u.val += funcrecord_reallochdr(&iter->u.data, 13*sizeof(int));
2789     if(!iter->u.data)
2790         return E_OUTOFMEMORY;
2791
2792     iter->u.data[4] |= 0x80;
2793     return ctl2_set_custdata(This->typelib, guid, pVarVal, &iter->u.data[12]);
2794 }
2795
2796 /******************************************************************************
2797  * ICreateTypeInfo2_SetParamCustData {OLEAUT32}
2798  *
2799  *  Set the custom data for a function parameter.
2800  *
2801  * RETURNS
2802  *
2803  *  Success: S_OK.
2804  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2805  */
2806 static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(
2807         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
2808         UINT indexFunc,          /* [I] The index of the function on which the parameter resides. */
2809         UINT indexParam,         /* [I] The index of the parameter on which to set the custom data. */
2810         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2811         VARIANT* pVarVal)        /* [I] The custom data. */
2812 {
2813     FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
2814     return E_OUTOFMEMORY;
2815 }
2816
2817 /******************************************************************************
2818  * ICreateTypeInfo2_SetVarCustData {OLEAUT32}
2819  *
2820  *  Set the custom data for a variable.
2821  *
2822  * RETURNS
2823  *
2824  *  Success: S_OK.
2825  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2826  */
2827 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData(
2828         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
2829         UINT index,              /* [I] The index of the variable on which to set the custom data. */
2830         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2831         VARIANT* pVarVal)        /* [I] The custom data. */
2832 {
2833     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
2834     return E_OUTOFMEMORY;
2835 }
2836
2837 /******************************************************************************
2838  * ICreateTypeInfo2_SetImplTypeCustData {OLEAUT32}
2839  *
2840  *  Set the custom data for an implemented interface.
2841  *
2842  * RETURNS
2843  *
2844  *  Success: S_OK.
2845  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2846  */
2847 static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData(
2848         ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the custom data. */
2849         UINT index,              /* [I] The index of the implemented interface on which to set the custom data. */
2850         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
2851         VARIANT* pVarVal)        /* [I] The custom data. */
2852 {
2853     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
2854     return E_OUTOFMEMORY;
2855 }
2856
2857 /******************************************************************************
2858  * ICreateTypeInfo2_SetHelpStringContext {OLEAUT32}
2859  *
2860  *  Set the help string context for the typeinfo.
2861  *
2862  * RETURNS
2863  *
2864  *  Success: S_OK.
2865  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2866  */
2867 static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(
2868         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
2869         ULONG dwHelpStringContext) /* [I] The help string context. */
2870 {
2871     FIXME("(%p,%d), stub!\n", iface, dwHelpStringContext);
2872     return E_OUTOFMEMORY;
2873 }
2874
2875 /******************************************************************************
2876  * ICreateTypeInfo2_SetFuncHelpStringContext {OLEAUT32}
2877  *
2878  *  Set the help string context for a function.
2879  *
2880  * RETURNS
2881  *
2882  *  Success: S_OK.
2883  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2884  */
2885 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(
2886         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
2887         UINT index,                /* [I] The index for the function on which to set the help string context. */
2888         ULONG dwHelpStringContext) /* [I] The help string context. */
2889 {
2890     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
2891     return E_OUTOFMEMORY;
2892 }
2893
2894 /******************************************************************************
2895  * ICreateTypeInfo2_SetVarHelpStringContext {OLEAUT32}
2896  *
2897  *  Set the help string context for a variable.
2898  *
2899  * RETURNS
2900  *
2901  *  Success: S_OK.
2902  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
2903  */
2904 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(
2905         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
2906         UINT index,                /* [I] The index of the variable on which to set the help string context. */
2907         ULONG dwHelpStringContext) /* [I] The help string context */
2908 {
2909     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
2910     return E_OUTOFMEMORY;
2911 }
2912
2913 /******************************************************************************
2914  * ICreateTypeInfo2_Invalidate {OLEAUT32}
2915  *
2916  *  Undocumented function. (!)
2917  */
2918 static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate(
2919         ICreateTypeInfo2* iface)
2920 {
2921     FIXME("(%p), stub!\n", iface);
2922     return E_OUTOFMEMORY;
2923 }
2924
2925 /******************************************************************************
2926  * ICreateTypeInfo2_SetName {OLEAUT32}
2927  *
2928  *  Set the name for a typeinfo.
2929  *
2930  * RETURNS
2931  *
2932  *  Success: S_OK.
2933  *  Failure: One of STG_E_INSUFFICIENTMEMORY, E_OUTOFMEMORY, E_INVALIDARG or TYPE_E_INVALIDSTATE.
2934  */
2935 static HRESULT WINAPI ICreateTypeInfo2_fnSetName(
2936         ICreateTypeInfo2* iface,
2937         LPOLESTR szName)
2938 {
2939     FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
2940     return E_OUTOFMEMORY;
2941 }
2942
2943 /*================== ITypeInfo2 Implementation ===================================*/
2944
2945 /******************************************************************************
2946  * ITypeInfo2_QueryInterface {OLEAUT32}
2947  *
2948  *  See IUnknown_QueryInterface.
2949  */
2950 static HRESULT WINAPI ITypeInfo2_fnQueryInterface(ITypeInfo2 * iface, REFIID riid, LPVOID * ppv)
2951 {
2952     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
2953
2954     return ICreateTypeInfo2_QueryInterface((ICreateTypeInfo2 *)This, riid, ppv);
2955 }
2956
2957 /******************************************************************************
2958  * ITypeInfo2_AddRef {OLEAUT32}
2959  *
2960  *  See IUnknown_AddRef.
2961  */
2962 static ULONG WINAPI ITypeInfo2_fnAddRef(ITypeInfo2 * iface)
2963 {
2964     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
2965
2966     return ICreateTypeInfo2_AddRef((ICreateTypeInfo2 *)This);
2967 }
2968
2969 /******************************************************************************
2970  * ITypeInfo2_Release {OLEAUT32}
2971  *
2972  *  See IUnknown_Release.
2973  */
2974 static ULONG WINAPI ITypeInfo2_fnRelease(ITypeInfo2 * iface)
2975 {
2976     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
2977
2978     return ICreateTypeInfo2_Release((ICreateTypeInfo2 *)This);
2979 }
2980
2981 /******************************************************************************
2982  * ITypeInfo2_GetTypeAttr {OLEAUT32}
2983  *
2984  *  See ITypeInfo_GetTypeAttr.
2985  */
2986 static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr(
2987         ITypeInfo2* iface,
2988         TYPEATTR** ppTypeAttr)
2989 {
2990     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
2991     HRESULT hres;
2992
2993     TRACE("(%p,%p)\n", iface, ppTypeAttr);
2994
2995     if(!ppTypeAttr)
2996         return E_INVALIDARG;
2997
2998     hres = ICreateTypeInfo_LayOut((ICreateTypeInfo*)This);
2999     if(FAILED(hres))
3000         return hres;
3001
3002     *ppTypeAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEATTR));
3003     if(!*ppTypeAttr)
3004         return E_OUTOFMEMORY;
3005
3006     if(This->typeinfo->posguid != -1) {
3007         MSFT_GuidEntry *guid;
3008
3009         guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][This->typeinfo->posguid];
3010         (*ppTypeAttr)->guid = guid->guid;
3011     }
3012
3013     (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid;
3014     (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size;
3015     (*ppTypeAttr)->typekind = This->typekind;
3016     (*ppTypeAttr)->cFuncs = This->typeinfo->cElement&0xffff;
3017     if(This->typeinfo->flags&TYPEFLAG_FDUAL && This->typekind==TKIND_DISPATCH)
3018         (*ppTypeAttr)->cFuncs += 7;
3019     (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16;
3020     (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes;
3021     (*ppTypeAttr)->cbSizeVft = This->typekind==TKIND_DISPATCH ? 7 * sizeof(void*) : This->typeinfo->cbSizeVft;
3022     (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f;
3023     (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags;
3024     (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff;
3025     (*ppTypeAttr)->wMinorVerNum = This->typeinfo->version>>16;
3026
3027     if((*ppTypeAttr)->typekind == TKIND_ALIAS)
3028         FIXME("TKIND_ALIAS handling not implemented\n");
3029
3030     return S_OK;
3031 }
3032
3033 /******************************************************************************
3034  * ITypeInfo2_GetTypeComp {OLEAUT32}
3035  *
3036  *  See ITypeInfo_GetTypeComp.
3037  */
3038 static HRESULT WINAPI ITypeInfo2_fnGetTypeComp(
3039         ITypeInfo2* iface,
3040         ITypeComp** ppTComp)
3041 {
3042     FIXME("(%p,%p), stub!\n", iface, ppTComp);
3043     return E_OUTOFMEMORY;
3044 }
3045
3046 /******************************************************************************
3047  * ITypeInfo2_GetFuncDesc {OLEAUT32}
3048  *
3049  *  See ITypeInfo_GetFuncDesc.
3050  */
3051 static HRESULT WINAPI ITypeInfo2_fnGetFuncDesc(
3052         ITypeInfo2* iface,
3053         UINT index,
3054         FUNCDESC** ppFuncDesc)
3055 {
3056     FIXME("(%p,%d,%p), stub!\n", iface, index, ppFuncDesc);
3057     return E_OUTOFMEMORY;
3058 }
3059
3060 /******************************************************************************
3061  * ITypeInfo2_GetVarDesc {OLEAUT32}
3062  *
3063  *  See ITypeInfo_GetVarDesc.
3064  */
3065 static HRESULT WINAPI ITypeInfo2_fnGetVarDesc(
3066         ITypeInfo2* iface,
3067         UINT index,
3068         VARDESC** ppVarDesc)
3069 {
3070     FIXME("(%p,%d,%p), stub!\n", iface, index, ppVarDesc);
3071     return E_OUTOFMEMORY;
3072 }
3073
3074 /******************************************************************************
3075  * ITypeInfo2_GetNames {OLEAUT32}
3076  *
3077  *  See ITypeInfo_GetNames.
3078  */
3079 static HRESULT WINAPI ITypeInfo2_fnGetNames(
3080         ITypeInfo2* iface,
3081         MEMBERID memid,
3082         BSTR* rgBstrNames,
3083         UINT cMaxNames,
3084         UINT* pcNames)
3085 {
3086     FIXME("(%p,%d,%p,%d,%p), stub!\n", iface, memid, rgBstrNames, cMaxNames, pcNames);
3087     return E_OUTOFMEMORY;
3088 }
3089
3090 /******************************************************************************
3091  * ITypeInfo2_GetRefTypeOfImplType {OLEAUT32}
3092  *
3093  *  See ITypeInfo_GetRefTypeOfImplType.
3094  */
3095 static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType(
3096         ITypeInfo2* iface,
3097         UINT index,
3098         HREFTYPE* pRefType)
3099 {
3100     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3101     MSFT_RefRecord *ref;
3102     int offset;
3103
3104     TRACE("(%p,%d,%p)\n", iface, index, pRefType);
3105
3106     if(!pRefType)
3107         return E_INVALIDARG;
3108
3109     if(This->typeinfo->flags&TYPEFLAG_FDUAL) {
3110         if(index == -1) {
3111             *pRefType = -2;
3112             return S_OK;
3113         }
3114
3115         if(This->typekind == TKIND_DISPATCH)
3116             return ITypeInfo2_GetRefTypeOfImplType((ITypeInfo2*)&This->dual->lpVtblTypeInfo2,
3117                     index, pRefType);
3118     }
3119
3120     if(index>=This->typeinfo->cImplTypes)
3121         return TYPE_E_ELEMENTNOTFOUND;
3122
3123     if(This->typekind == TKIND_INTERFACE) {
3124         *pRefType = This->typeinfo->datatype1 + 2;
3125         return S_OK;
3126     }
3127
3128     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
3129     if(offset == -1)
3130         return TYPE_E_ELEMENTNOTFOUND;
3131
3132     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
3133     *pRefType = ref->reftype;
3134     return S_OK;
3135 }
3136
3137 /******************************************************************************
3138  * ITypeInfo2_GetImplTypeFlags {OLEAUT32}
3139  *
3140  *  See ITypeInfo_GetImplTypeFlags.
3141  */
3142 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags(
3143         ITypeInfo2* iface,
3144         UINT index,
3145         INT* pImplTypeFlags)
3146 {
3147     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3148     int offset;
3149     MSFT_RefRecord *ref;
3150
3151     TRACE("(%p,%d,%p)\n", iface, index, pImplTypeFlags);
3152
3153     if(!pImplTypeFlags)
3154         return E_INVALIDARG;
3155
3156     if(index >= This->typeinfo->cImplTypes)
3157         return TYPE_E_ELEMENTNOTFOUND;
3158
3159     if(This->typekind != TKIND_COCLASS) {
3160         *pImplTypeFlags = 0;
3161         return S_OK;
3162     }
3163
3164     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
3165     if(offset == -1)
3166         return TYPE_E_ELEMENTNOTFOUND;
3167
3168     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
3169     *pImplTypeFlags = ref->flags;
3170     return S_OK;
3171 }
3172
3173 /******************************************************************************
3174  * ITypeInfo2_GetIDsOfNames {OLEAUT32}
3175  *
3176  *  See ITypeInfo_GetIDsOfNames.
3177  */
3178 static HRESULT WINAPI ITypeInfo2_fnGetIDsOfNames(
3179         ITypeInfo2* iface,
3180         LPOLESTR* rgszNames,
3181         UINT cNames,
3182         MEMBERID* pMemId)
3183 {
3184     FIXME("(%p,%p,%d,%p), stub!\n", iface, rgszNames, cNames, pMemId);
3185     return E_OUTOFMEMORY;
3186 }
3187
3188 /******************************************************************************
3189  * ITypeInfo2_Invoke {OLEAUT32}
3190  *
3191  *  See ITypeInfo_Invoke.
3192  */
3193 static HRESULT WINAPI ITypeInfo2_fnInvoke(
3194         ITypeInfo2* iface,
3195         PVOID pvInstance,
3196         MEMBERID memid,
3197         WORD wFlags,
3198         DISPPARAMS* pDispParams,
3199         VARIANT* pVarResult,
3200         EXCEPINFO* pExcepInfo,
3201         UINT* puArgErr)
3202 {
3203     FIXME("(%p,%p,%d,%x,%p,%p,%p,%p), stub!\n", iface, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3204     return E_OUTOFMEMORY;
3205 }
3206
3207 /******************************************************************************
3208  * ITypeInfo2_GetDocumentation {OLEAUT32}
3209  *
3210  *  See ITypeInfo_GetDocumentation.
3211  */
3212 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation(
3213         ITypeInfo2* iface,
3214         MEMBERID memid,
3215         BSTR* pBstrName,
3216         BSTR* pBstrDocString,
3217         DWORD* pdwHelpContext,
3218         BSTR* pBstrHelpFile)
3219 {
3220     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3221     HRESULT status = TYPE_E_ELEMENTNOTFOUND;
3222     INT nameoffset, docstringoffset, helpcontext;
3223
3224     TRACE("(%p,%d,%p,%p,%p,%p)\n", iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
3225
3226     if (memid == -1)
3227     {
3228         nameoffset = This->typeinfo->NameOffset;
3229         docstringoffset = This->typeinfo->docstringoffs;
3230         helpcontext = This->typeinfo->helpcontext;
3231         status = S_OK;
3232     } else {
3233         CyclicList *iter;
3234         if (This->typedata) {
3235             for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
3236                 if (iter->indice == memid) {
3237                     if (iter->type == CyclicListFunc) {
3238                         const int *typedata = iter->u.data;
3239                         int   size = typedata[0] - typedata[5]*(typedata[4]&0x1000?16:12);
3240
3241                         nameoffset = iter->name;
3242                         /* FIXME implement this once SetFuncDocString is implemented */
3243                         docstringoffset = -1;
3244                         helpcontext = (size < 7*sizeof(int)) ? 0 : typedata[6];
3245
3246                         status = S_OK;
3247                     } else {
3248                         FIXME("Not implemented for variable members\n");
3249                     }
3250
3251                     break;
3252                 }
3253             }
3254         }
3255     }
3256
3257     if (!status) {
3258         WCHAR *string;
3259         if (pBstrName) {
3260             if (nameoffset == -1)
3261                 *pBstrName = NULL;
3262             else {
3263                 MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib->
3264                         typelib_segment_data[MSFT_SEG_NAME][nameoffset];
3265                 ctl2_decode_name((char*)&name->namelen, &string);
3266                 *pBstrName = SysAllocString(string);
3267                 if(!*pBstrName)
3268                     return E_OUTOFMEMORY;
3269             }
3270         }
3271
3272         if (pBstrDocString) {
3273             if (docstringoffset == -1)
3274                 *pBstrDocString = NULL;
3275             else {
3276                 MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib->
3277                         typelib_segment_data[MSFT_SEG_NAME][docstringoffset];
3278                 ctl2_decode_name((char*)&name->namelen, &string);
3279                 *pBstrDocString = SysAllocString(string);
3280                 if(!*pBstrDocString) {
3281                     if (pBstrName) SysFreeString(*pBstrName);
3282                     return E_OUTOFMEMORY;
3283                 }
3284             }
3285         }
3286
3287         if (pdwHelpContext) {
3288             *pdwHelpContext = helpcontext;
3289         }
3290
3291         if (pBstrHelpFile) {
3292             status = ITypeLib_GetDocumentation((ITypeLib*)&This->typelib->lpVtblTypeLib2,
3293                     -1, NULL, NULL, NULL, pBstrHelpFile);
3294             if (status) {
3295                 if (pBstrName) SysFreeString(*pBstrName);
3296                 if (pBstrDocString) SysFreeString(*pBstrDocString);
3297             }
3298         }
3299     }
3300
3301     return status;
3302 }
3303
3304 /******************************************************************************
3305  * ITypeInfo2_GetDllEntry {OLEAUT32}
3306  *
3307  *  See ITypeInfo_GetDllEntry.
3308  */
3309 static HRESULT WINAPI ITypeInfo2_fnGetDllEntry(
3310         ITypeInfo2* iface,
3311         MEMBERID memid,
3312         INVOKEKIND invKind,
3313         BSTR* pBstrDllName,
3314         BSTR* pBstrName,
3315         WORD* pwOrdinal)
3316 {
3317     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
3318     return E_OUTOFMEMORY;
3319 }
3320
3321 /******************************************************************************
3322  * ITypeInfo2_GetRefTypeInfo {OLEAUT32}
3323  *
3324  *  See ITypeInfo_GetRefTypeInfo.
3325  */
3326 static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo(
3327         ITypeInfo2* iface,
3328         HREFTYPE hRefType,
3329         ITypeInfo** ppTInfo)
3330 {
3331     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3332
3333     TRACE("(%p,%d,%p)\n", iface, hRefType, ppTInfo);
3334
3335     if(!ppTInfo)
3336         return E_INVALIDARG;
3337
3338     if(hRefType==-2 && This->dual) {
3339         *ppTInfo = (ITypeInfo*)&This->dual->lpVtblTypeInfo2;
3340         ITypeInfo_AddRef(*ppTInfo);
3341         return S_OK;
3342     }
3343
3344     if(hRefType&1) {
3345         ITypeLib *tl;
3346         MSFT_ImpInfo *impinfo;
3347         MSFT_ImpFile *impfile;
3348         MSFT_GuidEntry *guid;
3349         WCHAR *filename;
3350         HRESULT hres;
3351
3352         if((hRefType&(~0x3)) >= This->typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length)
3353             return E_FAIL;
3354
3355         impinfo = (MSFT_ImpInfo*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][hRefType&(~0x3)];
3356         impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile];
3357         guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid];
3358
3359         ctl2_decode_string(impfile->filename, &filename);
3360
3361         hres = LoadTypeLib(filename, &tl);
3362         if(FAILED(hres))
3363             return hres;
3364
3365         hres = ITypeLib_GetTypeInfoOfGuid(tl, &guid->guid, ppTInfo);
3366
3367         ITypeLib_Release(tl);
3368         return hres;
3369     } else {
3370         ICreateTypeInfo2Impl *iter;
3371         int i = 0;
3372
3373         for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) {
3374             if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) {
3375                 *ppTInfo = (ITypeInfo*)&iter->lpVtblTypeInfo2;
3376
3377                 ITypeLib_AddRef(*ppTInfo);
3378                 return S_OK;
3379             }
3380             i++;
3381         }
3382     }
3383
3384     return E_FAIL;
3385 }
3386
3387 /******************************************************************************
3388  * ITypeInfo2_AddressOfMember {OLEAUT32}
3389  *
3390  *  See ITypeInfo_AddressOfMember.
3391  */
3392 static HRESULT WINAPI ITypeInfo2_fnAddressOfMember(
3393         ITypeInfo2* iface,
3394         MEMBERID memid,
3395         INVOKEKIND invKind,
3396         PVOID* ppv)
3397 {
3398     FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, ppv);
3399     return E_OUTOFMEMORY;
3400 }
3401
3402 /******************************************************************************
3403  * ITypeInfo2_CreateInstance {OLEAUT32}
3404  *
3405  *  See ITypeInfo_CreateInstance.
3406  */
3407 static HRESULT WINAPI ITypeInfo2_fnCreateInstance(
3408         ITypeInfo2* iface,
3409         IUnknown* pUnkOuter,
3410         REFIID riid,
3411         PVOID* ppvObj)
3412 {
3413     FIXME("(%p,%p,%s,%p), stub!\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj);
3414     return E_OUTOFMEMORY;
3415 }
3416
3417 /******************************************************************************
3418  * ITypeInfo2_GetMops {OLEAUT32}
3419  *
3420  *  See ITypeInfo_GetMops.
3421  */
3422 static HRESULT WINAPI ITypeInfo2_fnGetMops(
3423         ITypeInfo2* iface,
3424         MEMBERID memid,
3425         BSTR* pBstrMops)
3426 {
3427     FIXME("(%p,%d,%p), stub!\n", iface, memid, pBstrMops);
3428     return E_OUTOFMEMORY;
3429 }
3430
3431 /******************************************************************************
3432  * ITypeInfo2_GetContainingTypeLib {OLEAUT32}
3433  *
3434  *  See ITypeInfo_GetContainingTypeLib.
3435  */
3436 static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib(
3437         ITypeInfo2* iface,
3438         ITypeLib** ppTLib,
3439         UINT* pIndex)
3440 {
3441     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
3442
3443     TRACE("(%p,%p,%p)\n", iface, ppTLib, pIndex);
3444     
3445     *ppTLib = (ITypeLib *)&This->typelib->lpVtblTypeLib2;
3446     ICreateTypeLib_AddRef((ICreateTypeLib*)This->typelib);
3447     *pIndex = This->typeinfo->typekind >> 16;
3448
3449     return S_OK;
3450 }
3451
3452 /******************************************************************************
3453  * ITypeInfo2_ReleaseTypeAttr {OLEAUT32}
3454  *
3455  *  See ITypeInfo_ReleaseTypeAttr.
3456  */
3457 static void WINAPI ITypeInfo2_fnReleaseTypeAttr(
3458         ITypeInfo2* iface,
3459         TYPEATTR* pTypeAttr)
3460 {
3461     TRACE("(%p,%p)\n", iface, pTypeAttr);
3462
3463     HeapFree(GetProcessHeap(), 0, pTypeAttr);
3464 }
3465
3466 /******************************************************************************
3467  * ITypeInfo2_ReleaseFuncDesc {OLEAUT32}
3468  *
3469  *  See ITypeInfo_ReleaseFuncDesc.
3470  */
3471 static void WINAPI ITypeInfo2_fnReleaseFuncDesc(
3472         ITypeInfo2* iface,
3473         FUNCDESC* pFuncDesc)
3474 {
3475     FIXME("(%p,%p), stub!\n", iface, pFuncDesc);
3476 }
3477
3478 /******************************************************************************
3479  * ITypeInfo2_ReleaseVarDesc {OLEAUT32}
3480  *
3481  *  See ITypeInfo_ReleaseVarDesc.
3482  */
3483 static void WINAPI ITypeInfo2_fnReleaseVarDesc(
3484         ITypeInfo2* iface,
3485         VARDESC* pVarDesc)
3486 {
3487     FIXME("(%p,%p), stub!\n", iface, pVarDesc);
3488 }
3489
3490 /******************************************************************************
3491  * ITypeInfo2_GetTypeKind {OLEAUT32}
3492  *
3493  *  Get the TYPEKIND value for a TypeInfo.
3494  *
3495  * RETURNS
3496  *
3497  *  Success: S_OK.
3498  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3499  */
3500 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind(
3501         ITypeInfo2* iface,   /* [I] The TypeInfo to obtain the typekind for. */
3502         TYPEKIND* pTypeKind) /* [O] The typekind for this TypeInfo. */
3503 {
3504     FIXME("(%p,%p), stub!\n", iface, pTypeKind);
3505     return E_OUTOFMEMORY;
3506 }
3507
3508 /******************************************************************************
3509  * ITypeInfo2_GetTypeFlags {OLEAUT32}
3510  *
3511  *  Get the Type Flags for a TypeInfo.
3512  *
3513  * RETURNS
3514  *
3515  *  Success: S_OK.
3516  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3517  */
3518 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags(
3519         ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typeflags for. */
3520         ULONG* pTypeFlags) /* [O] The type flags for this TypeInfo. */
3521 {
3522     FIXME("(%p,%p), stub!\n", iface, pTypeFlags);
3523     return E_OUTOFMEMORY;
3524 }
3525
3526 /******************************************************************************
3527  * ITypeInfo2_GetFuncIndexOfMemId {OLEAUT32}
3528  *
3529  *  Gets the index of a function given its member id.
3530  *
3531  * RETURNS
3532  *
3533  *  Success: S_OK.
3534  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3535  */
3536 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId(
3537         ITypeInfo2* iface,  /* [I] The TypeInfo in which to find the function. */
3538         MEMBERID memid,     /* [I] The member id for the function. */
3539         INVOKEKIND invKind, /* [I] The invocation kind for the function. */
3540         UINT* pFuncIndex)   /* [O] The index of the function. */
3541 {
3542     FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex);
3543     return E_OUTOFMEMORY;
3544 }
3545
3546 /******************************************************************************
3547  * ITypeInfo2_GetVarIndexOfMemId {OLEAUT32}
3548  *
3549  *  Gets the index of a variable given its member id.
3550  *
3551  * RETURNS
3552  *
3553  *  Success: S_OK.
3554  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3555  */
3556 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId(
3557         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the variable. */
3558         MEMBERID memid,    /* [I] The member id for the variable. */
3559         UINT* pVarIndex)   /* [O] The index of the variable. */
3560 {
3561     FIXME("(%p,%d,%p), stub!\n", iface, memid, pVarIndex);
3562     return E_OUTOFMEMORY;
3563 }
3564
3565 /******************************************************************************
3566  * ITypeInfo2_GetCustData {OLEAUT32}
3567  *
3568  *  Gets a custom data element from a TypeInfo.
3569  *
3570  * RETURNS
3571  *
3572  *  Success: S_OK.
3573  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3574  */
3575 static HRESULT WINAPI ITypeInfo2_fnGetCustData(
3576         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3577         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3578         VARIANT* pVarVal)  /* [O] The custom data. */
3579 {
3580     FIXME("(%p,%s,%p), stub!\n", iface, debugstr_guid(guid), pVarVal);
3581     return E_OUTOFMEMORY;
3582 }
3583
3584 /******************************************************************************
3585  * ITypeInfo2_GetFuncCustData {OLEAUT32}
3586  *
3587  *  Gets a custom data element from a function.
3588  *
3589  * RETURNS
3590  *
3591  *  Success: S_OK.
3592  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3593  */
3594 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
3595         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3596         UINT index,        /* [I] The index of the function for which to retrieve the custom data. */
3597         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3598         VARIANT* pVarVal)  /* [O] The custom data. */
3599 {
3600     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3601     return E_OUTOFMEMORY;
3602 }
3603
3604 /******************************************************************************
3605  * ITypeInfo2_GetParamCustData {OLEAUT32}
3606  *
3607  *  Gets a custom data element from a parameter.
3608  *
3609  * RETURNS
3610  *
3611  *  Success: S_OK.
3612  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3613  */
3614 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
3615         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3616         UINT indexFunc,    /* [I] The index of the function for which to retrieve the custom data. */
3617         UINT indexParam,   /* [I] The index of the parameter for which to retrieve the custom data. */
3618         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3619         VARIANT* pVarVal)  /* [O] The custom data. */
3620 {
3621     FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
3622     return E_OUTOFMEMORY;
3623 }
3624
3625 /******************************************************************************
3626  * ITypeInfo2_GetVarCustData {OLEAUT32}
3627  *
3628  *  Gets a custom data element from a variable.
3629  *
3630  * RETURNS
3631  *
3632  *  Success: S_OK.
3633  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3634  */
3635 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
3636         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3637         UINT index,        /* [I] The index of the variable for which to retrieve the custom data. */
3638         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3639         VARIANT* pVarVal)  /* [O] The custom data. */
3640 {
3641     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3642     return E_OUTOFMEMORY;
3643 }
3644
3645 /******************************************************************************
3646  * ITypeInfo2_GetImplTypeCustData {OLEAUT32}
3647  *
3648  *  Gets a custom data element from an implemented type of a TypeInfo.
3649  *
3650  * RETURNS
3651  *
3652  *  Success: S_OK.
3653  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3654  */
3655 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
3656         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
3657         UINT index,        /* [I] The index of the implemented type for which to retrieve the custom data. */
3658         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
3659         VARIANT* pVarVal)  /* [O] The custom data. */
3660 {
3661     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
3662     return E_OUTOFMEMORY;
3663 }
3664
3665 /******************************************************************************
3666  * ITypeInfo2_GetDocumentation2 {OLEAUT32}
3667  *
3668  *  Gets some documentation from a TypeInfo in a locale-aware fashion.
3669  *
3670  * RETURNS
3671  *
3672  *  Success: S_OK.
3673  *  Failure: One of STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
3674  */
3675 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
3676         ITypeInfo2* iface,           /* [I] The TypeInfo to retrieve the documentation from. */
3677         MEMBERID memid,              /* [I] The member id (why?). */
3678         LCID lcid,                   /* [I] The locale (why?). */
3679         BSTR* pbstrHelpString,       /* [O] The help string. */
3680         DWORD* pdwHelpStringContext, /* [O] The help string context. */
3681         BSTR* pbstrHelpStringDll)    /* [O] The help file name. */
3682 {
3683     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
3684     return E_OUTOFMEMORY;
3685 }
3686
3687 /******************************************************************************
3688  * ITypeInfo2_GetAllCustData {OLEAUT32}
3689  *
3690  *  Gets all of the custom data associated with a TypeInfo.
3691  *
3692  * RETURNS
3693  *
3694  *  Success: S_OK.
3695  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3696  */
3697 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
3698         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3699         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3700 {
3701     FIXME("(%p,%p), stub!\n", iface, pCustData);
3702     return E_OUTOFMEMORY;
3703 }
3704
3705 /******************************************************************************
3706  * ITypeInfo2_GetAllFuncCustData {OLEAUT32}
3707  *
3708  *  Gets all of the custom data associated with a function.
3709  *
3710  * RETURNS
3711  *
3712  *  Success: S_OK.
3713  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3714  */
3715 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
3716         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3717         UINT index,          /* [I] The index of the function for which to retrieve the custom data. */
3718         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3719 {
3720     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
3721     return E_OUTOFMEMORY;
3722 }
3723
3724 /******************************************************************************
3725  * ITypeInfo2_GetAllParamCustData {OLEAUT32}
3726  *
3727  *  Gets all of the custom data associated with a parameter.
3728  *
3729  * RETURNS
3730  *
3731  *  Success: S_OK.
3732  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3733  */
3734 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData(
3735         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3736         UINT indexFunc,      /* [I] The index of the function for which to retrieve the custom data. */
3737         UINT indexParam,     /* [I] The index of the parameter for which to retrieve the custom data. */
3738         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3739 {
3740     FIXME("(%p,%d,%d,%p), stub!\n", iface, indexFunc, indexParam, pCustData);
3741     return E_OUTOFMEMORY;
3742 }
3743
3744 /******************************************************************************
3745  * ITypeInfo2_GetAllVarCustData {OLEAUT32}
3746  *
3747  *  Gets all of the custom data associated with a variable.
3748  *
3749  * RETURNS
3750  *
3751  *  Success: S_OK.
3752  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3753  */
3754 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData(
3755         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3756         UINT index,          /* [I] The index of the variable for which to retrieve the custom data. */
3757         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3758 {
3759     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
3760     return E_OUTOFMEMORY;
3761 }
3762
3763 /******************************************************************************
3764  * ITypeInfo2_GetAllImplTypeCustData {OLEAUT32}
3765  *
3766  *  Gets all of the custom data associated with an implemented type.
3767  *
3768  * RETURNS
3769  *
3770  *  Success: S_OK.
3771  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
3772  */
3773 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
3774         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
3775         UINT index,          /* [I] The index of the implemented type for which to retrieve the custom data. */
3776         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
3777 {
3778     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
3779     return E_OUTOFMEMORY;
3780 }
3781
3782
3783 /*================== ICreateTypeInfo2 & ITypeInfo2 VTABLEs And Creation ===================================*/
3784
3785 static const ICreateTypeInfo2Vtbl ctypeinfo2vt =
3786 {
3787
3788     ICreateTypeInfo2_fnQueryInterface,
3789     ICreateTypeInfo2_fnAddRef,
3790     ICreateTypeInfo2_fnRelease,
3791
3792     ICreateTypeInfo2_fnSetGuid,
3793     ICreateTypeInfo2_fnSetTypeFlags,
3794     ICreateTypeInfo2_fnSetDocString,
3795     ICreateTypeInfo2_fnSetHelpContext,
3796     ICreateTypeInfo2_fnSetVersion,
3797     ICreateTypeInfo2_fnAddRefTypeInfo,
3798     ICreateTypeInfo2_fnAddFuncDesc,
3799     ICreateTypeInfo2_fnAddImplType,
3800     ICreateTypeInfo2_fnSetImplTypeFlags,
3801     ICreateTypeInfo2_fnSetAlignment,
3802     ICreateTypeInfo2_fnSetSchema,
3803     ICreateTypeInfo2_fnAddVarDesc,
3804     ICreateTypeInfo2_fnSetFuncAndParamNames,
3805     ICreateTypeInfo2_fnSetVarName,
3806     ICreateTypeInfo2_fnSetTypeDescAlias,
3807     ICreateTypeInfo2_fnDefineFuncAsDllEntry,
3808     ICreateTypeInfo2_fnSetFuncDocString,
3809     ICreateTypeInfo2_fnSetVarDocString,
3810     ICreateTypeInfo2_fnSetFuncHelpContext,
3811     ICreateTypeInfo2_fnSetVarHelpContext,
3812     ICreateTypeInfo2_fnSetMops,
3813     ICreateTypeInfo2_fnSetTypeIdldesc,
3814     ICreateTypeInfo2_fnLayOut,
3815
3816     ICreateTypeInfo2_fnDeleteFuncDesc,
3817     ICreateTypeInfo2_fnDeleteFuncDescByMemId,
3818     ICreateTypeInfo2_fnDeleteVarDesc,
3819     ICreateTypeInfo2_fnDeleteVarDescByMemId,
3820     ICreateTypeInfo2_fnDeleteImplType,
3821     ICreateTypeInfo2_fnSetCustData,
3822     ICreateTypeInfo2_fnSetFuncCustData,
3823     ICreateTypeInfo2_fnSetParamCustData,
3824     ICreateTypeInfo2_fnSetVarCustData,
3825     ICreateTypeInfo2_fnSetImplTypeCustData,
3826     ICreateTypeInfo2_fnSetHelpStringContext,
3827     ICreateTypeInfo2_fnSetFuncHelpStringContext,
3828     ICreateTypeInfo2_fnSetVarHelpStringContext,
3829     ICreateTypeInfo2_fnInvalidate,
3830     ICreateTypeInfo2_fnSetName
3831 };
3832
3833 static const ITypeInfo2Vtbl typeinfo2vt =
3834 {
3835
3836     ITypeInfo2_fnQueryInterface,
3837     ITypeInfo2_fnAddRef,
3838     ITypeInfo2_fnRelease,
3839
3840     ITypeInfo2_fnGetTypeAttr,
3841     ITypeInfo2_fnGetTypeComp,
3842     ITypeInfo2_fnGetFuncDesc,
3843     ITypeInfo2_fnGetVarDesc,
3844     ITypeInfo2_fnGetNames,
3845     ITypeInfo2_fnGetRefTypeOfImplType,
3846     ITypeInfo2_fnGetImplTypeFlags,
3847     ITypeInfo2_fnGetIDsOfNames,
3848     ITypeInfo2_fnInvoke,
3849     ITypeInfo2_fnGetDocumentation,
3850     ITypeInfo2_fnGetDllEntry,
3851     ITypeInfo2_fnGetRefTypeInfo,
3852     ITypeInfo2_fnAddressOfMember,
3853     ITypeInfo2_fnCreateInstance,
3854     ITypeInfo2_fnGetMops,
3855     ITypeInfo2_fnGetContainingTypeLib,
3856     ITypeInfo2_fnReleaseTypeAttr,
3857     ITypeInfo2_fnReleaseFuncDesc,
3858     ITypeInfo2_fnReleaseVarDesc,
3859
3860     ITypeInfo2_fnGetTypeKind,
3861     ITypeInfo2_fnGetTypeFlags,
3862     ITypeInfo2_fnGetFuncIndexOfMemId,
3863     ITypeInfo2_fnGetVarIndexOfMemId,
3864     ITypeInfo2_fnGetCustData,
3865     ITypeInfo2_fnGetFuncCustData,
3866     ITypeInfo2_fnGetParamCustData,
3867     ITypeInfo2_fnGetVarCustData,
3868     ITypeInfo2_fnGetImplTypeCustData,
3869     ITypeInfo2_fnGetDocumentation2,
3870     ITypeInfo2_fnGetAllCustData,
3871     ITypeInfo2_fnGetAllFuncCustData,
3872     ITypeInfo2_fnGetAllParamCustData,
3873     ITypeInfo2_fnGetAllVarCustData,
3874     ITypeInfo2_fnGetAllImplTypeCustData,
3875 };
3876
3877 static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typelib, WCHAR *szName, TYPEKIND tkind)
3878 {
3879     ICreateTypeInfo2Impl *pCreateTypeInfo2Impl;
3880
3881     int nameoffset;
3882     int typeinfo_offset;
3883     MSFT_TypeInfoBase *typeinfo;
3884
3885     TRACE("Constructing ICreateTypeInfo2 for %s with tkind %d\n", debugstr_w(szName), tkind);
3886
3887     pCreateTypeInfo2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeInfo2Impl));
3888     if (!pCreateTypeInfo2Impl) return NULL;
3889
3890     pCreateTypeInfo2Impl->lpVtbl = &ctypeinfo2vt;
3891     pCreateTypeInfo2Impl->lpVtblTypeInfo2 = &typeinfo2vt;
3892     pCreateTypeInfo2Impl->ref = 1;
3893
3894     pCreateTypeInfo2Impl->typelib = typelib;
3895     ICreateTypeLib_AddRef((ICreateTypeLib*)typelib);
3896
3897     nameoffset = ctl2_alloc_name(typelib, szName);
3898     typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset);
3899     typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset];
3900
3901     typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38;
3902     *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset;
3903
3904     pCreateTypeInfo2Impl->typeinfo = typeinfo;
3905
3906     pCreateTypeInfo2Impl->typekind = tkind;
3907     typeinfo->typekind |= tkind | 0x20;
3908     ICreateTypeInfo2_SetAlignment((ICreateTypeInfo2 *)pCreateTypeInfo2Impl, 4);
3909
3910     switch (tkind) {
3911     case TKIND_ENUM:
3912     case TKIND_INTERFACE:
3913     case TKIND_DISPATCH:
3914     case TKIND_COCLASS:
3915         typeinfo->size = 4;
3916         break;
3917
3918     case TKIND_RECORD:
3919     case TKIND_UNION:
3920         typeinfo->size = 0;
3921         break;
3922
3923     case TKIND_MODULE:
3924         typeinfo->size = 2;
3925         break;
3926
3927     case TKIND_ALIAS:
3928         typeinfo->size = -0x75;
3929         break;
3930
3931     default:
3932         FIXME("(%s,%d), unrecognized typekind %d\n", debugstr_w(szName), tkind, tkind);
3933         typeinfo->size = 0xdeadbeef;
3934         break;
3935     }
3936
3937     if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = pCreateTypeInfo2Impl;
3938     typelib->last_typeinfo = pCreateTypeInfo2Impl;
3939     if (!typelib->typeinfos) typelib->typeinfos = pCreateTypeInfo2Impl;
3940
3941     TRACE(" -- %p\n", pCreateTypeInfo2Impl);
3942
3943     return (ICreateTypeInfo2 *)pCreateTypeInfo2Impl;
3944 }
3945
3946
3947 /*================== ICreateTypeLib2 Implementation ===================================*/
3948
3949 /******************************************************************************
3950  * ICreateTypeLib2_QueryInterface {OLEAUT32}
3951  *
3952  *  See IUnknown_QueryInterface.
3953  */
3954 static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(
3955         ICreateTypeLib2 * iface,
3956         REFIID riid,
3957         VOID **ppvObject)
3958 {
3959     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3960
3961     TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
3962
3963     *ppvObject=NULL;
3964     if(IsEqualIID(riid, &IID_IUnknown) ||
3965        IsEqualIID(riid,&IID_ICreateTypeLib)||
3966        IsEqualIID(riid,&IID_ICreateTypeLib2))
3967     {
3968         *ppvObject = This;
3969     } else if (IsEqualIID(riid, &IID_ITypeLib) ||
3970                IsEqualIID(riid, &IID_ITypeLib2)) {
3971         *ppvObject = &This->lpVtblTypeLib2;
3972     }
3973
3974     if(*ppvObject)
3975     {
3976         ICreateTypeLib2_AddRef(iface);
3977         TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
3978         return S_OK;
3979     }
3980     TRACE("-- Interface: E_NOINTERFACE\n");
3981     return E_NOINTERFACE;
3982 }
3983
3984 /******************************************************************************
3985  * ICreateTypeLib2_AddRef {OLEAUT32}
3986  *
3987  *  See IUnknown_AddRef.
3988  */
3989 static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
3990 {
3991     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
3992     ULONG ref = InterlockedIncrement(&This->ref);
3993
3994     TRACE("(%p)->ref was %u\n",This, ref - 1);
3995
3996     return ref;
3997 }
3998
3999 /******************************************************************************
4000  * ICreateTypeLib2_Release {OLEAUT32}
4001  *
4002  *  See IUnknown_Release.
4003  */
4004 static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
4005 {
4006     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4007     ULONG ref = InterlockedDecrement(&This->ref);
4008
4009     TRACE("(%p)->(%u)\n",This, ref);
4010
4011     if (!ref) {
4012         int i;
4013
4014         for (i = 0; i < MSFT_SEG_MAX; i++) {
4015             HeapFree(GetProcessHeap(), 0, This->typelib_segment_data[i]);
4016             This->typelib_segment_data[i] = NULL;
4017         }
4018
4019         HeapFree(GetProcessHeap(), 0, This->filename);
4020         This->filename = NULL;
4021
4022         while (This->typeinfos) {
4023             ICreateTypeInfo2Impl *typeinfo = This->typeinfos;
4024             This->typeinfos = typeinfo->next_typeinfo;
4025             if(typeinfo->typedata) {
4026                 CyclicList *iter, *rem;
4027
4028                 rem = typeinfo->typedata->next;
4029                 typeinfo->typedata->next = NULL;
4030                 iter = rem->next;
4031                 HeapFree(GetProcessHeap(), 0, rem);
4032
4033                 while(iter) {
4034                     rem = iter;
4035                     iter = iter->next;
4036                     HeapFree(GetProcessHeap(), 0, rem->u.data);
4037                     HeapFree(GetProcessHeap(), 0, rem);
4038                 }
4039             }
4040
4041             HeapFree(GetProcessHeap(), 0, typeinfo->dual);
4042             HeapFree(GetProcessHeap(), 0, typeinfo);
4043         }
4044
4045         HeapFree(GetProcessHeap(),0,This);
4046         return 0;
4047     }
4048
4049     return ref;
4050 }
4051
4052
4053 /******************************************************************************
4054  * ICreateTypeLib2_CreateTypeInfo {OLEAUT32}
4055  *
4056  *  See ICreateTypeLib_CreateTypeInfo.
4057  */
4058 static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(
4059         ICreateTypeLib2 * iface,
4060         LPOLESTR szName,
4061         TYPEKIND tkind,
4062         ICreateTypeInfo **ppCTInfo)
4063 {
4064     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4065     char *name;
4066
4067     TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo);
4068
4069     ctl2_encode_name(This, szName, &name);
4070     if(ctl2_find_name(This, name) != -1)
4071         return TYPE_E_NAMECONFLICT;
4072
4073     *ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind);
4074
4075     if (!*ppCTInfo) return E_OUTOFMEMORY;
4076
4077     return S_OK;
4078 }
4079
4080 /******************************************************************************
4081  * ICreateTypeLib2_SetName {OLEAUT32}
4082  *
4083  *  See ICreateTypeLib_SetName.
4084  */
4085 static HRESULT WINAPI ICreateTypeLib2_fnSetName(
4086         ICreateTypeLib2 * iface,
4087         LPOLESTR szName)
4088 {
4089     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4090
4091     int offset;
4092
4093     TRACE("(%p,%s)\n", iface, debugstr_w(szName));
4094
4095     offset = ctl2_alloc_name(This, szName);
4096     if (offset == -1) return E_OUTOFMEMORY;
4097     This->typelib_header.NameOffset = offset;
4098     return S_OK;
4099 }
4100
4101 /******************************************************************************
4102  * ICreateTypeLib2_SetVersion {OLEAUT32}
4103  *
4104  *  See ICreateTypeLib_SetVersion.
4105  */
4106 static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD wMajorVerNum, WORD wMinorVerNum)
4107 {
4108     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4109
4110     TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);
4111
4112     This->typelib_header.version = wMajorVerNum | (wMinorVerNum << 16);
4113     return S_OK;
4114 }
4115
4116 /******************************************************************************
4117  * ICreateTypeLib2_SetGuid {OLEAUT32}
4118  *
4119  *  See ICreateTypeLib_SetGuid.
4120  */
4121 static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID guid)
4122 {
4123     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4124
4125     MSFT_GuidEntry guidentry;
4126     int offset;
4127
4128     TRACE("(%p,%s)\n", iface, debugstr_guid(guid));
4129
4130     guidentry.guid = *guid;
4131     guidentry.hreftype = -2;
4132     guidentry.next_hash = -1;
4133
4134     offset = ctl2_alloc_guid(This, &guidentry);
4135     
4136     if (offset == -1) return E_OUTOFMEMORY;
4137
4138     This->typelib_header.posguid = offset;
4139
4140     return S_OK;
4141 }
4142
4143 /******************************************************************************
4144  * ICreateTypeLib2_SetDocString {OLEAUT32}
4145  *
4146  *  See ICreateTypeLib_SetDocString.
4147  */
4148 static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LPOLESTR szDoc)
4149 {
4150     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4151
4152     int offset;
4153
4154     TRACE("(%p,%s)\n", iface, debugstr_w(szDoc));
4155     if (!szDoc)
4156         return E_INVALIDARG;
4157
4158     offset = ctl2_alloc_string(This, szDoc);
4159     if (offset == -1) return E_OUTOFMEMORY;
4160     This->typelib_header.helpstring = offset;
4161     return S_OK;
4162 }
4163
4164 /******************************************************************************
4165  * ICreateTypeLib2_SetHelpFileName {OLEAUT32}
4166  *
4167  *  See ICreateTypeLib_SetHelpFileName.
4168  */
4169 static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, LPOLESTR szHelpFileName)
4170 {
4171     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4172
4173     int offset;
4174
4175     TRACE("(%p,%s)\n", iface, debugstr_w(szHelpFileName));
4176
4177     offset = ctl2_alloc_string(This, szHelpFileName);
4178     if (offset == -1) return E_OUTOFMEMORY;
4179     This->typelib_header.helpfile = offset;
4180     This->typelib_header.varflags |= 0x10;
4181     return S_OK;
4182 }
4183
4184 /******************************************************************************
4185  * ICreateTypeLib2_SetHelpContext {OLEAUT32}
4186  *
4187  *  See ICreateTypeLib_SetHelpContext.
4188  */
4189 static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext)
4190 {
4191     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4192
4193     TRACE("(%p,%d)\n", iface, dwHelpContext);
4194     This->typelib_header.helpcontext = dwHelpContext;
4195     return S_OK;
4196 }
4197
4198 /******************************************************************************
4199  * ICreateTypeLib2_SetLcid {OLEAUT32}
4200  *
4201  * Sets both the lcid and lcid2 members in the header to lcid.
4202  *
4203  * As a special case if lcid == LOCALE_NEUTRAL (0), then the first header lcid
4204  * is set to US English while the second one is set to 0.
4205  */
4206 static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lcid)
4207 {
4208     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4209
4210     TRACE("(%p,%d)\n", iface, lcid);
4211
4212     This->typelib_header.lcid = This->typelib_header.lcid2 = lcid;
4213
4214     if(lcid == LOCALE_NEUTRAL) This->typelib_header.lcid = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
4215
4216     return S_OK;
4217 }
4218
4219 /******************************************************************************
4220  * ICreateTypeLib2_SetLibFlags {OLEAUT32}
4221  *
4222  *  See ICreateTypeLib_SetLibFlags.
4223  */
4224 static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 * iface, UINT uLibFlags)
4225 {
4226     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4227
4228     TRACE("(%p,0x%x)\n", iface, uLibFlags);
4229
4230     This->typelib_header.flags = uLibFlags;
4231
4232     return S_OK;
4233 }
4234
4235 static int ctl2_write_chunk(HANDLE hFile, const void *segment, int length)
4236 {
4237     DWORD dwWritten;
4238     if (!WriteFile(hFile, segment, length, &dwWritten, 0)) {
4239         CloseHandle(hFile);
4240         return 0;
4241     }
4242     return -1;
4243 }
4244
4245 static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segment)
4246 {
4247     DWORD dwWritten;
4248     if (!WriteFile(hFile, This->typelib_segment_data[segment],
4249                    This->typelib_segdir[segment].length, &dwWritten, 0)) {
4250         CloseHandle(hFile);
4251         return 0;
4252     }
4253
4254     return -1;
4255 }
4256
4257 static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
4258 {
4259     ICreateTypeInfo2Impl *typeinfo;
4260     HRESULT hres;
4261
4262     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
4263         typeinfo->typeinfo->memoffset = filesize;
4264
4265         hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
4266         if(FAILED(hres))
4267             return hres;
4268
4269         if (typeinfo->typedata)
4270             filesize += typeinfo->typedata->next->u.val
4271                 + ((typeinfo->typeinfo->cElement >> 16) * 12)
4272                 + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
4273     }
4274
4275     return S_OK;
4276 }
4277
4278 static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment)
4279 {
4280     if (This->typelib_segdir[segment].length) {
4281         This->typelib_segdir[segment].offset = filepos;
4282     } else {
4283         This->typelib_segdir[segment].offset = -1;
4284     }
4285
4286     return This->typelib_segdir[segment].length;
4287 }
4288
4289 static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile)
4290 {
4291     ICreateTypeInfo2Impl *typeinfo;
4292
4293     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
4294         CyclicList *iter;
4295         int offset = 0;
4296
4297         if (!typeinfo->typedata) continue;
4298
4299         iter = typeinfo->typedata->next;
4300         ctl2_write_chunk(hFile, &iter->u.val, sizeof(int));
4301         for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next)
4302             ctl2_write_chunk(hFile, iter->u.data, iter->u.data[0] & 0xffff);
4303
4304         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
4305             ctl2_write_chunk(hFile, &iter->indice, sizeof(int));
4306
4307         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
4308             ctl2_write_chunk(hFile, &iter->name, sizeof(int));
4309
4310         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) {
4311             ctl2_write_chunk(hFile, &offset, sizeof(int));
4312             offset += iter->u.data[0] & 0xffff;
4313         }
4314     }
4315 }
4316
4317 /******************************************************************************
4318  * ICreateTypeLib2_SaveAllChanges {OLEAUT32}
4319  *
4320  *  See ICreateTypeLib_SaveAllChanges.
4321  */
4322 static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
4323 {
4324     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4325
4326     int retval;
4327     int filepos;
4328     HANDLE hFile;
4329     HRESULT hres;
4330
4331     TRACE("(%p)\n", iface);
4332
4333     retval = TYPE_E_IOERROR;
4334
4335     hFile = CreateFileW(This->filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
4336     if (hFile == INVALID_HANDLE_VALUE) return retval;
4337
4338     filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir);
4339     filepos += This->typelib_header.nrtypeinfos * 4;
4340
4341     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO);
4342     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH);
4343     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID);
4344     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
4345     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO);
4346     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES);
4347     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH);
4348     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME);
4349     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING);
4350     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEDESC);
4351     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_ARRAYDESC);
4352     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA);
4353     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID);
4354
4355     hres = ctl2_finalize_typeinfos(This, filepos);
4356     if(FAILED(hres)) {
4357         CloseHandle(hFile);
4358         return hres;
4359     }
4360
4361     if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval;
4362     if (This->typelib_header.varflags & HELPDLLFLAG)
4363         if (!ctl2_write_chunk(hFile, &This->helpStringDll, sizeof(This->helpStringDll))) return retval;
4364     if (!ctl2_write_chunk(hFile, This->typelib_typeinfo_offsets, This->typelib_header.nrtypeinfos * 4)) return retval;
4365     if (!ctl2_write_chunk(hFile, This->typelib_segdir, sizeof(This->typelib_segdir))) return retval;
4366     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO    )) return retval;
4367     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH    )) return retval;
4368     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID        )) return retval;
4369     if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES  )) return retval;
4370     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO  )) return retval;
4371     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval;
4372     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH    )) return retval;
4373     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME        )) return retval;
4374     if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING      )) return retval;
4375     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEDESC    )) return retval;
4376     if (!ctl2_write_segment(This, hFile, MSFT_SEG_ARRAYDESC   )) return retval;
4377     if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATA    )) return retval;
4378     if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATAGUID)) return retval;
4379
4380     ctl2_write_typeinfos(This, hFile);
4381
4382     if (!CloseHandle(hFile)) return retval;
4383
4384     return S_OK;
4385 }
4386
4387
4388 /******************************************************************************
4389  * ICreateTypeLib2_DeleteTypeInfo {OLEAUT32}
4390  *
4391  *  Deletes a named TypeInfo from a type library.
4392  *
4393  * RETURNS
4394  *
4395  *  Success: S_OK
4396  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4397  */
4398 static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(
4399         ICreateTypeLib2 * iface, /* [I] The type library to delete from. */
4400         LPOLESTR szName)         /* [I] The name of the typeinfo to delete. */
4401 {
4402     FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
4403     return E_OUTOFMEMORY;
4404 }
4405
4406 /******************************************************************************
4407  * ICreateTypeLib2_SetCustData {OLEAUT32}
4408  *
4409  *  Sets custom data for a type library.
4410  *
4411  * RETURNS
4412  *
4413  *  Success: S_OK
4414  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4415  */
4416 static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(
4417         ICreateTypeLib2 * iface, /* [I] The type library to store the custom data in. */
4418         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
4419         VARIANT *pVarVal)        /* [I] The custom data itself. */
4420 {
4421     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4422
4423     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal);
4424
4425     return ctl2_set_custdata(This, guid, pVarVal, &This->typelib_header.CustomDataOffset);
4426 }
4427
4428 /******************************************************************************
4429  * ICreateTypeLib2_SetHelpStringContext {OLEAUT32}
4430  *
4431  *  Sets a context number for the library help string.
4432  *
4433  * PARAMS
4434  *  iface     [I] The type library to set the help string context for.
4435  *  dwContext [I] The help string context.
4436  *
4437  * RETURNS
4438  *  Success: S_OK
4439  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4440  */
4441 static
4442 HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 * iface,
4443                                                       ULONG dwContext)
4444 {
4445     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4446
4447     TRACE("(%p,%d)\n", iface, dwContext);
4448
4449     This->typelib_header.helpstringcontext = dwContext;
4450     return S_OK;
4451 }
4452
4453 /******************************************************************************
4454  * ICreateTypeLib2_SetHelpStringDll {OLEAUT32}
4455  *
4456  *  Set the DLL used to look up localized help strings.
4457  *
4458  * PARAMS
4459  *  iface     [I] The type library to set the help DLL for.
4460  *  szDllName [I] The name of the help DLL.
4461  *
4462  * RETURNS
4463  *  Success: S_OK
4464  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4465  */
4466 static
4467 HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 * iface,
4468                                                   LPOLESTR szDllName)
4469 {
4470     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
4471     int offset;
4472
4473     TRACE("(%p,%s)\n", iface, debugstr_w(szDllName));
4474     if (!szDllName)
4475         return E_INVALIDARG;
4476
4477     offset = ctl2_alloc_string(This, szDllName);
4478     if (offset == -1)
4479         return E_OUTOFMEMORY;
4480     This->typelib_header.varflags |= HELPDLLFLAG;
4481     This->helpStringDll = offset;
4482     return S_OK;
4483 }
4484
4485 /*================== ITypeLib2 Implementation ===================================*/
4486
4487 /******************************************************************************
4488  * ITypeLib2_QueryInterface {OLEAUT32}
4489  *
4490  *  See IUnknown_QueryInterface.
4491  */
4492 static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 * iface, REFIID riid, LPVOID * ppv)
4493 {
4494     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4495
4496     return ICreateTypeLib2_QueryInterface((ICreateTypeLib2 *)This, riid, ppv);
4497 }
4498
4499 /******************************************************************************
4500  * ITypeLib2_AddRef {OLEAUT32}
4501  *
4502  *  See IUnknown_AddRef.
4503  */
4504 static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 * iface)
4505 {
4506     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4507
4508     return ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This);
4509 }
4510
4511 /******************************************************************************
4512  * ITypeLib2_Release {OLEAUT32}
4513  *
4514  *  See IUnknown_Release.
4515  */
4516 static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 * iface)
4517 {
4518     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4519
4520     return ICreateTypeLib2_Release((ICreateTypeLib2 *)This);
4521 }
4522
4523 /******************************************************************************
4524  * ITypeLib2_GetTypeInfoCount {OLEAUT32}
4525  *
4526  *  See ITypeLib_GetTypeInfoCount.
4527  */
4528 static UINT WINAPI ITypeLib2_fnGetTypeInfoCount(
4529         ITypeLib2 * iface)
4530 {
4531     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4532
4533     TRACE("(%p)\n", iface);
4534
4535     return This->typelib_header.nrtypeinfos;
4536 }
4537
4538 /******************************************************************************
4539  * ITypeLib2_GetTypeInfo {OLEAUT32}
4540  *
4541  *  See ITypeLib_GetTypeInfo.
4542  */
4543 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
4544         ITypeLib2 * iface,
4545         UINT index,
4546         ITypeInfo** ppTInfo)
4547 {
4548     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4549
4550     TRACE("(%p,%d,%p)\n", iface, index, ppTInfo);
4551
4552     if (index >= This->typelib_header.nrtypeinfos) {
4553         return TYPE_E_ELEMENTNOTFOUND;
4554     }
4555
4556     return ctl2_find_typeinfo_from_offset(This, This->typelib_typeinfo_offsets[index], ppTInfo);
4557 }
4558
4559 /******************************************************************************
4560  * ITypeLib2_GetTypeInfoType {OLEAUT32}
4561  *
4562  *  See ITypeLib_GetTypeInfoType.
4563  */
4564 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
4565         ITypeLib2 * iface,
4566         UINT index,
4567         TYPEKIND* pTKind)
4568 {
4569     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4570
4571     TRACE("(%p,%d,%p)\n", iface, index, pTKind);
4572
4573     if (index >= This->typelib_header.nrtypeinfos) {
4574         return TYPE_E_ELEMENTNOTFOUND;
4575     }
4576
4577     *pTKind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 15;
4578
4579     return S_OK;
4580 }
4581
4582 /******************************************************************************
4583  * ITypeLib2_GetTypeInfoOfGuid {OLEAUT32}
4584  *
4585  *  See ITypeLib_GetTypeInfoOfGuid.
4586  */
4587 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
4588         ITypeLib2 * iface,
4589         REFGUID guid,
4590         ITypeInfo** ppTinfo)
4591 {
4592     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4593
4594     int guidoffset;
4595     int typeinfo;
4596
4597     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), ppTinfo);
4598
4599     guidoffset = ctl2_find_guid(This, ctl2_hash_guid(guid), guid);
4600     if (guidoffset == -1) return TYPE_E_ELEMENTNOTFOUND;
4601
4602     typeinfo = ((MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][guidoffset])->hreftype;
4603     if (typeinfo < 0) return TYPE_E_ELEMENTNOTFOUND;
4604
4605     return ctl2_find_typeinfo_from_offset(This, typeinfo, ppTinfo);
4606 }
4607
4608 /******************************************************************************
4609  * ITypeLib2_GetLibAttr {OLEAUT32}
4610  *
4611  *  See ITypeLib_GetLibAttr.
4612  */
4613 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
4614         ITypeLib2 * iface,
4615         TLIBATTR** ppTLibAttr)
4616 {
4617     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4618
4619     TRACE("(%p,%p)\n", This, ppTLibAttr);
4620
4621     if(!ppTLibAttr)
4622         return E_INVALIDARG;
4623
4624     *ppTLibAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TLIBATTR));
4625     if(!*ppTLibAttr)
4626         return E_OUTOFMEMORY;
4627
4628     if(This->typelib_header.posguid != -1) {
4629         MSFT_GuidEntry *guid;
4630
4631         guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid];
4632         (*ppTLibAttr)->guid = guid->guid;
4633     }
4634
4635     (*ppTLibAttr)->lcid = This->typelib_header.lcid;
4636     (*ppTLibAttr)->syskind = This->typelib_header.varflags&0x3;
4637     (*ppTLibAttr)->wMajorVerNum = This->typelib_header.version&0xffff;
4638     (*ppTLibAttr)->wMinorVerNum = This->typelib_header.version>>16;
4639     (*ppTLibAttr)->wLibFlags = This->typelib_header.flags;
4640     return S_OK;
4641 }
4642
4643 /******************************************************************************
4644  * ITypeLib2_GetTypeComp {OLEAUT32}
4645  *
4646  *  See ITypeLib_GetTypeComp.
4647  */
4648 static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
4649         ITypeLib2 * iface,
4650         ITypeComp** ppTComp)
4651 {
4652     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4653
4654     FIXME("(%p,%p), stub!\n", This, ppTComp);
4655
4656     return E_OUTOFMEMORY;
4657 }
4658
4659 /******************************************************************************
4660  * ITypeLib2_GetDocumentation {OLEAUT32}
4661  *
4662  *  See ITypeLib_GetDocumentation.
4663  */
4664 static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
4665         ITypeLib2 * iface,
4666         INT index,
4667         BSTR* pBstrName,
4668         BSTR* pBstrDocString,
4669         DWORD* pdwHelpContext,
4670         BSTR* pBstrHelpFile)
4671 {
4672     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4673     WCHAR *string;
4674
4675     TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
4676
4677     if(index != -1) {
4678         ICreateTypeInfo2Impl *iter;
4679
4680         for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo)
4681             index--;
4682
4683         if(!iter)
4684             return TYPE_E_ELEMENTNOTFOUND;
4685
4686         return ITypeInfo_GetDocumentation((ITypeInfo*)&iter->lpVtblTypeInfo2,
4687                 -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
4688     }
4689
4690     if(pBstrName) {
4691         if(This->typelib_header.NameOffset == -1)
4692             *pBstrName = NULL;
4693         else {
4694             MSFT_NameIntro *name = (MSFT_NameIntro*)&This->
4695                 typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset];
4696
4697             ctl2_decode_name((char*)&name->namelen, &string);
4698
4699             *pBstrName = SysAllocString(string);
4700             if(!*pBstrName)
4701                 return E_OUTOFMEMORY;
4702         }
4703     }
4704
4705     if(pBstrDocString) {
4706         if(This->typelib_header.helpstring == -1)
4707             *pBstrDocString = NULL;
4708         else {
4709             ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string);
4710
4711             *pBstrDocString = SysAllocString(string);
4712             if(!*pBstrDocString) {
4713                 if(pBstrName) SysFreeString(*pBstrName);
4714                 return E_OUTOFMEMORY;
4715             }
4716         }
4717     }
4718
4719     if(pdwHelpContext)
4720         *pdwHelpContext = This->typelib_header.helpcontext;
4721
4722     if(pBstrHelpFile) {
4723         if(This->typelib_header.helpfile == -1)
4724             *pBstrHelpFile = NULL;
4725         else {
4726             ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string);
4727
4728             *pBstrHelpFile = SysAllocString(string);
4729             if(!*pBstrHelpFile) {
4730                 if(pBstrName) SysFreeString(*pBstrName);
4731                 if(pBstrDocString) SysFreeString(*pBstrDocString);
4732                 return E_OUTOFMEMORY;
4733             }
4734         }
4735     }
4736
4737     return S_OK;
4738 }
4739
4740 /******************************************************************************
4741  * ITypeLib2_IsName {OLEAUT32}
4742  *
4743  *  See ITypeLib_IsName.
4744  */
4745 static HRESULT WINAPI ITypeLib2_fnIsName(
4746         ITypeLib2 * iface,
4747         LPOLESTR szNameBuf,
4748         ULONG lHashVal,
4749         BOOL* pfName)
4750 {
4751     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4752
4753     char *encoded_name;
4754     int nameoffset;
4755     MSFT_NameIntro *nameintro;
4756
4757     TRACE("(%p,%s,%x,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName);
4758
4759     ctl2_encode_name(This, szNameBuf, &encoded_name);
4760     nameoffset = ctl2_find_name(This, encoded_name);
4761
4762     *pfName = 0;
4763
4764     if (nameoffset == -1) return S_OK;
4765
4766     nameintro = (MSFT_NameIntro *)(&This->typelib_segment_data[MSFT_SEG_NAME][nameoffset]);
4767     if (nameintro->hreftype == -1) return S_OK;
4768
4769     *pfName = 1;
4770
4771     FIXME("Should be decoding our copy of the name over szNameBuf.\n");
4772
4773     return S_OK;
4774 }
4775
4776 /******************************************************************************
4777  * ITypeLib2_FindName {OLEAUT32}
4778  *
4779  *  See ITypeLib_FindName.
4780  */
4781 static HRESULT WINAPI ITypeLib2_fnFindName(
4782         ITypeLib2 * iface,
4783         LPOLESTR szNameBuf,
4784         ULONG lHashVal,
4785         ITypeInfo** ppTInfo,
4786         MEMBERID* rgMemId,
4787         USHORT* pcFound)
4788 {
4789     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4790
4791     FIXME("(%p,%s,%x,%p,%p,%p), stub!\n", This, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound);
4792
4793     return E_OUTOFMEMORY;
4794 }
4795
4796 /******************************************************************************
4797  * ITypeLib2_ReleaseTLibAttr {OLEAUT32}
4798  *
4799  *  See ITypeLib_ReleaseTLibAttr.
4800  */
4801 static void WINAPI ITypeLib2_fnReleaseTLibAttr(
4802         ITypeLib2 * iface,
4803         TLIBATTR* pTLibAttr)
4804 {
4805     TRACE("(%p,%p)\n", iface, pTLibAttr);
4806
4807     HeapFree(GetProcessHeap(), 0, pTLibAttr);
4808 }
4809
4810 /******************************************************************************
4811  * ICreateTypeLib2_GetCustData {OLEAUT32}
4812  *
4813  *  Retrieves a custom data value stored on a type library.
4814  *
4815  * RETURNS
4816  *
4817  *  Success: S_OK
4818  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4819  */
4820 static HRESULT WINAPI ITypeLib2_fnGetCustData(
4821         ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */
4822         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
4823         VARIANT* pVarVal)  /* [O] The custom data. */
4824 {
4825     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4826
4827     FIXME("(%p,%s,%p), stub!\n", This, debugstr_guid(guid), pVarVal);
4828
4829     return E_OUTOFMEMORY;
4830 }
4831
4832 /******************************************************************************
4833  * ICreateTypeLib2_GetLibStatistics {OLEAUT32}
4834  *
4835  *  Retrieves some statistics about names in a type library, supposedly for
4836  *  hash table optimization purposes.
4837  *
4838  * RETURNS
4839  *
4840  *  Success: S_OK
4841  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4842  */
4843 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
4844         ITypeLib2 * iface,      /* [I] The type library to get statistics about. */
4845         ULONG* pcUniqueNames,   /* [O] The number of unique names in the type library. */
4846         ULONG* pcchUniqueNames) /* [O] The number of changed (?) characters in names in the type library. */
4847 {
4848     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4849
4850     FIXME("(%p,%p,%p), stub!\n", This, pcUniqueNames, pcchUniqueNames);
4851
4852     return E_OUTOFMEMORY;
4853 }
4854
4855 /******************************************************************************
4856  * ICreateTypeLib2_GetDocumentation2 {OLEAUT32}
4857  *
4858  *  Obtain locale-aware help string information.
4859  *
4860  * RETURNS
4861  *
4862  *  Success: S_OK
4863  *  Failure: STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
4864  */
4865 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
4866         ITypeLib2 * iface,
4867         INT index,
4868         LCID lcid,
4869         BSTR* pbstrHelpString,
4870         DWORD* pdwHelpStringContext,
4871         BSTR* pbstrHelpStringDll)
4872 {
4873     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4874
4875     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", This, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
4876
4877     return E_OUTOFMEMORY;
4878 }
4879
4880 /******************************************************************************
4881  * ICreateTypeLib2_GetAllCustData {OLEAUT32}
4882  *
4883  *  Retrieve all of the custom data for a type library.
4884  *
4885  * RETURNS
4886  *
4887  *  Success: S_OK
4888  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
4889  */
4890 static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
4891         ITypeLib2 * iface,   /* [I] The type library in which to find the custom data. */
4892         CUSTDATA* pCustData) /* [O] The structure in which to place the custom data. */
4893 {
4894     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
4895
4896     FIXME("(%p,%p), stub!\n", This, pCustData);
4897
4898     return E_OUTOFMEMORY;
4899 }
4900
4901
4902 /*================== ICreateTypeLib2 & ITypeLib2 VTABLEs And Creation ===================================*/
4903
4904 static const ICreateTypeLib2Vtbl ctypelib2vt =
4905 {
4906
4907     ICreateTypeLib2_fnQueryInterface,
4908     ICreateTypeLib2_fnAddRef,
4909     ICreateTypeLib2_fnRelease,
4910
4911     ICreateTypeLib2_fnCreateTypeInfo,
4912     ICreateTypeLib2_fnSetName,
4913     ICreateTypeLib2_fnSetVersion,
4914     ICreateTypeLib2_fnSetGuid,
4915     ICreateTypeLib2_fnSetDocString,
4916     ICreateTypeLib2_fnSetHelpFileName,
4917     ICreateTypeLib2_fnSetHelpContext,
4918     ICreateTypeLib2_fnSetLcid,
4919     ICreateTypeLib2_fnSetLibFlags,
4920     ICreateTypeLib2_fnSaveAllChanges,
4921
4922     ICreateTypeLib2_fnDeleteTypeInfo,
4923     ICreateTypeLib2_fnSetCustData,
4924     ICreateTypeLib2_fnSetHelpStringContext,
4925     ICreateTypeLib2_fnSetHelpStringDll
4926 };
4927
4928 static const ITypeLib2Vtbl typelib2vt =
4929 {
4930
4931     ITypeLib2_fnQueryInterface,
4932     ITypeLib2_fnAddRef,
4933     ITypeLib2_fnRelease,
4934
4935     ITypeLib2_fnGetTypeInfoCount,
4936     ITypeLib2_fnGetTypeInfo,
4937     ITypeLib2_fnGetTypeInfoType,
4938     ITypeLib2_fnGetTypeInfoOfGuid,
4939     ITypeLib2_fnGetLibAttr,
4940     ITypeLib2_fnGetTypeComp,
4941     ITypeLib2_fnGetDocumentation,
4942     ITypeLib2_fnIsName,
4943     ITypeLib2_fnFindName,
4944     ITypeLib2_fnReleaseTLibAttr,
4945
4946     ITypeLib2_fnGetCustData,
4947     ITypeLib2_fnGetLibStatistics,
4948     ITypeLib2_fnGetDocumentation2,
4949     ITypeLib2_fnGetAllCustData,
4950 };
4951
4952 static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR szFile)
4953 {
4954     ICreateTypeLib2Impl *pCreateTypeLib2Impl;
4955     int failed = 0;
4956
4957     TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(szFile));
4958
4959     pCreateTypeLib2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeLib2Impl));
4960     if (!pCreateTypeLib2Impl) return NULL;
4961
4962     pCreateTypeLib2Impl->filename = HeapAlloc(GetProcessHeap(), 0, (strlenW(szFile) + 1) * sizeof(WCHAR));
4963     if (!pCreateTypeLib2Impl->filename) {
4964         HeapFree(GetProcessHeap(), 0, pCreateTypeLib2Impl);
4965         return NULL;
4966     }
4967     strcpyW(pCreateTypeLib2Impl->filename, szFile);
4968
4969     ctl2_init_header(pCreateTypeLib2Impl);
4970     ctl2_init_segdir(pCreateTypeLib2Impl);
4971
4972     pCreateTypeLib2Impl->typelib_header.varflags |= syskind;
4973
4974     /*
4975      * The following two calls return an offset or -1 if out of memory. We
4976      * specifically need an offset of 0, however, so...
4977      */
4978     if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; }
4979     if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; }
4980
4981     pCreateTypeLib2Impl->typelib_guidhash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_GUIDHASH];
4982     pCreateTypeLib2Impl->typelib_namehash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_NAMEHASH];
4983
4984     memset(pCreateTypeLib2Impl->typelib_guidhash_segment, 0xff, 0x80);
4985     memset(pCreateTypeLib2Impl->typelib_namehash_segment, 0xff, 0x200);
4986
4987     pCreateTypeLib2Impl->lpVtbl = &ctypelib2vt;
4988     pCreateTypeLib2Impl->lpVtblTypeLib2 = &typelib2vt;
4989     pCreateTypeLib2Impl->ref = 1;
4990
4991     if (failed) {
4992         ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)pCreateTypeLib2Impl);
4993         return 0;
4994     }
4995
4996     return (ICreateTypeLib2 *)pCreateTypeLib2Impl;
4997 }
4998
4999 /******************************************************************************
5000  * CreateTypeLib2 [OLEAUT32.180]
5001  *
5002  *  Obtains an ICreateTypeLib2 object for creating a new-style (MSFT) type
5003  *  library.
5004  *
5005  * NOTES
5006  *
5007  *  See also CreateTypeLib.
5008  *
5009  * RETURNS
5010  *    Success: S_OK
5011  *    Failure: Status
5012  */
5013 HRESULT WINAPI CreateTypeLib2(
5014         SYSKIND syskind,           /* [I] System type library is for */
5015         LPCOLESTR szFile,          /* [I] Type library file name */
5016         ICreateTypeLib2** ppctlib) /* [O] Storage for object returned */
5017 {
5018     TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib);
5019
5020     if (!szFile) return E_INVALIDARG;
5021     *ppctlib = ICreateTypeLib2_Constructor(syskind, szFile);
5022     return (*ppctlib)? S_OK: E_OUTOFMEMORY;
5023 }
5024
5025 /******************************************************************************
5026  * ClearCustData (OLEAUT32.171)
5027  *
5028  * Clear a custom data types' data.
5029  *
5030  * PARAMS
5031  *  lpCust [I] The custom data type instance
5032  *
5033  * RETURNS
5034  *  Nothing.
5035  */
5036 void WINAPI ClearCustData(LPCUSTDATA lpCust)
5037 {
5038     if (lpCust && lpCust->cCustData)
5039     {
5040         if (lpCust->prgCustData)
5041         {
5042             DWORD i;
5043
5044             for (i = 0; i < lpCust->cCustData; i++)
5045                 VariantClear(&lpCust->prgCustData[i].varValue);
5046
5047             /* FIXME - Should be using a per-thread IMalloc */
5048             HeapFree(GetProcessHeap(), 0, lpCust->prgCustData);
5049             lpCust->prgCustData = NULL;
5050         }
5051         lpCust->cCustData = 0;
5052     }
5053 }