ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

typelib2.c
Go to the documentation of this file.
00001 /*
00002  *  TYPELIB2
00003  *
00004  *  Copyright 2004  Alastair Bridgewater
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  *
00020  * --------------------------------------------------------------------------------------
00021  *  Known problems:
00022  *
00023  *    Badly incomplete.
00024  *
00025  *    Only works on little-endian systems.
00026  *
00027  */
00028 
00029 #include "config.h"
00030 #include "wine/port.h"
00031 
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <stdarg.h>
00035 #include <stdio.h>
00036 #include <ctype.h>
00037 
00038 #define COBJMACROS
00039 #define NONAMELESSUNION
00040 #define NONAMELESSSTRUCT
00041 
00042 #include "winerror.h"
00043 #include "windef.h"
00044 #include "winbase.h"
00045 #include "winnls.h"
00046 #include "winreg.h"
00047 #include "winuser.h"
00048 
00049 #include "wine/unicode.h"
00050 #include "objbase.h"
00051 #include "typelib.h"
00052 #include "wine/debug.h"
00053 
00054 WINE_DEFAULT_DEBUG_CHANNEL(typelib2);
00055 /* WINE_DEFAULT_DEBUG_CHANNEL(ole); */
00056 
00057 
00058 /******************************************************************************
00059  * ICreateTypeLib2 {OLEAUT32}
00060  *
00061  * NOTES
00062  *  The ICreateTypeLib2 interface provides an interface whereby one may create
00063  *  new type library (.tlb) files.
00064  *
00065  *  This interface inherits from ICreateTypeLib, and can be freely cast back
00066  *  and forth between an ICreateTypeLib and an ICreateTypeLib2 on local clients.
00067  *  This dispensation applies only to ICreateTypeLib objects obtained on MSFT
00068  *  format type libraries (those made through CreateTypeLib2).
00069  *
00070  * METHODS
00071  */
00072 
00073 /******************************************************************************
00074  * ICreateTypeInfo2 {OLEAUT32}
00075  *
00076  * NOTES
00077  *  The ICreateTypeInfo2 interface provides an interface whereby one may add
00078  *  type information to type library (.tlb) files.
00079  *
00080  *  This interface inherits from ICreateTypeInfo, and can be freely cast back
00081  *  and forth between an ICreateTypeInfo and an ICreateTypeInfo2 on local clients.
00082  *  This dispensation applies only to ICreateTypeInfo objects obtained on MSFT
00083  *  format type libraries (those made through CreateTypeLib2).
00084  *
00085  * METHODS
00086  */
00087 
00088 /******************************************************************************
00089  * ITypeLib2 {OLEAUT32}
00090  *
00091  * NOTES
00092  *  The ITypeLib2 interface provides an interface whereby one may query MSFT
00093  *  format type library (.tlb) files.
00094  *
00095  *  This interface inherits from ITypeLib, and can be freely cast back and
00096  *  forth between an ITypeLib and an ITypeLib2 on local clients. This
00097  *  dispensation applies only to ITypeLib objects obtained on MSFT format type
00098  *  libraries (those made through CreateTypeLib2).
00099  *
00100  * METHODS
00101  */
00102 
00103 /******************************************************************************
00104  * ITypeInfo2 {OLEAUT32}
00105  *
00106  * NOTES
00107  *  The ITypeInfo2 interface provides an interface whereby one may query type
00108  *  information stored in MSFT format type library (.tlb) files.
00109  *
00110  *  This interface inherits from ITypeInfo, and can be freely cast back and
00111  *  forth between an ITypeInfo and an ITypeInfo2 on local clients. This
00112  *  dispensation applies only to ITypeInfo objects obtained on MSFT format type
00113  *  libraries (those made through CreateTypeLib2).
00114  *
00115  * METHODS
00116  */
00117 
00118 /*================== Implementation Structures ===================================*/
00119 
00120 /* Used for storing cyclic list. Tail address is kept */
00121 enum tagCyclicListElementType {
00122     CyclicListFunc,
00123     CyclicListVar
00124 };
00125 typedef struct tagCyclicList {
00126     struct tagCyclicList *next;
00127     int indice;
00128     int name;
00129     enum tagCyclicListElementType type;
00130 
00131     union {
00132         int val;
00133         int *data;
00134     }u;
00135 } CyclicList;
00136 
00137 enum MSFT_segment_index {
00138     MSFT_SEG_TYPEINFO = 0,  /* type information */
00139     MSFT_SEG_IMPORTINFO,    /* import information */
00140     MSFT_SEG_IMPORTFILES,   /* import filenames */
00141     MSFT_SEG_REFERENCES,    /* references (?) */
00142     MSFT_SEG_GUIDHASH,      /* hash table for guids? */
00143     MSFT_SEG_GUID,          /* guid storage */
00144     MSFT_SEG_NAMEHASH,      /* hash table for names */
00145     MSFT_SEG_NAME,          /* name storage */
00146     MSFT_SEG_STRING,        /* string storage */
00147     MSFT_SEG_TYPEDESC,      /* type descriptions */
00148     MSFT_SEG_ARRAYDESC,     /* array descriptions */
00149     MSFT_SEG_CUSTDATA,      /* custom data */
00150     MSFT_SEG_CUSTDATAGUID,  /* custom data guids */
00151     MSFT_SEG_UNKNOWN,       /* ??? */
00152     MSFT_SEG_UNKNOWN2,      /* ??? */
00153     MSFT_SEG_MAX            /* total number of segments */
00154 };
00155 
00156 typedef struct tagMSFT_ImpFile {
00157     int guid;
00158     LCID lcid;
00159     int version;
00160     char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */
00161 } MSFT_ImpFile;
00162 
00163 typedef struct tagICreateTypeLib2Impl
00164 {
00165     const ICreateTypeLib2Vtbl *lpVtbl;
00166     const ITypeLib2Vtbl       *lpVtblTypeLib2;
00167 
00168     LONG ref;
00169 
00170     WCHAR *filename;
00171 
00172     MSFT_Header typelib_header;
00173     INT helpStringDll;
00174     MSFT_pSeg typelib_segdir[MSFT_SEG_MAX];
00175     char *typelib_segment_data[MSFT_SEG_MAX];
00176     int typelib_segment_block_length[MSFT_SEG_MAX];
00177 
00178     int typelib_guids; /* Number of defined typelib guids */
00179     int typeinfo_guids; /* Number of defined typeinfo guids */
00180 
00181     INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */
00182 
00183     INT *typelib_namehash_segment;
00184     INT *typelib_guidhash_segment;
00185 
00186     struct tagICreateTypeInfo2Impl *typeinfos;
00187     struct tagICreateTypeInfo2Impl *last_typeinfo;
00188 } ICreateTypeLib2Impl;
00189 
00190 static inline ICreateTypeLib2Impl *impl_from_ITypeLib2( ITypeLib2 *iface )
00191 {
00192     return (ICreateTypeLib2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeLib2Impl, lpVtblTypeLib2));
00193 }
00194 
00195 typedef struct tagICreateTypeInfo2Impl
00196 {
00197     const ICreateTypeInfo2Vtbl *lpVtbl;
00198     const ITypeInfo2Vtbl       *lpVtblTypeInfo2;
00199 
00200     LONG ref;
00201 
00202     ICreateTypeLib2Impl *typelib;
00203     MSFT_TypeInfoBase *typeinfo;
00204 
00205     struct tagCyclicList *typedata; /* tail of cyclic list */
00206 
00207     TYPEKIND typekind;
00208     int datawidth;
00209 
00210     struct tagICreateTypeInfo2Impl *next_typeinfo;
00211     struct tagICreateTypeInfo2Impl *dual;
00212 } ICreateTypeInfo2Impl;
00213 
00214 static inline ICreateTypeInfo2Impl *impl_from_ITypeInfo2( ITypeInfo2 *iface )
00215 {
00216     return (ICreateTypeInfo2Impl *)((char*)iface - FIELD_OFFSET(ICreateTypeInfo2Impl, lpVtblTypeInfo2));
00217 }
00218 
00219 static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface);
00220 
00221 
00222 /*================== Internal functions ===================================*/
00223 
00224 /****************************************************************************
00225  *  ctl2_init_header
00226  *
00227  *  Initializes the type library header of a new typelib.
00228  */
00229 static void ctl2_init_header(
00230     ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */
00231 {
00232     This->typelib_header.magic1 = 0x5446534d;
00233     This->typelib_header.magic2 = 0x00010002;
00234     This->typelib_header.posguid = -1;
00235     This->typelib_header.lcid = This->typelib_header.lcid2 = GetUserDefaultLCID();
00236     This->typelib_header.varflags = 0x40;
00237     This->typelib_header.version = 0;
00238     This->typelib_header.flags = 0;
00239     This->typelib_header.nrtypeinfos = 0;
00240     This->typelib_header.helpstring = -1;
00241     This->typelib_header.helpstringcontext = 0;
00242     This->typelib_header.helpcontext = 0;
00243     This->typelib_header.nametablecount = 0;
00244     This->typelib_header.nametablechars = 0;
00245     This->typelib_header.NameOffset = -1;
00246     This->typelib_header.helpfile = -1;
00247     This->typelib_header.CustomDataOffset = -1;
00248     This->typelib_header.res44 = 0x20;
00249     This->typelib_header.res48 = 0x80;
00250     This->typelib_header.dispatchpos = -1;
00251     This->typelib_header.nimpinfos = 0;
00252     This->helpStringDll = -1;
00253 }
00254 
00255 /****************************************************************************
00256  *  ctl2_init_segdir
00257  *
00258  *  Initializes the segment directory of a new typelib.
00259  */
00260 static void ctl2_init_segdir(
00261     ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */
00262 {
00263     int i;
00264     MSFT_pSeg *segdir;
00265 
00266     segdir = &This->typelib_segdir[MSFT_SEG_TYPEINFO];
00267 
00268     for (i = 0; i < 15; i++) {
00269     segdir[i].offset = -1;
00270     segdir[i].length = 0;
00271     segdir[i].res08 = -1;
00272     segdir[i].res0c = 0x0f;
00273     }
00274 }
00275 
00276 /****************************************************************************
00277  *  ctl2_hash_guid
00278  *
00279  *  Generates a hash key from a GUID.
00280  *
00281  * RETURNS
00282  *
00283  *  The hash key for the GUID.
00284  */
00285 static int ctl2_hash_guid(
00286     REFGUID guid)                /* [I] The guid to find. */
00287 {
00288     int hash;
00289     int i;
00290 
00291     hash = 0;
00292     for (i = 0; i < 8; i ++) {
00293     hash ^= ((const short *)guid)[i];
00294     }
00295 
00296     return hash & 0x1f;
00297 }
00298 
00299 /****************************************************************************
00300  *  ctl2_find_guid
00301  *
00302  *  Locates a guid in a type library.
00303  *
00304  * RETURNS
00305  *
00306  *  The offset into the GUID segment of the guid, or -1 if not found.
00307  */
00308 static int ctl2_find_guid(
00309     ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */
00310     int hash_key,              /* [I] The hash key for the guid. */
00311     REFGUID guid)                /* [I] The guid to find. */
00312 {
00313     int offset;
00314     MSFT_GuidEntry *guidentry;
00315 
00316     offset = This->typelib_guidhash_segment[hash_key];
00317     while (offset != -1) {
00318     guidentry = (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][offset];
00319 
00320         if (IsEqualGUID(guidentry, guid)) return offset;
00321 
00322     offset = guidentry->next_hash;
00323     }
00324 
00325     return offset;
00326 }
00327 
00328 /****************************************************************************
00329  *  ctl2_find_name
00330  *
00331  *  Locates a name in a type library.
00332  *
00333  * RETURNS
00334  *
00335  *  The offset into the NAME segment of the name, or -1 if not found.
00336  *
00337  * NOTES
00338  *
00339  *  The name must be encoded as with ctl2_encode_name().
00340  */
00341 static int ctl2_find_name(
00342     ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */
00343     const char *name)          /* [I] The encoded name to find. */
00344 {
00345     int offset;
00346     int *namestruct;
00347 
00348     offset = This->typelib_namehash_segment[name[2] & 0x7f];
00349     while (offset != -1) {
00350     namestruct = (int *)&This->typelib_segment_data[MSFT_SEG_NAME][offset];
00351 
00352     if (!((namestruct[2] ^ *((const int *)name)) & 0xffff00ff)) {
00353         /* hash codes and lengths match, final test */
00354         if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break;
00355     }
00356 
00357     /* move to next item in hash bucket */
00358     offset = namestruct[1];
00359     }
00360 
00361     return offset;
00362 }
00363 
00364 /****************************************************************************
00365  *  ctl2_encode_name
00366  *
00367  *  Encodes a name string to a form suitable for storing into a type library
00368  *  or comparing to a name stored in a type library.
00369  *
00370  * RETURNS
00371  *
00372  *  The length of the encoded name, including padding and length+hash fields.
00373  *
00374  * NOTES
00375  *
00376  *  Will throw an exception if name or result are NULL. Is not multithread
00377  *  safe in the slightest.
00378  */
00379 static int ctl2_encode_name(
00380     ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (used for LCID only). */
00381     const WCHAR *name,         /* [I] The name string to encode. */
00382     char **result)             /* [O] A pointer to a pointer to receive the encoded name. */
00383 {
00384     int length;
00385     static char converted_name[0x104];
00386     int offset;
00387     int value;
00388 
00389     length = WideCharToMultiByte(CP_ACP, 0, name, strlenW(name), converted_name+4, 0x100, NULL, NULL);
00390     converted_name[0] = length & 0xff;
00391 
00392     converted_name[length + 4] = 0;
00393 
00394     converted_name[1] = 0x00;
00395 
00396     value = LHashValOfNameSysA(This->typelib_header.varflags & 0x0f, This->typelib_header.lcid, converted_name + 4);
00397 
00398     converted_name[2] = value;
00399     converted_name[3] = value >> 8;
00400 
00401     for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57;
00402 
00403     *result = converted_name;
00404 
00405     return (length + 7) & ~3;
00406 }
00407 
00408 /****************************************************************************
00409  *      ctl2_decode_name
00410  *
00411  * Converts string stored in typelib data to unicode.
00412  */
00413 static void ctl2_decode_name(
00414         char *data,         /* [I] String to be decoded */
00415         WCHAR **string)     /* [O] Decoded string */
00416 {
00417     int i, length;
00418     static WCHAR converted_string[0x104];
00419 
00420     length = data[0];
00421 
00422     for(i=0; i<length; i++)
00423         converted_string[i] = data[i+4];
00424     converted_string[length] = '\0';
00425 
00426     *string = converted_string;
00427 }
00428 
00429 /****************************************************************************
00430  *  ctl2_encode_string
00431  *
00432  *  Encodes a string to a form suitable for storing into a type library or
00433  *  comparing to a string stored in a type library.
00434  *
00435  * RETURNS
00436  *
00437  *  The length of the encoded string, including padding and length fields.
00438  *
00439  * NOTES
00440  *
00441  *  Will throw an exception if string or result are NULL. Is not multithread
00442  *  safe in the slightest.
00443  */
00444 static int ctl2_encode_string(
00445     ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (not used?). */
00446     const WCHAR *string,       /* [I] The string to encode. */
00447     char **result)             /* [O] A pointer to a pointer to receive the encoded string. */
00448 {
00449     int length;
00450     static char converted_string[0x104];
00451     int offset;
00452 
00453     length = WideCharToMultiByte(CP_ACP, 0, string, strlenW(string), converted_string+2, 0x102, NULL, NULL);
00454     converted_string[0] = length & 0xff;
00455     converted_string[1] = (length >> 8) & 0xff;
00456 
00457     for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57;
00458 
00459     *result = converted_string;
00460 
00461     return (length + 5) & ~3;
00462 }
00463 
00464 /****************************************************************************
00465  *      ctl2_decode_string
00466  *
00467  * Converts string stored in typelib data to unicode.
00468  */
00469 static void ctl2_decode_string(
00470         char *data,         /* [I] String to be decoded */
00471         WCHAR **string)     /* [O] Decoded string */
00472 {
00473     int i, length;
00474     static WCHAR converted_string[0x104];
00475 
00476     length = data[0] + (data[1]<<8);
00477     if((length&0x3) == 1)
00478         length >>= 2;
00479 
00480     for(i=0; i<length; i++)
00481         converted_string[i] = data[i+2];
00482     converted_string[length] = '\0';
00483 
00484     *string = converted_string;
00485 }
00486 
00487 /****************************************************************************
00488  *  ctl2_alloc_segment
00489  *
00490  *  Allocates memory from a segment in a type library.
00491  *
00492  * RETURNS
00493  *
00494  *  Success: The offset within the segment of the new data area.
00495  *  Failure: -1 (this is invariably an out of memory condition).
00496  *
00497  * BUGS
00498  *
00499  *  Does not (yet) handle the case where the allocated segment memory needs to grow.
00500  */
00501 static int ctl2_alloc_segment(
00502     ICreateTypeLib2Impl *This,       /* [I] The type library in which to allocate. */
00503     enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */
00504     int size,                        /* [I] The amount to allocate. */
00505     int block_size)                  /* [I] Initial allocation block size, or 0 for default. */
00506 {
00507     int offset;
00508 
00509     if(!This->typelib_segment_data[segment]) {
00510     if (!block_size) block_size = 0x2000;
00511 
00512     This->typelib_segment_block_length[segment] = block_size;
00513     This->typelib_segment_data[segment] = HeapAlloc(GetProcessHeap(), 0, block_size);
00514     if (!This->typelib_segment_data[segment]) return -1;
00515     memset(This->typelib_segment_data[segment], 0x57, block_size);
00516     }
00517 
00518     while ((This->typelib_segdir[segment].length + size) > This->typelib_segment_block_length[segment]) {
00519     char *block;
00520 
00521     block_size = This->typelib_segment_block_length[segment];
00522     block = HeapReAlloc(GetProcessHeap(), 0, This->typelib_segment_data[segment], block_size << 1);
00523     if (!block) return -1;
00524 
00525     if (segment == MSFT_SEG_TYPEINFO) {
00526         /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */
00527         ICreateTypeInfo2Impl *typeinfo;
00528 
00529         for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
00530         typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - This->typelib_segment_data[segment]];
00531         }
00532     }
00533 
00534     memset(block + block_size, 0x57, block_size);
00535     This->typelib_segment_block_length[segment] = block_size << 1;
00536     This->typelib_segment_data[segment] = block;
00537     }
00538 
00539     offset = This->typelib_segdir[segment].length;
00540     This->typelib_segdir[segment].length += size;
00541 
00542     return offset;
00543 }
00544 
00545 /****************************************************************************
00546  *  ctl2_alloc_typeinfo
00547  *
00548  *  Allocates and initializes a typeinfo structure in a type library.
00549  *
00550  * RETURNS
00551  *
00552  *  Success: The offset of the new typeinfo.
00553  *  Failure: -1 (this is invariably an out of memory condition).
00554  */
00555 static int ctl2_alloc_typeinfo(
00556     ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
00557     int nameoffset)            /* [I] The offset of the name for this typeinfo. */
00558 {
00559     int offset;
00560     MSFT_TypeInfoBase *typeinfo;
00561 
00562     offset = ctl2_alloc_segment(This, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0);
00563     if (offset == -1) return -1;
00564 
00565     This->typelib_typeinfo_offsets[This->typelib_header.nrtypeinfos++] = offset;
00566 
00567     typeinfo = (void *)(This->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset);
00568 
00569     typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16;
00570     typeinfo->memoffset = -1; /* should be EOF if no elements */
00571     typeinfo->res2 = 0;
00572     typeinfo->res3 = 0;
00573     typeinfo->res4 = 3;
00574     typeinfo->res5 = 0;
00575     typeinfo->cElement = 0;
00576     typeinfo->res7 = 0;
00577     typeinfo->res8 = 0;
00578     typeinfo->res9 = 0;
00579     typeinfo->resA = 0;
00580     typeinfo->posguid = -1;
00581     typeinfo->flags = 0;
00582     typeinfo->NameOffset = nameoffset;
00583     typeinfo->version = 0;
00584     typeinfo->docstringoffs = -1;
00585     typeinfo->helpstringcontext = 0;
00586     typeinfo->helpcontext = 0;
00587     typeinfo->oCustData = -1;
00588     typeinfo->cbSizeVft = 0;
00589     typeinfo->cImplTypes = 0;
00590     typeinfo->size = 0;
00591     typeinfo->datatype1 = -1;
00592     typeinfo->datatype2 = 0;
00593     typeinfo->res18 = 0;
00594     typeinfo->res19 = -1;
00595 
00596     return offset;
00597 }
00598 
00599 /****************************************************************************
00600  *  ctl2_alloc_guid
00601  *
00602  *  Allocates and initializes a GUID structure in a type library. Also updates
00603  *  the GUID hash table as needed.
00604  *
00605  * RETURNS
00606  *
00607  *  Success: The offset of the new GUID.
00608  *  Failure: -1 (this is invariably an out of memory condition).
00609  */
00610 static int ctl2_alloc_guid(
00611     ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
00612     MSFT_GuidEntry *guid)      /* [I] The GUID to store. */
00613 {
00614     int offset;
00615     MSFT_GuidEntry *guid_space;
00616     int hash_key;
00617 
00618     hash_key = ctl2_hash_guid(&guid->guid);
00619 
00620     offset = ctl2_find_guid(This, hash_key, &guid->guid);
00621     if (offset != -1) return offset;
00622 
00623     offset = ctl2_alloc_segment(This, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0);
00624     if (offset == -1) return -1;
00625 
00626     guid_space = (void *)(This->typelib_segment_data[MSFT_SEG_GUID] + offset);
00627     *guid_space = *guid;
00628 
00629     guid_space->next_hash = This->typelib_guidhash_segment[hash_key];
00630     This->typelib_guidhash_segment[hash_key] = offset;
00631 
00632     return offset;
00633 }
00634 
00635 /****************************************************************************
00636  *  ctl2_alloc_name
00637  *
00638  *  Allocates and initializes a name within a type library. Also updates the
00639  *  name hash table as needed.
00640  *
00641  * RETURNS
00642  *
00643  *  Success: The offset within the segment of the new name.
00644  *  Failure: -1 (this is invariably an out of memory condition).
00645  */
00646 static int ctl2_alloc_name(
00647     ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
00648     const WCHAR *name)         /* [I] The name to store. */
00649 {
00650     int length;
00651     int offset;
00652     MSFT_NameIntro *name_space;
00653     char *encoded_name;
00654 
00655     length = ctl2_encode_name(This, name, &encoded_name);
00656 
00657     offset = ctl2_find_name(This, encoded_name);
00658     if (offset != -1) return offset;
00659 
00660     offset = ctl2_alloc_segment(This, MSFT_SEG_NAME, length + 8, 0);
00661     if (offset == -1) return -1;
00662 
00663     name_space = (void *)(This->typelib_segment_data[MSFT_SEG_NAME] + offset);
00664     name_space->hreftype = -1;
00665     name_space->next_hash = -1;
00666     memcpy(&name_space->namelen, encoded_name, length);
00667 
00668     if (This->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1)
00669     name_space->next_hash = This->typelib_namehash_segment[encoded_name[2] & 0x7f];
00670 
00671     This->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset;
00672 
00673     This->typelib_header.nametablecount += 1;
00674     This->typelib_header.nametablechars += *encoded_name;
00675 
00676     return offset;
00677 }
00678 
00679 /****************************************************************************
00680  *  ctl2_alloc_string
00681  *
00682  *  Allocates and initializes a string in a type library.
00683  *
00684  * RETURNS
00685  *
00686  *  Success: The offset within the segment of the new string.
00687  *  Failure: -1 (this is invariably an out of memory condition).
00688  */
00689 static int ctl2_alloc_string(
00690     ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
00691     const WCHAR *string)       /* [I] The string to store. */
00692 {
00693     int length;
00694     int offset;
00695     char *string_space;
00696     char *encoded_string;
00697 
00698     length = ctl2_encode_string(This, string, &encoded_string);
00699 
00700     for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_STRING].length;
00701      offset += ((((This->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff)
00702          | (This->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) {
00703     if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset;
00704     }
00705 
00706     offset = ctl2_alloc_segment(This, MSFT_SEG_STRING, length, 0);
00707     if (offset == -1) return -1;
00708 
00709     string_space = This->typelib_segment_data[MSFT_SEG_STRING] + offset;
00710     memcpy(string_space, encoded_string, length);
00711 
00712     return offset;
00713 }
00714 
00715 /****************************************************************************
00716  *  ctl2_alloc_importinfo
00717  *
00718  *  Allocates and initializes an import information structure in a type library.
00719  *
00720  * RETURNS
00721  *
00722  *  Success: The offset of the new importinfo.
00723  *  Failure: -1 (this is invariably an out of memory condition).
00724  */
00725 static int ctl2_alloc_importinfo(
00726         ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
00727         MSFT_ImpInfo *impinfo)     /* [I] The import information to store. */
00728 {
00729     int offset;
00730     MSFT_ImpInfo *impinfo_space;
00731 
00732     impinfo_space = (MSFT_ImpInfo*)&This->typelib_segment_data[MSFT_SEG_IMPORTINFO][0];
00733     for (offset=0; offset<This->typelib_segdir[MSFT_SEG_IMPORTINFO].length;
00734             offset+=sizeof(MSFT_ImpInfo)) {
00735         if(impinfo_space->oImpFile == impinfo->oImpFile
00736                 && impinfo_space->oGuid == impinfo->oGuid)
00737             return offset;
00738 
00739         impinfo_space += 1;
00740     }
00741 
00742     impinfo->flags |= This->typelib_header.nimpinfos++;
00743 
00744     offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0);
00745     if (offset == -1) return -1;
00746 
00747     impinfo_space = (void *)(This->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset);
00748     *impinfo_space = *impinfo;
00749 
00750     return offset;
00751 }
00752 
00753 /****************************************************************************
00754  *  ctl2_alloc_importfile
00755  *
00756  *  Allocates and initializes an import file definition in a type library.
00757  *
00758  * RETURNS
00759  *
00760  *  Success: The offset of the new importinfo.
00761  *  Failure: -1 (this is invariably an out of memory condition).
00762  */
00763 static int ctl2_alloc_importfile(
00764     ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */
00765     int guidoffset,            /* [I] The offset to the GUID for the imported library. */
00766         LCID lcid,                 /* [I] The LCID of imported library. */
00767     int major_version,         /* [I] The major version number of the imported library. */
00768     int minor_version,         /* [I] The minor version number of the imported library. */
00769     const WCHAR *filename)     /* [I] The filename of the imported library. */
00770 {
00771     int length;
00772     int offset;
00773     MSFT_ImpFile *importfile;
00774     char *encoded_string;
00775 
00776     length = ctl2_encode_string(This, filename, &encoded_string);
00777 
00778     encoded_string[0] <<= 2;
00779     encoded_string[0] |= 1;
00780 
00781     for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_IMPORTFILES].length;
00782      offset += ((((((This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff00)
00783          | (This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 5) & 0xfffc) + 0xc) {
00784     if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset;
00785     }
00786 
00787     offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTFILES, length + 0xc, 0);
00788     if (offset == -1) return -1;
00789 
00790     importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset];
00791     importfile->guid = guidoffset;
00792     importfile->lcid = lcid;
00793     importfile->version = major_version | (minor_version << 16);
00794     memcpy(importfile->filename, encoded_string, length);
00795 
00796     return offset;
00797 }
00798 
00799 /****************************************************************************
00800  *      ctl2_encode_variant
00801  *
00802  *  Encodes a variant, inline if possible or in custom data segment
00803  *
00804  * RETURNS
00805  *
00806  *  Success: S_OK
00807  *  Failure: Error code from winerror.h
00808  */
00809 static HRESULT ctl2_encode_variant(
00810         ICreateTypeLib2Impl *This, /* [I] The typelib to allocate data in */
00811         int *encoded_value,        /* [O] The encoded default value or data offset */
00812         VARIANT *value,            /* [I] Default value to be encoded */
00813         VARTYPE arg_type)          /* [I] Argument type */
00814 {
00815     VARIANT v;
00816     HRESULT hres;
00817     int mask = 0;
00818 
00819     TRACE("%p %d %d\n", This, V_VT(value), arg_type);
00820 
00821     if(arg_type == VT_INT)
00822         arg_type = VT_I4;
00823     if(arg_type == VT_UINT)
00824         arg_type = VT_UI4;
00825 
00826     v = *value;
00827     if(V_VT(value) != arg_type) {
00828         hres = VariantChangeType(&v, value, 0, arg_type);
00829         if(FAILED(hres))
00830             return hres;
00831     }
00832 
00833     /* Check if default value can be stored in encoded_value */
00834     switch(arg_type) {
00835     case VT_I4:
00836     case VT_UI4:
00837         mask = 0x3ffffff;
00838         if(V_UI4(&v)>0x3ffffff)
00839             break;
00840     case VT_I1:
00841     case VT_UI1:
00842     case VT_BOOL:
00843          if(!mask)
00844              mask = 0xff;
00845     case VT_I2:
00846     case VT_UI2:
00847         if(!mask)
00848             mask = 0xffff;
00849         *encoded_value = (V_UI4(&v)&mask) | ((0x80+0x4*arg_type)<<24);
00850         return S_OK;
00851     }
00852 
00853     switch(arg_type) {
00854     case VT_I4:
00855     case VT_R4:
00856     case VT_UI4:
00857     case VT_INT:
00858     case VT_UINT:
00859     case VT_HRESULT:
00860     case VT_PTR: {
00861         /* Construct the data to be allocated */
00862         int data[2];
00863         data[0] = arg_type + (V_UI4(&v)<<16);
00864         data[1] = (V_UI4(&v)>>16) + 0x57570000;
00865 
00866         /* Check if the data was already allocated */
00867         /* Currently the structures doesn't allow to do it in a nice way */
00868         for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-8; *encoded_value+=4)
00869             if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8))
00870                 return S_OK;
00871 
00872         /* Allocate the data */
00873         *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0);
00874         if(*encoded_value == -1)
00875             return E_OUTOFMEMORY;
00876 
00877         memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, 8);
00878         return S_OK;
00879     }
00880     case VT_BSTR: {
00881         /* Construct the data */
00882         int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3;
00883         char *data = HeapAlloc(GetProcessHeap(), 0, len);
00884 
00885         if(!data)
00886             return E_OUTOFMEMORY;
00887 
00888         *((unsigned short*)data) = arg_type;
00889         *((unsigned*)(data+2)) = SysStringLen(V_BSTR(&v));
00890         for(i=0; i<SysStringLen(V_BSTR(&v)); i++) {
00891             if(V_BSTR(&v)[i] <= 0x7f)
00892                 data[i+6] = V_BSTR(&v)[i];
00893             else
00894                 data[i+6] = '?';
00895         }
00896         WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), SysStringLen(V_BSTR(&v)), &data[6], len-6, NULL, NULL);
00897         for(i=6+SysStringLen(V_BSTR(&v)); i<len; i++)
00898             data[i] = 0x57;
00899 
00900         /* Check if the data was already allocated */
00901         for(*encoded_value=0; *encoded_value<=This->typelib_segdir[MSFT_SEG_CUSTDATA].length-len; *encoded_value+=4)
00902             if(!memcmp(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len)) {
00903                 HeapFree(GetProcessHeap(), 0, data);
00904                 return S_OK;
00905             }
00906 
00907         /* Allocate the data */
00908         *encoded_value = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, len, 0);
00909         if(*encoded_value == -1) {
00910             HeapFree(GetProcessHeap(), 0, data);
00911             return E_OUTOFMEMORY;
00912         }
00913 
00914         memcpy(&This->typelib_segment_data[MSFT_SEG_CUSTDATA][*encoded_value], data, len);
00915         HeapFree(GetProcessHeap(), 0, data);
00916         return S_OK;
00917     }
00918     default:
00919         FIXME("Argument type not yet handled\n");
00920         return E_NOTIMPL;
00921     }
00922 }
00923 
00924 /****************************************************************************
00925  *  ctl2_set_custdata
00926  *
00927  *  Adds a custom data element to an object in a type library.
00928  *
00929  * RETURNS
00930  *
00931  *  Success: S_OK.
00932  *  Failure: One of E_INVALIDARG or E_OUTOFMEMORY.
00933  */
00934 static HRESULT ctl2_set_custdata(
00935     ICreateTypeLib2Impl *This, /* [I] The type library to store the custom data in. */
00936     REFGUID guid,              /* [I] The GUID used as a key to retrieve the custom data. */
00937     VARIANT *pVarVal,          /* [I] The custom data itself. */
00938     int *offset)               /* [I/O] The list of custom data to prepend to. */
00939 {
00940     MSFT_GuidEntry guidentry;
00941     HRESULT status;
00942     int dataoffset;
00943     int guidoffset;
00944     int custoffset;
00945     int *custdata;
00946 
00947     switch(V_VT(pVarVal))
00948     {
00949     case VT_I4:
00950     case VT_R4:
00951     case VT_UI4:
00952     case VT_INT:
00953     case VT_UINT:
00954     case VT_HRESULT:
00955     case VT_BSTR:
00956     /* empty */
00957     break;
00958     default:
00959     return DISP_E_BADVARTYPE;
00960     }
00961 
00962     guidentry.guid = *guid;
00963 
00964     guidentry.hreftype = -1;
00965     guidentry.next_hash = -1;
00966 
00967     guidoffset = ctl2_alloc_guid(This, &guidentry);
00968     if (guidoffset == -1) return E_OUTOFMEMORY;
00969 
00970     status = ctl2_encode_variant(This, &dataoffset, pVarVal, V_VT(pVarVal));
00971     if (status)
00972     return status;
00973 
00974     custoffset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATAGUID, 12, 0);
00975     if (custoffset == -1) return E_OUTOFMEMORY;
00976 
00977     custdata = (int *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset];
00978     custdata[0] = guidoffset;
00979     custdata[1] = dataoffset;
00980     custdata[2] = *offset;
00981     *offset = custoffset;
00982 
00983     return S_OK;
00984 }
00985 
00986 /****************************************************************************
00987  *  ctl2_encode_typedesc
00988  *
00989  *  Encodes a type description, storing information in the TYPEDESC and ARRAYDESC
00990  *  segments as needed.
00991  *
00992  * RETURNS
00993  *
00994  *  Success: 0.
00995  *  Failure: -1.
00996  */
00997 static int ctl2_encode_typedesc(
00998     ICreateTypeLib2Impl *This, /* [I] The type library in which to encode the TYPEDESC. */
00999     const TYPEDESC *tdesc,     /* [I] The type description to encode. */
01000     int *encoded_tdesc,        /* [O] The encoded type description. */
01001     int *width,                /* [O] The width of the type, or NULL. */
01002     int *alignment,            /* [O] The alignment of the type, or NULL. */
01003     int *decoded_size)         /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
01004 {
01005     int default_tdesc;
01006     int scratch;
01007     int typeoffset;
01008     int arrayoffset;
01009     int *typedata;
01010     int *arraydata;
01011     int target_type;
01012     int child_size;
01013 
01014     default_tdesc = 0x80000000 | (tdesc->vt << 16) | tdesc->vt;
01015     if (!width) width = &scratch;
01016     if (!alignment) alignment = &scratch;
01017     if (!decoded_size) decoded_size = &scratch;
01018 
01019     *decoded_size = 0;
01020 
01021     switch (tdesc->vt) {
01022     case VT_UI1:
01023     case VT_I1:
01024     *encoded_tdesc = default_tdesc;
01025     *width = 1;
01026     *alignment = 1;
01027     break;
01028 
01029     case VT_INT:
01030     *encoded_tdesc = 0x80000000 | (VT_I4 << 16) | VT_INT;
01031     if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) {
01032         *width = 2;
01033         *alignment = 2;
01034     } else {
01035         *width = 4;
01036         *alignment = 4;
01037     }
01038     break;
01039 
01040     case VT_UINT:
01041     *encoded_tdesc = 0x80000000 | (VT_UI4 << 16) | VT_UINT;
01042     if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) {
01043         *width = 2;
01044         *alignment = 2;
01045     } else {
01046         *width = 4;
01047         *alignment = 4;
01048     }
01049     break;
01050 
01051     case VT_UI2:
01052     case VT_I2:
01053     case VT_BOOL:
01054     *encoded_tdesc = default_tdesc;
01055     *width = 2;
01056     *alignment = 2;
01057     break;
01058 
01059     case VT_I4:
01060     case VT_UI4:
01061     case VT_R4:
01062     case VT_ERROR:
01063     case VT_BSTR:
01064     case VT_HRESULT:
01065     *encoded_tdesc = default_tdesc;
01066     *width = 4;
01067     *alignment = 4;
01068     break;
01069 
01070     case VT_CY:
01071     *encoded_tdesc = default_tdesc;
01072     *width = 8;
01073     *alignment = 4; /* guess? */
01074     break;
01075 
01076     case VT_VOID:
01077     *encoded_tdesc = 0x80000000 | (VT_EMPTY << 16) | tdesc->vt;
01078     *width = 0;
01079     *alignment = 1;
01080     break;
01081 
01082     case VT_PTR:
01083     case VT_SAFEARRAY:
01084     /* FIXME: Make with the error checking. */
01085     FIXME("PTR or SAFEARRAY vartype, may not work correctly.\n");
01086 
01087     ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);
01088 
01089     for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
01090         typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
01091         if (((typedata[0] & 0xffff) == tdesc->vt) && (typedata[1] == target_type)) break;
01092     }
01093 
01094     if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
01095         int mix_field;
01096         
01097         if (target_type & 0x80000000) {
01098         mix_field = (target_type >> 16) & VT_TYPEMASK;
01099         } else {
01100         typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
01101         switch((typedata[0]>>16) & ~VT_ARRAY)
01102         {
01103             case VT_UI1:
01104             case VT_I1:
01105             case VT_UI2:
01106             case VT_I2:
01107             case VT_I4:
01108             case VT_UI4:
01109             mix_field = typedata[0]>>16;
01110             break;
01111             default:
01112             mix_field = 0x7fff;
01113             break;
01114         }
01115         }
01116 
01117         if (tdesc->vt == VT_PTR)
01118         mix_field |= VT_BYREF;
01119         else if (tdesc->vt == VT_SAFEARRAY)
01120         mix_field |= VT_ARRAY;
01121 
01122         typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
01123         typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
01124 
01125         typedata[0] = (mix_field << 16) | tdesc->vt;
01126         typedata[1] = target_type;
01127     }
01128 
01129     *encoded_tdesc = typeoffset;
01130 
01131     *width = 4;
01132     *alignment = 4;
01133     *decoded_size = sizeof(TYPEDESC) + child_size;
01134     break;
01135 
01136     case VT_CARRAY:
01137       {
01138     /* FIXME: Make with the error checking. */
01139         int num_dims = tdesc->u.lpadesc->cDims, elements = 1, dim;
01140 
01141     ctl2_encode_typedesc(This, &tdesc->u.lpadesc->tdescElem, &target_type, width, alignment, NULL);
01142     arrayoffset = ctl2_alloc_segment(This, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
01143     arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
01144 
01145     arraydata[0] = target_type;
01146     arraydata[1] = num_dims;
01147         arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16);
01148         arraydata += 2;
01149 
01150         for(dim = 0; dim < num_dims; dim++) {
01151             arraydata[0] = tdesc->u.lpadesc->rgbounds[dim].cElements;
01152             arraydata[1] = tdesc->u.lpadesc->rgbounds[dim].lLbound;
01153             elements *= tdesc->u.lpadesc->rgbounds[dim].cElements;
01154             arraydata += 2;
01155         }
01156     typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
01157     typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
01158 
01159     typedata[0] = (0x7ffe << 16) | VT_CARRAY;
01160     typedata[1] = arrayoffset;
01161 
01162     *encoded_tdesc = typeoffset;
01163     *width = *width * elements;
01164     *decoded_size = sizeof(ARRAYDESC) + (num_dims - 1) * sizeof(SAFEARRAYBOUND);
01165 
01166     break;
01167       }
01168     case VT_USERDEFINED:
01169       {
01170     const MSFT_TypeInfoBase *basetype;
01171     INT basevt = 0x7fff;
01172 
01173     TRACE("USERDEFINED.\n");
01174     if (tdesc->u.hreftype % sizeof(*basetype) == 0 && tdesc->u.hreftype < This->typelib_segdir[MSFT_SEG_TYPEINFO].length)
01175     {
01176         basetype = (MSFT_TypeInfoBase*)&(This->typelib_segment_data[MSFT_SEG_TYPEINFO][tdesc->u.hreftype]);
01177         switch(basetype->typekind & 0xf)
01178         {
01179         case TKIND_ENUM:
01180             basevt = VT_I4;
01181             break;
01182         default:
01183             FIXME("USERDEFINED basetype %d not handled\n", basetype->typekind & 0xf);
01184             break;
01185         }
01186     }
01187     for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
01188         typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
01189         if ((typedata[0] == ((basevt << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break;
01190     }
01191 
01192     if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
01193         typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
01194         typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
01195 
01196         typedata[0] = (basevt << 16) | VT_USERDEFINED;
01197         typedata[1] = tdesc->u.hreftype;
01198     }
01199 
01200     *encoded_tdesc = typeoffset;
01201     *width = 0;
01202     *alignment = 1;
01203     break;
01204       }
01205 
01206     default:
01207     FIXME("Unrecognized type %d.\n", tdesc->vt);
01208     *encoded_tdesc = default_tdesc;
01209     *width = 0;
01210     *alignment = 1;
01211     break;
01212     }
01213 
01214     return 0;
01215 }
01216 
01217 /****************************************************************************
01218  *  ctl2_find_nth_reference
01219  *
01220  *  Finds a reference by index into the linked list of reference records.
01221  *
01222  * RETURNS
01223  *
01224  *  Success: Offset of the desired reference record.
01225  *  Failure: -1.
01226  */
01227 static int ctl2_find_nth_reference(
01228     ICreateTypeLib2Impl *This, /* [I] The type library in which to search. */
01229     int offset,                /* [I] The starting offset of the reference list. */
01230     int index)                 /* [I] The index of the reference to find. */
01231 {
01232     MSFT_RefRecord *ref;
01233 
01234     for (; index && (offset != -1); index--) {
01235     ref = (MSFT_RefRecord *)&This->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
01236     offset = ref->onext;
01237     }
01238 
01239     return offset;
01240 }
01241 
01242 /****************************************************************************
01243  *  ctl2_find_typeinfo_from_offset
01244  *
01245  *  Finds an ITypeInfo given an offset into the TYPEINFO segment.
01246  *
01247  * RETURNS
01248  *
01249  *  Success: S_OK.
01250  *  Failure: TYPE_E_ELEMENTNOTFOUND.
01251  */
01252 static HRESULT ctl2_find_typeinfo_from_offset(
01253     ICreateTypeLib2Impl *This, /* [I] The typelib to find the typeinfo in. */
01254     int offset,                /* [I] The offset of the desired typeinfo. */
01255     ITypeInfo **ppTinfo)       /* [I] The typeinfo found. */
01256 {
01257     void *typeinfodata;
01258     ICreateTypeInfo2Impl *typeinfo;
01259 
01260     typeinfodata = &This->typelib_segment_data[MSFT_SEG_TYPEINFO][offset];
01261 
01262     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
01263     if (typeinfo->typeinfo == typeinfodata) {
01264         *ppTinfo = (ITypeInfo *)&typeinfo->lpVtblTypeInfo2;
01265         ITypeInfo2_AddRef(*ppTinfo);
01266         return S_OK;
01267     }
01268     }
01269 
01270     ERR("Failed to find typeinfo, invariant varied.\n");
01271 
01272     return TYPE_E_ELEMENTNOTFOUND;
01273 }
01274 
01275 /****************************************************************************
01276  *      funcrecord_reallochdr
01277  *
01278  *  Ensure FuncRecord data block contains header of required size
01279  *
01280  *  PARAMS
01281  *
01282  *   typedata [IO] - reference to pointer to data block
01283  *   need     [I]  - required size of block in bytes
01284  *
01285  * RETURNS
01286  *
01287  *  Number of additionally allocated bytes
01288  */
01289 static INT funcrecord_reallochdr(INT **typedata, int need)
01290 {
01291     int tail = (*typedata)[5]*((*typedata)[4]&0x1000?16:12);
01292     int hdr = (*typedata)[0] - tail;
01293     int i;
01294 
01295     if (hdr >= need)
01296         return 0;
01297 
01298     *typedata = HeapReAlloc(GetProcessHeap(), 0, *typedata, need + tail);
01299     if (!*typedata)
01300         return -1;
01301 
01302     if (tail)
01303         memmove((char*)*typedata + need, (const char*)*typedata + hdr, tail);
01304     (*typedata)[0] = need + tail;
01305 
01306     /* fill in default values */
01307     for(i = (hdr+3)/4; (i+1)*4 <= need; i++)
01308     {
01309         switch(i)
01310         {
01311             case 2:
01312                 (*typedata)[i] = 0;
01313                 break;
01314             case 7:
01315                 (*typedata)[i] = -1;
01316                 break;
01317             case 8:
01318                 (*typedata)[i] = -1;
01319                 break;
01320             case 9:
01321                 (*typedata)[i] = -1;
01322                 break;
01323             case 10:
01324                 (*typedata)[i] = -1;
01325                 break;
01326             case 11:
01327                 (*typedata)[i] = 0;
01328                 break;
01329             case 12:
01330                 (*typedata)[i] = -1;
01331                 break;
01332         }
01333     }
01334 
01335     return need - hdr;
01336 }
01337 
01338 /*================== ICreateTypeInfo2 Implementation ===================================*/
01339 
01340 /******************************************************************************
01341  * ICreateTypeInfo2_QueryInterface {OLEAUT32}
01342  *
01343  *  See IUnknown_QueryInterface.
01344  */
01345 static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(
01346     ICreateTypeInfo2 * iface,
01347     REFIID riid,
01348     VOID **ppvObject)
01349 {
01350     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01351 
01352     TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
01353 
01354     *ppvObject=NULL;
01355     if(IsEqualIID(riid, &IID_IUnknown) ||
01356        IsEqualIID(riid,&IID_ICreateTypeInfo)||
01357        IsEqualIID(riid,&IID_ICreateTypeInfo2))
01358     {
01359         *ppvObject = This;
01360     } else if (IsEqualIID(riid, &IID_ITypeInfo) ||
01361            IsEqualIID(riid, &IID_ITypeInfo2)) {
01362     *ppvObject = &This->lpVtblTypeInfo2;
01363     }
01364 
01365     if(*ppvObject)
01366     {
01367         ICreateTypeInfo2_AddRef(iface);
01368         TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
01369         return S_OK;
01370     }
01371     TRACE("-- Interface: E_NOINTERFACE\n");
01372     return E_NOINTERFACE;
01373 }
01374 
01375 /******************************************************************************
01376  * ICreateTypeInfo2_AddRef {OLEAUT32}
01377  *
01378  *  See IUnknown_AddRef.
01379  */
01380 static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
01381 {
01382     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01383     ULONG ref = InterlockedIncrement(&This->ref);
01384 
01385     TRACE("(%p)->ref was %u\n",This, ref - 1);
01386 
01387     if(ref==1 && This->typelib)
01388         ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This->typelib);
01389 
01390     return ref;
01391 }
01392 
01393 /******************************************************************************
01394  * ICreateTypeInfo2_Release {OLEAUT32}
01395  *
01396  *  See IUnknown_Release.
01397  */
01398 static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
01399 {
01400     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01401     ULONG ref = InterlockedDecrement(&This->ref);
01402 
01403     TRACE("(%p)->(%u)\n",This, ref);
01404 
01405     if (!ref) {
01406     if (This->typelib) {
01407         ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib);
01408             /* Keep This->typelib reference to make stored ICreateTypeInfo structure valid */
01409             /* This->typelib = NULL; */
01410     }
01411 
01412     /* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */
01413     /* HeapFree(GetProcessHeap(),0,This); */
01414     return 0;
01415     }
01416 
01417     return ref;
01418 }
01419 
01420 
01421 /******************************************************************************
01422  * ICreateTypeInfo2_SetGuid {OLEAUT32}
01423  *
01424  *  See ICreateTypeInfo_SetGuid.
01425  */
01426 static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid)
01427 {
01428     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01429 
01430     MSFT_GuidEntry guidentry;
01431     int offset;
01432 
01433     TRACE("(%p,%s)\n", iface, debugstr_guid(guid));
01434 
01435     guidentry.guid = *guid;
01436     guidentry.hreftype = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
01437     guidentry.next_hash = -1;
01438 
01439     offset = ctl2_alloc_guid(This->typelib, &guidentry);
01440     
01441     if (offset == -1) return E_OUTOFMEMORY;
01442 
01443     This->typeinfo->posguid = offset;
01444 
01445     if (IsEqualIID(guid, &IID_IDispatch)) {
01446     This->typelib->typelib_header.dispatchpos = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
01447     }
01448 
01449     return S_OK;
01450 }
01451 
01452 /******************************************************************************
01453  * ICreateTypeInfo2_SetTypeFlags {OLEAUT32}
01454  *
01455  *  See ICreateTypeInfo_SetTypeFlags.
01456  */
01457 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT uTypeFlags)
01458 {
01459     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01460 
01461     TRACE("(%p,0x%x)\n", iface, uTypeFlags);
01462 
01463     if(uTypeFlags & TYPEFLAG_FDUAL) {
01464         This->typeinfo->typekind |= 0x10;
01465         This->typeinfo->typekind &= ~0x0f;
01466         This->typeinfo->typekind |= TKIND_DISPATCH;
01467 
01468         if(!This->dual) {
01469             This->dual = HeapAlloc(GetProcessHeap(), 0, sizeof(ICreateTypeInfo2Impl));
01470             if(!This->dual)
01471                 return E_OUTOFMEMORY;
01472 
01473             memcpy(This->dual, This, sizeof(ICreateTypeInfo2Impl));
01474             This->dual->ref = 0;
01475             This->dual->typekind = This->typekind==TKIND_DISPATCH ?
01476                 TKIND_INTERFACE : TKIND_DISPATCH;
01477             This->dual->dual = This;
01478         }
01479 
01480         /* Make sure dispatch is in typeinfos queue */
01481         if(This->typekind != TKIND_DISPATCH) {
01482             if(This->typelib->last_typeinfo == This)
01483                 This->typelib->last_typeinfo = This->dual;
01484 
01485             if(This->typelib->typeinfos == This)
01486                 This->typelib->typeinfos = This->dual;
01487             else {
01488                 ICreateTypeInfo2Impl *iter;
01489 
01490                 for(iter=This->typelib->typeinfos; iter->next_typeinfo!=This; iter=iter->next_typeinfo);
01491                 iter->next_typeinfo = This->dual;
01492             }
01493         } else
01494             iface = (ICreateTypeInfo2*)&This->dual->lpVtbl;
01495     }
01496 
01497     if (uTypeFlags & (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL)) {
01498         static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 };
01499         ITypeLib *stdole;
01500         ITypeInfo *dispatch;
01501         HREFTYPE hreftype;
01502         HRESULT hres;
01503 
01504         hres = LoadTypeLib(stdole2tlb, &stdole);
01505         if(FAILED(hres))
01506             return hres;
01507 
01508         hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch);
01509         ITypeLib_Release(stdole);
01510         if(FAILED(hres))
01511             return hres;
01512 
01513         hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype);
01514         ITypeInfo_Release(dispatch);
01515         if(FAILED(hres))
01516             return hres;
01517     }
01518 
01519     This->typeinfo->flags = uTypeFlags;
01520     return S_OK;
01521 }
01522 
01523 /******************************************************************************
01524  * ICreateTypeInfo2_SetDocString {OLEAUT32}
01525  *
01526  *  See ICreateTypeInfo_SetDocString.
01527  */
01528 static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(
01529         ICreateTypeInfo2* iface,
01530         LPOLESTR pStrDoc)
01531 {
01532     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01533 
01534     int offset;
01535 
01536     TRACE("(%p,%s)\n", iface, debugstr_w(pStrDoc));
01537     if (!pStrDoc)
01538         return E_INVALIDARG;
01539 
01540     offset = ctl2_alloc_string(This->typelib, pStrDoc);
01541     if (offset == -1) return E_OUTOFMEMORY;
01542     This->typeinfo->docstringoffs = offset;
01543     return S_OK;
01544 }
01545 
01546 /******************************************************************************
01547  * ICreateTypeInfo2_SetHelpContext {OLEAUT32}
01548  *
01549  *  See ICreateTypeInfo_SetHelpContext.
01550  */
01551 static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(
01552         ICreateTypeInfo2* iface,
01553         DWORD dwHelpContext)
01554 {
01555     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01556 
01557     TRACE("(%p,%d)\n", iface, dwHelpContext);
01558 
01559     This->typeinfo->helpcontext = dwHelpContext;
01560 
01561     return S_OK;
01562 }
01563 
01564 /******************************************************************************
01565  * ICreateTypeInfo2_SetVersion {OLEAUT32}
01566  *
01567  *  See ICreateTypeInfo_SetVersion.
01568  */
01569 static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(
01570         ICreateTypeInfo2* iface,
01571         WORD wMajorVerNum,
01572         WORD wMinorVerNum)
01573 {
01574     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01575 
01576     TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);
01577 
01578     This->typeinfo->version = wMajorVerNum | (wMinorVerNum << 16);
01579     return S_OK;
01580 }
01581 
01582 /******************************************************************************
01583  * ICreateTypeInfo2_AddRefTypeInfo {OLEAUT32}
01584  *
01585  *  See ICreateTypeInfo_AddRefTypeInfo.
01586  */
01587 static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(
01588         ICreateTypeInfo2* iface,
01589         ITypeInfo* pTInfo,
01590         HREFTYPE* phRefType)
01591 {
01592     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01593 
01594     ITypeLib *container;
01595     UINT index;
01596     HRESULT res;
01597 
01598     TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType);
01599 
01600     if(!pTInfo || !phRefType)
01601         return E_INVALIDARG;
01602 
01603     /*
01604      * Unfortunately, we can't rely on the passed-in TypeInfo even having the
01605      * same internal structure as one of ours. It could be from another
01606      * implementation of ITypeInfo. So we need to do the following...
01607      */
01608     res = ITypeInfo_GetContainingTypeLib(pTInfo, &container, &index);
01609     if (FAILED(res)) {
01610     TRACE("failed to find containing typelib.\n");
01611     return res;
01612     }
01613 
01614     if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) {
01615         /* Process locally defined TypeInfo */
01616     *phRefType = This->typelib->typelib_typeinfo_offsets[index];
01617     } else {
01618         BSTR name;
01619         TLIBATTR *tlibattr;
01620         TYPEATTR *typeattr;
01621         TYPEKIND typekind;
01622         MSFT_GuidEntry guid, *check_guid;
01623         MSFT_ImpInfo impinfo;
01624         int guid_offset, import_offset;
01625         HRESULT hres;
01626 
01627         /* Allocate container GUID */
01628         hres = ITypeLib_GetLibAttr(container, &tlibattr);
01629         if(FAILED(hres)) {
01630             ITypeLib_Release(container);
01631             return hres;
01632         }
01633 
01634         guid.guid = tlibattr->guid;
01635         guid.hreftype = This->typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length+2;
01636         guid.next_hash = -1;
01637 
01638         guid_offset = ctl2_alloc_guid(This->typelib, &guid);
01639         if(guid_offset == -1) {
01640             ITypeLib_ReleaseTLibAttr(container, tlibattr);
01641             ITypeLib_Release(container);
01642             return E_OUTOFMEMORY;
01643         }
01644 
01645         check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
01646         if(check_guid->hreftype == guid.hreftype)
01647             This->typelib->typelib_guids++;
01648 
01649         /* Get import file name */
01650         hres = QueryPathOfRegTypeLib(&guid.guid, tlibattr->wMajorVerNum,
01651                 tlibattr->wMinorVerNum, tlibattr->lcid, &name);
01652         if(FAILED(hres)) {
01653             ITypeLib_ReleaseTLibAttr(container, tlibattr);
01654             ITypeLib_Release(container);
01655             return hres;
01656         }
01657 
01658         /* Import file */
01659         import_offset = ctl2_alloc_importfile(This->typelib, guid_offset, tlibattr->lcid,
01660                 tlibattr->wMajorVerNum, tlibattr->wMinorVerNum, strrchrW(name, '\\')+1);
01661         ITypeLib_ReleaseTLibAttr(container, tlibattr);
01662         SysFreeString(name);
01663 
01664         if(import_offset == -1) {
01665             ITypeLib_Release(container);
01666             return E_OUTOFMEMORY;
01667         }
01668 
01669         /* Allocate referenced guid */
01670         hres = ITypeInfo_GetTypeAttr(pTInfo, &typeattr);
01671         if(FAILED(hres)) {
01672             ITypeLib_Release(container);
01673             return hres;
01674         }
01675 
01676         guid.guid = typeattr->guid;
01677         guid.hreftype = This->typelib->typeinfo_guids*12+1;
01678         guid.next_hash = -1;
01679         typekind = typeattr->typekind;
01680         ITypeInfo_ReleaseTypeAttr(pTInfo, typeattr);
01681 
01682         guid_offset = ctl2_alloc_guid(This->typelib, &guid);
01683         if(guid_offset == -1) {
01684             ITypeLib_Release(container);
01685             return E_OUTOFMEMORY;
01686         }
01687 
01688         check_guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][guid_offset];
01689         if(check_guid->hreftype == guid.hreftype)
01690             This->typelib->typeinfo_guids++;
01691 
01692         /* Allocate importinfo */
01693         impinfo.flags = (typekind<<24) | MSFT_IMPINFO_OFFSET_IS_GUID;
01694         impinfo.oImpFile = import_offset;
01695         impinfo.oGuid = guid_offset;
01696         *phRefType = ctl2_alloc_importinfo(This->typelib, &impinfo)+1;
01697 
01698         if(IsEqualGUID(&guid.guid, &IID_IDispatch))
01699             This->typelib->typelib_header.dispatchpos = *phRefType;
01700     }
01701 
01702     ITypeLib_Release(container);
01703     return S_OK;
01704 }
01705 
01706 /******************************************************************************
01707  * ICreateTypeInfo2_AddFuncDesc {OLEAUT32}
01708  *
01709  *  See ICreateTypeInfo_AddFuncDesc.
01710  */
01711 static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(
01712         ICreateTypeInfo2* iface,
01713         UINT index,
01714         FUNCDESC* pFuncDesc)
01715 {
01716     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01717 
01718     CyclicList *iter, *insert;
01719     int *typedata;
01720     int i, num_defaults = 0, num_retval = 0;
01721     int decoded_size;
01722     HRESULT hres;
01723 
01724     TRACE("(%p,%d,%p)\n", iface, index, pFuncDesc);
01725 
01726     if(!pFuncDesc || pFuncDesc->oVft&3)
01727         return E_INVALIDARG;
01728 
01729     TRACE("{%d,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid,
01730             pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind,
01731             pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams,
01732             pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes,
01733             pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags);
01734 
01735     if(pFuncDesc->cParamsOpt || pFuncDesc->cScodes)
01736         FIXME("Unimplemented parameter - created typelib will be incorrect\n");
01737 
01738     switch(This->typekind) {
01739     case TKIND_MODULE:
01740         if(pFuncDesc->funckind != FUNC_STATIC)
01741             return TYPE_E_BADMODULEKIND;
01742         break;
01743     case TKIND_DISPATCH:
01744         if(pFuncDesc->funckind != FUNC_DISPATCH)
01745             return TYPE_E_BADMODULEKIND;
01746         break;
01747     default:
01748         if(pFuncDesc->funckind != FUNC_PUREVIRTUAL)
01749             return TYPE_E_BADMODULEKIND;
01750     }
01751 
01752     if(This->typeinfo->cElement<index)
01753         return TYPE_E_ELEMENTNOTFOUND;
01754 
01755     if((pFuncDesc->invkind&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) &&
01756         !pFuncDesc->cParams)
01757         return TYPE_E_INCONSISTENTPROPFUNCS;
01758 
01759     /* get number of arguments with default values specified */
01760     for (i = 0; i < pFuncDesc->cParams; i++) {
01761         if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
01762             num_defaults++;
01763         if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
01764             num_retval++;
01765     }
01766 
01767     if (!This->typedata) {
01768         This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
01769         if(!This->typedata)
01770             return E_OUTOFMEMORY;
01771 
01772         This->typedata->next = This->typedata;
01773         This->typedata->u.val = 0;
01774 
01775         if(This->dual)
01776             This->dual->typedata = This->typedata;
01777     }
01778 
01779     /* allocate type data space for us */
01780     insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
01781     if(!insert)
01782         return E_OUTOFMEMORY;
01783     insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int)*6+sizeof(int)*(num_defaults?4:3)*pFuncDesc->cParams);
01784     if(!insert->u.data) {
01785         HeapFree(GetProcessHeap(), 0, insert);
01786         return E_OUTOFMEMORY;
01787     }
01788 
01789     /* fill out the basic type information */
01790     typedata = insert->u.data;
01791     typedata[0] = 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
01792     ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size);
01793     typedata[2] = pFuncDesc->wFuncFlags;
01794     typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | (unsigned short)(pFuncDesc->oVft?pFuncDesc->oVft+1:0);
01795     typedata[4] = (pFuncDesc->callconv << 8) | (pFuncDesc->invkind << 3) | pFuncDesc->funckind;
01796     if(num_defaults) typedata[4] |= 0x1000;
01797     if (num_retval) typedata[4] |= 0x4000;
01798     typedata[5] = pFuncDesc->cParams;
01799 
01800     /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */
01801     /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */
01802     typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16;
01803     typedata[3] += (sizeof(PARAMDESCEX) * num_defaults) << 16;
01804 
01805     /* add default values */
01806     if(num_defaults) {
01807         for (i = 0; i < pFuncDesc->cParams; i++)
01808             if(pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
01809                 hres = ctl2_encode_variant(This->typelib, typedata+6+i,
01810                         &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue,
01811                         pFuncDesc->lprgelemdescParam[i].tdesc.vt);
01812 
01813                 if(FAILED(hres)) {
01814                     HeapFree(GetProcessHeap(), 0, insert->u.data);
01815                     HeapFree(GetProcessHeap(), 0, insert);
01816                     return hres;
01817                 }
01818             } else
01819                 typedata[6+i] = 0xffffffff;
01820 
01821         num_defaults = pFuncDesc->cParams;
01822     }
01823 
01824     /* add arguments */
01825     for (i = 0; i < pFuncDesc->cParams; i++) {
01826     ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc,
01827                 &typedata[6+num_defaults+(i*3)], NULL, NULL, &decoded_size);
01828     typedata[7+num_defaults+(i*3)] = -1;
01829     typedata[8+num_defaults+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
01830     typedata[3] += decoded_size << 16;
01831     }
01832 
01833     /* update the index data */
01834     insert->indice = pFuncDesc->memid;
01835     insert->name = -1;
01836     insert->type = CyclicListFunc;
01837 
01838     /* insert type data to list */
01839     if(index == This->typeinfo->cElement) {
01840         insert->next = This->typedata->next;
01841         This->typedata->next = insert;
01842         This->typedata = insert;
01843 
01844         if(This->dual)
01845             This->dual->typedata = This->typedata;
01846     } else {
01847         iter = This->typedata->next;
01848         for(i=0; i<index; i++)
01849             iter = iter->next;
01850 
01851         insert->next = iter->next;
01852         iter->next = insert;
01853     }
01854 
01855     /* update type data size */
01856     This->typedata->next->u.val += 0x18 + pFuncDesc->cParams*(num_defaults?16:12);
01857 
01858     /* Increment the number of function elements */
01859     This->typeinfo->cElement += 1;
01860 
01861     return S_OK;
01862 }
01863 
01864 /******************************************************************************
01865  * ICreateTypeInfo2_AddImplType {OLEAUT32}
01866  *
01867  *  See ICreateTypeInfo_AddImplType.
01868  */
01869 static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(
01870         ICreateTypeInfo2* iface,
01871         UINT index,
01872         HREFTYPE hRefType)
01873 {
01874     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01875 
01876     TRACE("(%p,%d,%d)\n", iface, index, hRefType);
01877 
01878     if (This->typekind == TKIND_COCLASS) {
01879     int offset;
01880     MSFT_RefRecord *ref;
01881 
01882     if (index == 0) {
01883         if (This->typeinfo->datatype1 != -1) return TYPE_E_ELEMENTNOTFOUND;
01884 
01885         offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
01886         if (offset == -1) return E_OUTOFMEMORY;
01887 
01888         This->typeinfo->datatype1 = offset;
01889     } else {
01890         int lastoffset;
01891 
01892         lastoffset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index - 1);
01893         if (lastoffset == -1) return TYPE_E_ELEMENTNOTFOUND;
01894 
01895         ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][lastoffset];
01896         if (ref->onext != -1) return TYPE_E_ELEMENTNOTFOUND;
01897 
01898         offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0);
01899         if (offset == -1) return E_OUTOFMEMORY;
01900 
01901         ref->onext = offset;
01902     }
01903 
01904     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
01905 
01906     ref->reftype = hRefType;
01907     ref->flags = 0;
01908     ref->oCustData = -1;
01909     ref->onext = -1;
01910         This->typeinfo->cImplTypes++;
01911     } else if (This->typekind == TKIND_INTERFACE) {
01912         if (This->typeinfo->cImplTypes && index==1)
01913             return TYPE_E_BADMODULEKIND;
01914 
01915         if( index != 0)  return TYPE_E_ELEMENTNOTFOUND;
01916 
01917         This->typeinfo->datatype1 = hRefType;
01918         This->typeinfo->cImplTypes = 1;
01919     } else if (This->typekind == TKIND_DISPATCH) {
01920         if(index != 0) return TYPE_E_ELEMENTNOTFOUND;
01921 
01922         /* FIXME: Check if referenced typeinfo is IDispatch */
01923         This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
01924         This->typeinfo->cImplTypes = 1;
01925     } else {
01926     FIXME("AddImplType unsupported on typekind %d\n", This->typekind);
01927     return E_OUTOFMEMORY;
01928     }
01929 
01930     return S_OK;
01931 }
01932 
01933 /******************************************************************************
01934  * ICreateTypeInfo2_SetImplTypeFlags {OLEAUT32}
01935  *
01936  *  See ICreateTypeInfo_SetImplTypeFlags.
01937  */
01938 static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(
01939         ICreateTypeInfo2* iface,
01940         UINT index,
01941         INT implTypeFlags)
01942 {
01943     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01944     int offset;
01945     MSFT_RefRecord *ref;
01946 
01947     TRACE("(%p,%d,0x%x)\n", iface, index, implTypeFlags);
01948 
01949     if (This->typekind != TKIND_COCLASS) {
01950     return TYPE_E_BADMODULEKIND;
01951     }
01952 
01953     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
01954     if (offset == -1) return TYPE_E_ELEMENTNOTFOUND;
01955 
01956     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
01957     ref->flags = implTypeFlags;
01958 
01959     return S_OK;
01960 }
01961 
01962 /******************************************************************************
01963  * ICreateTypeInfo2_SetAlignment {OLEAUT32}
01964  *
01965  *  See ICreateTypeInfo_SetAlignment.
01966  */
01967 static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(
01968         ICreateTypeInfo2* iface,
01969         WORD cbAlignment)
01970 {
01971     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
01972 
01973     TRACE("(%p,%d)\n", iface, cbAlignment);
01974 
01975     if (!cbAlignment) return E_INVALIDARG;
01976     if (cbAlignment > 16) return E_INVALIDARG;
01977 
01978     This->typeinfo->typekind &= ~0xffc0;
01979     This->typeinfo->typekind |= cbAlignment << 6;
01980 
01981     /* FIXME: There's probably some way to simplify this. */
01982     switch (This->typekind) {
01983     case TKIND_ALIAS:
01984     default:
01985     break;
01986 
01987     case TKIND_ENUM:
01988     case TKIND_INTERFACE:
01989     case TKIND_DISPATCH:
01990     case TKIND_COCLASS:
01991     if (cbAlignment > 4) cbAlignment = 4;
01992     break;
01993 
01994     case TKIND_RECORD:
01995     case TKIND_MODULE:
01996     case TKIND_UNION:
01997     cbAlignment = 1;
01998     break;
01999     }
02000 
02001     This->typeinfo->typekind |= cbAlignment << 11;
02002 
02003     return S_OK;
02004 }
02005 
02006 /******************************************************************************
02007  * ICreateTypeInfo2_SetSchema {OLEAUT32}
02008  *
02009  *  See ICreateTypeInfo_SetSchema.
02010  */
02011 static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(
02012         ICreateTypeInfo2* iface,
02013         LPOLESTR pStrSchema)
02014 {
02015     FIXME("(%p,%s), stub!\n", iface, debugstr_w(pStrSchema));
02016     return E_OUTOFMEMORY;
02017 }
02018 
02019 /******************************************************************************
02020  * ICreateTypeInfo2_AddVarDesc {OLEAUT32}
02021  *
02022  *  See ICreateTypeInfo_AddVarDesc.
02023  */
02024 static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(
02025         ICreateTypeInfo2* iface,
02026         UINT index,
02027         VARDESC* pVarDesc)
02028 {
02029     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02030 
02031     HRESULT status = S_OK;
02032     CyclicList *insert;
02033     INT *typedata;
02034     int var_datawidth;
02035     int var_alignment;
02036     int var_type_size;
02037     int alignment;
02038 
02039     TRACE("(%p,%d,%p), stub!\n", iface, index, pVarDesc);
02040     TRACE("%d, %p, %d, {{%x, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst,
02041       pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt,
02042       pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags,
02043       pVarDesc->wVarFlags, pVarDesc->varkind);
02044 
02045     if ((This->typeinfo->cElement >> 16) != index) {
02046     TRACE("Out-of-order element.\n");
02047     return TYPE_E_ELEMENTNOTFOUND;
02048     }
02049 
02050     if (!This->typedata) {
02051         This->typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
02052         if(!This->typedata)
02053             return E_OUTOFMEMORY;
02054 
02055         This->typedata->next = This->typedata;
02056         This->typedata->u.val = 0;
02057 
02058         if(This->dual)
02059             This->dual->typedata = This->typedata;
02060     }
02061 
02062     /* allocate type data space for us */
02063     insert = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList));
02064     if(!insert)
02065         return E_OUTOFMEMORY;
02066     insert->u.data = HeapAlloc(GetProcessHeap(), 0, sizeof(int[5]));
02067     if(!insert->u.data) {
02068         HeapFree(GetProcessHeap(), 0, insert);
02069         return E_OUTOFMEMORY;
02070     }
02071 
02072     insert->next = This->typedata->next;
02073     This->typedata->next = insert;
02074     This->typedata = insert;
02075 
02076     if(This->dual)
02077         This->dual->typedata = This->typedata;
02078 
02079     This->typedata->next->u.val += 0x14;
02080     typedata = This->typedata->u.data;
02081 
02082     /* fill out the basic type information */
02083     typedata[0] = 0x14 | (index << 16);
02084     typedata[2] = pVarDesc->wVarFlags;
02085     typedata[3] = (sizeof(VARDESC) << 16) | pVarDesc->varkind;
02086 
02087     /* update the index data */
02088     insert->indice = 0x40000000 + index;
02089     insert->name = -1;
02090     insert->type = CyclicListVar;
02091 
02092     /* figure out type widths and whatnot */
02093     ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc,
02094              &typedata[1], &var_datawidth, &var_alignment,
02095              &var_type_size);
02096 
02097     if (pVarDesc->varkind != VAR_CONST)
02098     {
02099     /* pad out starting position to data width */
02100     This->datawidth += var_alignment - 1;
02101     This->datawidth &= ~(var_alignment - 1);
02102     typedata[4] = This->datawidth;
02103 
02104     /* add the new variable to the total data width */
02105     This->datawidth += var_datawidth;
02106     if(This->dual)
02107         This->dual->datawidth = This->datawidth;
02108 
02109     /* add type description size to total required allocation */
02110     typedata[3] += var_type_size << 16;
02111 
02112     /* fix type alignment */
02113     alignment = (This->typeinfo->typekind >> 11) & 0x1f;
02114     if (alignment < var_alignment) {
02115         alignment = var_alignment;
02116         This->typeinfo->typekind &= ~0xf800;
02117         This->typeinfo->typekind |= alignment << 11;
02118     }
02119 
02120     /* ??? */
02121     if (!This->typeinfo->res2) This->typeinfo->res2 = 0x1a;
02122     if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) {
02123         This->typeinfo->res2 <<= 1;
02124     }
02125 
02126     /* ??? */
02127     if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0;
02128     This->typeinfo->res3 += 0x2c;
02129 
02130     /* pad data width to alignment */
02131     This->typeinfo->size = (This->datawidth + (alignment - 1)) & ~(alignment - 1);
02132     } else {
02133     VARIANT *value = pVarDesc->DUMMYUNIONNAME.lpvarValue;
02134     status = ctl2_encode_variant(This->typelib, typedata+4, value, V_VT(value));
02135         /* ??? native sets size 0x34 */
02136     typedata[3] += 0x10 << 16;
02137     }
02138 
02139     /* increment the number of variable elements */
02140     This->typeinfo->cElement += 0x10000;
02141 
02142     return status;
02143 }
02144 
02145 /******************************************************************************
02146  * ICreateTypeInfo2_SetFuncAndParamNames {OLEAUT32}
02147  *
02148  *  See ICreateTypeInfo_SetFuncAndParamNames.
02149  */
02150 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(
02151         ICreateTypeInfo2* iface,
02152         UINT index,
02153         LPOLESTR* rgszNames,
02154         UINT cNames)
02155 {
02156     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02157     CyclicList *iter = NULL, *iter2;
02158     int offset, len, i=0;
02159     char *namedata;
02160 
02161     TRACE("(%p %d %p %d)\n", iface, index, rgszNames, cNames);
02162 
02163     if(!rgszNames)
02164         return E_INVALIDARG;
02165 
02166     if(index >= (This->typeinfo->cElement&0xFFFF) || !cNames)
02167         return TYPE_E_ELEMENTNOTFOUND;
02168 
02169     for(iter=This->typedata->next->next, i=0; /* empty */; iter=iter->next)
02170         if (iter->type == CyclicListFunc)
02171             if (i++ >= index)
02172                 break;
02173 
02174     /* cNames == cParams for put or putref accessor, cParams+1 otherwise */
02175     if(cNames != iter->u.data[5] + ((iter->u.data[4]>>3)&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF) ? 0 : 1))
02176         return TYPE_E_ELEMENTNOTFOUND;
02177 
02178     len = ctl2_encode_name(This->typelib, rgszNames[0], &namedata);
02179     for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
02180         if(iter2->name!=-1 && !memcmp(namedata,
02181                     This->typelib->typelib_segment_data[MSFT_SEG_NAME]+iter2->name+8, len)) {
02182             /* getters/setters can have a same name */
02183             if (iter2->type == CyclicListFunc) {
02184                 INT inv1 = iter2->u.data[4] >> 3;
02185                 INT inv2 = iter->u.data[4] >> 3;
02186                 if (((inv1&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && (inv2&INVOKE_PROPERTYGET)) ||
02187                     ((inv2&(INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF)) && (inv1&INVOKE_PROPERTYGET)))
02188                     continue;
02189             }
02190 
02191             return TYPE_E_AMBIGUOUSNAME;
02192         }
02193     }
02194 
02195     offset = ctl2_alloc_name(This->typelib, rgszNames[0]);
02196     if(offset == -1)
02197         return E_OUTOFMEMORY;
02198 
02199     iter->name = offset;
02200 
02201     namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
02202     if (*((INT*)namedata) == -1)
02203         *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
02204 
02205     len = iter->u.data[0]/4 - iter->u.data[5]*3;
02206 
02207     for (i = 1; i < cNames; i++) {
02208     offset = ctl2_alloc_name(This->typelib, rgszNames[i]);
02209     iter->u.data[len + ((i-1)*3) + 1] = offset;
02210     }
02211 
02212     return S_OK;
02213 }
02214 
02215 /******************************************************************************
02216  * ICreateTypeInfo2_SetVarName {OLEAUT32}
02217  *
02218  *  See ICreateTypeInfo_SetVarName.
02219  */
02220 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(
02221         ICreateTypeInfo2* iface,
02222         UINT index,
02223         LPOLESTR szName)
02224 {
02225     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02226     CyclicList *iter;
02227     int offset, i;
02228     char *namedata;
02229 
02230     TRACE("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szName));
02231 
02232     if ((This->typeinfo->cElement >> 16) <= index) {
02233     TRACE("Out-of-order element.\n");
02234     return TYPE_E_ELEMENTNOTFOUND;
02235     }
02236 
02237     offset = ctl2_alloc_name(This->typelib, szName);
02238     if (offset == -1) return E_OUTOFMEMORY;
02239 
02240     namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
02241     if (*((INT *)namedata) == -1) {
02242     *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16];
02243     namedata[9] |= 0x10;
02244     }
02245     if (This->typekind == TKIND_ENUM) {
02246     namedata[9] |= 0x20;
02247     }
02248 
02249     for(iter = This->typedata->next->next, i = 0; /* empty */; iter = iter->next)
02250         if (iter->type == CyclicListVar)
02251             if (i++ >= index)
02252                 break;
02253 
02254     iter->name = offset;
02255     return S_OK;
02256 }
02257 
02258 /******************************************************************************
02259  * ICreateTypeInfo2_SetTypeDescAlias {OLEAUT32}
02260  *
02261  *  See ICreateTypeInfo_SetTypeDescAlias.
02262  */
02263 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(
02264         ICreateTypeInfo2* iface,
02265         TYPEDESC* pTDescAlias)
02266 {
02267     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02268 
02269     int encoded_typedesc;
02270     int width;
02271 
02272     if (This->typekind != TKIND_ALIAS) {
02273     return TYPE_E_WRONGTYPEKIND;
02274     }
02275 
02276     FIXME("(%p,%p), hack!\n", iface, pTDescAlias);
02277 
02278     if (ctl2_encode_typedesc(This->typelib, pTDescAlias, &encoded_typedesc, &width, NULL, NULL) == -1) {
02279     return E_OUTOFMEMORY;
02280     }
02281 
02282     This->typeinfo->size = width;
02283     This->typeinfo->datatype1 = encoded_typedesc;
02284 
02285     return S_OK;
02286 }
02287 
02288 /******************************************************************************
02289  * ICreateTypeInfo2_DefineFuncAsDllEntry {OLEAUT32}
02290  *
02291  *  See ICreateTypeInfo_DefineFuncAsDllEntry.
02292  */
02293 static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(
02294         ICreateTypeInfo2* iface,
02295         UINT index,
02296         LPOLESTR szDllName,
02297         LPOLESTR szProcName)
02298 {
02299     FIXME("(%p,%d,%s,%s), stub!\n", iface, index, debugstr_w(szDllName), debugstr_w(szProcName));
02300     return E_OUTOFMEMORY;
02301 }
02302 
02303 /******************************************************************************
02304  * ICreateTypeInfo2_SetFuncDocString {OLEAUT32}
02305  *
02306  *  See ICreateTypeInfo_SetFuncDocString.
02307  */
02308 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(
02309         ICreateTypeInfo2* iface,
02310         UINT index,
02311         LPOLESTR szDocString)
02312 {
02313     FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString));
02314     return E_OUTOFMEMORY;
02315 }
02316 
02317 /******************************************************************************
02318  * ICreateTypeInfo2_SetVarDocString {OLEAUT32}
02319  *
02320  *  See ICreateTypeInfo_SetVarDocString.
02321  */
02322 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(
02323         ICreateTypeInfo2* iface,
02324         UINT index,
02325         LPOLESTR szDocString)
02326 {
02327     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02328 
02329     FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString));
02330 
02331     ctl2_alloc_string(This->typelib, szDocString);
02332 
02333     return E_OUTOFMEMORY;
02334 }
02335 
02336 /******************************************************************************
02337  * ICreateTypeInfo2_SetFuncHelpContext {OLEAUT32}
02338  *
02339  *  See ICreateTypeInfo_SetFuncHelpContext.
02340  */
02341 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(
02342         ICreateTypeInfo2* iface,
02343         UINT index,
02344         DWORD dwHelpContext)
02345 {
02346     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02347     CyclicList *func;
02348 
02349     TRACE("(%p,%d,%d)\n", iface, index, dwHelpContext);
02350 
02351     if(This->typeinfo->cElement<index)
02352         return TYPE_E_ELEMENTNOTFOUND;
02353 
02354     if(This->typeinfo->cElement == index && This->typedata->type == CyclicListFunc)
02355         func = This->typedata;
02356     else
02357         for(func=This->typedata->next->next; func!=This->typedata; func=func->next)
02358             if (func->type == CyclicListFunc)
02359                 if(index-- == 0)
02360                     break;
02361 
02362     This->typedata->next->u.val += funcrecord_reallochdr(&func->u.data, 7*sizeof(int));
02363     if(!func->u.data)
02364         return E_OUTOFMEMORY;
02365 
02366     func->u.data[6] = dwHelpContext;
02367     return S_OK;
02368 }
02369 
02370 /******************************************************************************
02371  * ICreateTypeInfo2_SetVarHelpContext {OLEAUT32}
02372  *
02373  *  See ICreateTypeInfo_SetVarHelpContext.
02374  */
02375 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(
02376         ICreateTypeInfo2* iface,
02377         UINT index,
02378         DWORD dwHelpContext)
02379 {
02380     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpContext);
02381     return E_OUTOFMEMORY;
02382 }
02383 
02384 /******************************************************************************
02385  * ICreateTypeInfo2_SetMops {OLEAUT32}
02386  *
02387  *  See ICreateTypeInfo_SetMops.
02388  */
02389 static HRESULT WINAPI ICreateTypeInfo2_fnSetMops(
02390         ICreateTypeInfo2* iface,
02391         UINT index,
02392         BSTR bstrMops)
02393 {
02394     FIXME("(%p,%d,%p), stub!\n", iface, index, bstrMops);
02395     return E_OUTOFMEMORY;
02396 }
02397 
02398 /******************************************************************************
02399  * ICreateTypeInfo2_SetTypeIdldesc {OLEAUT32}
02400  *
02401  *  See ICreateTypeInfo_SetTypeIdldesc.
02402  */
02403 static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(
02404         ICreateTypeInfo2* iface,
02405         IDLDESC* pIdlDesc)
02406 {
02407     FIXME("(%p,%p), stub!\n", iface, pIdlDesc);
02408     return E_OUTOFMEMORY;
02409 }
02410 
02411 /******************************************************************************
02412  * ICreateTypeInfo2_LayOut {OLEAUT32}
02413  *
02414  *  See ICreateTypeInfo_LayOut.
02415  */
02416 static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(
02417     ICreateTypeInfo2* iface)
02418 {
02419     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02420     CyclicList *iter, *iter2, *last = NULL, **typedata;
02421     HREFTYPE hreftype;
02422     HRESULT hres;
02423     unsigned user_vft = 0;
02424     int i;
02425 
02426     TRACE("(%p)\n", iface);
02427 
02428     /* FIXME: LayOut should be run on all ImplTypes */
02429     if(This->typekind == TKIND_COCLASS)
02430         return S_OK;
02431 
02432     /* Validate inheritance */
02433     This->typeinfo->datatype2 = 0;
02434     hreftype = This->typeinfo->datatype1;
02435 
02436     /* Process internally defined interfaces */
02437     for(i=0; i<This->typelib->typelib_header.nrtypeinfos; i++) {
02438         MSFT_TypeInfoBase *header;
02439 
02440         if(hreftype&1)
02441             break;
02442 
02443         header = (MSFT_TypeInfoBase*)&(This->typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][hreftype]);
02444         This->typeinfo->datatype2 += (header->cElement<<16) + 1;
02445         hreftype = header->datatype1;
02446     }
02447     if(i == This->typelib->typelib_header.nrtypeinfos)
02448         return TYPE_E_CIRCULARTYPE;
02449 
02450     /* Process externally defined interfaces */
02451     if(hreftype != -1) {
02452         ITypeInfo *cur, *next;
02453         TYPEATTR *typeattr;
02454 
02455         hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&next);
02456         if(FAILED(hres))
02457             return hres;
02458 
02459         hres = ITypeInfo_GetRefTypeInfo(next, hreftype, &cur);
02460         ITypeInfo_Release(next);
02461         if(FAILED(hres))
02462             return hres;
02463 
02464 
02465         while(1) {
02466             hres = ITypeInfo_GetTypeAttr(cur, &typeattr);
02467             if(FAILED(hres)) {
02468                 ITypeInfo_Release(cur);
02469                 return hres;
02470             }
02471 
02472             if(IsEqualGUID(&typeattr->guid, &IID_IDispatch))
02473                 This->typeinfo->flags |= TYPEFLAG_FDISPATCHABLE;
02474 
02475             This->typeinfo->datatype2 += (typeattr->cFuncs<<16) + 1;
02476             ITypeInfo_ReleaseTypeAttr(cur, typeattr);
02477 
02478             hres = ITypeInfo_GetRefTypeOfImplType(cur, 0, &hreftype);
02479             if(hres == TYPE_E_ELEMENTNOTFOUND)
02480                 break;
02481             if(FAILED(hres)) {
02482                 ITypeInfo_Release(cur);
02483                 return hres;
02484             }
02485 
02486             hres = ITypeInfo_GetRefTypeInfo(cur, hreftype, &next);
02487             if(FAILED(hres)) {
02488                 ITypeInfo_Release(cur);
02489                 return hres;
02490             }
02491 
02492             ITypeInfo_Release(cur);
02493             cur = next;
02494         }
02495         ITypeInfo_Release(cur);
02496     }
02497 
02498     /* Get cbSizeVft of inherited interface */
02499     /* Makes LayOut running recursively */
02500     if(This->typeinfo->datatype1 != -1) {
02501         ITypeInfo *cur, *inherited;
02502         TYPEATTR *typeattr;
02503 
02504         hres = ICreateTypeInfo_QueryInterface(iface, &IID_ITypeInfo, (void**)&cur);
02505         if(FAILED(hres))
02506             return hres;
02507 
02508         hres = ITypeInfo_GetRefTypeInfo(cur, This->typeinfo->datatype1, &inherited);
02509         ITypeInfo_Release(cur);
02510         if(FAILED(hres))
02511             return hres;
02512 
02513         hres = ITypeInfo_GetTypeAttr(inherited, &typeattr);
02514         if(FAILED(hres)) {
02515             ITypeInfo_Release(inherited);
02516             return hres;
02517         }
02518 
02519         This->typeinfo->cbSizeVft = typeattr->cbSizeVft * 4 / sizeof(void *);
02520 
02521         ITypeInfo_ReleaseTypeAttr(inherited, typeattr);
02522         ITypeInfo_Release(inherited);
02523     } else
02524         This->typeinfo->cbSizeVft = 0;
02525 
02526     if(!This->typedata)
02527         return S_OK;
02528 
02529     typedata = HeapAlloc(GetProcessHeap(), 0, sizeof(CyclicList*)*(This->typeinfo->cElement&0xffff));
02530     if(!typedata)
02531         return E_OUTOFMEMORY;
02532 
02533     /* Assign IDs and VTBL entries */
02534     for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next)
02535         if (iter->type == CyclicListFunc)
02536             last = iter;
02537 
02538     if(last && last->u.data[3]&1)
02539         user_vft = last->u.data[3]&0xffff;
02540 
02541     i = 0;
02542     for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
02543         /* Assign MEMBERID if MEMBERID_NIL was specified */
02544         if(iter->indice == MEMBERID_NIL) {
02545             iter->indice = 0x60000000 + i + (This->typeinfo->datatype2<<16);
02546 
02547             for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
02548                 if(iter == iter2) continue;
02549                 if(iter2->indice == iter->indice) {
02550                     iter->indice = 0x5fffffff + This->typeinfo->cElement + i + (This->typeinfo->datatype2<<16);
02551 
02552                     for(iter2=This->typedata->next->next; iter2!=This->typedata->next; iter2=iter2->next) {
02553                         if(iter == iter2) continue;
02554                         if(iter2->indice == iter->indice) {
02555                             HeapFree(GetProcessHeap(), 0, typedata);
02556                             return E_ACCESSDENIED;
02557                         }
02558                     }
02559 
02560                     break;
02561                 }
02562             }
02563         }
02564 
02565         if (iter->type != CyclicListFunc)
02566             continue;
02567 
02568         typedata[i] = iter;
02569 
02570         iter->u.data[0] = (iter->u.data[0]&0xffff) | (i<<16);
02571 
02572         if((iter->u.data[3]&1) != (user_vft&1)) {
02573             HeapFree(GetProcessHeap(), 0, typedata);
02574             return TYPE_E_INVALIDID;
02575         }
02576 
02577         if(user_vft&1) {
02578             if(user_vft < (iter->u.data[3]&0xffff))
02579                 user_vft = (iter->u.data[3]&0xffff);
02580 
02581             if((iter->u.data[3]&0xffff) < This->typeinfo->cbSizeVft) {
02582                 HeapFree(GetProcessHeap(), 0, typedata);
02583                 return TYPE_E_INVALIDID;
02584             }
02585         } else if(This->typekind != TKIND_MODULE) {
02586             iter->u.data[3] = (iter->u.data[3]&0xffff0000) | This->typeinfo->cbSizeVft;
02587             This->typeinfo->cbSizeVft += 4;
02588         }
02589 
02590         /* Construct a list of elements with the same memberid */
02591         iter->u.data[4] = (iter->u.data[4]&0xffff) | (i<<16);
02592         for(iter2=This->typedata->next->next; iter2!=iter; iter2=iter2->next) {
02593             if(iter->indice == iter2->indice) {
02594                 int v1, v2;
02595 
02596                 v1 = iter->u.data[4] >> 16;
02597                 v2 = iter2->u.data[4] >> 16;
02598 
02599                 iter->u.data[4] = (iter->u.data[4]&0xffff) | (v2<<16);
02600                 iter2->u.data[4] = (iter2->u.data[4]&0xffff) | (v1<<16);
02601                 break;
02602             }
02603         }
02604 
02605         i++;
02606     }
02607 
02608     if(user_vft)
02609         This->typeinfo->cbSizeVft = user_vft+3;
02610 
02611     for(i=0; i<(This->typeinfo->cElement&0xffff); i++) {
02612         if(typedata[i]->u.data[4]>>16 > i) {
02613             int inv;
02614 
02615             inv = (typedata[i]->u.data[4]>>3) & 0xf;
02616             i = typedata[i]->u.data[4] >> 16;
02617 
02618             while(i > typedata[i]->u.data[4]>>16) {
02619                 int invkind = (typedata[i]->u.data[4]>>3) & 0xf;
02620 
02621                 if(inv & invkind) {
02622                     HeapFree(GetProcessHeap(), 0, typedata);
02623                     return TYPE_E_DUPLICATEID;
02624                 }
02625 
02626                 i = typedata[i]->u.data[4] >> 16;
02627                 inv |= invkind;
02628             }
02629 
02630             if(inv & INVOKE_FUNC) {
02631                 HeapFree(GetProcessHeap(), 0, typedata);
02632                 return TYPE_E_INCONSISTENTPROPFUNCS;
02633             }
02634         }
02635     }
02636 
02637     HeapFree(GetProcessHeap(), 0, typedata);
02638     return S_OK;
02639 }
02640 
02641 /******************************************************************************
02642  * ICreateTypeInfo2_DeleteFuncDesc {OLEAUT32}
02643  *
02644  *  Delete a function description from a type.
02645  *
02646  * RETURNS
02647  *
02648  *  Success: S_OK.
02649  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02650  */
02651 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(
02652         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */
02653         UINT index)              /* [I] The index of the function to delete. */
02654 {
02655     FIXME("(%p,%d), stub!\n", iface, index);
02656     return E_OUTOFMEMORY;
02657 }
02658 
02659 /******************************************************************************
02660  * ICreateTypeInfo2_DeleteFuncDescByMemId {OLEAUT32}
02661  *
02662  *  Delete a function description from a type.
02663  *
02664  * RETURNS
02665  *
02666  *  Success: S_OK.
02667  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02668  */
02669 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(
02670         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */
02671         MEMBERID memid,          /* [I] The member id of the function to delete. */
02672         INVOKEKIND invKind)      /* [I] The invocation type of the function to delete. (?) */
02673 {
02674     FIXME("(%p,%d,%d), stub!\n", iface, memid, invKind);
02675     return E_OUTOFMEMORY;
02676 }
02677 
02678 /******************************************************************************
02679  * ICreateTypeInfo2_DeleteVarDesc {OLEAUT32}
02680  *
02681  *  Delete a variable description from a type.
02682  *
02683  * RETURNS
02684  *
02685  *  Success: S_OK.
02686  *  Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR,
02687  *  TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE.
02688  */
02689 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc(
02690         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
02691         UINT index)              /* [I] The index of the variable description to delete. */
02692 {
02693     FIXME("(%p,%d), stub!\n", iface, index);
02694     return E_OUTOFMEMORY;
02695 }
02696 
02697 /******************************************************************************
02698  * ICreateTypeInfo2_DeleteVarDescByMemId {OLEAUT32}
02699  *
02700  *  Delete a variable description from a type.
02701  *
02702  * RETURNS
02703  *
02704  *  Success: S_OK.
02705  *  Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR,
02706  *  TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE.
02707  */
02708 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(
02709         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */
02710         MEMBERID memid)          /* [I] The member id of the variable description to delete. */
02711 {
02712     FIXME("(%p,%d), stub!\n", iface, memid);
02713     return E_OUTOFMEMORY;
02714 }
02715 
02716 /******************************************************************************
02717  * ICreateTypeInfo2_DeleteImplType {OLEAUT32}
02718  *
02719  *  Delete an interface implementation from a type. (?)
02720  *
02721  * RETURNS
02722  *
02723  *  Success: S_OK.
02724  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02725  */
02726 static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(
02727         ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete. */
02728         UINT index)              /* [I] The index of the interface to delete. */
02729 {
02730     FIXME("(%p,%d), stub!\n", iface, index);
02731     return E_OUTOFMEMORY;
02732 }
02733 
02734 /******************************************************************************
02735  * ICreateTypeInfo2_SetCustData {OLEAUT32}
02736  *
02737  *  Set the custom data for a type.
02738  *
02739  * RETURNS
02740  *
02741  *  Success: S_OK.
02742  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02743  */
02744 static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(
02745         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
02746         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
02747         VARIANT* pVarVal)        /* [I] The custom data. */
02748 {
02749     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02750 
02751     TRACE("(%p,%s,%p)!\n", iface, debugstr_guid(guid), pVarVal);
02752 
02753     if (!pVarVal)
02754         return E_INVALIDARG;
02755 
02756     return ctl2_set_custdata(This->typelib, guid, pVarVal, &This->typeinfo->oCustData);
02757 }
02758 
02759 /******************************************************************************
02760  * ICreateTypeInfo2_SetFuncCustData {OLEAUT32}
02761  *
02762  *  Set the custom data for a function.
02763  *
02764  * RETURNS
02765  *
02766  *  Success: S_OK.
02767  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02768  */
02769 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(
02770         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
02771         UINT index,              /* [I] The index of the function for which to set the custom data. */
02772         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
02773         VARIANT* pVarVal)        /* [I] The custom data. */
02774 {
02775     ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface;
02776     CyclicList *iter;
02777 
02778     TRACE("(%p,%d,%s,%p)\n", iface, index, debugstr_guid(guid), pVarVal);
02779 
02780     if(index >= (This->typeinfo->cElement&0xFFFF))
02781         return TYPE_E_ELEMENTNOTFOUND;
02782 
02783     for(iter=This->typedata->next->next; /* empty */; iter=iter->next)
02784         if (iter->type == CyclicListFunc)
02785             if (index-- == 0)
02786                 break;
02787 
02788     This->typedata->next->u.val += funcrecord_reallochdr(&iter->u.data, 13*sizeof(int));
02789     if(!iter->u.data)
02790         return E_OUTOFMEMORY;
02791 
02792     iter->u.data[4] |= 0x80;
02793     return ctl2_set_custdata(This->typelib, guid, pVarVal, &iter->u.data[12]);
02794 }
02795 
02796 /******************************************************************************
02797  * ICreateTypeInfo2_SetParamCustData {OLEAUT32}
02798  *
02799  *  Set the custom data for a function parameter.
02800  *
02801  * RETURNS
02802  *
02803  *  Success: S_OK.
02804  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02805  */
02806 static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(
02807         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
02808         UINT indexFunc,          /* [I] The index of the function on which the parameter resides. */
02809         UINT indexParam,         /* [I] The index of the parameter on which to set the custom data. */
02810         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
02811         VARIANT* pVarVal)        /* [I] The custom data. */
02812 {
02813     FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
02814     return E_OUTOFMEMORY;
02815 }
02816 
02817 /******************************************************************************
02818  * ICreateTypeInfo2_SetVarCustData {OLEAUT32}
02819  *
02820  *  Set the custom data for a variable.
02821  *
02822  * RETURNS
02823  *
02824  *  Success: S_OK.
02825  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02826  */
02827 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData(
02828         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */
02829         UINT index,              /* [I] The index of the variable on which to set the custom data. */
02830         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
02831         VARIANT* pVarVal)        /* [I] The custom data. */
02832 {
02833     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
02834     return E_OUTOFMEMORY;
02835 }
02836 
02837 /******************************************************************************
02838  * ICreateTypeInfo2_SetImplTypeCustData {OLEAUT32}
02839  *
02840  *  Set the custom data for an implemented interface.
02841  *
02842  * RETURNS
02843  *
02844  *  Success: S_OK.
02845  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02846  */
02847 static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData(
02848         ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the custom data. */
02849         UINT index,              /* [I] The index of the implemented interface on which to set the custom data. */
02850         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
02851         VARIANT* pVarVal)        /* [I] The custom data. */
02852 {
02853     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
02854     return E_OUTOFMEMORY;
02855 }
02856 
02857 /******************************************************************************
02858  * ICreateTypeInfo2_SetHelpStringContext {OLEAUT32}
02859  *
02860  *  Set the help string context for the typeinfo.
02861  *
02862  * RETURNS
02863  *
02864  *  Success: S_OK.
02865  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02866  */
02867 static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(
02868         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
02869         ULONG dwHelpStringContext) /* [I] The help string context. */
02870 {
02871     FIXME("(%p,%d), stub!\n", iface, dwHelpStringContext);
02872     return E_OUTOFMEMORY;
02873 }
02874 
02875 /******************************************************************************
02876  * ICreateTypeInfo2_SetFuncHelpStringContext {OLEAUT32}
02877  *
02878  *  Set the help string context for a function.
02879  *
02880  * RETURNS
02881  *
02882  *  Success: S_OK.
02883  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02884  */
02885 static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(
02886         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
02887         UINT index,                /* [I] The index for the function on which to set the help string context. */
02888         ULONG dwHelpStringContext) /* [I] The help string context. */
02889 {
02890     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
02891     return E_OUTOFMEMORY;
02892 }
02893 
02894 /******************************************************************************
02895  * ICreateTypeInfo2_SetVarHelpStringContext {OLEAUT32}
02896  *
02897  *  Set the help string context for a variable.
02898  *
02899  * RETURNS
02900  *
02901  *  Success: S_OK.
02902  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
02903  */
02904 static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(
02905         ICreateTypeInfo2* iface,   /* [I] The typeinfo on which to set the help string context. */
02906         UINT index,                /* [I] The index of the variable on which to set the help string context. */
02907         ULONG dwHelpStringContext) /* [I] The help string context */
02908 {
02909     FIXME("(%p,%d,%d), stub!\n", iface, index, dwHelpStringContext);
02910     return E_OUTOFMEMORY;
02911 }
02912 
02913 /******************************************************************************
02914  * ICreateTypeInfo2_Invalidate {OLEAUT32}
02915  *
02916  *  Undocumented function. (!)
02917  */
02918 static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate(
02919         ICreateTypeInfo2* iface)
02920 {
02921     FIXME("(%p), stub!\n", iface);
02922     return E_OUTOFMEMORY;
02923 }
02924 
02925 /******************************************************************************
02926  * ICreateTypeInfo2_SetName {OLEAUT32}
02927  *
02928  *  Set the name for a typeinfo.
02929  *
02930  * RETURNS
02931  *
02932  *  Success: S_OK.
02933  *  Failure: One of STG_E_INSUFFICIENTMEMORY, E_OUTOFMEMORY, E_INVALIDARG or TYPE_E_INVALIDSTATE.
02934  */
02935 static HRESULT WINAPI ICreateTypeInfo2_fnSetName(
02936         ICreateTypeInfo2* iface,
02937         LPOLESTR szName)
02938 {
02939     FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
02940     return E_OUTOFMEMORY;
02941 }
02942 
02943 /*================== ITypeInfo2 Implementation ===================================*/
02944 
02945 /******************************************************************************
02946  * ITypeInfo2_QueryInterface {OLEAUT32}
02947  *
02948  *  See IUnknown_QueryInterface.
02949  */
02950 static HRESULT WINAPI ITypeInfo2_fnQueryInterface(ITypeInfo2 * iface, REFIID riid, LPVOID * ppv)
02951 {
02952     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
02953 
02954     return ICreateTypeInfo2_QueryInterface((ICreateTypeInfo2 *)This, riid, ppv);
02955 }
02956 
02957 /******************************************************************************
02958  * ITypeInfo2_AddRef {OLEAUT32}
02959  *
02960  *  See IUnknown_AddRef.
02961  */
02962 static ULONG WINAPI ITypeInfo2_fnAddRef(ITypeInfo2 * iface)
02963 {
02964     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
02965 
02966     return ICreateTypeInfo2_AddRef((ICreateTypeInfo2 *)This);
02967 }
02968 
02969 /******************************************************************************
02970  * ITypeInfo2_Release {OLEAUT32}
02971  *
02972  *  See IUnknown_Release.
02973  */
02974 static ULONG WINAPI ITypeInfo2_fnRelease(ITypeInfo2 * iface)
02975 {
02976     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
02977 
02978     return ICreateTypeInfo2_Release((ICreateTypeInfo2 *)This);
02979 }
02980 
02981 /******************************************************************************
02982  * ITypeInfo2_GetTypeAttr {OLEAUT32}
02983  *
02984  *  See ITypeInfo_GetTypeAttr.
02985  */
02986 static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr(
02987         ITypeInfo2* iface,
02988         TYPEATTR** ppTypeAttr)
02989 {
02990     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
02991     HRESULT hres;
02992 
02993     TRACE("(%p,%p)\n", iface, ppTypeAttr);
02994 
02995     if(!ppTypeAttr)
02996         return E_INVALIDARG;
02997 
02998     hres = ICreateTypeInfo_LayOut((ICreateTypeInfo*)This);
02999     if(FAILED(hres))
03000         return hres;
03001 
03002     *ppTypeAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TYPEATTR));
03003     if(!*ppTypeAttr)
03004         return E_OUTOFMEMORY;
03005 
03006     if(This->typeinfo->posguid != -1) {
03007         MSFT_GuidEntry *guid;
03008 
03009         guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][This->typeinfo->posguid];
03010         (*ppTypeAttr)->guid = guid->guid;
03011     }
03012 
03013     (*ppTypeAttr)->lcid = This->typelib->typelib_header.lcid;
03014     (*ppTypeAttr)->cbSizeInstance = This->typeinfo->size;
03015     (*ppTypeAttr)->typekind = This->typekind;
03016     (*ppTypeAttr)->cFuncs = This->typeinfo->cElement&0xffff;
03017     if(This->typeinfo->flags&TYPEFLAG_FDUAL && This->typekind==TKIND_DISPATCH)
03018         (*ppTypeAttr)->cFuncs += 7;
03019     (*ppTypeAttr)->cVars = This->typeinfo->cElement>>16;
03020     (*ppTypeAttr)->cImplTypes = This->typeinfo->cImplTypes;
03021     (*ppTypeAttr)->cbSizeVft = This->typekind==TKIND_DISPATCH ? 7 * sizeof(void*) : This->typeinfo->cbSizeVft;
03022     (*ppTypeAttr)->cbAlignment = (This->typeinfo->typekind>>11) & 0x1f;
03023     (*ppTypeAttr)->wTypeFlags = This->typeinfo->flags;
03024     (*ppTypeAttr)->wMajorVerNum = This->typeinfo->version&0xffff;
03025     (*ppTypeAttr)->wMinorVerNum = This->typeinfo->version>>16;
03026 
03027     if((*ppTypeAttr)->typekind == TKIND_ALIAS)
03028         FIXME("TKIND_ALIAS handling not implemented\n");
03029 
03030     return S_OK;
03031 }
03032 
03033 /******************************************************************************
03034  * ITypeInfo2_GetTypeComp {OLEAUT32}
03035  *
03036  *  See ITypeInfo_GetTypeComp.
03037  */
03038 static HRESULT WINAPI ITypeInfo2_fnGetTypeComp(
03039         ITypeInfo2* iface,
03040         ITypeComp** ppTComp)
03041 {
03042     FIXME("(%p,%p), stub!\n", iface, ppTComp);
03043     return E_OUTOFMEMORY;
03044 }
03045 
03046 /******************************************************************************
03047  * ITypeInfo2_GetFuncDesc {OLEAUT32}
03048  *
03049  *  See ITypeInfo_GetFuncDesc.
03050  */
03051 static HRESULT WINAPI ITypeInfo2_fnGetFuncDesc(
03052         ITypeInfo2* iface,
03053         UINT index,
03054         FUNCDESC** ppFuncDesc)
03055 {
03056     FIXME("(%p,%d,%p), stub!\n", iface, index, ppFuncDesc);
03057     return E_OUTOFMEMORY;
03058 }
03059 
03060 /******************************************************************************
03061  * ITypeInfo2_GetVarDesc {OLEAUT32}
03062  *
03063  *  See ITypeInfo_GetVarDesc.
03064  */
03065 static HRESULT WINAPI ITypeInfo2_fnGetVarDesc(
03066         ITypeInfo2* iface,
03067         UINT index,
03068         VARDESC** ppVarDesc)
03069 {
03070     FIXME("(%p,%d,%p), stub!\n", iface, index, ppVarDesc);
03071     return E_OUTOFMEMORY;
03072 }
03073 
03074 /******************************************************************************
03075  * ITypeInfo2_GetNames {OLEAUT32}
03076  *
03077  *  See ITypeInfo_GetNames.
03078  */
03079 static HRESULT WINAPI ITypeInfo2_fnGetNames(
03080         ITypeInfo2* iface,
03081         MEMBERID memid,
03082         BSTR* rgBstrNames,
03083         UINT cMaxNames,
03084         UINT* pcNames)
03085 {
03086     FIXME("(%p,%d,%p,%d,%p), stub!\n", iface, memid, rgBstrNames, cMaxNames, pcNames);
03087     return E_OUTOFMEMORY;
03088 }
03089 
03090 /******************************************************************************
03091  * ITypeInfo2_GetRefTypeOfImplType {OLEAUT32}
03092  *
03093  *  See ITypeInfo_GetRefTypeOfImplType.
03094  */
03095 static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType(
03096         ITypeInfo2* iface,
03097         UINT index,
03098         HREFTYPE* pRefType)
03099 {
03100     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
03101     MSFT_RefRecord *ref;
03102     int offset;
03103 
03104     TRACE("(%p,%d,%p)\n", iface, index, pRefType);
03105 
03106     if(!pRefType)
03107         return E_INVALIDARG;
03108 
03109     if(This->typeinfo->flags&TYPEFLAG_FDUAL) {
03110         if(index == -1) {
03111             *pRefType = -2;
03112             return S_OK;
03113         }
03114 
03115         if(This->typekind == TKIND_DISPATCH)
03116             return ITypeInfo2_GetRefTypeOfImplType((ITypeInfo2*)&This->dual->lpVtblTypeInfo2,
03117                     index, pRefType);
03118     }
03119 
03120     if(index>=This->typeinfo->cImplTypes)
03121         return TYPE_E_ELEMENTNOTFOUND;
03122 
03123     if(This->typekind == TKIND_INTERFACE) {
03124         *pRefType = This->typeinfo->datatype1 + 2;
03125         return S_OK;
03126     }
03127 
03128     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
03129     if(offset == -1)
03130         return TYPE_E_ELEMENTNOTFOUND;
03131 
03132     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
03133     *pRefType = ref->reftype;
03134     return S_OK;
03135 }
03136 
03137 /******************************************************************************
03138  * ITypeInfo2_GetImplTypeFlags {OLEAUT32}
03139  *
03140  *  See ITypeInfo_GetImplTypeFlags.
03141  */
03142 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags(
03143         ITypeInfo2* iface,
03144         UINT index,
03145         INT* pImplTypeFlags)
03146 {
03147     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
03148     int offset;
03149     MSFT_RefRecord *ref;
03150 
03151     TRACE("(%p,%d,%p)\n", iface, index, pImplTypeFlags);
03152 
03153     if(!pImplTypeFlags)
03154         return E_INVALIDARG;
03155 
03156     if(index >= This->typeinfo->cImplTypes)
03157         return TYPE_E_ELEMENTNOTFOUND;
03158 
03159     if(This->typekind != TKIND_COCLASS) {
03160         *pImplTypeFlags = 0;
03161         return S_OK;
03162     }
03163 
03164     offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index);
03165     if(offset == -1)
03166         return TYPE_E_ELEMENTNOTFOUND;
03167 
03168     ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset];
03169     *pImplTypeFlags = ref->flags;
03170     return S_OK;
03171 }
03172 
03173 /******************************************************************************
03174  * ITypeInfo2_GetIDsOfNames {OLEAUT32}
03175  *
03176  *  See ITypeInfo_GetIDsOfNames.
03177  */
03178 static HRESULT WINAPI ITypeInfo2_fnGetIDsOfNames(
03179         ITypeInfo2* iface,
03180         LPOLESTR* rgszNames,
03181         UINT cNames,
03182         MEMBERID* pMemId)
03183 {
03184     FIXME("(%p,%p,%d,%p), stub!\n", iface, rgszNames, cNames, pMemId);
03185     return E_OUTOFMEMORY;
03186 }
03187 
03188 /******************************************************************************
03189  * ITypeInfo2_Invoke {OLEAUT32}
03190  *
03191  *  See ITypeInfo_Invoke.
03192  */
03193 static HRESULT WINAPI ITypeInfo2_fnInvoke(
03194         ITypeInfo2* iface,
03195         PVOID pvInstance,
03196         MEMBERID memid,
03197         WORD wFlags,
03198         DISPPARAMS* pDispParams,
03199         VARIANT* pVarResult,
03200         EXCEPINFO* pExcepInfo,
03201         UINT* puArgErr)
03202 {
03203     FIXME("(%p,%p,%d,%x,%p,%p,%p,%p), stub!\n", iface, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
03204     return E_OUTOFMEMORY;
03205 }
03206 
03207 /******************************************************************************
03208  * ITypeInfo2_GetDocumentation {OLEAUT32}
03209  *
03210  *  See ITypeInfo_GetDocumentation.
03211  */
03212 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation(
03213         ITypeInfo2* iface,
03214         MEMBERID memid,
03215         BSTR* pBstrName,
03216         BSTR* pBstrDocString,
03217         DWORD* pdwHelpContext,
03218         BSTR* pBstrHelpFile)
03219 {
03220     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
03221     HRESULT status = TYPE_E_ELEMENTNOTFOUND;
03222     INT nameoffset, docstringoffset, helpcontext;
03223 
03224     TRACE("(%p,%d,%p,%p,%p,%p)\n", iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
03225 
03226     if (memid == -1)
03227     {
03228         nameoffset = This->typeinfo->NameOffset;
03229         docstringoffset = This->typeinfo->docstringoffs;
03230         helpcontext = This->typeinfo->helpcontext;
03231         status = S_OK;
03232     } else {
03233         CyclicList *iter;
03234         if (This->typedata) {
03235             for(iter=This->typedata->next->next; iter!=This->typedata->next; iter=iter->next) {
03236                 if (iter->indice == memid) {
03237                     if (iter->type == CyclicListFunc) {
03238                         const int *typedata = iter->u.data;
03239                         int   size = typedata[0] - typedata[5]*(typedata[4]&0x1000?16:12);
03240 
03241                         nameoffset = iter->name;
03242                         /* FIXME implement this once SetFuncDocString is implemented */
03243                         docstringoffset = -1;
03244                         helpcontext = (size < 7*sizeof(int)) ? 0 : typedata[6];
03245 
03246                         status = S_OK;
03247                     } else {
03248                         FIXME("Not implemented for variable members\n");
03249                     }
03250 
03251                     break;
03252                 }
03253             }
03254         }
03255     }
03256 
03257     if (!status) {
03258         WCHAR *string;
03259         if (pBstrName) {
03260             if (nameoffset == -1)
03261                 *pBstrName = NULL;
03262             else {
03263                 MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib->
03264                         typelib_segment_data[MSFT_SEG_NAME][nameoffset];
03265                 ctl2_decode_name((char*)&name->namelen, &string);
03266                 *pBstrName = SysAllocString(string);
03267                 if(!*pBstrName)
03268                     return E_OUTOFMEMORY;
03269             }
03270         }
03271 
03272         if (pBstrDocString) {
03273             if (docstringoffset == -1)
03274                 *pBstrDocString = NULL;
03275             else {
03276                 MSFT_NameIntro *name = (MSFT_NameIntro*)&This->typelib->
03277                         typelib_segment_data[MSFT_SEG_NAME][docstringoffset];
03278                 ctl2_decode_name((char*)&name->namelen, &string);
03279                 *pBstrDocString = SysAllocString(string);
03280                 if(!*pBstrDocString) {
03281                     if (pBstrName) SysFreeString(*pBstrName);
03282                     return E_OUTOFMEMORY;
03283                 }
03284             }
03285         }
03286 
03287         if (pdwHelpContext) {
03288             *pdwHelpContext = helpcontext;
03289         }
03290 
03291         if (pBstrHelpFile) {
03292             status = ITypeLib_GetDocumentation((ITypeLib*)&This->typelib->lpVtblTypeLib2,
03293                     -1, NULL, NULL, NULL, pBstrHelpFile);
03294             if (status) {
03295                 if (pBstrName) SysFreeString(*pBstrName);
03296                 if (pBstrDocString) SysFreeString(*pBstrDocString);
03297             }
03298         }
03299     }
03300 
03301     return status;
03302 }
03303 
03304 /******************************************************************************
03305  * ITypeInfo2_GetDllEntry {OLEAUT32}
03306  *
03307  *  See ITypeInfo_GetDllEntry.
03308  */
03309 static HRESULT WINAPI ITypeInfo2_fnGetDllEntry(
03310         ITypeInfo2* iface,
03311         MEMBERID memid,
03312         INVOKEKIND invKind,
03313         BSTR* pBstrDllName,
03314         BSTR* pBstrName,
03315         WORD* pwOrdinal)
03316 {
03317     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
03318     return E_OUTOFMEMORY;
03319 }
03320 
03321 /******************************************************************************
03322  * ITypeInfo2_GetRefTypeInfo {OLEAUT32}
03323  *
03324  *  See ITypeInfo_GetRefTypeInfo.
03325  */
03326 static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo(
03327         ITypeInfo2* iface,
03328         HREFTYPE hRefType,
03329         ITypeInfo** ppTInfo)
03330 {
03331     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
03332 
03333     TRACE("(%p,%d,%p)\n", iface, hRefType, ppTInfo);
03334 
03335     if(!ppTInfo)
03336         return E_INVALIDARG;
03337 
03338     if(hRefType==-2 && This->dual) {
03339         *ppTInfo = (ITypeInfo*)&This->dual->lpVtblTypeInfo2;
03340         ITypeInfo_AddRef(*ppTInfo);
03341         return S_OK;
03342     }
03343 
03344     if(hRefType&1) {
03345         ITypeLib *tl;
03346         MSFT_ImpInfo *impinfo;
03347         MSFT_ImpFile *impfile;
03348         MSFT_GuidEntry *guid;
03349         WCHAR *filename;
03350         HRESULT hres;
03351 
03352         if((hRefType&(~0x3)) >= This->typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length)
03353             return E_FAIL;
03354 
03355         impinfo = (MSFT_ImpInfo*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][hRefType&(~0x3)];
03356         impfile = (MSFT_ImpFile*)&This->typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][impinfo->oImpFile];
03357         guid = (MSFT_GuidEntry*)&This->typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo->oGuid];
03358 
03359         ctl2_decode_string(impfile->filename, &filename);
03360 
03361         hres = LoadTypeLib(filename, &tl);
03362         if(FAILED(hres))
03363             return hres;
03364 
03365         hres = ITypeLib_GetTypeInfoOfGuid(tl, &guid->guid, ppTInfo);
03366 
03367         ITypeLib_Release(tl);
03368         return hres;
03369     } else {
03370         ICreateTypeInfo2Impl *iter;
03371         int i = 0;
03372 
03373         for(iter=This->typelib->typeinfos; iter; iter=iter->next_typeinfo) {
03374             if(This->typelib->typelib_typeinfo_offsets[i] == (hRefType&(~0x3))) {
03375                 *ppTInfo = (ITypeInfo*)&iter->lpVtblTypeInfo2;
03376 
03377                 ITypeLib_AddRef(*ppTInfo);
03378                 return S_OK;
03379             }
03380             i++;
03381         }
03382     }
03383 
03384     return E_FAIL;
03385 }
03386 
03387 /******************************************************************************
03388  * ITypeInfo2_AddressOfMember {OLEAUT32}
03389  *
03390  *  See ITypeInfo_AddressOfMember.
03391  */
03392 static HRESULT WINAPI ITypeInfo2_fnAddressOfMember(
03393         ITypeInfo2* iface,
03394         MEMBERID memid,
03395         INVOKEKIND invKind,
03396         PVOID* ppv)
03397 {
03398     FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, ppv);
03399     return E_OUTOFMEMORY;
03400 }
03401 
03402 /******************************************************************************
03403  * ITypeInfo2_CreateInstance {OLEAUT32}
03404  *
03405  *  See ITypeInfo_CreateInstance.
03406  */
03407 static HRESULT WINAPI ITypeInfo2_fnCreateInstance(
03408         ITypeInfo2* iface,
03409         IUnknown* pUnkOuter,
03410         REFIID riid,
03411         PVOID* ppvObj)
03412 {
03413     FIXME("(%p,%p,%s,%p), stub!\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj);
03414     return E_OUTOFMEMORY;
03415 }
03416 
03417 /******************************************************************************
03418  * ITypeInfo2_GetMops {OLEAUT32}
03419  *
03420  *  See ITypeInfo_GetMops.
03421  */
03422 static HRESULT WINAPI ITypeInfo2_fnGetMops(
03423         ITypeInfo2* iface,
03424         MEMBERID memid,
03425         BSTR* pBstrMops)
03426 {
03427     FIXME("(%p,%d,%p), stub!\n", iface, memid, pBstrMops);
03428     return E_OUTOFMEMORY;
03429 }
03430 
03431 /******************************************************************************
03432  * ITypeInfo2_GetContainingTypeLib {OLEAUT32}
03433  *
03434  *  See ITypeInfo_GetContainingTypeLib.
03435  */
03436 static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib(
03437         ITypeInfo2* iface,
03438         ITypeLib** ppTLib,
03439         UINT* pIndex)
03440 {
03441     ICreateTypeInfo2Impl *This = impl_from_ITypeInfo2(iface);
03442 
03443     TRACE("(%p,%p,%p)\n", iface, ppTLib, pIndex);
03444     
03445     *ppTLib = (ITypeLib *)&This->typelib->lpVtblTypeLib2;
03446     ICreateTypeLib_AddRef((ICreateTypeLib*)This->typelib);
03447     *pIndex = This->typeinfo->typekind >> 16;
03448 
03449     return S_OK;
03450 }
03451 
03452 /******************************************************************************
03453  * ITypeInfo2_ReleaseTypeAttr {OLEAUT32}
03454  *
03455  *  See ITypeInfo_ReleaseTypeAttr.
03456  */
03457 static void WINAPI ITypeInfo2_fnReleaseTypeAttr(
03458         ITypeInfo2* iface,
03459         TYPEATTR* pTypeAttr)
03460 {
03461     TRACE("(%p,%p)\n", iface, pTypeAttr);
03462 
03463     HeapFree(GetProcessHeap(), 0, pTypeAttr);
03464 }
03465 
03466 /******************************************************************************
03467  * ITypeInfo2_ReleaseFuncDesc {OLEAUT32}
03468  *
03469  *  See ITypeInfo_ReleaseFuncDesc.
03470  */
03471 static void WINAPI ITypeInfo2_fnReleaseFuncDesc(
03472         ITypeInfo2* iface,
03473         FUNCDESC* pFuncDesc)
03474 {
03475     FIXME("(%p,%p), stub!\n", iface, pFuncDesc);
03476 }
03477 
03478 /******************************************************************************
03479  * ITypeInfo2_ReleaseVarDesc {OLEAUT32}
03480  *
03481  *  See ITypeInfo_ReleaseVarDesc.
03482  */
03483 static void WINAPI ITypeInfo2_fnReleaseVarDesc(
03484         ITypeInfo2* iface,
03485         VARDESC* pVarDesc)
03486 {
03487     FIXME("(%p,%p), stub!\n", iface, pVarDesc);
03488 }
03489 
03490 /******************************************************************************
03491  * ITypeInfo2_GetTypeKind {OLEAUT32}
03492  *
03493  *  Get the TYPEKIND value for a TypeInfo.
03494  *
03495  * RETURNS
03496  *
03497  *  Success: S_OK.
03498  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03499  */
03500 static HRESULT WINAPI ITypeInfo2_fnGetTypeKind(
03501         ITypeInfo2* iface,   /* [I] The TypeInfo to obtain the typekind for. */
03502         TYPEKIND* pTypeKind) /* [O] The typekind for this TypeInfo. */
03503 {
03504     FIXME("(%p,%p), stub!\n", iface, pTypeKind);
03505     return E_OUTOFMEMORY;
03506 }
03507 
03508 /******************************************************************************
03509  * ITypeInfo2_GetTypeFlags {OLEAUT32}
03510  *
03511  *  Get the Type Flags for a TypeInfo.
03512  *
03513  * RETURNS
03514  *
03515  *  Success: S_OK.
03516  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03517  */
03518 static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags(
03519         ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typeflags for. */
03520         ULONG* pTypeFlags) /* [O] The type flags for this TypeInfo. */
03521 {
03522     FIXME("(%p,%p), stub!\n", iface, pTypeFlags);
03523     return E_OUTOFMEMORY;
03524 }
03525 
03526 /******************************************************************************
03527  * ITypeInfo2_GetFuncIndexOfMemId {OLEAUT32}
03528  *
03529  *  Gets the index of a function given its member id.
03530  *
03531  * RETURNS
03532  *
03533  *  Success: S_OK.
03534  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03535  */
03536 static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId(
03537         ITypeInfo2* iface,  /* [I] The TypeInfo in which to find the function. */
03538         MEMBERID memid,     /* [I] The member id for the function. */
03539         INVOKEKIND invKind, /* [I] The invocation kind for the function. */
03540         UINT* pFuncIndex)   /* [O] The index of the function. */
03541 {
03542     FIXME("(%p,%d,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex);
03543     return E_OUTOFMEMORY;
03544 }
03545 
03546 /******************************************************************************
03547  * ITypeInfo2_GetVarIndexOfMemId {OLEAUT32}
03548  *
03549  *  Gets the index of a variable given its member id.
03550  *
03551  * RETURNS
03552  *
03553  *  Success: S_OK.
03554  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03555  */
03556 static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId(
03557         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the variable. */
03558         MEMBERID memid,    /* [I] The member id for the variable. */
03559         UINT* pVarIndex)   /* [O] The index of the variable. */
03560 {
03561     FIXME("(%p,%d,%p), stub!\n", iface, memid, pVarIndex);
03562     return E_OUTOFMEMORY;
03563 }
03564 
03565 /******************************************************************************
03566  * ITypeInfo2_GetCustData {OLEAUT32}
03567  *
03568  *  Gets a custom data element from a TypeInfo.
03569  *
03570  * RETURNS
03571  *
03572  *  Success: S_OK.
03573  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03574  */
03575 static HRESULT WINAPI ITypeInfo2_fnGetCustData(
03576         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
03577         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
03578         VARIANT* pVarVal)  /* [O] The custom data. */
03579 {
03580     FIXME("(%p,%s,%p), stub!\n", iface, debugstr_guid(guid), pVarVal);
03581     return E_OUTOFMEMORY;
03582 }
03583 
03584 /******************************************************************************
03585  * ITypeInfo2_GetFuncCustData {OLEAUT32}
03586  *
03587  *  Gets a custom data element from a function.
03588  *
03589  * RETURNS
03590  *
03591  *  Success: S_OK.
03592  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03593  */
03594 static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
03595         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
03596         UINT index,        /* [I] The index of the function for which to retrieve the custom data. */
03597         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
03598         VARIANT* pVarVal)  /* [O] The custom data. */
03599 {
03600     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
03601     return E_OUTOFMEMORY;
03602 }
03603 
03604 /******************************************************************************
03605  * ITypeInfo2_GetParamCustData {OLEAUT32}
03606  *
03607  *  Gets a custom data element from a parameter.
03608  *
03609  * RETURNS
03610  *
03611  *  Success: S_OK.
03612  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03613  */
03614 static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
03615         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
03616         UINT indexFunc,    /* [I] The index of the function for which to retrieve the custom data. */
03617         UINT indexParam,   /* [I] The index of the parameter for which to retrieve the custom data. */
03618         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
03619         VARIANT* pVarVal)  /* [O] The custom data. */
03620 {
03621     FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal);
03622     return E_OUTOFMEMORY;
03623 }
03624 
03625 /******************************************************************************
03626  * ITypeInfo2_GetVarCustData {OLEAUT32}
03627  *
03628  *  Gets a custom data element from a variable.
03629  *
03630  * RETURNS
03631  *
03632  *  Success: S_OK.
03633  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03634  */
03635 static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
03636         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
03637         UINT index,        /* [I] The index of the variable for which to retrieve the custom data. */
03638         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
03639         VARIANT* pVarVal)  /* [O] The custom data. */
03640 {
03641     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
03642     return E_OUTOFMEMORY;
03643 }
03644 
03645 /******************************************************************************
03646  * ITypeInfo2_GetImplTypeCustData {OLEAUT32}
03647  *
03648  *  Gets a custom data element from an implemented type of a TypeInfo.
03649  *
03650  * RETURNS
03651  *
03652  *  Success: S_OK.
03653  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03654  */
03655 static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
03656         ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */
03657         UINT index,        /* [I] The index of the implemented type for which to retrieve the custom data. */
03658         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
03659         VARIANT* pVarVal)  /* [O] The custom data. */
03660 {
03661     FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal);
03662     return E_OUTOFMEMORY;
03663 }
03664 
03665 /******************************************************************************
03666  * ITypeInfo2_GetDocumentation2 {OLEAUT32}
03667  *
03668  *  Gets some documentation from a TypeInfo in a locale-aware fashion.
03669  *
03670  * RETURNS
03671  *
03672  *  Success: S_OK.
03673  *  Failure: One of STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
03674  */
03675 static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
03676         ITypeInfo2* iface,           /* [I] The TypeInfo to retrieve the documentation from. */
03677         MEMBERID memid,              /* [I] The member id (why?). */
03678         LCID lcid,                   /* [I] The locale (why?). */
03679         BSTR* pbstrHelpString,       /* [O] The help string. */
03680         DWORD* pdwHelpStringContext, /* [O] The help string context. */
03681         BSTR* pbstrHelpStringDll)    /* [O] The help file name. */
03682 {
03683     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
03684     return E_OUTOFMEMORY;
03685 }
03686 
03687 /******************************************************************************
03688  * ITypeInfo2_GetAllCustData {OLEAUT32}
03689  *
03690  *  Gets all of the custom data associated with a TypeInfo.
03691  *
03692  * RETURNS
03693  *
03694  *  Success: S_OK.
03695  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03696  */
03697 static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
03698         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
03699         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
03700 {
03701     FIXME("(%p,%p), stub!\n", iface, pCustData);
03702     return E_OUTOFMEMORY;
03703 }
03704 
03705 /******************************************************************************
03706  * ITypeInfo2_GetAllFuncCustData {OLEAUT32}
03707  *
03708  *  Gets all of the custom data associated with a function.
03709  *
03710  * RETURNS
03711  *
03712  *  Success: S_OK.
03713  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03714  */
03715 static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
03716         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
03717         UINT index,          /* [I] The index of the function for which to retrieve the custom data. */
03718         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
03719 {
03720     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
03721     return E_OUTOFMEMORY;
03722 }
03723 
03724 /******************************************************************************
03725  * ITypeInfo2_GetAllParamCustData {OLEAUT32}
03726  *
03727  *  Gets all of the custom data associated with a parameter.
03728  *
03729  * RETURNS
03730  *
03731  *  Success: S_OK.
03732  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03733  */
03734 static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData(
03735         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
03736         UINT indexFunc,      /* [I] The index of the function for which to retrieve the custom data. */
03737         UINT indexParam,     /* [I] The index of the parameter for which to retrieve the custom data. */
03738         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
03739 {
03740     FIXME("(%p,%d,%d,%p), stub!\n", iface, indexFunc, indexParam, pCustData);
03741     return E_OUTOFMEMORY;
03742 }
03743 
03744 /******************************************************************************
03745  * ITypeInfo2_GetAllVarCustData {OLEAUT32}
03746  *
03747  *  Gets all of the custom data associated with a variable.
03748  *
03749  * RETURNS
03750  *
03751  *  Success: S_OK.
03752  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03753  */
03754 static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData(
03755         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
03756         UINT index,          /* [I] The index of the variable for which to retrieve the custom data. */
03757         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
03758 {
03759     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
03760     return E_OUTOFMEMORY;
03761 }
03762 
03763 /******************************************************************************
03764  * ITypeInfo2_GetAllImplTypeCustData {OLEAUT32}
03765  *
03766  *  Gets all of the custom data associated with an implemented type.
03767  *
03768  * RETURNS
03769  *
03770  *  Success: S_OK.
03771  *  Failure: One of E_OUTOFMEMORY or E_INVALIDARG.
03772  */
03773 static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
03774         ITypeInfo2* iface,   /* [I] The TypeInfo in which to find the custom data. */
03775         UINT index,          /* [I] The index of the implemented type for which to retrieve the custom data. */
03776         CUSTDATA* pCustData) /* [O] A pointer to the custom data. */
03777 {
03778     FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData);
03779     return E_OUTOFMEMORY;
03780 }
03781 
03782 
03783 /*================== ICreateTypeInfo2 & ITypeInfo2 VTABLEs And Creation ===================================*/
03784 
03785 static const ICreateTypeInfo2Vtbl ctypeinfo2vt =
03786 {
03787 
03788     ICreateTypeInfo2_fnQueryInterface,
03789     ICreateTypeInfo2_fnAddRef,
03790     ICreateTypeInfo2_fnRelease,
03791 
03792     ICreateTypeInfo2_fnSetGuid,
03793     ICreateTypeInfo2_fnSetTypeFlags,
03794     ICreateTypeInfo2_fnSetDocString,
03795     ICreateTypeInfo2_fnSetHelpContext,
03796     ICreateTypeInfo2_fnSetVersion,
03797     ICreateTypeInfo2_fnAddRefTypeInfo,
03798     ICreateTypeInfo2_fnAddFuncDesc,
03799     ICreateTypeInfo2_fnAddImplType,
03800     ICreateTypeInfo2_fnSetImplTypeFlags,
03801     ICreateTypeInfo2_fnSetAlignment,
03802     ICreateTypeInfo2_fnSetSchema,
03803     ICreateTypeInfo2_fnAddVarDesc,
03804     ICreateTypeInfo2_fnSetFuncAndParamNames,
03805     ICreateTypeInfo2_fnSetVarName,
03806     ICreateTypeInfo2_fnSetTypeDescAlias,
03807     ICreateTypeInfo2_fnDefineFuncAsDllEntry,
03808     ICreateTypeInfo2_fnSetFuncDocString,
03809     ICreateTypeInfo2_fnSetVarDocString,
03810     ICreateTypeInfo2_fnSetFuncHelpContext,
03811     ICreateTypeInfo2_fnSetVarHelpContext,
03812     ICreateTypeInfo2_fnSetMops,
03813     ICreateTypeInfo2_fnSetTypeIdldesc,
03814     ICreateTypeInfo2_fnLayOut,
03815 
03816     ICreateTypeInfo2_fnDeleteFuncDesc,
03817     ICreateTypeInfo2_fnDeleteFuncDescByMemId,
03818     ICreateTypeInfo2_fnDeleteVarDesc,
03819     ICreateTypeInfo2_fnDeleteVarDescByMemId,
03820     ICreateTypeInfo2_fnDeleteImplType,
03821     ICreateTypeInfo2_fnSetCustData,
03822     ICreateTypeInfo2_fnSetFuncCustData,
03823     ICreateTypeInfo2_fnSetParamCustData,
03824     ICreateTypeInfo2_fnSetVarCustData,
03825     ICreateTypeInfo2_fnSetImplTypeCustData,
03826     ICreateTypeInfo2_fnSetHelpStringContext,
03827     ICreateTypeInfo2_fnSetFuncHelpStringContext,
03828     ICreateTypeInfo2_fnSetVarHelpStringContext,
03829     ICreateTypeInfo2_fnInvalidate,
03830     ICreateTypeInfo2_fnSetName
03831 };
03832 
03833 static const ITypeInfo2Vtbl typeinfo2vt =
03834 {
03835 
03836     ITypeInfo2_fnQueryInterface,
03837     ITypeInfo2_fnAddRef,
03838     ITypeInfo2_fnRelease,
03839 
03840     ITypeInfo2_fnGetTypeAttr,
03841     ITypeInfo2_fnGetTypeComp,
03842     ITypeInfo2_fnGetFuncDesc,
03843     ITypeInfo2_fnGetVarDesc,
03844     ITypeInfo2_fnGetNames,
03845     ITypeInfo2_fnGetRefTypeOfImplType,
03846     ITypeInfo2_fnGetImplTypeFlags,
03847     ITypeInfo2_fnGetIDsOfNames,
03848     ITypeInfo2_fnInvoke,
03849     ITypeInfo2_fnGetDocumentation,
03850     ITypeInfo2_fnGetDllEntry,
03851     ITypeInfo2_fnGetRefTypeInfo,
03852     ITypeInfo2_fnAddressOfMember,
03853     ITypeInfo2_fnCreateInstance,
03854     ITypeInfo2_fnGetMops,
03855     ITypeInfo2_fnGetContainingTypeLib,
03856     ITypeInfo2_fnReleaseTypeAttr,
03857     ITypeInfo2_fnReleaseFuncDesc,
03858     ITypeInfo2_fnReleaseVarDesc,
03859 
03860     ITypeInfo2_fnGetTypeKind,
03861     ITypeInfo2_fnGetTypeFlags,
03862     ITypeInfo2_fnGetFuncIndexOfMemId,
03863     ITypeInfo2_fnGetVarIndexOfMemId,
03864     ITypeInfo2_fnGetCustData,
03865     ITypeInfo2_fnGetFuncCustData,
03866     ITypeInfo2_fnGetParamCustData,
03867     ITypeInfo2_fnGetVarCustData,
03868     ITypeInfo2_fnGetImplTypeCustData,
03869     ITypeInfo2_fnGetDocumentation2,
03870     ITypeInfo2_fnGetAllCustData,
03871     ITypeInfo2_fnGetAllFuncCustData,
03872     ITypeInfo2_fnGetAllParamCustData,
03873     ITypeInfo2_fnGetAllVarCustData,
03874     ITypeInfo2_fnGetAllImplTypeCustData,
03875 };
03876 
03877 static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typelib, WCHAR *szName, TYPEKIND tkind)
03878 {
03879     ICreateTypeInfo2Impl *pCreateTypeInfo2Impl;
03880 
03881     int nameoffset;
03882     int typeinfo_offset;
03883     MSFT_TypeInfoBase *typeinfo;
03884 
03885     TRACE("Constructing ICreateTypeInfo2 for %s with tkind %d\n", debugstr_w(szName), tkind);
03886 
03887     pCreateTypeInfo2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeInfo2Impl));
03888     if (!pCreateTypeInfo2Impl) return NULL;
03889 
03890     pCreateTypeInfo2Impl->lpVtbl = &ctypeinfo2vt;
03891     pCreateTypeInfo2Impl->lpVtblTypeInfo2 = &typeinfo2vt;
03892     pCreateTypeInfo2Impl->ref = 1;
03893 
03894     pCreateTypeInfo2Impl->typelib = typelib;
03895     ICreateTypeLib_AddRef((ICreateTypeLib*)typelib);
03896 
03897     nameoffset = ctl2_alloc_name(typelib, szName);
03898     typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset);
03899     typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset];
03900 
03901     typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38;
03902     *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset;
03903 
03904     pCreateTypeInfo2Impl->typeinfo = typeinfo;
03905 
03906     pCreateTypeInfo2Impl->typekind = tkind;
03907     typeinfo->typekind |= tkind | 0x20;
03908     ICreateTypeInfo2_SetAlignment((ICreateTypeInfo2 *)pCreateTypeInfo2Impl, 4);
03909 
03910     switch (tkind) {
03911     case TKIND_ENUM:
03912     case TKIND_INTERFACE:
03913     case TKIND_DISPATCH:
03914     case TKIND_COCLASS:
03915     typeinfo->size = 4;
03916     break;
03917 
03918     case TKIND_RECORD:
03919     case TKIND_UNION:
03920     typeinfo->size = 0;
03921     break;
03922 
03923     case TKIND_MODULE:
03924     typeinfo->size = 2;
03925     break;
03926 
03927     case TKIND_ALIAS:
03928     typeinfo->size = -0x75;
03929     break;
03930 
03931     default:
03932     FIXME("(%s,%d), unrecognized typekind %d\n", debugstr_w(szName), tkind, tkind);
03933     typeinfo->size = 0xdeadbeef;
03934     break;
03935     }
03936 
03937     if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = pCreateTypeInfo2Impl;
03938     typelib->last_typeinfo = pCreateTypeInfo2Impl;
03939     if (!typelib->typeinfos) typelib->typeinfos = pCreateTypeInfo2Impl;
03940 
03941     TRACE(" -- %p\n", pCreateTypeInfo2Impl);
03942 
03943     return (ICreateTypeInfo2 *)pCreateTypeInfo2Impl;
03944 }
03945 
03946 
03947 /*================== ICreateTypeLib2 Implementation ===================================*/
03948 
03949 /******************************************************************************
03950  * ICreateTypeLib2_QueryInterface {OLEAUT32}
03951  *
03952  *  See IUnknown_QueryInterface.
03953  */
03954 static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(
03955     ICreateTypeLib2 * iface,
03956     REFIID riid,
03957     VOID **ppvObject)
03958 {
03959     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
03960 
03961     TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
03962 
03963     *ppvObject=NULL;
03964     if(IsEqualIID(riid, &IID_IUnknown) ||
03965        IsEqualIID(riid,&IID_ICreateTypeLib)||
03966        IsEqualIID(riid,&IID_ICreateTypeLib2))
03967     {
03968         *ppvObject = This;
03969     } else if (IsEqualIID(riid, &IID_ITypeLib) ||
03970            IsEqualIID(riid, &IID_ITypeLib2)) {
03971     *ppvObject = &This->lpVtblTypeLib2;
03972     }
03973 
03974     if(*ppvObject)
03975     {
03976         ICreateTypeLib2_AddRef(iface);
03977         TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
03978         return S_OK;
03979     }
03980     TRACE("-- Interface: E_NOINTERFACE\n");
03981     return E_NOINTERFACE;
03982 }
03983 
03984 /******************************************************************************
03985  * ICreateTypeLib2_AddRef {OLEAUT32}
03986  *
03987  *  See IUnknown_AddRef.
03988  */
03989 static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
03990 {
03991     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
03992     ULONG ref = InterlockedIncrement(&This->ref);
03993 
03994     TRACE("(%p)->ref was %u\n",This, ref - 1);
03995 
03996     return ref;
03997 }
03998 
03999 /******************************************************************************
04000  * ICreateTypeLib2_Release {OLEAUT32}
04001  *
04002  *  See IUnknown_Release.
04003  */
04004 static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
04005 {
04006     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04007     ULONG ref = InterlockedDecrement(&This->ref);
04008 
04009     TRACE("(%p)->(%u)\n",This, ref);
04010 
04011     if (!ref) {
04012     int i;
04013 
04014     for (i = 0; i < MSFT_SEG_MAX; i++) {
04015             HeapFree(GetProcessHeap(), 0, This->typelib_segment_data[i]);
04016             This->typelib_segment_data[i] = NULL;
04017     }
04018 
04019         HeapFree(GetProcessHeap(), 0, This->filename);
04020         This->filename = NULL;
04021 
04022     while (This->typeinfos) {
04023         ICreateTypeInfo2Impl *typeinfo = This->typeinfos;
04024         This->typeinfos = typeinfo->next_typeinfo;
04025             if(typeinfo->typedata) {
04026                 CyclicList *iter, *rem;
04027 
04028                 rem = typeinfo->typedata->next;
04029                 typeinfo->typedata->next = NULL;
04030                 iter = rem->next;
04031                 HeapFree(GetProcessHeap(), 0, rem);
04032 
04033                 while(iter) {
04034                     rem = iter;
04035                     iter = iter->next;
04036                     HeapFree(GetProcessHeap(), 0, rem->u.data);
04037                     HeapFree(GetProcessHeap(), 0, rem);
04038                 }
04039             }
04040 
04041             HeapFree(GetProcessHeap(), 0, typeinfo->dual);
04042             HeapFree(GetProcessHeap(), 0, typeinfo);
04043     }
04044 
04045     HeapFree(GetProcessHeap(),0,This);
04046     return 0;
04047     }
04048 
04049     return ref;
04050 }
04051 
04052 
04053 /******************************************************************************
04054  * ICreateTypeLib2_CreateTypeInfo {OLEAUT32}
04055  *
04056  *  See ICreateTypeLib_CreateTypeInfo.
04057  */
04058 static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(
04059     ICreateTypeLib2 * iface,
04060     LPOLESTR szName,
04061     TYPEKIND tkind,
04062     ICreateTypeInfo **ppCTInfo)
04063 {
04064     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04065     char *name;
04066 
04067     TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo);
04068 
04069     ctl2_encode_name(This, szName, &name);
04070     if(ctl2_find_name(This, name) != -1)
04071         return TYPE_E_NAMECONFLICT;
04072 
04073     *ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind);
04074 
04075     if (!*ppCTInfo) return E_OUTOFMEMORY;
04076 
04077     return S_OK;
04078 }
04079 
04080 /******************************************************************************
04081  * ICreateTypeLib2_SetName {OLEAUT32}
04082  *
04083  *  See ICreateTypeLib_SetName.
04084  */
04085 static HRESULT WINAPI ICreateTypeLib2_fnSetName(
04086     ICreateTypeLib2 * iface,
04087     LPOLESTR szName)
04088 {
04089     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04090 
04091     int offset;
04092 
04093     TRACE("(%p,%s)\n", iface, debugstr_w(szName));
04094 
04095     offset = ctl2_alloc_name(This, szName);
04096     if (offset == -1) return E_OUTOFMEMORY;
04097     This->typelib_header.NameOffset = offset;
04098     return S_OK;
04099 }
04100 
04101 /******************************************************************************
04102  * ICreateTypeLib2_SetVersion {OLEAUT32}
04103  *
04104  *  See ICreateTypeLib_SetVersion.
04105  */
04106 static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD wMajorVerNum, WORD wMinorVerNum)
04107 {
04108     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04109 
04110     TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum);
04111 
04112     This->typelib_header.version = wMajorVerNum | (wMinorVerNum << 16);
04113     return S_OK;
04114 }
04115 
04116 /******************************************************************************
04117  * ICreateTypeLib2_SetGuid {OLEAUT32}
04118  *
04119  *  See ICreateTypeLib_SetGuid.
04120  */
04121 static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID guid)
04122 {
04123     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04124 
04125     MSFT_GuidEntry guidentry;
04126     int offset;
04127 
04128     TRACE("(%p,%s)\n", iface, debugstr_guid(guid));
04129 
04130     guidentry.guid = *guid;
04131     guidentry.hreftype = -2;
04132     guidentry.next_hash = -1;
04133 
04134     offset = ctl2_alloc_guid(This, &guidentry);
04135     
04136     if (offset == -1) return E_OUTOFMEMORY;
04137 
04138     This->typelib_header.posguid = offset;
04139 
04140     return S_OK;
04141 }
04142 
04143 /******************************************************************************
04144  * ICreateTypeLib2_SetDocString {OLEAUT32}
04145  *
04146  *  See ICreateTypeLib_SetDocString.
04147  */
04148 static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LPOLESTR szDoc)
04149 {
04150     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04151 
04152     int offset;
04153 
04154     TRACE("(%p,%s)\n", iface, debugstr_w(szDoc));
04155     if (!szDoc)
04156         return E_INVALIDARG;
04157 
04158     offset = ctl2_alloc_string(This, szDoc);
04159     if (offset == -1) return E_OUTOFMEMORY;
04160     This->typelib_header.helpstring = offset;
04161     return S_OK;
04162 }
04163 
04164 /******************************************************************************
04165  * ICreateTypeLib2_SetHelpFileName {OLEAUT32}
04166  *
04167  *  See ICreateTypeLib_SetHelpFileName.
04168  */
04169 static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, LPOLESTR szHelpFileName)
04170 {
04171     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04172 
04173     int offset;
04174 
04175     TRACE("(%p,%s)\n", iface, debugstr_w(szHelpFileName));
04176 
04177     offset = ctl2_alloc_string(This, szHelpFileName);
04178     if (offset == -1) return E_OUTOFMEMORY;
04179     This->typelib_header.helpfile = offset;
04180     This->typelib_header.varflags |= 0x10;
04181     return S_OK;
04182 }
04183 
04184 /******************************************************************************
04185  * ICreateTypeLib2_SetHelpContext {OLEAUT32}
04186  *
04187  *  See ICreateTypeLib_SetHelpContext.
04188  */
04189 static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext)
04190 {
04191     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04192 
04193     TRACE("(%p,%d)\n", iface, dwHelpContext);
04194     This->typelib_header.helpcontext = dwHelpContext;
04195     return S_OK;
04196 }
04197 
04198 /******************************************************************************
04199  * ICreateTypeLib2_SetLcid {OLEAUT32}
04200  *
04201  * Sets both the lcid and lcid2 members in the header to lcid.
04202  *
04203  * As a special case if lcid == LOCALE_NEUTRAL (0), then the first header lcid
04204  * is set to US English while the second one is set to 0.
04205  */
04206 static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lcid)
04207 {
04208     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04209 
04210     TRACE("(%p,%d)\n", iface, lcid);
04211 
04212     This->typelib_header.lcid = This->typelib_header.lcid2 = lcid;
04213 
04214     if(lcid == LOCALE_NEUTRAL) This->typelib_header.lcid = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
04215 
04216     return S_OK;
04217 }
04218 
04219 /******************************************************************************
04220  * ICreateTypeLib2_SetLibFlags {OLEAUT32}
04221  *
04222  *  See ICreateTypeLib_SetLibFlags.
04223  */
04224 static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 * iface, UINT uLibFlags)
04225 {
04226     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04227 
04228     TRACE("(%p,0x%x)\n", iface, uLibFlags);
04229 
04230     This->typelib_header.flags = uLibFlags;
04231 
04232     return S_OK;
04233 }
04234 
04235 static int ctl2_write_chunk(HANDLE hFile, const void *segment, int length)
04236 {
04237     DWORD dwWritten;
04238     if (!WriteFile(hFile, segment, length, &dwWritten, 0)) {
04239         CloseHandle(hFile);
04240         return 0;
04241     }
04242     return -1;
04243 }
04244 
04245 static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segment)
04246 {
04247     DWORD dwWritten;
04248     if (!WriteFile(hFile, This->typelib_segment_data[segment],
04249            This->typelib_segdir[segment].length, &dwWritten, 0)) {
04250     CloseHandle(hFile);
04251     return 0;
04252     }
04253 
04254     return -1;
04255 }
04256 
04257 static HRESULT ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize)
04258 {
04259     ICreateTypeInfo2Impl *typeinfo;
04260     HRESULT hres;
04261 
04262     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
04263         typeinfo->typeinfo->memoffset = filesize;
04264 
04265         hres = ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo);
04266         if(FAILED(hres))
04267             return hres;
04268 
04269     if (typeinfo->typedata)
04270         filesize += typeinfo->typedata->next->u.val
04271                 + ((typeinfo->typeinfo->cElement >> 16) * 12)
04272                 + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4;
04273     }
04274 
04275     return S_OK;
04276 }
04277 
04278 static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment)
04279 {
04280     if (This->typelib_segdir[segment].length) {
04281     This->typelib_segdir[segment].offset = filepos;
04282     } else {
04283     This->typelib_segdir[segment].offset = -1;
04284     }
04285 
04286     return This->typelib_segdir[segment].length;
04287 }
04288 
04289 static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile)
04290 {
04291     ICreateTypeInfo2Impl *typeinfo;
04292 
04293     for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) {
04294         CyclicList *iter;
04295         int offset = 0;
04296 
04297     if (!typeinfo->typedata) continue;
04298 
04299         iter = typeinfo->typedata->next;
04300         ctl2_write_chunk(hFile, &iter->u.val, sizeof(int));
04301         for(iter=iter->next; iter!=typeinfo->typedata->next; iter=iter->next)
04302             ctl2_write_chunk(hFile, iter->u.data, iter->u.data[0] & 0xffff);
04303 
04304         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
04305             ctl2_write_chunk(hFile, &iter->indice, sizeof(int));
04306 
04307         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next)
04308             ctl2_write_chunk(hFile, &iter->name, sizeof(int));
04309 
04310         for(iter=typeinfo->typedata->next->next; iter!=typeinfo->typedata->next; iter=iter->next) {
04311             ctl2_write_chunk(hFile, &offset, sizeof(int));
04312             offset += iter->u.data[0] & 0xffff;
04313         }
04314     }
04315 }
04316 
04317 /******************************************************************************
04318  * ICreateTypeLib2_SaveAllChanges {OLEAUT32}
04319  *
04320  *  See ICreateTypeLib_SaveAllChanges.
04321  */
04322 static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface)
04323 {
04324     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04325 
04326     int retval;
04327     int filepos;
04328     HANDLE hFile;
04329     HRESULT hres;
04330 
04331     TRACE("(%p)\n", iface);
04332 
04333     retval = TYPE_E_IOERROR;
04334 
04335     hFile = CreateFileW(This->filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
04336     if (hFile == INVALID_HANDLE_VALUE) return retval;
04337 
04338     filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir);
04339     filepos += This->typelib_header.nrtypeinfos * 4;
04340 
04341     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO);
04342     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH);
04343     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID);
04344     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES);
04345     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO);
04346     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES);
04347     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH);
04348     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME);
04349     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING);
04350     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEDESC);
04351     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_ARRAYDESC);
04352     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA);
04353     filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID);
04354 
04355     hres = ctl2_finalize_typeinfos(This, filepos);
04356     if(FAILED(hres)) {
04357         CloseHandle(hFile);
04358         return hres;
04359     }
04360 
04361     if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval;
04362     if (This->typelib_header.varflags & HELPDLLFLAG)
04363         if (!ctl2_write_chunk(hFile, &This->helpStringDll, sizeof(This->helpStringDll))) return retval;
04364     if (!ctl2_write_chunk(hFile, This->typelib_typeinfo_offsets, This->typelib_header.nrtypeinfos * 4)) return retval;
04365     if (!ctl2_write_chunk(hFile, This->typelib_segdir, sizeof(This->typelib_segdir))) return retval;
04366     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO    )) return retval;
04367     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH    )) return retval;
04368     if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID        )) return retval;
04369     if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES  )) return retval;
04370     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO  )) return retval;
04371     if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval;
04372     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH    )) return retval;
04373     if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME        )) return retval;
04374     if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING      )) return retval;
04375     if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEDESC    )) return retval;
04376     if (!ctl2_write_segment(This, hFile, MSFT_SEG_ARRAYDESC   )) return retval;
04377     if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATA    )) return retval;
04378     if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATAGUID)) return retval;
04379 
04380     ctl2_write_typeinfos(This, hFile);
04381 
04382     if (!CloseHandle(hFile)) return retval;
04383 
04384     return S_OK;
04385 }
04386 
04387 
04388 /******************************************************************************
04389  * ICreateTypeLib2_DeleteTypeInfo {OLEAUT32}
04390  *
04391  *  Deletes a named TypeInfo from a type library.
04392  *
04393  * RETURNS
04394  *
04395  *  Success: S_OK
04396  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
04397  */
04398 static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(
04399     ICreateTypeLib2 * iface, /* [I] The type library to delete from. */
04400     LPOLESTR szName)         /* [I] The name of the typeinfo to delete. */
04401 {
04402     FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName));
04403     return E_OUTOFMEMORY;
04404 }
04405 
04406 /******************************************************************************
04407  * ICreateTypeLib2_SetCustData {OLEAUT32}
04408  *
04409  *  Sets custom data for a type library.
04410  *
04411  * RETURNS
04412  *
04413  *  Success: S_OK
04414  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
04415  */
04416 static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(
04417     ICreateTypeLib2 * iface, /* [I] The type library to store the custom data in. */
04418     REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */
04419     VARIANT *pVarVal)        /* [I] The custom data itself. */
04420 {
04421     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04422 
04423     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal);
04424 
04425     return ctl2_set_custdata(This, guid, pVarVal, &This->typelib_header.CustomDataOffset);
04426 }
04427 
04428 /******************************************************************************
04429  * ICreateTypeLib2_SetHelpStringContext {OLEAUT32}
04430  *
04431  *  Sets a context number for the library help string.
04432  *
04433  * PARAMS
04434  *  iface     [I] The type library to set the help string context for.
04435  *  dwContext [I] The help string context.
04436  *
04437  * RETURNS
04438  *  Success: S_OK
04439  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
04440  */
04441 static
04442 HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 * iface,
04443                                                       ULONG dwContext)
04444 {
04445     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04446 
04447     TRACE("(%p,%d)\n", iface, dwContext);
04448 
04449     This->typelib_header.helpstringcontext = dwContext;
04450     return S_OK;
04451 }
04452 
04453 /******************************************************************************
04454  * ICreateTypeLib2_SetHelpStringDll {OLEAUT32}
04455  *
04456  *  Set the DLL used to look up localized help strings.
04457  *
04458  * PARAMS
04459  *  iface     [I] The type library to set the help DLL for.
04460  *  szDllName [I] The name of the help DLL.
04461  *
04462  * RETURNS
04463  *  Success: S_OK
04464  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
04465  */
04466 static
04467 HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 * iface,
04468                                                   LPOLESTR szDllName)
04469 {
04470     ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface;
04471     int offset;
04472 
04473     TRACE("(%p,%s)\n", iface, debugstr_w(szDllName));
04474     if (!szDllName)
04475         return E_INVALIDARG;
04476 
04477     offset = ctl2_alloc_string(This, szDllName);
04478     if (offset == -1)
04479         return E_OUTOFMEMORY;
04480     This->typelib_header.varflags |= HELPDLLFLAG;
04481     This->helpStringDll = offset;
04482     return S_OK;
04483 }
04484 
04485 /*================== ITypeLib2 Implementation ===================================*/
04486 
04487 /******************************************************************************
04488  * ITypeLib2_QueryInterface {OLEAUT32}
04489  *
04490  *  See IUnknown_QueryInterface.
04491  */
04492 static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 * iface, REFIID riid, LPVOID * ppv)
04493 {
04494     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04495 
04496     return ICreateTypeLib2_QueryInterface((ICreateTypeLib2 *)This, riid, ppv);
04497 }
04498 
04499 /******************************************************************************
04500  * ITypeLib2_AddRef {OLEAUT32}
04501  *
04502  *  See IUnknown_AddRef.
04503  */
04504 static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 * iface)
04505 {
04506     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04507 
04508     return ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This);
04509 }
04510 
04511 /******************************************************************************
04512  * ITypeLib2_Release {OLEAUT32}
04513  *
04514  *  See IUnknown_Release.
04515  */
04516 static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 * iface)
04517 {
04518     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04519 
04520     return ICreateTypeLib2_Release((ICreateTypeLib2 *)This);
04521 }
04522 
04523 /******************************************************************************
04524  * ITypeLib2_GetTypeInfoCount {OLEAUT32}
04525  *
04526  *  See ITypeLib_GetTypeInfoCount.
04527  */
04528 static UINT WINAPI ITypeLib2_fnGetTypeInfoCount(
04529         ITypeLib2 * iface)
04530 {
04531     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04532 
04533     TRACE("(%p)\n", iface);
04534 
04535     return This->typelib_header.nrtypeinfos;
04536 }
04537 
04538 /******************************************************************************
04539  * ITypeLib2_GetTypeInfo {OLEAUT32}
04540  *
04541  *  See ITypeLib_GetTypeInfo.
04542  */
04543 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
04544         ITypeLib2 * iface,
04545         UINT index,
04546         ITypeInfo** ppTInfo)
04547 {
04548     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04549 
04550     TRACE("(%p,%d,%p)\n", iface, index, ppTInfo);
04551 
04552     if (index >= This->typelib_header.nrtypeinfos) {
04553     return TYPE_E_ELEMENTNOTFOUND;
04554     }
04555 
04556     return ctl2_find_typeinfo_from_offset(This, This->typelib_typeinfo_offsets[index], ppTInfo);
04557 }
04558 
04559 /******************************************************************************
04560  * ITypeLib2_GetTypeInfoType {OLEAUT32}
04561  *
04562  *  See ITypeLib_GetTypeInfoType.
04563  */
04564 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
04565         ITypeLib2 * iface,
04566         UINT index,
04567         TYPEKIND* pTKind)
04568 {
04569     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04570 
04571     TRACE("(%p,%d,%p)\n", iface, index, pTKind);
04572 
04573     if (index >= This->typelib_header.nrtypeinfos) {
04574     return TYPE_E_ELEMENTNOTFOUND;
04575     }
04576 
04577     *pTKind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 15;
04578 
04579     return S_OK;
04580 }
04581 
04582 /******************************************************************************
04583  * ITypeLib2_GetTypeInfoOfGuid {OLEAUT32}
04584  *
04585  *  See ITypeLib_GetTypeInfoOfGuid.
04586  */
04587 static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
04588         ITypeLib2 * iface,
04589         REFGUID guid,
04590         ITypeInfo** ppTinfo)
04591 {
04592     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04593 
04594     int guidoffset;
04595     int typeinfo;
04596 
04597     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), ppTinfo);
04598 
04599     guidoffset = ctl2_find_guid(This, ctl2_hash_guid(guid), guid);
04600     if (guidoffset == -1) return TYPE_E_ELEMENTNOTFOUND;
04601 
04602     typeinfo = ((MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][guidoffset])->hreftype;
04603     if (typeinfo < 0) return TYPE_E_ELEMENTNOTFOUND;
04604 
04605     return ctl2_find_typeinfo_from_offset(This, typeinfo, ppTinfo);
04606 }
04607 
04608 /******************************************************************************
04609  * ITypeLib2_GetLibAttr {OLEAUT32}
04610  *
04611  *  See ITypeLib_GetLibAttr.
04612  */
04613 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
04614         ITypeLib2 * iface,
04615         TLIBATTR** ppTLibAttr)
04616 {
04617     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04618 
04619     TRACE("(%p,%p)\n", This, ppTLibAttr);
04620 
04621     if(!ppTLibAttr)
04622         return E_INVALIDARG;
04623 
04624     *ppTLibAttr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TLIBATTR));
04625     if(!*ppTLibAttr)
04626         return E_OUTOFMEMORY;
04627 
04628     if(This->typelib_header.posguid != -1) {
04629         MSFT_GuidEntry *guid;
04630 
04631         guid = (MSFT_GuidEntry*)&This->typelib_segment_data[MSFT_SEG_GUID][This->typelib_header.posguid];
04632         (*ppTLibAttr)->guid = guid->guid;
04633     }
04634 
04635     (*ppTLibAttr)->lcid = This->typelib_header.lcid;
04636     (*ppTLibAttr)->syskind = This->typelib_header.varflags&0x3;
04637     (*ppTLibAttr)->wMajorVerNum = This->typelib_header.version&0xffff;
04638     (*ppTLibAttr)->wMinorVerNum = This->typelib_header.version>>16;
04639     (*ppTLibAttr)->wLibFlags = This->typelib_header.flags;
04640     return S_OK;
04641 }
04642 
04643 /******************************************************************************
04644  * ITypeLib2_GetTypeComp {OLEAUT32}
04645  *
04646  *  See ITypeLib_GetTypeComp.
04647  */
04648 static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
04649         ITypeLib2 * iface,
04650         ITypeComp** ppTComp)
04651 {
04652     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04653 
04654     FIXME("(%p,%p), stub!\n", This, ppTComp);
04655 
04656     return E_OUTOFMEMORY;
04657 }
04658 
04659 /******************************************************************************
04660  * ITypeLib2_GetDocumentation {OLEAUT32}
04661  *
04662  *  See ITypeLib_GetDocumentation.
04663  */
04664 static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
04665         ITypeLib2 * iface,
04666         INT index,
04667         BSTR* pBstrName,
04668         BSTR* pBstrDocString,
04669         DWORD* pdwHelpContext,
04670         BSTR* pBstrHelpFile)
04671 {
04672     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04673     WCHAR *string;
04674 
04675     TRACE("(%p,%d,%p,%p,%p,%p)\n", This, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
04676 
04677     if(index != -1) {
04678         ICreateTypeInfo2Impl *iter;
04679 
04680         for(iter=This->typeinfos; iter!=NULL && index!=0; iter=iter->next_typeinfo)
04681             index--;
04682 
04683         if(!iter)
04684             return TYPE_E_ELEMENTNOTFOUND;
04685 
04686         return ITypeInfo_GetDocumentation((ITypeInfo*)&iter->lpVtblTypeInfo2,
04687                 -1, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
04688     }
04689 
04690     if(pBstrName) {
04691         if(This->typelib_header.NameOffset == -1)
04692             *pBstrName = NULL;
04693         else {
04694             MSFT_NameIntro *name = (MSFT_NameIntro*)&This->
04695                 typelib_segment_data[MSFT_SEG_NAME][This->typelib_header.NameOffset];
04696 
04697             ctl2_decode_name((char*)&name->namelen, &string);
04698 
04699             *pBstrName = SysAllocString(string);
04700             if(!*pBstrName)
04701                 return E_OUTOFMEMORY;
04702         }
04703     }
04704 
04705     if(pBstrDocString) {
04706         if(This->typelib_header.helpstring == -1)
04707             *pBstrDocString = NULL;
04708         else {
04709             ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpstring], &string);
04710 
04711             *pBstrDocString = SysAllocString(string);
04712             if(!*pBstrDocString) {
04713                 if(pBstrName) SysFreeString(*pBstrName);
04714                 return E_OUTOFMEMORY;
04715             }
04716         }
04717     }
04718 
04719     if(pdwHelpContext)
04720         *pdwHelpContext = This->typelib_header.helpcontext;
04721 
04722     if(pBstrHelpFile) {
04723         if(This->typelib_header.helpfile == -1)
04724             *pBstrHelpFile = NULL;
04725         else {
04726             ctl2_decode_string(&This->typelib_segment_data[MSFT_SEG_STRING][This->typelib_header.helpfile], &string);
04727 
04728             *pBstrHelpFile = SysAllocString(string);
04729             if(!*pBstrHelpFile) {
04730                 if(pBstrName) SysFreeString(*pBstrName);
04731                 if(pBstrDocString) SysFreeString(*pBstrDocString);
04732                 return E_OUTOFMEMORY;
04733             }
04734         }
04735     }
04736 
04737     return S_OK;
04738 }
04739 
04740 /******************************************************************************
04741  * ITypeLib2_IsName {OLEAUT32}
04742  *
04743  *  See ITypeLib_IsName.
04744  */
04745 static HRESULT WINAPI ITypeLib2_fnIsName(
04746         ITypeLib2 * iface,
04747         LPOLESTR szNameBuf,
04748         ULONG lHashVal,
04749         BOOL* pfName)
04750 {
04751     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04752 
04753     char *encoded_name;
04754     int nameoffset;
04755     MSFT_NameIntro *nameintro;
04756 
04757     TRACE("(%p,%s,%x,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName);
04758 
04759     ctl2_encode_name(This, szNameBuf, &encoded_name);
04760     nameoffset = ctl2_find_name(This, encoded_name);
04761 
04762     *pfName = 0;
04763 
04764     if (nameoffset == -1) return S_OK;
04765 
04766     nameintro = (MSFT_NameIntro *)(&This->typelib_segment_data[MSFT_SEG_NAME][nameoffset]);
04767     if (nameintro->hreftype == -1) return S_OK;
04768 
04769     *pfName = 1;
04770 
04771     FIXME("Should be decoding our copy of the name over szNameBuf.\n");
04772 
04773     return S_OK;
04774 }
04775 
04776 /******************************************************************************
04777  * ITypeLib2_FindName {OLEAUT32}
04778  *
04779  *  See ITypeLib_FindName.
04780  */
04781 static HRESULT WINAPI ITypeLib2_fnFindName(
04782         ITypeLib2 * iface,
04783         LPOLESTR szNameBuf,
04784         ULONG lHashVal,
04785         ITypeInfo** ppTInfo,
04786         MEMBERID* rgMemId,
04787         USHORT* pcFound)
04788 {
04789     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04790 
04791     FIXME("(%p,%s,%x,%p,%p,%p), stub!\n", This, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound);
04792 
04793     return E_OUTOFMEMORY;
04794 }
04795 
04796 /******************************************************************************
04797  * ITypeLib2_ReleaseTLibAttr {OLEAUT32}
04798  *
04799  *  See ITypeLib_ReleaseTLibAttr.
04800  */
04801 static void WINAPI ITypeLib2_fnReleaseTLibAttr(
04802         ITypeLib2 * iface,
04803         TLIBATTR* pTLibAttr)
04804 {
04805     TRACE("(%p,%p)\n", iface, pTLibAttr);
04806 
04807     HeapFree(GetProcessHeap(), 0, pTLibAttr);
04808 }
04809 
04810 /******************************************************************************
04811  * ICreateTypeLib2_GetCustData {OLEAUT32}
04812  *
04813  *  Retrieves a custom data value stored on a type library.
04814  *
04815  * RETURNS
04816  *
04817  *  Success: S_OK
04818  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
04819  */
04820 static HRESULT WINAPI ITypeLib2_fnGetCustData(
04821         ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */
04822         REFGUID guid,      /* [I] The GUID under which the custom data is stored. */
04823         VARIANT* pVarVal)  /* [O] The custom data. */
04824 {
04825     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04826 
04827     FIXME("(%p,%s,%p), stub!\n", This, debugstr_guid(guid), pVarVal);
04828 
04829     return E_OUTOFMEMORY;
04830 }
04831 
04832 /******************************************************************************
04833  * ICreateTypeLib2_GetLibStatistics {OLEAUT32}
04834  *
04835  *  Retrieves some statistics about names in a type library, supposedly for
04836  *  hash table optimization purposes.
04837  *
04838  * RETURNS
04839  *
04840  *  Success: S_OK
04841  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
04842  */
04843 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
04844         ITypeLib2 * iface,      /* [I] The type library to get statistics about. */
04845         ULONG* pcUniqueNames,   /* [O] The number of unique names in the type library. */
04846         ULONG* pcchUniqueNames) /* [O] The number of changed (?) characters in names in the type library. */
04847 {
04848     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04849 
04850     FIXME("(%p,%p,%p), stub!\n", This, pcUniqueNames, pcchUniqueNames);
04851 
04852     return E_OUTOFMEMORY;
04853 }
04854 
04855 /******************************************************************************
04856  * ICreateTypeLib2_GetDocumentation2 {OLEAUT32}
04857  *
04858  *  Obtain locale-aware help string information.
04859  *
04860  * RETURNS
04861  *
04862  *  Success: S_OK
04863  *  Failure: STG_E_INSUFFICIENTMEMORY or E_INVALIDARG.
04864  */
04865 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
04866         ITypeLib2 * iface,
04867         INT index,
04868         LCID lcid,
04869         BSTR* pbstrHelpString,
04870         DWORD* pdwHelpStringContext,
04871         BSTR* pbstrHelpStringDll)
04872 {
04873     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04874 
04875     FIXME("(%p,%d,%d,%p,%p,%p), stub!\n", This, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll);
04876 
04877     return E_OUTOFMEMORY;
04878 }
04879 
04880 /******************************************************************************
04881  * ICreateTypeLib2_GetAllCustData {OLEAUT32}
04882  *
04883  *  Retrieve all of the custom data for a type library.
04884  *
04885  * RETURNS
04886  *
04887  *  Success: S_OK
04888  *  Failure: E_OUTOFMEMORY or E_INVALIDARG.
04889  */
04890 static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
04891         ITypeLib2 * iface,   /* [I] The type library in which to find the custom data. */
04892         CUSTDATA* pCustData) /* [O] The structure in which to place the custom data. */
04893 {
04894     ICreateTypeLib2Impl *This = impl_from_ITypeLib2(iface);
04895 
04896     FIXME("(%p,%p), stub!\n", This, pCustData);
04897 
04898     return E_OUTOFMEMORY;
04899 }
04900 
04901 
04902 /*================== ICreateTypeLib2 & ITypeLib2 VTABLEs And Creation ===================================*/
04903 
04904 static const ICreateTypeLib2Vtbl ctypelib2vt =
04905 {
04906 
04907     ICreateTypeLib2_fnQueryInterface,
04908     ICreateTypeLib2_fnAddRef,
04909     ICreateTypeLib2_fnRelease,
04910 
04911     ICreateTypeLib2_fnCreateTypeInfo,
04912     ICreateTypeLib2_fnSetName,
04913     ICreateTypeLib2_fnSetVersion,
04914     ICreateTypeLib2_fnSetGuid,
04915     ICreateTypeLib2_fnSetDocString,
04916     ICreateTypeLib2_fnSetHelpFileName,
04917     ICreateTypeLib2_fnSetHelpContext,
04918     ICreateTypeLib2_fnSetLcid,
04919     ICreateTypeLib2_fnSetLibFlags,
04920     ICreateTypeLib2_fnSaveAllChanges,
04921 
04922     ICreateTypeLib2_fnDeleteTypeInfo,
04923     ICreateTypeLib2_fnSetCustData,
04924     ICreateTypeLib2_fnSetHelpStringContext,
04925     ICreateTypeLib2_fnSetHelpStringDll
04926 };
04927 
04928 static const ITypeLib2Vtbl typelib2vt =
04929 {
04930 
04931     ITypeLib2_fnQueryInterface,
04932     ITypeLib2_fnAddRef,
04933     ITypeLib2_fnRelease,
04934 
04935     ITypeLib2_fnGetTypeInfoCount,
04936     ITypeLib2_fnGetTypeInfo,
04937     ITypeLib2_fnGetTypeInfoType,
04938     ITypeLib2_fnGetTypeInfoOfGuid,
04939     ITypeLib2_fnGetLibAttr,
04940     ITypeLib2_fnGetTypeComp,
04941     ITypeLib2_fnGetDocumentation,
04942     ITypeLib2_fnIsName,
04943     ITypeLib2_fnFindName,
04944     ITypeLib2_fnReleaseTLibAttr,
04945 
04946     ITypeLib2_fnGetCustData,
04947     ITypeLib2_fnGetLibStatistics,
04948     ITypeLib2_fnGetDocumentation2,
04949     ITypeLib2_fnGetAllCustData,
04950 };
04951 
04952 static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR szFile)
04953 {
04954     ICreateTypeLib2Impl *pCreateTypeLib2Impl;
04955     int failed = 0;
04956 
04957     TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(szFile));
04958 
04959     pCreateTypeLib2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeLib2Impl));
04960     if (!pCreateTypeLib2Impl) return NULL;
04961 
04962     pCreateTypeLib2Impl->filename = HeapAlloc(GetProcessHeap(), 0, (strlenW(szFile) + 1) * sizeof(WCHAR));
04963     if (!pCreateTypeLib2Impl->filename) {
04964     HeapFree(GetProcessHeap(), 0, pCreateTypeLib2Impl);
04965     return NULL;
04966     }
04967     strcpyW(pCreateTypeLib2Impl->filename, szFile);
04968 
04969     ctl2_init_header(pCreateTypeLib2Impl);
04970     ctl2_init_segdir(pCreateTypeLib2Impl);
04971 
04972     pCreateTypeLib2Impl->typelib_header.varflags |= syskind;
04973 
04974     /*
04975      * The following two calls return an offset or -1 if out of memory. We
04976      * specifically need an offset of 0, however, so...
04977      */
04978     if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; }
04979     if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; }
04980 
04981     pCreateTypeLib2Impl->typelib_guidhash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_GUIDHASH];
04982     pCreateTypeLib2Impl->typelib_namehash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_NAMEHASH];
04983 
04984     memset(pCreateTypeLib2Impl->typelib_guidhash_segment, 0xff, 0x80);
04985     memset(pCreateTypeLib2Impl->typelib_namehash_segment, 0xff, 0x200);
04986 
04987     pCreateTypeLib2Impl->lpVtbl = &ctypelib2vt;
04988     pCreateTypeLib2Impl->lpVtblTypeLib2 = &typelib2vt;
04989     pCreateTypeLib2Impl->ref = 1;
04990 
04991     if (failed) {
04992     ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)pCreateTypeLib2Impl);
04993     return 0;
04994     }
04995 
04996     return (ICreateTypeLib2 *)pCreateTypeLib2Impl;
04997 }
04998 
04999 /******************************************************************************
05000  * CreateTypeLib2 [OLEAUT32.180]
05001  *
05002  *  Obtains an ICreateTypeLib2 object for creating a new-style (MSFT) type
05003  *  library.
05004  *
05005  * NOTES
05006  *
05007  *  See also CreateTypeLib.
05008  *
05009  * RETURNS
05010  *    Success: S_OK
05011  *    Failure: Status
05012  */
05013 HRESULT WINAPI CreateTypeLib2(
05014     SYSKIND syskind,           /* [I] System type library is for */
05015     LPCOLESTR szFile,          /* [I] Type library file name */
05016     ICreateTypeLib2** ppctlib) /* [O] Storage for object returned */
05017 {
05018     TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib);
05019 
05020     if (!szFile) return E_INVALIDARG;
05021     *ppctlib = ICreateTypeLib2_Constructor(syskind, szFile);
05022     return (*ppctlib)? S_OK: E_OUTOFMEMORY;
05023 }
05024 
05025 /******************************************************************************
05026  * ClearCustData (OLEAUT32.171)
05027  *
05028  * Clear a custom data types' data.
05029  *
05030  * PARAMS
05031  *  lpCust [I] The custom data type instance
05032  *
05033  * RETURNS
05034  *  Nothing.
05035  */
05036 void WINAPI ClearCustData(LPCUSTDATA lpCust)
05037 {
05038     if (lpCust && lpCust->cCustData)
05039     {
05040         if (lpCust->prgCustData)
05041         {
05042             DWORD i;
05043 
05044             for (i = 0; i < lpCust->cCustData; i++)
05045                 VariantClear(&lpCust->prgCustData[i].varValue);
05046 
05047             /* FIXME - Should be using a per-thread IMalloc */
05048             HeapFree(GetProcessHeap(), 0, lpCust->prgCustData);
05049             lpCust->prgCustData = NULL;
05050         }
05051         lpCust->cCustData = 0;
05052     }
05053 }

Generated on Sat May 26 2012 04:24:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.