Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentypelib2.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
1.7.6.1
|