ReactOS 0.4.16-dev-197-g92996da
typelib.c
Go to the documentation of this file.
1/*
2 * TYPELIB
3 *
4 * Copyright 1997 Marcus Meissner
5 * 1999 Rein Klazes
6 * 2000 Francois Jacques
7 * 2001 Huw D M Davies for CodeWeavers
8 * 2004 Alastair Bridgewater
9 * 2005 Robert Shearman, for CodeWeavers
10 * 2013 Andrew Eikum for CodeWeavers
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 *
26 * --------------------------------------------------------------------------------------
27 * Known problems (2000, Francois Jacques)
28 *
29 * - Tested using OLEVIEW (Platform SDK tool) only.
30 *
31 * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are
32 * creating by doing a straight copy of the dispinterface instance and just changing
33 * its typekind. Pointed structures aren't copied - only the address of the pointers.
34 *
35 * - locale stuff is partially implemented but hasn't been tested.
36 *
37 * - typelib file is still read in its entirety, but it is released now.
38 *
39 * --------------------------------------------------------------------------------------
40 * Known problems left from previous implementation (1999, Rein Klazes) :
41 *
42 * -. Data structures are straightforward, but slow for look-ups.
43 * -. (related) nothing is hashed
44 * -. Most error return values are just guessed not checked with windows
45 * behaviour.
46 * -. lousy fatal error handling
47 *
48 */
49
50#include <stdlib.h>
51#include <string.h>
52#include <stdarg.h>
53#include <stdio.h>
54#include <ctype.h>
55
56#define COBJMACROS
57#define NONAMELESSUNION
58
59#include "winerror.h"
60#include "windef.h"
61#include "winbase.h"
62#include "winnls.h"
63#include "winreg.h"
64#include "winuser.h"
65#include "winternl.h"
66#include "lzexpand.h"
67
68#include "objbase.h"
69#include "typelib.h"
70#include "wine/debug.h"
71#include "variant.h"
72#include "wine/asm.h"
73#include "wine/heap.h"
74#include "wine/list.h"
75
78
79typedef struct
80{
88
89typedef struct
90{
91 WORD type_id; /* Type identifier */
92 WORD count; /* Number of resources of this type */
93 DWORD resloader; /* SetResourceHandler() */
94 /*
95 * Name info array.
96 */
98
99static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt);
100static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr);
101static void TLB_FreeVarDesc(VARDESC*);
102
103/****************************************************************************
104 * FromLExxx
105 *
106 * Takes p_iVal (which is in little endian) and returns it
107 * in the host machine's byte order.
108 */
109#ifdef WORDS_BIGENDIAN
110static WORD FromLEWord(WORD p_iVal)
111{
112 return (((p_iVal & 0x00FF) << 8) |
113 ((p_iVal & 0xFF00) >> 8));
114}
115
116
117static DWORD FromLEDWord(DWORD p_iVal)
118{
119 return (((p_iVal & 0x000000FF) << 24) |
120 ((p_iVal & 0x0000FF00) << 8) |
121 ((p_iVal & 0x00FF0000) >> 8) |
122 ((p_iVal & 0xFF000000) >> 24));
123}
124#else
125#define FromLEWord(X) (X)
126#define FromLEDWord(X) (X)
127#endif
128
129#define DISPATCH_HREF_OFFSET 0x01000000
130#define DISPATCH_HREF_MASK 0xff000000
131
132/****************************************************************************
133 * FromLExxx
134 *
135 * Fix byte order in any structure if necessary
136 */
137#ifdef WORDS_BIGENDIAN
138static void FromLEWords(void *p_Val, int p_iSize)
139{
140 WORD *Val = p_Val;
141
142 p_iSize /= sizeof(WORD);
143
144 while (p_iSize) {
145 *Val = FromLEWord(*Val);
146 Val++;
147 p_iSize--;
148 }
149}
150
151
152static void FromLEDWords(void *p_Val, int p_iSize)
153{
154 DWORD *Val = p_Val;
155
156 p_iSize /= sizeof(DWORD);
157
158 while (p_iSize) {
159 *Val = FromLEDWord(*Val);
160 Val++;
161 p_iSize--;
162 }
163}
164#else
165#define FromLEWords(X,Y) /*nothing*/
166#define FromLEDWords(X,Y) /*nothing*/
167#endif
168
169/*
170 * Find a typelib key which matches a requested maj.min version.
171 */
172static BOOL find_typelib_key( REFGUID guid, WORD *wMaj, WORD *wMin )
173{
174 static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
175 WCHAR buffer[60];
176 char key_name[16];
177 DWORD len, i;
178 INT best_maj = -1, best_min = -1;
179 HKEY hkey;
180
181 memcpy( buffer, typelibW, sizeof(typelibW) );
183
185 return FALSE;
186
187 len = sizeof(key_name);
188 i = 0;
189 while (RegEnumKeyExA(hkey, i++, key_name, &len, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
190 {
191 INT v_maj, v_min;
192
193 if (sscanf(key_name, "%x.%x", &v_maj, &v_min) == 2)
194 {
195 TRACE("found %s: %x.%x\n", debugstr_w(buffer), v_maj, v_min);
196
197 if (*wMaj == 0xffff && *wMin == 0xffff)
198 {
199 if (v_maj > best_maj) best_maj = v_maj;
200 if (v_min > best_min) best_min = v_min;
201 }
202 else if (*wMaj == v_maj)
203 {
204 best_maj = v_maj;
205
206 if (*wMin == v_min)
207 {
208 best_min = v_min;
209 break; /* exact match */
210 }
211 if (*wMin != 0xffff && v_min > best_min) best_min = v_min;
212 }
213 }
214 len = sizeof(key_name);
215 }
216 RegCloseKey( hkey );
217
218 TRACE("found best_maj %d, best_min %d\n", best_maj, best_min);
219
220 if (*wMaj == 0xffff && *wMin == 0xffff)
221 {
222 if (best_maj >= 0 && best_min >= 0)
223 {
224 *wMaj = best_maj;
225 *wMin = best_min;
226 return TRUE;
227 }
228 }
229
230 if (*wMaj == best_maj && best_min >= 0)
231 {
232 *wMin = best_min;
233 return TRUE;
234 }
235 return FALSE;
236}
237
238/* get the path of a typelib key, in the form "Typelib\<guid>\<maj>.<min>" */
239/* buffer must be at least 60 characters long */
241{
242 static const WCHAR TypelibW[] = {'T','y','p','e','l','i','b','\\',0};
243 static const WCHAR VersionFormatW[] = {'\\','%','x','.','%','x',0};
244
245 memcpy( buffer, TypelibW, sizeof(TypelibW) );
247 swprintf( buffer + lstrlenW(buffer), VersionFormatW, wMaj, wMin );
248 return buffer;
249}
250
251/* get the path of an interface key, in the form "Interface\<guid>" */
252/* buffer must be at least 50 characters long */
254{
255 static const WCHAR InterfaceW[] = {'I','n','t','e','r','f','a','c','e','\\',0};
256
257 memcpy( buffer, InterfaceW, sizeof(InterfaceW) );
259 return buffer;
260}
261
262/* get the lcid subkey for a typelib, in the form "<lcid>\<syskind>" */
263/* buffer must be at least 16 characters long */
264static WCHAR *get_lcid_subkey( LCID lcid, SYSKIND syskind, WCHAR *buffer )
265{
266 static const WCHAR LcidFormatW[] = {'%','l','x','\\',0};
267 static const WCHAR win16W[] = {'w','i','n','1','6',0};
268 static const WCHAR win32W[] = {'w','i','n','3','2',0};
269 static const WCHAR win64W[] = {'w','i','n','6','4',0};
270
271 swprintf( buffer, LcidFormatW, lcid );
272 switch(syskind)
273 {
274 case SYS_WIN16: lstrcatW( buffer, win16W ); break;
275 case SYS_WIN32: lstrcatW( buffer, win32W ); break;
276 case SYS_WIN64: lstrcatW( buffer, win64W ); break;
277 default:
278 TRACE("Typelib is for unsupported syskind %i\n", syskind);
279 return NULL;
280 }
281 return buffer;
282}
283
284static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib);
285
287{
288 ULONG size;
289 DWORD res;
293 WORD flags;
298};
299
300/* Get the path to a registered type library. Helper for QueryPathOfRegTypeLib. */
302 SYSKIND syskind, LCID lcid, BSTR *path, BOOL redir )
303{
305 LCID myLCID = lcid;
306 HKEY hkey;
307 WCHAR buffer[60];
309 LONG res;
310
311 TRACE_(typelib)("(%s, %x.%x, 0x%x, %p)\n", debugstr_guid(guid), wMaj, wMin, lcid, path);
312
313 if (redir)
314 {
315 ACTCTX_SECTION_KEYED_DATA data;
316
317 data.cbSize = sizeof(data);
318 if (FindActCtxSectionGuid( 0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, guid, &data ))
319 {
320 struct tlibredirect_data *tlib = (struct tlibredirect_data*)data.lpData;
321 WCHAR *nameW;
322 DWORD len;
323
324 if ((wMaj != 0xffff || wMin != 0xffff) && (tlib->major_version != wMaj || tlib->minor_version < wMin))
326
327 nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
329 if (!len) return TYPE_E_LIBNOTREGISTERED;
330
331 TRACE_(typelib)("got path from context %s\n", debugstr_w(Path));
333 return S_OK;
334 }
335 }
336
337 if (!find_typelib_key( guid, &wMaj, &wMin )) return TYPE_E_LIBNOTREGISTERED;
338 get_typelib_key( guid, wMaj, wMin, buffer );
339
342 {
343 TRACE_(typelib)("%s not found\n", debugstr_w(buffer));
345 }
346 else if (res != ERROR_SUCCESS)
347 {
348 TRACE_(typelib)("failed to open %s for read access\n", debugstr_w(buffer));
350 }
351
352 while (hr != S_OK)
353 {
354 LONG dwPathLen = sizeof(Path);
355
356 get_lcid_subkey( myLCID, syskind, buffer );
357
358 if (RegQueryValueW(hkey, buffer, Path, &dwPathLen))
359 {
360 if (!lcid)
361 break;
362 else if (myLCID == lcid)
363 {
364 /* try with sub-langid */
365 myLCID = SUBLANGID(lcid);
366 }
367 else if ((myLCID == SUBLANGID(lcid)) && myLCID)
368 {
369 /* try with system langid */
370 myLCID = 0;
371 }
372 else
373 {
374 break;
375 }
376 }
377 else
378 {
380 hr = S_OK;
381 }
382 }
383 RegCloseKey( hkey );
384 TRACE_(typelib)("-- 0x%08x\n", hr);
385 return hr;
386}
387
388/****************************************************************************
389 * QueryPathOfRegTypeLib [OLEAUT32.164]
390 *
391 * Gets the path to a registered type library.
392 *
393 * PARAMS
394 * guid [I] referenced guid
395 * wMaj [I] major version
396 * wMin [I] minor version
397 * lcid [I] locale id
398 * path [O] path of typelib
399 *
400 * RETURNS
401 * Success: S_OK.
402 * Failure: If the type library is not registered then TYPE_E_LIBNOTREGISTERED
403 * or TYPE_E_REGISTRYACCESS if the type library registration key couldn't be
404 * opened.
405 */
407{
408 BOOL redir = TRUE;
409#ifdef _WIN64
410 HRESULT hres = query_typelib_path( guid, wMaj, wMin, SYS_WIN64, lcid, path, TRUE );
411 if(SUCCEEDED(hres))
412 return hres;
413 redir = FALSE;
414#endif
415 return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path, redir );
416}
417
418/******************************************************************************
419 * CreateTypeLib [OLEAUT32.160] creates a typelib
420 *
421 * RETURNS
422 * Success: S_OK
423 * Failure: Status
424 */
426{
427 ICreateTypeLib2 *typelib2;
429
430 FIXME("(%d, %s, %p): forwarding to CreateTypeLib2\n", syskind, debugstr_w(file), ctlib);
431
432 hres = CreateTypeLib2(syskind, file, &typelib2);
433 if(SUCCEEDED(hres))
434 {
435 hres = ICreateTypeLib2_QueryInterface(typelib2, &IID_ICreateTypeLib, (void **)&ctlib);
436 ICreateTypeLib2_Release(typelib2);
437 }
438
439 return hres;
440}
441
442/******************************************************************************
443 * LoadTypeLib [OLEAUT32.161]
444 *
445 * Loads a type library
446 *
447 * PARAMS
448 * szFile [I] Name of file to load from.
449 * pptLib [O] Pointer that receives ITypeLib object on success.
450 *
451 * RETURNS
452 * Success: S_OK
453 * Failure: Status
454 *
455 * SEE
456 * LoadTypeLibEx, LoadRegTypeLib, CreateTypeLib.
457 */
458HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib * *pptLib)
459{
460 TRACE("(%s,%p)\n",debugstr_w(szFile), pptLib);
461 return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
462}
463
464/******************************************************************************
465 * LoadTypeLibEx [OLEAUT32.183]
466 *
467 * Loads and optionally registers a type library
468 *
469 * RETURNS
470 * Success: S_OK
471 * Failure: Status
472 */
474 LPCOLESTR szFile, /* [in] Name of file to load from */
475 REGKIND regkind, /* [in] Specify kind of registration */
476 ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
477{
479 HRESULT res;
480
481 TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
482
483 if (!szFile || !pptLib)
484 return E_INVALIDARG;
485
486 *pptLib = NULL;
487
488 res = TLB_ReadTypeLib(szFile, szPath, MAX_PATH + 1, (ITypeLib2**)pptLib);
489
490 if (SUCCEEDED(res))
491 switch(regkind)
492 {
493 case REGKIND_DEFAULT:
494 /* don't register typelibs supplied with full path. Experimentation confirms the following */
495 if (((szFile[0] == '\\') && (szFile[1] == '\\')) ||
496 (szFile[0] && (szFile[1] == ':'))) break;
497 /* else fall-through */
498
499 case REGKIND_REGISTER:
500 if (FAILED(res = RegisterTypeLib(*pptLib, szPath, NULL)))
501 {
502 ITypeLib_Release(*pptLib);
503 *pptLib = 0;
504 }
505 break;
506 case REGKIND_NONE:
507 break;
508 }
509
510 TRACE(" returns %08x\n",res);
511 return res;
512}
513
514/******************************************************************************
515 * LoadRegTypeLib [OLEAUT32.162]
516 *
517 * Loads a registered type library.
518 *
519 * PARAMS
520 * rguid [I] GUID of the registered type library.
521 * wVerMajor [I] major version.
522 * wVerMinor [I] minor version.
523 * lcid [I] locale ID.
524 * ppTLib [O] pointer that receives an ITypeLib object on success.
525 *
526 * RETURNS
527 * Success: S_OK.
528 * Failure: Any HRESULT code returned from QueryPathOfRegTypeLib or
529 * LoadTypeLib.
530 */
532 REFGUID rguid,
533 WORD wVerMajor,
534 WORD wVerMinor,
535 LCID lcid,
536 ITypeLib **ppTLib)
537{
538 BSTR bstr=NULL;
539 HRESULT res;
540
541 *ppTLib = NULL;
542
543 res = QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);
544
545 if(SUCCEEDED(res))
546 {
547 res= LoadTypeLib(bstr, ppTLib);
548 SysFreeString(bstr);
549
550 if ((wVerMajor!=0xffff || wVerMinor!=0xffff) && *ppTLib)
551 {
552 TLIBATTR *attr;
553
554 res = ITypeLib_GetLibAttr(*ppTLib, &attr);
555 if (res == S_OK)
556 {
557 BOOL mismatch = attr->wMajorVerNum != wVerMajor || attr->wMinorVerNum < wVerMinor;
558 ITypeLib_ReleaseTLibAttr(*ppTLib, attr);
559
560 if (mismatch)
561 {
562 ITypeLib_Release(*ppTLib);
563 *ppTLib = NULL;
565 }
566 }
567 }
568 }
569
570 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
571
572 return res;
573}
574
575
576/* some string constants shared between RegisterTypeLib and UnRegisterTypeLib */
577static const WCHAR TypeLibW[] = {'T','y','p','e','L','i','b',0};
578static const WCHAR FLAGSW[] = {'F','L','A','G','S',0};
579static const WCHAR HELPDIRW[] = {'H','E','L','P','D','I','R',0};
580static const WCHAR ProxyStubClsidW[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d',0};
581static const WCHAR ProxyStubClsid32W[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
582
583static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *tattr, DWORD flag)
584{
585 WCHAR keyName[60];
586 HKEY key, subKey;
587
588 static const WCHAR typelib_proxy_clsid[] = {'{','0','0','0','2','0','4','2','4','-',
589 '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-',
590 '0','0','0','0','0','0','0','0','0','0','4','6','}',0};
591 static const WCHAR dispatch_proxy_clsid[] = {'{','0','0','0','2','0','4','2','0','-',
592 '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-',
593 '0','0','0','0','0','0','0','0','0','0','4','6','}',0};
594
595 get_interface_key( &tattr->guid, keyName );
596 if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
598 {
599 const WCHAR *proxy_clsid;
600
601 if (tattr->typekind == TKIND_INTERFACE || (tattr->wTypeFlags & TYPEFLAG_FDUAL))
602 proxy_clsid = typelib_proxy_clsid;
603 else
604 proxy_clsid = dispatch_proxy_clsid;
605
606 if (name)
608 (BYTE *)name, (lstrlenW(name)+1) * sizeof(OLECHAR));
609
611 KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) {
612 RegSetValueExW(subKey, NULL, 0, REG_SZ,
613 (const BYTE *)proxy_clsid, sizeof(typelib_proxy_clsid));
614 RegCloseKey(subKey);
615 }
616
618 KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS) {
619 RegSetValueExW(subKey, NULL, 0, REG_SZ,
620 (const BYTE *)proxy_clsid, sizeof(typelib_proxy_clsid));
621 RegCloseKey(subKey);
622 }
623
624 if (RegCreateKeyExW(key, TypeLibW, 0, NULL, 0,
625 KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS)
626 {
627 WCHAR buffer[40];
628 static const WCHAR fmtver[] = {'%','x','.','%','x',0 };
629 static const WCHAR VersionW[] = {'V','e','r','s','i','o','n',0};
630
631 StringFromGUID2(&libattr->guid, buffer, 40);
632 RegSetValueExW(subKey, NULL, 0, REG_SZ,
633 (BYTE *)buffer, (lstrlenW(buffer)+1) * sizeof(WCHAR));
634 swprintf(buffer, fmtver, libattr->wMajorVerNum, libattr->wMinorVerNum);
635 RegSetValueExW(subKey, VersionW, 0, REG_SZ,
636 (BYTE*)buffer, (lstrlenW(buffer)+1) * sizeof(WCHAR));
637 RegCloseKey(subKey);
638 }
639
641 }
642}
643
644/******************************************************************************
645 * RegisterTypeLib [OLEAUT32.163]
646 * Adds information about a type library to the System Registry
647 * NOTES
648 * Docs: ITypeLib FAR * ptlib
649 * Docs: OLECHAR FAR* szFullPath
650 * Docs: OLECHAR FAR* szHelpDir
651 *
652 * RETURNS
653 * Success: S_OK
654 * Failure: Status
655 */
656HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const WCHAR *szHelpDir)
657{
658 HRESULT res;
659 TLIBATTR *attr;
660 WCHAR keyName[60];
661 WCHAR tmp[16];
662 HKEY key, subKey;
663 UINT types, tidx;
664 TYPEKIND kind;
665 DWORD disposition;
666
667 if (ptlib == NULL || szFullPath == NULL)
668 return E_INVALIDARG;
669
670 if (FAILED(ITypeLib_GetLibAttr(ptlib, &attr)))
671 return E_FAIL;
672
673#ifndef _WIN64
674 if (attr->syskind == SYS_WIN64) return TYPE_E_BADMODULEKIND;
675#endif
676
677 get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName );
678
679 res = S_OK;
680 if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
682 {
683 LPOLESTR doc;
684
685 /* Set the human-readable name of the typelib */
686 if (FAILED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
687 res = E_FAIL;
688 else if (doc)
689 {
690 if (RegSetValueExW(key, NULL, 0, REG_SZ,
691 (BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
692 res = E_FAIL;
693
694 SysFreeString(doc);
695 }
696
697 /* Make up the name of the typelib path subkey */
698 if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;
699
700 /* Create the typelib path subkey */
701 if (res == S_OK && RegCreateKeyExW(key, tmp, 0, NULL, 0,
702 KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
703 {
704 if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
705 (BYTE *)szFullPath, (lstrlenW(szFullPath)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
706 res = E_FAIL;
707
708 RegCloseKey(subKey);
709 }
710 else
711 res = E_FAIL;
712
713 /* Create the flags subkey */
714 if (res == S_OK && RegCreateKeyExW(key, FLAGSW, 0, NULL, 0,
715 KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
716 {
717 /* FIXME: is %u correct? */
718 static const WCHAR formatW[] = {'%','u',0};
719 WCHAR buf[20];
720 swprintf(buf, formatW, attr->wLibFlags);
721 if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
722 (BYTE *)buf, (lstrlenW(buf) + 1)*sizeof(WCHAR) ) != ERROR_SUCCESS)
723 res = E_FAIL;
724
725 RegCloseKey(subKey);
726 }
727 else
728 res = E_FAIL;
729
730 /* create the helpdir subkey */
731 if (res == S_OK && RegCreateKeyExW(key, HELPDIRW, 0, NULL, 0,
732 KEY_WRITE, NULL, &subKey, &disposition) == ERROR_SUCCESS)
733 {
734 BSTR freeHelpDir = NULL;
735 OLECHAR* pIndexStr;
736
737 /* if we created a new key, and helpDir was null, set the helpdir
738 to the directory which contains the typelib. However,
739 if we just opened an existing key, we leave the helpdir alone */
740 if ((disposition == REG_CREATED_NEW_KEY) && (szHelpDir == NULL)) {
741 szHelpDir = freeHelpDir = SysAllocString(szFullPath);
742 pIndexStr = wcsrchr(szHelpDir, '\\');
743 if (pIndexStr) {
744 *pIndexStr = 0;
745 }
746 }
747
748 /* if we have an szHelpDir, set it! */
749 if (szHelpDir != NULL) {
750 if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
751 (BYTE *)szHelpDir, (lstrlenW(szHelpDir)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) {
752 res = E_FAIL;
753 }
754 }
755
756 SysFreeString(freeHelpDir);
757 RegCloseKey(subKey);
758 } else {
759 res = E_FAIL;
760 }
761
763 }
764 else
765 res = E_FAIL;
766
767 /* register OLE Automation-compatible interfaces for this typelib */
768 types = ITypeLib_GetTypeInfoCount(ptlib);
769 for (tidx=0; tidx<types; tidx++) {
770 if (SUCCEEDED(ITypeLib_GetTypeInfoType(ptlib, tidx, &kind))) {
772 ITypeInfo *tinfo = NULL;
773
774 ITypeLib_GetDocumentation(ptlib, tidx, &name, NULL, NULL, NULL);
775
776 switch (kind) {
777 case TKIND_INTERFACE:
778 TRACE_(typelib)("%d: interface %s\n", tidx, debugstr_w(name));
779 ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
780 break;
781
782 case TKIND_DISPATCH:
783 TRACE_(typelib)("%d: dispinterface %s\n", tidx, debugstr_w(name));
784 ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
785 break;
786
787 default:
788 TRACE_(typelib)("%d: %s\n", tidx, debugstr_w(name));
789 break;
790 }
791
792 if (tinfo) {
793 TYPEATTR *tattr = NULL;
794 ITypeInfo_GetTypeAttr(tinfo, &tattr);
795
796 if (tattr) {
797 TRACE_(typelib)("guid=%s, flags=%04x (",
798 debugstr_guid(&tattr->guid),
799 tattr->wTypeFlags);
800
801 if (TRACE_ON(typelib)) {
802#define XX(x) if (TYPEFLAG_##x & tattr->wTypeFlags) MESSAGE(#x"|");
803 XX(FAPPOBJECT);
804 XX(FCANCREATE);
805 XX(FLICENSED);
806 XX(FPREDECLID);
807 XX(FHIDDEN);
808 XX(FCONTROL);
809 XX(FDUAL);
810 XX(FNONEXTENSIBLE);
811 XX(FOLEAUTOMATION);
812 XX(FRESTRICTED);
813 XX(FAGGREGATABLE);
814 XX(FREPLACEABLE);
815 XX(FDISPATCHABLE);
816 XX(FREVERSEBIND);
817 XX(FPROXY);
818#undef XX
819 MESSAGE("\n");
820 }
821
822 /* Register all dispinterfaces (which includes dual interfaces) and
823 oleautomation interfaces */
824 if ((kind == TKIND_INTERFACE && (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
825 kind == TKIND_DISPATCH)
826 {
828 DWORD opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
829
830 /* register interface<->typelib coupling */
831 TLB_register_interface(attr, name, tattr, 0);
832
833 /* register TLBs into the opposite registry view, too */
834 if(opposite == KEY_WOW64_32KEY ||
836 TLB_register_interface(attr, name, tattr, opposite);
837 }
838
839 ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
840 }
841
842 ITypeInfo_Release(tinfo);
843 }
844
846 }
847 }
848
849 ITypeLib_ReleaseTLibAttr(ptlib, attr);
850
851 return res;
852}
853
855{
856 WCHAR subKeyName[50];
857 HKEY subKey;
858
859 /* the path to the type */
860 get_interface_key( guid, subKeyName );
861
862 /* Delete its bits */
863 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE | flag, &subKey) != ERROR_SUCCESS)
864 return;
865
868 RegDeleteKeyW(subKey, TypeLibW);
869 RegCloseKey(subKey);
870 RegDeleteKeyExW(HKEY_CLASSES_ROOT, subKeyName, flag, 0);
871}
872
873/******************************************************************************
874 * UnRegisterTypeLib [OLEAUT32.186]
875 * Removes information about a type library from the System Registry
876 * NOTES
877 *
878 * RETURNS
879 * Success: S_OK
880 * Failure: Status
881 */
883 REFGUID libid, /* [in] Guid of the library */
884 WORD wVerMajor, /* [in] major version */
885 WORD wVerMinor, /* [in] minor version */
886 LCID lcid, /* [in] locale id */
887 SYSKIND syskind)
888{
889 BSTR tlibPath = NULL;
890 DWORD tmpLength;
891 WCHAR keyName[60];
892 WCHAR subKeyName[50];
893 int result = S_OK;
894 DWORD i = 0;
895 BOOL deleteOtherStuff;
896 HKEY key = NULL;
897 TYPEATTR* typeAttr = NULL;
898 TYPEKIND kind;
899 ITypeInfo* typeInfo = NULL;
900 ITypeLib* typeLib = NULL;
901 int numTypes;
902
903 TRACE("(IID: %s)\n",debugstr_guid(libid));
904
905 /* Create the path to the key */
906 get_typelib_key( libid, wVerMajor, wVerMinor, keyName );
907
908 if (syskind != SYS_WIN16 && syskind != SYS_WIN32 && syskind != SYS_WIN64)
909 {
910 TRACE("Unsupported syskind %i\n", syskind);
912 goto end;
913 }
914
915 /* get the path to the typelib on disk */
916 if (query_typelib_path(libid, wVerMajor, wVerMinor, syskind, lcid, &tlibPath, FALSE) != S_OK) {
918 goto end;
919 }
920
921 /* Try and open the key to the type library. */
924 goto end;
925 }
926
927 /* Try and load the type library */
928 if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib) != S_OK) {
930 goto end;
931 }
932
933 /* remove any types registered with this typelib */
934 numTypes = ITypeLib_GetTypeInfoCount(typeLib);
935 for (i=0; i<numTypes; i++) {
936 /* get the kind of type */
937 if (ITypeLib_GetTypeInfoType(typeLib, i, &kind) != S_OK) {
938 goto enddeleteloop;
939 }
940
941 /* skip non-interfaces, and get type info for the type */
942 if ((kind != TKIND_INTERFACE) && (kind != TKIND_DISPATCH)) {
943 goto enddeleteloop;
944 }
945 if (ITypeLib_GetTypeInfo(typeLib, i, &typeInfo) != S_OK) {
946 goto enddeleteloop;
947 }
948 if (ITypeInfo_GetTypeAttr(typeInfo, &typeAttr) != S_OK) {
949 goto enddeleteloop;
950 }
951
952 if ((kind == TKIND_INTERFACE && (typeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
953 kind == TKIND_DISPATCH)
954 {
956 REGSAM opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
957
958 TLB_unregister_interface(&typeAttr->guid, 0);
959
960 /* unregister TLBs into the opposite registry view, too */
961 if(opposite == KEY_WOW64_32KEY ||
963 TLB_unregister_interface(&typeAttr->guid, opposite);
964 }
965 }
966
967enddeleteloop:
968 if (typeAttr) ITypeInfo_ReleaseTypeAttr(typeInfo, typeAttr);
969 typeAttr = NULL;
970 if (typeInfo) ITypeInfo_Release(typeInfo);
971 typeInfo = NULL;
972 }
973
974 /* Now, delete the type library path subkey */
975 get_lcid_subkey( lcid, syskind, subKeyName );
976 RegDeleteKeyW(key, subKeyName);
977 *wcsrchr( subKeyName, '\\' ) = 0; /* remove last path component */
978 RegDeleteKeyW(key, subKeyName);
979
980 /* check if there is anything besides the FLAGS/HELPDIR keys.
981 If there is, we don't delete them */
982 tmpLength = ARRAY_SIZE(subKeyName);
983 deleteOtherStuff = TRUE;
984 i = 0;
985 while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
986 tmpLength = ARRAY_SIZE(subKeyName);
987
988 /* if its not FLAGS or HELPDIR, then we must keep the rest of the key */
989 if (!wcscmp(subKeyName, FLAGSW)) continue;
990 if (!wcscmp(subKeyName, HELPDIRW)) continue;
991 deleteOtherStuff = FALSE;
992 break;
993 }
994
995 /* only delete the other parts of the key if we're absolutely sure */
996 if (deleteOtherStuff) {
1000 key = NULL;
1001
1003 *wcsrchr( keyName, '\\' ) = 0; /* remove last path component */
1005 }
1006
1007end:
1008 SysFreeString(tlibPath);
1009 if (typeLib) ITypeLib_Release(typeLib);
1010 if (key) RegCloseKey(key);
1011 return result;
1012}
1013
1014/******************************************************************************
1015 * RegisterTypeLibForUser [OLEAUT32.442]
1016 * Adds information about a type library to the user registry
1017 * NOTES
1018 * Docs: ITypeLib FAR * ptlib
1019 * Docs: OLECHAR FAR* szFullPath
1020 * Docs: OLECHAR FAR* szHelpDir
1021 *
1022 * RETURNS
1023 * Success: S_OK
1024 * Failure: Status
1025 */
1027 ITypeLib * ptlib, /* [in] Pointer to the library*/
1028 OLECHAR * szFullPath, /* [in] full Path of the library*/
1029 OLECHAR * szHelpDir) /* [in] dir to the helpfile for the library,
1030 may be NULL*/
1031{
1032 FIXME("(%p, %s, %s) registering the typelib system-wide\n", ptlib,
1033 debugstr_w(szFullPath), debugstr_w(szHelpDir));
1034 return RegisterTypeLib(ptlib, szFullPath, szHelpDir);
1035}
1036
1037/******************************************************************************
1038 * UnRegisterTypeLibForUser [OLEAUT32.443]
1039 * Removes information about a type library from the user registry
1040 *
1041 * RETURNS
1042 * Success: S_OK
1043 * Failure: Status
1044 */
1046 REFGUID libid, /* [in] GUID of the library */
1047 WORD wVerMajor, /* [in] major version */
1048 WORD wVerMinor, /* [in] minor version */
1049 LCID lcid, /* [in] locale id */
1050 SYSKIND syskind)
1051{
1052 FIXME("(%s, %u, %u, %u, %u) unregistering the typelib system-wide\n",
1053 debugstr_guid(libid), wVerMajor, wVerMinor, lcid, syskind);
1054 return UnRegisterTypeLib(libid, wVerMajor, wVerMinor, lcid, syskind);
1055}
1056
1057/*======================= ITypeLib implementation =======================*/
1058
1059typedef struct tagTLBGuid {
1063 struct list entry;
1065
1066typedef struct tagTLBCustData
1067{
1070 struct list entry;
1072
1073/* data structure for import typelibs */
1074typedef struct tagTLBImpLib
1075{
1076 int offset; /* offset in the file (MSFT)
1077 offset in nametable (SLTG)
1078 just used to identify library while reading
1079 data from file */
1080 TLBGuid *guid; /* libid */
1081 BSTR name; /* name */
1082
1083 LCID lcid; /* lcid of imported typelib */
1084
1085 WORD wVersionMajor; /* major version number */
1086 WORD wVersionMinor; /* minor version number */
1087
1088 struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib, or
1089 NULL if not yet loaded */
1090 struct list entry;
1092
1093typedef struct tagTLBString {
1096 struct list entry;
1098
1099/* internal ITypeLib data */
1100typedef struct tagITypeLibImpl
1101{
1114
1115 /* strings can be stored in tlb as multibyte strings BUT they are *always*
1116 * exported to the application as a UNICODE string.
1117 */
1121
1127 int TypeInfoCount; /* nr of typeinfo's in librarry */
1131 int ctTypeDesc; /* number of items in type desc array */
1132 TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the
1133 library. Only used while reading MSFT
1134 typelibs */
1135 struct list ref_list; /* list of ref types in this typelib */
1136 HREFTYPE dispatch_href; /* reference to IDispatch, -1 if unused */
1137
1138
1139 /* typelibs are cached, keyed by path and index, so store the linked list info within them */
1140 struct list entry;
1144
1145static const ITypeLib2Vtbl tlbvt;
1146static const ITypeCompVtbl tlbtcvt;
1147static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl;
1148
1150{
1151 return CONTAINING_RECORD(iface, ITypeLibImpl, ITypeLib2_iface);
1152}
1153
1155{
1156 return impl_from_ITypeLib2((ITypeLib2*)iface);
1157}
1158
1160{
1161 return CONTAINING_RECORD(iface, ITypeLibImpl, ITypeComp_iface);
1162}
1163
1165{
1166 return CONTAINING_RECORD(iface, ITypeLibImpl, ICreateTypeLib2_iface);
1167}
1168
1169/* ITypeLib methods */
1170static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength);
1171static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength);
1172
1173/*======================= ITypeInfo implementation =======================*/
1174
1175/* data for referenced types */
1176typedef struct tagTLBRefType
1177{
1178 INT index; /* Type index for internal ref or for external ref
1179 it the format is SLTG. -2 indicates to
1180 use guid */
1181
1182 TYPEKIND tkind;
1183 TLBGuid *guid; /* guid of the referenced type */
1184 /* if index == TLB_REF_USE_GUID */
1185
1186 HREFTYPE reference; /* The href of this ref */
1187 TLBImpLib *pImpTLInfo; /* If ref is external ptr to library data
1188 TLB_REF_INTERNAL for internal refs
1189 TLB_REF_NOT_FOUND for broken refs */
1190
1191 struct list entry;
1193
1194#define TLB_REF_USE_GUID -2
1195
1196#define TLB_REF_INTERNAL (void*)-2
1197#define TLB_REF_NOT_FOUND (void*)-1
1198
1199/* internal Parameter data */
1200typedef struct tagTLBParDesc
1201{
1205
1206/* internal Function data */
1207typedef struct tagTLBFuncDesc
1208{
1209 FUNCDESC funcdesc; /* lots of info on the function and its attributes. */
1210 const TLBString *Name; /* the name of this function */
1211 TLBParDesc *pParamDesc; /* array with param names and custom data */
1215 const TLBString *Entry; /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */
1218
1219/* internal Variable data */
1220typedef struct tagTLBVarDesc
1221{
1222 VARDESC vardesc; /* lots of info on the variable and its attributes. */
1223 VARDESC *vardesc_create; /* additional data needed for storing VARDESC */
1224 const TLBString *Name; /* the name of this variable */
1230
1231/* internal implemented interface data */
1232typedef struct tagTLBImplType
1233{
1234 HREFTYPE hRef; /* hRef of interface */
1235 int implflags; /* IMPLFLAG_*s */
1238
1239/* internal TypeInfo data */
1240typedef struct tagITypeInfoImpl
1241{
1248
1250 TYPEATTR typeattr;
1251 TYPEDESC *tdescAlias;
1252
1253 ITypeLibImpl * pTypeLib; /* back pointer to typelib */
1254 int index; /* index in this typelib; */
1255 HREFTYPE hreftype; /* hreftype for app object binding */
1256 /* type libs seem to store the doc strings in ascii
1257 * so why should we do it in unicode?
1258 */
1265
1266 /* functions */
1268
1269 /* variables */
1271
1272 /* Implemented Interfaces */
1274
1278
1280{
1281 return CONTAINING_RECORD(iface, ITypeInfoImpl, ITypeComp_iface);
1282}
1283
1285{
1286 return CONTAINING_RECORD(iface, ITypeInfoImpl, ITypeInfo2_iface);
1287}
1288
1290{
1291 return impl_from_ITypeInfo2((ITypeInfo2*)iface);
1292}
1293
1295{
1296 return CONTAINING_RECORD(iface, ITypeInfoImpl, ICreateTypeInfo2_iface);
1297}
1298
1299static const ITypeInfo2Vtbl tinfvt;
1300static const ITypeCompVtbl tcompvt;
1301static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl;
1302
1305
1306typedef struct tagTLBContext
1307{
1308 unsigned int oStart; /* start of TLB in file */
1309 unsigned int pos; /* current pos */
1310 unsigned int length; /* total length */
1311 void *mapping; /* memory mapping */
1315
1316
1317static inline BSTR TLB_get_bstr(const TLBString *str)
1318{
1319 return str != NULL ? str->str : NULL;
1320}
1321
1322static inline int TLB_str_memcmp(void *left, const TLBString *str, DWORD len)
1323{
1324 if(!str)
1325 return 1;
1326 return memcmp(left, str->str, len);
1327}
1328
1329static inline const GUID *TLB_get_guidref(const TLBGuid *guid)
1330{
1331 return guid != NULL ? &guid->guid : NULL;
1332}
1333
1334static inline const GUID *TLB_get_guid_null(const TLBGuid *guid)
1335{
1336 return guid != NULL ? &guid->guid : &GUID_NULL;
1337}
1338
1339static int get_ptr_size(SYSKIND syskind)
1340{
1341 switch(syskind){
1342 case SYS_WIN64:
1343 return 8;
1344 case SYS_WIN32:
1345 case SYS_MAC:
1346 case SYS_WIN16:
1347 return 4;
1348 }
1349 WARN("Unhandled syskind: 0x%x\n", syskind);
1350 return 4;
1351}
1352
1353/*
1354 debug
1355*/
1356static void dump_TypeDesc(const TYPEDESC *pTD,char *szVarType) {
1357 if (pTD->vt & VT_RESERVED)
1358 szVarType += strlen(strcpy(szVarType, "reserved | "));
1359 if (pTD->vt & VT_BYREF)
1360 szVarType += strlen(strcpy(szVarType, "ref to "));
1361 if (pTD->vt & VT_ARRAY)
1362 szVarType += strlen(strcpy(szVarType, "array of "));
1363 if (pTD->vt & VT_VECTOR)
1364 szVarType += strlen(strcpy(szVarType, "vector of "));
1365 switch(pTD->vt & VT_TYPEMASK) {
1366 case VT_UI1: sprintf(szVarType, "VT_UI1"); break;
1367 case VT_I2: sprintf(szVarType, "VT_I2"); break;
1368 case VT_I4: sprintf(szVarType, "VT_I4"); break;
1369 case VT_R4: sprintf(szVarType, "VT_R4"); break;
1370 case VT_R8: sprintf(szVarType, "VT_R8"); break;
1371 case VT_BOOL: sprintf(szVarType, "VT_BOOL"); break;
1372 case VT_ERROR: sprintf(szVarType, "VT_ERROR"); break;
1373 case VT_CY: sprintf(szVarType, "VT_CY"); break;
1374 case VT_DATE: sprintf(szVarType, "VT_DATE"); break;
1375 case VT_BSTR: sprintf(szVarType, "VT_BSTR"); break;
1376 case VT_UNKNOWN: sprintf(szVarType, "VT_UNKNOWN"); break;
1377 case VT_DISPATCH: sprintf(szVarType, "VT_DISPATCH"); break;
1378 case VT_I1: sprintf(szVarType, "VT_I1"); break;
1379 case VT_UI2: sprintf(szVarType, "VT_UI2"); break;
1380 case VT_UI4: sprintf(szVarType, "VT_UI4"); break;
1381 case VT_INT: sprintf(szVarType, "VT_INT"); break;
1382 case VT_UINT: sprintf(szVarType, "VT_UINT"); break;
1383 case VT_VARIANT: sprintf(szVarType, "VT_VARIANT"); break;
1384 case VT_VOID: sprintf(szVarType, "VT_VOID"); break;
1385 case VT_HRESULT: sprintf(szVarType, "VT_HRESULT"); break;
1386 case VT_USERDEFINED: sprintf(szVarType, "VT_USERDEFINED ref = %x",
1387 pTD->u.hreftype); break;
1388 case VT_LPSTR: sprintf(szVarType, "VT_LPSTR"); break;
1389 case VT_LPWSTR: sprintf(szVarType, "VT_LPWSTR"); break;
1390 case VT_PTR: sprintf(szVarType, "ptr to ");
1391 dump_TypeDesc(pTD->u.lptdesc, szVarType + 7);
1392 break;
1393 case VT_SAFEARRAY: sprintf(szVarType, "safearray of ");
1394 dump_TypeDesc(pTD->u.lptdesc, szVarType + 13);
1395 break;
1396 case VT_CARRAY: sprintf(szVarType, "%d dim array of ",
1397 pTD->u.lpadesc->cDims); /* FIXME print out sizes */
1398 dump_TypeDesc(&pTD->u.lpadesc->tdescElem, szVarType + strlen(szVarType));
1399 break;
1400
1401 default: sprintf(szVarType, "unknown(%d)", pTD->vt & VT_TYPEMASK); break;
1402 }
1403}
1404
1405static void dump_ELEMDESC(const ELEMDESC *edesc) {
1406 char buf[200];
1407 USHORT flags = edesc->u.paramdesc.wParamFlags;
1408 dump_TypeDesc(&edesc->tdesc,buf);
1409 MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc->tdesc.vt,buf);
1410 MESSAGE("\t\tu.paramdesc.wParamFlags");
1411 if (!flags) MESSAGE(" PARAMFLAGS_NONE");
1412 if (flags & PARAMFLAG_FIN) MESSAGE(" PARAMFLAG_FIN");
1413 if (flags & PARAMFLAG_FOUT) MESSAGE(" PARAMFLAG_FOUT");
1414 if (flags & PARAMFLAG_FLCID) MESSAGE(" PARAMFLAG_FLCID");
1415 if (flags & PARAMFLAG_FRETVAL) MESSAGE(" PARAMFLAG_FRETVAL");
1416 if (flags & PARAMFLAG_FOPT) MESSAGE(" PARAMFLAG_FOPT");
1417 if (flags & PARAMFLAG_FHASDEFAULT) MESSAGE(" PARAMFLAG_FHASDEFAULT");
1418 if (flags & PARAMFLAG_FHASCUSTDATA) MESSAGE(" PARAMFLAG_FHASCUSTDATA");
1419 MESSAGE("\n\t\tu.paramdesc.lpex %p\n",edesc->u.paramdesc.pparamdescex);
1420}
1421static void dump_FUNCDESC(const FUNCDESC *funcdesc) {
1422 int i;
1423 MESSAGE("memid is %08x\n",funcdesc->memid);
1424 for (i=0;i<funcdesc->cParams;i++) {
1425 MESSAGE("Param %d:\n",i);
1426 dump_ELEMDESC(funcdesc->lprgelemdescParam+i);
1427 }
1428 MESSAGE("\tfunckind: %d (",funcdesc->funckind);
1429 switch (funcdesc->funckind) {
1430 case FUNC_VIRTUAL: MESSAGE("virtual");break;
1431 case FUNC_PUREVIRTUAL: MESSAGE("pure virtual");break;
1432 case FUNC_NONVIRTUAL: MESSAGE("nonvirtual");break;
1433 case FUNC_STATIC: MESSAGE("static");break;
1434 case FUNC_DISPATCH: MESSAGE("dispatch");break;
1435 default: MESSAGE("unknown");break;
1436 }
1437 MESSAGE(")\n\tinvkind: %d (",funcdesc->invkind);
1438 switch (funcdesc->invkind) {
1439 case INVOKE_FUNC: MESSAGE("func");break;
1440 case INVOKE_PROPERTYGET: MESSAGE("property get");break;
1441 case INVOKE_PROPERTYPUT: MESSAGE("property put");break;
1442 case INVOKE_PROPERTYPUTREF: MESSAGE("property put ref");break;
1443 }
1444 MESSAGE(")\n\tcallconv: %d (",funcdesc->callconv);
1445 switch (funcdesc->callconv) {
1446 case CC_CDECL: MESSAGE("cdecl");break;
1447 case CC_PASCAL: MESSAGE("pascal");break;
1448 case CC_STDCALL: MESSAGE("stdcall");break;
1449 case CC_SYSCALL: MESSAGE("syscall");break;
1450 default:break;
1451 }
1452 MESSAGE(")\n\toVft: %d\n", funcdesc->oVft);
1453 MESSAGE("\tcParamsOpt: %d\n", funcdesc->cParamsOpt);
1454 MESSAGE("\twFlags: %x\n", funcdesc->wFuncFlags);
1455
1456 MESSAGE("\telemdescFunc (return value type):\n");
1457 dump_ELEMDESC(&funcdesc->elemdescFunc);
1458}
1459
1460static const char * const typekind_desc[] =
1461{
1462 "TKIND_ENUM",
1463 "TKIND_RECORD",
1464 "TKIND_MODULE",
1465 "TKIND_INTERFACE",
1466 "TKIND_DISPATCH",
1467 "TKIND_COCLASS",
1468 "TKIND_ALIAS",
1469 "TKIND_UNION",
1470 "TKIND_MAX"
1471};
1472
1474{
1475 int i;
1476 MESSAGE("%s(%u)\n", debugstr_w(TLB_get_bstr(pfd->Name)), pfd->funcdesc.cParams);
1477 for (i=0;i<pfd->funcdesc.cParams;i++)
1478 MESSAGE("\tparm%d: %s\n",i,debugstr_w(TLB_get_bstr(pfd->pParamDesc[i].Name)));
1479
1480
1481 dump_FUNCDESC(&(pfd->funcdesc));
1482
1483 MESSAGE("\thelpstring: %s\n", debugstr_w(TLB_get_bstr(pfd->HelpString)));
1484 if(pfd->Entry == NULL)
1485 MESSAGE("\tentry: (null)\n");
1486 else if(pfd->Entry == (void*)-1)
1487 MESSAGE("\tentry: invalid\n");
1488 else if(IS_INTRESOURCE(pfd->Entry))
1489 MESSAGE("\tentry: %p\n", pfd->Entry);
1490 else
1491 MESSAGE("\tentry: %s\n", debugstr_w(TLB_get_bstr(pfd->Entry)));
1492}
1494{
1495 while (n)
1496 {
1498 ++pfd;
1499 --n;
1500 }
1501}
1502static void dump_TLBVarDesc(const TLBVarDesc * pvd, UINT n)
1503{
1504 while (n)
1505 {
1506 TRACE_(typelib)("%s\n", debugstr_w(TLB_get_bstr(pvd->Name)));
1507 ++pvd;
1508 --n;
1509 }
1510}
1511
1512static void dump_TLBImpLib(const TLBImpLib *import)
1513{
1514 TRACE_(typelib)("%s %s\n", debugstr_guid(TLB_get_guidref(import->guid)),
1515 debugstr_w(import->name));
1516 TRACE_(typelib)("v%d.%d lcid=%x offset=%x\n", import->wVersionMajor,
1517 import->wVersionMinor, import->lcid, import->offset);
1518}
1519
1520static void dump_TLBRefType(const ITypeLibImpl *pTL)
1521{
1522 TLBRefType *ref;
1523
1525 {
1526 TRACE_(typelib)("href:0x%08x\n", ref->reference);
1527 if(ref->index == -1)
1529 else
1530 TRACE_(typelib)("type no: %d\n", ref->index);
1531
1532 if(ref->pImpTLInfo != TLB_REF_INTERNAL && ref->pImpTLInfo != TLB_REF_NOT_FOUND)
1533 {
1534 TRACE_(typelib)("in lib\n");
1535 dump_TLBImpLib(ref->pImpTLInfo);
1536 }
1537 }
1538}
1539
1540static void dump_TLBImplType(const TLBImplType * impl, UINT n)
1541{
1542 if(!impl)
1543 return;
1544 while (n) {
1545 TRACE_(typelib)("implementing/inheriting interface hRef = %x implflags %x\n",
1546 impl->hRef, impl->implflags);
1547 ++impl;
1548 --n;
1549 }
1550}
1551
1552static void dump_DispParms(const DISPPARAMS * pdp)
1553{
1554 unsigned int index;
1555
1556 TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
1557
1558 if (pdp->cNamedArgs && pdp->rgdispidNamedArgs)
1559 {
1560 TRACE("named args:\n");
1561 for (index = 0; index < pdp->cNamedArgs; index++)
1562 TRACE( "\t0x%x\n", pdp->rgdispidNamedArgs[index] );
1563 }
1564
1565 if (pdp->cArgs && pdp->rgvarg)
1566 {
1567 TRACE("args:\n");
1568 for (index = 0; index < pdp->cArgs; index++)
1569 TRACE(" [%d] %s\n", index, debugstr_variant(pdp->rgvarg+index));
1570 }
1571}
1572
1573static void dump_TypeInfo(const ITypeInfoImpl * pty)
1574{
1575 TRACE("%p ref=%u\n", pty, pty->ref);
1577 TRACE("attr:%s\n", debugstr_guid(TLB_get_guidref(pty->guid)));
1578 TRACE("kind:%s\n", typekind_desc[pty->typeattr.typekind]);
1579 TRACE("fct:%u var:%u impl:%u\n", pty->typeattr.cFuncs, pty->typeattr.cVars, pty->typeattr.cImplTypes);
1580 TRACE("wTypeFlags: 0x%04x\n", pty->typeattr.wTypeFlags);
1581 TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
1582 if (pty->typeattr.typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(TLB_get_bstr(pty->DllName)));
1583 if (TRACE_ON(ole))
1584 dump_TLBFuncDesc(pty->funcdescs, pty->typeattr.cFuncs);
1585 dump_TLBVarDesc(pty->vardescs, pty->typeattr.cVars);
1586 dump_TLBImplType(pty->impltypes, pty->typeattr.cImplTypes);
1587}
1588
1589static void dump_VARDESC(const VARDESC *v)
1590{
1591 MESSAGE("memid %d\n",v->memid);
1592 MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema));
1593 MESSAGE("oInst %d\n",v->u.oInst);
1594 dump_ELEMDESC(&(v->elemdescVar));
1595 MESSAGE("wVarFlags %x\n",v->wVarFlags);
1596 MESSAGE("varkind %d\n",v->varkind);
1597}
1598
1599static TYPEDESC std_typedesc[VT_LPWSTR+1] =
1600{
1601 /* VT_LPWSTR is largest type that, may appear in type description */
1602 {{0}, VT_EMPTY}, {{0}, VT_NULL}, {{0}, VT_I2}, {{0}, VT_I4},
1603 {{0}, VT_R4}, {{0}, VT_R8}, {{0}, VT_CY}, {{0}, VT_DATE},
1604 {{0}, VT_BSTR}, {{0}, VT_DISPATCH}, {{0}, VT_ERROR}, {{0}, VT_BOOL},
1605 {{0}, VT_VARIANT},{{0}, VT_UNKNOWN}, {{0}, VT_DECIMAL}, {{0}, 15}, /* unused in VARENUM */
1606 {{0}, VT_I1}, {{0}, VT_UI1}, {{0}, VT_UI2}, {{0}, VT_UI4},
1607 {{0}, VT_I8}, {{0}, VT_UI8}, {{0}, VT_INT}, {{0}, VT_UINT},
1608 {{0}, VT_VOID}, {{0}, VT_HRESULT}, {{0}, VT_PTR}, {{0}, VT_SAFEARRAY},
1609 {{0}, VT_CARRAY}, {{0}, VT_USERDEFINED}, {{0}, VT_LPSTR}, {{0}, VT_LPWSTR}
1610};
1611
1612static void TLB_abort(void)
1613{
1614 DebugBreak();
1615}
1616
1617/* returns the size required for a deep copy of a typedesc into a
1618 * flat buffer */
1619static SIZE_T TLB_SizeTypeDesc( const TYPEDESC *tdesc, BOOL alloc_initial_space )
1620{
1621 SIZE_T size = 0;
1622
1623 if (alloc_initial_space)
1624 size += sizeof(TYPEDESC);
1625
1626 switch (tdesc->vt)
1627 {
1628 case VT_PTR:
1629 case VT_SAFEARRAY:
1630 size += TLB_SizeTypeDesc(tdesc->u.lptdesc, TRUE);
1631 break;
1632 case VT_CARRAY:
1633 size += FIELD_OFFSET(ARRAYDESC, rgbounds[tdesc->u.lpadesc->cDims]);
1634 size += TLB_SizeTypeDesc(&tdesc->u.lpadesc->tdescElem, FALSE);
1635 break;
1636 }
1637 return size;
1638}
1639
1640/* deep copy a typedesc into a flat buffer */
1641static void *TLB_CopyTypeDesc( TYPEDESC *dest, const TYPEDESC *src, void *buffer )
1642{
1643 if (!dest)
1644 {
1645 dest = buffer;
1646 buffer = (char *)buffer + sizeof(TYPEDESC);
1647 }
1648
1649 *dest = *src;
1650
1651 switch (src->vt)
1652 {
1653 case VT_PTR:
1654 case VT_SAFEARRAY:
1655 dest->u.lptdesc = buffer;
1656 buffer = TLB_CopyTypeDesc(NULL, src->u.lptdesc, buffer);
1657 break;
1658 case VT_CARRAY:
1659 dest->u.lpadesc = buffer;
1660 memcpy(dest->u.lpadesc, src->u.lpadesc, FIELD_OFFSET(ARRAYDESC, rgbounds[src->u.lpadesc->cDims]));
1661 buffer = (char *)buffer + FIELD_OFFSET(ARRAYDESC, rgbounds[src->u.lpadesc->cDims]);
1662 buffer = TLB_CopyTypeDesc(&dest->u.lpadesc->tdescElem, &src->u.lpadesc->tdescElem, buffer);
1663 break;
1664 }
1665 return buffer;
1666}
1667
1668/* free custom data allocated by MSFT_CustData */
1669static inline void TLB_FreeCustData(struct list *custdata_list)
1670{
1671 TLBCustData *cd, *cdn;
1672 LIST_FOR_EACH_ENTRY_SAFE(cd, cdn, custdata_list, TLBCustData, entry)
1673 {
1674 list_remove(&cd->entry);
1675 VariantClear(&cd->data);
1676 heap_free(cd);
1677 }
1678}
1679
1680static BSTR TLB_MultiByteToBSTR(const char *ptr)
1681{
1682 DWORD len;
1683 BSTR ret;
1684
1685 len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, 0);
1686 ret = SysAllocStringLen(NULL, len - 1);
1687 if (!ret) return ret;
1689 return ret;
1690}
1691
1693 UINT n, MEMBERID memid)
1694{
1695 while(n){
1696 if(funcdescs->funcdesc.memid == memid)
1697 return funcdescs;
1698 ++funcdescs;
1699 --n;
1700 }
1701 return NULL;
1702}
1703
1705 UINT n, MEMBERID memid)
1706{
1707 while(n){
1708 if(vardescs->vardesc.memid == memid)
1709 return vardescs;
1710 ++vardescs;
1711 --n;
1712 }
1713 return NULL;
1714}
1715
1717 UINT n, const OLECHAR *name)
1718{
1719 while(n){
1720 if(!lstrcmpiW(TLB_get_bstr(vardescs->Name), name))
1721 return vardescs;
1722 ++vardescs;
1723 --n;
1724 }
1725 return NULL;
1726}
1727
1728static inline TLBCustData *TLB_get_custdata_by_guid(struct list *custdata_list, REFGUID guid)
1729{
1730 TLBCustData *cust_data;
1731 LIST_FOR_EACH_ENTRY(cust_data, custdata_list, TLBCustData, entry)
1732 if(IsEqualIID(TLB_get_guid_null(cust_data->guid), guid))
1733 return cust_data;
1734 return NULL;
1735}
1736
1738 UINT n, const OLECHAR *name)
1739{
1740 while(n){
1741 if(!lstrcmpiW(TLB_get_bstr((*typeinfos)->Name), name))
1742 return *typeinfos;
1743 ++typeinfos;
1744 --n;
1745 }
1746 return NULL;
1747}
1748
1750{
1751 list_init(&var_desc->custdata_list);
1752}
1753
1755{
1756 TLBVarDesc *ret;
1757
1758 ret = heap_alloc_zero(sizeof(TLBVarDesc) * n);
1759 if(!ret)
1760 return NULL;
1761
1762 while(n){
1764 --n;
1765 }
1766
1767 return ret;
1768}
1769
1771{
1772 TLBParDesc *ret;
1773
1774 ret = heap_alloc_zero(sizeof(TLBParDesc) * n);
1775 if(!ret)
1776 return NULL;
1777
1778 while(n){
1779 list_init(&ret[n-1].custdata_list);
1780 --n;
1781 }
1782
1783 return ret;
1784}
1785
1787{
1788 list_init(&func_desc->custdata_list);
1789}
1790
1792{
1794
1795 ret = heap_alloc_zero(sizeof(TLBFuncDesc) * n);
1796 if(!ret)
1797 return NULL;
1798
1799 while(n){
1801 --n;
1802 }
1803
1804 return ret;
1805}
1806
1808{
1809 list_init(&impl->custdata_list);
1810}
1811
1813{
1815
1816 ret = heap_alloc_zero(sizeof(TLBImplType) * n);
1817 if(!ret)
1818 return NULL;
1819
1820 while(n){
1822 --n;
1823 }
1824
1825 return ret;
1826}
1827
1829 const GUID *new_guid, HREFTYPE hreftype)
1830{
1831 TLBGuid *guid;
1832
1834 if (IsEqualGUID(&guid->guid, new_guid))
1835 return guid;
1836 }
1837
1838 guid = heap_alloc(sizeof(TLBGuid));
1839 if (!guid)
1840 return NULL;
1841
1842 memcpy(&guid->guid, new_guid, sizeof(GUID));
1843 guid->hreftype = hreftype;
1844
1845 list_add_tail(guid_list, &guid->entry);
1846
1847 return guid;
1848}
1849
1850static HRESULT TLB_set_custdata(struct list *custdata_list, TLBGuid *tlbguid, VARIANT *var)
1851{
1852 TLBCustData *cust_data;
1853
1854 switch(V_VT(var)){
1855 case VT_I4:
1856 case VT_R4:
1857 case VT_UI4:
1858 case VT_INT:
1859 case VT_UINT:
1860 case VT_HRESULT:
1861 case VT_BSTR:
1862 break;
1863 default:
1864 return DISP_E_BADVARTYPE;
1865 }
1866
1867 cust_data = TLB_get_custdata_by_guid(custdata_list, TLB_get_guid_null(tlbguid));
1868
1869 if (!cust_data) {
1870 cust_data = heap_alloc(sizeof(TLBCustData));
1871 if (!cust_data)
1872 return E_OUTOFMEMORY;
1873
1874 cust_data->guid = tlbguid;
1875 VariantInit(&cust_data->data);
1876
1877 list_add_tail(custdata_list, &cust_data->entry);
1878 }else
1879 VariantClear(&cust_data->data);
1880
1881 return VariantCopy(&cust_data->data, var);
1882}
1883
1885{
1886 TLBString *str;
1887
1888 if(!new_str)
1889 return NULL;
1890
1892 if (wcscmp(str->str, new_str) == 0)
1893 return str;
1894 }
1895
1896 str = heap_alloc(sizeof(TLBString));
1897 if (!str)
1898 return NULL;
1899
1900 str->str = SysAllocString(new_str);
1901 if (!str->str) {
1902 heap_free(str);
1903 return NULL;
1904 }
1905
1906 list_add_tail(string_list, &str->entry);
1907
1908 return str;
1909}
1910
1912 ULONG *size, WORD *align)
1913{
1915 TYPEATTR *attr;
1916 HRESULT hr;
1917
1918 hr = ITypeInfo2_GetRefTypeInfo(&info->ITypeInfo2_iface, href, &other);
1919 if(FAILED(hr))
1920 return hr;
1921
1922 hr = ITypeInfo_GetTypeAttr(other, &attr);
1923 if(FAILED(hr)){
1924 ITypeInfo_Release(other);
1925 return hr;
1926 }
1927
1928 if(size)
1929 *size = attr->cbSizeInstance;
1930 if(align)
1931 *align = attr->cbAlignment;
1932
1933 ITypeInfo_ReleaseTypeAttr(other, attr);
1934 ITypeInfo_Release(other);
1935
1936 return S_OK;
1937}
1938
1940 TYPEDESC *tdesc, ULONG *size, WORD *align)
1941{
1942 ULONG i, sub, ptr_size;
1943 HRESULT hr;
1944
1945 ptr_size = get_ptr_size(sys);
1946
1947 switch(tdesc->vt){
1948 case VT_VOID:
1949 *size = 0;
1950 break;
1951 case VT_I1:
1952 case VT_UI1:
1953 *size = 1;
1954 break;
1955 case VT_I2:
1956 case VT_BOOL:
1957 case VT_UI2:
1958 *size = 2;
1959 break;
1960 case VT_I4:
1961 case VT_R4:
1962 case VT_ERROR:
1963 case VT_UI4:
1964 case VT_INT:
1965 case VT_UINT:
1966 case VT_HRESULT:
1967 *size = 4;
1968 break;
1969 case VT_R8:
1970 case VT_I8:
1971 case VT_UI8:
1972 *size = 8;
1973 break;
1974 case VT_BSTR:
1975 case VT_DISPATCH:
1976 case VT_UNKNOWN:
1977 case VT_PTR:
1978 case VT_SAFEARRAY:
1979 case VT_LPSTR:
1980 case VT_LPWSTR:
1981 *size = ptr_size;
1982 break;
1983 case VT_DATE:
1984 *size = sizeof(DATE);
1985 break;
1986 case VT_VARIANT:
1987 *size = sizeof(VARIANT);
1988#ifdef _WIN64
1989 if(sys == SYS_WIN32)
1990 *size -= 8; /* 32-bit VARIANT is 8 bytes smaller than 64-bit VARIANT */
1991#endif
1992 break;
1993 case VT_DECIMAL:
1994 *size = sizeof(DECIMAL);
1995 break;
1996 case VT_CY:
1997 *size = sizeof(CY);
1998 break;
1999 case VT_CARRAY:
2000 *size = 0;
2001 for(i = 0; i < tdesc->u.lpadesc->cDims; ++i)
2002 *size += tdesc->u.lpadesc->rgbounds[i].cElements;
2003 hr = TLB_size_instance(info, sys, &tdesc->u.lpadesc->tdescElem, &sub, align);
2004 if(FAILED(hr))
2005 return hr;
2006 *size *= sub;
2007 return S_OK;
2008 case VT_USERDEFINED:
2009 return TLB_get_size_from_hreftype(info, tdesc->u.hreftype, size, align);
2010 default:
2011 FIXME("Unsized VT: 0x%x\n", tdesc->vt);
2012 return E_FAIL;
2013 }
2014
2015 if(align){
2016 if(*size < 4)
2017 *align = *size;
2018 else
2019 *align = 4;
2020 }
2021
2022 return S_OK;
2023}
2024
2025/**********************************************************************
2026 *
2027 * Functions for reading MSFT typelibs (those created by CreateTypeLib2)
2028 */
2029
2030static inline void MSFT_Seek(TLBContext *pcx, LONG where)
2031{
2032 if (where != DO_NOT_SEEK)
2033 {
2034 where += pcx->oStart;
2035 if (where > pcx->length)
2036 {
2037 /* FIXME */
2038 ERR("seek beyond end (%d/%d)\n", where, pcx->length );
2039 TLB_abort();
2040 }
2041 pcx->pos = where;
2042 }
2043}
2044
2045/* read function */
2046static DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, LONG where )
2047{
2048 TRACE_(typelib)("pos=0x%08x len=0x%08x 0x%08x 0x%08x 0x%08x\n",
2049 pcx->pos, count, pcx->oStart, pcx->length, where);
2050
2051 MSFT_Seek(pcx, where);
2052 if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
2053 memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
2054 pcx->pos += count;
2055 return count;
2056}
2057
2059 LONG where )
2060{
2061 DWORD ret;
2062
2063 ret = MSFT_Read(buffer, count, pcx, where);
2065
2066 return ret;
2067}
2068
2070 LONG where )
2071{
2072 DWORD ret;
2073
2074 ret = MSFT_Read(buffer, count, pcx, where);
2076
2077 return ret;
2078}
2079
2081{
2082 TLBGuid *guid;
2084 int offs = 0;
2085
2086 MSFT_Seek(pcx, pcx->pTblDir->pGuidTab.offset);
2087 while (1) {
2088 if (offs >= pcx->pTblDir->pGuidTab.length)
2089 return S_OK;
2090
2092
2093 guid = heap_alloc(sizeof(TLBGuid));
2094
2095 guid->offset = offs;
2096 guid->guid = entry.guid;
2097 guid->hreftype = entry.hreftype;
2098
2099 list_add_tail(&pcx->pLibInfo->guid_list, &guid->entry);
2100
2101 offs += sizeof(MSFT_GuidEntry);
2102 }
2103}
2104
2106{
2107 TLBGuid *ret;
2108
2110 if(ret->offset == offset){
2111 TRACE_(typelib)("%s\n", debugstr_guid(&ret->guid));
2112 return ret;
2113 }
2114 }
2115
2116 return NULL;
2117}
2118
2119static HREFTYPE MSFT_ReadHreftype( TLBContext *pcx, int offset )
2120{
2121 MSFT_NameIntro niName;
2122
2123 if (offset < 0)
2124 {
2125 ERR_(typelib)("bad offset %d\n", offset);
2126 return -1;
2127 }
2128
2129 MSFT_ReadLEDWords(&niName, sizeof(niName), pcx,
2131
2132 return niName.hreftype;
2133}
2134
2136{
2137 char *string;
2138 MSFT_NameIntro intro;
2139 INT16 len_piece;
2140 int offs = 0, lengthInChars;
2141
2142 MSFT_Seek(pcx, pcx->pTblDir->pNametab.offset);
2143 while (1) {
2144 TLBString *tlbstr;
2145
2146 if (offs >= pcx->pTblDir->pNametab.length)
2147 return S_OK;
2148
2149 MSFT_ReadLEWords(&intro, sizeof(MSFT_NameIntro), pcx, DO_NOT_SEEK);
2150 intro.namelen &= 0xFF;
2151 len_piece = intro.namelen + sizeof(MSFT_NameIntro);
2152 if(len_piece % 4)
2153 len_piece = (len_piece + 4) & ~0x3;
2154 if(len_piece < 8)
2155 len_piece = 8;
2156
2157 string = heap_alloc(len_piece + 1);
2158 MSFT_Read(string, len_piece - sizeof(MSFT_NameIntro), pcx, DO_NOT_SEEK);
2159 string[intro.namelen] = '\0';
2160
2162 string, -1, NULL, 0);
2163 if (!lengthInChars) {
2164 heap_free(string);
2165 return E_UNEXPECTED;
2166 }
2167
2168 tlbstr = heap_alloc(sizeof(TLBString));
2169
2170 tlbstr->offset = offs;
2171 tlbstr->str = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR));
2172 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, tlbstr->str, lengthInChars);
2173
2174 heap_free(string);
2175
2176 list_add_tail(&pcx->pLibInfo->name_list, &tlbstr->entry);
2177
2178 offs += len_piece;
2179 }
2180}
2181
2183{
2184 TLBString *tlbstr;
2185
2187 if (tlbstr->offset == offset) {
2188 TRACE_(typelib)("%s\n", debugstr_w(tlbstr->str));
2189 return tlbstr;
2190 }
2191 }
2192
2193 return NULL;
2194}
2195
2197{
2198 TLBString *tlbstr;
2199
2201 if (tlbstr->offset == offset) {
2202 TRACE_(typelib)("%s\n", debugstr_w(tlbstr->str));
2203 return tlbstr;
2204 }
2205 }
2206
2207 return NULL;
2208}
2209
2210/*
2211 * read a value and fill a VARIANT structure
2212 */
2213static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
2214{
2215 int size;
2216
2217 TRACE_(typelib)("\n");
2218
2219 if(offset <0) { /* data are packed in here */
2220 V_VT(pVar) = (offset & 0x7c000000 )>> 26;
2221 V_I4(pVar) = offset & 0x3ffffff;
2222 return;
2223 }
2224 MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
2225 pcx->pTblDir->pCustData.offset + offset );
2226 TRACE_(typelib)("Vartype = %x\n", V_VT(pVar));
2227 switch (V_VT(pVar)){
2228 case VT_EMPTY: /* FIXME: is this right? */
2229 case VT_NULL: /* FIXME: is this right? */
2230 case VT_I2 : /* this should not happen */
2231 case VT_I4 :
2232 case VT_R4 :
2233 case VT_ERROR :
2234 case VT_BOOL :
2235 case VT_I1 :
2236 case VT_UI1 :
2237 case VT_UI2 :
2238 case VT_UI4 :
2239 case VT_INT :
2240 case VT_UINT :
2241 case VT_VOID : /* FIXME: is this right? */
2242 case VT_HRESULT :
2243 size=4; break;
2244 case VT_R8 :
2245 case VT_CY :
2246 case VT_DATE :
2247 case VT_I8 :
2248 case VT_UI8 :
2249 case VT_DECIMAL : /* FIXME: is this right? */
2250 case VT_FILETIME :
2251 size=8;break;
2252 /* pointer types with known behaviour */
2253 case VT_BSTR :{
2254 char * ptr;
2255 MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
2256 if(size == -1){
2257 V_BSTR(pVar) = NULL;
2258 }else{
2259 ptr = heap_alloc_zero(size);
2260 MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);
2262 /* FIXME: do we need a AtoW conversion here? */
2263 V_UNION(pVar, bstrVal[size])='\0';
2264 while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
2265 heap_free(ptr);
2266 }
2267 }
2268 size=-4; break;
2269 /* FIXME: this will not work AT ALL when the variant contains a pointer */
2270 case VT_DISPATCH :
2271 case VT_VARIANT :
2272 case VT_UNKNOWN :
2273 case VT_PTR :
2274 case VT_SAFEARRAY :
2275 case VT_CARRAY :
2276 case VT_USERDEFINED :
2277 case VT_LPSTR :
2278 case VT_LPWSTR :
2279 case VT_BLOB :
2280 case VT_STREAM :
2281 case VT_STORAGE :
2282 case VT_STREAMED_OBJECT :
2283 case VT_STORED_OBJECT :
2284 case VT_BLOB_OBJECT :
2285 case VT_CF :
2286 case VT_CLSID :
2287 default:
2288 size=0;
2289 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
2290 V_VT(pVar));
2291 }
2292
2293 if(size>0) /* (big|small) endian correct? */
2294 MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );
2295 return;
2296}
2297/*
2298 * create a linked list with custom data
2299 */
2300static int MSFT_CustData( TLBContext *pcx, int offset, struct list *custdata_list)
2301{
2303 TLBCustData* pNew;
2304 int count=0;
2305
2306 TRACE_(typelib)("\n");
2307
2308 if (pcx->pTblDir->pCDGuids.offset < 0) return 0;
2309
2310 while(offset >=0){
2311 count++;
2312 pNew=heap_alloc_zero(sizeof(TLBCustData));
2313 MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset);
2314 pNew->guid = MSFT_ReadGuid(entry.GuidOffset, pcx);
2315 MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
2316 list_add_head(custdata_list, &pNew->entry);
2317 offset = entry.next;
2318 }
2319 return count;
2320}
2321
2322static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd)
2323{
2324 if(type <0)
2325 pTd->vt=type & VT_TYPEMASK;
2326 else
2327 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
2328
2329 TRACE_(typelib)("vt type = %X\n", pTd->vt);
2330}
2331
2332static BOOL TLB_is_propgetput(INVOKEKIND invkind)
2333{
2334 return (invkind == INVOKE_PROPERTYGET ||
2335 invkind == INVOKE_PROPERTYPUT ||
2336 invkind == INVOKE_PROPERTYPUTREF);
2337}
2338
2339static void
2341 ITypeInfoImpl* pTI,
2342 int cFuncs,
2343 int cVars,
2344 int offset,
2345 TLBFuncDesc** pptfd)
2346{
2347 /*
2348 * member information is stored in a data structure at offset
2349 * indicated by the memoffset field of the typeinfo structure
2350 * There are several distinctive parts.
2351 * The first part starts with a field that holds the total length
2352 * of this (first) part excluding this field. Then follow the records,
2353 * for each member there is one record.
2354 *
2355 * The first entry is always the length of the record (including this
2356 * length word).
2357 * The rest of the record depends on the type of the member. If there is
2358 * a field indicating the member type (function, variable, interface, etc)
2359 * I have not found it yet. At this time we depend on the information
2360 * in the type info and the usual order how things are stored.
2361 *
2362 * Second follows an array sized nrMEM*sizeof(INT) with a member id
2363 * for each member;
2364 *
2365 * Third is an equal sized array with file offsets to the name entry
2366 * of each member.
2367 *
2368 * The fourth and last (?) part is an array with offsets to the records
2369 * in the first part of this file segment.
2370 */
2371
2372 int infolen, nameoffset, reclength, i;
2373 int recoffset = offset + sizeof(INT);
2374
2375 char *recbuf = heap_alloc(0xffff);
2376 MSFT_FuncRecord *pFuncRec = (MSFT_FuncRecord*)recbuf;
2377 TLBFuncDesc *ptfd_prev = NULL, *ptfd;
2378
2379 TRACE_(typelib)("\n");
2380
2381 MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);
2382
2383 *pptfd = TLBFuncDesc_Alloc(cFuncs);
2384 ptfd = *pptfd;
2385 for ( i = 0; i < cFuncs ; i++ )
2386 {
2387 int optional;
2388
2389 /* name, eventually add to a hash table */
2390 MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
2391 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
2392
2393 /* read the function information record */
2394 MSFT_ReadLEDWords(&reclength, sizeof(pFuncRec->Info), pcx, recoffset);
2395
2396 reclength &= 0xffff;
2397
2399
2400 /* size without argument data */
2401 optional = reclength - pFuncRec->nrargs*sizeof(MSFT_ParameterInfo);
2402 if (pFuncRec->FKCCIC & 0x1000)
2403 optional -= pFuncRec->nrargs * sizeof(INT);
2404
2406 ptfd->helpcontext = pFuncRec->HelpContext;
2407
2408 if (optional > FIELD_OFFSET(MSFT_FuncRecord, oHelpString))
2409 ptfd->HelpString = MSFT_ReadString(pcx, pFuncRec->oHelpString);
2410
2411 if (optional > FIELD_OFFSET(MSFT_FuncRecord, oEntry))
2412 {
2413 if (pFuncRec->FKCCIC & 0x2000 )
2414 {
2415 if (!IS_INTRESOURCE(pFuncRec->oEntry))
2416 ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->oEntry);
2417 ptfd->Entry = (TLBString*)(DWORD_PTR)LOWORD(pFuncRec->oEntry);
2418 }
2419 else
2420 ptfd->Entry = MSFT_ReadString(pcx, pFuncRec->oEntry);
2421 }
2422 else
2423 ptfd->Entry = (TLBString*)-1;
2424
2425 if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpStringContext))
2426 ptfd->HelpStringContext = pFuncRec->HelpStringContext;
2427
2428 if (optional > FIELD_OFFSET(MSFT_FuncRecord, oCustData) && pFuncRec->FKCCIC & 0x80)
2429 MSFT_CustData(pcx, pFuncRec->oCustData, &ptfd->custdata_list);
2430
2431 /* fill the FuncDesc Structure */
2432 MSFT_ReadLEDWords( & ptfd->funcdesc.memid, sizeof(INT), pcx,
2433 offset + infolen + ( i + 1) * sizeof(INT));
2434
2435 ptfd->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
2436 ptfd->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF;
2437 ptfd->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF;
2438 ptfd->funcdesc.cParams = pFuncRec->nrargs ;
2439 ptfd->funcdesc.cParamsOpt = pFuncRec->nroargs ;
2440 ptfd->funcdesc.oVft = (pFuncRec->VtableOffset & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
2441 ptfd->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
2442
2443 /* nameoffset is sometimes -1 on the second half of a propget/propput
2444 * pair of functions */
2445 if ((nameoffset == -1) && (i > 0) &&
2446 TLB_is_propgetput(ptfd_prev->funcdesc.invkind) &&
2447 TLB_is_propgetput(ptfd->funcdesc.invkind))
2448 ptfd->Name = ptfd_prev->Name;
2449 else
2450 ptfd->Name = MSFT_ReadName(pcx, nameoffset);
2451
2452 MSFT_GetTdesc(pcx,
2453 pFuncRec->DataType,
2454 &ptfd->funcdesc.elemdescFunc.tdesc);
2455
2456 /* do the parameters/arguments */
2457 if(pFuncRec->nrargs)
2458 {
2459 int j = 0;
2460 MSFT_ParameterInfo paraminfo;
2461
2462 ptfd->funcdesc.lprgelemdescParam =
2463 heap_alloc_zero(pFuncRec->nrargs * (sizeof(ELEMDESC) + sizeof(PARAMDESCEX)));
2464
2465 ptfd->pParamDesc = TLBParDesc_Constructor(pFuncRec->nrargs);
2466
2467 MSFT_ReadLEDWords(&paraminfo, sizeof(paraminfo), pcx,
2468 recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
2469
2470 for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
2471 {
2472 ELEMDESC *elemdesc = &ptfd->funcdesc.lprgelemdescParam[j];
2473
2474 MSFT_GetTdesc(pcx,
2475 paraminfo.DataType,
2476 &elemdesc->tdesc);
2477
2478 elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags;
2479
2480 /* name */
2481 if (paraminfo.oName != -1)
2482 ptfd->pParamDesc[j].Name =
2483 MSFT_ReadName( pcx, paraminfo.oName );
2484 TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w(TLB_get_bstr(ptfd->pParamDesc[j].Name)));
2485
2486 /* default value */
2487 if ( (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) &&
2488 (pFuncRec->FKCCIC & 0x1000) )
2489 {
2490 INT* pInt = (INT *)((char *)pFuncRec +
2491 reclength -
2492 (pFuncRec->nrargs * 4) * sizeof(INT) );
2493
2494 PARAMDESC* pParamDesc = &elemdesc->u.paramdesc;
2495
2496 pParamDesc->pparamdescex = (PARAMDESCEX*)(ptfd->funcdesc.lprgelemdescParam+pFuncRec->nrargs)+j;
2497 pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);
2498
2499 MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
2500 pInt[j], pcx);
2501 }
2502 else
2503 elemdesc->u.paramdesc.pparamdescex = NULL;
2504
2505 /* custom info */
2506 if (optional > (FIELD_OFFSET(MSFT_FuncRecord, oArgCustData) +
2507 j*sizeof(pFuncRec->oArgCustData[0])) &&
2508 pFuncRec->FKCCIC & 0x80 )
2509 {
2510 MSFT_CustData(pcx,
2511 pFuncRec->oArgCustData[j],
2512 &ptfd->pParamDesc[j].custdata_list);
2513 }
2514
2515 /* SEEK value = jump to offset,
2516 * from there jump to the end of record,
2517 * go back by (j-1) arguments
2518 */
2519 MSFT_ReadLEDWords( &paraminfo ,
2520 sizeof(MSFT_ParameterInfo), pcx,
2521 recoffset + reclength - ((pFuncRec->nrargs - j - 1)
2522 * sizeof(MSFT_ParameterInfo)));
2523 }
2524 }
2525
2526 /* scode is not used: archaic win16 stuff FIXME: right? */
2527 ptfd->funcdesc.cScodes = 0 ;
2528 ptfd->funcdesc.lprgscode = NULL ;
2529
2530 ptfd_prev = ptfd;
2531 ++ptfd;
2532 recoffset += reclength;
2533 }
2534 heap_free(recbuf);
2535}
2536
2537static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
2538 int cVars, int offset, TLBVarDesc ** pptvd)
2539{
2540 int infolen, nameoffset, reclength;
2541 char recbuf[256];
2542 MSFT_VarRecord *pVarRec = (MSFT_VarRecord*)recbuf;
2543 TLBVarDesc *ptvd;
2544 int i;
2545 int recoffset;
2546
2547 TRACE_(typelib)("\n");
2548
2549 ptvd = *pptvd = TLBVarDesc_Alloc(cVars);
2550 MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
2551 MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
2552 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
2553 recoffset += offset+sizeof(INT);
2554 for(i=0;i<cVars;i++, ++ptvd){
2555 /* name, eventually add to a hash table */
2556 MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
2557 offset + infolen + (2*cFuncs + cVars + i + 1) * sizeof(INT));
2558 ptvd->Name=MSFT_ReadName(pcx, nameoffset);
2559 /* read the variable information record */
2560 MSFT_ReadLEDWords(&reclength, sizeof(pVarRec->Info), pcx, recoffset);
2561 reclength &= 0xff;
2563
2564 /* optional data */
2565 if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpContext))
2566 ptvd->HelpContext = pVarRec->HelpContext;
2567
2568 if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpString))
2569 ptvd->HelpString = MSFT_ReadString(pcx, pVarRec->HelpString);
2570
2571 if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpStringContext))
2572 ptvd->HelpStringContext = pVarRec->HelpStringContext;
2573
2574 /* fill the VarDesc Structure */
2575 MSFT_ReadLEDWords(&ptvd->vardesc.memid, sizeof(INT), pcx,
2576 offset + infolen + (cFuncs + i + 1) * sizeof(INT));
2577 ptvd->vardesc.varkind = pVarRec->VarKind;
2578 ptvd->vardesc.wVarFlags = pVarRec->Flags;
2579 MSFT_GetTdesc(pcx, pVarRec->DataType,
2580 &ptvd->vardesc.elemdescVar.tdesc);
2581/* ptvd->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
2582 if(pVarRec->VarKind == VAR_CONST ){
2583 ptvd->vardesc.u.lpvarValue = heap_alloc_zero(sizeof(VARIANT));
2584 MSFT_ReadValue(ptvd->vardesc.u.lpvarValue,
2585 pVarRec->OffsValue, pcx);
2586 } else
2587 ptvd->vardesc.u.oInst=pVarRec->OffsValue;
2588 recoffset += reclength;
2589 }
2590}
2591
2592/* process Implemented Interfaces of a com class */
2594 int offset)
2595{
2596 int i;
2597 MSFT_RefRecord refrec;
2598 TLBImplType *pImpl;
2599
2600 TRACE_(typelib)("\n");
2601
2603 pImpl = pTI->impltypes;
2604 for(i=0;i<count;i++){
2605 if(offset<0) break; /* paranoia */
2606 MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
2607 pImpl->hRef = refrec.reftype;
2608 pImpl->implflags=refrec.flags;
2609 MSFT_CustData(pcx, refrec.oCustData, &pImpl->custdata_list);
2610 offset=refrec.onext;
2611 ++pImpl;
2612 }
2613}
2614
2615#ifdef _WIN64
2616/* when a 32-bit typelib is loaded in 64-bit mode, we need to resize pointers
2617 * and some structures, and fix the alignment */
2618static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info)
2619{
2620 if(info->typeattr.typekind == TKIND_ALIAS){
2621 switch(info->tdescAlias->vt){
2622 case VT_BSTR:
2623 case VT_DISPATCH:
2624 case VT_UNKNOWN:
2625 case VT_PTR:
2626 case VT_SAFEARRAY:
2627 case VT_LPSTR:
2628 case VT_LPWSTR:
2629 info->typeattr.cbSizeInstance = sizeof(void*);
2630 info->typeattr.cbAlignment = sizeof(void*);
2631 break;
2632 case VT_CARRAY:
2633 case VT_USERDEFINED:
2634 TLB_size_instance(info, SYS_WIN64, info->tdescAlias, &info->typeattr.cbSizeInstance, &info->typeattr.cbAlignment);
2635 break;
2636 case VT_VARIANT:
2637 info->typeattr.cbSizeInstance = sizeof(VARIANT);
2638 info->typeattr.cbAlignment = 8;
2639 default:
2640 if(info->typeattr.cbSizeInstance < sizeof(void*))
2641 info->typeattr.cbAlignment = info->typeattr.cbSizeInstance;
2642 else
2643 info->typeattr.cbAlignment = sizeof(void*);
2644 break;
2645 }
2646 }else if(info->typeattr.typekind == TKIND_INTERFACE ||
2647 info->typeattr.typekind == TKIND_DISPATCH ||
2648 info->typeattr.typekind == TKIND_COCLASS){
2649 info->typeattr.cbSizeInstance = sizeof(void*);
2650 info->typeattr.cbAlignment = sizeof(void*);
2651 }
2652}
2653#endif
2654
2655/*
2656 * process a typeinfo record
2657 */
2659 TLBContext *pcx,
2660 int count,
2661 ITypeLibImpl * pLibInfo)
2662{
2663 MSFT_TypeInfoBase tiBase;
2664 ITypeInfoImpl *ptiRet;
2665
2666 TRACE_(typelib)("count=%u\n", count);
2667
2668 ptiRet = ITypeInfoImpl_Constructor();
2669 MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx ,
2670 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
2671
2672/* this is where we are coming from */
2673 ptiRet->pTypeLib = pLibInfo;
2674 ptiRet->index=count;
2675
2676 ptiRet->guid = MSFT_ReadGuid(tiBase.posguid, pcx);
2677 ptiRet->typeattr.lcid = pLibInfo->set_lcid; /* FIXME: correct? */
2678 ptiRet->typeattr.lpstrSchema = NULL; /* reserved */
2679 ptiRet->typeattr.cbSizeInstance = tiBase.size;
2680 ptiRet->typeattr.typekind = tiBase.typekind & 0xF;
2681 ptiRet->typeattr.cFuncs = LOWORD(tiBase.cElement);
2682 ptiRet->typeattr.cVars = HIWORD(tiBase.cElement);
2683 ptiRet->typeattr.cbAlignment = (tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
2684 ptiRet->typeattr.wTypeFlags = tiBase.flags;
2685 ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version);
2686 ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version);
2687 ptiRet->typeattr.cImplTypes = tiBase.cImplTypes;
2688 ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft;
2689 if (ptiRet->typeattr.typekind == TKIND_ALIAS) {
2690 TYPEDESC tmp;
2691 MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
2692 ptiRet->tdescAlias = heap_alloc(TLB_SizeTypeDesc(&tmp, TRUE));
2693 TLB_CopyTypeDesc(NULL, &tmp, ptiRet->tdescAlias);
2694 }
2695
2696/* FIXME: */
2697/* IDLDESC idldescType; *//* never saw this one != zero */
2698
2699/* name, eventually add to a hash table */
2700 ptiRet->Name=MSFT_ReadName(pcx, tiBase.NameOffset);
2701 ptiRet->hreftype = MSFT_ReadHreftype(pcx, tiBase.NameOffset);
2702 TRACE_(typelib)("reading %s\n", debugstr_w(TLB_get_bstr(ptiRet->Name)));
2703 /* help info */
2704 ptiRet->DocString=MSFT_ReadString(pcx, tiBase.docstringoffs);
2706 ptiRet->dwHelpContext=tiBase.helpcontext;
2707
2708 if (ptiRet->typeattr.typekind == TKIND_MODULE)
2709 ptiRet->DllName = MSFT_ReadString(pcx, tiBase.datatype1);
2710
2711/* note: InfoType's Help file and HelpStringDll come from the containing
2712 * library. Further HelpString and Docstring appear to be the same thing :(
2713 */
2714 /* functions */
2715 if(ptiRet->typeattr.cFuncs >0 )
2716 MSFT_DoFuncs(pcx, ptiRet, ptiRet->typeattr.cFuncs,
2717 ptiRet->typeattr.cVars,
2718 tiBase.memoffset, &ptiRet->funcdescs);
2719 /* variables */
2720 if(ptiRet->typeattr.cVars >0 )
2721 MSFT_DoVars(pcx, ptiRet, ptiRet->typeattr.cFuncs,
2722 ptiRet->typeattr.cVars,
2723 tiBase.memoffset, &ptiRet->vardescs);
2724 if(ptiRet->typeattr.cImplTypes >0 ) {
2725 switch(ptiRet->typeattr.typekind)
2726 {
2727 case TKIND_COCLASS:
2728 MSFT_DoImplTypes(pcx, ptiRet, ptiRet->typeattr.cImplTypes,
2729 tiBase.datatype1);
2730 break;
2731 case TKIND_DISPATCH:
2732 /* This is not -1 when the interface is a non-base dual interface or
2733 when a dispinterface wraps an interface, i.e., the idl 'dispinterface x {interface y;};'.
2734 Note however that GetRefTypeOfImplType(0) always returns a ref to IDispatch and
2735 not this interface.
2736 */
2737
2738 if (tiBase.datatype1 != -1)
2739 {
2740 ptiRet->impltypes = TLBImplType_Alloc(1);
2741 ptiRet->impltypes[0].hRef = tiBase.datatype1;
2742 }
2743 break;
2744 default:
2745 ptiRet->impltypes = TLBImplType_Alloc(1);
2746 ptiRet->impltypes[0].hRef = tiBase.datatype1;
2747 break;
2748 }
2749 }
2750 MSFT_CustData(pcx, tiBase.oCustData, ptiRet->pcustdata_list);
2751
2752 TRACE_(typelib)("%s guid: %s kind:%s\n",
2753 debugstr_w(TLB_get_bstr(ptiRet->Name)),
2755 typekind_desc[ptiRet->typeattr.typekind]);
2756 if (TRACE_ON(typelib))
2757 dump_TypeInfo(ptiRet);
2758
2759 return ptiRet;
2760}
2761
2763{
2764 char *string;
2765 INT16 len_str, len_piece;
2766 int offs = 0, lengthInChars;
2767
2768 MSFT_Seek(pcx, pcx->pTblDir->pStringtab.offset);
2769 while (1) {
2770 TLBString *tlbstr;
2771
2772 if (offs >= pcx->pTblDir->pStringtab.length)
2773 return S_OK;
2774
2775 MSFT_ReadLEWords(&len_str, sizeof(INT16), pcx, DO_NOT_SEEK);
2776 len_piece = len_str + sizeof(INT16);
2777 if(len_piece % 4)
2778 len_piece = (len_piece + 4) & ~0x3;
2779 if(len_piece < 8)
2780 len_piece = 8;
2781
2782 string = heap_alloc(len_piece + 1);
2783 MSFT_Read(string, len_piece - sizeof(INT16), pcx, DO_NOT_SEEK);
2784 string[len_str] = '\0';
2785
2787 string, -1, NULL, 0);
2788 if (!lengthInChars) {
2789 heap_free(string);
2790 return E_UNEXPECTED;
2791 }
2792
2793 tlbstr = heap_alloc(sizeof(TLBString));
2794
2795 tlbstr->offset = offs;
2796 tlbstr->str = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR));
2797 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, tlbstr->str, lengthInChars);
2798
2799 heap_free(string);
2800
2801 list_add_tail(&pcx->pLibInfo->string_list, &tlbstr->entry);
2802
2803 offs += len_piece;
2804 }
2805}
2806
2808{
2809 TLBRefType *ref;
2810 int offs = 0;
2811
2812 MSFT_Seek(pcx, pcx->pTblDir->pImpInfo.offset);
2813 while (offs < pcx->pTblDir->pImpInfo.length) {
2814 MSFT_ImpInfo impinfo;
2815 TLBImpLib *pImpLib;
2816
2817 MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx, DO_NOT_SEEK);
2818
2819 ref = heap_alloc_zero(sizeof(TLBRefType));
2820 list_add_tail(&pcx->pLibInfo->ref_list, &ref->entry);
2821
2823 if(pImpLib->offset==impinfo.oImpFile)
2824 break;
2825
2826 if(&pImpLib->entry != &pcx->pLibInfo->implib_list){
2827 ref->reference = offs;
2828 ref->pImpTLInfo = pImpLib;
2829 if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
2830 ref->guid = MSFT_ReadGuid(impinfo.oGuid, pcx);
2831 TRACE("importing by guid %s\n", debugstr_guid(TLB_get_guidref(ref->guid)));
2832 ref->index = TLB_REF_USE_GUID;
2833 } else
2834 ref->index = impinfo.oGuid;
2835 }else{
2836 ERR("Cannot find a reference\n");
2837 ref->reference = -1;
2838 ref->pImpTLInfo = TLB_REF_NOT_FOUND;
2839 }
2840
2841 offs += sizeof(impinfo);
2842 }
2843
2844 return S_OK;
2845}
2846
2847/* Because type library parsing has some degree of overhead, and some apps repeatedly load the same
2848 * typelibs over and over, we cache them here. According to MSDN Microsoft have a similar scheme in
2849 * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable
2850 * tradeoff here.
2851 */
2855{
2856 0, 0, &cache_section,
2858 0, 0, { (DWORD_PTR)(__FILE__ ": typelib loader cache") }
2859};
2860static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 };
2861
2862
2863typedef struct TLB_PEFile
2864{
2872
2874{
2875 return CONTAINING_RECORD(iface, TLB_PEFile, IUnknown_iface);
2876}
2877
2879{
2881 {
2882 *ppv = iface;
2883 IUnknown_AddRef(iface);
2884 return S_OK;
2885 }
2886 *ppv = NULL;
2887 return E_NOINTERFACE;
2888}
2889
2891{
2893 return InterlockedIncrement(&This->refs);
2894}
2895
2897{
2899 ULONG refs = InterlockedDecrement(&This->refs);
2900 if (!refs)
2901 {
2902 if (This->typelib_global)
2903 FreeResource(This->typelib_global);
2904 if (This->dll)
2905 FreeLibrary(This->dll);
2906 heap_free(This);
2907 }
2908 return refs;
2909}
2910
2911static const IUnknownVtbl TLB_PEFile_Vtable =
2912{
2916};
2917
2918static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
2919{
2922
2923 This = heap_alloc(sizeof(TLB_PEFile));
2924 if (!This)
2925 return E_OUTOFMEMORY;
2926
2927 This->IUnknown_iface.lpVtbl = &TLB_PEFile_Vtable;
2928 This->refs = 1;
2929 This->dll = NULL;
2930 This->typelib_resource = NULL;
2931 This->typelib_global = NULL;
2932 This->typelib_base = NULL;
2933
2936
2937 if (This->dll)
2938 {
2939 static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0};
2940 This->typelib_resource = FindResourceW(This->dll, MAKEINTRESOURCEW(index), TYPELIBW);
2941 if (This->typelib_resource)
2942 {
2943 This->typelib_global = LoadResource(This->dll, This->typelib_resource);
2944 if (This->typelib_global)
2945 {
2946 This->typelib_base = LockResource(This->typelib_global);
2947
2948 if (This->typelib_base)
2949 {
2950 *pdwTLBLength = SizeofResource(This->dll, This->typelib_resource);
2951 *ppBase = This->typelib_base;
2952 *ppFile = &This->IUnknown_iface;
2953 return S_OK;
2954 }
2955 }
2956 }
2957
2958 TRACE("No TYPELIB resource found\n");
2959 hr = E_FAIL;
2960 }
2961
2962 TLB_PEFile_Release(&This->IUnknown_iface);
2963 return hr;
2964}
2965
2966typedef struct TLB_NEFile
2967{
2972
2974{
2975 return CONTAINING_RECORD(iface, TLB_NEFile, IUnknown_iface);
2976}
2977
2979{
2981 {
2982 *ppv = iface;
2983 IUnknown_AddRef(iface);
2984 return S_OK;
2985 }
2986 *ppv = NULL;
2987 return E_NOINTERFACE;
2988}
2989
2991{
2993 return InterlockedIncrement(&This->refs);
2994}
2995
2997{
2999 ULONG refs = InterlockedDecrement(&This->refs);
3000 if (!refs)
3001 {
3002 heap_free(This->typelib_base);
3003 heap_free(This);
3004 }
3005 return refs;
3006}
3007
3008static const IUnknownVtbl TLB_NEFile_Vtable =
3009{
3013};
3014
3015/***********************************************************************
3016 * read_xx_header [internal]
3017 */
3018static int read_xx_header( HFILE lzfd )
3019{
3020 IMAGE_DOS_HEADER mzh;
3021 char magic[3];
3022
3023 LZSeek( lzfd, 0, SEEK_SET );
3024 if ( sizeof(mzh) != LZRead( lzfd, (LPSTR)&mzh, sizeof(mzh) ) )
3025 return 0;
3026 if ( mzh.e_magic != IMAGE_DOS_SIGNATURE )
3027 return 0;
3028
3029 LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
3030 if ( 2 != LZRead( lzfd, magic, 2 ) )
3031 return 0;
3032
3033 LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
3034
3035 if ( magic[0] == 'N' && magic[1] == 'E' )
3036 return IMAGE_OS2_SIGNATURE;
3037 if ( magic[0] == 'P' && magic[1] == 'E' )
3038 return IMAGE_NT_SIGNATURE;
3039
3040 magic[2] = '\0';
3041 WARN("Can't handle %s files.\n", magic );
3042 return 0;
3043}
3044
3045
3046/***********************************************************************
3047 * find_ne_resource [internal]
3048 */
3049static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
3050 DWORD *resLen, DWORD *resOff )
3051{
3052 IMAGE_OS2_HEADER nehd;
3053 NE_TYPEINFO *typeInfo;
3054 NE_NAMEINFO *nameInfo;
3055 DWORD nehdoffset;
3056 LPBYTE resTab;
3057 DWORD resTabSize;
3058 int count;
3059
3060 /* Read in NE header */
3061 nehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
3062 if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return FALSE;
3063
3064 resTabSize = nehd.ne_restab - nehd.ne_rsrctab;
3065 if ( !resTabSize )
3066 {
3067 TRACE("No resources in NE dll\n" );
3068 return FALSE;
3069 }
3070
3071 /* Read in resource table */
3072 resTab = heap_alloc( resTabSize );
3073 if ( !resTab ) return FALSE;
3074
3075 LZSeek( lzfd, nehd.ne_rsrctab + nehdoffset, SEEK_SET );
3076 if ( resTabSize != LZRead( lzfd, (char*)resTab, resTabSize ) )
3077 {
3078 heap_free( resTab );
3079 return FALSE;
3080 }
3081
3082 /* Find resource */
3083 typeInfo = (NE_TYPEINFO *)(resTab + 2);
3084
3085 if (!IS_INTRESOURCE(typeid)) /* named type */
3086 {
3087 BYTE len = strlen( typeid );
3088 while (typeInfo->type_id)
3089 {
3090 if (!(typeInfo->type_id & 0x8000))
3091 {
3092 BYTE *p = resTab + typeInfo->type_id;
3093 if ((*p == len) && !_strnicmp( (char*)p+1, typeid, len )) goto found_type;
3094 }
3095 typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
3096 typeInfo->count * sizeof(NE_NAMEINFO));
3097 }
3098 }
3099 else /* numeric type id */
3100 {
3101 WORD id = LOWORD(typeid) | 0x8000;
3102 while (typeInfo->type_id)
3103 {
3104 if (typeInfo->type_id == id) goto found_type;
3105 typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
3106 typeInfo->count * sizeof(NE_NAMEINFO));
3107 }
3108 }
3109 TRACE("No typeid entry found for %p\n", typeid );
3110 heap_free( resTab );
3111 return FALSE;
3112
3113 found_type:
3114 nameInfo = (NE_NAMEINFO *)(typeInfo + 1);
3115
3116 if (!IS_INTRESOURCE(resid)) /* named resource */
3117 {
3118 BYTE len = strlen( resid );
3119 for (count = typeInfo->count; count > 0; count--, nameInfo++)
3120 {
3121 BYTE *p = resTab + nameInfo->id;
3122 if (nameInfo->id & 0x8000) continue;
3123 if ((*p == len) && !_strnicmp( (char*)p+1, resid, len )) goto found_name;
3124 }
3125 }
3126 else /* numeric resource id */
3127 {
3128 WORD id = LOWORD(resid) | 0x8000;
3129 for (count = typeInfo->count; count > 0; count--, nameInfo++)
3130 if (nameInfo->id == id) goto found_name;
3131 }
3132 TRACE("No resid entry found for %p\n", typeid );
3133 heap_free( resTab );
3134 return FALSE;
3135
3136 found_name:
3137 /* Return resource data */
3138 if ( resLen ) *resLen = nameInfo->length << *(WORD *)resTab;
3139 if ( resOff ) *resOff = nameInfo->offset << *(WORD *)resTab;
3140
3141 heap_free( resTab );
3142 return TRUE;
3143}
3144
3145static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile){
3146
3147 HFILE lzfd = -1;
3148 OFSTRUCT ofs;
3151
3152 This = heap_alloc(sizeof(TLB_NEFile));
3153 if (!This) return E_OUTOFMEMORY;
3154
3155 This->IUnknown_iface.lpVtbl = &TLB_NEFile_Vtable;
3156 This->refs = 1;
3157 This->typelib_base = NULL;
3158
3159 lzfd = LZOpenFileW( (LPWSTR)path, &ofs, OF_READ );
3160 if ( lzfd >= 0 && read_xx_header( lzfd ) == IMAGE_OS2_SIGNATURE )
3161 {
3163 if( find_ne_resource( lzfd, "TYPELIB", MAKEINTRESOURCEA(index), &reslen, &offset ) )
3164 {
3165 This->typelib_base = heap_alloc(reslen);
3166 if( !This->typelib_base )
3167 hr = E_OUTOFMEMORY;
3168 else
3169 {
3170 LZSeek( lzfd, offset, SEEK_SET );
3171 reslen = LZRead( lzfd, This->typelib_base, reslen );
3172 LZClose( lzfd );
3173 *ppBase = This->typelib_base;
3174 *pdwTLBLength = reslen;
3175 *ppFile = &This->IUnknown_iface;
3176 return S_OK;
3177 }
3178 }
3179 }
3180
3181 if( lzfd >= 0) LZClose( lzfd );
3182 TLB_NEFile_Release(&This->IUnknown_iface);
3183 return hr;
3184}
3185
3186typedef struct TLB_Mapping
3187{
3194
3196{
3197 return CONTAINING_RECORD(iface, TLB_Mapping, IUnknown_iface);
3198}
3199
3201{
3203 {
3204 *ppv = iface;
3205 IUnknown_AddRef(iface);
3206 return S_OK;
3207 }
3208 *ppv = NULL;
3209 return E_NOINTERFACE;
3210}
3211
3213{
3215 return InterlockedIncrement(&This->refs);
3216}
3217
3219{
3221 ULONG refs = InterlockedDecrement(&This->refs);
3222 if (!refs)
3223 {
3224 if (This->typelib_base)
3225 UnmapViewOfFile(This->typelib_base);
3226 if (This->mapping)
3227 CloseHandle(This->mapping);
3228 if (This->file != INVALID_HANDLE_VALUE)
3229 CloseHandle(This->file);
3230 heap_free(This);
3231 }
3232 return refs;
3233}
3234
3235static const IUnknownVtbl TLB_Mapping_Vtable =
3236{
3240};
3241
3242static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
3243{
3245
3246 This = heap_alloc(sizeof(TLB_Mapping));
3247 if (!This)
3248 return E_OUTOFMEMORY;
3249
3250 This->IUnknown_iface.lpVtbl = &TLB_Mapping_Vtable;
3251 This->refs = 1;
3252 This->file = INVALID_HANDLE_VALUE;
3253 This->mapping = NULL;
3254 This->typelib_base = NULL;
3255
3257 if (INVALID_HANDLE_VALUE != This->file)
3258 {
3259 This->mapping = CreateFileMappingW(This->file, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
3260 if (This->mapping)
3261 {
3262 This->typelib_base = MapViewOfFile(This->mapping, FILE_MAP_READ, 0, 0, 0);
3263 if(This->typelib_base)
3264 {
3265 /* retrieve file size */
3266 *pdwTLBLength = GetFileSize(This->file, NULL);
3267 *ppBase = This->typelib_base;
3268 *ppFile = &This->IUnknown_iface;
3269 return S_OK;
3270 }
3271 }
3272 }
3273
3274 IUnknown_Release(&This->IUnknown_iface);
3276}
3277
3278/****************************************************************************
3279 * TLB_ReadTypeLib
3280 *
3281 * find the type of the typelib file and map the typelib resource into
3282 * the memory
3283 */
3284
3285#define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */
3286static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib)
3287{
3289 HRESULT ret;
3290 INT index = 1;
3291 LPWSTR index_str, file = (LPWSTR)pszFileName;
3292 LPVOID pBase = NULL;
3293 DWORD dwTLBLength = 0;
3294 IUnknown *pFile = NULL;
3295 HANDLE h;
3296
3297 *ppTypeLib = NULL;
3298
3299 index_str = wcsrchr(pszFileName, '\\');
3300 if(index_str && *++index_str != '\0')
3301 {
3302 LPWSTR end_ptr;
3303 LONG idx = wcstol(index_str, &end_ptr, 10);
3304 if(*end_ptr == '\0')
3305 {
3306 int str_len = index_str - pszFileName - 1;
3307 index = idx;
3308 file = heap_alloc((str_len + 1) * sizeof(WCHAR));
3309 memcpy(file, pszFileName, str_len * sizeof(WCHAR));
3310 file[str_len] = 0;
3311 }
3312 }
3313
3314 if(!SearchPathW(NULL, file, NULL, cchPath, pszPath, NULL))
3315 {
3316 if(wcschr(file, '\\'))
3317 {
3318 lstrcpyW(pszPath, file);
3319 }
3320 else
3321 {
3322 int len = GetSystemDirectoryW(pszPath, cchPath);
3323 pszPath[len] = '\\';
3324 memcpy(pszPath + len + 1, file, (lstrlenW(file) + 1) * sizeof(WCHAR));
3325 }
3326 }
3327
3329
3331 if(h != INVALID_HANDLE_VALUE){
3332 FILE_NAME_INFORMATION size_info;
3333 BOOL br;
3334
3335 /* GetFileInformationByHandleEx returns the path of the file without
3336 * WOW64 redirection */
3337 br = GetFileInformationByHandleEx(h, FileNameInfo, &size_info, sizeof(size_info));
3338 if(br || GetLastError() == ERROR_MORE_DATA){
3340 DWORD size = sizeof(*info) + size_info.FileNameLength + sizeof(WCHAR);
3341
3343
3344 br = GetFileInformationByHandleEx(h, FileNameInfo, info, size);
3345 if(br){
3346 info->FileName[info->FileNameLength / sizeof(WCHAR)] = 0;
3347 lstrcpynW(pszPath + 2, info->FileName, cchPath - 2);
3348 }
3349
3351 }
3352
3353 CloseHandle(h);
3354 }
3355
3356 TRACE_(typelib)("File %s index %d\n", debugstr_w(pszPath), index);
3357
3358 /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */
3361 {
3362 if (!wcsicmp(entry->path, pszPath) && entry->index == index)
3363 {
3364 TRACE("cache hit\n");
3365 *ppTypeLib = &entry->ITypeLib2_iface;
3366 ITypeLib2_AddRef(*ppTypeLib);
3368 return S_OK;
3369 }
3370 }
3372
3373 /* now actually load and parse the typelib */
3374
3375 ret = TLB_PEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
3377 ret = TLB_NEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
3379 ret = TLB_Mapping_Open(pszPath, &pBase, &dwTLBLength, &pFile);
3380 if (SUCCEEDED(ret))
3381 {
3382 if (dwTLBLength >= 4)
3383 {
3384 DWORD dwSignature = FromLEDWord(*((DWORD*) pBase));
3385 if (dwSignature == MSFT_SIGNATURE)
3386 *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
3387 else if (dwSignature == SLTG_SIGNATURE)
3388 *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
3389 else
3390 {
3391 FIXME("Header type magic 0x%08x not supported.\n",dwSignature);
3393 }
3394 }
3395 else
3397 IUnknown_Release(pFile);
3398 }
3399
3400 if(*ppTypeLib) {
3401 ITypeLibImpl *impl = impl_from_ITypeLib2(*ppTypeLib);
3402
3403 TRACE("adding to cache\n");
3404 impl->path = heap_alloc((lstrlenW(pszPath)+1) * sizeof(WCHAR));
3405 lstrcpyW(impl->path, pszPath);
3406 /* We should really canonicalise the path here. */
3407 impl->index = index;
3408
3409 /* FIXME: check if it has added already in the meantime */
3411 list_add_head(&tlb_cache, &impl->entry);
3413 ret = S_OK;
3414 }
3415 else
3416 {
3417 if(ret != E_FAIL)
3418 ERR("Loading of typelib %s failed with error %d\n", debugstr_w(pszFileName), GetLastError());
3419
3421 }
3422
3423
3424 return ret;
3425}
3426
3427/*================== ITypeLib(2) Methods ===================================*/
3428
3430{
3431 ITypeLibImpl* pTypeLibImpl;
3432
3433 pTypeLibImpl = heap_alloc_zero(sizeof(ITypeLibImpl));
3434 if (!pTypeLibImpl) return NULL;
3435
3436 pTypeLibImpl->ITypeLib2_iface.lpVtbl = &tlbvt;
3437 pTypeLibImpl->ITypeComp_iface.lpVtbl = &tlbtcvt;
3438 pTypeLibImpl->ICreateTypeLib2_iface.lpVtbl = &CreateTypeLib2Vtbl;
3439 pTypeLibImpl->ref = 1;
3440
3441 list_init(&pTypeLibImpl->implib_list);
3442 list_init(&pTypeLibImpl->custdata_list);
3443 list_init(&pTypeLibImpl->name_list);
3444 list_init(&pTypeLibImpl->string_list);
3445 list_init(&pTypeLibImpl->guid_list);
3446 list_init(&pTypeLibImpl->ref_list);
3447 pTypeLibImpl->dispatch_href = -1;
3448
3449 return pTypeLibImpl;
3450}
3451
3452/****************************************************************************
3453 * ITypeLib2_Constructor_MSFT
3454 *
3455 * loading an MSFT typelib from an in-memory image
3456 */
3458{
3459 TLBContext cx;
3460 LONG lPSegDir;
3461 MSFT_Header tlbHeader;
3462 MSFT_SegDir tlbSegDir;
3463 ITypeLibImpl * pTypeLibImpl;
3464 int i;
3465
3466 TRACE("%p, TLB length = %d\n", pLib, dwTLBLength);
3467
3468 pTypeLibImpl = TypeLibImpl_Constructor();
3469 if (!pTypeLibImpl) return NULL;
3470
3471 /* get pointer to beginning of typelib data */
3472 cx.pos = 0;
3473 cx.oStart=0;
3474 cx.mapping = pLib;
3475 cx.pLibInfo = pTypeLibImpl;
3476 cx.length = dwTLBLength;
3477
3478 /* read header */
3479 MSFT_ReadLEDWords(&tlbHeader, sizeof(tlbHeader), &cx, 0);
3480 TRACE_(typelib)("header:\n");
3481 TRACE_(typelib)("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
3482 if (tlbHeader.magic1 != MSFT_SIGNATURE) {
3483 FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
3484 return NULL;
3485 }
3486 TRACE_(typelib)("\tdispatchpos = 0x%x\n", tlbHeader.dispatchpos);
3487
3488 /* there is a small amount of information here until the next important
3489 * part:
3490 * the segment directory . Try to calculate the amount of data */
3491 lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);
3492
3493 /* now read the segment directory */
3494 TRACE("read segment directory (at %d)\n",lPSegDir);
3495 MSFT_ReadLEDWords(&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
3496 cx.pTblDir = &tlbSegDir;
3497
3498 /* just check two entries */
3499 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
3500 {
3501 ERR("cannot find the table directory, ptr=0x%x\n",lPSegDir);
3502 heap_free(pTypeLibImpl);
3503 return NULL;
3504 }
3505
3509
3510 /* now fill our internal data */
3511 /* TLIBATTR fields */
3512 pTypeLibImpl->guid = MSFT_ReadGuid(tlbHeader.posguid, &cx);
3513
3514 pTypeLibImpl->syskind = tlbHeader.varflags & 0x0f; /* check the mask */
3515 pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind);
3516 pTypeLibImpl->ver_major = LOWORD(tlbHeader.version);
3517 pTypeLibImpl->ver_minor = HIWORD(tlbHeader.version);
3518 pTypeLibImpl->libflags = ((WORD) tlbHeader.flags & 0xffff) /* check mask */ | LIBFLAG_FHASDISKIMAGE;
3519
3520 pTypeLibImpl->set_lcid = tlbHeader.lcid2;
3521 pTypeLibImpl->lcid = tlbHeader.lcid;
3522
3523 /* name, eventually add to a hash table */
3524 pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset);
3525
3526 /* help info */
3527 pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring);
3528 pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile);
3529
3530 if( tlbHeader.varflags & HELPDLLFLAG)
3531 {
3532 int offset;
3533 MSFT_ReadLEDWords(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
3534 pTypeLibImpl->HelpStringDll = MSFT_ReadString(&cx, offset);
3535 }
3536
3537 pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;
3538
3539 /* custom data */
3540 if(tlbHeader.CustomDataOffset >= 0)
3541 {
3542 MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->custdata_list);
3543 }
3544
3545 /* fill in type descriptions */
3546 if(tlbSegDir.pTypdescTab.length > 0)
3547 {
3548 int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
3549 INT16 td[4];
3550 pTypeLibImpl->ctTypeDesc = cTD;
3551 pTypeLibImpl->pTypeDesc = heap_alloc_zero( cTD * sizeof(TYPEDESC));
3552 MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
3553 for(i=0; i<cTD; )
3554 {
3555 /* FIXME: add several sanity checks here */
3556 pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
3557 if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
3558 {
3559 /* FIXME: check safearray */
3560 if(td[3] < 0)
3561 pTypeLibImpl->pTypeDesc[i].u.lptdesc = &std_typedesc[td[2]];
3562 else
3563 pTypeLibImpl->pTypeDesc[i].u.lptdesc = &pTypeLibImpl->pTypeDesc[td[2]/8];
3564 }
3565 else if(td[0] == VT_CARRAY)
3566 {
3567 /* array descr table here */
3568 pTypeLibImpl->pTypeDesc[i].u.lpadesc = (void *)(INT_PTR)td[2]; /* temp store offset in*/
3569 }
3570 else if(td[0] == VT_USERDEFINED)
3571 {
3572 pTypeLibImpl->pTypeDesc[i].u.hreftype = MAKELONG(td[2],td[3]);
3573 }
3574 if(++i<cTD) MSFT_ReadLEWords(td, sizeof(td), &cx, DO_NOT_SEEK);
3575 }
3576
3577 /* second time around to fill the array subscript info */
3578 for(i=0;i<cTD;i++)
3579 {
3580 if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
3581 if(tlbSegDir.pArrayDescriptions.offset>0)
3582 {
3583 MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (INT_PTR)pTypeLibImpl->pTypeDesc[i].u.lpadesc);
3584 pTypeLibImpl->pTypeDesc[i].u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
3585
3586 if(td[1]<0)
3587 pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK;
3588 else
3589 pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = cx.pLibInfo->pTypeDesc[td[0]/(2*sizeof(INT))];
3590
3591 pTypeLibImpl->pTypeDesc[i].u.lpadesc->cDims = td[2];
3592
3593 for(j = 0; j<td[2]; j++)
3594 {
3595 MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].cElements,
3596 sizeof(INT), &cx, DO_NOT_SEEK);
3597 MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].lLbound,
3598 sizeof(INT), &cx, DO_NOT_SEEK);
3599 }
3600 }
3601 else
3602 {
3603 pTypeLibImpl->pTypeDesc[i].u.lpadesc = NULL;
3604 ERR("didn't find array description data\n");
3605 }
3606 }
3607 }
3608
3609 /* imported type libs */
3610 if(tlbSegDir.pImpFiles.offset>0)
3611 {
3612 TLBImpLib *pImpLib;
3613 int oGuid, offset = tlbSegDir.pImpFiles.offset;
3614 UINT16 size;
3615
3616 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
3617 {
3618 char *name;
3619
3620 pImpLib = heap_alloc_zero(sizeof(TLBImpLib));
3621 pImpLib->offset = offset - tlbSegDir.pImpFiles.offset;
3622 MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset);
3623
3624 MSFT_ReadLEDWords(&pImpLib->lcid, sizeof(LCID), &cx, DO_NOT_SEEK);
3625 MSFT_ReadLEWords(&pImpLib->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK);
3626 MSFT_ReadLEWords(&pImpLib->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK);
3627 MSFT_ReadLEWords(& size, sizeof(UINT16), &cx, DO_NOT_SEEK);
3628
3629 size >>= 2;
3630 name = heap_alloc_zero(size+1);
3632 pImpLib->name = TLB_MultiByteToBSTR(name);
3633 heap_free(name);
3634
3635 pImpLib->guid = MSFT_ReadGuid(oGuid, &cx);
3636 offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3;
3637
3638 list_add_tail(&pTypeLibImpl->implib_list, &pImpLib->entry);
3639 }
3640 }
3641
3643
3644 pTypeLibImpl->dispatch_href = tlbHeader.dispatchpos;
3645
3646 /* type infos */
3647 if(tlbHeader.nrtypeinfos >= 0 )
3648 {
3649 ITypeInfoImpl **ppTI;
3650
3651 ppTI = pTypeLibImpl->typeinfos = heap_alloc_zero(sizeof(ITypeInfoImpl*) * tlbHeader.nrtypeinfos);
3652
3653 for(i = 0; i < tlbHeader.nrtypeinfos; i++)
3654 {
3655 *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl);
3656
3657 ++ppTI;
3658 (pTypeLibImpl->TypeInfoCount)++;
3659 }
3660 }
3661
3662#ifdef _WIN64
3663 if(pTypeLibImpl->syskind == SYS_WIN32){
3664 for(i = 0; i < pTypeLibImpl->TypeInfoCount; ++i)
3665 TLB_fix_32on64_typeinfo(pTypeLibImpl->typeinfos[i]);
3666 }
3667#endif
3668
3669 TRACE("(%p)\n", pTypeLibImpl);
3670 return &pTypeLibImpl->ITypeLib2_iface;
3671}
3672
3673
3674static BOOL TLB_GUIDFromString(const char *str, GUID *guid)
3675{
3676 char b[3];
3677 int i;
3678 short s;
3679
3680 if(sscanf(str, "%x-%hx-%hx-%hx", &guid->Data1, &guid->Data2, &guid->Data3, &s) != 4) {
3681 FIXME("Can't parse guid %s\n", debugstr_guid(guid));
3682 return FALSE;
3683 }
3684
3685 guid->Data4[0] = s >> 8;
3686 guid->Data4[1] = s & 0xff;
3687
3688 b[2] = '\0';
3689 for(i = 0; i < 6; i++) {
3690 memcpy(b, str + 24 + 2 * i, 2);
3691 guid->Data4[i + 2] = strtol(b, NULL, 16);
3692 }
3693 return TRUE;
3694}
3695
3697{
3698 const BYTE *buffer;
3701};
3702
3703static const char *lookup_code(const BYTE *table, DWORD table_size, struct bitstream *bits)
3704{
3705 const BYTE *p = table;
3706
3707 while (p < table + table_size && *p == 0x80)
3708 {
3709 if (p + 2 >= table + table_size) return NULL;
3710
3711 if (!(bits->current & 0xff))
3712 {
3713 if (!bits->length) return NULL;
3714 bits->current = (*bits->buffer << 8) | 1;
3715 bits->buffer++;
3716 bits->length--;
3717 }
3718
3719 if (bits->current & 0x8000)
3720 {
3721 p += 3;
3722 }
3723 else
3724 {
3725 p = table + (*(p + 2) | (*(p + 1) << 8));
3726 }
3727
3728 bits->current <<= 1;
3729 }
3730
3731 if (p + 1 < table + table_size && *(p + 1))
3732 {
3733 /* FIXME: Whats the meaning of *p? */
3734 const BYTE *q = p + 1;
3735 while (q < table + table_size && *q) q++;
3736 return (q < table + table_size) ? (const char *)(p + 1) : NULL;
3737 }
3738
3739 return NULL;
3740}
3741
3742static const TLBString *decode_string(const BYTE *table, const char *stream, DWORD stream_length, ITypeLibImpl *lib)
3743{
3744 DWORD buf_size, table_size;
3745 const char *p;
3746 struct bitstream bits;
3747 BSTR buf;
3748 TLBString *tlbstr;
3749
3750 if (!stream_length) return NULL;
3751
3752 bits.buffer = (const BYTE *)stream;
3753 bits.length = stream_length;
3754 bits.current = 0;
3755
3756 buf_size = *(const WORD *)table;
3757 table += sizeof(WORD);
3758 table_size = *(const DWORD *)table;
3759 table += sizeof(DWORD);
3760
3761 buf = SysAllocStringLen(NULL, buf_size);
3762 buf[0] = 0;
3763
3764 while ((p = lookup_code(table, table_size, &bits)))
3765 {
3766 static const WCHAR spaceW[] = { ' ',0 };
3767 if (buf[0]) lstrcatW(buf, spaceW);
3768 MultiByteToWideChar(CP_ACP, 0, p, -1, buf + lstrlenW(buf), buf_size - lstrlenW(buf));
3769 }
3770
3771 tlbstr = TLB_append_str(&lib->string_list, buf);
3773
3774 return tlbstr;
3775}
3776
3777static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib)
3778{
3779 WORD bytelen;
3780 DWORD len;
3781 BSTR tmp_str;
3782
3783 *pStr = NULL;
3784 bytelen = *(const WORD*)ptr;
3785 if(bytelen == 0xffff) return 2;
3786
3787 len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, NULL, 0);
3788 tmp_str = SysAllocStringLen(NULL, len);
3789 if (tmp_str) {
3790 MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, tmp_str, len);
3791 *pStr = TLB_append_str(&lib->string_list, tmp_str);
3792 SysFreeString(tmp_str);
3793 }
3794 return bytelen + 2;
3795}
3796
3797static WORD SLTG_ReadStringA(const char *ptr, char **str)
3798{
3799 WORD bytelen;
3800
3801 *str = NULL;
3802 bytelen = *(const WORD*)ptr;
3803 if(bytelen == 0xffff) return 2;
3804 *str = heap_alloc(bytelen + 1);
3805 memcpy(*str, ptr + 2, bytelen);
3806 (*str)[bytelen] = '\0';
3807 return bytelen + 2;
3808}
3809
3810static TLBString *SLTG_ReadName(const char *pNameTable, int offset, ITypeLibImpl *lib)
3811{
3812 BSTR tmp_str;
3813 TLBString *tlbstr;
3814
3815 LIST_FOR_EACH_ENTRY(tlbstr, &lib->name_list, TLBString, entry) {
3816 if (tlbstr->offset == offset)
3817 return tlbstr;
3818 }
3819
3820 tmp_str = TLB_MultiByteToBSTR(pNameTable + offset);
3821 tlbstr = TLB_append_str(&lib->name_list, tmp_str);
3822 SysFreeString(tmp_str);
3823
3824 return tlbstr;
3825}
3826
3827static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl)
3828{
3829 char *ptr = pLibBlk;
3830 WORD w;
3831
3832 if((w = *(WORD*)ptr) != SLTG_LIBBLK_MAGIC) {
3833 FIXME("libblk magic = %04x\n", w);
3834 return 0;
3835 }
3836
3837 ptr += 6;
3838 if((w = *(WORD*)ptr) != 0xffff) {
3839 FIXME("LibBlk.res06 = %04x. Assumung string and skipping\n", w);
3840 ptr += w;
3841 }
3842 ptr += 2;
3843
3844 ptr += SLTG_ReadString(ptr, &pTypeLibImpl->DocString, pTypeLibImpl);
3845
3846 ptr += SLTG_ReadString(ptr, &pTypeLibImpl->HelpFile, pTypeLibImpl);
3847
3848 pTypeLibImpl->dwHelpContext = *(DWORD*)ptr;
3849 ptr += 4;
3850
3851 pTypeLibImpl->syskind = *(WORD*)ptr;
3852 pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind);
3853 ptr += 2;
3854
3856 pTypeLibImpl->lcid = pTypeLibImpl->set_lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0);
3857 else
3858 pTypeLibImpl->lcid = pTypeLibImpl->set_lcid = 0;
3859 ptr += 2;
3860
3861 ptr += 4; /* skip res12 */
3862
3863 pTypeLibImpl->libflags = *(WORD*)ptr;
3864 ptr += 2;
3865
3866 pTypeLibImpl->ver_major = *(WORD*)ptr;
3867 ptr += 2;
3868
3869 pTypeLibImpl->ver_minor = *(WORD*)ptr;
3870 ptr += 2;
3871
3872 pTypeLibImpl->guid = TLB_append_guid(&pTypeLibImpl->guid_list, (GUID*)ptr, -2);
3873 ptr += sizeof(GUID);
3874
3875 return ptr - (char*)pLibBlk;
3876}
3877
3878/* stores a mapping between the sltg typeinfo's references and the typelib's HREFTYPEs */
3879typedef struct
3880{
3881 unsigned int num;
3882 HREFTYPE refs[1];
3884
3886 HREFTYPE *typelib_ref)
3887{
3888 if(table && typeinfo_ref < table->num)
3889 {
3890 *typelib_ref = table->refs[typeinfo_ref];
3891 return S_OK;
3892 }
3893
3894 ERR_(typelib)("Unable to find reference\n");
3895 *typelib_ref = -1;
3896 return E_FAIL;
3897}
3898
3899static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_lookup_t *ref_lookup)
3900{
3901 BOOL done = FALSE;
3902
3903 while(!done) {
3904 if((*pType & 0xe00) == 0xe00) {
3905 pTD->vt = VT_PTR;
3906 pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
3907 pTD = pTD->u.lptdesc;
3908 }
3909 switch(*pType & 0x3f) {
3910 case VT_PTR:
3911 pTD->vt = VT_PTR;
3912 pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
3913 pTD = pTD->u.lptdesc;
3914 break;
3915
3916 case VT_USERDEFINED:
3917 pTD->vt = VT_USERDEFINED;
3918 sltg_get_typelib_ref(ref_lookup, *(++pType) / 4, &pTD->u.hreftype);
3919 done = TRUE;
3920 break;
3921
3922 case VT_CARRAY:
3923 {
3924 /* *(pType+1) is offset to a SAFEARRAY, *(pType+2) is type of
3925 array */
3926
3927 SAFEARRAY *pSA = (SAFEARRAY *)(pBlk + *(++pType));
3928
3929 pTD->vt = VT_CARRAY;
3930 pTD->u.lpadesc = heap_alloc_zero(sizeof(ARRAYDESC) + (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND));
3931 pTD->u.lpadesc->cDims = pSA->cDims;
3932 memcpy(pTD->u.lpadesc->rgbounds, pSA->rgsabound,
3933 pSA->cDims * sizeof(SAFEARRAYBOUND));
3934
3935 pTD = &pTD->u.lpadesc->tdescElem;
3936 break;
3937 }
3938
3939 case VT_SAFEARRAY:
3940 {
3941 /* FIXME: *(pType+1) gives an offset to SAFEARRAY, is this
3942 useful? */
3943
3944 pType++;
3945 pTD->vt = VT_SAFEARRAY;
3946 pTD->u.lptdesc = heap_alloc_zero(sizeof(TYPEDESC));
3947 pTD = pTD->u.lptdesc;
3948 break;
3949 }
3950 default:
3951 pTD->vt = *pType & 0x3f;
3952 done = TRUE;
3953 break;
3954 }
3955 pType++;
3956 }
3957 return pType;
3958}
3959
3960static WORD *SLTG_DoElem(WORD *pType, char *pBlk,
3961 ELEMDESC *pElem, const sltg_ref_lookup_t *ref_lookup)
3962{
3963 /* Handle [in/out] first */
3964 if((*pType & 0xc000) == 0xc000)
3965 pElem->u.paramdesc.wParamFlags = PARAMFLAG_NONE;
3966 else if(*pType & 0x8000)
3967 pElem->u.paramdesc.wParamFlags = PARAMFLAG_FIN | PARAMFLAG_FOUT;
3968 else if(*pType & 0x4000)
3969 pElem->u.paramdesc.wParamFlags = PARAMFLAG_FOUT;
3970 else
3971 pElem->u.paramdesc.wParamFlags = PARAMFLAG_FIN;
3972
3973 if(*pType & 0x2000)
3974 pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FLCID;
3975
3976 if(*pType & 0x80)
3977 pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FRETVAL;
3978
3979 return SLTG_DoType(pType, pBlk, &pElem->tdesc, ref_lookup);
3980}
3981
3982
3984 char *pNameTable)
3985{
3986 unsigned int ref;
3987 char *name;
3988 TLBRefType *ref_type;
3990 HREFTYPE typelib_ref;
3991
3992 if(pRef->magic != SLTG_REF_MAGIC) {
3993 FIXME("Ref magic = %x\n", pRef->magic);
3994 return NULL;
3995 }
3996 name = ( (char*)pRef->names + pRef->number);
3997
3998 table = heap_alloc(sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0]));
3999 table->num = pRef->number >> 3;
4000
4001 /* FIXME should scan the existing list and reuse matching refs added by previous typeinfos */
4002
4003 /* We don't want the first href to be 0 */
4004 typelib_ref = (list_count(&pTL->ref_list) + 1) << 2;
4005
4006 for(ref = 0; ref < pRef->number >> 3; ref++) {
4007 char *refname;
4008 unsigned int lib_offs, type_num;
4009
4010 ref_type = heap_alloc_zero(sizeof(TLBRefType));
4011
4012 name += SLTG_ReadStringA(name, &refname);
4013 if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2)
4014 FIXME_(typelib)("Can't sscanf ref\n");
4015 if(lib_offs != 0xffff) {
4016 TLBImpLib *import;
4017
4019 if(import->offset == lib_offs)
4020 break;
4021
4022 if(&import->entry == &pTL->implib_list) {
4023 char fname[MAX_PATH+1];
4024 int len;
4025 GUID tmpguid;
4026
4027 import = heap_alloc_zero(sizeof(*import));
4028 import->offset = lib_offs;
4029 TLB_GUIDFromString( pNameTable + lib_offs + 4, &tmpguid);
4030 import->guid = TLB_append_guid(&pTL->guid_list, &tmpguid, 2);
4031 if(sscanf(pNameTable + lib_offs + 40, "}#%hd.%hd#%x#%s",
4032 &import->wVersionMajor,
4033 &import->wVersionMinor,
4034 &import->lcid, fname) != 4) {
4035 FIXME_(typelib)("can't sscanf ref %s\n",
4036 pNameTable + lib_offs + 40);
4037 }
4038 len = strlen(fname);
4039 if(fname[len-1] != '#')
4040 FIXME("fname = %s\n", fname);
4041 fname[len-1] = '\0';
4042 import->name = TLB_MultiByteToBSTR(fname);
4043 list_add_tail(&pTL->implib_list, &import->entry);
4044 }
4045 ref_type->pImpTLInfo = import;
4046
4047 /* Store a reference to IDispatch */
4048 if(pTL->dispatch_href == -1 && IsEqualGUID(&import->guid->guid, &IID_StdOle) && type_num == 4)
4049 pTL->dispatch_href = typelib_ref;
4050
4051 } else { /* internal ref */
4052 ref_type->pImpTLInfo = TLB_REF_INTERNAL;
4053 }
4054 ref_type->reference = typelib_ref;
4055 ref_type->index = type_num;
4056
4057 heap_free(refname);
4058 list_add_tail(&pTL->ref_list, &ref_type->entry);
4059
4060 table->refs[ref] = typelib_ref;
4061 typelib_ref += 4;
4062 }
4063 if((BYTE)*name != SLTG_REF_MAGIC)
4064 FIXME_(typelib)("End of ref block magic = %x\n", *name);
4065 dump_TLBRefType(pTL);
4066 return table;
4067}
4068
4069static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
4070 BOOL OneOnly, const sltg_ref_lookup_t *ref_lookup)
4071{
4073 TLBImplType *pImplType;
4074 /* I don't really get this structure, usually it's 0x16 bytes
4075 long, but iuser.tlb contains some that are 0x18 bytes long.
4076 That's ok because we can use the next ptr to jump to the next
4077 one. But how do we know the length of the last one? The WORD
4078 at offs 0x8 might be the clue. For now I'm just assuming that
4079 the last one is the regular 0x16 bytes. */
4080
4081 info = (SLTG_ImplInfo*)pBlk;
4082 while(1){
4083 pTI->typeattr.cImplTypes++;
4084 if(info->next == 0xffff)
4085 break;
4086 info = (SLTG_ImplInfo*)(pBlk + info->next);
4087 }
4088
4089 info = (SLTG_ImplInfo*)pBlk;
4090 pTI->impltypes = TLBImplType_Alloc(pTI->typeattr.cImplTypes);
4091 pImplType = pTI->impltypes;
4092 while(1) {
4093 sltg_get_typelib_ref(ref_lookup, info->ref, &pImplType->hRef);
4094 pImplType->implflags = info->impltypeflags;
4095 ++pImplType;
4096
4097 if(info->next == 0xffff)
4098 break;
4099 if(OneOnly)
4100 FIXME_(typelib)("Interface inheriting more than one interface\n");
4101 info = (SLTG_ImplInfo*)(pBlk + info->next);
4102 }
4103 info++; /* see comment at top of function */
4104 return (char*)info;
4105}
4106
4107static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars,
4108 const char *pNameTable, const sltg_ref_lookup_t *ref_lookup, const BYTE *hlp_strings)
4109{
4110 TLBVarDesc *pVarDesc;
4111 const TLBString *prevName = NULL;
4112 SLTG_Variable *pItem;
4113 unsigned short i;
4114 WORD *pType;
4115
4116 pVarDesc = pTI->vardescs = TLBVarDesc_Alloc(cVars);
4117
4118 for(pItem = (SLTG_Variable *)pFirstItem, i = 0; i < cVars;
4119 pItem = (SLTG_Variable *)(pBlk + pItem->next), i++, ++pVarDesc) {
4120
4121 pVarDesc->vardesc.memid = pItem->memid;
4122
4123 if (pItem->magic != SLTG_VAR_MAGIC &&
4124 pItem->magic != SLTG_VAR_WITH_FLAGS_MAGIC) {
4125 FIXME_(typelib)("var magic = %02x\n", pItem->magic);
4126 return;
4127 }
4128
4129 if (pItem->name == 0xfffe)
4130 pVarDesc->Name = prevName;
4131 else
4132 pVarDesc->Name = SLTG_ReadName(pNameTable, pItem->name, pTI->pTypeLib);
4133
4134 TRACE_(typelib)("name: %s\n", debugstr_w(TLB_get_bstr(pVarDesc->Name)));
4135 TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs);
4136 TRACE_(typelib)("memid = 0x%x\n", pItem->memid);
4137
4138 if (pItem->helpstring != 0xffff)
4139 {
4140 pVarDesc->HelpString = decode_string(hlp_strings, pBlk + pItem->helpstring, pNameTable - pBlk, pTI->pTypeLib);
4141 TRACE_(typelib)("helpstring = %s\n", debugstr_w(pVarDesc->HelpString->str));
4142 }
4143
4144 if(pItem->flags & 0x02)
4145 pType = &pItem->type;
4146 else
4147 pType = (WORD*)(pBlk + pItem->type);
4148
4149 if (pItem->flags & ~0xda)
4150 FIXME_(typelib)("unhandled flags = %02x\n", pItem->flags & ~0xda);
4151
4152 SLTG_DoElem(pType, pBlk,
4153 &pVarDesc->vardesc.elemdescVar, ref_lookup);
4154
4155 if (TRACE_ON(typelib)) {
4156 char buf[300];
4157 dump_TypeDesc(&pVarDesc->vardesc.elemdescVar.tdesc, buf);
4158 TRACE_(typelib)("elemdescVar: %s\n", buf);
4159 }
4160
4161 if (pItem->flags & 0x40) {
4162 TRACE_(typelib)("VAR_DISPATCH\n");
4163 pVarDesc->vardesc.varkind = VAR_DISPATCH;
4164 }
4165 else if (pItem->flags & 0x10) {
4166 TRACE_(typelib)("VAR_CONST\n");
4167 pVarDesc->vardesc.varkind = VAR_CONST;
4168 pVarDesc->vardesc.u.lpvarValue = heap_alloc(sizeof(VARIANT));
4169 V_VT(pVarDesc->vardesc.u.lpvarValue) = VT_INT;
4170 if (pItem->flags & 0x08)
4171 V_INT(pVarDesc->vardesc.u.lpvarValue) = pItem->byte_offs;
4172 else {
4173 switch (pVarDesc->vardesc.elemdescVar.tdesc.vt)
4174 {
4175 case VT_LPSTR:
4176 case VT_LPWSTR:
4177 case VT_BSTR:
4178 {
4179 WORD len = *(WORD *)(pBlk + pItem->byte_offs);
4180 BSTR str;
4181 TRACE_(typelib)("len = %u\n", len);
4182 if (len == 0xffff) {
4183 str = NULL;
4184 } else {
4185 INT alloc_len = MultiByteToWideChar(CP_ACP, 0, pBlk + pItem->byte_offs + 2, len, NULL, 0);
4186 str = SysAllocStringLen(NULL, alloc_len);
4187 MultiByteToWideChar(CP_ACP, 0, pBlk + pItem->byte_offs + 2, len, str, alloc_len);
4188 }
4189 V_VT(pVarDesc->vardesc.u.lpvarValue) = VT_BSTR;
4190 V_BSTR(pVarDesc->vardesc.u.lpvarValue) = str;
4191 break;
4192 }
4193 case VT_I2:
4194 case VT_UI2:
4195 case VT_I4:
4196 case VT_UI4:
4197 case VT_INT:
4198 case VT_UINT:
4199 V_INT(pVarDesc->vardesc.u.lpvarValue) =
4200 *(INT*)(pBlk + pItem->byte_offs);
4201 break;
4202 default:
4203 FIXME_(typelib)("VAR_CONST unimplemented for type %d\n", pVarDesc->vardesc.elemdescVar.tdesc.vt);
4204 }
4205 }
4206 }
4207 else {
4208 TRACE_(typelib)("VAR_PERINSTANCE\n");
4209 pVarDesc->vardesc.u.oInst = pItem->byte_offs;
4210 pVarDesc->vardesc.varkind = VAR_PERINSTANCE;
4211 }
4212
4213 if (pItem->magic == SLTG_VAR_WITH_FLAGS_MAGIC)
4214 pVarDesc->vardesc.wVarFlags = pItem->varflags;
4215
4216 if (pItem->flags & 0x80)
4217 pVarDesc->vardesc.wVarFlags |= VARFLAG_FREADONLY;
4218
4219 prevName = pVarDesc->Name;
4220 }
4221 pTI->typeattr.cVars = cVars;
4222}
4223
4224static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
4225 unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup,
4226 const BYTE *hlp_strings)
4227{
4228 SLTG_Function *pFunc;
4229 unsigned short i;
4230 TLBFuncDesc *pFuncDesc;
4231
4232 pTI->funcdescs = TLBFuncDesc_Alloc(cFuncs);
4233
4234 pFuncDesc = pTI->funcdescs;
4235 for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs && pFunc != (SLTG_Function*)0xFFFF;
4236 pFunc = (SLTG_Function*)(pBlk + pFunc->next), i++, ++pFuncDesc) {
4237
4238 int param;
4239 WORD *pType, *pArg;
4240
4241 switch (pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT) {
4243 pFuncDesc->funcdesc.funckind = FUNC_PUREVIRTUAL;
4244 break;
4246 pFuncDesc->funcdesc.funckind = FUNC_DISPATCH;
4247 break;
4249 pFuncDesc->funcdesc.funckind = FUNC_STATIC;
4250 break;
4251 default:
4252 FIXME("unimplemented func magic = %02x\n", pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT);
4253 continue;
4254 }
4255 pFuncDesc->Name = SLTG_ReadName(pNameTable, pFunc->name, pTI->pTypeLib);
4256
4257 pFuncDesc->funcdesc.memid = pFunc->dispid;
4258 pFuncDesc->funcdesc.invkind = pFunc->inv >> 4;
4259 pFuncDesc->funcdesc.callconv = pFunc->nacc & 0x7;
4260 pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3;
4261 pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
4262 pFuncDesc->funcdesc.oVft = (pFunc->vtblpos & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
4263 if (pFunc->helpstring != 0xffff)
4264 pFuncDesc->HelpString = decode_string(hlp_strings, pBlk + pFunc->helpstring, pNameTable - pBlk, pTI->pTypeLib);
4265
4267 pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;
4268
4269 if(pFunc->retnextopt & 0x80)
4270 pType = &pFunc->rettype;
4271 else
4272 pType = (WORD*)(pBlk + pFunc->rettype);
4273
4274 SLTG_DoElem(pType, pBlk, &pFuncDesc->funcdesc.elemdescFunc, ref_lookup);
4275
4276 pFuncDesc->funcdesc.lprgelemdescParam =
4277 heap_alloc_zero(pFuncDesc->funcdesc.cParams * sizeof(ELEMDESC));
4278 pFuncDesc->pParamDesc = TLBParDesc_Constructor(pFuncDesc->funcdesc.cParams);
4279
4280 pArg = (WORD*)(pBlk + pFunc->arg_off);
4281
4282 for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) {
4283 char *paramName = pNameTable + (*pArg & ~1);
4284 BOOL HaveOffs;
4285 /* If arg type follows then paramName points to the 2nd
4286 letter of the name, else the next WORD is an offset to
4287 the arg type and paramName points to the first letter.
4288 So let's take one char off paramName and see if we're
4289 pointing at an alpha-numeric char. However if *pArg is
4290 0xffff or 0xfffe then the param has no name, the former
4291 meaning that the next WORD is the type, the latter
4292 meaning that the next WORD is an offset to the type. */
4293
4294 if(*pArg == 0xffff || *pArg == 0xfffe)
4295 paramName = NULL;
4296
4297 HaveOffs = !(*pArg & 1);
4298 pArg++;
4299
4300 TRACE_(typelib)("param %d: paramName %s, *pArg %#x\n",
4301 param, debugstr_a(paramName), *pArg);
4302
4303 if(HaveOffs) { /* the next word is an offset to type */
4304 pType = (WORD*)(pBlk + *pArg);
4305 SLTG_DoElem(pType, pBlk,
4306 &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
4307 pArg++;
4308 } else {
4309 pArg = SLTG_DoElem(pArg, pBlk,
4310 &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
4311 }
4312
4313 /* Are we an optional param ? */
4314 if(pFuncDesc->funcdesc.cParams - param <=
4315 pFuncDesc->funcdesc.cParamsOpt)
4316 pFuncDesc->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT;
4317
4318 if(paramName) {
4319 pFuncDesc->pParamDesc[param].Name = SLTG_ReadName(pNameTable,
4320 paramName - pNameTable, pTI->pTypeLib);
4321 } else {
4322 pFuncDesc->pParamDesc[param].Name = pFuncDesc->Name;
4323 }
4324 }
4325 }
4326 pTI->typeattr.cFuncs = cFuncs;
4327}
4328
4329static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
4330 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4331 SLTG_TypeInfoTail *pTITail)
4332{
4333 char *pFirstItem;
4334 sltg_ref_lookup_t *ref_lookup = NULL;
4335
4336 if(pTIHeader->href_table != 0xffffffff) {
4337 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4338 pNameTable);
4339 }
4340
4341 pFirstItem = pBlk;
4342
4343 if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
4344 SLTG_DoImpls(pFirstItem, pTI, FALSE, ref_lookup);
4345 }
4346 heap_free(ref_lookup);
4347}
4348
4349
4350static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
4351 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4352 const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
4353{
4354 char *pFirstItem;
4355 sltg_ref_lookup_t *ref_lookup = NULL;
4356
4357 if(pTIHeader->href_table != 0xffffffff) {
4358 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4359 pNameTable);
4360 }
4361
4362 pFirstItem = pBlk;
4363
4364 if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
4365 SLTG_DoImpls(pFirstItem, pTI, TRUE, ref_lookup);
4366 }
4367
4368 if (pTITail->funcs_off != 0xffff)
4369 SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings);
4370
4371 heap_free(ref_lookup);
4372
4373 if (TRACE_ON(typelib))
4374 dump_TLBFuncDesc(pTI->funcdescs, pTI->typeattr.cFuncs);
4375}
4376
4377static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
4378 const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4379 const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
4380{
4381 SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings);
4382}
4383
4384static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
4385 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4386 const SLTG_TypeInfoTail *pTITail)
4387{
4388 WORD *pType;
4389 sltg_ref_lookup_t *ref_lookup = NULL;
4390
4391 if (pTITail->simple_alias) {
4392 /* if simple alias, no more processing required */
4393 pTI->tdescAlias = heap_alloc_zero(sizeof(TYPEDESC));
4394 pTI->tdescAlias->vt = pTITail->tdescalias_vt;
4395 return;
4396 }
4397
4398 if(pTIHeader->href_table != 0xffffffff) {
4399 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4400 pNameTable);
4401 }
4402
4403 /* otherwise it is an offset to a type */
4404 pType = (WORD *)(pBlk + pTITail->tdescalias_vt);
4405
4406 pTI->tdescAlias = heap_alloc(sizeof(TYPEDESC));
4407 SLTG_DoType(pType, pBlk, pTI->tdescAlias, ref_lookup);
4408
4409 heap_free(ref_lookup);
4410}
4411
4412static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
4413 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4414 const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
4415{
4416 sltg_ref_lookup_t *ref_lookup = NULL;
4417 if (pTIHeader->href_table != 0xffffffff)
4418 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4419 pNameTable);
4420
4421 if (pTITail->vars_off != 0xffff)
4422 SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings);
4423
4424 if (pTITail->funcs_off != 0xffff)
4425 SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings);
4426
4427 if (pTITail->impls_off != 0xffff)
4428 SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);
4429
4430 /* this is necessary to cope with MSFT typelibs that set cFuncs to the number
4431 * of dispinterface functions including the IDispatch ones, so
4432 * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
4433 pTI->typeattr.cbSizeVft = pTI->typeattr.cFuncs * pTI->pTypeLib->ptr_size;
4434
4435 heap_free(ref_lookup);
4436 if (TRACE_ON(typelib))
4437 dump_TLBFuncDesc(pTI->funcdescs, pTI->typeattr.cFuncs);
4438}
4439
4440static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
4441 const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4442 const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
4443{
4444 SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL, hlp_strings);
4445}
4446
4447static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
4448 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4449 const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
4450{
4451 sltg_ref_lookup_t *ref_lookup = NULL;
4452 if (pTIHeader->href_table != 0xffffffff)
4453 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4454 pNameTable);
4455
4456 if (pTITail->vars_off != 0xffff)
4457 SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup, hlp_strings);
4458
4459 if (pTITail->funcs_off != 0xffff)
4460 SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup, hlp_strings);
4461 heap_free(ref_lookup);
4462 if (TRACE_ON(typelib))
4463 dump_TypeInfo(pTI);
4464}
4465
4466/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
4467 manageable copy of it into this */
4468typedef struct {
4474 char *extra;
4481
4482/****************************************************************************
4483 * ITypeLib2_Constructor_SLTG
4484 *
4485 * loading a SLTG typelib from an in-memory image
4486 */
4488{
4489 ITypeLibImpl *pTypeLibImpl;
4491 SLTG_BlkEntry *pBlkEntry;
4492 SLTG_Magic *pMagic;
4494 SLTG_Pad9 *pPad9;
4495 LPVOID pBlk, pFirstBlk;
4496 SLTG_LibBlk *pLibBlk;
4497 SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks;
4498 char *pNameTable, *ptr;
4499 const BYTE *hlp_strings;
4500 int i;
4501 DWORD len, order;
4502 ITypeInfoImpl **ppTypeInfoImpl;
4503
4504 TRACE_(typelib)("%p, TLB length = %d\n", pLib, dwTLBLength);
4505
4506
4507 pTypeLibImpl = TypeLibImpl_Constructor();
4508 if (!pTypeLibImpl) return NULL;
4509
4510 pHeader = pLib;
4511
4512 TRACE_(typelib)("header:\n");
4513 TRACE_(typelib)("\tmagic=0x%08x, file blocks = %d\n", pHeader->SLTG_magic,
4514 pHeader->nrOfFileBlks );
4515 if (pHeader->SLTG_magic != SLTG_SIGNATURE) {
4516 FIXME_(typelib)("Header type magic 0x%08x not supported.\n",
4517 pHeader->SLTG_magic);
4518 return NULL;
4519 }
4520
4521 /* There are pHeader->nrOfFileBlks - 2 TypeInfo records in this typelib */
4522 pTypeLibImpl->TypeInfoCount = pHeader->nrOfFileBlks - 2;
4523
4524 /* This points to pHeader->nrOfFileBlks - 1 of SLTG_BlkEntry */
4525 pBlkEntry = (SLTG_BlkEntry*)(pHeader + 1);
4526
4527 /* Next we have a magic block */
4528 pMagic = (SLTG_Magic*)(pBlkEntry + pHeader->nrOfFileBlks - 1);
4529
4530 /* Let's see if we're still in sync */
4532 sizeof(SLTG_COMPOBJ_MAGIC))) {
4533 FIXME_(typelib)("CompObj magic = %s\n", pMagic->CompObj_magic);
4534 return NULL;
4535 }
4536 if(memcmp(pMagic->dir_magic, SLTG_DIR_MAGIC,
4537 sizeof(SLTG_DIR_MAGIC))) {
4538 FIXME_(typelib)("dir magic = %s\n", pMagic->dir_magic);
4539 return NULL;
4540 }
4541
4542 pIndex = (SLTG_Index*)(pMagic+1);
4543
4544 pPad9 = (SLTG_Pad9*)(pIndex + pTypeLibImpl->TypeInfoCount);
4545
4546 pFirstBlk = pPad9 + 1;
4547
4548 /* We'll set up a ptr to the main library block, which is the last one. */
4549
4550 for(pBlk = pFirstBlk, order = pHeader->first_blk - 1;
4551 pBlkEntry[order].next != 0;
4552 order = pBlkEntry[order].next - 1) {
4553 pBlk = (char*)pBlk + pBlkEntry[order].len;
4554 }
4555 pLibBlk = pBlk;
4556
4557 len = SLTG_ReadLibBlk(pLibBlk, pTypeLibImpl);
4558
4559 /* Now there are 0x40 bytes of 0xffff with the numbers 0 to TypeInfoCount
4560 interspersed */
4561
4562 len += 0x40;
4563
4564 /* And now TypeInfoCount of SLTG_OtherTypeInfo */
4565 pTypeLibImpl->TypeInfoCount = *(WORD *)((char *)pLibBlk + len);
4566 len += sizeof(WORD);
4567
4568 pOtherTypeInfoBlks = heap_alloc_zero(sizeof(*pOtherTypeInfoBlks) * pTypeLibImpl->TypeInfoCount);
4569
4570 ptr = (char*)pLibBlk + len;
4571
4572 for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) {
4573 WORD w, extra;
4574 len = 0;
4575
4576 w = *(WORD*)ptr;
4577 if(w != 0xffff) {
4578 len += w;
4579 pOtherTypeInfoBlks[i].index_name = heap_alloc(w+1);
4580 memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 2, w);
4581 pOtherTypeInfoBlks[i].index_name[w] = '\0';
4582 }
4583 w = *(WORD*)(ptr + 2 + len);
4584 if(w != 0xffff) {
4585 TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 4 + len, w));
4586 pOtherTypeInfoBlks[i].other_name = heap_alloc(w+1);
4587 memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 4 + len, w);
4588 pOtherTypeInfoBlks[i].other_name[w] = '\0';
4589 len += w;
4590 }
4591 pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + 4 + len);
4592 pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + 6 + len);
4593 extra = pOtherTypeInfoBlks[i].hlpstr_len = *(WORD*)(ptr + 8 + len);
4594 if(extra) {
4595 pOtherTypeInfoBlks[i].extra = heap_alloc(extra);
4596 memcpy(pOtherTypeInfoBlks[i].extra, ptr + 10 + len, extra);
4597 len += extra;
4598 }
4599 pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 10 + len);
4600 pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 12 + len);
4601 pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 16 + len);
4602 memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 18 + len, sizeof(GUID));
4603 pOtherTypeInfoBlks[i].typekind = *(WORD*)(ptr + 18 + sizeof(GUID) + len);
4604 len += sizeof(SLTG_OtherTypeInfo);
4605 ptr += len;
4606 }
4607
4608 /* Get the next DWORD */
4609 len = *(DWORD*)ptr;
4610
4611 hlp_strings = (const BYTE *)ptr + sizeof(DWORD);
4612 TRACE("max help string length %#x, help strings length %#x\n",
4613 *(WORD *)hlp_strings, *(DWORD *)(hlp_strings + 2));
4614
4615 /* Now add this to pLibBLk look at what we're pointing at and
4616 possibly add 0x20, then add 0x216, sprinkle a bit a magic
4617 dust and we should be pointing at the beginning of the name
4618 table */
4619
4620 pNameTable = (char*)pLibBlk + len;
4621
4622 switch(*(WORD*)pNameTable) {
4623 case 0xffff:
4624 break;
4625 case 0x0200:
4626 pNameTable += 0x20;
4627 break;
4628 default:
4629 FIXME_(typelib)("pNameTable jump = %x\n", *(WORD*)pNameTable);
4630 break;
4631 }
4632
4633 pNameTable += 0x216;
4634
4635 pNameTable += 2;
4636
4637 TRACE_(typelib)("Library name is %s\n", pNameTable + pLibBlk->name);
4638
4639 pTypeLibImpl->Name = SLTG_ReadName(pNameTable, pLibBlk->name, pTypeLibImpl);
4640
4641
4642 /* Hopefully we now have enough ptrs set up to actually read in
4643 some TypeInfos. It's not clear which order to do them in, so
4644 I'll just follow the links along the BlkEntry chain and read
4645 them in the order in which they are in the file */
4646
4647 pTypeLibImpl->typeinfos = heap_alloc_zero(pTypeLibImpl->TypeInfoCount * sizeof(ITypeInfoImpl*));
4648 ppTypeInfoImpl = pTypeLibImpl->typeinfos;
4649
4650 for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0;
4651 pBlkEntry[order].next != 0;
4652 order = pBlkEntry[order].next - 1, i++) {
4653
4654 SLTG_TypeInfoHeader *pTIHeader;
4655 SLTG_TypeInfoTail *pTITail;
4656 SLTG_MemberHeader *pMemHeader;
4657
4658 if(strcmp(pBlkEntry[order].index_string + (char*)pMagic, pOtherTypeInfoBlks[i].index_name)) {
4659 FIXME_(typelib)("Index strings don't match\n");
4660 heap_free(pOtherTypeInfoBlks);
4661 return NULL;
4662 }
4663
4664 pTIHeader = pBlk;
4665 if(pTIHeader->magic != SLTG_TIHEADER_MAGIC) {
4666 FIXME_(typelib)("TypeInfoHeader magic = %04x\n", pTIHeader->magic);
4667 heap_free(pOtherTypeInfoBlks);
4668 return NULL;
4669 }
4670 TRACE_(typelib)("pTIHeader->res06 = %x, pTIHeader->res0e = %x, "
4671 "pTIHeader->res16 = %x, pTIHeader->res1e = %x\n",
4672 pTIHeader->res06, pTIHeader->res0e, pTIHeader->res16, pTIHeader->res1e);
4673
4674 *ppTypeInfoImpl = ITypeInfoImpl_Constructor();
4675 (*ppTypeInfoImpl)->pTypeLib = pTypeLibImpl;
4676 (*ppTypeInfoImpl)->index = i;
4677 (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl);
4678 (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext;
4679 (*ppTypeInfoImpl)->DocString = decode_string(hlp_strings, pOtherTypeInfoBlks[i].extra, pOtherTypeInfoBlks[i].hlpstr_len, pTypeLibImpl);
4680 (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2);
4681 (*ppTypeInfoImpl)->typeattr.typekind = pTIHeader->typekind;
4682 (*ppTypeInfoImpl)->typeattr.wMajorVerNum = pTIHeader->major_version;
4683 (*ppTypeInfoImpl)->typeattr.wMinorVerNum = pTIHeader->minor_version;
4684 (*ppTypeInfoImpl)->typeattr.wTypeFlags =
4685 (pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5);
4686
4687 if((*ppTypeInfoImpl)->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
4688 (*ppTypeInfoImpl)->typeattr.typekind = TKIND_DISPATCH;
4689
4690 if((pTIHeader->typeflags1 & 7) != 2)
4691 FIXME_(typelib)("typeflags1 = %02x\n", pTIHeader->typeflags1);
4692 if(pTIHeader->typeflags3 != 2)
4693 FIXME_(typelib)("typeflags3 = %02x\n", pTIHeader->typeflags3);
4694
4695 TRACE_(typelib)("TypeInfo %s of kind %s guid %s typeflags %04x\n",
4696 debugstr_w(TLB_get_bstr((*ppTypeInfoImpl)->Name)),
4697 typekind_desc[pTIHeader->typekind],
4698 debugstr_guid(TLB_get_guidref((*ppTypeInfoImpl)->guid)),
4699 (*ppTypeInfoImpl)->typeattr.wTypeFlags);
4700
4701 pMemHeader = (SLTG_MemberHeader*)((char *)pBlk + pTIHeader->elem_table);
4702
4703 pTITail = (SLTG_TypeInfoTail*)((char *)(pMemHeader + 1) + pMemHeader->cbExtra);
4704
4705 (*ppTypeInfoImpl)->typeattr.cbAlignment = pTITail->cbAlignment;
4706 (*ppTypeInfoImpl)->typeattr.cbSizeInstance = pTITail->cbSizeInstance;
4707 (*ppTypeInfoImpl)->typeattr.cbSizeVft = pTITail->cbSizeVft;
4708
4709 switch(pTIHeader->typekind) {
4710 case TKIND_ENUM:
4711 SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4712 pTIHeader, pTITail, hlp_strings);
4713 break;
4714
4715 case TKIND_RECORD:
4716 SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4717 pTIHeader, pTITail, hlp_strings);
4718 break;
4719
4720 case TKIND_INTERFACE:
4721 SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4722 pTIHeader, pTITail, hlp_strings);
4723 break;
4724
4725 case TKIND_COCLASS:
4726 SLTG_ProcessCoClass((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4727 pTIHeader, pTITail);
4728 break;
4729
4730 case TKIND_ALIAS:
4731 SLTG_ProcessAlias((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4732 pTIHeader, pTITail);
4733 break;
4734
4735 case TKIND_DISPATCH:
4736 SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4737 pTIHeader, pTITail, hlp_strings);
4738 break;
4739
4740 case TKIND_MODULE:
4741 SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4742 pTIHeader, pTITail, hlp_strings);
4743 break;
4744
4745 default:
4746 FIXME("Not processing typekind %d\n", pTIHeader->typekind);
4747 break;
4748
4749 }
4750
4751 /* could get cFuncs, cVars and cImplTypes from here
4752 but we've already set those */
4753#define X(x) TRACE_(typelib)("tt "#x": %x\n",pTITail->res##x);
4754 X(06);
4755 X(16);
4756 X(18);
4757 X(1a);
4758 X(1e);
4759 X(24);
4760 X(26);
4761 X(2a);
4762 X(2c);
4763 X(2e);
4764 X(30);
4765 X(32);
4766 X(34);
4767#undef X
4768 ++ppTypeInfoImpl;
4769 pBlk = (char*)pBlk + pBlkEntry[order].len;
4770 }
4771
4772 if(i != pTypeLibImpl->TypeInfoCount) {
4773 FIXME("Somehow processed %d TypeInfos\n", i);
4774 heap_free(pOtherTypeInfoBlks);
4775 return NULL;
4776 }
4777
4778 heap_free(pOtherTypeInfoBlks);
4779 return &pTypeLibImpl->ITypeLib2_iface;
4780}
4781
4783{
4785
4786 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
4787
4789 IsEqualIID(riid,&IID_ITypeLib)||
4790 IsEqualIID(riid,&IID_ITypeLib2))
4791 {
4792 *ppv = &This->ITypeLib2_iface;
4793 }
4794 else if(IsEqualIID(riid, &IID_ICreateTypeLib) ||
4795 IsEqualIID(riid, &IID_ICreateTypeLib2))
4796 {
4797 *ppv = &This->ICreateTypeLib2_iface;
4798 }
4799 else
4800 {
4801 *ppv = NULL;
4802 TRACE("-- Interface: E_NOINTERFACE\n");
4803 return E_NOINTERFACE;
4804 }
4805
4806 IUnknown_AddRef((IUnknown*)*ppv);
4807 return S_OK;
4808}
4809
4811{
4814
4815 TRACE("(%p) ref=%u\n", This, ref);
4816
4817 return ref;
4818}
4819
4821{
4824
4825 TRACE("(%p) ref=%u\n",This, ref);
4826
4827 if (!ref)
4828 {
4829 TLBImpLib *pImpLib, *pImpLibNext;
4830 TLBRefType *ref_type, *ref_type_next;
4831 TLBString *tlbstr, *tlbstr_next;
4832 TLBGuid *tlbguid, *tlbguid_next;
4833 int i;
4834
4835 /* remove cache entry */
4836 if(This->path)
4837 {
4838 TRACE("removing from cache list\n");
4840 if(This->entry.next)
4841 list_remove(&This->entry);
4843 heap_free(This->path);
4844 }
4845 TRACE(" destroying ITypeLib(%p)\n",This);
4846
4847 LIST_FOR_EACH_ENTRY_SAFE(tlbstr, tlbstr_next, &This->string_list, TLBString, entry) {
4848 list_remove(&tlbstr->entry);
4849 SysFreeString(tlbstr->str);
4850 heap_free(tlbstr);
4851 }
4852
4853 LIST_FOR_EACH_ENTRY_SAFE(tlbstr, tlbstr_next, &This->name_list, TLBString, entry) {
4854 list_remove(&tlbstr->entry);
4855 SysFreeString(tlbstr->str);
4856 heap_free(tlbstr);
4857 }
4858
4859 LIST_FOR_EACH_ENTRY_SAFE(tlbguid, tlbguid_next, &This->guid_list, TLBGuid, entry) {
4860 list_remove(&tlbguid->entry);
4861 heap_free(tlbguid);
4862 }
4863
4864 TLB_FreeCustData(&This->custdata_list);
4865
4866 for (i = 0; i < This->ctTypeDesc; i++)
4867 if (This->pTypeDesc[i].vt == VT_CARRAY)
4868 heap_free(This->pTypeDesc[i].u.lpadesc);
4869
4870 heap_free(This->pTypeDesc);
4871
4872 LIST_FOR_EACH_ENTRY_SAFE(pImpLib, pImpLibNext, &This->implib_list, TLBImpLib, entry)
4873 {
4874 if (pImpLib->pImpTypeLib)
4875 ITypeLib2_Release(&pImpLib->pImpTypeLib->ITypeLib2_iface);
4876 SysFreeString(pImpLib->name);
4877
4878 list_remove(&pImpLib->entry);
4879 heap_free(pImpLib);
4880 }
4881
4882 LIST_FOR_EACH_ENTRY_SAFE(ref_type, ref_type_next, &This->ref_list, TLBRefType, entry)
4883 {
4884 list_remove(&ref_type->entry);
4885 heap_free(ref_type);
4886 }
4887
4888 for (i = 0; i < This->TypeInfoCount; ++i){
4889 heap_free(This->typeinfos[i]->tdescAlias);
4890 ITypeInfoImpl_Destroy(This->typeinfos[i]);
4891 }
4892 heap_free(This->typeinfos);
4893 heap_free(This);
4894 return 0;
4895 }
4896
4897 return ref;
4898}
4899
4900/* ITypeLib::GetTypeInfoCount
4901 *
4902 * Returns the number of type descriptions in the type library
4903 */
4905{
4907 TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
4908 return This->TypeInfoCount;
4909}
4910
4911/* ITypeLib::GetTypeInfo
4912 *
4913 * retrieves the specified type description in the library.
4914 */
4916 ITypeLib2 *iface,
4917 UINT index,
4918 ITypeInfo **ppTInfo)
4919{
4921
4922 TRACE("%p %u %p\n", This, index, ppTInfo);
4923
4924 if(!ppTInfo)
4925 return E_INVALIDARG;
4926
4927 if(index >= This->TypeInfoCount)
4929
4930 *ppTInfo = (ITypeInfo *)&This->typeinfos[index]->ITypeInfo2_iface;
4931 ITypeInfo_AddRef(*ppTInfo);
4932
4933 return S_OK;
4934}
4935
4936
4937/* ITypeLibs::GetTypeInfoType
4938 *
4939 * Retrieves the type of a type description.
4940 */
4942 ITypeLib2 *iface,
4943 UINT index,
4944 TYPEKIND *pTKind)
4945{
4947
4948 TRACE("(%p, %d, %p)\n", This, index, pTKind);
4949
4950 if(!pTKind)
4951 return E_INVALIDARG;
4952
4953 if(index >= This->TypeInfoCount)
4955
4956 *pTKind = This->typeinfos[index]->typeattr.typekind;
4957
4958 return S_OK;
4959}
4960
4961/* ITypeLib::GetTypeInfoOfGuid
4962 *
4963 * Retrieves the type description that corresponds to the specified GUID.
4964 *
4965 */
4967 ITypeLib2 *iface,
4968 REFGUID guid,
4969 ITypeInfo **ppTInfo)
4970{
4972 int i;
4973
4974 TRACE("%p %s %p\n", This, debugstr_guid(guid), ppTInfo);
4975
4976 for(i = 0; i < This->TypeInfoCount; ++i){
4977 if(IsEqualIID(TLB_get_guid_null(This->typeinfos[i]->guid), guid)){
4978 *ppTInfo = (ITypeInfo *)&This->typeinfos[i]->ITypeInfo2_iface;
4979 ITypeInfo_AddRef(*ppTInfo);
4980 return S_OK;
4981 }
4982 }
4983
4985}
4986
4987/* ITypeLib::GetLibAttr
4988 *
4989 * Retrieves the structure that contains the library's attributes.
4990 *
4991 */
4993 ITypeLib2 *iface,
4994 LPTLIBATTR *attr)
4995{
4997
4998 TRACE("(%p, %p)\n", This, attr);
4999
5000 if (!attr) return E_INVALIDARG;
5001
5002 *attr = heap_alloc(sizeof(**attr));
5003 if (!*attr) return E_OUTOFMEMORY;
5004
5005 (*attr)->guid = *TLB_get_guid_null(This->guid);
5006 (*attr)->lcid = This->set_lcid;
5007 (*attr)->syskind = This->syskind;
5008 (*attr)->wMajorVerNum = This->ver_major;
5009 (*attr)->wMinorVerNum = This->ver_minor;
5010 (*attr)->wLibFlags = This->libflags;
5011
5012 return S_OK;
5013}
5014
5015/* ITypeLib::GetTypeComp
5016 *
5017 * Enables a client compiler to bind to a library's types, variables,
5018 * constants, and global functions.
5019 *
5020 */
5022 ITypeLib2 *iface,
5023 ITypeComp **ppTComp)
5024{
5026
5027 TRACE("(%p)->(%p)\n",This,ppTComp);
5028 *ppTComp = &This->ITypeComp_iface;
5029 ITypeComp_AddRef(*ppTComp);
5030
5031 return S_OK;
5032}
5033
5034/* ITypeLib::GetDocumentation
5035 *
5036 * Retrieves the library's documentation string, the complete Help file name
5037 * and path, and the context identifier for the library Help topic in the Help
5038 * file.
5039 *
5040 * On a successful return all non-null BSTR pointers will have been set,
5041 * possibly to NULL.
5042 */
5044 ITypeLib2 *iface,
5045 INT index,
5046 BSTR *pBstrName,
5047 BSTR *pBstrDocString,
5048 DWORD *pdwHelpContext,
5049 BSTR *pBstrHelpFile)
5050{
5053 ITypeInfo *pTInfo;
5054
5055 TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n",
5056 This, index,
5057 pBstrName, pBstrDocString,
5058 pdwHelpContext, pBstrHelpFile);
5059
5060 if(index<0)
5061 {
5062 /* documentation for the typelib */
5063 if(pBstrName)
5064 {
5065 if (This->Name)
5066 {
5067 if(!(*pBstrName = SysAllocString(TLB_get_bstr(This->Name))))
5068 goto memerr1;
5069 }
5070 else
5071 *pBstrName = NULL;
5072 }
5073 if(pBstrDocString)
5074 {
5075 if (This->DocString)
5076 {
5077 if(!(*pBstrDocString = SysAllocString(TLB_get_bstr(This->DocString))))
5078 goto memerr2;
5079 }
5080 else
5081 *pBstrDocString = NULL;
5082 }
5083 if(pdwHelpContext)
5084 {
5085 *pdwHelpContext = This->dwHelpContext;
5086 }
5087 if(pBstrHelpFile)
5088 {
5089 if (This->HelpFile)
5090 {
5091 if(!(*pBstrHelpFile = SysAllocString(TLB_get_bstr(This->HelpFile))))
5092 goto memerr3;
5093 }
5094 else
5095 *pBstrHelpFile = NULL;
5096 }
5097
5098 result = S_OK;
5099 }
5100 else
5101 {
5102 /* for a typeinfo */
5103 result = ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
5104
5105 if(SUCCEEDED(result))
5106 {
5107 result = ITypeInfo_GetDocumentation(pTInfo,
5109 pBstrName,
5110 pBstrDocString,
5111 pdwHelpContext, pBstrHelpFile);
5112
5113 ITypeInfo_Release(pTInfo);
5114 }
5115 }
5116 return result;
5117memerr3:
5118 if (pBstrDocString) SysFreeString (*pBstrDocString);
5119memerr2:
5120 if (pBstrName) SysFreeString (*pBstrName);
5121memerr1:
5123}
5124
5125/* ITypeLib::IsName
5126 *
5127 * Indicates whether a passed-in string contains the name of a type or member
5128 * described in the library.
5129 *
5130 */
5132 ITypeLib2 *iface,
5133 LPOLESTR szNameBuf,
5134 ULONG lHashVal,
5135 BOOL *pfName)
5136{
5138 int tic;
5139 UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR), fdc, vrc;
5140
5141 TRACE("(%p)->(%s,%08x,%p)\n", This, debugstr_w(szNameBuf), lHashVal,
5142 pfName);
5143
5144 *pfName=TRUE;
5145 for(tic = 0; tic < This->TypeInfoCount; ++tic){
5146 ITypeInfoImpl *pTInfo = This->typeinfos[tic];
5147 if(!TLB_str_memcmp(szNameBuf, pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
5148 for(fdc = 0; fdc < pTInfo->typeattr.cFuncs; ++fdc) {
5149 TLBFuncDesc *pFInfo = &pTInfo->funcdescs[fdc];
5150 int pc;
5151 if(!TLB_str_memcmp(szNameBuf, pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
5152 for(pc=0; pc < pFInfo->funcdesc.cParams; pc++){
5153 if(!TLB_str_memcmp(szNameBuf, pFInfo->pParamDesc[pc].Name, nNameBufLen))
5154 goto ITypeLib2_fnIsName_exit;
5155 }
5156 }
5157 for(vrc = 0; vrc < pTInfo->typeattr.cVars; ++vrc){
5158 TLBVarDesc *pVInfo = &pTInfo->vardescs[vrc];
5159 if(!TLB_str_memcmp(szNameBuf, pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
5160 }
5161
5162 }
5163 *pfName=FALSE;
5164
5165ITypeLib2_fnIsName_exit:
5166 TRACE("(%p)slow! search for %s: %sfound!\n", This,
5167 debugstr_w(szNameBuf), *pfName ? "" : "NOT ");
5168
5169 return S_OK;
5170}
5171
5172/* ITypeLib::FindName
5173 *
5174 * Finds occurrences of a type description in a type library. This may be used
5175 * to quickly verify that a name exists in a type library.
5176 *
5177 */
5179 ITypeLib2 *iface,
5180 LPOLESTR name,
5181 ULONG hash,
5182 ITypeInfo **ppTInfo,
5183 MEMBERID *memid,
5184 UINT16 *found)
5185{
5187 int tic;
5188 UINT count = 0;
5189 UINT len;
5190
5191 TRACE("(%p)->(%s %u %p %p %p)\n", This, debugstr_w(name), hash, ppTInfo, memid, found);
5192
5193 if ((!name && hash == 0) || !ppTInfo || !memid || !found)
5194 return E_INVALIDARG;
5195
5196 len = (lstrlenW(name) + 1)*sizeof(WCHAR);
5197 for(tic = 0; count < *found && tic < This->TypeInfoCount; ++tic) {
5198 ITypeInfoImpl *pTInfo = This->typeinfos[tic];
5199 TLBVarDesc *var;
5200 UINT fdc;
5201
5202 if(!TLB_str_memcmp(name, pTInfo->Name, len)) {
5203 memid[count] = MEMBERID_NIL;
5204 goto ITypeLib2_fnFindName_exit;
5205 }
5206
5207 for(fdc = 0; fdc < pTInfo->typeattr.cFuncs; ++fdc) {
5208 TLBFuncDesc *func = &pTInfo->funcdescs[fdc];
5209
5210 if(!TLB_str_memcmp(name, func->Name, len)) {
5211 memid[count] = func->funcdesc.memid;
5212 goto ITypeLib2_fnFindName_exit;
5213 }
5214 }
5215
5216 var = TLB_get_vardesc_by_name(pTInfo->vardescs, pTInfo->typeattr.cVars, name);
5217 if (var) {
5218 memid[count] = var->vardesc.memid;
5219 goto ITypeLib2_fnFindName_exit;
5220 }
5221
5222 continue;
5223ITypeLib2_fnFindName_exit:
5224 ITypeInfo2_AddRef(&pTInfo->ITypeInfo2_iface);
5225 ppTInfo[count] = (ITypeInfo *)&pTInfo->ITypeInfo2_iface;
5226 count++;
5227 }
5228 TRACE("found %d typeinfos\n", count);
5229
5230 *found = count;
5231
5232 return S_OK;
5233}
5234
5235/* ITypeLib::ReleaseTLibAttr
5236 *
5237 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
5238 *
5239 */
5241 ITypeLib2 *iface,
5242 TLIBATTR *pTLibAttr)
5243{
5245 TRACE("(%p)->(%p)\n", This, pTLibAttr);
5246 heap_free(pTLibAttr);
5247}
5248
5249/* ITypeLib2::GetCustData
5250 *
5251 * gets the custom data
5252 */
5254 ITypeLib2 * iface,
5255 REFGUID guid,
5256 VARIANT *pVarVal)
5257{
5259 TLBCustData *pCData;
5260
5261 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(guid), pVarVal);
5262
5263 pCData = TLB_get_custdata_by_guid(&This->custdata_list, guid);
5264 if(!pCData)
5266
5267 VariantInit(pVarVal);
5268 VariantCopy(pVarVal, &pCData->data);
5269
5270 return S_OK;
5271}
5272
5273/* ITypeLib2::GetLibStatistics
5274 *
5275 * Returns statistics about a type library that are required for efficient
5276 * sizing of hash tables.
5277 *
5278 */
5280 ITypeLib2 * iface,
5281 ULONG *pcUniqueNames,
5282 ULONG *pcchUniqueNames)
5283{
5285
5286 FIXME("(%p): stub!\n", This);
5287
5288 if(pcUniqueNames) *pcUniqueNames=1;
5289 if(pcchUniqueNames) *pcchUniqueNames=1;
5290 return S_OK;
5291}
5292
5293/* ITypeLib2::GetDocumentation2
5294 *
5295 * Retrieves the library's documentation string, the complete Help file name
5296 * and path, the localization context to use, and the context ID for the
5297 * library Help topic in the Help file.
5298 *
5299 */
5301 ITypeLib2 * iface,
5302 INT index,
5303 LCID lcid,
5304 BSTR *pbstrHelpString,
5305 DWORD *pdwHelpStringContext,
5306 BSTR *pbstrHelpStringDll)
5307{
5310 ITypeInfo *pTInfo;
5311
5312 FIXME("(%p) index %d lcid %d half implemented stub!\n", This, index, lcid);
5313
5314 /* the help string should be obtained from the helpstringdll,
5315 * using the _DLLGetDocumentation function, based on the supplied
5316 * lcid. Nice to do sometime...
5317 */
5318 if(index<0)
5319 {
5320 /* documentation for the typelib */
5321 if(pbstrHelpString)
5322 *pbstrHelpString=SysAllocString(TLB_get_bstr(This->DocString));
5323 if(pdwHelpStringContext)
5324 *pdwHelpStringContext=This->dwHelpContext;
5325 if(pbstrHelpStringDll)
5326 *pbstrHelpStringDll=SysAllocString(TLB_get_bstr(This->HelpStringDll));
5327
5328 result = S_OK;
5329 }
5330 else
5331 {
5332 /* for a typeinfo */
5333 result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
5334
5335 if(SUCCEEDED(result))
5336 {
5337 ITypeInfo2 * pTInfo2;
5338 result = ITypeInfo_QueryInterface(pTInfo,
5339 &IID_ITypeInfo2,
5340 (LPVOID*) &pTInfo2);
5341
5342 if(SUCCEEDED(result))
5343 {
5344 result = ITypeInfo2_GetDocumentation2(pTInfo2,
5346 lcid,
5347 pbstrHelpString,
5348 pdwHelpStringContext,
5349 pbstrHelpStringDll);
5350
5351 ITypeInfo2_Release(pTInfo2);
5352 }
5353
5354 ITypeInfo_Release(pTInfo);
5355 }
5356 }
5357 return result;
5358}
5359
5360static HRESULT TLB_copy_all_custdata(struct list *custdata_list, CUSTDATA *pCustData)
5361{
5362 TLBCustData *pCData;
5363 unsigned int ct;
5364 CUSTDATAITEM *cdi;
5365
5366 ct = list_count(custdata_list);
5367
5368 pCustData->prgCustData = CoTaskMemAlloc(ct * sizeof(CUSTDATAITEM));
5369 if(!pCustData->prgCustData)
5370 return E_OUTOFMEMORY;
5371
5372 pCustData->cCustData = ct;
5373
5374 cdi = pCustData->prgCustData;
5375 LIST_FOR_EACH_ENTRY(pCData, custdata_list, TLBCustData, entry){
5376 cdi->guid = *TLB_get_guid_null(pCData->guid);
5377 VariantCopy(&cdi->varValue, &pCData->data);
5378 ++cdi;
5379 }
5380
5381 return S_OK;
5382}
5383
5384
5385/* ITypeLib2::GetAllCustData
5386 *
5387 * Gets all custom data items for the library.
5388 *
5389 */
5391 ITypeLib2 * iface,
5392 CUSTDATA *pCustData)
5393{
5395 TRACE("(%p)->(%p)\n", This, pCustData);
5396 return TLB_copy_all_custdata(&This->custdata_list, pCustData);
5397}
5398
5399static const ITypeLib2Vtbl tlbvt = {
5413
5418 };
5419
5420
5422{
5424
5425 return ITypeLib2_QueryInterface(&This->ITypeLib2_iface, riid, ppv);
5426}
5427
5429{
5431
5432 return ITypeLib2_AddRef(&This->ITypeLib2_iface);
5433}
5434
5436{
5438
5439 return ITypeLib2_Release(&This->ITypeLib2_iface);
5440}
5441
5443 ITypeComp * iface,
5444 OLECHAR * szName,
5445 ULONG lHash,
5446 WORD wFlags,
5447 ITypeInfo ** ppTInfo,
5448 DESCKIND * pDescKind,
5449 BINDPTR * pBindPtr)
5450{
5452 BOOL typemismatch = FALSE;
5453 int i;
5454
5455 TRACE("(%p)->(%s, 0x%x, 0x%x, %p, %p, %p)\n", This, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
5456
5457 *pDescKind = DESCKIND_NONE;
5458 pBindPtr->lptcomp = NULL;
5459 *ppTInfo = NULL;
5460
5461 for(i = 0; i < This->TypeInfoCount; ++i){
5462 ITypeInfoImpl *pTypeInfo = This->typeinfos[i];
5463 TRACE("testing %s\n", debugstr_w(TLB_get_bstr(pTypeInfo->Name)));
5464
5465 /* FIXME: check wFlags here? */
5466 /* FIXME: we should use a hash table to look this info up using lHash
5467 * instead of an O(n) search */
5468 if ((pTypeInfo->typeattr.typekind == TKIND_ENUM) ||
5469 (pTypeInfo->typeattr.typekind == TKIND_MODULE))
5470 {
5471 if (pTypeInfo->Name && !wcscmp(pTypeInfo->Name->str, szName))
5472 {
5473 *pDescKind = DESCKIND_TYPECOMP;
5474 pBindPtr->lptcomp = &pTypeInfo->ITypeComp_iface;
5475 ITypeComp_AddRef(pBindPtr->lptcomp);
5476 TRACE("module or enum: %s\n", debugstr_w(szName));
5477 return S_OK;
5478 }
5479 }
5480
5481 if ((pTypeInfo->typeattr.typekind == TKIND_MODULE) ||
5482 (pTypeInfo->typeattr.typekind == TKIND_ENUM))
5483 {
5484 ITypeComp *pSubTypeComp = &pTypeInfo->ITypeComp_iface;
5485 HRESULT hr;
5486
5487 hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
5488 if (SUCCEEDED(hr) && (*pDescKind != DESCKIND_NONE))
5489 {
5490 TRACE("found in module or in enum: %s\n", debugstr_w(szName));
5491 return S_OK;
5492 }
5493 else if (hr == TYPE_E_TYPEMISMATCH)
5494 typemismatch = TRUE;
5495 }
5496
5497 if ((pTypeInfo->typeattr.typekind == TKIND_COCLASS) &&
5498 (pTypeInfo->typeattr.wTypeFlags & TYPEFLAG_FAPPOBJECT))
5499 {
5500 ITypeComp *pSubTypeComp = &pTypeInfo->ITypeComp_iface;
5501 HRESULT hr;
5502 ITypeInfo *subtypeinfo;
5503 BINDPTR subbindptr;
5504 DESCKIND subdesckind;
5505
5506 hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags,
5507 &subtypeinfo, &subdesckind, &subbindptr);
5508 if (SUCCEEDED(hr) && (subdesckind != DESCKIND_NONE))
5509 {
5510 TYPEDESC tdesc_appobject;
5511 const VARDESC vardesc_appobject =
5512 {
5513 -2, /* memid */
5514 NULL, /* lpstrSchema */
5515 {
5516 0 /* oInst */
5517 },
5518 {
5519 /* ELEMDESC */
5520 {
5521 /* TYPEDESC */
5522 {
5523 &tdesc_appobject
5524 },
5525 VT_PTR
5526 },
5527 },
5528 0, /* wVarFlags */
5529 VAR_STATIC /* varkind */
5530 };
5531
5532 tdesc_appobject.u.hreftype = pTypeInfo->hreftype;
5533 tdesc_appobject.vt = VT_USERDEFINED;
5534
5535 TRACE("found in implicit app object: %s\n", debugstr_w(szName));
5536
5537 /* cleanup things filled in by Bind call so we can put our
5538 * application object data in there instead */
5539 switch (subdesckind)
5540 {
5541 case DESCKIND_FUNCDESC:
5542 ITypeInfo_ReleaseFuncDesc(subtypeinfo, subbindptr.lpfuncdesc);
5543 break;
5544 case DESCKIND_VARDESC:
5545 ITypeInfo_ReleaseVarDesc(subtypeinfo, subbindptr.lpvardesc);
5546 break;
5547 default:
5548 break;
5549 }
5550 if (subtypeinfo) ITypeInfo_Release(subtypeinfo);
5551
5552 if (pTypeInfo->hreftype == -1)
5553 FIXME("no hreftype for interface %p\n", pTypeInfo);
5554
5555 hr = TLB_AllocAndInitVarDesc(&vardesc_appobject, &pBindPtr->lpvardesc);
5556 if (FAILED(hr))
5557 return hr;
5558
5559 *pDescKind = DESCKIND_IMPLICITAPPOBJ;
5560 *ppTInfo = (ITypeInfo *)&pTypeInfo->ITypeInfo2_iface;
5561 ITypeInfo_AddRef(*ppTInfo);
5562 return S_OK;
5563 }
5564 else if (hr == TYPE_E_TYPEMISMATCH)
5565 typemismatch = TRUE;
5566 }
5567 }
5568
5569 if (typemismatch)
5570 {
5571 TRACE("type mismatch %s\n", debugstr_w(szName));
5572 return TYPE_E_TYPEMISMATCH;
5573 }
5574 else
5575 {
5576 TRACE("name not found %s\n", debugstr_w(szName));
5577 return S_OK;
5578 }
5579}
5580
5582 ITypeComp * iface,
5583 OLECHAR * szName,
5584 ULONG lHash,
5585 ITypeInfo ** ppTInfo,
5586 ITypeComp ** ppTComp)
5587{
5590
5591 TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
5592
5593 if(!szName || !ppTInfo || !ppTComp)
5594 return E_INVALIDARG;
5595
5596 info = TLB_get_typeinfo_by_name(This->typeinfos, This->TypeInfoCount, szName);
5597 if(!info){
5598 *ppTInfo = NULL;
5599 *ppTComp = NULL;
5600 return S_OK;
5601 }
5602
5603 *ppTInfo = (ITypeInfo *)&info->ITypeInfo2_iface;
5604 ITypeInfo_AddRef(*ppTInfo);
5605 *ppTComp = &info->ITypeComp_iface;
5606 ITypeComp_AddRef(*ppTComp);
5607
5608 return S_OK;
5609}
5610
5611static const ITypeCompVtbl tlbtcvt =
5612{
5613
5617
5620};
5621
5622/*================== ITypeInfo(2) Methods ===================================*/
5624{
5625 ITypeInfoImpl *pTypeInfoImpl;
5626
5627 pTypeInfoImpl = heap_alloc_zero(sizeof(ITypeInfoImpl));
5628 if (pTypeInfoImpl)
5629 {
5630 pTypeInfoImpl->ITypeInfo2_iface.lpVtbl = &tinfvt;
5631 pTypeInfoImpl->ITypeComp_iface.lpVtbl = &tcompvt;
5632 pTypeInfoImpl->ICreateTypeInfo2_iface.lpVtbl = &CreateTypeInfo2Vtbl;
5633 pTypeInfoImpl->ref = 0;
5634 pTypeInfoImpl->hreftype = -1;
5635 pTypeInfoImpl->typeattr.memidConstructor = MEMBERID_NIL;
5636 pTypeInfoImpl->typeattr.memidDestructor = MEMBERID_NIL;
5637 pTypeInfoImpl->pcustdata_list = &pTypeInfoImpl->custdata_list;
5638 list_init(pTypeInfoImpl->pcustdata_list);
5639 }
5640 TRACE("(%p)\n", pTypeInfoImpl);
5641 return pTypeInfoImpl;
5642}
5643
5644/* ITypeInfo::QueryInterface
5645 */
5647 ITypeInfo2 *iface,
5648 REFIID riid,
5649 VOID **ppvObject)
5650{
5652
5653 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
5654
5655 *ppvObject=NULL;
5657 IsEqualIID(riid,&IID_ITypeInfo)||
5658 IsEqualIID(riid,&IID_ITypeInfo2))
5659 *ppvObject = &This->ITypeInfo2_iface;
5660 else if(IsEqualIID(riid, &IID_ICreateTypeInfo) ||
5661 IsEqualIID(riid, &IID_ICreateTypeInfo2))
5662 *ppvObject = &This->ICreateTypeInfo2_iface;
5663 else if(IsEqualIID(riid, &IID_ITypeComp))
5664 *ppvObject = &This->ITypeComp_iface;
5665
5666 if(*ppvObject){
5667 IUnknown_AddRef((IUnknown*)*ppvObject);
5668 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
5669 return S_OK;
5670 }
5671 TRACE("-- Interface: E_NOINTERFACE\n");
5672 return E_NOINTERFACE;
5673}
5674
5675/* ITypeInfo::AddRef
5676 */
5678{
5681
5682 TRACE("(%p)->ref is %u\n",This, ref);
5683
5684 if (ref == 1 /* incremented from 0 */)
5685 ITypeLib2_AddRef(&This->pTypeLib->ITypeLib2_iface);
5686
5687 return ref;
5688}
5689
5691{
5692 UINT i;
5693
5694 TRACE("destroying ITypeInfo(%p)\n",This);
5695
5696 for (i = 0; i < This->typeattr.cFuncs; ++i)
5697 {
5698 int j;
5699 TLBFuncDesc *pFInfo = &This->funcdescs[i];
5700 for(j = 0; j < pFInfo->funcdesc.cParams; j++)
5701 {
5702 ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[j];
5703 if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
5704 VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
5706 }
5707 heap_free(pFInfo->funcdesc.lprgelemdescParam);
5708 heap_free(pFInfo->pParamDesc);
5710 }
5711 heap_free(This->funcdescs);
5712
5713 for(i = 0; i < This->typeattr.cVars; ++i)
5714 {
5715 TLBVarDesc *pVInfo = &This->vardescs[i];
5716 if (pVInfo->vardesc_create) {
5718 } else if (pVInfo->vardesc.varkind == VAR_CONST) {
5719 VariantClear(pVInfo->vardesc.u.lpvarValue);
5720 heap_free(pVInfo->vardesc.u.lpvarValue);
5721 }
5723 }
5724 heap_free(This->vardescs);
5725
5726 if(This->impltypes){
5727 for (i = 0; i < This->typeattr.cImplTypes; ++i){
5728 TLBImplType *pImpl = &This->impltypes[i];
5730 }
5731 heap_free(This->impltypes);
5732 }
5733
5734 TLB_FreeCustData(&This->custdata_list);
5735
5736 heap_free(This);
5737}
5738
5739/* ITypeInfo::Release
5740 */
5742{
5745
5746 TRACE("(%p)->(%u)\n",This, ref);
5747
5748 if (!ref)
5749 {
5750 BOOL not_attached_to_typelib = This->not_attached_to_typelib;
5751 ITypeLib2_Release(&This->pTypeLib->ITypeLib2_iface);
5752 if (not_attached_to_typelib)
5753 heap_free(This);
5754 /* otherwise This will be freed when typelib is freed */
5755 }
5756
5757 return ref;
5758}
5759
5760/* ITypeInfo::GetTypeAttr
5761 *
5762 * Retrieves a TYPEATTR structure that contains the attributes of the type
5763 * description.
5764 *
5765 */
5767 LPTYPEATTR *ppTypeAttr)
5768{
5770 SIZE_T size;
5771
5772 TRACE("(%p)\n",This);
5773
5774 size = sizeof(**ppTypeAttr);
5775 if (This->typeattr.typekind == TKIND_ALIAS && This->tdescAlias)
5776 size += TLB_SizeTypeDesc(This->tdescAlias, FALSE);
5777
5778 *ppTypeAttr = heap_alloc(size);
5779 if (!*ppTypeAttr)
5780 return E_OUTOFMEMORY;
5781
5782 **ppTypeAttr = This->typeattr;
5783 (*ppTypeAttr)->guid = *TLB_get_guid_null(This->guid);
5784
5785 if (This->tdescAlias)
5786 TLB_CopyTypeDesc(&(*ppTypeAttr)->tdescAlias, This->tdescAlias, *ppTypeAttr + 1);
5787
5788 if((*ppTypeAttr)->typekind == TKIND_DISPATCH) {
5789 /* This should include all the inherited funcs */
5790 (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / This->pTypeLib->ptr_size;
5791 /* This is always the size of IDispatch's vtbl */
5792 (*ppTypeAttr)->cbSizeVft = sizeof(IDispatchVtbl);
5793 (*ppTypeAttr)->wTypeFlags &= ~TYPEFLAG_FOLEAUTOMATION;
5794 }
5795 return S_OK;
5796}
5797
5798/* ITypeInfo::GetTypeComp
5799 *
5800 * Retrieves the ITypeComp interface for the type description, which enables a
5801 * client compiler to bind to the type description's members.
5802 *
5803 */
5805 ITypeComp * *ppTComp)
5806{
5808
5809 TRACE("(%p)->(%p)\n", This, ppTComp);
5810
5811 *ppTComp = &This->ITypeComp_iface;
5812 ITypeComp_AddRef(*ppTComp);
5813 return S_OK;
5814}
5815
5816static SIZE_T TLB_SizeElemDesc( const ELEMDESC *elemdesc )
5817{
5818 SIZE_T size = TLB_SizeTypeDesc(&elemdesc->tdesc, FALSE);
5819 if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
5820 size += sizeof(*elemdesc->u.paramdesc.pparamdescex);
5821 return size;
5822}
5823
5824static HRESULT TLB_CopyElemDesc( const ELEMDESC *src, ELEMDESC *dest, char **buffer )
5825{
5826 *dest = *src;
5827 *buffer = TLB_CopyTypeDesc(&dest->tdesc, &src->tdesc, *buffer);
5828 if (src->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
5829 {
5830 const PARAMDESCEX *pparamdescex_src = src->u.paramdesc.pparamdescex;
5831 PARAMDESCEX *pparamdescex_dest = dest->u.paramdesc.pparamdescex = (PARAMDESCEX *)*buffer;
5832 *buffer += sizeof(PARAMDESCEX);
5833 *pparamdescex_dest = *pparamdescex_src;
5834 pparamdescex_dest->cBytes = sizeof(PARAMDESCEX);
5835 VariantInit(&pparamdescex_dest->varDefaultValue);
5836 return VariantCopy(&pparamdescex_dest->varDefaultValue,
5837 (VARIANTARG *)&pparamdescex_src->varDefaultValue);
5838 }
5839 else
5840 dest->u.paramdesc.pparamdescex = NULL;
5841 return S_OK;
5842}
5843
5845{
5847 for (i = 0; i < len; ++i)
5848 if (str[i] > 0x7f)
5849 str[i] = '?';
5850 return S_OK;
5851}
5852
5854{
5855 if (V_VT(var) == VT_INT)
5856 return VariantChangeType(var, var, 0, VT_I4);
5857 else if (V_VT(var) == VT_UINT)
5858 return VariantChangeType(var, var, 0, VT_UI4);
5859 else if (V_VT(var) == VT_BSTR)
5860 return TLB_SanitizeBSTR(V_BSTR(var));
5861
5862 return S_OK;
5863}
5864
5865static void TLB_FreeElemDesc( ELEMDESC *elemdesc )
5866{
5867 if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
5868 VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
5869}
5870
5871static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_ptr, BOOL dispinterface )
5872{
5873 FUNCDESC *dest;
5874 char *buffer;
5875 SIZE_T size = sizeof(*src);
5876 SHORT i;
5877 HRESULT hr;
5878
5879 size += sizeof(*src->lprgscode) * src->cScodes;
5880 size += TLB_SizeElemDesc(&src->elemdescFunc);
5881 for (i = 0; i < src->cParams; i++)
5882 {
5883 size += sizeof(ELEMDESC);
5884 size += TLB_SizeElemDesc(&src->lprgelemdescParam[i]);
5885 }
5886
5887 dest = (FUNCDESC *)SysAllocStringByteLen(NULL, size);
5888 if (!dest) return E_OUTOFMEMORY;
5889
5890 *dest = *src;
5891 if (dispinterface) /* overwrite funckind */
5892 dest->funckind = FUNC_DISPATCH;
5893 buffer = (char *)(dest + 1);
5894
5895 dest->oVft = dest->oVft & 0xFFFC;
5896
5897 if (dest->cScodes) {
5898 dest->lprgscode = (SCODE *)buffer;
5899 memcpy(dest->lprgscode, src->lprgscode, sizeof(*src->lprgscode) * src->cScodes);
5900 buffer += sizeof(*src->lprgscode) * src->cScodes;
5901 } else
5902 dest->lprgscode = NULL;
5903
5904 hr = TLB_CopyElemDesc(&src->elemdescFunc, &dest->elemdescFunc, &buffer);
5905 if (FAILED(hr))
5906 {
5908 return hr;
5909 }
5910
5911 if (dest->cParams) {
5912 dest->lprgelemdescParam = (ELEMDESC *)buffer;
5913 buffer += sizeof(ELEMDESC) * src->cParams;
5914 for (i = 0; i < src->cParams; i++)
5915 {
5916 hr = TLB_CopyElemDesc(&src->lprgelemdescParam[i], &dest->lprgelemdescParam[i], &buffer);
5917 if (FAILED(hr))
5918 break;
5919 }
5920 if (FAILED(hr))
5921 {
5922 /* undo the above actions */
5923 for (i = i - 1; i >= 0; i--)
5924 TLB_FreeElemDesc(&dest->lprgelemdescParam[i]);
5925 TLB_FreeElemDesc(&dest->elemdescFunc);
5927 return hr;
5928 }
5929 } else
5930 dest->lprgelemdescParam = NULL;
5931
5932 /* special treatment for dispinterfaces: this makes functions appear
5933 * to return their [retval] value when it is really returning an
5934 * HRESULT */
5935 if (dispinterface && dest->elemdescFunc.tdesc.vt == VT_HRESULT)
5936 {
5937 if (dest->cParams &&
5938 (dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
5939 {
5940 ELEMDESC *elemdesc = &dest->lprgelemdescParam[dest->cParams - 1];
5941 if (elemdesc->tdesc.vt != VT_PTR)
5942 {
5943 ERR("elemdesc should have started with VT_PTR instead of:\n");
5944 if (ERR_ON(ole))
5945 dump_ELEMDESC(elemdesc);
5946 return E_UNEXPECTED;
5947 }
5948
5949 /* copy last parameter to the return value. we are using a flat
5950 * buffer so there is no danger of leaking memory in
5951 * elemdescFunc */
5952 dest->elemdescFunc.tdesc = *elemdesc->tdesc.u.lptdesc;
5953
5954 /* remove the last parameter */
5955 dest->cParams--;
5956 }
5957 else
5958 /* otherwise this function is made to appear to have no return
5959 * value */
5960 dest->elemdescFunc.tdesc.vt = VT_VOID;
5961
5962 }
5963
5964 *dest_ptr = dest;
5965 return S_OK;
5966}
5967
5968static void TLB_FreeVarDesc(VARDESC *var_desc)
5969{
5970 TLB_FreeElemDesc(&var_desc->elemdescVar);
5971 if (var_desc->varkind == VAR_CONST)
5972 VariantClear(var_desc->u.lpvarValue);
5973 SysFreeString((BSTR)var_desc);
5974}
5975
5976HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc )
5977{
5979
5980 if (index >= This->typeattr.cFuncs)
5982
5983 *ppFuncDesc = &This->funcdescs[index].funcdesc;
5984 return S_OK;
5985}
5986
5987/* internal function to make the inherited interfaces' methods appear
5988 * part of the interface */
5990 UINT index, const FUNCDESC **ppFuncDesc, UINT *funcs, UINT *hrefoffset)
5991{
5993 HRESULT hr;
5994 UINT implemented_funcs = 0;
5995
5996 if (funcs)
5997 *funcs = 0;
5998 else
5999 *hrefoffset = DISPATCH_HREF_OFFSET;
6000
6001 if(This->impltypes)
6002 {
6003 ITypeInfo *pSubTypeInfo;
6004 UINT sub_funcs;
6005
6006 hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pSubTypeInfo);
6007 if (FAILED(hr))
6008 return hr;
6009
6011 index,
6012 ppFuncDesc,
6013 &sub_funcs, hrefoffset);
6014 implemented_funcs += sub_funcs;
6015 ITypeInfo_Release(pSubTypeInfo);
6016 if (SUCCEEDED(hr))
6017 return hr;
6018 *hrefoffset += DISPATCH_HREF_OFFSET;
6019 }
6020
6021 if (funcs)
6022 *funcs = implemented_funcs + This->typeattr.cFuncs;
6023 else
6024 *hrefoffset = 0;
6025
6026 if (index < implemented_funcs)
6027 return E_INVALIDARG;
6028 return ITypeInfoImpl_GetInternalFuncDesc(iface, index - implemented_funcs,
6029 ppFuncDesc);
6030}
6031
6032static inline void ITypeInfoImpl_ElemDescAddHrefOffset( LPELEMDESC pElemDesc, UINT hrefoffset)
6033{
6034 TYPEDESC *pTypeDesc = &pElemDesc->tdesc;
6035 while (TRUE)
6036 {
6037 switch (pTypeDesc->vt)
6038 {
6039 case VT_USERDEFINED:
6040 pTypeDesc->u.hreftype += hrefoffset;
6041 return;
6042 case VT_PTR:
6043 case VT_SAFEARRAY:
6044 pTypeDesc = pTypeDesc->u.lptdesc;
6045 break;
6046 case VT_CARRAY:
6047 pTypeDesc = &pTypeDesc->u.lpadesc->tdescElem;
6048 break;
6049 default:
6050 return;
6051 }
6052 }
6053}
6054
6055static inline void ITypeInfoImpl_FuncDescAddHrefOffset( LPFUNCDESC pFuncDesc, UINT hrefoffset)
6056{
6057 SHORT i;
6058 for (i = 0; i < pFuncDesc->cParams; i++)
6059 ITypeInfoImpl_ElemDescAddHrefOffset(&pFuncDesc->lprgelemdescParam[i], hrefoffset);
6060 ITypeInfoImpl_ElemDescAddHrefOffset(&pFuncDesc->elemdescFunc, hrefoffset);
6061}
6062
6063/* ITypeInfo::GetFuncDesc
6064 *
6065 * Retrieves the FUNCDESC structure that contains information about a
6066 * specified function.
6067 *
6068 */
6070 LPFUNCDESC *ppFuncDesc)
6071{
6073 const FUNCDESC *internal_funcdesc;
6074 HRESULT hr;
6075 UINT hrefoffset = 0;
6076
6077 TRACE("(%p) index %d\n", This, index);
6078
6079 if (!ppFuncDesc)
6080 return E_INVALIDARG;
6081
6082 if (This->needs_layout)
6083 ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface);
6084
6085 if (This->typeattr.typekind == TKIND_DISPATCH)
6087 &internal_funcdesc, NULL,
6088 &hrefoffset);
6089 else
6091 &internal_funcdesc);
6092 if (FAILED(hr))
6093 {
6094 WARN("description for function %d not found\n", index);
6095 return hr;
6096 }
6097
6099 internal_funcdesc,
6100 ppFuncDesc,
6101 This->typeattr.typekind == TKIND_DISPATCH);
6102
6103 if ((This->typeattr.typekind == TKIND_DISPATCH) && hrefoffset)
6104 ITypeInfoImpl_FuncDescAddHrefOffset(*ppFuncDesc, hrefoffset);
6105
6106 TRACE("-- 0x%08x\n", hr);
6107 return hr;
6108}
6109
6110static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
6111{
6112 VARDESC *dest;
6113 char *buffer;
6114 SIZE_T size = sizeof(*src);
6115 HRESULT hr;
6116
6117 if (src->lpstrSchema) size += (lstrlenW(src->lpstrSchema) + 1) * sizeof(WCHAR);
6118 if (src->varkind == VAR_CONST)
6119 size += sizeof(VARIANT);
6120 size += TLB_SizeElemDesc(&src->elemdescVar);
6121
6122 dest = (VARDESC *)SysAllocStringByteLen(NULL, size);
6123 if (!dest) return E_OUTOFMEMORY;
6124
6125 *dest = *src;
6126 buffer = (char *)(dest + 1);
6127 if (src->lpstrSchema)
6128 {
6129 int len;
6130 dest->lpstrSchema = (LPOLESTR)buffer;
6131 len = lstrlenW(src->lpstrSchema);
6132 memcpy(dest->lpstrSchema, src->lpstrSchema, (len + 1) * sizeof(WCHAR));
6133 buffer += (len + 1) * sizeof(WCHAR);
6134 }
6135
6136 if (src->varkind == VAR_CONST)
6137 {
6138 HRESULT hr;
6139
6140 dest->u.lpvarValue = (VARIANT *)buffer;
6141 *dest->u.lpvarValue = *src->u.lpvarValue;
6142 buffer += sizeof(VARIANT);
6143 VariantInit(dest->u.lpvarValue);
6144 hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue);
6145 if (FAILED(hr))
6146 {
6148 return hr;
6149 }
6150 }
6151 hr = TLB_CopyElemDesc(&src->elemdescVar, &dest->elemdescVar, &buffer);
6152 if (FAILED(hr))
6153 {
6154 if (src->varkind == VAR_CONST)
6155 VariantClear(dest->u.lpvarValue);
6157 return hr;
6158 }
6159 *dest_ptr = dest;
6160 return S_OK;
6161}
6162
6163/* ITypeInfo::GetVarDesc
6164 *
6165 * Retrieves a VARDESC structure that describes the specified variable.
6166 *
6167 */
6169 LPVARDESC *ppVarDesc)
6170{
6172 const TLBVarDesc *pVDesc = &This->vardescs[index];
6173
6174 TRACE("(%p) index %d\n", This, index);
6175
6176 if(index >= This->typeattr.cVars)
6178
6179 if (This->needs_layout)
6180 ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface);
6181
6182 return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc);
6183}
6184
6185/* ITypeInfo_GetNames
6186 *
6187 * Retrieves the variable with the specified member ID (or the name of the
6188 * property or method and its parameters) that correspond to the specified
6189 * function ID.
6190 */
6191static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
6192 BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
6193{
6195 const TLBFuncDesc *pFDesc;
6196 const TLBVarDesc *pVDesc;
6197 int i;
6198 TRACE("(%p) memid=0x%08x Maxname=%d\n", This, memid, cMaxNames);
6199
6200 if(!rgBstrNames)
6201 return E_INVALIDARG;
6202
6203 *pcNames = 0;
6204
6205 pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->typeattr.cFuncs, memid);
6206 if(pFDesc)
6207 {
6208 if(!cMaxNames || !pFDesc->Name)
6209 return S_OK;
6210
6211 *rgBstrNames = SysAllocString(TLB_get_bstr(pFDesc->Name));
6212 ++(*pcNames);
6213
6214 for(i = 0; i < pFDesc->funcdesc.cParams; ++i){
6215 if(*pcNames >= cMaxNames || !pFDesc->pParamDesc[i].Name)
6216 return S_OK;
6217 rgBstrNames[*pcNames] = SysAllocString(TLB_get_bstr(pFDesc->pParamDesc[i].Name));
6218 ++(*pcNames);
6219 }
6220 return S_OK;
6221 }
6222
6223 pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->typeattr.cVars, memid);
6224 if(pVDesc)
6225 {
6226 *rgBstrNames=SysAllocString(TLB_get_bstr(pVDesc->Name));
6227 *pcNames=1;
6228 }
6229 else
6230 {
6231 if(This->impltypes &&
6232 (This->typeattr.typekind == TKIND_INTERFACE || This->typeattr.typekind == TKIND_DISPATCH)) {
6233 /* recursive search */
6234 ITypeInfo *pTInfo;
6236 result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
6237 if(SUCCEEDED(result))
6238 {
6239 result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames);
6240 ITypeInfo_Release(pTInfo);
6241 return result;
6242 }
6243 WARN("Could not search inherited interface!\n");
6244 }
6245 else
6246 {
6247 WARN("no names found\n");
6248 }
6249 *pcNames=0;
6251 }
6252 return S_OK;
6253}
6254
6255
6256/* ITypeInfo::GetRefTypeOfImplType
6257 *
6258 * If a type description describes a COM class, it retrieves the type
6259 * description of the implemented interface types. For an interface,
6260 * GetRefTypeOfImplType returns the type information for inherited interfaces,
6261 * if any exist.
6262 *
6263 */
6265 ITypeInfo2 *iface,
6266 UINT index,
6267 HREFTYPE *pRefType)
6268{
6270 HRESULT hr = S_OK;
6271
6272 TRACE("(%p) index %d\n", This, index);
6273 if (TRACE_ON(ole)) dump_TypeInfo(This);
6274
6275 if(index==(UINT)-1)
6276 {
6277 /* only valid on dual interfaces;
6278 retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH
6279 */
6280
6281 if (This->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
6282 {
6283 *pRefType = -2;
6284 }
6285 else
6286 {
6288 }
6289 }
6290 else if(index == 0 && This->typeattr.typekind == TKIND_DISPATCH)
6291 {
6292 /* All TKIND_DISPATCHs are made to look like they inherit from IDispatch */
6293 *pRefType = This->pTypeLib->dispatch_href;
6294 }
6295 else
6296 {
6297 if(index >= This->typeattr.cImplTypes)
6299 else{
6300 *pRefType = This->impltypes[index].hRef;
6301 if (This->typeattr.typekind == TKIND_INTERFACE)
6302 *pRefType |= 0x2;
6303 }
6304 }
6305
6306 if(TRACE_ON(ole))
6307 {
6308 if(SUCCEEDED(hr))
6309 TRACE("SUCCESS -- hRef = 0x%08x\n", *pRefType );
6310 else
6311 TRACE("FAILURE -- hresult = 0x%08x\n", hr);
6312 }
6313
6314 return hr;
6315}
6316
6317/* ITypeInfo::GetImplTypeFlags
6318 *
6319 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
6320 * or base interface in a type description.
6321 */
6323 UINT index, INT *pImplTypeFlags)
6324{
6326
6327 TRACE("(%p) index %d\n", This, index);
6328
6329 if(!pImplTypeFlags)
6330 return E_INVALIDARG;
6331
6332 if(This->typeattr.typekind == TKIND_DISPATCH && index == 0){
6333 *pImplTypeFlags = 0;
6334 return S_OK;
6335 }
6336
6337 if(index >= This->typeattr.cImplTypes)
6339
6340 *pImplTypeFlags = This->impltypes[index].implflags;
6341
6342 return S_OK;
6343}
6344
6345/* GetIDsOfNames
6346 * Maps between member names and member IDs, and parameter names and
6347 * parameter IDs.
6348 */
6350 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
6351{
6353 const TLBVarDesc *pVDesc;
6355 UINT i, fdc;
6356
6357 TRACE("(%p) Name %s cNames %d\n", This, debugstr_w(*rgszNames),
6358 cNames);
6359
6360 /* init out parameters in case of failure */
6361 for (i = 0; i < cNames; i++)
6362 pMemId[i] = MEMBERID_NIL;
6363
6364 for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc) {
6365 int j;
6366 const TLBFuncDesc *pFDesc = &This->funcdescs[fdc];
6367 if(!lstrcmpiW(*rgszNames, TLB_get_bstr(pFDesc->Name))) {
6368 if(cNames) *pMemId=pFDesc->funcdesc.memid;
6369 for(i=1; i < cNames; i++){
6370 for(j=0; j<pFDesc->funcdesc.cParams; j++)
6371 if(!lstrcmpiW(rgszNames[i],TLB_get_bstr(pFDesc->pParamDesc[j].Name)))
6372 break;
6373 if( j<pFDesc->funcdesc.cParams)
6374 pMemId[i]=j;
6375 else
6377 };
6378 TRACE("-- 0x%08x\n", ret);
6379 return ret;
6380 }
6381 }
6382 pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->typeattr.cVars, *rgszNames);
6383 if(pVDesc){
6384 if(cNames)
6385 *pMemId = pVDesc->vardesc.memid;
6386 return ret;
6387 }
6388 /* not found, see if it can be found in an inherited interface */
6389 if(This->impltypes) {
6390 /* recursive search */
6391 ITypeInfo *pTInfo;
6392 ret = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
6393 if(SUCCEEDED(ret)){
6394 ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
6395 ITypeInfo_Release(pTInfo);
6396 return ret;
6397 }
6398 WARN("Could not search inherited interface!\n");
6399 } else
6400 WARN("no names found\n");
6401 return DISP_E_UNKNOWNNAME;
6402}
6403
6404
6405#ifdef __i386__
6406
6407extern LONGLONG call_method( void *func, int nb_args, const DWORD *args, int *stack_offset );
6408extern double call_double_method( void *func, int nb_args, const DWORD *args, int *stack_offset );
6409__ASM_GLOBAL_FUNC( call_method,
6410 "pushl %ebp\n\t"
6411 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
6412 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
6413 "movl %esp,%ebp\n\t"
6414 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
6415 "pushl %esi\n\t"
6416 __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
6417 "pushl %edi\n\t"
6418 __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
6419 "movl 12(%ebp),%edx\n\t"
6420 "movl %esp,%edi\n\t"
6421 "shll $2,%edx\n\t"
6422 "jz 1f\n\t"
6423 "subl %edx,%edi\n\t"
6424 "andl $~15,%edi\n\t"
6425 "movl %edi,%esp\n\t"
6426 "movl 12(%ebp),%ecx\n\t"
6427 "movl 16(%ebp),%esi\n\t"
6428 "cld\n\t"
6429 "rep; movsl\n"
6430 "1:\tcall *8(%ebp)\n\t"
6431 "subl %esp,%edi\n\t"
6432 "movl 20(%ebp),%ecx\n\t"
6433 "movl %edi,(%ecx)\n\t"
6434 "leal -8(%ebp),%esp\n\t"
6435 "popl %edi\n\t"
6436 __ASM_CFI(".cfi_same_value %edi\n\t")
6437 "popl %esi\n\t"
6438 __ASM_CFI(".cfi_same_value %esi\n\t")
6439 "popl %ebp\n\t"
6440 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
6441 __ASM_CFI(".cfi_same_value %ebp\n\t")
6442 "ret" )
6443__ASM_GLOBAL_FUNC( call_double_method,
6444 "jmp " __ASM_NAME("call_method") )
6445
6446HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
6447 UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
6448{
6449 int argspos = 0, stack_offset;
6450 void *func;
6451 UINT i;
6452 DWORD *args;
6453
6454 TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
6455 pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
6456 pvargResult, V_VT(pvargResult));
6457
6458 if (cc != CC_STDCALL && cc != CC_CDECL)
6459 {
6460 FIXME("unsupported calling convention %d\n",cc);
6461 return E_INVALIDARG;
6462 }
6463
6464 /* maximum size for an argument is sizeof(VARIANT) */
6465 args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );
6466
6467 if (pvInstance)
6468 {
6469 const FARPROC *vtable = *(FARPROC **)pvInstance;
6470 func = vtable[oVft/sizeof(void *)];
6471 args[argspos++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
6472 }
6473 else func = (void *)oVft;
6474
6475 switch (vtReturn)
6476 {
6477 case VT_DECIMAL:
6478 case VT_VARIANT:
6479 args[argspos++] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */
6480 break;
6481 case VT_HRESULT:
6482 WARN("invalid return type %u\n", vtReturn);
6483 heap_free( args );
6484 return E_INVALIDARG;
6485 default:
6486 break;
6487 }
6488
6489 for (i = 0; i < cActuals; i++)
6490 {
6491 VARIANT *arg = prgpvarg[i];
6492
6493 switch (prgvt[i])
6494 {
6495 case VT_EMPTY:
6496 break;
6497 case VT_I8:
6498 case VT_UI8:
6499 case VT_R8:
6500 case VT_DATE:
6501 case VT_CY:
6502 memcpy( &args[argspos], &V_I8(arg), sizeof(V_I8(arg)) );
6503 argspos += sizeof(V_I8(arg)) / sizeof(DWORD);
6504 break;
6505 case VT_DECIMAL:
6506 case VT_VARIANT:
6507 memcpy( &args[argspos], arg, sizeof(*arg) );
6508 argspos += sizeof(*arg) / sizeof(DWORD);
6509 break;
6510 case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
6511 args[argspos++] = V_BOOL(arg);
6512 break;
6513 default:
6514 args[argspos++] = V_UI4(arg);
6515 break;
6516 }
6517 TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
6518 }
6519
6520 switch (vtReturn)
6521 {
6522 case VT_EMPTY:
6523 case VT_DECIMAL:
6524 case VT_VARIANT:
6525 call_method( func, argspos, args, &stack_offset );
6526 break;
6527 case VT_R4:
6528 V_R4(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
6529 break;
6530 case VT_R8:
6531 case VT_DATE:
6532 V_R8(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
6533 break;
6534 case VT_I8:
6535 case VT_UI8:
6536 case VT_CY:
6537 V_UI8(pvargResult) = call_method( func, argspos, args, &stack_offset );
6538 break;
6539 default:
6540 V_UI4(pvargResult) = call_method( func, argspos, args, &stack_offset );
6541 break;
6542 }
6543 heap_free( args );
6544 if (stack_offset && cc == CC_STDCALL)
6545 {
6546 WARN( "stack pointer off by %d\n", stack_offset );
6547 return DISP_E_BADCALLEE;
6548 }
6549 if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
6550 TRACE("retval: %s\n", debugstr_variant(pvargResult));
6551 return S_OK;
6552}
6553
6554#elif defined(__x86_64__)
6555
6556extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args );
6557extern double CDECL call_double_method( void *func, int nb_args, const DWORD_PTR *args );
6558__ASM_GLOBAL_FUNC( call_method,
6559 "pushq %rbp\n\t"
6560 __ASM_SEH(".seh_pushreg %rbp\n\t")
6561 __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
6562 __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
6563 "movq %rsp,%rbp\n\t"
6564 __ASM_SEH(".seh_setframe %rbp,0\n\t")
6565 __ASM_CFI(".cfi_def_cfa_register %rbp\n\t")
6566 "pushq %rsi\n\t"
6567 __ASM_SEH(".seh_pushreg %rsi\n\t")
6568 __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t")
6569 "pushq %rdi\n\t"
6570 __ASM_SEH(".seh_pushreg %rdi\n\t")
6571 __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t")
6572 __ASM_SEH(".seh_endprologue\n\t")
6573 "movq %rcx,%rax\n\t"
6574 "movq $4,%rcx\n\t"
6575 "cmp %rcx,%rdx\n\t"
6576 "cmovgq %rdx,%rcx\n\t"
6577 "leaq 0(,%rcx,8),%rdx\n\t"
6578 "subq %rdx,%rsp\n\t"
6579 "andq $~15,%rsp\n\t"
6580 "movq %rsp,%rdi\n\t"
6581 "movq %r8,%rsi\n\t"
6582 "rep; movsq\n\t"
6583 "movq 0(%rsp),%rcx\n\t"
6584 "movq 8(%rsp),%rdx\n\t"
6585 "movq 16(%rsp),%r8\n\t"
6586 "movq 24(%rsp),%r9\n\t"
6587 "movq 0(%rsp),%xmm0\n\t"
6588 "movq 8(%rsp),%xmm1\n\t"
6589 "movq 16(%rsp),%xmm2\n\t"
6590 "movq 24(%rsp),%xmm3\n\t"
6591 "callq *%rax\n\t"
6592 "leaq -16(%rbp),%rsp\n\t"
6593 "popq %rdi\n\t"
6594 __ASM_CFI(".cfi_same_value %rdi\n\t")
6595 "popq %rsi\n\t"
6596 __ASM_CFI(".cfi_same_value %rsi\n\t")
6597 __ASM_CFI(".cfi_def_cfa_register %rsp\n\t")
6598 "popq %rbp\n\t"
6599 __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
6600 __ASM_CFI(".cfi_same_value %rbp\n\t")
6601 "ret")
6602__ASM_GLOBAL_FUNC( call_double_method,
6603 "jmp " __ASM_NAME("call_method") )
6604
6605HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
6606 UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
6607{
6608 int argspos = 0;
6609 UINT i;
6610 DWORD_PTR *args;
6611 void *func;
6612
6613 TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
6614 pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
6615 pvargResult, V_VT(pvargResult));
6616
6617 if (cc != CC_STDCALL && cc != CC_CDECL)
6618 {
6619 FIXME("unsupported calling convention %d\n",cc);
6620 return E_INVALIDARG;
6621 }
6622
6623 /* maximum size for an argument is sizeof(DWORD_PTR) */
6624 args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) );
6625
6626 if (pvInstance)
6627 {
6628 const FARPROC *vtable = *(FARPROC **)pvInstance;
6629 func = vtable[oVft/sizeof(void *)];
6630 args[argspos++] = (DWORD_PTR)pvInstance; /* the This pointer is always the first parameter */
6631 }
6632 else func = (void *)oVft;
6633
6634 switch (vtReturn)
6635 {
6636 case VT_DECIMAL:
6637 case VT_VARIANT:
6638 args[argspos++] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */
6639 break;
6640 case VT_HRESULT:
6641 WARN("invalid return type %u\n", vtReturn);
6642 heap_free( args );
6643 return E_INVALIDARG;
6644 default:
6645 break;
6646 }
6647
6648 for (i = 0; i < cActuals; i++)
6649 {
6650 VARIANT *arg = prgpvarg[i];
6651
6652 switch (prgvt[i])
6653 {
6654 case VT_DECIMAL:
6655 case VT_VARIANT:
6656 args[argspos++] = (ULONG_PTR)arg;
6657 break;
6658 case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
6659 args[argspos++] = V_BOOL(arg);
6660 break;
6661 default:
6662 args[argspos++] = V_UI8(arg);
6663 break;
6664 }
6665 TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
6666 }
6667
6668 switch (vtReturn)
6669 {
6670 case VT_R4:
6671 V_R4(pvargResult) = call_double_method( func, argspos, args );
6672 break;
6673 case VT_R8:
6674 case VT_DATE:
6675 V_R8(pvargResult) = call_double_method( func, argspos, args );
6676 break;
6677 case VT_DECIMAL:
6678 case VT_VARIANT:
6679 call_method( func, argspos, args );
6680 break;
6681 default:
6682 V_UI8(pvargResult) = call_method( func, argspos, args );
6683 break;
6684 }
6685 heap_free( args );
6686 if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
6687 TRACE("retval: %s\n", debugstr_variant(pvargResult));
6688 return S_OK;
6689}
6690
6691#elif defined(__arm__)
6692
6693extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
6694extern float CDECL call_float_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
6695extern double CDECL call_double_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
6696__ASM_GLOBAL_FUNC( call_method,
6697 /* r0 = *func
6698 * r1 = nb_stk_args
6699 * r2 = *stk_args (pointer to 'nb_stk_args' DWORD values to push on stack)
6700 * r3 = *reg_args (pointer to 8, 64-bit d0-d7 (double) values OR as 16, 32-bit s0-s15 (float) values, followed by 4, 32-bit (DWORD) r0-r3 values)
6701 */
6702
6703 "push {fp, lr}\n\t" /* Save frame pointer and return address (stack still aligned to 8 bytes) */
6704 "mov fp, sp\n\t" /* Save stack pointer as our frame for cleaning the stack on return */
6705
6706 "lsls r1, r1, #2\n\t" /* r1 = nb_stk_args * sizeof(DWORD) */
6707 "beq 1f\n\t" /* Skip allocation if no stack args */
6708 "add r2, r2, r1\n" /* Calculate ending address of incoming stack data */
6709 "2:\tldr ip, [r2, #-4]!\n\t" /* Get next value */
6710 "str ip, [sp, #-4]!\n\t" /* Push it on the stack */
6711 "subs r1, r1, #4\n\t" /* Decrement count */
6712 "bgt 2b\n\t" /* Loop till done */
6713
6714 "1:\n\t"
6715#ifndef __SOFTFP__
6716 "vldm r3!, {s0-s15}\n\t" /* Load the s0-s15/d0-d7 arguments */
6717#endif
6718 "mov ip, r0\n\t" /* Save the function call address to ip before we nuke r0 with arguments to pass */
6719 "ldm r3, {r0-r3}\n\t" /* Load the r0-r3 arguments */
6720
6721 "blx ip\n\t" /* Call the target function */
6722
6723 "mov sp, fp\n\t" /* Clean the stack using fp */
6724 "pop {fp, pc}\n\t" /* Restore fp and return */
6725 )
6726__ASM_GLOBAL_FUNC( call_float_method,
6727 "b " __ASM_NAME("call_method") )
6728__ASM_GLOBAL_FUNC( call_double_method,
6729 "b " __ASM_NAME("call_method") )
6730
6731HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
6732 UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
6733{
6734 int argspos;
6735 void *func;
6736 UINT i;
6737 DWORD *args;
6738 struct {
6739#ifndef __SOFTFP__
6740 union {
6741 float s[16];
6742 double d[8];
6743 } sd;
6744#endif
6745 DWORD r[4];
6746 } regs;
6747 int rcount; /* 32-bit register index count */
6748#ifndef __SOFTFP__
6749 int scount = 0; /* single-precision float register index count */
6750 int dcount = 0; /* double-precision float register index count */
6751#endif
6752
6753 TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
6754 pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
6755
6756 if (cc != CC_STDCALL && cc != CC_CDECL)
6757 {
6758 FIXME("unsupported calling convention %d\n",cc);
6759 return E_INVALIDARG;
6760 }
6761
6762 argspos = 0;
6763 rcount = 0;
6764
6765 if (pvInstance)
6766 {
6767 const FARPROC *vtable = *(FARPROC **)pvInstance;
6768 func = vtable[oVft/sizeof(void *)];
6769 regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
6770 }
6771 else func = (void *)oVft;
6772
6773 /* Determine if we need to pass a pointer for the return value as arg 0. If so, do that */
6774 /* first as it will need to be in the 'r' registers: */
6775 switch (vtReturn)
6776 {
6777 case VT_DECIMAL:
6778 case VT_VARIANT:
6779 regs.r[rcount++] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */
6780 break;
6781 case VT_HRESULT:
6782 WARN("invalid return type %u\n", vtReturn);
6783 return E_INVALIDARG;
6784 default: /* And all others are in 'r', 's', or 'd' registers or have no return value */
6785 break;
6786 }
6787
6788 /* maximum size for an argument is sizeof(VARIANT). Also allow for return pointer and stack alignment. */
6789 args = heap_alloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 4 );
6790
6791 for (i = 0; i < cActuals; i++)
6792 {
6793 VARIANT *arg = prgpvarg[i];
6794 DWORD *pdwarg = (DWORD *)(arg); /* a reinterpret_cast of the variant, used for copying structures when they are split between registers and stack */
6795 int ntemp; /* Used for counting words split between registers and stack */
6796
6797 switch (prgvt[i])
6798 {
6799 case VT_EMPTY:
6800 break;
6801 case VT_R8: /* these must be 8-byte aligned, and put in 'd' regs or stack, as they are double-floats */
6802 case VT_DATE:
6803#ifndef __SOFTFP__
6804 dcount = max( (scount + 1) / 2, dcount );
6805 if (dcount < 8)
6806 {
6807 regs.sd.d[dcount++] = V_R8(arg);
6808 }
6809 else
6810 {
6811 argspos += (argspos % 2); /* align argspos to 8-bytes */
6812 memcpy( &args[argspos], &V_R8(arg), sizeof(V_R8(arg)) );
6813 argspos += sizeof(V_R8(arg)) / sizeof(DWORD);
6814 }
6815 break;
6816#endif
6817 case VT_I8: /* these must be 8-byte aligned, and put in 'r' regs or stack, as they are long-longs */
6818 case VT_UI8:
6819 case VT_CY:
6820 if (rcount < 3)
6821 {
6822 rcount += (rcount % 2); /* align rcount to 8-byte register pair */
6823 memcpy( &regs.r[rcount], &V_UI8(arg), sizeof(V_UI8(arg)) );
6824 rcount += sizeof(V_UI8(arg)) / sizeof(DWORD);
6825 }
6826 else
6827 {
6828 rcount = 4; /* Make sure we flag that all 'r' regs are full */
6829 argspos += (argspos % 2); /* align argspos to 8-bytes */
6830 memcpy( &args[argspos], &V_UI8(arg), sizeof(V_UI8(arg)) );
6831 argspos += sizeof(V_UI8(arg)) / sizeof(DWORD);
6832 }
6833 break;
6834 case VT_DECIMAL: /* these structures are 8-byte aligned, and put in 'r' regs or stack, can be split between the two */
6835 case VT_VARIANT:
6836 /* 8-byte align 'r' and/or stack: */
6837 if (rcount < 3)
6838 rcount += (rcount % 2);
6839 else
6840 {
6841 rcount = 4;
6842 argspos += (argspos % 2);
6843 }
6844 ntemp = sizeof(*arg) / sizeof(DWORD);
6845 while (ntemp > 0)
6846 {
6847 if (rcount < 4)
6848 regs.r[rcount++] = *pdwarg++;
6849 else
6850 args[argspos++] = *pdwarg++;
6851 --ntemp;
6852 }
6853 break;
6854 case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
6855 if (rcount < 4)
6856 regs.r[rcount++] = V_BOOL(arg);
6857 else
6858 args[argspos++] = V_BOOL(arg);
6859 break;
6860 case VT_R4: /* these must be 4-byte aligned, and put in 's' regs or stack, as they are single-floats */
6861#ifndef __SOFTFP__
6862 if (!(scount % 2)) scount = max( scount, dcount * 2 );
6863 if (scount < 16)
6864 regs.sd.s[scount++] = V_R4(arg);
6865 else
6866 args[argspos++] = V_UI4(arg);
6867 break;
6868#endif
6869 default:
6870 if (rcount < 4)
6871 regs.r[rcount++] = V_UI4(arg);
6872 else
6873 args[argspos++] = V_UI4(arg);
6874 break;
6875 }
6876 TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
6877 }
6878
6879 argspos += (argspos % 2); /* Make sure stack function alignment is 8-byte */
6880
6881 switch (vtReturn)
6882 {
6883 case VT_EMPTY: /* EMPTY = no return value */
6884 case VT_DECIMAL: /* DECIMAL and VARIANT already have a pointer argument passed (see above) */
6885 case VT_VARIANT:
6886 call_method( func, argspos, args, (DWORD*)&regs );
6887 break;
6888 case VT_R4:
6889 V_R4(pvargResult) = call_float_method( func, argspos, args, (DWORD*)&regs );
6890 break;
6891 case VT_R8:
6892 case VT_DATE:
6893 V_R8(pvargResult) = call_double_method( func, argspos, args, (DWORD*)&regs );
6894 break;
6895 case VT_I8:
6896 case VT_UI8:
6897 case VT_CY:
6898 V_UI8(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
6899 break;
6900 default:
6901 V_UI4(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
6902 break;
6903 }
6904 heap_free( args );
6905 if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
6906 TRACE("retval: %s\n", debugstr_variant(pvargResult));
6907 return S_OK;
6908}
6909
6910#elif defined(__aarch64__)
6911
6912extern DWORD_PTR CDECL call_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
6913extern float CDECL call_float_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
6914extern double CDECL call_double_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
6915__ASM_GLOBAL_FUNC( call_method,
6916 "stp x29, x30, [sp, #-16]!\n\t"
6917 "mov x29, sp\n\t"
6918 "sub sp, sp, x1, lsl #3\n\t"
6919 "cbz x1, 2f\n"
6920 "1:\tsub x1, x1, #1\n\t"
6921 "ldr x4, [x2, x1, lsl #3]\n\t"
6922 "str x4, [sp, x1, lsl #3]\n\t"
6923 "cbnz x1, 1b\n"
6924 "2:\tmov x16, x0\n\t"
6925 "mov x9, x3\n\t"
6926 "ldp d0, d1, [x9]\n\t"
6927 "ldp d2, d3, [x9, #0x10]\n\t"
6928 "ldp d4, d5, [x9, #0x20]\n\t"
6929 "ldp d6, d7, [x9, #0x30]\n\t"
6930 "ldp x0, x1, [x9, #0x40]\n\t"
6931 "ldp x2, x3, [x9, #0x50]\n\t"
6932 "ldp x4, x5, [x9, #0x60]\n\t"
6933 "ldp x6, x7, [x9, #0x70]\n\t"
6934 "ldr x8, [x9, #0x80]\n\t"
6935 "blr x16\n\t"
6936 "mov sp, x29\n\t"
6937 "ldp x29, x30, [sp], #16\n\t"
6938 "ret" )
6939__ASM_GLOBAL_FUNC( call_float_method,
6940 "b " __ASM_NAME("call_method") )
6941__ASM_GLOBAL_FUNC( call_double_method,
6942 "b " __ASM_NAME("call_method") )
6943
6944HRESULT WINAPI DispCallFunc( void *instance, ULONG_PTR offset, CALLCONV cc, VARTYPE ret_type, UINT count,
6945 VARTYPE *types, VARIANTARG **vargs, VARIANT *result )
6946{
6947 int argspos;
6948 void *func;
6949 UINT i;
6950 DWORD_PTR *args;
6951 struct
6952 {
6953 union
6954 {
6955 float f;
6956 double d;
6957 } fp[8];
6958 DWORD_PTR x[9];
6959 } regs;
6960 int rcount; /* 64-bit register index count */
6961 int fpcount = 0; /* float register index count */
6962
6963 TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
6964 instance, offset, cc, ret_type, count, types, vargs, result, V_VT(result));
6965
6966 if (cc != CC_STDCALL && cc != CC_CDECL)
6967 {
6968 FIXME("unsupported calling convention %d\n",cc);
6969 return E_INVALIDARG;
6970 }
6971
6972 argspos = 0;
6973 rcount = 0;
6974
6975 if (instance)
6976 {
6977 const FARPROC *vtable = *(FARPROC **)instance;
6978 func = vtable[offset/sizeof(void *)];
6979 regs.x[rcount++] = (DWORD_PTR)instance; /* the This pointer is always the first parameter */
6980 }
6981 else func = (void *)offset;
6982
6983 /* Determine if we need to pass a pointer for the return value as arg 0. If so, do that */
6984 /* first as it will need to be in the 'x' registers: */
6985 switch (ret_type)
6986 {
6987 case VT_DECIMAL:
6988 case VT_VARIANT:
6989 regs.x[8] = (DWORD_PTR)result; /* x8 is a pointer to the result */
6990 break;
6991 case VT_HRESULT:
6992 WARN("invalid return type %u\n", ret_type);
6993 return E_INVALIDARG;
6994 default:
6995 break;
6996 }
6997
6998 /* maximum size for an argument is sizeof(VARIANT). Also allow for return pointer and stack alignment. */
6999 args = heap_alloc( sizeof(VARIANT) * count + sizeof(DWORD_PTR) * 4 );
7000
7001 for (i = 0; i < count; i++)
7002 {
7003 VARIANT *arg = vargs[i];
7004
7005 switch (types[i])
7006 {
7007 case VT_EMPTY:
7008 break;
7009 case VT_R4:
7010 if (fpcount < 8) regs.fp[fpcount++].f = V_R4(arg);
7011 else *(float *)&args[argspos++] = V_R4(arg);
7012 break;
7013 case VT_R8:
7014 case VT_DATE:
7015 if (fpcount < 8) regs.fp[fpcount++].d = V_R8(arg);
7016 else *(double *)&args[argspos++] = V_R8(arg);
7017 break;
7018 case VT_DECIMAL:
7019 case VT_VARIANT:
7020 if (rcount < 7)
7021 {
7022 memcpy( &regs.x[rcount], arg, sizeof(*arg) );
7023 rcount += 2;
7024 }
7025 else
7026 {
7027 memcpy( &args[argspos], arg, sizeof(*arg) );
7028 argspos += 2;
7029 }
7030 break;
7031 case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
7032 if (rcount < 8) regs.x[rcount++] = V_BOOL(arg);
7033 else args[argspos++] = V_BOOL(arg);
7034 break;
7035 default:
7036 if (rcount < 8) regs.x[rcount++] = V_UI8(arg);
7037 else args[argspos++] = V_UI8(arg);
7038 break;
7039 }
7040 TRACE("arg %u: type %s %s\n", i, debugstr_vt(types[i]), debugstr_variant(arg));
7041 }
7042
7043 argspos += (argspos % 2); /* Make sure stack function alignment is 16-byte */
7044
7045 switch (ret_type)
7046 {
7047 case VT_EMPTY: /* EMPTY = no return value */
7048 case VT_DECIMAL: /* DECIMAL and VARIANT already have a pointer argument passed (see above) */
7049 case VT_VARIANT:
7050 call_method( func, argspos, args, (DWORD_PTR *)&regs );
7051 break;
7052 case VT_R4:
7053 V_R4(result) = call_float_method( func, argspos, args, (DWORD_PTR *)&regs );
7054 break;
7055 case VT_R8:
7056 case VT_DATE:
7057 V_R8(result) = call_double_method( func, argspos, args, (DWORD_PTR *)&regs );
7058 break;
7059 default:
7060 V_UI8(result) = call_method( func, argspos, args, (DWORD_PTR *)&regs );
7061 break;
7062 }
7063 heap_free( args );
7064 if (ret_type != VT_VARIANT) V_VT(result) = ret_type;
7065 TRACE("retval: %s\n", debugstr_variant(result));
7066 return S_OK;
7067}
7068
7069#else /* __aarch64__ */
7070
7071HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
7072 UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
7073{
7074 FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
7075 pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
7076 return E_NOTIMPL;
7077}
7078
7079#endif
7080
7081static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
7082{
7083 HRESULT hr = S_OK;
7084 ITypeInfo *tinfo2 = NULL;
7085 TYPEATTR *tattr = NULL;
7086
7087 hr = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
7088 if (hr)
7089 {
7090 ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED, "
7091 "hr = 0x%08x\n",
7092 tdesc->u.hreftype, hr);
7093 return hr;
7094 }
7095 hr = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
7096 if (hr)
7097 {
7098 ERR("ITypeInfo_GetTypeAttr failed, hr = 0x%08x\n", hr);
7099 ITypeInfo_Release(tinfo2);
7100 return hr;
7101 }
7102
7103 switch (tattr->typekind)
7104 {
7105 case TKIND_ENUM:
7106 *vt |= VT_I4;
7107 break;
7108
7109 case TKIND_ALIAS:
7110 hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
7111 break;
7112
7113 case TKIND_INTERFACE:
7114 if (tattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
7115 *vt |= VT_DISPATCH;
7116 else
7117 *vt |= VT_UNKNOWN;
7118 break;
7119
7120 case TKIND_DISPATCH:
7121 *vt |= VT_DISPATCH;
7122 break;
7123
7124 case TKIND_COCLASS:
7125 *vt |= VT_DISPATCH;
7126 break;
7127
7128 case TKIND_RECORD:
7129 FIXME("TKIND_RECORD unhandled.\n");
7130 hr = E_NOTIMPL;
7131 break;
7132
7133 case TKIND_UNION:
7134 FIXME("TKIND_UNION unhandled.\n");
7135 hr = E_NOTIMPL;
7136 break;
7137
7138 default:
7139 FIXME("TKIND %d unhandled.\n",tattr->typekind);
7140 hr = E_NOTIMPL;
7141 break;
7142 }
7143 ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
7144 ITypeInfo_Release(tinfo2);
7145 return hr;
7146}
7147
7148static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
7149{
7150 HRESULT hr = S_OK;
7151
7152 /* enforce only one level of pointer indirection */
7153 if (!(*vt & VT_BYREF) && !(*vt & VT_ARRAY) && (tdesc->vt == VT_PTR))
7154 {
7155 tdesc = tdesc->u.lptdesc;
7156
7157 /* munch VT_PTR -> VT_USERDEFINED(interface) into VT_UNKNOWN or
7158 * VT_DISPATCH and VT_PTR -> VT_PTR -> VT_USERDEFINED(interface) into
7159 * VT_BYREF|VT_DISPATCH or VT_BYREF|VT_UNKNOWN */
7160 if ((tdesc->vt == VT_USERDEFINED) ||
7161 ((tdesc->vt == VT_PTR) && (tdesc->u.lptdesc->vt == VT_USERDEFINED)))
7162 {
7163 VARTYPE vt_userdefined = 0;
7164 const TYPEDESC *tdesc_userdefined = tdesc;
7165 if (tdesc->vt == VT_PTR)
7166 {
7167 vt_userdefined = VT_BYREF;
7168 tdesc_userdefined = tdesc->u.lptdesc;
7169 }
7170 hr = userdefined_to_variantvt(tinfo, tdesc_userdefined, &vt_userdefined);
7171 if ((hr == S_OK) &&
7172 (((vt_userdefined & VT_TYPEMASK) == VT_UNKNOWN) ||
7173 ((vt_userdefined & VT_TYPEMASK) == VT_DISPATCH)))
7174 {
7175 *vt |= vt_userdefined;
7176 return S_OK;
7177 }
7178 }
7179 *vt = VT_BYREF;
7180 }
7181
7182 switch (tdesc->vt)
7183 {
7184 case VT_HRESULT:
7185 *vt |= VT_ERROR;
7186 break;
7187 case VT_USERDEFINED:
7188 hr = userdefined_to_variantvt(tinfo, tdesc, vt);
7189 break;
7190 case VT_VOID:
7191 case VT_CARRAY:
7192 case VT_PTR:
7193 case VT_LPSTR:
7194 case VT_LPWSTR:
7195 ERR("cannot convert type %d into variant VT\n", tdesc->vt);
7197 break;
7198 case VT_SAFEARRAY:
7199 *vt |= VT_ARRAY;
7200 hr = typedescvt_to_variantvt(tinfo, tdesc->u.lptdesc, vt);
7201 break;
7202 case VT_INT:
7203 *vt |= VT_I4;
7204 break;
7205 case VT_UINT:
7206 *vt |= VT_UI4;
7207 break;
7208 default:
7209 *vt |= tdesc->vt;
7210 break;
7211 }
7212 return hr;
7213}
7214
7215static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
7216{
7217 ITypeInfo *tinfo2;
7218 TYPEATTR *tattr;
7219 HRESULT hres;
7220 int flags, i;
7221
7222 hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
7223 if(FAILED(hres))
7224 return hres;
7225
7226 hres = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
7227 if(FAILED(hres)) {
7228 ITypeInfo_Release(tinfo2);
7229 return hres;
7230 }
7231
7232 switch(tattr->typekind) {
7233 case TKIND_ALIAS:
7234 hres = get_iface_guid(tinfo2, tattr->tdescAlias.u.hreftype, guid);
7235 break;
7236
7237 case TKIND_INTERFACE:
7238 case TKIND_DISPATCH:
7239 *guid = tattr->guid;
7240 break;
7241
7242 case TKIND_COCLASS:
7243 for (i = 0; i < tattr->cImplTypes; i++)
7244 {
7245 ITypeInfo_GetImplTypeFlags(tinfo2, i, &flags);
7246 if (flags & IMPLTYPEFLAG_FDEFAULT)
7247 break;
7248 }
7249
7250 if (i == tattr->cImplTypes)
7251 i = 0;
7252
7253 hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href);
7254 if (SUCCEEDED(hres))
7255 hres = get_iface_guid(tinfo2, href, guid);
7256 break;
7257
7258 default:
7259 ERR("Unexpected typekind %d\n", tattr->typekind);
7261 }
7262
7263 ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
7264 ITypeInfo_Release(tinfo2);
7265 return hres;
7266}
7267
7268static inline BOOL func_restricted( const FUNCDESC *desc )
7269{
7270 return (desc->wFuncFlags & FUNCFLAG_FRESTRICTED) && (desc->memid >= 0);
7271}
7272
7273#define INVBUF_ELEMENT_SIZE \
7274 (sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *) + sizeof(VARTYPE))
7275#define INVBUF_GET_ARG_ARRAY(buffer, params) (buffer)
7276#define INVBUF_GET_MISSING_ARG_ARRAY(buffer, params) \
7277 ((VARIANTARG *)((char *)(buffer) + sizeof(VARIANTARG) * (params)))
7278#define INVBUF_GET_ARG_PTR_ARRAY(buffer, params) \
7279 ((VARIANTARG **)((char *)(buffer) + (sizeof(VARIANTARG) + sizeof(VARIANTARG)) * (params)))
7280#define INVBUF_GET_ARG_TYPE_ARRAY(buffer, params) \
7281 ((VARTYPE *)((char *)(buffer) + (sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *)) * (params)))
7282
7284 ITypeInfo2 *iface,
7285 VOID *pIUnk,
7286 MEMBERID memid,
7287 UINT16 wFlags,
7288 DISPPARAMS *pDispParams,
7289 VARIANT *pVarResult,
7290 EXCEPINFO *pExcepInfo,
7291 UINT *pArgErr)
7292{
7294 int i;
7295 unsigned int var_index;
7296 TYPEKIND type_kind;
7297 HRESULT hres;
7298 const TLBFuncDesc *pFuncInfo;
7299 UINT fdc;
7300
7301 TRACE("(%p)(%p,id=%d,flags=0x%08x,%p,%p,%p,%p)\n",
7302 This,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr
7303 );
7304
7305 if( This->typeattr.wTypeFlags & TYPEFLAG_FRESTRICTED )
7306 return DISP_E_MEMBERNOTFOUND;
7307
7308 if (!pDispParams)
7309 {
7310 ERR("NULL pDispParams not allowed\n");
7311 return E_INVALIDARG;
7312 }
7313
7314 dump_DispParms(pDispParams);
7315
7316 if (pDispParams->cNamedArgs > pDispParams->cArgs)
7317 {
7318 ERR("named argument array cannot be bigger than argument array (%d/%d)\n",
7319 pDispParams->cNamedArgs, pDispParams->cArgs);
7320 return E_INVALIDARG;
7321 }
7322
7323 /* we do this instead of using GetFuncDesc since it will return a fake
7324 * FUNCDESC for dispinterfaces and we want the real function description */
7325 for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
7326 pFuncInfo = &This->funcdescs[fdc];
7327 if ((memid == pFuncInfo->funcdesc.memid) &&
7328 (wFlags & pFuncInfo->funcdesc.invkind) &&
7329 !func_restricted( &pFuncInfo->funcdesc ))
7330 break;
7331 }
7332
7333 if (fdc < This->typeattr.cFuncs) {
7334 const FUNCDESC *func_desc = &pFuncInfo->funcdesc;
7335
7336 if (TRACE_ON(ole))
7337 {
7338 TRACE("invoking:\n");
7339 dump_TLBFuncDescOne(pFuncInfo);
7340 }
7341
7342 switch (func_desc->funckind) {
7343 case FUNC_PUREVIRTUAL:
7344 case FUNC_VIRTUAL: {
7345 void *buffer = heap_alloc_zero(INVBUF_ELEMENT_SIZE * func_desc->cParams);
7346 VARIANT varresult;
7347 VARIANT retval; /* pointer for storing byref retvals in */
7348 VARIANTARG **prgpvarg = INVBUF_GET_ARG_PTR_ARRAY(buffer, func_desc->cParams);
7349 VARIANTARG *rgvarg = INVBUF_GET_ARG_ARRAY(buffer, func_desc->cParams);
7350 VARTYPE *rgvt = INVBUF_GET_ARG_TYPE_ARRAY(buffer, func_desc->cParams);
7351 UINT cNamedArgs = pDispParams->cNamedArgs;
7352 DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs;
7353 UINT vargs_converted=0;
7354
7355 hres = S_OK;
7356
7357 if (func_desc->invkind & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF))
7358 {
7359 if (!cNamedArgs || (rgdispidNamedArgs[0] != DISPID_PROPERTYPUT))
7360 {
7361 ERR("first named arg for property put invocation must be DISPID_PROPERTYPUT\n");
7363 goto func_fail;
7364 }
7365 }
7366
7367 if (func_desc->cParamsOpt < 0 && cNamedArgs)
7368 {
7369 ERR("functions with the vararg attribute do not support named arguments\n");
7371 goto func_fail;
7372 }
7373
7374 for (i = 0; i < func_desc->cParams; i++)
7375 {
7376 TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
7377 hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc, &rgvt[i]);
7378 if (FAILED(hres))
7379 goto func_fail;
7380 }
7381
7382 TRACE("changing args\n");
7383 for (i = 0; i < func_desc->cParams; i++)
7384 {
7385 USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
7386 TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
7387 VARIANTARG *src_arg;
7388
7389 if (wParamFlags & PARAMFLAG_FLCID)
7390 {
7391 VARIANTARG *arg;
7392 arg = prgpvarg[i] = &rgvarg[i];
7393 V_VT(arg) = VT_I4;
7394 V_I4(arg) = This->pTypeLib->lcid;
7395 continue;
7396 }
7397
7398 src_arg = NULL;
7399
7400 if (cNamedArgs)
7401 {
7402 USHORT j;
7403 for (j = 0; j < cNamedArgs; j++)
7404 if (rgdispidNamedArgs[j] == i || (i == func_desc->cParams-1 && rgdispidNamedArgs[j] == DISPID_PROPERTYPUT))
7405 {
7406 src_arg = &pDispParams->rgvarg[j];
7407 break;
7408 }
7409 }
7410
7411 if (!src_arg && vargs_converted + cNamedArgs < pDispParams->cArgs)
7412 {
7413 src_arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
7414 vargs_converted++;
7415 }
7416
7417 if (wParamFlags & PARAMFLAG_FRETVAL)
7418 {
7419 /* under most conditions the caller is not allowed to
7420 * pass in a dispparam arg in the index of what would be
7421 * the retval parameter. however, there is an exception
7422 * where the extra parameter is used in an extra
7423 * IDispatch::Invoke below */
7424 if ((i < pDispParams->cArgs) &&
7425 ((func_desc->cParams != 1) || !pVarResult ||
7426 !(func_desc->invkind & INVOKE_PROPERTYGET)))
7427 {
7429 break;
7430 }
7431
7432 /* note: this check is placed so that if the caller passes
7433 * in a VARIANTARG for the retval we just ignore it, like
7434 * native does */
7435 if (i == func_desc->cParams - 1)
7436 {
7437 VARIANTARG *arg;
7438 arg = prgpvarg[i] = &rgvarg[i];
7439 memset(arg, 0, sizeof(*arg));
7440 V_VT(arg) = rgvt[i];
7441 memset(&retval, 0, sizeof(retval));
7442 V_BYREF(arg) = &retval;
7443 }
7444 else
7445 {
7446 ERR("[retval] parameter must be the last parameter of the method (%d/%d)\n", i, func_desc->cParams);
7448 break;
7449 }
7450 }
7451 else if (src_arg && !((wParamFlags & PARAMFLAG_FOPT) &&
7452 V_VT(src_arg) == VT_ERROR && V_ERROR(src_arg) == DISP_E_PARAMNOTFOUND))
7453 {
7454 TRACE("%s\n", debugstr_variant(src_arg));
7455
7456 if(rgvt[i]!=V_VT(src_arg))
7457 {
7458 if (rgvt[i] == VT_VARIANT)
7459 hres = VariantCopy(&rgvarg[i], src_arg);
7460 else if (rgvt[i] == (VT_VARIANT | VT_BYREF))
7461 {
7462 if (rgvt[i] == V_VT(src_arg))
7463 V_VARIANTREF(&rgvarg[i]) = V_VARIANTREF(src_arg);
7464 else
7465 {
7466 VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
7467 if (wParamFlags & PARAMFLAG_FIN)
7468 hres = VariantCopy(&missing_arg[i], src_arg);
7469 V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
7470 }
7471 V_VT(&rgvarg[i]) = rgvt[i];
7472 }
7473 else if ((rgvt[i] == (VT_VARIANT | VT_ARRAY) || rgvt[i] == (VT_VARIANT | VT_ARRAY | VT_BYREF)) && func_desc->cParamsOpt < 0)
7474 {
7475 SAFEARRAY *a;
7476 SAFEARRAYBOUND bound;
7477 VARIANT *v;
7478 LONG j;
7479 bound.lLbound = 0;
7480 bound.cElements = pDispParams->cArgs-i;
7481 if (!(a = SafeArrayCreate(VT_VARIANT, 1, &bound)))
7482 {
7483 ERR("SafeArrayCreate failed\n");
7484 break;
7485 }
7487 if (hres != S_OK)
7488 {
7489 ERR("SafeArrayAccessData failed with %x\n", hres);
7491 break;
7492 }
7493 for (j = 0; j < bound.cElements; j++)
7494 VariantCopy(&v[j], &pDispParams->rgvarg[pDispParams->cArgs - 1 - i - j]);
7496 if (hres != S_OK)
7497 {
7498 ERR("SafeArrayUnaccessData failed with %x\n", hres);
7500 break;
7501 }
7502 if (rgvt[i] & VT_BYREF)
7503 V_BYREF(&rgvarg[i]) = &a;
7504 else
7505 V_ARRAY(&rgvarg[i]) = a;
7506 V_VT(&rgvarg[i]) = rgvt[i];
7507 }
7508 else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
7509 {
7510 VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
7511 if (wParamFlags & PARAMFLAG_FIN)
7512 hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
7513 else
7514 V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF;
7515 V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
7516 V_VT(&rgvarg[i]) = rgvt[i];
7517 }
7518 else if ((rgvt[i] & VT_BYREF) && (rgvt[i] == V_VT(src_arg)))
7519 {
7520 V_BYREF(&rgvarg[i]) = V_BYREF(src_arg);
7521 V_VT(&rgvarg[i]) = rgvt[i];
7522 }
7523 else
7524 {
7525 /* FIXME: this doesn't work for VT_BYREF arguments if
7526 * they are not the same type as in the paramdesc */
7527 V_VT(&rgvarg[i]) = V_VT(src_arg);
7528 hres = VariantChangeType(&rgvarg[i], src_arg, 0, rgvt[i]);
7529 V_VT(&rgvarg[i]) = rgvt[i];
7530 }
7531
7532 if (FAILED(hres))
7533 {
7534 ERR("failed to convert param %d to %s from %s\n", i,
7535 debugstr_vt(rgvt[i]), debugstr_variant(src_arg));
7536 break;
7537 }
7538 prgpvarg[i] = &rgvarg[i];
7539 }
7540 else
7541 {
7542 prgpvarg[i] = src_arg;
7543 }
7544
7545 if((tdesc->vt == VT_USERDEFINED || (tdesc->vt == VT_PTR && tdesc->u.lptdesc->vt == VT_USERDEFINED))
7546 && (V_VT(prgpvarg[i]) == VT_DISPATCH || V_VT(prgpvarg[i]) == VT_UNKNOWN)
7547 && V_UNKNOWN(prgpvarg[i])) {
7548 IUnknown *userdefined_iface;
7549 GUID guid;
7550
7551 if (tdesc->vt == VT_PTR)
7552 tdesc = tdesc->u.lptdesc;
7553
7554 hres = get_iface_guid((ITypeInfo*)iface, tdesc->u.hreftype, &guid);
7555 if(FAILED(hres))
7556 break;
7557
7558 hres = IUnknown_QueryInterface(V_UNKNOWN(prgpvarg[i]), &guid, (void**)&userdefined_iface);
7559 if(FAILED(hres)) {
7560 ERR("argument does not support %s interface\n", debugstr_guid(&guid));
7561 break;
7562 }
7563
7564 IUnknown_Release(V_UNKNOWN(prgpvarg[i]));
7565 V_UNKNOWN(prgpvarg[i]) = userdefined_iface;
7566 }
7567 }
7568 else if (wParamFlags & PARAMFLAG_FOPT)
7569 {
7570 VARIANTARG *arg;
7571 arg = prgpvarg[i] = &rgvarg[i];
7572 if (wParamFlags & PARAMFLAG_FHASDEFAULT)
7573 {
7574 hres = VariantCopy(arg, &func_desc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
7575 if (FAILED(hres))
7576 break;
7577 }
7578 else
7579 {
7580 VARIANTARG *missing_arg;
7581 /* if the function wants a pointer to a variant then
7582 * set that up, otherwise just pass the VT_ERROR in
7583 * the argument by value */
7584 if (rgvt[i] & VT_BYREF)
7585 {
7586 missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams) + i;
7588 V_VARIANTREF(arg) = missing_arg;
7589 }
7590 else
7591 missing_arg = arg;
7592 V_VT(missing_arg) = VT_ERROR;
7593 V_ERROR(missing_arg) = DISP_E_PARAMNOTFOUND;
7594 }
7595 }
7596 else
7597 {
7599 break;
7600 }
7601 }
7602 if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
7603
7604 /* VT_VOID is a special case for return types, so it is not
7605 * handled in the general function */
7606 if (func_desc->elemdescFunc.tdesc.vt == VT_VOID)
7607 V_VT(&varresult) = VT_EMPTY;
7608 else
7609 {
7610 V_VT(&varresult) = 0;
7611 hres = typedescvt_to_variantvt((ITypeInfo *)iface, &func_desc->elemdescFunc.tdesc, &V_VT(&varresult));
7612 if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
7613 }
7614
7615 hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, func_desc->callconv,
7616 V_VT(&varresult), func_desc->cParams, rgvt,
7617 prgpvarg, &varresult);
7618
7619 vargs_converted = 0;
7620
7621 for (i = 0; i < func_desc->cParams; i++)
7622 {
7623 USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
7624 VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
7625
7626 if (wParamFlags & PARAMFLAG_FLCID)
7627 continue;
7628 else if (wParamFlags & PARAMFLAG_FRETVAL)
7629 {
7630 TRACE("[retval] value: %s\n", debugstr_variant(prgpvarg[i]));
7631
7632 if (pVarResult)
7633 {
7634 VariantInit(pVarResult);
7635 /* deref return value */
7636 hres = VariantCopyInd(pVarResult, prgpvarg[i]);
7637 }
7638
7639 VARIANT_ClearInd(prgpvarg[i]);
7640 }
7641 else if (vargs_converted < pDispParams->cArgs)
7642 {
7643 VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
7644 if (wParamFlags & PARAMFLAG_FOUT)
7645 {
7646 if ((rgvt[i] & VT_BYREF) && !(V_VT(arg) & VT_BYREF))
7647 {
7648 hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg));
7649
7650 if (FAILED(hres))
7651 {
7652 ERR("failed to convert param %d to vt %d\n", i,
7653 V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
7654 break;
7655 }
7656 }
7657 }
7658 else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
7659 func_desc->cParamsOpt < 0 &&
7660 i == func_desc->cParams-1)
7661 {
7662 SAFEARRAY *a = V_ARRAY(prgpvarg[i]);
7663 LONG j, ubound;
7664 VARIANT *v;
7665 hres = SafeArrayGetUBound(a, 1, &ubound);
7666 if (hres != S_OK)
7667 {
7668 ERR("SafeArrayGetUBound failed with %x\n", hres);
7669 break;
7670 }
7672 if (hres != S_OK)
7673 {
7674 ERR("SafeArrayAccessData failed with %x\n", hres);
7675 break;
7676 }
7677 for (j = 0; j <= ubound; j++)
7678 VariantClear(&v[j]);
7680 if (hres != S_OK)
7681 {
7682 ERR("SafeArrayUnaccessData failed with %x\n", hres);
7683 break;
7684 }
7685 }
7686 VariantClear(&rgvarg[i]);
7687 vargs_converted++;
7688 }
7689 else if (wParamFlags & PARAMFLAG_FOPT)
7690 {
7691 if (wParamFlags & PARAMFLAG_FHASDEFAULT)
7692 VariantClear(&rgvarg[i]);
7693 }
7694
7695 VariantClear(&missing_arg[i]);
7696 }
7697
7698 if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
7699 {
7700 WARN("invoked function failed with error 0x%08x\n", V_ERROR(&varresult));
7702 if (pExcepInfo)
7703 {
7704 IErrorInfo *pErrorInfo;
7705 pExcepInfo->scode = V_ERROR(&varresult);
7706 if (GetErrorInfo(0, &pErrorInfo) == S_OK)
7707 {
7708 IErrorInfo_GetDescription(pErrorInfo, &pExcepInfo->bstrDescription);
7709 IErrorInfo_GetHelpFile(pErrorInfo, &pExcepInfo->bstrHelpFile);
7710 IErrorInfo_GetSource(pErrorInfo, &pExcepInfo->bstrSource);
7711 IErrorInfo_GetHelpContext(pErrorInfo, &pExcepInfo->dwHelpContext);
7712
7713 IErrorInfo_Release(pErrorInfo);
7714 }
7715 }
7716 }
7717 if (V_VT(&varresult) != VT_ERROR)
7718 {
7719 TRACE("varresult value: %s\n", debugstr_variant(&varresult));
7720
7721 if (pVarResult)
7722 {
7723 VariantClear(pVarResult);
7724 *pVarResult = varresult;
7725 }
7726 else
7727 VariantClear(&varresult);
7728 }
7729
7730 if (SUCCEEDED(hres) && pVarResult && (func_desc->cParams == 1) &&
7731 (func_desc->invkind & INVOKE_PROPERTYGET) &&
7732 (func_desc->lprgelemdescParam[0].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL) &&
7733 (pDispParams->cArgs != 0))
7734 {
7735 if (V_VT(pVarResult) == VT_DISPATCH)
7736 {
7737 IDispatch *pDispatch = V_DISPATCH(pVarResult);
7738 /* Note: not VariantClear; we still need the dispatch
7739 * pointer to be valid */
7740 VariantInit(pVarResult);
7741 hres = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL,
7743 pDispParams, pVarResult, pExcepInfo, pArgErr);
7744 IDispatch_Release(pDispatch);
7745 }
7746 else
7747 {
7748 VariantClear(pVarResult);
7750 }
7751 }
7752
7753func_fail:
7755 break;
7756 }
7757 case FUNC_DISPATCH: {
7758 IDispatch *disp;
7759
7760 hres = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp);
7761 if (SUCCEEDED(hres)) {
7762 FIXME("Calling Invoke in IDispatch iface. untested!\n");
7763 hres = IDispatch_Invoke(
7764 disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,wFlags,pDispParams,
7765 pVarResult,pExcepInfo,pArgErr
7766 );
7767 if (FAILED(hres))
7768 FIXME("IDispatch::Invoke failed with %08x. (Could be not a real error?)\n", hres);
7769 IDispatch_Release(disp);
7770 } else
7771 FIXME("FUNC_DISPATCH used on object without IDispatch iface?\n");
7772 break;
7773 }
7774 default:
7775 FIXME("Unknown function invocation type %d\n", func_desc->funckind);
7776 hres = E_FAIL;
7777 break;
7778 }
7779
7780 TRACE("-- 0x%08x\n", hres);
7781 return hres;
7782
7783 } else if(SUCCEEDED(hres = ITypeInfo2_GetVarIndexOfMemId(iface, memid, &var_index))) {
7784 VARDESC *var_desc;
7785
7786 hres = ITypeInfo2_GetVarDesc(iface, var_index, &var_desc);
7787 if(FAILED(hres)) return hres;
7788
7789 FIXME("varseek: Found memid, but variable-based invoking not supported\n");
7790 dump_VARDESC(var_desc);
7791 ITypeInfo2_ReleaseVarDesc(iface, var_desc);
7792 return E_NOTIMPL;
7793 }
7794
7795 /* not found, look for it in inherited interfaces */
7796 ITypeInfo2_GetTypeKind(iface, &type_kind);
7798 if(This->impltypes) {
7799 /* recursive search */
7800 ITypeInfo *pTInfo;
7801 hres = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
7802 if(SUCCEEDED(hres)){
7803 hres = ITypeInfo_Invoke(pTInfo,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr);
7804 ITypeInfo_Release(pTInfo);
7805 return hres;
7806 }
7807 WARN("Could not search inherited interface!\n");
7808 }
7809 }
7810 WARN("did not find member id %d, flags 0x%x!\n", memid, wFlags);
7811 return DISP_E_MEMBERNOTFOUND;
7812}
7813
7814/* ITypeInfo::GetDocumentation
7815 *
7816 * Retrieves the documentation string, the complete Help file name and path,
7817 * and the context ID for the Help topic for a specified type description.
7818 *
7819 * (Can be tested by the Visual Basic Editor in Word for instance.)
7820 */
7822 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
7823 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
7824{
7826 const TLBFuncDesc *pFDesc;
7827 const TLBVarDesc *pVDesc;
7828 TRACE("(%p) memid %d Name(%p) DocString(%p)"
7829 " HelpContext(%p) HelpFile(%p)\n",
7830 This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
7831 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
7832 if(pBstrName)
7833 *pBstrName=SysAllocString(TLB_get_bstr(This->Name));
7834 if(pBstrDocString)
7835 *pBstrDocString=SysAllocString(TLB_get_bstr(This->DocString));
7836 if(pdwHelpContext)
7837 *pdwHelpContext=This->dwHelpContext;
7838 if(pBstrHelpFile)
7839 *pBstrHelpFile=SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
7840 return S_OK;
7841 }else {/* for a member */
7842 pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->typeattr.cFuncs, memid);
7843 if(pFDesc){
7844 if(pBstrName)
7845 *pBstrName = SysAllocString(TLB_get_bstr(pFDesc->Name));
7846 if(pBstrDocString)
7847 *pBstrDocString=SysAllocString(TLB_get_bstr(pFDesc->HelpString));
7848 if(pdwHelpContext)
7849 *pdwHelpContext=pFDesc->helpcontext;
7850 if(pBstrHelpFile)
7851 *pBstrHelpFile = SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
7852 return S_OK;
7853 }
7854 pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->typeattr.cVars, memid);
7855 if(pVDesc){
7856 if(pBstrName)
7857 *pBstrName = SysAllocString(TLB_get_bstr(pVDesc->Name));
7858 if(pBstrDocString)
7859 *pBstrDocString=SysAllocString(TLB_get_bstr(pVDesc->HelpString));
7860 if(pdwHelpContext)
7861 *pdwHelpContext=pVDesc->HelpContext;
7862 if(pBstrHelpFile)
7863 *pBstrHelpFile = SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
7864 return S_OK;
7865 }
7866 }
7867
7868 if(This->impltypes &&
7869 (This->typeattr.typekind == TKIND_INTERFACE || This->typeattr.typekind == TKIND_DISPATCH)) {
7870 /* recursive search */
7871 ITypeInfo *pTInfo;
7873 result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
7874 if(SUCCEEDED(result)) {
7875 result = ITypeInfo_GetDocumentation(pTInfo, memid, pBstrName,
7876 pBstrDocString, pdwHelpContext, pBstrHelpFile);
7877 ITypeInfo_Release(pTInfo);
7878 return result;
7879 }
7880 WARN("Could not search inherited interface!\n");
7881 }
7882
7883 WARN("member %d not found\n", memid);
7885}
7886
7887/* ITypeInfo::GetDllEntry
7888 *
7889 * Retrieves a description or specification of an entry point for a function
7890 * in a DLL.
7891 */
7892static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid,
7893 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
7894 WORD *pwOrdinal)
7895{
7897 const TLBFuncDesc *pFDesc;
7898
7899 TRACE("(%p)->(memid %x, %d, %p, %p, %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
7900
7901 if (pBstrDllName) *pBstrDllName = NULL;
7902 if (pBstrName) *pBstrName = NULL;
7903 if (pwOrdinal) *pwOrdinal = 0;
7904
7905 if (This->typeattr.typekind != TKIND_MODULE)
7906 return TYPE_E_BADMODULEKIND;
7907
7908 pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->typeattr.cFuncs, memid);
7909 if(pFDesc){
7911 if (TRACE_ON(ole))
7912 dump_TLBFuncDescOne(pFDesc);
7913
7914 if (pBstrDllName)
7915 *pBstrDllName = SysAllocString(TLB_get_bstr(This->DllName));
7916
7917 if (!IS_INTRESOURCE(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
7918 if (pBstrName)
7919 *pBstrName = SysAllocString(TLB_get_bstr(pFDesc->Entry));
7920 if (pwOrdinal)
7921 *pwOrdinal = -1;
7922 return S_OK;
7923 }
7924 if (pBstrName)
7925 *pBstrName = NULL;
7926 if (pwOrdinal)
7927 *pwOrdinal = LOWORD(pFDesc->Entry);
7928 return S_OK;
7929 }
7931}
7932
7933/* internal function to make the inherited interfaces' methods appear
7934 * part of the interface */
7936 HREFTYPE *hRefType, ITypeInfo **ppTInfo)
7937{
7939 HRESULT hr;
7940
7941 TRACE("%p, 0x%x\n", iface, *hRefType);
7942
7943 if (This->impltypes && (*hRefType & DISPATCH_HREF_MASK))
7944 {
7945 ITypeInfo *pSubTypeInfo;
7946
7947 hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pSubTypeInfo);
7948 if (FAILED(hr))
7949 return hr;
7950
7952 hRefType, ppTInfo);
7953 ITypeInfo_Release(pSubTypeInfo);
7954 if (SUCCEEDED(hr))
7955 return hr;
7956 }
7957 *hRefType -= DISPATCH_HREF_OFFSET;
7958
7959 if (!(*hRefType & DISPATCH_HREF_MASK))
7960 return ITypeInfo_GetRefTypeInfo(iface, *hRefType, ppTInfo);
7961 else
7962 return E_FAIL;
7963}
7964
7966{
7967 const GUID *guid;
7969};
7970
7972{
7974 static const WCHAR formatW[] = {'\\','%','d',0};
7976 ITypeLib *pTLib = NULL;
7977 HRESULT ret;
7978 DWORD len;
7979
7980 if (IS_INTRESOURCE(lpszName) == FALSE)
7981 return TRUE;
7982
7984 return TRUE;
7985
7986 if (swprintf(szPath + len, formatW, LOWORD(lpszName)) < 0)
7987 return TRUE;
7988
7990 if (SUCCEEDED(ret))
7991 {
7993 if (IsEqualGUID(params->guid, impl->guid))
7994 {
7995 params->pTLib = pTLib;
7996 return FALSE; /* stop enumeration */
7997 }
7998 ITypeLib_Release(pTLib);
7999 }
8000
8001 return TRUE;
8002}
8003
8004/* ITypeInfo::GetRefTypeInfo
8005 *
8006 * If a type description references other type descriptions, it retrieves
8007 * the referenced type descriptions.
8008 */
8010 ITypeInfo2 *iface,
8011 HREFTYPE hRefType,
8012 ITypeInfo **ppTInfo)
8013{
8016
8017 if(!ppTInfo)
8018 return E_INVALIDARG;
8019
8020 if ((INT)hRefType < 0) {
8021 ITypeInfoImpl *pTypeInfoImpl;
8022
8023 if (!(This->typeattr.wTypeFlags & TYPEFLAG_FDUAL) ||
8024 !(This->typeattr.typekind == TKIND_INTERFACE ||
8025 This->typeattr.typekind == TKIND_DISPATCH))
8027
8028 /* when we meet a DUAL typeinfo, we must create the alternate
8029 * version of it.
8030 */
8031 pTypeInfoImpl = ITypeInfoImpl_Constructor();
8032
8033 *pTypeInfoImpl = *This;
8034 pTypeInfoImpl->ref = 0;
8035 list_init(&pTypeInfoImpl->custdata_list);
8036
8037 if (This->typeattr.typekind == TKIND_INTERFACE)
8038 pTypeInfoImpl->typeattr.typekind = TKIND_DISPATCH;
8039 else
8040 pTypeInfoImpl->typeattr.typekind = TKIND_INTERFACE;
8041
8042 *ppTInfo = (ITypeInfo *)&pTypeInfoImpl->ITypeInfo2_iface;
8043 /* the AddRef implicitly adds a reference to the parent typelib, which
8044 * stops the copied data from being destroyed until the new typeinfo's
8045 * refcount goes to zero, but we need to signal to the new instance to
8046 * not free its data structures when it is destroyed */
8047 pTypeInfoImpl->not_attached_to_typelib = TRUE;
8048
8049 ITypeInfo_AddRef(*ppTInfo);
8050
8051 result = S_OK;
8052 } else if ((hRefType & DISPATCH_HREF_MASK) &&
8053 (This->typeattr.typekind == TKIND_DISPATCH))
8054 {
8055 HREFTYPE href_dispatch = hRefType;
8056 result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo);
8057 } else {
8058 TLBRefType *ref_type;
8059 ITypeLib *pTLib = NULL;
8060 UINT i;
8061
8062 if(!(hRefType & 0x1)){
8063 for(i = 0; i < This->pTypeLib->TypeInfoCount; ++i)
8064 {
8065 if (This->pTypeLib->typeinfos[i]->hreftype == (hRefType&(~0x3)))
8066 {
8067 result = S_OK;
8068 *ppTInfo = (ITypeInfo*)&This->pTypeLib->typeinfos[i]->ITypeInfo2_iface;
8069 ITypeInfo_AddRef(*ppTInfo);
8070 goto end;
8071 }
8072 }
8073 }
8074
8075 LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry)
8076 {
8077 if(ref_type->reference == (hRefType & (~0x3)))
8078 break;
8079 }
8080 if(&ref_type->entry == &This->pTypeLib->ref_list)
8081 {
8082 FIXME("Can't find pRefType for ref %x\n", hRefType);
8083 goto end;
8084 }
8085
8086 if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) {
8087 UINT Index;
8088 TRACE("internal reference\n");
8089 result = ITypeInfo2_GetContainingTypeLib(iface, &pTLib, &Index);
8090 } else {
8091 if(ref_type->pImpTLInfo->pImpTypeLib) {
8092 TRACE("typeinfo in imported typelib that is already loaded\n");
8093 pTLib = (ITypeLib*)&ref_type->pImpTLInfo->pImpTypeLib->ITypeLib2_iface;
8094 ITypeLib_AddRef(pTLib);
8095 result = S_OK;
8096 } else {
8097 static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0};
8099 BSTR libnam;
8100
8101 TRACE("typeinfo in imported typelib that isn't already loaded\n");
8102
8103 /* Search in resource table */
8104 params.guid = TLB_get_guid_null(ref_type->pImpTLInfo->guid);
8105 params.pTLib = NULL;
8107 pTLib = params.pTLib;
8108 result = S_OK;
8109
8110 if (!pTLib)
8111 {
8112 /* Search on disk */
8114 ref_type->pImpTLInfo->wVersionMajor,
8115 ref_type->pImpTLInfo->wVersionMinor,
8116 This->pTypeLib->syskind,
8117 ref_type->pImpTLInfo->lcid, &libnam, TRUE);
8118 if (FAILED(result))
8119 libnam = SysAllocString(ref_type->pImpTLInfo->name);
8120
8121 result = LoadTypeLib(libnam, &pTLib);
8122 SysFreeString(libnam);
8123 }
8124
8125 if(SUCCEEDED(result)) {
8127 ITypeLib_AddRef(pTLib);
8128 }
8129 }
8130 }
8131 if(SUCCEEDED(result)) {
8132 if(ref_type->index == TLB_REF_USE_GUID)
8133 result = ITypeLib_GetTypeInfoOfGuid(pTLib, TLB_get_guid_null(ref_type->guid), ppTInfo);
8134 else
8135 result = ITypeLib_GetTypeInfo(pTLib, ref_type->index, ppTInfo);
8136 }
8137 if (pTLib != NULL)
8138 ITypeLib_Release(pTLib);
8139 }
8140
8141end:
8142 TRACE("(%p) hreftype 0x%04x loaded %s (%p)\n", This, hRefType,
8143 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
8144 return result;
8145}
8146
8147/* ITypeInfo::AddressOfMember
8148 *
8149 * Retrieves the addresses of static functions or variables, such as those
8150 * defined in a DLL.
8151 */
8153 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
8154{
8156 HRESULT hr;
8157 BSTR dll, entry;
8158 WORD ordinal;
8160
8161 TRACE("(%p)->(0x%x, 0x%x, %p)\n", This, memid, invKind, ppv);
8162
8163 hr = ITypeInfo2_GetDllEntry(iface, memid, invKind, &dll, &entry, &ordinal);
8164 if (FAILED(hr))
8165 return hr;
8166
8168 if (!module)
8169 {
8170 ERR("couldn't load %s\n", debugstr_w(dll));
8173 return STG_E_FILENOTFOUND;
8174 }
8175 /* FIXME: store library somewhere where we can free it */
8176
8177 if (entry)
8178 {
8179 LPSTR entryA;
8181 entryA = heap_alloc(len);
8182 WideCharToMultiByte(CP_ACP, 0, entry, -1, entryA, len, NULL, NULL);
8183
8184 *ppv = GetProcAddress(module, entryA);
8185 if (!*ppv)
8186 ERR("function not found %s\n", debugstr_a(entryA));
8187
8188 heap_free(entryA);
8189 }
8190 else
8191 {
8193 if (!*ppv)
8194 ERR("function not found %d\n", ordinal);
8195 }
8196
8199
8200 if (!*ppv)
8202
8203 return S_OK;
8204}
8205
8206/* ITypeInfo::CreateInstance
8207 *
8208 * Creates a new instance of a type that describes a component object class
8209 * (coclass).
8210 */
8212 IUnknown *pOuterUnk, REFIID riid, VOID **ppvObj)
8213{
8215 HRESULT hr;
8216 TYPEATTR *pTA;
8217
8218 TRACE("(%p)->(%p, %s, %p)\n", This, pOuterUnk, debugstr_guid(riid), ppvObj);
8219
8220 *ppvObj = NULL;
8221
8222 if(pOuterUnk)
8223 {
8224 WARN("Not able to aggregate\n");
8225 return CLASS_E_NOAGGREGATION;
8226 }
8227
8228 hr = ITypeInfo2_GetTypeAttr(iface, &pTA);
8229 if(FAILED(hr)) return hr;
8230
8231 if(pTA->typekind != TKIND_COCLASS)
8232 {
8233 WARN("CreateInstance on typeinfo of type %x\n", pTA->typekind);
8234 hr = E_INVALIDARG;
8235 goto end;
8236 }
8237
8238 hr = S_FALSE;
8239 if(pTA->wTypeFlags & TYPEFLAG_FAPPOBJECT)
8240 {
8241 IUnknown *pUnk;
8242 hr = GetActiveObject(&pTA->guid, NULL, &pUnk);
8243 TRACE("GetActiveObject rets %08x\n", hr);
8244 if(hr == S_OK)
8245 {
8246 hr = IUnknown_QueryInterface(pUnk, riid, ppvObj);
8247 IUnknown_Release(pUnk);
8248 }
8249 }
8250
8251 if(hr != S_OK)
8252 hr = CoCreateInstance(&pTA->guid, NULL,
8253 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
8254 riid, ppvObj);
8255
8256end:
8257 ITypeInfo2_ReleaseTypeAttr(iface, pTA);
8258 return hr;
8259}
8260
8261/* ITypeInfo::GetMops
8262 *
8263 * Retrieves marshalling information.
8264 */
8265static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid,
8266 BSTR *pBstrMops)
8267{
8269 FIXME("(%p %d) stub!\n", This, memid);
8270 *pBstrMops = NULL;
8271 return S_OK;
8272}
8273
8274/* ITypeInfo::GetContainingTypeLib
8275 *
8276 * Retrieves the containing type library and the index of the type description
8277 * within that type library.
8278 */
8280 ITypeLib * *ppTLib, UINT *pIndex)
8281{
8283
8284 /* If a pointer is null, we simply ignore it, the ATL in particular passes pIndex as 0 */
8285 if (pIndex) {
8286 *pIndex=This->index;
8287 TRACE("returning pIndex=%d\n", *pIndex);
8288 }
8289
8290 if (ppTLib) {
8291 *ppTLib = (ITypeLib *)&This->pTypeLib->ITypeLib2_iface;
8292 ITypeLib_AddRef(*ppTLib);
8293 TRACE("returning ppTLib=%p\n", *ppTLib);
8294 }
8295
8296 return S_OK;
8297}
8298
8299/* ITypeInfo::ReleaseTypeAttr
8300 *
8301 * Releases a TYPEATTR previously returned by Get
8302 *
8303 */
8305 TYPEATTR* pTypeAttr)
8306{
8308 TRACE("(%p)->(%p)\n", This, pTypeAttr);
8309 heap_free(pTypeAttr);
8310}
8311
8312/* ITypeInfo::ReleaseFuncDesc
8313 *
8314 * Releases a FUNCDESC previously returned by GetFuncDesc. *
8315 */
8317 ITypeInfo2 *iface,
8318 FUNCDESC *pFuncDesc)
8319{
8321 SHORT i;
8322
8323 TRACE("(%p)->(%p)\n", This, pFuncDesc);
8324
8325 for (i = 0; i < pFuncDesc->cParams; i++)
8326 TLB_FreeElemDesc(&pFuncDesc->lprgelemdescParam[i]);
8327 TLB_FreeElemDesc(&pFuncDesc->elemdescFunc);
8328
8329 SysFreeString((BSTR)pFuncDesc);
8330}
8331
8332/* ITypeInfo::ReleaseVarDesc
8333 *
8334 * Releases a VARDESC previously returned by GetVarDesc.
8335 */
8337 VARDESC *pVarDesc)
8338{
8340 TRACE("(%p)->(%p)\n", This, pVarDesc);
8341
8342 TLB_FreeVarDesc(pVarDesc);
8343}
8344
8345/* ITypeInfo2::GetTypeKind
8346 *
8347 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
8348 *
8349 */
8351 TYPEKIND *pTypeKind)
8352{
8354 *pTypeKind = This->typeattr.typekind;
8355 TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
8356 return S_OK;
8357}
8358
8359/* ITypeInfo2::GetTypeFlags
8360 *
8361 * Returns the type flags without any allocations. This returns a DWORD type
8362 * flag, which expands the type flags without growing the TYPEATTR (type
8363 * attribute).
8364 *
8365 */
8367{
8369 *pTypeFlags=This->typeattr.wTypeFlags;
8370 TRACE("(%p) flags 0x%x\n", This,*pTypeFlags);
8371 return S_OK;
8372}
8373
8374/* ITypeInfo2::GetFuncIndexOfMemId
8375 * Binds to a specific member based on a known DISPID, where the member name
8376 * is not known (for example, when binding to a default member).
8377 *
8378 */
8380 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
8381{
8383 UINT fdc;
8385
8386 for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
8387 const TLBFuncDesc *pFuncInfo = &This->funcdescs[fdc];
8388 if(memid == pFuncInfo->funcdesc.memid && (invKind & pFuncInfo->funcdesc.invkind))
8389 break;
8390 }
8391 if(fdc < This->typeattr.cFuncs) {
8392 *pFuncIndex = fdc;
8393 result = S_OK;
8394 } else
8396
8397 TRACE("(%p) memid 0x%08x invKind 0x%04x -> %s\n", This,
8398 memid, invKind, SUCCEEDED(result) ? "SUCCESS" : "FAILED");
8399 return result;
8400}
8401
8402/* TypeInfo2::GetVarIndexOfMemId
8403 *
8404 * Binds to a specific member based on a known DISPID, where the member name
8405 * is not known (for example, when binding to a default member).
8406 *
8407 */
8409 MEMBERID memid, UINT *pVarIndex)
8410{
8412 TLBVarDesc *pVarInfo;
8413
8414 TRACE("%p %d %p\n", iface, memid, pVarIndex);
8415
8416 pVarInfo = TLB_get_vardesc_by_memberid(This->vardescs, This->typeattr.cVars, memid);
8417 if(!pVarInfo)
8419
8420 *pVarIndex = (pVarInfo - This->vardescs);
8421
8422 return S_OK;
8423}
8424
8425/* ITypeInfo2::GetCustData
8426 *
8427 * Gets the custom data
8428 */
8430 ITypeInfo2 * iface,
8431 REFGUID guid,
8432 VARIANT *pVarVal)
8433{
8435 TLBCustData *pCData;
8436
8437 TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal);
8438
8439 if(!guid || !pVarVal)
8440 return E_INVALIDARG;
8441
8442 pCData = TLB_get_custdata_by_guid(This->pcustdata_list, guid);
8443
8444 VariantInit( pVarVal);
8445 if (pCData)
8446 VariantCopy( pVarVal, &pCData->data);
8447 else
8448 VariantClear( pVarVal );
8449 return S_OK;
8450}
8451
8452/* ITypeInfo2::GetFuncCustData
8453 *
8454 * Gets the custom data
8455 */
8457 ITypeInfo2 * iface,
8458 UINT index,
8459 REFGUID guid,
8460 VARIANT *pVarVal)
8461{
8463 TLBCustData *pCData;
8464 TLBFuncDesc *pFDesc = &This->funcdescs[index];
8465
8466 TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal);
8467
8468 if(index >= This->typeattr.cFuncs)
8470
8471 pCData = TLB_get_custdata_by_guid(&pFDesc->custdata_list, guid);
8472 if(!pCData)
8474
8475 VariantInit(pVarVal);
8476 VariantCopy(pVarVal, &pCData->data);
8477
8478 return S_OK;
8479}
8480
8481/* ITypeInfo2::GetParamCustData
8482 *
8483 * Gets the custom data
8484 */
8486 ITypeInfo2 * iface,
8487 UINT indexFunc,
8488 UINT indexParam,
8489 REFGUID guid,
8490 VARIANT *pVarVal)
8491{
8493 TLBCustData *pCData;
8494 TLBFuncDesc *pFDesc = &This->funcdescs[indexFunc];
8495
8496 TRACE("%p %u %u %s %p\n", This, indexFunc, indexParam,
8497 debugstr_guid(guid), pVarVal);
8498
8499 if(indexFunc >= This->typeattr.cFuncs)
8501
8502 if(indexParam >= pFDesc->funcdesc.cParams)
8504
8505 pCData = TLB_get_custdata_by_guid(&pFDesc->pParamDesc[indexParam].custdata_list, guid);
8506 if(!pCData)
8508
8509 VariantInit(pVarVal);
8510 VariantCopy(pVarVal, &pCData->data);
8511
8512 return S_OK;
8513}
8514
8515/* ITypeInfo2::GetVarCustData
8516 *
8517 * Gets the custom data
8518 */
8520 ITypeInfo2 * iface,
8521 UINT index,
8522 REFGUID guid,
8523 VARIANT *pVarVal)
8524{
8526 TLBCustData *pCData;
8527 TLBVarDesc *pVDesc = &This->vardescs[index];
8528
8529 TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal);
8530
8531 if(index >= This->typeattr.cVars)
8533
8534 pCData = TLB_get_custdata_by_guid(&pVDesc->custdata_list, guid);
8535 if(!pCData)
8537
8538 VariantInit(pVarVal);
8539 VariantCopy(pVarVal, &pCData->data);
8540
8541 return S_OK;
8542}
8543
8544/* ITypeInfo2::GetImplCustData
8545 *
8546 * Gets the custom data
8547 */
8549 ITypeInfo2 * iface,
8550 UINT index,
8551 REFGUID guid,
8552 VARIANT *pVarVal)
8553{
8555 TLBCustData *pCData;
8556 TLBImplType *pRDesc = &This->impltypes[index];
8557
8558 TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal);
8559
8560 if(index >= This->typeattr.cImplTypes)
8562
8563 pCData = TLB_get_custdata_by_guid(&pRDesc->custdata_list, guid);
8564 if(!pCData)
8566
8567 VariantInit(pVarVal);
8568 VariantCopy(pVarVal, &pCData->data);
8569
8570 return S_OK;
8571}
8572
8573/* ITypeInfo2::GetDocumentation2
8574 *
8575 * Retrieves the documentation string, the complete Help file name and path,
8576 * the localization context to use, and the context ID for the library Help
8577 * topic in the Help file.
8578 *
8579 */
8581 ITypeInfo2 * iface,
8582 MEMBERID memid,
8583 LCID lcid,
8584 BSTR *pbstrHelpString,
8585 DWORD *pdwHelpStringContext,
8586 BSTR *pbstrHelpStringDll)
8587{
8589 const TLBFuncDesc *pFDesc;
8590 const TLBVarDesc *pVDesc;
8591 TRACE("(%p) memid %d lcid(0x%x) HelpString(%p) "
8592 "HelpStringContext(%p) HelpStringDll(%p)\n",
8593 This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
8594 pbstrHelpStringDll );
8595 /* the help string should be obtained from the helpstringdll,
8596 * using the _DLLGetDocumentation function, based on the supplied
8597 * lcid. Nice to do sometime...
8598 */
8599 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
8600 if(pbstrHelpString)
8601 *pbstrHelpString=SysAllocString(TLB_get_bstr(This->Name));
8602 if(pdwHelpStringContext)
8603 *pdwHelpStringContext=This->dwHelpStringContext;
8604 if(pbstrHelpStringDll)
8605 *pbstrHelpStringDll=
8606 SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
8607 return S_OK;
8608 }else {/* for a member */
8609 pFDesc = TLB_get_funcdesc_by_memberid(This->funcdescs, This->typeattr.cFuncs, memid);
8610 if(pFDesc){
8611 if(pbstrHelpString)
8612 *pbstrHelpString=SysAllocString(TLB_get_bstr(pFDesc->HelpString));
8613 if(pdwHelpStringContext)
8614 *pdwHelpStringContext=pFDesc->HelpStringContext;
8615 if(pbstrHelpStringDll)
8616 *pbstrHelpStringDll=
8617 SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
8618 return S_OK;
8619 }
8620 pVDesc = TLB_get_vardesc_by_memberid(This->vardescs, This->typeattr.cVars, memid);
8621 if(pVDesc){
8622 if(pbstrHelpString)
8623 *pbstrHelpString=SysAllocString(TLB_get_bstr(pVDesc->HelpString));
8624 if(pdwHelpStringContext)
8625 *pdwHelpStringContext=pVDesc->HelpStringContext;
8626 if(pbstrHelpStringDll)
8627 *pbstrHelpStringDll=
8628 SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
8629 return S_OK;
8630 }
8631 }
8633}
8634
8635/* ITypeInfo2::GetAllCustData
8636 *
8637 * Gets all custom data items for the Type info.
8638 *
8639 */
8641 ITypeInfo2 * iface,
8642 CUSTDATA *pCustData)
8643{
8645
8646 TRACE("%p %p\n", This, pCustData);
8647
8648 return TLB_copy_all_custdata(This->pcustdata_list, pCustData);
8649}
8650
8651/* ITypeInfo2::GetAllFuncCustData
8652 *
8653 * Gets all custom data items for the specified Function
8654 *
8655 */
8657 ITypeInfo2 * iface,
8658 UINT index,
8659 CUSTDATA *pCustData)
8660{
8662 TLBFuncDesc *pFDesc = &This->funcdescs[index];
8663
8664 TRACE("%p %u %p\n", This, index, pCustData);
8665
8666 if(index >= This->typeattr.cFuncs)
8668
8669 return TLB_copy_all_custdata(&pFDesc->custdata_list, pCustData);
8670}
8671
8672/* ITypeInfo2::GetAllParamCustData
8673 *
8674 * Gets all custom data items for the Functions
8675 *
8676 */
8678 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
8679{
8681 TLBFuncDesc *pFDesc = &This->funcdescs[indexFunc];
8682
8683 TRACE("%p %u %u %p\n", This, indexFunc, indexParam, pCustData);
8684
8685 if(indexFunc >= This->typeattr.cFuncs)
8687
8688 if(indexParam >= pFDesc->funcdesc.cParams)
8690
8691 return TLB_copy_all_custdata(&pFDesc->pParamDesc[indexParam].custdata_list, pCustData);
8692}
8693
8694/* ITypeInfo2::GetAllVarCustData
8695 *
8696 * Gets all custom data items for the specified Variable
8697 *
8698 */
8700 UINT index, CUSTDATA *pCustData)
8701{
8703 TLBVarDesc * pVDesc = &This->vardescs[index];
8704
8705 TRACE("%p %u %p\n", This, index, pCustData);
8706
8707 if(index >= This->typeattr.cVars)
8709
8710 return TLB_copy_all_custdata(&pVDesc->custdata_list, pCustData);
8711}
8712
8713/* ITypeInfo2::GetAllImplCustData
8714 *
8715 * Gets all custom data items for the specified implementation type
8716 *
8717 */
8719 ITypeInfo2 * iface,
8720 UINT index,
8721 CUSTDATA *pCustData)
8722{
8724 TLBImplType *pRDesc = &This->impltypes[index];
8725
8726 TRACE("%p %u %p\n", This, index, pCustData);
8727
8728 if(index >= This->typeattr.cImplTypes)
8730
8731 return TLB_copy_all_custdata(&pRDesc->custdata_list, pCustData);
8732}
8733
8734static const ITypeInfo2Vtbl tinfvt =
8735{
8736
8740
8760
8776};
8777
8778/******************************************************************************
8779 * CreateDispTypeInfo [OLEAUT32.31]
8780 *
8781 * Build type information for an object so it can be called through an
8782 * IDispatch interface.
8783 *
8784 * RETURNS
8785 * Success: S_OK. pptinfo contains the created ITypeInfo object.
8786 * Failure: E_INVALIDARG, if one or more arguments is invalid.
8787 *
8788 * NOTES
8789 * This call allows an objects methods to be accessed through IDispatch, by
8790 * building an ITypeInfo object that IDispatch can use to call through.
8791 */
8793 INTERFACEDATA *pidata, /* [I] Description of the interface to build type info for */
8794 LCID lcid, /* [I] Locale Id */
8795 ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
8796{
8797 ITypeInfoImpl *pTIClass, *pTIIface;
8798 ITypeLibImpl *pTypeLibImpl;
8799 unsigned int param, func;
8800 TLBFuncDesc *pFuncDesc;
8801 TLBRefType *ref;
8802
8803 TRACE("\n");
8804 pTypeLibImpl = TypeLibImpl_Constructor();
8805 if (!pTypeLibImpl) return E_FAIL;
8806
8807 pTypeLibImpl->TypeInfoCount = 2;
8808 pTypeLibImpl->typeinfos = heap_alloc_zero(pTypeLibImpl->TypeInfoCount * sizeof(ITypeInfoImpl*));
8809
8810 pTIIface = pTypeLibImpl->typeinfos[0] = ITypeInfoImpl_Constructor();
8811 pTIIface->pTypeLib = pTypeLibImpl;
8812 pTIIface->index = 0;
8813 pTIIface->Name = NULL;
8814 pTIIface->dwHelpContext = -1;
8815 pTIIface->guid = NULL;
8816 pTIIface->typeattr.lcid = lcid;
8817 pTIIface->typeattr.typekind = TKIND_INTERFACE;
8818 pTIIface->typeattr.wMajorVerNum = 0;
8819 pTIIface->typeattr.wMinorVerNum = 0;
8820 pTIIface->typeattr.cbAlignment = 2;
8821 pTIIface->typeattr.cbSizeInstance = -1;
8822 pTIIface->typeattr.cbSizeVft = -1;
8823 pTIIface->typeattr.cFuncs = 0;
8824 pTIIface->typeattr.cImplTypes = 0;
8825 pTIIface->typeattr.cVars = 0;
8826 pTIIface->typeattr.wTypeFlags = 0;
8827 pTIIface->hreftype = 0;
8828
8829 pTIIface->funcdescs = TLBFuncDesc_Alloc(pidata->cMembers);
8830 pFuncDesc = pTIIface->funcdescs;
8831 for(func = 0; func < pidata->cMembers; func++) {
8832 METHODDATA *md = pidata->pmethdata + func;
8833 pFuncDesc->Name = TLB_append_str(&pTypeLibImpl->name_list, md->szName);
8834 pFuncDesc->funcdesc.memid = md->dispid;
8835 pFuncDesc->funcdesc.lprgscode = NULL;
8836 pFuncDesc->funcdesc.funckind = FUNC_VIRTUAL;
8837 pFuncDesc->funcdesc.invkind = md->wFlags;
8838 pFuncDesc->funcdesc.callconv = md->cc;
8839 pFuncDesc->funcdesc.cParams = md->cArgs;
8840 pFuncDesc->funcdesc.cParamsOpt = 0;
8841 pFuncDesc->funcdesc.oVft = md->iMeth * sizeof(void *);
8842 pFuncDesc->funcdesc.cScodes = 0;
8843 pFuncDesc->funcdesc.wFuncFlags = 0;
8844 pFuncDesc->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
8845 pFuncDesc->funcdesc.elemdescFunc.u.paramdesc.wParamFlags = PARAMFLAG_NONE;
8846 pFuncDesc->funcdesc.elemdescFunc.u.paramdesc.pparamdescex = NULL;
8847 pFuncDesc->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
8848 md->cArgs * sizeof(ELEMDESC));
8849 pFuncDesc->pParamDesc = TLBParDesc_Constructor(md->cArgs);
8850 for(param = 0; param < md->cArgs; param++) {
8851 pFuncDesc->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt;
8852 pFuncDesc->pParamDesc[param].Name = TLB_append_str(&pTypeLibImpl->name_list, md->ppdata[param].szName);
8853 }
8854 pFuncDesc->helpcontext = 0;
8855 pFuncDesc->HelpStringContext = 0;
8856 pFuncDesc->HelpString = NULL;
8857 pFuncDesc->Entry = NULL;
8858 list_init(&pFuncDesc->custdata_list);
8859 pTIIface->typeattr.cFuncs++;
8860 ++pFuncDesc;
8861 }
8862
8863 dump_TypeInfo(pTIIface);
8864
8865 pTIClass = pTypeLibImpl->typeinfos[1] = ITypeInfoImpl_Constructor();
8866 pTIClass->pTypeLib = pTypeLibImpl;
8867 pTIClass->index = 1;
8868 pTIClass->Name = NULL;
8869 pTIClass->dwHelpContext = -1;
8870 pTIClass->guid = NULL;
8871 pTIClass->typeattr.lcid = lcid;
8872 pTIClass->typeattr.typekind = TKIND_COCLASS;
8873 pTIClass->typeattr.wMajorVerNum = 0;
8874 pTIClass->typeattr.wMinorVerNum = 0;
8875 pTIClass->typeattr.cbAlignment = 2;
8876 pTIClass->typeattr.cbSizeInstance = -1;
8877 pTIClass->typeattr.cbSizeVft = -1;
8878 pTIClass->typeattr.cFuncs = 0;
8879 pTIClass->typeattr.cImplTypes = 1;
8880 pTIClass->typeattr.cVars = 0;
8881 pTIClass->typeattr.wTypeFlags = 0;
8882 pTIClass->hreftype = sizeof(MSFT_TypeInfoBase);
8883
8884 pTIClass->impltypes = TLBImplType_Alloc(1);
8885
8886 ref = heap_alloc_zero(sizeof(*ref));
8887 ref->pImpTLInfo = TLB_REF_INTERNAL;
8888 list_add_head(&pTypeLibImpl->ref_list, &ref->entry);
8889
8890 dump_TypeInfo(pTIClass);
8891
8892 *pptinfo = (ITypeInfo *)&pTIClass->ITypeInfo2_iface;
8893
8894 ITypeInfo_AddRef(*pptinfo);
8895 ITypeLib2_Release(&pTypeLibImpl->ITypeLib2_iface);
8896
8897 return S_OK;
8898
8899}
8900
8902{
8904
8905 return ITypeInfo2_QueryInterface(&This->ITypeInfo2_iface, riid, ppv);
8906}
8907
8909{
8911
8912 return ITypeInfo2_AddRef(&This->ITypeInfo2_iface);
8913}
8914
8916{
8918
8919 return ITypeInfo2_Release(&This->ITypeInfo2_iface);
8920}
8921
8923 ITypeComp * iface,
8924 OLECHAR * szName,
8925 ULONG lHash,
8926 WORD wFlags,
8927 ITypeInfo ** ppTInfo,
8928 DESCKIND * pDescKind,
8929 BINDPTR * pBindPtr)
8930{
8932 const TLBFuncDesc *pFDesc;
8933 const TLBVarDesc *pVDesc;
8935 UINT fdc;
8936
8937 TRACE("(%p)->(%s, %x, 0x%x, %p, %p, %p)\n", This, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
8938
8939 *pDescKind = DESCKIND_NONE;
8940 pBindPtr->lpfuncdesc = NULL;
8941 *ppTInfo = NULL;
8942
8943 for(fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
8944 pFDesc = &This->funcdescs[fdc];
8945 if (!lstrcmpiW(TLB_get_bstr(pFDesc->Name), szName)) {
8946 if (!wFlags || (pFDesc->funcdesc.invkind & wFlags))
8947 break;
8948 else
8949 /* name found, but wrong flags */
8951 }
8952 }
8953
8954 if (fdc < This->typeattr.cFuncs)
8955 {
8957 &pFDesc->funcdesc,
8958 &pBindPtr->lpfuncdesc,
8959 This->typeattr.typekind == TKIND_DISPATCH);
8960 if (FAILED(hr))
8961 return hr;
8962 *pDescKind = DESCKIND_FUNCDESC;
8963 *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface;
8964 ITypeInfo_AddRef(*ppTInfo);
8965 return S_OK;
8966 } else {
8967 pVDesc = TLB_get_vardesc_by_name(This->vardescs, This->typeattr.cVars, szName);
8968 if(pVDesc){
8969 HRESULT hr = TLB_AllocAndInitVarDesc(&pVDesc->vardesc, &pBindPtr->lpvardesc);
8970 if (FAILED(hr))
8971 return hr;
8972 *pDescKind = DESCKIND_VARDESC;
8973 *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface;
8974 ITypeInfo_AddRef(*ppTInfo);
8975 return S_OK;
8976 }
8977 }
8978
8979 if (hr == DISP_E_MEMBERNOTFOUND && This->impltypes) {
8980 /* recursive search */
8981 ITypeInfo *pTInfo;
8982 ITypeComp *pTComp;
8983 HRESULT hr;
8984 hr=ITypeInfo2_GetRefTypeInfo(&This->ITypeInfo2_iface, This->impltypes[0].hRef, &pTInfo);
8985 if (SUCCEEDED(hr))
8986 {
8987 hr = ITypeInfo_GetTypeComp(pTInfo,&pTComp);
8988 ITypeInfo_Release(pTInfo);
8989 }
8990 if (SUCCEEDED(hr))
8991 {
8992 hr = ITypeComp_Bind(pTComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
8993 ITypeComp_Release(pTComp);
8994 if (SUCCEEDED(hr) && *pDescKind == DESCKIND_FUNCDESC &&
8995 This->typeattr.typekind == TKIND_DISPATCH)
8996 {
8997 FUNCDESC *tmp = pBindPtr->lpfuncdesc;
8998 hr = TLB_AllocAndInitFuncDesc(tmp, &pBindPtr->lpfuncdesc, TRUE);
8999 SysFreeString((BSTR)tmp);
9000 }
9001 return hr;
9002 }
9003 WARN("Could not search inherited interface!\n");
9004 }
9006 hr = S_OK;
9007 TRACE("did not find member with name %s, flags 0x%x\n", debugstr_w(szName), wFlags);
9008 return hr;
9009}
9010
9012 ITypeComp * iface,
9013 OLECHAR * szName,
9014 ULONG lHash,
9015 ITypeInfo ** ppTInfo,
9016 ITypeComp ** ppTComp)
9017{
9018 TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
9019
9020 /* strange behaviour (does nothing) but like the
9021 * original */
9022
9023 if (!ppTInfo || !ppTComp)
9024 return E_POINTER;
9025
9026 *ppTInfo = NULL;
9027 *ppTComp = NULL;
9028
9029 return S_OK;
9030}
9031
9032static const ITypeCompVtbl tcompvt =
9033{
9034
9038
9041};
9042
9043HRESULT WINAPI CreateTypeLib2(SYSKIND syskind, LPCOLESTR szFile,
9044 ICreateTypeLib2** ppctlib)
9045{
9047 HRESULT hres;
9048
9049 TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib);
9050
9051 if (!szFile) return E_INVALIDARG;
9052
9054 if (!This)
9055 return E_OUTOFMEMORY;
9056
9057 This->lcid = GetSystemDefaultLCID();
9058 This->syskind = syskind;
9059 This->ptr_size = get_ptr_size(syskind);
9060
9061 This->path = heap_alloc((lstrlenW(szFile) + 1) * sizeof(WCHAR));
9062 if (!This->path) {
9063 ITypeLib2_Release(&This->ITypeLib2_iface);
9064 return E_OUTOFMEMORY;
9065 }
9066 lstrcpyW(This->path, szFile);
9067
9068 hres = ITypeLib2_QueryInterface(&This->ITypeLib2_iface, &IID_ICreateTypeLib2, (LPVOID*)ppctlib);
9069 ITypeLib2_Release(&This->ITypeLib2_iface);
9070 return hres;
9071}
9072
9074 REFIID riid, void **object)
9075{
9077
9078 return ITypeLib2_QueryInterface(&This->ITypeLib2_iface, riid, object);
9079}
9080
9082{
9084
9085 return ITypeLib2_AddRef(&This->ITypeLib2_iface);
9086}
9087
9089{
9091
9092 return ITypeLib2_Release(&This->ITypeLib2_iface);
9093}
9094
9096 LPOLESTR name, TYPEKIND kind, ICreateTypeInfo **ctinfo)
9097{
9100 HRESULT hres;
9101
9102 TRACE("%p %s %d %p\n", This, wine_dbgstr_w(name), kind, ctinfo);
9103
9104 if (!ctinfo || !name)
9105 return E_INVALIDARG;
9106
9107 info = TLB_get_typeinfo_by_name(This->typeinfos, This->TypeInfoCount, name);
9108 if (info)
9109 return TYPE_E_NAMECONFLICT;
9110
9111 if (This->typeinfos)
9112 This->typeinfos = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->typeinfos,
9113 sizeof(ITypeInfoImpl*) * (This->TypeInfoCount + 1));
9114 else
9115 This->typeinfos = heap_alloc_zero(sizeof(ITypeInfoImpl*));
9116
9117 info = This->typeinfos[This->TypeInfoCount] = ITypeInfoImpl_Constructor();
9118
9119 info->pTypeLib = This;
9120 info->Name = TLB_append_str(&This->name_list, name);
9121 info->index = This->TypeInfoCount;
9122 info->typeattr.typekind = kind;
9123 info->typeattr.cbAlignment = 4;
9124
9125 switch (info->typeattr.typekind) {
9126 case TKIND_ENUM:
9127 case TKIND_INTERFACE:
9128 case TKIND_DISPATCH:
9129 case TKIND_COCLASS:
9130 info->typeattr.cbSizeInstance = This->ptr_size;
9131 break;
9132 case TKIND_RECORD:
9133 case TKIND_UNION:
9134 info->typeattr.cbSizeInstance = 0;
9135 break;
9136 case TKIND_MODULE:
9137 info->typeattr.cbSizeInstance = 2;
9138 break;
9139 case TKIND_ALIAS:
9140 info->typeattr.cbSizeInstance = -0x75;
9141 break;
9142 default:
9143 FIXME("unrecognized typekind %d\n", info->typeattr.typekind);
9144 info->typeattr.cbSizeInstance = 0xdeadbeef;
9145 break;
9146 }
9147
9148 hres = ITypeInfo2_QueryInterface(&info->ITypeInfo2_iface,
9149 &IID_ICreateTypeInfo, (void **)ctinfo);
9150 if (FAILED(hres)) {
9151 ITypeInfo2_Release(&info->ITypeInfo2_iface);
9152 return hres;
9153 }
9154
9155 info->hreftype = info->index * sizeof(MSFT_TypeInfoBase);
9156
9157 ++This->TypeInfoCount;
9158
9159 return S_OK;
9160}
9161
9163 LPOLESTR name)
9164{
9166
9167 TRACE("%p %s\n", This, wine_dbgstr_w(name));
9168
9169 if (!name)
9170 return E_INVALIDARG;
9171
9172 This->Name = TLB_append_str(&This->name_list, name);
9173
9174 return S_OK;
9175}
9176
9178 WORD majorVerNum, WORD minorVerNum)
9179{
9181
9182 TRACE("%p %d %d\n", This, majorVerNum, minorVerNum);
9183
9184 This->ver_major = majorVerNum;
9185 This->ver_minor = minorVerNum;
9186
9187 return S_OK;
9188}
9189
9191 REFGUID guid)
9192{
9194
9195 TRACE("%p %s\n", This, debugstr_guid(guid));
9196
9197 This->guid = TLB_append_guid(&This->guid_list, guid, -2);
9198
9199 return S_OK;
9200}
9201
9203 LPOLESTR doc)
9204{
9206
9207 TRACE("%p %s\n", This, wine_dbgstr_w(doc));
9208
9209 if (!doc)
9210 return E_INVALIDARG;
9211
9212 This->DocString = TLB_append_str(&This->string_list, doc);
9213
9214 return S_OK;
9215}
9216
9218 LPOLESTR helpFileName)
9219{
9221
9222 TRACE("%p %s\n", This, wine_dbgstr_w(helpFileName));
9223
9224 if (!helpFileName)
9225 return E_INVALIDARG;
9226
9227 This->HelpFile = TLB_append_str(&This->string_list, helpFileName);
9228
9229 return S_OK;
9230}
9231
9233 DWORD helpContext)
9234{
9236
9237 TRACE("%p %d\n", This, helpContext);
9238
9239 This->dwHelpContext = helpContext;
9240
9241 return S_OK;
9242}
9243
9245 LCID lcid)
9246{
9248
9249 TRACE("%p %x\n", This, lcid);
9250
9251 This->set_lcid = lcid;
9252
9253 return S_OK;
9254}
9255
9257 UINT libFlags)
9258{
9260
9261 TRACE("%p %x\n", This, libFlags);
9262
9263 This->libflags = libFlags;
9264
9265 return S_OK;
9266}
9267
9268typedef struct tagWMSFT_SegContents {
9270 void *data;
9272
9273typedef struct tagWMSFT_TLBFile {
9291
9294{
9295 TLBString *str;
9296 UINT last_offs;
9297 char *data;
9298
9299 file->string_seg.len = 0;
9300 LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) {
9301 int size;
9302
9303 size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str), NULL, 0, NULL, NULL);
9304 if (size == 0)
9305 return E_UNEXPECTED;
9306
9307 size += sizeof(INT16);
9308 if (size % 4)
9309 size = (size + 4) & ~0x3;
9310 if (size < 8)
9311 size = 8;
9312
9313 file->string_seg.len += size;
9314
9315 /* temporarily use str->offset to store the length of the aligned,
9316 * converted string */
9317 str->offset = size;
9318 }
9319
9320 file->string_seg.data = data = heap_alloc(file->string_seg.len);
9321
9322 last_offs = 0;
9323 LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) {
9324 int size;
9325
9326 size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str),
9327 data + sizeof(INT16), file->string_seg.len - last_offs - sizeof(INT16), NULL, NULL);
9328 if (size == 0) {
9329 heap_free(file->string_seg.data);
9330 return E_UNEXPECTED;
9331 }
9332
9333 *((INT16*)data) = size;
9334
9335 memset(data + sizeof(INT16) + size, 0x57, str->offset - size - sizeof(INT16));
9336
9337 size = str->offset;
9338 data += size;
9339 str->offset = last_offs;
9340 last_offs += size;
9341 }
9342
9343 return S_OK;
9344}
9345
9348{
9349 TLBString *str;
9350 UINT last_offs;
9351 char *data;
9352 MSFT_NameIntro *last_intro = NULL;
9353
9354 file->header.nametablecount = 0;
9355 file->header.nametablechars = 0;
9356
9357 file->name_seg.len = 0;
9358 LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) {
9359 int size;
9360
9361 size = lstrlenW(str->str);
9362 file->header.nametablechars += size;
9363 file->header.nametablecount++;
9364
9365 size = WideCharToMultiByte(CP_ACP, 0, str->str, size, NULL, 0, NULL, NULL);
9366 if (size == 0)
9367 return E_UNEXPECTED;
9368
9369 size += sizeof(MSFT_NameIntro);
9370 if (size % 4)
9371 size = (size + 4) & ~0x3;
9372 if (size < 8)
9373 size = 8;
9374
9375 file->name_seg.len += size;
9376
9377 /* temporarily use str->offset to store the length of the aligned,
9378 * converted string */
9379 str->offset = size;
9380 }
9381
9382 /* Allocate bigger buffer so we can temporarily NULL terminate the name */
9383 file->name_seg.data = data = heap_alloc(file->name_seg.len+1);
9384
9385 last_offs = 0;
9386 LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) {
9387 int size, hash;
9389
9390 size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str),
9391 data + sizeof(MSFT_NameIntro),
9392 file->name_seg.len - last_offs - sizeof(MSFT_NameIntro), NULL, NULL);
9393 if (size == 0) {
9394 heap_free(file->name_seg.data);
9395 return E_UNEXPECTED;
9396 }
9397 data[sizeof(MSFT_NameIntro) + size] = '\0';
9398
9399 intro->hreftype = -1; /* TODO? */
9400 intro->namelen = size & 0xFF;
9401 /* TODO: namelen & 0xFF00 == ??? maybe HREF type indicator? */
9402 hash = LHashValOfNameSysA(This->syskind, This->lcid, data + sizeof(MSFT_NameIntro));
9403 intro->namelen |= hash << 16;
9404 intro->next_hash = ((DWORD*)file->namehash_seg.data)[hash & 0x7f];
9405 ((DWORD*)file->namehash_seg.data)[hash & 0x7f] = last_offs;
9406
9407 memset(data + sizeof(MSFT_NameIntro) + size, 0x57,
9408 str->offset - size - sizeof(MSFT_NameIntro));
9409
9410 /* update str->offset to actual value to use in other
9411 * compilation functions that require positions within
9412 * the string table */
9413 last_intro = intro;
9414 size = str->offset;
9415 data += size;
9416 str->offset = last_offs;
9417 last_offs += size;
9418 }
9419
9420 if(last_intro)
9421 last_intro->hreftype = 0; /* last one is 0? */
9422
9423 return S_OK;
9424}
9425
9426static inline int hash_guid(GUID *guid)
9427{
9428 int i, hash = 0;
9429
9430 for (i = 0; i < 8; i ++)
9431 hash ^= ((const short *)guid)[i];
9432
9433 return hash & 0x1f;
9434}
9435
9437{
9438 TLBGuid *guid;
9440 DWORD offs;
9441 int hash_key, *guidhashtab;
9442
9443 file->guid_seg.len = sizeof(MSFT_GuidEntry) * list_count(&This->guid_list);
9444 file->guid_seg.data = heap_alloc(file->guid_seg.len);
9445
9446 entry = file->guid_seg.data;
9447 offs = 0;
9448 guidhashtab = file->guidhash_seg.data;
9449 LIST_FOR_EACH_ENTRY(guid, &This->guid_list, TLBGuid, entry){
9450 memcpy(&entry->guid, &guid->guid, sizeof(GUID));
9451 entry->hreftype = guid->hreftype;
9452
9453 hash_key = hash_guid(&guid->guid);
9454 entry->next_hash = guidhashtab[hash_key];
9455 guidhashtab[hash_key] = offs;
9456
9457 guid->offset = offs;
9458 offs += sizeof(MSFT_GuidEntry);
9459 ++entry;
9460 }
9461
9462 return S_OK;
9463}
9464
9466{
9467 VARIANT v = *value;
9468 VARTYPE arg_type = V_VT(value);
9469 int mask = 0;
9470 HRESULT hres;
9471 DWORD ret = file->custdata_seg.len;
9472
9473 if(arg_type == VT_INT)
9474 arg_type = VT_I4;
9475 if(arg_type == VT_UINT)
9476 arg_type = VT_UI4;
9477
9478 v = *value;
9479 if(V_VT(value) != arg_type) {
9480 hres = VariantChangeType(&v, value, 0, arg_type);
9481 if(FAILED(hres)){
9482 ERR("VariantChangeType failed: %08x\n", hres);
9483 return -1;
9484 }
9485 }
9486
9487 /* Check if default value can be stored in-place */
9488 switch(arg_type){
9489 case VT_I4:
9490 case VT_UI4:
9491 mask = 0x3ffffff;
9492 if(V_UI4(&v) > 0x3ffffff)
9493 break;
9494 /* fall through */
9495 case VT_I1:
9496 case VT_UI1:
9497 case VT_BOOL:
9498 if(!mask)
9499 mask = 0xff;
9500 /* fall through */
9501 case VT_I2:
9502 case VT_UI2:
9503 if(!mask)
9504 mask = 0xffff;
9505 return ((0x80 + 0x4 * V_VT(value)) << 24) | (V_UI4(&v) & mask);
9506 }
9507
9508 /* have to allocate space in custdata_seg */
9509 switch(arg_type) {
9510 case VT_I4:
9511 case VT_R4:
9512 case VT_UI4:
9513 case VT_INT:
9514 case VT_UINT:
9515 case VT_HRESULT:
9516 case VT_PTR: {
9517 /* Construct the data to be allocated */
9518 int *data;
9519
9520 if(file->custdata_seg.data){
9521 file->custdata_seg.data = heap_realloc(file->custdata_seg.data, file->custdata_seg.len + sizeof(int) * 2);
9522 data = (int *)(((char *)file->custdata_seg.data) + file->custdata_seg.len);
9523 file->custdata_seg.len += sizeof(int) * 2;
9524 }else{
9525 file->custdata_seg.len = sizeof(int) * 2;
9526 data = file->custdata_seg.data = heap_alloc(file->custdata_seg.len);
9527 }
9528
9529 data[0] = V_VT(value) + (V_UI4(&v) << 16);
9530 data[1] = (V_UI4(&v) >> 16) + 0x57570000;
9531
9532 /* TODO: Check if the encoded data is already present in custdata_seg */
9533
9534 return ret;
9535 }
9536
9537 case VT_BSTR: {
9538 int i, len = (6+SysStringLen(V_BSTR(&v))+3) & ~0x3;
9539 char *data;
9540
9541 if(file->custdata_seg.data){
9542 file->custdata_seg.data = heap_realloc(file->custdata_seg.data, file->custdata_seg.len + len);
9543 data = ((char *)file->custdata_seg.data) + file->custdata_seg.len;
9544 file->custdata_seg.len += len;
9545 }else{
9546 file->custdata_seg.len = len;
9547 data = file->custdata_seg.data = heap_alloc(file->custdata_seg.len);
9548 }
9549
9550 *((unsigned short *)data) = V_VT(value);
9551 *((unsigned int *)(data+2)) = SysStringLen(V_BSTR(&v));
9552 for(i=0; i<SysStringLen(V_BSTR(&v)); i++) {
9553 if(V_BSTR(&v)[i] <= 0x7f)
9554 data[i+6] = V_BSTR(&v)[i];
9555 else
9556 data[i+6] = '?';
9557 }
9559 for(i=6+SysStringLen(V_BSTR(&v)); i<len; i++)
9560 data[i] = 0x57;
9561
9562 /* TODO: Check if the encoded data is already present in custdata_seg */
9563
9564 return ret;
9565 }
9566 default:
9567 FIXME("Argument type not yet handled\n");
9568 return -1;
9569 }
9570}
9571
9572static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *out_mix, INT16 *out_size);
9573
9575{
9576 DWORD offs = file->arraydesc_seg.len;
9577 DWORD *encoded;
9578 USHORT i;
9579
9580 /* TODO: we should check for duplicates, but that's harder because each
9581 * chunk is variable length (really we should store TYPEDESC and ARRAYDESC
9582 * at the library-level) */
9583
9584 file->arraydesc_seg.len += (2 + desc->cDims * 2) * sizeof(DWORD);
9585 if(!file->arraydesc_seg.data)
9586 file->arraydesc_seg.data = heap_alloc(file->arraydesc_seg.len);
9587 else
9588 file->arraydesc_seg.data = heap_realloc(file->arraydesc_seg.data, file->arraydesc_seg.len);
9589 encoded = (DWORD*)((char *)file->arraydesc_seg.data + offs);
9590
9591 encoded[0] = WMSFT_append_typedesc(&desc->tdescElem, file, NULL, NULL);
9592 encoded[1] = desc->cDims | ((desc->cDims * 2 * sizeof(DWORD)) << 16);
9593 for(i = 0; i < desc->cDims; ++i){
9594 encoded[2 + i * 2] = desc->rgbounds[i].cElements;
9595 encoded[2 + i * 2 + 1] = desc->rgbounds[i].lLbound;
9596 }
9597
9598 return offs;
9599}
9600
9602{
9603 DWORD junk;
9604 INT16 junk2;
9605 DWORD offs = 0;
9606 DWORD encoded[2];
9607 VARTYPE vt, subtype;
9608 char *data;
9609
9610 if(!desc)
9611 return -1;
9612
9613 if(!out_mix)
9614 out_mix = &junk;
9615 if(!out_size)
9616 out_size = &junk2;
9617
9618 vt = desc->vt & VT_TYPEMASK;
9619
9620 if(vt == VT_PTR || vt == VT_SAFEARRAY){
9621 DWORD mix;
9622 encoded[1] = WMSFT_append_typedesc(desc->u.lptdesc, file, &mix, out_size);
9623 encoded[0] = desc->vt | ((mix | VT_BYREF) << 16);
9624 *out_mix = 0x7FFF;
9625 *out_size += 2 * sizeof(DWORD);
9626 }else if(vt == VT_CARRAY){
9627 encoded[0] = desc->vt | (0x7FFE << 16);
9628 encoded[1] = WMSFT_append_arraydesc(desc->u.lpadesc, file);
9629 *out_mix = 0x7FFE;
9630 }else if(vt == VT_USERDEFINED){
9631 encoded[0] = desc->vt | (0x7FFF << 16);
9632 encoded[1] = desc->u.hreftype;
9633 *out_mix = 0x7FFF; /* FIXME: Should get TYPEKIND of the hreftype, e.g. TKIND_ENUM => VT_I4 */
9634 }else{
9635 TRACE("Mixing in-place, VT: 0x%x\n", desc->vt);
9636
9637 switch(vt){
9638 case VT_INT:
9639 subtype = VT_I4;
9640 break;
9641 case VT_UINT:
9642 subtype = VT_UI4;
9643 break;
9644 case VT_VOID:
9645 subtype = VT_EMPTY;
9646 break;
9647 default:
9648 subtype = vt;
9649 break;
9650 }
9651
9652 *out_mix = subtype;
9653 return 0x80000000 | (subtype << 16) | desc->vt;
9654 }
9655
9656 data = file->typdesc_seg.data;
9657 while(offs < file->typdesc_seg.len){
9658 if(!memcmp(&data[offs], encoded, sizeof(encoded)))
9659 return offs;
9660 offs += sizeof(encoded);
9661 }
9662
9663 file->typdesc_seg.len += sizeof(encoded);
9664 if(!file->typdesc_seg.data)
9665 data = file->typdesc_seg.data = heap_alloc(file->typdesc_seg.len);
9666 else
9667 data = file->typdesc_seg.data = heap_realloc(file->typdesc_seg.data, file->typdesc_seg.len);
9668
9669 memcpy(&data[offs], encoded, sizeof(encoded));
9670
9671 return offs;
9672}
9673
9674static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *file)
9675{
9676 WMSFT_SegContents *cdguids_seg = &file->cdguids_seg;
9677 DWORD ret = cdguids_seg->len, offs;
9678 MSFT_CDGuid *cdguid;
9679 TLBCustData *cd;
9680
9681 if(list_empty(custdata_list))
9682 return -1;
9683
9684 cdguids_seg->len += sizeof(MSFT_CDGuid) * list_count(custdata_list);
9685 if(!cdguids_seg->data){
9686 cdguid = cdguids_seg->data = heap_alloc(cdguids_seg->len);
9687 }else {
9688 cdguids_seg->data = heap_realloc(cdguids_seg->data, cdguids_seg->len);
9689 cdguid = (MSFT_CDGuid*)((char*)cdguids_seg->data + ret);
9690 }
9691
9692 offs = ret + sizeof(MSFT_CDGuid);
9693 LIST_FOR_EACH_ENTRY(cd, custdata_list, TLBCustData, entry){
9694 cdguid->GuidOffset = cd->guid->offset;
9695 cdguid->DataOffset = WMSFT_encode_variant(&cd->data, file);
9696 cdguid->next = offs;
9697 offs += sizeof(MSFT_CDGuid);
9698 ++cdguid;
9699 }
9700
9701 --cdguid;
9702 cdguid->next = -1;
9703
9704 return ret;
9705}
9706
9709{
9710 WMSFT_SegContents *aux_seg = &file->aux_seg;
9711 DWORD ret = aux_seg->len, i, j, recorded_size = 0, extra_size = 0;
9712 MSFT_VarRecord *varrecord;
9713 MSFT_FuncRecord *funcrecord;
9714 MEMBERID *memid;
9715 DWORD *name, *offsets, offs;
9716
9717 for(i = 0; i < info->typeattr.cFuncs; ++i){
9718 TLBFuncDesc *desc = &info->funcdescs[i];
9719
9720 recorded_size += 6 * sizeof(INT); /* mandatory fields */
9721
9722 /* optional fields */
9723 /* TODO: oArgCustData - FuncSetCustData not impl yet */
9724 if(!list_empty(&desc->custdata_list))
9725 recorded_size += 7 * sizeof(INT);
9726 else if(desc->HelpStringContext != 0)
9727 recorded_size += 6 * sizeof(INT);
9728 /* res9? resA? */
9729 else if(desc->Entry)
9730 recorded_size += 3 * sizeof(INT);
9731 else if(desc->HelpString)
9732 recorded_size += 2 * sizeof(INT);
9733 else if(desc->helpcontext)
9734 recorded_size += sizeof(INT);
9735
9736 recorded_size += desc->funcdesc.cParams * sizeof(MSFT_ParameterInfo);
9737
9738 for(j = 0; j < desc->funcdesc.cParams; ++j){
9739 if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT){
9740 recorded_size += desc->funcdesc.cParams * sizeof(INT);
9741 break;
9742 }
9743 }
9744
9745 extra_size += 2 * sizeof(INT); /* memberid, name offs */
9746 }
9747
9748 for(i = 0; i < info->typeattr.cVars; ++i){
9749 TLBVarDesc *desc = &info->vardescs[i];
9750
9751 recorded_size += 5 * sizeof(INT); /* mandatory fields */
9752
9753 /* optional fields */
9754 if(desc->HelpStringContext != 0)
9755 recorded_size += 5 * sizeof(INT);
9756 else if(!list_empty(&desc->custdata_list))
9757 recorded_size += 4 * sizeof(INT);
9758 /* res9? */
9759 else if(desc->HelpString)
9760 recorded_size += 2 * sizeof(INT);
9761 else if(desc->HelpContext != 0)
9762 recorded_size += sizeof(INT);
9763
9764 extra_size += 2 * sizeof(INT); /* memberid, name offs */
9765 }
9766
9767 if(!recorded_size && !extra_size)
9768 return ret;
9769
9770 extra_size += sizeof(INT); /* total aux size for this typeinfo */
9771
9772 aux_seg->len += recorded_size + extra_size;
9773
9774 aux_seg->len += sizeof(INT) * (info->typeattr.cVars + info->typeattr.cFuncs); /* offsets at the end */
9775
9776 if(aux_seg->data)
9777 aux_seg->data = heap_realloc(aux_seg->data, aux_seg->len);
9778 else
9779 aux_seg->data = heap_alloc(aux_seg->len);
9780
9781 *((DWORD*)((char *)aux_seg->data + ret)) = recorded_size;
9782
9783 offsets = (DWORD*)((char *)aux_seg->data + ret + recorded_size + extra_size);
9784 offs = 0;
9785
9786 funcrecord = (MSFT_FuncRecord*)(((char *)aux_seg->data) + ret + sizeof(INT));
9787 for(i = 0; i < info->typeattr.cFuncs; ++i){
9788 TLBFuncDesc *desc = &info->funcdescs[i];
9789 DWORD size = 6 * sizeof(INT), paramdefault_size = 0, *paramdefault;
9790
9791 funcrecord->funcdescsize = sizeof(desc->funcdesc) + desc->funcdesc.cParams * sizeof(ELEMDESC);
9792 funcrecord->DataType = WMSFT_append_typedesc(&desc->funcdesc.elemdescFunc.tdesc, file, NULL, &funcrecord->funcdescsize);
9793 funcrecord->Flags = desc->funcdesc.wFuncFlags;
9794 funcrecord->VtableOffset = desc->funcdesc.oVft;
9795
9796 /* FKCCIC:
9797 * XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
9798 * ^^^funckind
9799 * ^^^ ^invkind
9800 * ^has_cust_data
9801 * ^^^^callconv
9802 * ^has_param_defaults
9803 * ^oEntry_is_intresource
9804 */
9805 funcrecord->FKCCIC =
9806 desc->funcdesc.funckind |
9807 (desc->funcdesc.invkind << 3) |
9808 (list_empty(&desc->custdata_list) ? 0 : 0x80) |
9809 (desc->funcdesc.callconv << 8);
9810
9811 if(desc->Entry && desc->Entry != (TLBString*)-1 && IS_INTRESOURCE(desc->Entry))
9812 funcrecord->FKCCIC |= 0x2000;
9813
9814 for(j = 0; j < desc->funcdesc.cParams; ++j){
9815 if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT){
9816 paramdefault_size = sizeof(INT) * desc->funcdesc.cParams;
9817 funcrecord->funcdescsize += sizeof(PARAMDESCEX);
9818 }
9819 }
9820 if(paramdefault_size > 0)
9821 funcrecord->FKCCIC |= 0x1000;
9822
9823 funcrecord->nrargs = desc->funcdesc.cParams;
9824 funcrecord->nroargs = desc->funcdesc.cParamsOpt;
9825
9826 /* optional fields */
9827 /* res9? resA? */
9828 if(!list_empty(&desc->custdata_list)){
9829 size += 7 * sizeof(INT);
9830 funcrecord->HelpContext = desc->helpcontext;
9831 if(desc->HelpString)
9832 funcrecord->oHelpString = desc->HelpString->offset;
9833 else
9834 funcrecord->oHelpString = -1;
9835 if(!desc->Entry)
9836 funcrecord->oEntry = -1;
9837 else if(IS_INTRESOURCE(desc->Entry))
9838 funcrecord->oEntry = LOWORD(desc->Entry);
9839 else
9840 funcrecord->oEntry = desc->Entry->offset;
9841 funcrecord->res9 = -1;
9842 funcrecord->resA = -1;
9843 funcrecord->HelpStringContext = desc->HelpStringContext;
9844 funcrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
9845 }else if(desc->HelpStringContext != 0){
9846 size += 6 * sizeof(INT);
9847 funcrecord->HelpContext = desc->helpcontext;
9848 if(desc->HelpString)
9849 funcrecord->oHelpString = desc->HelpString->offset;
9850 else
9851 funcrecord->oHelpString = -1;
9852 if(!desc->Entry)
9853 funcrecord->oEntry = -1;
9854 else if(IS_INTRESOURCE(desc->Entry))
9855 funcrecord->oEntry = LOWORD(desc->Entry);
9856 else
9857 funcrecord->oEntry = desc->Entry->offset;
9858 funcrecord->res9 = -1;
9859 funcrecord->resA = -1;
9860 funcrecord->HelpStringContext = desc->HelpStringContext;
9861 }else if(desc->Entry){
9862 size += 3 * sizeof(INT);
9863 funcrecord->HelpContext = desc->helpcontext;
9864 if(desc->HelpString)
9865 funcrecord->oHelpString = desc->HelpString->offset;
9866 else
9867 funcrecord->oHelpString = -1;
9868 if(!desc->Entry)
9869 funcrecord->oEntry = -1;
9870 else if(IS_INTRESOURCE(desc->Entry))
9871 funcrecord->oEntry = LOWORD(desc->Entry);
9872 else
9873 funcrecord->oEntry = desc->Entry->offset;
9874 }else if(desc->HelpString){
9875 size += 2 * sizeof(INT);
9876 funcrecord->HelpContext = desc->helpcontext;
9877 funcrecord->oHelpString = desc->HelpString->offset;
9878 }else if(desc->helpcontext){
9879 size += sizeof(INT);
9880 funcrecord->HelpContext = desc->helpcontext;
9881 }
9882
9883 paramdefault = (DWORD*)((char *)funcrecord + size);
9884 size += paramdefault_size;
9885
9886 for(j = 0; j < desc->funcdesc.cParams; ++j){
9887 MSFT_ParameterInfo *info = (MSFT_ParameterInfo*)(((char *)funcrecord) + size);
9888
9889 info->DataType = WMSFT_append_typedesc(&desc->funcdesc.lprgelemdescParam[j].tdesc, file, NULL, &funcrecord->funcdescsize);
9890 if(desc->pParamDesc[j].Name)
9891 info->oName = desc->pParamDesc[j].Name->offset;
9892 else
9893 info->oName = -1;
9894 info->Flags = desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags;
9895
9896 if(paramdefault_size){
9897 if(desc->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
9898 *paramdefault = WMSFT_encode_variant(&desc->funcdesc.lprgelemdescParam[j].u.paramdesc.pparamdescex->varDefaultValue, file);
9899 else if(paramdefault_size)
9900 *paramdefault = -1;
9901 ++paramdefault;
9902 }
9903
9904 size += sizeof(MSFT_ParameterInfo);
9905 }
9906
9907 funcrecord->Info = size | (i << 16); /* is it just the index? */
9908
9909 *offsets = offs;
9910 offs += size;
9911 ++offsets;
9912
9913 funcrecord = (MSFT_FuncRecord*)(((char*)funcrecord) + size);
9914 }
9915
9916 varrecord = (MSFT_VarRecord*)funcrecord;
9917 for(i = 0; i < info->typeattr.cVars; ++i){
9918 TLBVarDesc *desc = &info->vardescs[i];
9919 DWORD size = 5 * sizeof(INT);
9920
9921 varrecord->vardescsize = sizeof(desc->vardesc);
9922 varrecord->DataType = WMSFT_append_typedesc(&desc->vardesc.elemdescVar.tdesc, file, NULL, &varrecord->vardescsize);
9923 varrecord->Flags = desc->vardesc.wVarFlags;
9924 varrecord->VarKind = desc->vardesc.varkind;
9925
9926 if(desc->vardesc.varkind == VAR_CONST){
9927 varrecord->vardescsize += sizeof(VARIANT);
9928 varrecord->OffsValue = WMSFT_encode_variant(desc->vardesc.u.lpvarValue, file);
9929 }else
9930 varrecord->OffsValue = desc->vardesc.u.oInst;
9931
9932 /* res9? */
9933 if(desc->HelpStringContext != 0){
9934 size += 5 * sizeof(INT);
9935 varrecord->HelpContext = desc->HelpContext;
9936 if(desc->HelpString)
9937 varrecord->HelpString = desc->HelpString->offset;
9938 else
9939 varrecord->HelpString = -1;
9940 varrecord->res9 = -1;
9941 varrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
9942 varrecord->HelpStringContext = desc->HelpStringContext;
9943 }else if(!list_empty(&desc->custdata_list)){
9944 size += 4 * sizeof(INT);
9945 varrecord->HelpContext = desc->HelpContext;
9946 if(desc->HelpString)
9947 varrecord->HelpString = desc->HelpString->offset;
9948 else
9949 varrecord->HelpString = -1;
9950 varrecord->res9 = -1;
9951 varrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
9952 }else if(desc->HelpString){
9953 size += 2 * sizeof(INT);
9954 varrecord->HelpContext = desc->HelpContext;
9955 if(desc->HelpString)
9956 varrecord->HelpString = desc->HelpString->offset;
9957 else
9958 varrecord->HelpString = -1;
9959 }else if(desc->HelpContext != 0){
9960 size += sizeof(INT);
9961 varrecord->HelpContext = desc->HelpContext;
9962 }
9963
9964 varrecord->Info = size | (i << 16);
9965
9966 *offsets = offs;
9967 offs += size;
9968 ++offsets;
9969
9970 varrecord = (MSFT_VarRecord*)(((char*)varrecord) + size);
9971 }
9972
9973 memid = (MEMBERID*)varrecord;
9974 for(i = 0; i < info->typeattr.cFuncs; ++i){
9975 TLBFuncDesc *desc = &info->funcdescs[i];
9976 *memid = desc->funcdesc.memid;
9977 ++memid;
9978 }
9979 for(i = 0; i < info->typeattr.cVars; ++i){
9980 TLBVarDesc *desc = &info->vardescs[i];
9981 *memid = desc->vardesc.memid;
9982 ++memid;
9983 }
9984
9985 name = (UINT*)memid;
9986 for(i = 0; i < info->typeattr.cFuncs; ++i){
9987 TLBFuncDesc *desc = &info->funcdescs[i];
9988 if(desc->Name)
9989 *name = desc->Name->offset;
9990 else
9991 *name = -1;
9992 ++name;
9993 }
9994 for(i = 0; i < info->typeattr.cVars; ++i){
9995 TLBVarDesc *desc = &info->vardescs[i];
9996 if(desc->Name)
9997 *name = desc->Name->offset;
9998 else
9999 *name = -1;
10000 ++name;
10001 }
10002
10003 return ret;
10004}
10005
10006typedef struct tagWMSFT_RefChunk {
10012
10014{
10015 DWORD offs = file->ref_seg.len, i;
10017
10018 file->ref_seg.len += info->typeattr.cImplTypes * sizeof(WMSFT_RefChunk);
10019 if(!file->ref_seg.data)
10020 file->ref_seg.data = heap_alloc(file->ref_seg.len);
10021 else
10022 file->ref_seg.data = heap_realloc(file->ref_seg.data, file->ref_seg.len);
10023
10024 chunk = (WMSFT_RefChunk*)((char*)file->ref_seg.data + offs);
10025
10026 for(i = 0; i < info->typeattr.cImplTypes; ++i){
10027 chunk->href = info->impltypes[i].hRef;
10028 chunk->res04 = info->impltypes[i].implflags;
10029 chunk->res08 = -1;
10030 if(i < info->typeattr.cImplTypes - 1)
10031 chunk->next = offs + sizeof(WMSFT_RefChunk) * (i + 1);
10032 else
10033 chunk->next = -1;
10034 ++chunk;
10035 }
10036
10037 return offs;
10038}
10039
10041{
10042 DWORD size;
10043
10044 size = sizeof(MSFT_TypeInfoBase);
10045
10046 if(data){
10048 if(info->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
10049 base->typekind = TKIND_DISPATCH;
10050 else
10051 base->typekind = info->typeattr.typekind;
10052 base->typekind |= index << 16; /* TODO: There are some other flags here */
10053 base->typekind |= (info->typeattr.cbAlignment << 11) | (info->typeattr.cbAlignment << 6);
10055 base->res2 = 0;
10056 base->res3 = 0;
10057 base->res4 = 3;
10058 base->res5 = 0;
10059 base->cElement = (info->typeattr.cVars << 16) | info->typeattr.cFuncs;
10060 base->res7 = 0;
10061 base->res8 = 0;
10062 base->res9 = 0;
10063 base->resA = 0;
10064 if(info->guid)
10065 base->posguid = info->guid->offset;
10066 else
10067 base->posguid = -1;
10068 base->flags = info->typeattr.wTypeFlags;
10069 if(info->Name) {
10070 base->NameOffset = info->Name->offset;
10071
10072 ((unsigned char*)file->name_seg.data)[info->Name->offset+9] = 0x38;
10073 *(HREFTYPE*)((unsigned char*)file->name_seg.data+info->Name->offset) = info->hreftype;
10074 }else {
10075 base->NameOffset = -1;
10076 }
10077 base->version = (info->typeattr.wMinorVerNum << 16) | info->typeattr.wMajorVerNum;
10078 if(info->DocString)
10079 base->docstringoffs = info->DocString->offset;
10080 else
10081 base->docstringoffs = -1;
10082 base->helpstringcontext = info->dwHelpStringContext;
10083 base->helpcontext = info->dwHelpContext;
10084 base->oCustData = WMSFT_compile_custdata(info->pcustdata_list, file);
10085 base->cImplTypes = info->typeattr.cImplTypes;
10086 base->cbSizeVft = info->typeattr.cbSizeVft;
10087 base->size = info->typeattr.cbSizeInstance;
10088 if(info->typeattr.typekind == TKIND_COCLASS){
10090 }else if(info->typeattr.typekind == TKIND_ALIAS){
10091 base->datatype1 = WMSFT_append_typedesc(info->tdescAlias, file, NULL, NULL);
10092 }else if(info->typeattr.typekind == TKIND_MODULE){
10093 if(info->DllName)
10094 base->datatype1 = info->DllName->offset;
10095 else
10096 base->datatype1 = -1;
10097 }else{
10098 if(info->typeattr.cImplTypes > 0)
10099 base->datatype1 = info->impltypes[0].hRef;
10100 else
10101 base->datatype1 = -1;
10102 }
10103 base->datatype2 = index; /* FIXME: i think there's more here */
10104 base->res18 = 0;
10105 base->res19 = -1;
10106 }
10107
10108 return size;
10109}
10110
10112{
10113 UINT i;
10114
10115 file->typeinfo_seg.len = 0;
10116 for(i = 0; i < This->TypeInfoCount; ++i){
10117 ITypeInfoImpl *info = This->typeinfos[i];
10118 *junk = file->typeinfo_seg.len;
10119 ++junk;
10120 file->typeinfo_seg.len += WMSFT_compile_typeinfo(info, i, NULL, NULL);
10121 }
10122
10123 file->typeinfo_seg.data = heap_alloc(file->typeinfo_seg.len);
10124 memset(file->typeinfo_seg.data, 0x96, file->typeinfo_seg.len);
10125
10126 file->aux_seg.len = 0;
10127 file->aux_seg.data = NULL;
10128
10129 file->typeinfo_seg.len = 0;
10130 for(i = 0; i < This->TypeInfoCount; ++i){
10131 ITypeInfoImpl *info = This->typeinfos[i];
10132 file->typeinfo_seg.len += WMSFT_compile_typeinfo(info, i, file,
10133 ((char *)file->typeinfo_seg.data) + file->typeinfo_seg.len);
10134 }
10135}
10136
10137typedef struct tagWMSFT_ImpFile {
10142
10144{
10145 TLBImpLib *implib;
10146 WMSFT_ImpFile *impfile;
10147 char *data;
10148 DWORD last_offs = 0;
10149
10150 file->impfile_seg.len = 0;
10151 LIST_FOR_EACH_ENTRY(implib, &This->implib_list, TLBImpLib, entry){
10152 int size = 0;
10153
10154 if(implib->name){
10155 WCHAR *path = wcsrchr(implib->name, '\\');
10156 if(path)
10157 ++path;
10158 else
10159 path = implib->name;
10161 if (size == 0)
10162 ERR("failed to convert wide string: %s\n", debugstr_w(path));
10163 }
10164
10165 size += sizeof(INT16);
10166 if (size % 4)
10167 size = (size + 4) & ~0x3;
10168 if (size < 8)
10169 size = 8;
10170
10171 file->impfile_seg.len += sizeof(WMSFT_ImpFile) + size;
10172 }
10173
10174 data = file->impfile_seg.data = heap_alloc(file->impfile_seg.len);
10175
10176 LIST_FOR_EACH_ENTRY(implib, &This->implib_list, TLBImpLib, entry){
10177 int strlen = 0, size;
10178
10179 impfile = (WMSFT_ImpFile*)data;
10180 impfile->guid_offs = implib->guid->offset;
10181 impfile->lcid = implib->lcid;
10182 impfile->version = (implib->wVersionMinor << 16) | implib->wVersionMajor;
10183
10184 data += sizeof(WMSFT_ImpFile);
10185
10186 if(implib->name){
10187 WCHAR *path= wcsrchr(implib->name, '\\');
10188 if(path)
10189 ++path;
10190 else
10191 path = implib->name;
10193 data + sizeof(INT16), file->impfile_seg.len - last_offs - sizeof(INT16), NULL, NULL);
10194 if (strlen == 0)
10195 ERR("failed to convert wide string: %s\n", debugstr_w(path));
10196 }
10197
10198 *((INT16*)data) = (strlen << 2) | 1; /* FIXME: is that a flag, or what? */
10199
10200 size = strlen + sizeof(INT16);
10201 if (size % 4)
10202 size = (size + 4) & ~0x3;
10203 if (size < 8)
10204 size = 8;
10205 memset(data + sizeof(INT16) + strlen, 0x57, size - strlen - sizeof(INT16));
10206
10207 data += size;
10208 implib->offset = last_offs;
10209 last_offs += size + sizeof(WMSFT_ImpFile);
10210 }
10211}
10212
10214{
10216 TLBRefType *ref_type;
10217 UINT i = 0;
10218
10220
10221 file->impinfo_seg.len = sizeof(MSFT_ImpInfo) * list_count(&This->ref_list);
10222 info = file->impinfo_seg.data = heap_alloc(file->impinfo_seg.len);
10223
10224 LIST_FOR_EACH_ENTRY(ref_type, &This->ref_list, TLBRefType, entry){
10225 info->flags = i | ((ref_type->tkind & 0xFF) << 24);
10226 if(ref_type->index == TLB_REF_USE_GUID){
10228 info->oGuid = ref_type->guid->offset;
10229 }else
10230 info->oGuid = ref_type->index;
10231 info->oImpFile = ref_type->pImpTLInfo->offset;
10232 ++i;
10233 ++info;
10234 }
10235}
10236
10238{
10239 file->guidhash_seg.len = 0x80;
10240 file->guidhash_seg.data = heap_alloc(file->guidhash_seg.len);
10241 memset(file->guidhash_seg.data, 0xFF, file->guidhash_seg.len);
10242}
10243
10245{
10246 file->namehash_seg.len = 0x200;
10247 file->namehash_seg.data = heap_alloc(file->namehash_seg.len);
10248 memset(file->namehash_seg.data, 0xFF, file->namehash_seg.len);
10249}
10250
10251static void tmp_fill_segdir_seg(MSFT_pSeg *segdir, WMSFT_SegContents *contents, DWORD *running_offset)
10252{
10253 if(contents && contents->len){
10254 segdir->offset = *running_offset;
10255 segdir->length = contents->len;
10256 *running_offset += segdir->length;
10257 }else{
10258 segdir->offset = -1;
10259 segdir->length = 0;
10260 }
10261
10262 /* TODO: do these ever change? */
10263 segdir->res08 = -1;
10264 segdir->res0c = 0xf;
10265}
10266
10268{
10269 DWORD written;
10270 if(segment)
10271 WriteFile(outfile, segment->data, segment->len, &written, NULL);
10272}
10273
10275 DWORD file_len)
10276{
10277 DWORD i;
10278 MSFT_TypeInfoBase *base = (MSFT_TypeInfoBase *)file->typeinfo_seg.data;
10279
10280 for(i = 0; i < This->TypeInfoCount; ++i){
10281 base->memoffset += file_len;
10282 ++base;
10283 }
10284
10285 return S_OK;
10286}
10287
10289{
10290 HeapFree(GetProcessHeap(), 0, file->typeinfo_seg.data);
10291 HeapFree(GetProcessHeap(), 0, file->guidhash_seg.data);
10292 HeapFree(GetProcessHeap(), 0, file->guid_seg.data);
10293 HeapFree(GetProcessHeap(), 0, file->ref_seg.data);
10294 HeapFree(GetProcessHeap(), 0, file->impinfo_seg.data);
10295 HeapFree(GetProcessHeap(), 0, file->impfile_seg.data);
10296 HeapFree(GetProcessHeap(), 0, file->namehash_seg.data);
10297 HeapFree(GetProcessHeap(), 0, file->name_seg.data);
10298 HeapFree(GetProcessHeap(), 0, file->string_seg.data);
10299 HeapFree(GetProcessHeap(), 0, file->typdesc_seg.data);
10300 HeapFree(GetProcessHeap(), 0, file->arraydesc_seg.data);
10301 HeapFree(GetProcessHeap(), 0, file->custdata_seg.data);
10302 HeapFree(GetProcessHeap(), 0, file->cdguids_seg.data);
10303 HeapFree(GetProcessHeap(), 0, file->aux_seg.data);
10304}
10305
10307{
10310 DWORD written, junk_size, junk_offs, running_offset;
10311 BOOL br;
10313 HRESULT hres;
10314 DWORD *junk;
10315 UINT i;
10316
10317 TRACE("%p\n", This);
10318
10319 for(i = 0; i < This->TypeInfoCount; ++i)
10320 if(This->typeinfos[i]->needs_layout)
10321 ICreateTypeInfo2_LayOut(&This->typeinfos[i]->ICreateTypeInfo2_iface);
10322
10323 memset(&file, 0, sizeof(file));
10324
10325 file.header.magic1 = 0x5446534D;
10326 file.header.magic2 = 0x00010002;
10327 file.header.lcid = This->set_lcid ? This->set_lcid : MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
10328 file.header.lcid2 = This->set_lcid;
10329 file.header.varflags = 0x40 | This->syskind;
10330 if (This->HelpFile)
10331 file.header.varflags |= 0x10;
10332 if (This->HelpStringDll)
10333 file.header.varflags |= HELPDLLFLAG;
10334 file.header.version = (This->ver_minor << 16) | This->ver_major;
10335 file.header.flags = This->libflags;
10336 file.header.helpstringcontext = 0; /* TODO - SetHelpStringContext not implemented yet */
10337 file.header.helpcontext = This->dwHelpContext;
10338 file.header.res44 = 0x20;
10339 file.header.res48 = 0x80;
10340 file.header.dispatchpos = This->dispatch_href;
10341
10343 /* do name and string compilation to get offsets for other compilations */
10345 if (FAILED(hres)){
10347 return hres;
10348 }
10349
10351 if (FAILED(hres)){
10353 return hres;
10354 }
10355
10358 if (FAILED(hres)){
10360 return hres;
10361 }
10362
10363 if(This->HelpFile)
10364 file.header.helpfile = This->HelpFile->offset;
10365 else
10366 file.header.helpfile = -1;
10367
10368 if(This->DocString)
10369 file.header.helpstring = This->DocString->offset;
10370 else
10371 file.header.helpstring = -1;
10372
10373 /* do some more segment compilation */
10374 file.header.nimpinfos = list_count(&This->ref_list);
10375 file.header.nrtypeinfos = This->TypeInfoCount;
10376
10377 if(This->Name)
10378 file.header.NameOffset = This->Name->offset;
10379 else
10380 file.header.NameOffset = -1;
10381
10382 file.header.CustomDataOffset = WMSFT_compile_custdata(&This->custdata_list, &file);
10383
10384 if(This->guid)
10385 file.header.posguid = This->guid->offset;
10386 else
10387 file.header.posguid = -1;
10388
10389 junk_size = file.header.nrtypeinfos * sizeof(DWORD);
10390 if(file.header.varflags & HELPDLLFLAG)
10391 junk_size += sizeof(DWORD);
10392 if(junk_size){
10393 junk = heap_alloc_zero(junk_size);
10394 if(file.header.varflags & HELPDLLFLAG){
10395 *junk = This->HelpStringDll->offset;
10396 junk_offs = 1;
10397 }else
10398 junk_offs = 0;
10399 }else{
10400 junk = NULL;
10401 junk_offs = 0;
10402 }
10403
10404 WMSFT_compile_typeinfo_seg(This, &file, junk + junk_offs);
10406
10407 running_offset = 0;
10408
10409 TRACE("header at: 0x%x\n", running_offset);
10410 running_offset += sizeof(file.header);
10411
10412 TRACE("junk at: 0x%x\n", running_offset);
10413 running_offset += junk_size;
10414
10415 TRACE("segdir at: 0x%x\n", running_offset);
10416 running_offset += sizeof(file.segdir);
10417
10418 TRACE("typeinfo at: 0x%x\n", running_offset);
10419 tmp_fill_segdir_seg(&file.segdir.pTypeInfoTab, &file.typeinfo_seg, &running_offset);
10420
10421 TRACE("guidhashtab at: 0x%x\n", running_offset);
10422 tmp_fill_segdir_seg(&file.segdir.pGuidHashTab, &file.guidhash_seg, &running_offset);
10423
10424 TRACE("guidtab at: 0x%x\n", running_offset);
10425 tmp_fill_segdir_seg(&file.segdir.pGuidTab, &file.guid_seg, &running_offset);
10426
10427 TRACE("reftab at: 0x%x\n", running_offset);
10428 tmp_fill_segdir_seg(&file.segdir.pRefTab, &file.ref_seg, &running_offset);
10429
10430 TRACE("impinfo at: 0x%x\n", running_offset);
10431 tmp_fill_segdir_seg(&file.segdir.pImpInfo, &file.impinfo_seg, &running_offset);
10432
10433 TRACE("impfiles at: 0x%x\n", running_offset);
10434 tmp_fill_segdir_seg(&file.segdir.pImpFiles, &file.impfile_seg, &running_offset);
10435
10436 TRACE("namehashtab at: 0x%x\n", running_offset);
10437 tmp_fill_segdir_seg(&file.segdir.pNameHashTab, &file.namehash_seg, &running_offset);
10438
10439 TRACE("nametab at: 0x%x\n", running_offset);
10440 tmp_fill_segdir_seg(&file.segdir.pNametab, &file.name_seg, &running_offset);
10441
10442 TRACE("stringtab at: 0x%x\n", running_offset);
10443 tmp_fill_segdir_seg(&file.segdir.pStringtab, &file.string_seg, &running_offset);
10444
10445 TRACE("typdesc at: 0x%x\n", running_offset);
10446 tmp_fill_segdir_seg(&file.segdir.pTypdescTab, &file.typdesc_seg, &running_offset);
10447
10448 TRACE("arraydescriptions at: 0x%x\n", running_offset);
10449 tmp_fill_segdir_seg(&file.segdir.pArrayDescriptions, &file.arraydesc_seg, &running_offset);
10450
10451 TRACE("custdata at: 0x%x\n", running_offset);
10452 tmp_fill_segdir_seg(&file.segdir.pCustData, &file.custdata_seg, &running_offset);
10453
10454 TRACE("cdguids at: 0x%x\n", running_offset);
10455 tmp_fill_segdir_seg(&file.segdir.pCDGuids, &file.cdguids_seg, &running_offset);
10456
10457 TRACE("res0e at: 0x%x\n", running_offset);
10458 tmp_fill_segdir_seg(&file.segdir.res0e, NULL, &running_offset);
10459
10460 TRACE("res0f at: 0x%x\n", running_offset);
10461 tmp_fill_segdir_seg(&file.segdir.res0f, NULL, &running_offset);
10462
10463 TRACE("aux_seg at: 0x%x\n", running_offset);
10464
10465 WMSFT_fixup_typeinfos(This, &file, running_offset);
10466
10471 heap_free(junk);
10472 return TYPE_E_IOERROR;
10473 }
10474
10475 br = WriteFile(outfile, &file.header, sizeof(file.header), &written, NULL);
10476 if (!br) {
10479 heap_free(junk);
10480 return TYPE_E_IOERROR;
10481 }
10482
10483 br = WriteFile(outfile, junk, junk_size, &written, NULL);
10484 heap_free(junk);
10485 if (!br) {
10488 return TYPE_E_IOERROR;
10489 }
10490
10491 br = WriteFile(outfile, &file.segdir, sizeof(file.segdir), &written, NULL);
10492 if (!br) {
10495 return TYPE_E_IOERROR;
10496 }
10497
10498 WMSFT_write_segment(outfile, &file.typeinfo_seg);
10499 WMSFT_write_segment(outfile, &file.guidhash_seg);
10500 WMSFT_write_segment(outfile, &file.guid_seg);
10501 WMSFT_write_segment(outfile, &file.ref_seg);
10502 WMSFT_write_segment(outfile, &file.impinfo_seg);
10503 WMSFT_write_segment(outfile, &file.impfile_seg);
10504 WMSFT_write_segment(outfile, &file.namehash_seg);
10505 WMSFT_write_segment(outfile, &file.name_seg);
10506 WMSFT_write_segment(outfile, &file.string_seg);
10507 WMSFT_write_segment(outfile, &file.typdesc_seg);
10508 WMSFT_write_segment(outfile, &file.arraydesc_seg);
10509 WMSFT_write_segment(outfile, &file.custdata_seg);
10510 WMSFT_write_segment(outfile, &file.cdguids_seg);
10511 WMSFT_write_segment(outfile, &file.aux_seg);
10512
10514
10516
10517 return S_OK;
10518}
10519
10521 LPOLESTR name)
10522{
10524 FIXME("%p %s - stub\n", This, wine_dbgstr_w(name));
10525 return E_NOTIMPL;
10526}
10527
10529 REFGUID guid, VARIANT *varVal)
10530{
10532 TLBGuid *tlbguid;
10533
10534 TRACE("%p %s %p\n", This, debugstr_guid(guid), varVal);
10535
10536 if (!guid || !varVal)
10537 return E_INVALIDARG;
10538
10539 tlbguid = TLB_append_guid(&This->guid_list, guid, -1);
10540
10541 return TLB_set_custdata(&This->custdata_list, tlbguid, varVal);
10542}
10543
10545 ULONG helpStringContext)
10546{
10548 FIXME("%p %u - stub\n", This, helpStringContext);
10549 return E_NOTIMPL;
10550}
10551
10554{
10556 TRACE("%p %s\n", This, wine_dbgstr_w(filename));
10557
10558 if (!filename)
10559 return E_INVALIDARG;
10560
10561 This->HelpStringDll = TLB_append_str(&This->string_list, filename);
10562
10563 return S_OK;
10564}
10565
10566static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl = {
10584};
10585
10587 REFIID riid, void **object)
10588{
10590
10591 return ITypeInfo2_QueryInterface(&This->ITypeInfo2_iface, riid, object);
10592}
10593
10595{
10597
10598 return ITypeInfo2_AddRef(&This->ITypeInfo2_iface);
10599}
10600
10602{
10604
10605 return ITypeInfo2_Release(&This->ITypeInfo2_iface);
10606}
10607
10609 REFGUID guid)
10610{
10612
10613 TRACE("%p %s\n", This, debugstr_guid(guid));
10614
10615 This->guid = TLB_append_guid(&This->pTypeLib->guid_list, guid, This->hreftype);
10616
10617 return S_OK;
10618}
10619
10621 UINT typeFlags)
10622{
10624 WORD old_flags;
10625 HRESULT hres;
10626
10627 TRACE("%p %x\n", This, typeFlags);
10628
10629 if (typeFlags & TYPEFLAG_FDUAL) {
10630 static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 };
10633 HREFTYPE hreftype;
10634 HRESULT hres;
10635
10636 hres = LoadTypeLib(stdole2tlb, &stdole);
10637 if(FAILED(hres))
10638 return hres;
10639
10640 hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch);
10641 ITypeLib_Release(stdole);
10642 if(FAILED(hres))
10643 return hres;
10644
10645 hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype);
10646 ITypeInfo_Release(dispatch);
10647 if(FAILED(hres))
10648 return hres;
10649 }
10650
10651 old_flags = This->typeattr.wTypeFlags;
10652 This->typeattr.wTypeFlags = typeFlags;
10653
10654 hres = ICreateTypeInfo2_LayOut(iface);
10655 if (FAILED(hres)) {
10656 This->typeattr.wTypeFlags = old_flags;
10657 return hres;
10658 }
10659
10660 return S_OK;
10661}
10662
10664 LPOLESTR doc)
10665{
10667
10668 TRACE("%p %s\n", This, wine_dbgstr_w(doc));
10669
10670 if (!doc)
10671 return E_INVALIDARG;
10672
10673 This->DocString = TLB_append_str(&This->pTypeLib->string_list, doc);
10674
10675 return S_OK;
10676}
10677
10679 DWORD helpContext)
10680{
10682
10683 TRACE("%p %d\n", This, helpContext);
10684
10685 This->dwHelpContext = helpContext;
10686
10687 return S_OK;
10688}
10689
10691 WORD majorVerNum, WORD minorVerNum)
10692{
10694
10695 TRACE("%p %d %d\n", This, majorVerNum, minorVerNum);
10696
10697 This->typeattr.wMajorVerNum = majorVerNum;
10698 This->typeattr.wMinorVerNum = minorVerNum;
10699
10700 return S_OK;
10701}
10702
10704 ITypeInfo *typeInfo, HREFTYPE *refType)
10705{
10707 UINT index;
10709 TLBRefType *ref_type;
10710 TLBImpLib *implib;
10711 TYPEATTR *typeattr;
10712 TLIBATTR *libattr;
10713 HRESULT hres;
10714
10715 TRACE("%p %p %p\n", This, typeInfo, refType);
10716
10717 if (!typeInfo || !refType)
10718 return E_INVALIDARG;
10719
10720 hres = ITypeInfo_GetContainingTypeLib(typeInfo, &container, &index);
10721 if (FAILED(hres))
10722 return hres;
10723
10724 if (container == (ITypeLib*)&This->pTypeLib->ITypeLib2_iface) {
10726
10727 ITypeLib_Release(container);
10728
10729 *refType = target->hreftype;
10730
10731 return S_OK;
10732 }
10733
10734 hres = ITypeLib_GetLibAttr(container, &libattr);
10735 if (FAILED(hres)) {
10736 ITypeLib_Release(container);
10737 return hres;
10738 }
10739
10740 LIST_FOR_EACH_ENTRY(implib, &This->pTypeLib->implib_list, TLBImpLib, entry){
10741 if(IsEqualGUID(&implib->guid->guid, &libattr->guid) &&
10742 implib->lcid == libattr->lcid &&
10743 implib->wVersionMajor == libattr->wMajorVerNum &&
10744 implib->wVersionMinor == libattr->wMinorVerNum)
10745 break;
10746 }
10747
10748 if(&implib->entry == &This->pTypeLib->implib_list){
10749 implib = heap_alloc_zero(sizeof(TLBImpLib));
10750
10751 if((ITypeLib2Vtbl*)container->lpVtbl == &tlbvt){
10752 const ITypeLibImpl *our_container = impl_from_ITypeLib2((ITypeLib2*)container);
10753 implib->name = SysAllocString(our_container->path);
10754 }else{
10755 hres = QueryPathOfRegTypeLib(&libattr->guid, libattr->wMajorVerNum,
10756 libattr->wMinorVerNum, libattr->lcid, &implib->name);
10757 if(FAILED(hres)){
10758 implib->name = NULL;
10759 TRACE("QueryPathOfRegTypeLib failed, no name stored: %08x\n", hres);
10760 }
10761 }
10762
10763 implib->guid = TLB_append_guid(&This->pTypeLib->guid_list, &libattr->guid, 2);
10764 implib->lcid = libattr->lcid;
10765 implib->wVersionMajor = libattr->wMajorVerNum;
10766 implib->wVersionMinor = libattr->wMinorVerNum;
10767
10768 list_add_tail(&This->pTypeLib->implib_list, &implib->entry);
10769 }
10770
10771 ITypeLib_ReleaseTLibAttr(container, libattr);
10772 ITypeLib_Release(container);
10773
10774 hres = ITypeInfo_GetTypeAttr(typeInfo, &typeattr);
10775 if (FAILED(hres))
10776 return hres;
10777
10778 index = 0;
10779 LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry){
10780 if(ref_type->index == TLB_REF_USE_GUID &&
10781 IsEqualGUID(&ref_type->guid->guid, &typeattr->guid) &&
10782 ref_type->tkind == typeattr->typekind)
10783 break;
10784 ++index;
10785 }
10786
10787 if(&ref_type->entry == &This->pTypeLib->ref_list){
10788 ref_type = heap_alloc_zero(sizeof(TLBRefType));
10789
10790 ref_type->tkind = typeattr->typekind;
10791 ref_type->pImpTLInfo = implib;
10792 ref_type->reference = index * sizeof(MSFT_ImpInfo);
10793
10794 ref_type->index = TLB_REF_USE_GUID;
10795
10796 ref_type->guid = TLB_append_guid(&This->pTypeLib->guid_list, &typeattr->guid, ref_type->reference+1);
10797
10798 list_add_tail(&This->pTypeLib->ref_list, &ref_type->entry);
10799 }
10800
10801 ITypeInfo_ReleaseTypeAttr(typeInfo, typeattr);
10802
10803 *refType = ref_type->reference | 0x1;
10804
10805 if(IsEqualGUID(&ref_type->guid->guid, &IID_IDispatch))
10806 This->pTypeLib->dispatch_href = *refType;
10807
10808 return S_OK;
10809}
10810
10812 UINT index, FUNCDESC *funcDesc)
10813{
10815 TLBFuncDesc tmp_func_desc, *func_desc;
10816 int buf_size, i;
10817 char *buffer;
10818 HRESULT hres;
10819
10820 TRACE("%p %u %p\n", This, index, funcDesc);
10821
10822 if (!funcDesc || funcDesc->oVft & 3)
10823 return E_INVALIDARG;
10824
10825 switch (This->typeattr.typekind) {
10826 case TKIND_MODULE:
10827 if (funcDesc->funckind != FUNC_STATIC)
10828 return TYPE_E_BADMODULEKIND;
10829 break;
10830 case TKIND_DISPATCH:
10831 if (funcDesc->funckind != FUNC_DISPATCH)
10832 return TYPE_E_BADMODULEKIND;
10833 break;
10834 default:
10835 if (funcDesc->funckind != FUNC_PUREVIRTUAL)
10836 return TYPE_E_BADMODULEKIND;
10837 }
10838
10839 if (index > This->typeattr.cFuncs)
10841
10842 if (funcDesc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF) &&
10843 !funcDesc->cParams)
10845
10846#ifdef _WIN64
10847 if(This->pTypeLib->syskind == SYS_WIN64 &&
10848 funcDesc->oVft % 8 != 0)
10849 return E_INVALIDARG;
10850#endif
10851
10852 memset(&tmp_func_desc, 0, sizeof(tmp_func_desc));
10853 TLBFuncDesc_Constructor(&tmp_func_desc);
10854
10855 tmp_func_desc.funcdesc = *funcDesc;
10856
10857 if (tmp_func_desc.funcdesc.oVft != 0)
10858 tmp_func_desc.funcdesc.oVft |= 1;
10859
10860 if (funcDesc->cScodes && funcDesc->lprgscode) {
10861 tmp_func_desc.funcdesc.lprgscode = heap_alloc(sizeof(SCODE) * funcDesc->cScodes);
10862 memcpy(tmp_func_desc.funcdesc.lprgscode, funcDesc->lprgscode, sizeof(SCODE) * funcDesc->cScodes);
10863 } else {
10864 tmp_func_desc.funcdesc.lprgscode = NULL;
10865 tmp_func_desc.funcdesc.cScodes = 0;
10866 }
10867
10868 buf_size = TLB_SizeElemDesc(&funcDesc->elemdescFunc);
10869 for (i = 0; i < funcDesc->cParams; ++i) {
10870 buf_size += sizeof(ELEMDESC);
10871 buf_size += TLB_SizeElemDesc(funcDesc->lprgelemdescParam + i);
10872 }
10873 tmp_func_desc.funcdesc.lprgelemdescParam = heap_alloc(buf_size);
10874 buffer = (char*)(tmp_func_desc.funcdesc.lprgelemdescParam + funcDesc->cParams);
10875
10876 hres = TLB_CopyElemDesc(&funcDesc->elemdescFunc, &tmp_func_desc.funcdesc.elemdescFunc, &buffer);
10877 if (FAILED(hres)) {
10878 heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
10879 heap_free(tmp_func_desc.funcdesc.lprgscode);
10880 return hres;
10881 }
10882
10883 for (i = 0; i < funcDesc->cParams; ++i) {
10884 hres = TLB_CopyElemDesc(funcDesc->lprgelemdescParam + i,
10885 tmp_func_desc.funcdesc.lprgelemdescParam + i, &buffer);
10886 if (FAILED(hres)) {
10887 heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
10888 heap_free(tmp_func_desc.funcdesc.lprgscode);
10889 return hres;
10890 }
10891 if (tmp_func_desc.funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT &&
10892 tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_VARIANT &&
10893 tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED){
10894 hres = TLB_SanitizeVariant(&tmp_func_desc.funcdesc.lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue);
10895 if (FAILED(hres)) {
10896 heap_free(tmp_func_desc.funcdesc.lprgelemdescParam);
10897 heap_free(tmp_func_desc.funcdesc.lprgscode);
10898 return hres;
10899 }
10900 }
10901 }
10902
10903 tmp_func_desc.pParamDesc = TLBParDesc_Constructor(funcDesc->cParams);
10904
10905 if (This->funcdescs) {
10906 This->funcdescs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->funcdescs,
10907 sizeof(TLBFuncDesc) * (This->typeattr.cFuncs + 1));
10908
10909 if (index < This->typeattr.cFuncs) {
10910 memmove(This->funcdescs + index + 1, This->funcdescs + index,
10911 (This->typeattr.cFuncs - index) * sizeof(TLBFuncDesc));
10912 func_desc = This->funcdescs + index;
10913 } else
10914 func_desc = This->funcdescs + This->typeattr.cFuncs;
10915
10916 /* move custdata lists to the new memory location */
10917 for(i = 0; i < This->typeattr.cFuncs + 1; ++i){
10918 if(index != i){
10919 TLBFuncDesc *fd = &This->funcdescs[i];
10920 if(fd->custdata_list.prev == fd->custdata_list.next)
10921 list_init(&fd->custdata_list);
10922 else{
10923 fd->custdata_list.prev->next = &fd->custdata_list;
10924 fd->custdata_list.next->prev = &fd->custdata_list;
10925 }
10926 }
10927 }
10928 } else
10929 func_desc = This->funcdescs = heap_alloc(sizeof(TLBFuncDesc));
10930
10931 memcpy(func_desc, &tmp_func_desc, sizeof(tmp_func_desc));
10932 list_init(&func_desc->custdata_list);
10933
10934 ++This->typeattr.cFuncs;
10935
10936 This->needs_layout = TRUE;
10937
10938 return S_OK;
10939}
10940
10942 UINT index, HREFTYPE refType)
10943{
10945 TLBImplType *impl_type;
10946 HRESULT hres;
10947
10948 TRACE("%p %u %d\n", This, index, refType);
10949
10950 switch(This->typeattr.typekind){
10951 case TKIND_COCLASS: {
10952 if (index == -1) {
10953 FIXME("Unhandled index: -1\n");
10954 return E_NOTIMPL;
10955 }
10956
10957 if(index != This->typeattr.cImplTypes)
10959
10960 break;
10961 }
10962 case TKIND_INTERFACE:
10963 case TKIND_DISPATCH:
10964 if (index != 0 || This->typeattr.cImplTypes)
10966 break;
10967 default:
10968 FIXME("Unimplemented typekind: %d\n", This->typeattr.typekind);
10969 return E_NOTIMPL;
10970 }
10971
10972 if (This->impltypes){
10973 UINT i;
10974
10975 This->impltypes = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->impltypes,
10976 sizeof(TLBImplType) * (This->typeattr.cImplTypes + 1));
10977
10978 if (index < This->typeattr.cImplTypes) {
10979 memmove(This->impltypes + index + 1, This->impltypes + index,
10980 (This->typeattr.cImplTypes - index) * sizeof(TLBImplType));
10981 impl_type = This->impltypes + index;
10982 } else
10983 impl_type = This->impltypes + This->typeattr.cImplTypes;
10984
10985 /* move custdata lists to the new memory location */
10986 for(i = 0; i < This->typeattr.cImplTypes + 1; ++i){
10987 if(index != i){
10988 TLBImplType *it = &This->impltypes[i];
10989 if(it->custdata_list.prev == it->custdata_list.next)
10991 else{
10992 it->custdata_list.prev->next = &it->custdata_list;
10993 it->custdata_list.next->prev = &it->custdata_list;
10994 }
10995 }
10996 }
10997 } else
10998 impl_type = This->impltypes = heap_alloc(sizeof(TLBImplType));
10999
11000 memset(impl_type, 0, sizeof(TLBImplType));
11001 TLBImplType_Constructor(impl_type);
11002 impl_type->hRef = refType;
11003
11004 ++This->typeattr.cImplTypes;
11005
11006 if((refType & (~0x3)) == (This->pTypeLib->dispatch_href & (~0x3)))
11007 This->typeattr.wTypeFlags |= TYPEFLAG_FDISPATCHABLE;
11008
11009 hres = ICreateTypeInfo2_LayOut(iface);
11010 if (FAILED(hres))
11011 return hres;
11012
11013 return S_OK;
11014}
11015
11017 UINT index, INT implTypeFlags)
11018{
11020 TLBImplType *impl_type = &This->impltypes[index];
11021
11022 TRACE("%p %u %x\n", This, index, implTypeFlags);
11023
11024 if (This->typeattr.typekind != TKIND_COCLASS)
11025 return TYPE_E_BADMODULEKIND;
11026
11027 if (index >= This->typeattr.cImplTypes)
11029
11030 impl_type->implflags = implTypeFlags;
11031
11032 return S_OK;
11033}
11034
11036 WORD alignment)
11037{
11039
11040 TRACE("%p %d\n", This, alignment);
11041
11042 This->typeattr.cbAlignment = alignment;
11043
11044 return S_OK;
11045}
11046
11049{
11051
11052 TRACE("%p %s\n", This, wine_dbgstr_w(schema));
11053
11054 if (!schema)
11055 return E_INVALIDARG;
11056
11057 This->Schema = TLB_append_str(&This->pTypeLib->string_list, schema);
11058
11059 This->typeattr.lpstrSchema = This->Schema->str;
11060
11061 return S_OK;
11062}
11063
11065 UINT index, VARDESC *varDesc)
11066{
11068 TLBVarDesc *var_desc;
11069
11070 TRACE("%p %u %p\n", This, index, varDesc);
11071
11072 if (This->vardescs){
11073 UINT i;
11074
11075 This->vardescs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->vardescs,
11076 sizeof(TLBVarDesc) * (This->typeattr.cVars + 1));
11077
11078 if (index < This->typeattr.cVars) {
11079 memmove(This->vardescs + index + 1, This->vardescs + index,
11080 (This->typeattr.cVars - index) * sizeof(TLBVarDesc));
11081 var_desc = This->vardescs + index;
11082 } else
11083 var_desc = This->vardescs + This->typeattr.cVars;
11084
11085 /* move custdata lists to the new memory location */
11086 for(i = 0; i < This->typeattr.cVars + 1; ++i){
11087 if(index != i){
11088 TLBVarDesc *var = &This->vardescs[i];
11089 if(var->custdata_list.prev == var->custdata_list.next)
11090 list_init(&var->custdata_list);
11091 else{
11092 var->custdata_list.prev->next = &var->custdata_list;
11093 var->custdata_list.next->prev = &var->custdata_list;
11094 }
11095 }
11096 }
11097 } else
11098 var_desc = This->vardescs = heap_alloc_zero(sizeof(TLBVarDesc));
11099
11100 TLBVarDesc_Constructor(var_desc);
11101 TLB_AllocAndInitVarDesc(varDesc, &var_desc->vardesc_create);
11102 var_desc->vardesc = *var_desc->vardesc_create;
11103
11104 ++This->typeattr.cVars;
11105
11106 This->needs_layout = TRUE;
11107
11108 return S_OK;
11109}
11110
11112 UINT index, LPOLESTR *names, UINT numNames)
11113{
11115 TLBFuncDesc *func_desc = &This->funcdescs[index];
11116 int i;
11117
11118 TRACE("%p %u %p %u\n", This, index, names, numNames);
11119
11120 if (!names)
11121 return E_INVALIDARG;
11122
11123 if (index >= This->typeattr.cFuncs || numNames == 0)
11125
11126 if (func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)){
11127 if(numNames > func_desc->funcdesc.cParams)
11129 } else
11130 if(numNames > func_desc->funcdesc.cParams + 1)
11132
11133 for(i = 0; i < This->typeattr.cFuncs; ++i) {
11134 TLBFuncDesc *iter = &This->funcdescs[i];
11135 if (iter->Name && !wcscmp(TLB_get_bstr(iter->Name), *names)) {
11136 if (iter->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) &&
11137 func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) &&
11138 func_desc->funcdesc.invkind != iter->funcdesc.invkind)
11139 continue;
11140 return TYPE_E_AMBIGUOUSNAME;
11141 }
11142 }
11143
11144 func_desc->Name = TLB_append_str(&This->pTypeLib->name_list, *names);
11145
11146 for (i = 1; i < numNames; ++i) {
11147 TLBParDesc *par_desc = func_desc->pParamDesc + i - 1;
11148 par_desc->Name = TLB_append_str(&This->pTypeLib->name_list, *(names + i));
11149 }
11150
11151 return S_OK;
11152}
11153
11156{
11158
11159 TRACE("%p %u %s\n", This, index, wine_dbgstr_w(name));
11160
11161 if(!name)
11162 return E_INVALIDARG;
11163
11164 if(index >= This->typeattr.cVars)
11166
11167 This->vardescs[index].Name = TLB_append_str(&This->pTypeLib->name_list, name);
11168 return S_OK;
11169}
11170
11172 TYPEDESC *tdescAlias)
11173{
11175 HRESULT hr;
11176
11177 TRACE("%p %p\n", This, tdescAlias);
11178
11179 if(!tdescAlias)
11180 return E_INVALIDARG;
11181
11182 if(This->typeattr.typekind != TKIND_ALIAS)
11183 return TYPE_E_BADMODULEKIND;
11184
11185 hr = TLB_size_instance(This, This->pTypeLib->syskind, tdescAlias, &This->typeattr.cbSizeInstance, &This->typeattr.cbAlignment);
11186 if(FAILED(hr))
11187 return hr;
11188
11189 heap_free(This->tdescAlias);
11190 This->tdescAlias = heap_alloc(TLB_SizeTypeDesc(tdescAlias, TRUE));
11191 TLB_CopyTypeDesc(NULL, tdescAlias, This->tdescAlias);
11192
11193 return S_OK;
11194}
11195
11197 UINT index, LPOLESTR dllName, LPOLESTR procName)
11198{
11200 FIXME("%p %u %s %s - stub\n", This, index, wine_dbgstr_w(dllName), wine_dbgstr_w(procName));
11201 return E_NOTIMPL;
11202}
11203
11205 UINT index, LPOLESTR docString)
11206{
11208 TLBFuncDesc *func_desc = &This->funcdescs[index];
11209
11210 TRACE("%p %u %s\n", This, index, wine_dbgstr_w(docString));
11211
11212 if(!docString)
11213 return E_INVALIDARG;
11214
11215 if(index >= This->typeattr.cFuncs)
11217
11218 func_desc->HelpString = TLB_append_str(&This->pTypeLib->string_list, docString);
11219
11220 return S_OK;
11221}
11222
11224 UINT index, LPOLESTR docString)
11225{
11227 TLBVarDesc *var_desc = &This->vardescs[index];
11228
11229 TRACE("%p %u %s\n", This, index, wine_dbgstr_w(docString));
11230
11231 if(!docString)
11232 return E_INVALIDARG;
11233
11234 if(index >= This->typeattr.cVars)
11236
11237 var_desc->HelpString = TLB_append_str(&This->pTypeLib->string_list, docString);
11238
11239 return S_OK;
11240}
11241
11243 UINT index, DWORD helpContext)
11244{
11246 TLBFuncDesc *func_desc = &This->funcdescs[index];
11247
11248 TRACE("%p %u %d\n", This, index, helpContext);
11249
11250 if(index >= This->typeattr.cFuncs)
11252
11253 func_desc->helpcontext = helpContext;
11254
11255 return S_OK;
11256}
11257
11259 UINT index, DWORD helpContext)
11260{
11262 TLBVarDesc *var_desc = &This->vardescs[index];
11263
11264 TRACE("%p %u %d\n", This, index, helpContext);
11265
11266 if(index >= This->typeattr.cVars)
11268
11269 var_desc->HelpContext = helpContext;
11270
11271 return S_OK;
11272}
11273
11275 UINT index, BSTR bstrMops)
11276{
11278 FIXME("%p %u %s - stub\n", This, index, wine_dbgstr_w(bstrMops));
11279 return E_NOTIMPL;
11280}
11281
11283 IDLDESC *idlDesc)
11284{
11286
11287 TRACE("%p %p\n", This, idlDesc);
11288
11289 if (!idlDesc)
11290 return E_INVALIDARG;
11291
11292 This->typeattr.idldescType.dwReserved = idlDesc->dwReserved;
11293 This->typeattr.idldescType.wIDLFlags = idlDesc->wIDLFlags;
11294
11295 return S_OK;
11296}
11297
11299{
11301 ITypeInfo *tinfo;
11302 TLBFuncDesc *func_desc;
11303 UINT user_vft = 0, i, depth = 0;
11304 HRESULT hres = S_OK;
11305
11306 TRACE("%p\n", This);
11307
11308 This->needs_layout = FALSE;
11309
11310 hres = ICreateTypeInfo2_QueryInterface(iface, &IID_ITypeInfo, (LPVOID*)&tinfo);
11311 if (FAILED(hres))
11312 return hres;
11313
11314 if (This->typeattr.typekind == TKIND_INTERFACE) {
11315 ITypeInfo *inh;
11316 TYPEATTR *attr;
11317 HREFTYPE inh_href;
11318
11319 hres = ITypeInfo_GetRefTypeOfImplType(tinfo, 0, &inh_href);
11320
11321 if (SUCCEEDED(hres)) {
11322 hres = ITypeInfo_GetRefTypeInfo(tinfo, inh_href, &inh);
11323
11324 if (SUCCEEDED(hres)) {
11325 hres = ITypeInfo_GetTypeAttr(inh, &attr);
11326 if (FAILED(hres)) {
11327 ITypeInfo_Release(inh);
11328 ITypeInfo_Release(tinfo);
11329 return hres;
11330 }
11331 This->typeattr.cbSizeVft = attr->cbSizeVft;
11332 ITypeInfo_ReleaseTypeAttr(inh, attr);
11333
11334 do{
11335 ++depth;
11336 hres = ITypeInfo_GetRefTypeOfImplType(inh, 0, &inh_href);
11337 if(SUCCEEDED(hres)){
11338 ITypeInfo *next;
11339 hres = ITypeInfo_GetRefTypeInfo(inh, inh_href, &next);
11340 if(SUCCEEDED(hres)){
11341 ITypeInfo_Release(inh);
11342 inh = next;
11343 }
11344 }
11345 }while(SUCCEEDED(hres));
11346 hres = S_OK;
11347
11348 ITypeInfo_Release(inh);
11349 } else if (hres == TYPE_E_ELEMENTNOTFOUND) {
11350 This->typeattr.cbSizeVft = 0;
11351 hres = S_OK;
11352 } else {
11353 ITypeInfo_Release(tinfo);
11354 return hres;
11355 }
11356 } else if (hres == TYPE_E_ELEMENTNOTFOUND) {
11357 This->typeattr.cbSizeVft = 0;
11358 hres = S_OK;
11359 } else {
11360 ITypeInfo_Release(tinfo);
11361 return hres;
11362 }
11363 } else if (This->typeattr.typekind == TKIND_DISPATCH)
11364 This->typeattr.cbSizeVft = 7 * This->pTypeLib->ptr_size;
11365 else
11366 This->typeattr.cbSizeVft = 0;
11367
11368 func_desc = This->funcdescs;
11369 i = 0;
11370 while (i < This->typeattr.cFuncs) {
11371 if (!(func_desc->funcdesc.oVft & 0x1))
11372 func_desc->funcdesc.oVft = This->typeattr.cbSizeVft;
11373
11374 if ((func_desc->funcdesc.oVft & 0xFFFC) > user_vft)
11375 user_vft = func_desc->funcdesc.oVft & 0xFFFC;
11376
11377 This->typeattr.cbSizeVft += This->pTypeLib->ptr_size;
11378
11379 if (func_desc->funcdesc.memid == MEMBERID_NIL) {
11380 TLBFuncDesc *iter;
11381 UINT j = 0;
11382 BOOL reset = FALSE;
11383
11384 func_desc->funcdesc.memid = 0x60000000 + (depth << 16) + i;
11385
11386 iter = This->funcdescs;
11387 while (j < This->typeattr.cFuncs) {
11388 if (iter != func_desc && iter->funcdesc.memid == func_desc->funcdesc.memid) {
11389 if (!reset) {
11390 func_desc->funcdesc.memid = 0x60000000 + (depth << 16) + This->typeattr.cFuncs;
11391 reset = TRUE;
11392 } else
11393 ++func_desc->funcdesc.memid;
11394 iter = This->funcdescs;
11395 j = 0;
11396 } else {
11397 ++iter;
11398 ++j;
11399 }
11400 }
11401 }
11402
11403 ++func_desc;
11404 ++i;
11405 }
11406
11407 if (user_vft > This->typeattr.cbSizeVft)
11408 This->typeattr.cbSizeVft = user_vft + This->pTypeLib->ptr_size;
11409
11410 for(i = 0; i < This->typeattr.cVars; ++i){
11411 TLBVarDesc *var_desc = &This->vardescs[i];
11412 if(var_desc->vardesc.memid == MEMBERID_NIL){
11413 UINT j = 0;
11414 BOOL reset = FALSE;
11415 TLBVarDesc *iter;
11416
11417 var_desc->vardesc.memid = 0x40000000 + (depth << 16) + i;
11418
11419 iter = This->vardescs;
11420 while (j < This->typeattr.cVars) {
11421 if (iter != var_desc && iter->vardesc.memid == var_desc->vardesc.memid) {
11422 if (!reset) {
11423 var_desc->vardesc.memid = 0x40000000 + (depth << 16) + This->typeattr.cVars;
11424 reset = TRUE;
11425 } else
11426 ++var_desc->vardesc.memid;
11427 iter = This->vardescs;
11428 j = 0;
11429 } else {
11430 ++iter;
11431 ++j;
11432 }
11433 }
11434 }
11435 }
11436
11437 ITypeInfo_Release(tinfo);
11438 return hres;
11439}
11440
11442 UINT index)
11443{
11445 FIXME("%p %u - stub\n", This, index);
11446 return E_NOTIMPL;
11447}
11448
11450 MEMBERID memid, INVOKEKIND invKind)
11451{
11453 FIXME("%p %x %d - stub\n", This, memid, invKind);
11454 return E_NOTIMPL;
11455}
11456
11458 UINT index)
11459{
11461 FIXME("%p %u - stub\n", This, index);
11462 return E_NOTIMPL;
11463}
11464
11466 MEMBERID memid)
11467{
11469 FIXME("%p %x - stub\n", This, memid);
11470 return E_NOTIMPL;
11471}
11472
11474 UINT index)
11475{
11477 FIXME("%p %u - stub\n", This, index);
11478 return E_NOTIMPL;
11479}
11480
11482 REFGUID guid, VARIANT *varVal)
11483{
11484 TLBGuid *tlbguid;
11485
11487
11488 TRACE("%p %s %p\n", This, debugstr_guid(guid), varVal);
11489
11490 if (!guid || !varVal)
11491 return E_INVALIDARG;
11492
11493 tlbguid = TLB_append_guid(&This->pTypeLib->guid_list, guid, -1);
11494
11495 return TLB_set_custdata(This->pcustdata_list, tlbguid, varVal);
11496}
11497
11499 UINT index, REFGUID guid, VARIANT *varVal)
11500{
11502 FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
11503 return E_NOTIMPL;
11504}
11505
11507 UINT funcIndex, UINT paramIndex, REFGUID guid, VARIANT *varVal)
11508{
11510 FIXME("%p %u %u %s %p - stub\n", This, funcIndex, paramIndex, debugstr_guid(guid), varVal);
11511 return E_NOTIMPL;
11512}
11513
11515 UINT index, REFGUID guid, VARIANT *varVal)
11516{
11518 FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
11519 return E_NOTIMPL;
11520}
11521
11523 UINT index, REFGUID guid, VARIANT *varVal)
11524{
11526 FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
11527 return E_NOTIMPL;
11528}
11529
11531 ULONG helpStringContext)
11532{
11534
11535 TRACE("%p %u\n", This, helpStringContext);
11536
11537 This->dwHelpStringContext = helpStringContext;
11538
11539 return S_OK;
11540}
11541
11543 UINT index, ULONG helpStringContext)
11544{
11546 FIXME("%p %u %u - stub\n", This, index, helpStringContext);
11547 return E_NOTIMPL;
11548}
11549
11551 UINT index, ULONG helpStringContext)
11552{
11554 FIXME("%p %u %u - stub\n", This, index, helpStringContext);
11555 return E_NOTIMPL;
11556}
11557
11559{
11561 FIXME("%p - stub\n", This);
11562 return E_NOTIMPL;
11563}
11564
11566 LPOLESTR name)
11567{
11569
11570 TRACE("%p %s\n", This, wine_dbgstr_w(name));
11571
11572 if (!name)
11573 return E_INVALIDARG;
11574
11575 This->Name = TLB_append_str(&This->pTypeLib->name_list, name);
11576
11577 return S_OK;
11578}
11579
11580static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl = {
11622};
11623
11624/******************************************************************************
11625 * ClearCustData (OLEAUT32.171)
11626 *
11627 * Clear a custom data type's data.
11628 *
11629 * PARAMS
11630 * lpCust [I] The custom data type instance
11631 *
11632 * RETURNS
11633 * Nothing.
11634 */
11635void WINAPI ClearCustData(CUSTDATA *lpCust)
11636{
11637 if (lpCust && lpCust->cCustData)
11638 {
11639 if (lpCust->prgCustData)
11640 {
11641 DWORD i;
11642
11643 for (i = 0; i < lpCust->cCustData; i++)
11644 VariantClear(&lpCust->prgCustData[i].varValue);
11645
11646 CoTaskMemFree(lpCust->prgCustData);
11647 lpCust->prgCustData = NULL;
11648 }
11649 lpCust->cCustData = 0;
11650 }
11651}
BOOL WINAPI DECLSPEC_HOTPATCH GetFileInformationByHandleEx(HANDLE handle, FILE_INFO_BY_HANDLE_CLASS class, LPVOID info, DWORD size)
unsigned short UINT16
signed short INT16
InitDirComponents & cd
PRTL_UNICODE_STRING_BUFFER Path
@ optional
Definition: SystemMenu.c:34
_STLP_INLINE_LOOP _STLP_STD::pair< _InputIter1, _InputIter2 > mismatch(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2)
Definition: _algobase.h:522
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static const WCHAR nameW[]
Definition: main.c:49
#define index(s, c)
Definition: various.h:29
static VOID HelpContext(PCONTEXT_ENTRY pContext)
Definition: help.c:39
#define ARRAY_SIZE(A)
Definition: main.h:20
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: list.h:37
LPARAM lParam
Definition: combotst.c:139
#define md
Definition: compat-1.3.h:2013
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HINSTANCE instance
Definition: main.c:40
unsigned int idx
Definition: utils.c:41
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegDeleteKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1286
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LSTATUS WINAPI RegQueryValueW(HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count)
Definition: reg.c:4241
LONG WINAPI RegEnumKeyExA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2419
HMODULE hModule
Definition: animate.c:44
#define CDECL
Definition: compat.h:29
#define CloseHandle
Definition: compat.h:739
double DATE
Definition: compat.h:2253
#define wcschr
Definition: compat.h:17
union tagCY CY
#define GetProcessHeap()
Definition: compat.h:736
#define PAGE_READONLY
Definition: compat.h:138
struct tagDEC DECIMAL
int(* FARPROC)()
Definition: compat.h:36
#define UnmapViewOfFile
Definition: compat.h:746
#define wcsrchr
Definition: compat.h:16
#define FIXME_(x)
Definition: compat.h:77
struct tagVARIANT VARIANT
Definition: compat.h:2377
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define TRACE_(x)
Definition: compat.h:76
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
WCHAR OLECHAR
Definition: compat.h:2292
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define FreeLibrary(x)
Definition: compat.h:748
OLECHAR * BSTR
Definition: compat.h:2293
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define TRACE_ON(x)
Definition: compat.h:75
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define IsWow64Process
Definition: compat.h:760
#define MAX_PATH
Definition: compat.h:34
unsigned short VARTYPE
Definition: compat.h:2254
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MapViewOfFile
Definition: compat.h:745
#define MultiByteToWideChar
Definition: compat.h:110
#define LoadLibraryW(x)
Definition: compat.h:747
#define FILE_SHARE_READ
Definition: compat.h:136
LONG SCODE
Definition: compat.h:2252
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
@ VT_BLOB
Definition: compat.h:2330
@ VT_UI8
Definition: compat.h:2315
@ VT_BLOB_OBJECT
Definition: compat.h:2335
@ VT_BSTR
Definition: compat.h:2303
@ VT_VOID
Definition: compat.h:2318
@ VT_INT
Definition: compat.h:2316
@ VT_LPSTR
Definition: compat.h:2324
@ VT_R4
Definition: compat.h:2299
@ VT_NULL
Definition: compat.h:2296
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_TYPEMASK
Definition: compat.h:2346
@ VT_RESERVED
Definition: compat.h:2343
@ VT_BYREF
Definition: compat.h:2342
@ VT_PTR
Definition: compat.h:2320
@ VT_UI2
Definition: compat.h:2312
@ VT_DECIMAL
Definition: compat.h:2309
@ VT_ERROR
Definition: compat.h:2305
@ VT_CLSID
Definition: compat.h:2337
@ VT_STREAM
Definition: compat.h:2331
@ VT_ARRAY
Definition: compat.h:2341
@ VT_STORED_OBJECT
Definition: compat.h:2334
@ VT_SAFEARRAY
Definition: compat.h:2321
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_R8
Definition: compat.h:2300
@ VT_CY
Definition: compat.h:2301
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I8
Definition: compat.h:2314
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_CF
Definition: compat.h:2336
@ VT_STORAGE
Definition: compat.h:2332
@ VT_USERDEFINED
Definition: compat.h:2323
@ VT_HRESULT
Definition: compat.h:2319
@ VT_FILETIME
Definition: compat.h:2329
@ VT_DATE
Definition: compat.h:2302
@ VT_BOOL
Definition: compat.h:2306
@ VT_STREAMED_OBJECT
Definition: compat.h:2333
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_UINT
Definition: compat.h:2317
@ VT_EMPTY
Definition: compat.h:2295
@ VT_CARRAY
Definition: compat.h:2322
@ VT_VECTOR
Definition: compat.h:2340
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
#define wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
BOOL WINAPI FindActCtxSectionGuid(DWORD dwFlags, const GUID *lpExtGuid, ULONG ulId, const GUID *lpSearchGuid, PACTCTX_SECTION_KEYED_DATA pInfo)
Definition: actctx.c:265
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
BOOL WINAPI EnumResourceNamesW(HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam)
Definition: res.c:358
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
LCID WINAPI GetSystemDefaultLCID(void)
Definition: locale.c:1230
BOOL is_wow64
Definition: msi.c:52
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
Definition: errorinfo.c:417
ULONG WINAPI LHashValOfNameSysA(SYSKIND skind, LCID lcid, LPCSTR lpStr)
Definition: hash.c:506
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
static ITypeInfoImpl * info_impl_from_ICreateTypeInfo2(ICreateTypeInfo2 *iface)
Definition: typelib.c:1294
static void TLBFuncDesc_Constructor(TLBFuncDesc *func_desc)
Definition: typelib.c:1786
struct tagITypeInfoImpl ITypeInfoImpl
static HRESULT WINAPI ITypeLib2_fnGetTypeComp(ITypeLib2 *iface, ITypeComp **ppTComp)
Definition: typelib.c:5021
static const WCHAR HELPDIRW[]
Definition: typelib.c:579
static TLBGuid * TLB_append_guid(struct list *guid_list, const GUID *new_guid, HREFTYPE hreftype)
Definition: typelib.c:1828
static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(ITypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8548
void WINAPI ClearCustData(CUSTDATA *lpCust)
Definition: typelib.c:11635
static HRESULT TLB_copy_all_custdata(struct list *custdata_list, CUSTDATA *pCustData)
Definition: typelib.c:5360
static SIZE_T TLB_SizeElemDesc(const ELEMDESC *elemdesc)
Definition: typelib.c:5816
static HRESULT WINAPI ITypeLib2_fnGetLibAttr(ITypeLib2 *iface, LPTLIBATTR *attr)
Definition: typelib.c:4992
static WCHAR * get_interface_key(REFGUID guid, WCHAR *buffer)
Definition: typelib.c:253
static HRESULT WINAPI ITypeInfo_fnGetVarDesc(ITypeInfo2 *iface, UINT index, LPVARDESC *ppVarDesc)
Definition: typelib.c:6168
static HRESULT MSFT_ReadAllGuids(TLBContext *pcx)
Definition: typelib.c:2080
static HRESULT WINAPI ITypeInfo_fnInvoke(ITypeInfo2 *iface, VOID *pIUnk, MEMBERID memid, UINT16 wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr)
Definition: typelib.c:7283
static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(ITypeLib2 *iface, REFGUID guid, ITypeInfo **ppTInfo)
Definition: typelib.c:4966
static TLBGuid * MSFT_ReadGuid(int offset, TLBContext *pcx)
Definition: typelib.c:2105
static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(ITypeInfo2 *iface, MEMBERID memid, LCID lcid, BSTR *pbstrHelpString, DWORD *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
Definition: typelib.c:8580
static ULONG WINAPI TLB_Mapping_Release(IUnknown *iface)
Definition: typelib.c:3218
static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib)
Definition: typelib.c:3777
static void TLB_unregister_interface(GUID *guid, REGSAM flag)
Definition: typelib.c:854
static int TLB_str_memcmp(void *left, const TLBString *str, DWORD len)
Definition: typelib.c:1322
static WORD SLTG_ReadStringA(const char *ptr, char **str)
Definition: typelib.c:3797
static void MSFT_ReadValue(VARIANT *pVar, int offset, TLBContext *pcx)
Definition: typelib.c:2213
static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 *iface)
Definition: typelib.c:10306
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(ICreateTypeInfo2 *iface, UINT index)
Definition: typelib.c:11473
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(ICreateTypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11498
static const ITypeCompVtbl tlbtcvt
Definition: typelib.c:1146
static void TLBVarDesc_Constructor(TLBVarDesc *var_desc)
Definition: typelib.c:1749
struct tagTLBString TLBString
static int MSFT_CustData(TLBContext *pcx, int offset, struct list *custdata_list)
Definition: typelib.c:2300
static TLBImplType * TLBImplType_Alloc(UINT n)
Definition: typelib.c:1812
HRESULT ITypeInfoImpl_GetInternalFuncDesc(ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc)
Definition: typelib.c:5976
static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
Definition: typelib.c:10601
static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
Definition: typelib.c:4447
static HRESULT WINAPI ITypeComp_fnQueryInterface(ITypeComp *iface, REFIID riid, LPVOID *ppv)
Definition: typelib.c:8901
static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, const char *pNameTable, const sltg_ref_lookup_t *ref_lookup, const BYTE *hlp_strings)
Definition: typelib.c:4107
static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(ICreateTypeInfo2 *iface, LPOLESTR schema)
Definition: typelib.c:11047
static HRESULT WINAPI ITypeComp_fnBindType(ITypeComp *iface, OLECHAR *szName, ULONG lHash, ITypeInfo **ppTInfo, ITypeComp **ppTComp)
Definition: typelib.c:9011
static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 *iface, REFGUID guid)
Definition: typelib.c:9190
static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(ITypeInfo2 *iface, UINT index, CUSTDATA *pCustData)
Definition: typelib.c:8656
static void WMSFT_free_file(WMSFT_TLBFile *file)
Definition: typelib.c:10288
static HRESULT WMSFT_fixup_typeinfos(ITypeLibImpl *This, WMSFT_TLBFile *file, DWORD file_len)
Definition: typelib.c:10274
static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId(ITypeInfo2 *iface, MEMBERID memid, UINT *pVarIndex)
Definition: typelib.c:8408
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(ICreateTypeInfo2 *iface, UINT index, DWORD helpContext)
Definition: typelib.c:11242
static ITypeInfoImpl * MSFT_DoTypeInfo(TLBContext *pcx, int count, ITypeLibImpl *pLibInfo)
Definition: typelib.c:2658
#define FromLEDWords(X, Y)
Definition: typelib.c:166
static void tmp_fill_segdir_seg(MSFT_pSeg *segdir, WMSFT_SegContents *contents, DWORD *running_offset)
Definition: typelib.c:10251
static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib)
Definition: typelib.c:3286
static HRESULT MSFT_ReadAllStrings(TLBContext *pcx)
Definition: typelib.c:2762
static ULONG WINAPI ITypeInfo_fnAddRef(ITypeInfo2 *iface)
Definition: typelib.c:5677
static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(ICreateTypeInfo2 *iface, WORD majorVerNum, WORD minorVerNum)
Definition: typelib.c:10690
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT typeFlags)
Definition: typelib.c:10620
static HRESULT WMSFT_compile_guids(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9436
static HRESULT WINAPI ICreateTypeLib2_fnSetName(ICreateTypeLib2 *iface, LPOLESTR name)
Definition: typelib.c:9162
static char * SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, BOOL OneOnly, const sltg_ref_lookup_t *ref_lookup)
Definition: typelib.c:4069
static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd)
Definition: typelib.c:2322
static HRESULT WINAPI ITypeLibComp_fnBindType(ITypeComp *iface, OLECHAR *szName, ULONG lHash, ITypeInfo **ppTInfo, ITypeComp **ppTComp)
Definition: typelib.c:5581
static HRESULT TLB_set_custdata(struct list *custdata_list, TLBGuid *tlbguid, VARIANT *var)
Definition: typelib.c:1850
static void TLB_FreeVarDesc(VARDESC *)
Definition: typelib.c:5968
static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags(ITypeInfo2 *iface, ULONG *pTypeFlags)
Definition: typelib.c:8366
static HRESULT WINAPI TLB_PEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: typelib.c:2878
static TLBVarDesc * TLB_get_vardesc_by_name(TLBVarDesc *vardescs, UINT n, const OLECHAR *name)
Definition: typelib.c:1716
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 *iface, DWORD helpContext)
Definition: typelib.c:9232
static WCHAR * get_typelib_key(REFGUID guid, WORD wMaj, WORD wMin, WCHAR *buffer)
Definition: typelib.c:240
static HRESULT WINAPI ITypeLibComp_fnBind(ITypeComp *iface, OLECHAR *szName, ULONG lHash, WORD wFlags, ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
Definition: typelib.c:5442
static TLBVarDesc * TLB_get_vardesc_by_memberid(TLBVarDesc *vardescs, UINT n, MEMBERID memid)
Definition: typelib.c:1704
static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *out_mix, INT16 *out_size)
Definition: typelib.c:9601
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 *iface, LPOLESTR helpFileName)
Definition: typelib.c:9217
static const IUnknownVtbl TLB_Mapping_Vtable
Definition: typelib.c:3235
static void dump_TypeInfo(const ITypeInfoImpl *pty)
Definition: typelib.c:1573
static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(ITypeInfo2 *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo)
Definition: typelib.c:8009
static ITypeLibImpl * impl_from_ITypeLib(ITypeLib *iface)
Definition: typelib.c:1154
static ITypeLibImpl * TypeLibImpl_Constructor(void)
Definition: typelib.c:3429
static void TLBImplType_Constructor(TLBImplType *impl)
Definition: typelib.c:1807
static void dump_ELEMDESC(const ELEMDESC *edesc)
Definition: typelib.c:1405
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(ICreateTypeInfo2 *iface, TYPEDESC *tdescAlias)
Definition: typelib.c:11171
static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(ITypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8456
static TLBCustData * TLB_get_custdata_by_guid(struct list *custdata_list, REFGUID guid)
Definition: typelib.c:1728
static const GUID * TLB_get_guidref(const TLBGuid *guid)
Definition: typelib.c:1329
static void ITypeInfoImpl_FuncDescAddHrefOffset(LPFUNCDESC pFuncDesc, UINT hrefoffset)
Definition: typelib.c:6055
static TLBString * TLB_append_str(struct list *string_list, BSTR new_str)
Definition: typelib.c:1884
static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup, const BYTE *hlp_strings)
Definition: typelib.c:4224
static DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, LONG where)
Definition: typelib.c:2046
static HRESULT WINAPI ITypeInfo2_fnGetTypeKind(ITypeInfo2 *iface, TYPEKIND *pTypeKind)
Definition: typelib.c:8350
HRESULT WINAPI CreateTypeLib(SYSKIND syskind, LPCOLESTR file, ICreateTypeLib **ctlib)
Definition: typelib.c:425
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(ICreateTypeInfo2 *iface, UINT index, LPOLESTR name)
Definition: typelib.c:11154
static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(ICreateTypeLib2 *iface, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:10528
#define DISPATCH_HREF_OFFSET
Definition: typelib.c:129
static void WMSFT_compile_impinfo(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:10213
static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(ITypeLib2 *iface, UINT index, ITypeInfo **ppTInfo)
Definition: typelib.c:4915
static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(ICreateTypeInfo2 *iface, UINT index, INT implTypeFlags)
Definition: typelib.c:11016
static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
Definition: typelib.c:4350
struct tagTLBContext TLBContext
static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
Definition: typelib.c:9088
static void dump_TLBVarDesc(const TLBVarDesc *pvd, UINT n)
Definition: typelib.c:1502
#define FromLEDWord(X)
Definition: typelib.c:126
static void WINAPI ITypeInfo_fnReleaseFuncDesc(ITypeInfo2 *iface, FUNCDESC *pFuncDesc)
Definition: typelib.c:8316
static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData(ITypeInfo2 *iface, UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
Definition: typelib.c:8677
static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
Definition: typelib.c:3242
static void MSFT_DoFuncs(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, int cVars, int offset, TLBFuncDesc **pptfd)
Definition: typelib.c:2340
static HRESULT WINAPI ITypeLib2_fnGetAllCustData(ITypeLib2 *iface, CUSTDATA *pCustData)
Definition: typelib.c:5390
static TLBFuncDesc * TLB_get_funcdesc_by_memberid(TLBFuncDesc *funcdescs, UINT n, MEMBERID memid)
Definition: typelib.c:1692
static HRESULT sltg_get_typelib_ref(const sltg_ref_lookup_t *table, DWORD typeinfo_ref, HREFTYPE *typelib_ref)
Definition: typelib.c:3885
static SIZE_T TLB_SizeTypeDesc(const TYPEDESC *tdesc, BOOL alloc_initial_space)
Definition: typelib.c:1619
static int read_xx_header(HFILE lzfd)
Definition: typelib.c:3018
static ULONG WINAPI ITypeComp_fnAddRef(ITypeComp *iface)
Definition: typelib.c:8908
static UINT WINAPI ITypeLib2_fnGetTypeInfoCount(ITypeLib2 *iface)
Definition: typelib.c:4904
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(ICreateTypeInfo2 *iface, UINT index)
Definition: typelib.c:11441
static const IUnknownVtbl TLB_NEFile_Vtable
Definition: typelib.c:3008
static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 *iface, LPOLESTR doc)
Definition: typelib.c:9202
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(ICreateTypeInfo2 *iface, UINT index, ULONG helpStringContext)
Definition: typelib.c:11550
static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(ICreateTypeInfo2 *iface, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11481
static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
Definition: typelib.c:4412
static void dump_TLBRefType(const ITypeLibImpl *pTL)
Definition: typelib.c:1520
static const TLBString * decode_string(const BYTE *table, const char *stream, DWORD stream_length, ITypeLibImpl *lib)
Definition: typelib.c:3742
static HRESULT WINAPI ITypeInfo_fnGetMops(ITypeInfo2 *iface, MEMBERID memid, BSTR *pBstrMops)
Definition: typelib.c:8265
static const ITypeCompVtbl tcompvt
Definition: typelib.c:1300
static HRESULT TLB_size_instance(ITypeInfoImpl *info, SYSKIND sys, TYPEDESC *tdesc, ULONG *size, WORD *align)
Definition: typelib.c:1939
HRESULT WINAPI CreateDispTypeInfo(INTERFACEDATA *pidata, LCID lcid, ITypeInfo **pptinfo)
Definition: typelib.c:8792
static const IUnknownVtbl TLB_PEFile_Vtable
Definition: typelib.c:2911
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(ICreateTypeInfo2 *iface, UINT index, LPOLESTR docString)
Definition: typelib.c:11223
static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags(ITypeInfo2 *iface, UINT index, INT *pImplTypeFlags)
Definition: typelib.c:6322
static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(ITypeInfo2 *iface, UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8485
static HRESULT WINAPI ITypeLib2_fnGetDocumentation(ITypeLib2 *iface, INT index, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
Definition: typelib.c:5043
static HRESULT WINAPI ITypeInfo_fnGetTypeComp(ITypeInfo2 *iface, ITypeComp **ppTComp)
Definition: typelib.c:5804
static TYPEDESC std_typedesc[VT_LPWSTR+1]
Definition: typelib.c:1599
static const ITypeInfo2Vtbl tinfvt
Definition: typelib.c:1299
static WCHAR * get_lcid_subkey(LCID lcid, SYSKIND syskind, WCHAR *buffer)
Definition: typelib.c:264
HRESULT WINAPI LoadRegTypeLib(REFGUID rguid, WORD wVerMajor, WORD wVerMinor, LCID lcid, ITypeLib **ppTLib)
Definition: typelib.c:531
#define X(x)
static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, int cVars, int offset, TLBVarDesc **pptvd)
Definition: typelib.c:2537
HRESULT WINAPI CreateTypeLib2(SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib2 **ppctlib)
Definition: typelib.c:9043
static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(ITypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8519
static HRESULT WINAPI ITypeInfo_fnCreateInstance(ITypeInfo2 *iface, IUnknown *pOuterUnk, REFIID riid, VOID **ppvObj)
Definition: typelib.c:8211
static BOOL find_typelib_key(REFGUID guid, WORD *wMaj, WORD *wMin)
Definition: typelib.c:172
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(ICreateTypeInfo2 *iface, UINT index, ULONG helpStringContext)
Definition: typelib.c:11542
static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
Definition: typelib.c:2918
static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl)
Definition: typelib.c:3827
static BSTR TLB_get_bstr(const TLBString *str)
Definition: typelib.c:1317
static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(ITypeLib2 *iface, INT index, LCID lcid, BSTR *pbstrHelpString, DWORD *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
Definition: typelib.c:5300
static void WMSFT_write_segment(HANDLE outfile, WMSFT_SegContents *segment)
Definition: typelib.c:10267
HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const WCHAR *szHelpDir)
Definition: typelib.c:656
static void dump_TLBImpLib(const TLBImpLib *import)
Definition: typelib.c:1512
static ITypeInfoImpl * TLB_get_typeinfo_by_name(ITypeInfoImpl **typeinfos, UINT n, const OLECHAR *name)
Definition: typelib.c:1737
static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
Definition: typelib.c:4440
#define INVBUF_GET_ARG_PTR_ARRAY(buffer, params)
Definition: typelib.c:7278
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 *iface, LPOLESTR filename)
Definition: typelib.c:10552
HRESULT WINAPI DispCallFunc(void *pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals, VARTYPE *prgvt, VARIANTARG **prgpvarg, VARIANT *pvargResult)
Definition: typelib.c:7071
static ULONG WINAPI TLB_NEFile_AddRef(IUnknown *iface)
Definition: typelib.c:2990
static void ITypeInfoImpl_ElemDescAddHrefOffset(LPELEMDESC pElemDesc, UINT hrefoffset)
Definition: typelib.c:6032
static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData(ITypeInfo2 *iface, UINT index, CUSTDATA *pCustData)
Definition: typelib.c:8699
static void WINAPI ITypeInfo_fnReleaseVarDesc(ITypeInfo2 *iface, VARDESC *pVarDesc)
Definition: typelib.c:8336
static ITypeLib2 * ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
Definition: typelib.c:4487
static BOOL CALLBACK search_res_tlb(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam)
Definition: typelib.c:7971
static void * TLB_CopyTypeDesc(TYPEDESC *dest, const TYPEDESC *src, void *buffer)
Definition: typelib.c:1641
static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames(ITypeInfo2 *iface, LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
Definition: typelib.c:6349
static void MSFT_Seek(TLBContext *pcx, LONG where)
Definition: typelib.c:2030
struct tagWMSFT_TLBFile WMSFT_TLBFile
static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *tattr, DWORD flag)
Definition: typelib.c:583
static DWORD WMSFT_append_arraydesc(ARRAYDESC *desc, WMSFT_TLBFile *file)
Definition: typelib.c:9574
static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
Definition: typelib.c:3145
static HRESULT WMSFT_compile_names(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9346
static TLBString * MSFT_ReadString(TLBContext *pcx, int offset)
Definition: typelib.c:2196
static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(ICreateTypeInfo2 *iface, ULONG helpStringContext)
Definition: typelib.c:11530
static HRESULT WINAPI ICreateTypeInfo2_fnSetMops(ICreateTypeInfo2 *iface, UINT index, BSTR bstrMops)
Definition: typelib.c:11274
struct tagTLBGuid TLBGuid
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(ICreateTypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind)
Definition: typelib.c:11449
static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib(ITypeInfo2 *iface, ITypeLib **ppTLib, UINT *pIndex)
Definition: typelib.c:8279
static ULONG WINAPI ITypeComp_fnRelease(ITypeComp *iface)
Definition: typelib.c:8915
#define XX(x)
static CRITICAL_SECTION_DEBUG cache_section_debug
Definition: typelib.c:2854
static HRESULT TLB_AllocAndInitFuncDesc(const FUNCDESC *src, FUNCDESC **dest_ptr, BOOL dispinterface)
Definition: typelib.c:5871
#define INVBUF_GET_MISSING_ARG_ARRAY(buffer, params)
Definition: typelib.c:7276
static TLB_PEFile * pefile_impl_from_IUnknown(IUnknown *iface)
Definition: typelib.c:2873
static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, int offset)
Definition: typelib.c:2593
static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface, UINT index, FUNCDESC *funcDesc)
Definition: typelib.c:10811
static HRESULT MSFT_ReadAllNames(TLBContext *pcx)
Definition: typelib.c:2135
static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(ICreateTypeInfo2 *iface, UINT index, VARDESC *varDesc)
Definition: typelib.c:11064
static HRESULT WINAPI ITypeLibComp_fnQueryInterface(ITypeComp *iface, REFIID riid, LPVOID *ppv)
Definition: typelib.c:5421
static TLB_Mapping * mapping_impl_from_IUnknown(IUnknown *iface)
Definition: typelib.c:3195
static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(ICreateTypeInfo2 *iface, DWORD helpContext)
Definition: typelib.c:10678
static void dump_TypeDesc(const TYPEDESC *pTD, char *szVarType)
Definition: typelib.c:1356
struct tagWMSFT_SegContents WMSFT_SegContents
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData(ICreateTypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11514
HRESULT WINAPI LoadTypeLibEx(LPCOLESTR szFile, REGKIND regkind, ITypeLib **pptLib)
Definition: typelib.c:473
#define INVBUF_ELEMENT_SIZE
Definition: typelib.c:7273
HRESULT WINAPI QueryPathOfRegTypeLib(REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path)
Definition: typelib.c:406
static HRESULT query_typelib_path(REFGUID guid, WORD wMaj, WORD wMin, SYSKIND syskind, LCID lcid, BSTR *path, BOOL redir)
Definition: typelib.c:301
static void dump_VARDESC(const VARDESC *v)
Definition: typelib.c:1589
static ITypeLibImpl * impl_from_ICreateTypeLib2(ICreateTypeLib2 *iface)
Definition: typelib.c:1164
static TLBVarDesc * TLBVarDesc_Alloc(UINT n)
Definition: typelib.c:1754
struct tagWMSFT_ImpFile WMSFT_ImpFile
struct tagITypeLibImpl ITypeLibImpl
static ITypeInfoImpl * ITypeInfoImpl_Constructor(void)
Definition: typelib.c:5623
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc(ICreateTypeInfo2 *iface, UINT index)
Definition: typelib.c:11457
#define FromLEWord(X)
Definition: typelib.c:125
static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(ITypeLib2 *iface, UINT index, TYPEKIND *pTKind)
Definition: typelib.c:4941
static TLBString * SLTG_ReadName(const char *pNameTable, int offset, ITypeLibImpl *lib)
Definition: typelib.c:3810
static BOOL find_ne_resource(HFILE lzfd, LPCSTR typeid, LPCSTR resid, DWORD *resLen, DWORD *resOff)
Definition: typelib.c:3049
static HRESULT WINAPI ITypeLib2_fnIsName(ITypeLib2 *iface, LPOLESTR szNameBuf, ULONG lHashVal, BOOL *pfName)
Definition: typelib.c:5131
static void WMSFT_compile_guidhash(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:10237
static VOID WINAPI ITypeLib2_fnReleaseTLibAttr(ITypeLib2 *iface, TLIBATTR *pTLibAttr)
Definition: typelib.c:5240
static void dump_TLBImplType(const TLBImplType *impl, UINT n)
Definition: typelib.c:1540
static HRESULT WINAPI ITypeInfo_fnAddressOfMember(ITypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
Definition: typelib.c:8152
static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
Definition: typelib.c:7081
static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 *iface, WORD majorVerNum, WORD minorVerNum)
Definition: typelib.c:9177
static void dump_DispParms(const DISPPARAMS *pdp)
Definition: typelib.c:1552
#define TLB_REF_USE_GUID
Definition: typelib.c:1194
static HRESULT TLB_SanitizeBSTR(BSTR str)
Definition: typelib.c:5844
static struct list tlb_cache
Definition: typelib.c:2852
static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
Definition: typelib.c:5741
static DWORD WMSFT_compile_typeinfo_aux(ITypeInfoImpl *info, WMSFT_TLBFile *file)
Definition: typelib.c:9707
static const char * lookup_code(const BYTE *table, DWORD table_size, struct bitstream *bits)
Definition: typelib.c:3703
static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This)
Definition: typelib.c:5690
static HRESULT WINAPI ICreateTypeInfo2_fnSetName(ICreateTypeInfo2 *iface, LPOLESTR name)
Definition: typelib.c:11565
static ULONG WINAPI TLB_PEFile_AddRef(IUnknown *iface)
Definition: typelib.c:2890
static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(ICreateTypeLib2 *iface, LPOLESTR name)
Definition: typelib.c:10520
static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
Definition: typelib.c:7215
static CRITICAL_SECTION cache_section
Definition: typelib.c:2853
static ITypeLibImpl * impl_from_ITypeLib2(ITypeLib2 *iface)
Definition: typelib.c:1149
static HRESULT WINAPI ITypeInfo_fnQueryInterface(ITypeInfo2 *iface, REFIID riid, VOID **ppvObject)
Definition: typelib.c:5646
static ULONG WINAPI TLB_PEFile_Release(IUnknown *iface)
Definition: typelib.c:2896
static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(ITypeInfo2 *iface, UINT index, CUSTDATA *pCustData)
Definition: typelib.c:8718
static const ITypeLib2Vtbl tlbvt
Definition: typelib.c:1145
static sltg_ref_lookup_t * SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, char *pNameTable)
Definition: typelib.c:3983
static const WCHAR ProxyStubClsidW[]
Definition: typelib.c:580
static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(ICreateTypeInfo2 *iface, LPOLESTR doc)
Definition: typelib.c:10663
static ULONG WINAPI TLB_NEFile_Release(IUnknown *iface)
Definition: typelib.c:2996
static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface, UINT index, HREFTYPE refType)
Definition: typelib.c:10941
static BOOL TLB_is_propgetput(INVOKEKIND invkind)
Definition: typelib.c:2332
#define TLB_REF_INTERNAL
Definition: typelib.c:1196
HRESULT WINAPI RegisterTypeLibForUser(ITypeLib *ptlib, OLECHAR *szFullPath, OLECHAR *szHelpDir)
Definition: typelib.c:1026
static void WMSFT_compile_impfile(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:10143
static void WMSFT_compile_namehash(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:10244
HRESULT WINAPI UnRegisterTypeLib(REFGUID libid, WORD wVerMajor, WORD wVerMinor, LCID lcid, SYSKIND syskind)
Definition: typelib.c:882
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(ICreateTypeInfo2 *iface, UINT index, LPOLESTR *names, UINT numNames)
Definition: typelib.c:11111
static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail, const BYTE *hlp_strings)
Definition: typelib.c:4377
static ULONG WINAPI ITypeLibComp_fnAddRef(ITypeComp *iface)
Definition: typelib.c:5428
static int get_ptr_size(SYSKIND syskind)
Definition: typelib.c:1339
static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 *iface, REFIID riid, void **ppv)
Definition: typelib.c:4782
static BOOL func_restricted(const FUNCDESC *desc)
Definition: typelib.c:7268
static HRESULT TLB_CopyElemDesc(const ELEMDESC *src, ELEMDESC *dest, char **buffer)
Definition: typelib.c:5824
static ITypeInfoImpl * impl_from_ITypeInfo2(ITypeInfo2 *iface)
Definition: typelib.c:1284
static const WCHAR ProxyStubClsid32W[]
Definition: typelib.c:581
static ITypeInfoImpl * info_impl_from_ITypeComp(ITypeComp *iface)
Definition: typelib.c:1279
static HRESULT WINAPI ITypeInfo_fnGetFuncDesc(ITypeInfo2 *iface, UINT index, LPFUNCDESC *ppFuncDesc)
Definition: typelib.c:6069
static HRESULT WINAPI ITypeInfo_fnGetTypeAttr(ITypeInfo2 *iface, LPTYPEATTR *ppTypeAttr)
Definition: typelib.c:5766
static HRESULT WINAPI ITypeLib2_fnFindName(ITypeLib2 *iface, LPOLESTR name, ULONG hash, ITypeInfo **ppTInfo, MEMBERID *memid, UINT16 *found)
Definition: typelib.c:5178
static HRESULT WINAPI ITypeInfo_fnGetDocumentation(ITypeInfo2 *iface, MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
Definition: typelib.c:7821
static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 *iface, UINT libFlags)
Definition: typelib.c:9256
static WORD * SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem, const sltg_ref_lookup_t *ref_lookup)
Definition: typelib.c:3960
struct tagTLBImpLib TLBImpLib
static ITypeLibImpl * impl_from_ITypeComp(ITypeComp *iface)
Definition: typelib.c:1159
static const char *const typekind_desc[]
Definition: typelib.c:1460
static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr)
Definition: typelib.c:6110
static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 *iface)
Definition: typelib.c:4810
struct tagTLBRefType TLBRefType
static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(ICreateTypeLib2 *iface, LPOLESTR name, TYPEKIND kind, ICreateTypeInfo **ctinfo)
Definition: typelib.c:9095
static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(ITypeLib2 *iface, ULONG *pcUniqueNames, ULONG *pcchUniqueNames)
Definition: typelib.c:5279
static HRESULT WINAPI ITypeInfo_fnGetDllEntry(ITypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
Definition: typelib.c:7892
static const GUID * TLB_get_guid_null(const TLBGuid *guid)
Definition: typelib.c:1334
static void WINAPI ITypeInfo_fnReleaseTypeAttr(ITypeInfo2 *iface, TYPEATTR *pTypeAttr)
Definition: typelib.c:8304
static HRESULT TLB_SanitizeVariant(VARIANT *var)
Definition: typelib.c:5853
static HRESULT ITypeInfoImpl_GetInternalDispatchFuncDesc(ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc, UINT *funcs, UINT *hrefoffset)
Definition: typelib.c:5989
static HRESULT WINAPI ITypeLib2_fnGetCustData(ITypeLib2 *iface, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:5253
struct tagWMSFT_RefChunk WMSFT_RefChunk
static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *file)
Definition: typelib.c:9674
static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(ICreateTypeInfo2 *iface)
Definition: typelib.c:11298
static ITypeLib2 * ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
Definition: typelib.c:3457
static DWORD MSFT_ReadLEWords(void *buffer, DWORD count, TLBContext *pcx, LONG where)
Definition: typelib.c:2069
static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl
Definition: typelib.c:1301
static void dump_FUNCDESC(const FUNCDESC *funcdesc)
Definition: typelib.c:1421
static HRESULT ITypeInfoImpl_GetDispatchRefTypeInfo(ITypeInfo *iface, HREFTYPE *hRefType, ITypeInfo **ppTInfo)
Definition: typelib.c:7935
struct tagTLBCustData TLBCustData
struct tagTLBImplType TLBImplType
static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(ICreateTypeInfo2 *iface, WORD alignment)
Definition: typelib.c:11035
static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(ITypeInfo2 *iface, CUSTDATA *pCustData)
Definition: typelib.c:8640
static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(ICreateTypeInfo2 *iface, UINT funcIndex, UINT paramIndex, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11506
static DWORD MSFT_ReadLEDWords(void *buffer, DWORD count, TLBContext *pcx, LONG where)
Definition: typelib.c:2058
static void dump_TLBFuncDesc(const TLBFuncDesc *pfd, UINT n)
Definition: typelib.c:1493
static HRESULT WINAPI ITypeComp_fnBind(ITypeComp *iface, OLECHAR *szName, ULONG lHash, WORD wFlags, ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
Definition: typelib.c:8922
static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(ICreateTypeLib2 *iface, REFIID riid, void **object)
Definition: typelib.c:9073
static DWORD WMSFT_encode_variant(VARIANT *value, WMSFT_TLBFile *file)
Definition: typelib.c:9465
static ULONG WINAPI TLB_Mapping_AddRef(IUnknown *iface)
Definition: typelib.c:3212
static WORD * SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_lookup_t *ref_lookup)
Definition: typelib.c:3899
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(ICreateTypeInfo2 *iface, MEMBERID memid)
Definition: typelib.c:11465
static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData(ICreateTypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11522
static const WCHAR TypeLibW[]
Definition: typelib.c:577
static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4384
static BOOL TLB_GUIDFromString(const char *str, GUID *guid)
Definition: typelib.c:3674
static ITypeInfoImpl * impl_from_ITypeInfo(ITypeInfo *iface)
Definition: typelib.c:1289
static HRESULT WINAPI ITypeInfo_fnGetNames(ITypeInfo2 *iface, MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
Definition: typelib.c:6191
static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid)
Definition: typelib.c:10608
static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
Definition: typelib.c:10594
#define INVBUF_GET_ARG_ARRAY(buffer, params)
Definition: typelib.c:7275
static HREFTYPE MSFT_ReadHreftype(TLBContext *pcx, int offset)
Definition: typelib.c:2119
static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
Definition: typelib.c:9081
static TLBString * MSFT_ReadName(TLBContext *pcx, int offset)
Definition: typelib.c:2182
#define INVBUF_GET_ARG_TYPE_ARRAY(buffer, params)
Definition: typelib.c:7280
static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4329
static const WCHAR FLAGSW[]
Definition: typelib.c:578
static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
Definition: typelib.c:7148
static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId(ITypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
Definition: typelib.c:8379
static HRESULT WMSFT_compile_strings(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9292
static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate(ICreateTypeInfo2 *iface)
Definition: typelib.c:11558
HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib **pptLib)
Definition: typelib.c:458
struct tagTLBParDesc TLBParDesc
static ULONG WINAPI ITypeLibComp_fnRelease(ITypeComp *iface)
Definition: typelib.c:5435
HRESULT WINAPI UnRegisterTypeLibForUser(REFGUID libid, WORD wVerMajor, WORD wVerMinor, LCID lcid, SYSKIND syskind)
Definition: typelib.c:1045
static HRESULT TLB_get_size_from_hreftype(ITypeInfoImpl *info, HREFTYPE href, ULONG *size, WORD *align)
Definition: typelib.c:1911
static void TLB_FreeElemDesc(ELEMDESC *elemdesc)
Definition: typelib.c:5865
#define SLTG_SIGNATURE
Definition: typelib.c:3285
static int hash_guid(GUID *guid)
Definition: typelib.c:9426
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 *iface, ULONG helpStringContext)
Definition: typelib.c:10544
#define FromLEWords(X, Y)
Definition: typelib.c:165
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(ICreateTypeInfo2 *iface, UINT index, LPOLESTR docString)
Definition: typelib.c:11204
static TLBFuncDesc * TLBFuncDesc_Alloc(UINT n)
Definition: typelib.c:1791
static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 *iface)
Definition: typelib.c:4820
static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(ICreateTypeInfo2 *iface, ITypeInfo *typeInfo, HREFTYPE *refType)
Definition: typelib.c:10703
static HRESULT MSFT_ReadAllRefs(TLBContext *pcx)
Definition: typelib.c:2807
static TLB_NEFile * nefile_impl_from_IUnknown(IUnknown *iface)
Definition: typelib.c:2973
#define TLB_REF_NOT_FOUND
Definition: typelib.c:1197
static void WMSFT_compile_typeinfo_seg(ITypeLibImpl *This, WMSFT_TLBFile *file, DWORD *junk)
Definition: typelib.c:10111
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(ICreateTypeInfo2 *iface, UINT index, DWORD helpContext)
Definition: typelib.c:11258
static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 *iface, LCID lcid)
Definition: typelib.c:9244
static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl
Definition: typelib.c:1147
static HRESULT WINAPI TLB_NEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: typelib.c:2978
struct tagTLBFuncDesc TLBFuncDesc
static void TLB_FreeCustData(struct list *custdata_list)
Definition: typelib.c:1669
static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(ICreateTypeInfo2 *iface, UINT index, LPOLESTR dllName, LPOLESTR procName)
Definition: typelib.c:11196
static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(ITypeInfo2 *iface, UINT index, HREFTYPE *pRefType)
Definition: typelib.c:6264
static BSTR TLB_MultiByteToBSTR(const char *ptr)
Definition: typelib.c:1680
#define DISPATCH_HREF_MASK
Definition: typelib.c:130
static DWORD WMSFT_compile_typeinfo(ITypeInfoImpl *info, INT16 index, WMSFT_TLBFile *file, char *data)
Definition: typelib.c:10040
static DWORD WMSFT_compile_typeinfo_ref(ITypeInfoImpl *info, WMSFT_TLBFile *file)
Definition: typelib.c:10013
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(ICreateTypeInfo2 *iface, IDLDESC *idlDesc)
Definition: typelib.c:11282
static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(ICreateTypeInfo2 *iface, REFIID riid, void **object)
Definition: typelib.c:10586
static void TLB_abort(void)
Definition: typelib.c:1612
static HRESULT WINAPI ITypeInfo2_fnGetCustData(ITypeInfo2 *iface, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8429
static HRESULT WINAPI TLB_Mapping_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: typelib.c:3200
struct tagTLBVarDesc TLBVarDesc
static void dump_TLBFuncDescOne(const TLBFuncDesc *pfd)
Definition: typelib.c:1473
static TLBParDesc * TLBParDesc_Constructor(UINT n)
Definition: typelib.c:1770
struct tagMSFT_ImpInfo MSFT_ImpInfo
#define SLTG_FUNCTION_FLAGS_PRESENT
Definition: typelib.h:501
#define SLTG_REF_MAGIC
Definition: typelib.h:546
#define SLTG_COMPOBJ_MAGIC
Definition: typelib.h:337
#define SLTG_TIHEADER_MAGIC
Definition: typelib.h:424
#define SLTG_FUNCTION_MAGIC
Definition: typelib.h:502
#define DO_NOT_SEEK
Definition: typelib.h:31
#define SLTG_STATIC_FUNCTION_MAGIC
Definition: typelib.h:504
struct tagMSFT_TypeInfoBase MSFT_TypeInfoBase
#define SLTG_IMPL_MAGIC
Definition: typelib.h:571
#define SLTG_LIBBLK_MAGIC
Definition: typelib.h:384
#define SLTG_VAR_WITH_FLAGS_MAGIC
Definition: typelib.h:587
#define HELPDLLFLAG
Definition: typelib.h:30
#define SLTG_DISPATCH_FUNCTION_MAGIC
Definition: typelib.h:503
#define SLTG_DIR_MAGIC
Definition: typelib.h:338
#define MSFT_IMPINFO_OFFSET_IS_GUID
Definition: typelib.h:174
#define SLTG_VAR_MAGIC
Definition: typelib.h:586
#define MSFT_SIGNATURE
Definition: typelib.h:56
static const WCHAR win32W[]
Definition: cache.c:44
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define swprintf
Definition: precomp.h:40
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
#define ULONG_PTR
Definition: config.h:101
int align(int length, int align)
Definition: dsound8.c:36
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
uint8_t junk[422]
Definition: fsck.fat.h:34
static const FxOffsetAndName offsets[]
MdFileObject pFile
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLboolean reset
Definition: glext.h:5666
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint GLuint * names
Definition: glext.h:11545
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLuint GLuint num
Definition: glext.h:9618
GLfloat param
Definition: glext.h:5796
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLuint64EXT * result
Definition: glext.h:11304
GLintptr offset
Definition: glext.h:5920
GLenum target
Definition: glext.h:7315
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
FxContextHeader * pHeader
Definition: handleapi.cpp:604
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
@ extra
Definition: id3.c:95
static ITypeInfo * typeinfos[LAST_tid]
Definition: ieframe_main.c:35
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
Definition: msctf.idl:550
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t cc
Definition: isohybrid.c:75
uint32_t entry
Definition: isohybrid.c:63
#define SEEK_SET
Definition: jmemansi.c:26
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define a
Definition: ke_i.h:78
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
if(dx< 0)
Definition: linetemp.h:194
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
LONG WINAPI LZSeek(HFILE fd, LONG off, INT type)
Definition: lzexpand.c:431
INT WINAPI LZRead(HFILE fd, LPSTR vbuf, INT toread)
Definition: lzexpand.c:345
HFILE WINAPI LZOpenFileW(LPWSTR fn, LPOFSTRUCT ofs, WORD mode)
Definition: lzexpand.c:580
void WINAPI LZClose(HFILE fd)
Definition: lzexpand.c:595
const WCHAR * schema
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define for
Definition: utility.h:88
#define MESSAGE
Definition: options.h:86
#define SEEK_CUR
Definition: util.h:63
char string[160]
Definition: util.h:11
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LPCWSTR szPath
Definition: env.c:37
static PVOID ptr
Definition: dispmode.c:27
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const DWORD ptr_size
Definition: registry.c:42
static const WCHAR desc[]
Definition: protectdata.c:36
static HMODULE dll
Definition: str.c:188
const char * var
Definition: shader.c:5666
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
HRESULT hres
Definition: protocol.c:465
static const WCHAR sd[]
Definition: suminfo.c:286
static DWORD LPDWORD reslen
Definition: directory.c:51
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:100
static char * dest
Definition: rtl.c:135
static LPOLESTR
Definition: stg_prop.c:27
static void * vtable[]
Definition: typelib.c:1231
static OLECHAR OLECHAR *static SYSKIND
Definition: typelib.c:80
static const char * contents
Definition: parser.c:511
static VARIANTARG static DISPID
Definition: ordinal.c:52
static const GUID * guid_list[]
Definition: metadata.c:2260
#define __ASM_NAME(name)
Definition: config.h:934
#define __ASM_GLOBAL_FUNC(name, code)
Definition: port.h:201
int other
Definition: msacm.c:1376
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static const WCHAR spaceW[]
Definition: mxwriter.c:44
_Out_ PULONG _Out_ PULONG pIndex
Definition: ndis.h:4565
unsigned int UINT
Definition: ndis.h:50
#define SEC_COMMIT
Definition: mmtypes.h:100
static LPUNKNOWN
Definition: ndr_ole.c:49
u32_t magic(void)
#define KEY_READ
Definition: nt_native.h:1023
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define KEY_WRITE
Definition: nt_native.h:1031
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
#define LPVOID
Definition: nt_native.h:45
#define LOCALE_USER_DEFAULT
#define MAKELCID(lgid, srtid)
HRESULT WINAPI DECLSPEC_HOTPATCH GetActiveObject(REFCLSID rcid, LPVOID preserved, LPUNKNOWN *ppunk)
Definition: oleaut.c:592
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
Definition: oleaut.c:428
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_ERROR(A)
Definition: oleauto.h:241
#define V_I8(A)
Definition: oleauto.h:249
#define V_BOOL(A)
Definition: oleauto.h:224
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_ISBYREF(A)
Definition: oleauto.h:217
#define MEMBERID_NIL
Definition: oleauto.h:1003
#define V_VARIANTREF(A)
Definition: oleauto.h:283
#define V_VT(A)
Definition: oleauto.h:211
@ REGKIND_NONE
Definition: oleauto.h:927
@ REGKIND_DEFAULT
Definition: oleauto.h:925
@ REGKIND_REGISTER
Definition: oleauto.h:926
#define V_NONE(A)
Definition: oleauto.h:220
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_BYREF(A)
Definition: oleauto.h:228
enum tagREGKIND REGKIND
#define V_I4(A)
Definition: oleauto.h:247
#define V_R4(A)
Definition: oleauto.h:260
#define V_UI4(A)
Definition: oleauto.h:270
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define V_R8(A)
Definition: oleauto.h:262
#define V_UI8(A)
Definition: oleauto.h:272
#define V_I2(A)
Definition: oleauto.h:245
#define V_UNION(A, B)
Definition: oleauto.h:212
const GUID IID_IDispatch
#define LOWORD(l)
Definition: pedump.c:82
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define IMAGE_OS2_SIGNATURE
Definition: pedump.c:90
unsigned short USHORT
Definition: pedump.c:61
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
#define INT
Definition: polytest.cpp:20
static const WCHAR szName[]
Definition: powrprof.c:45
_Out_opt_ int * cx
Definition: commctrl.h:585
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define IID_NULL
Definition: guiddef.h:98
static unsigned __int64 next
Definition: rand_nt.c:6
#define __ASM_CFI(str)
Definition: asm.h:39
#define __ASM_SEH(str)
Definition: asm.h:45
const WCHAR * str
struct @5012 regs[]
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANGID(l)
Definition: nls.h:17
#define LANG_ENGLISH
Definition: nls.h:52
#define SUBLANG_NEUTRAL
Definition: nls.h:167
DWORD LCID
Definition: nls.h:13
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
#define ERR_(ch,...)
Definition: debug.h:156
#define ERR_ON(ch)
Definition: debug.h:412
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
Definition: list.h:155
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
static struct __wine_debug_functions funcs
Definition: debug.c:59
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
@ LIBFLAG_FHASDISKIMAGE
Definition: actctx.c:78
static const WCHAR typelibW[]
Definition: actctx.c:702
#define args
Definition: format.c:66
LOCAL int table_size
Definition: write.c:65
HRESULT hr
Definition: shlfolder.c:183
DataType
Definition: simd.h:252
#define TRACE(s)
Definition: solgame.cpp:4
@ CC_CDECL
Definition: spec2def.c:94
@ CC_STDCALL
Definition: spec2def.c:93
static PIXELFORMATDESCRIPTOR pfd
Definition: ssstars.c:67
INT next
Definition: typelib.h:291
INT DataOffset
Definition: typelib.h:290
INT GuidOffset
Definition: typelib.h:289
INT oArgCustData[1]
Definition: typelib.h:213
INT HelpStringContext
Definition: typelib.h:210
INT16 VtableOffset
Definition: typelib.h:185
INT16 nrargs
Definition: typelib.h:200
INT16 funcdescsize
Definition: typelib.h:186
INT16 nroargs
Definition: typelib.h:201
INT HelpContext
Definition: typelib.h:244
INT HelpString
Definition: typelib.h:245
INT HelpStringContext
Definition: typelib.h:248
INT16 vardescsize
Definition: typelib.h:238
INT16 VarKind
Definition: typelib.h:237
WORD handle
Definition: typelib.c:85
WORD offset
Definition: typelib.c:81
WORD length
Definition: typelib.c:82
WORD id
Definition: typelib.c:84
WORD flags
Definition: typelib.c:83
WORD usage
Definition: typelib.c:86
WORD type_id
Definition: typelib.c:91
WORD count
Definition: typelib.c:92
DWORD resloader
Definition: typelib.c:93
WORD rettype
Definition: typelib.h:491
WORD arg_off
Definition: typelib.h:486
WORD helpstring
Definition: typelib.h:485
WORD vtblpos
Definition: typelib.h:492
WORD funcflags
Definition: typelib.h:493
DWORD dispid
Definition: typelib.h:483
BYTE magic
Definition: typelib.h:479
BYTE retnextopt
Definition: typelib.h:488
WORD name
Definition: typelib.h:370
CHAR dir_magic[4]
Definition: typelib.h:334
CHAR CompObj_magic[8]
Definition: typelib.h:333
SLTG_Name names[1]
Definition: typelib.h:532
BYTE magic
Definition: typelib.h:507
DWORD number
Definition: typelib.h:526
WORD cbSizeInstance
Definition: typelib.h:443
WORD tdescalias_vt
Definition: typelib.h:437
WORD byte_offs
Definition: typelib.h:578
BYTE flags
Definition: typelib.h:575
BYTE magic
Definition: typelib.h:574
WORD varflags
Definition: typelib.h:583
DWORD memid
Definition: typelib.h:580
WORD helpstring
Definition: typelib.h:582
LONG refs
Definition: typelib.c:3189
HANDLE file
Definition: typelib.c:3190
LPVOID typelib_base
Definition: typelib.c:3192
HANDLE mapping
Definition: typelib.c:3191
IUnknown IUnknown_iface
Definition: typelib.c:3188
IUnknown IUnknown_iface
Definition: typelib.c:2968
LPVOID typelib_base
Definition: typelib.c:2970
LONG refs
Definition: typelib.c:2969
HMODULE dll
Definition: typelib.c:2867
LONG refs
Definition: typelib.c:2866
IUnknown IUnknown_iface
Definition: typelib.c:2865
HGLOBAL typelib_global
Definition: typelib.c:2869
LPVOID typelib_base
Definition: typelib.c:2870
HRSRC typelib_resource
Definition: typelib.c:2868
LIST_ENTRY ProcessLocksList
Definition: winbase.h:907
Definition: scsiwmi.h:51
Definition: match.c:390
Definition: cookie.c:202
WORD current
Definition: typelib.c:3700
const BYTE * buffer
Definition: typelib.c:3698
DWORD length
Definition: typelib.c:3699
Definition: fci.c:127
Definition: _hash_fun.h:40
unsigned int index
Definition: notification.c:65
Definition: copy.c:22
Definition: name.c:39
Definition: send.c:48
ITypeLib * pTLib
Definition: typelib.c:7968
const GUID * guid
Definition: typelib.c:7967
unsigned int num
Definition: typelib.c:3881
Definition: parse.h:23
METHODDATA * pmethdata
Definition: oleauto.h:919
const TLBString * DocString
Definition: typelib.c:1260
DWORD dwHelpContext
Definition: typelib.c:1263
BOOL not_attached_to_typelib
Definition: typelib.c:1246
const TLBString * Name
Definition: typelib.c:1259
struct list * pcustdata_list
Definition: typelib.c:1275
const TLBString * DllName
Definition: typelib.c:1261
ITypeInfo2 ITypeInfo2_iface
Definition: typelib.c:1242
const TLBString * Schema
Definition: typelib.c:1262
TYPEATTR typeattr
Definition: typelib.c:1250
TYPEDESC * tdescAlias
Definition: typelib.c:1251
TLBFuncDesc * funcdescs
Definition: typelib.c:1267
DWORD dwHelpStringContext
Definition: typelib.c:1264
ITypeLibImpl * pTypeLib
Definition: typelib.c:1253
ITypeComp ITypeComp_iface
Definition: typelib.c:1243
TLBGuid * guid
Definition: typelib.c:1249
TLBVarDesc * vardescs
Definition: typelib.c:1270
struct list custdata_list
Definition: typelib.c:1276
ICreateTypeInfo2 ICreateTypeInfo2_iface
Definition: typelib.c:1244
TLBImplType * impltypes
Definition: typelib.c:1273
HREFTYPE hreftype
Definition: typelib.c:1255
const TLBString * Name
Definition: typelib.c:1122
struct list guid_list
Definition: typelib.c:1120
ICreateTypeLib2 ICreateTypeLib2_iface
Definition: typelib.c:1104
ITypeLib2 ITypeLib2_iface
Definition: typelib.c:1102
const TLBString * HelpFile
Definition: typelib.c:1124
struct list custdata_list
Definition: typelib.c:1129
SYSKIND syskind
Definition: typelib.c:1108
TYPEDESC * pTypeDesc
Definition: typelib.c:1132
DWORD dwHelpContext
Definition: typelib.c:1126
TLBGuid * guid
Definition: typelib.c:1106
struct list name_list
Definition: typelib.c:1119
struct list entry
Definition: typelib.c:1140
WCHAR * path
Definition: typelib.c:1141
struct list implib_list
Definition: typelib.c:1130
const TLBString * DocString
Definition: typelib.c:1123
HREFTYPE dispatch_href
Definition: typelib.c:1136
struct list ref_list
Definition: typelib.c:1135
struct tagITypeInfoImpl ** typeinfos
Definition: typelib.c:1128
struct list string_list
Definition: typelib.c:1118
ITypeComp ITypeComp_iface
Definition: typelib.c:1103
const TLBString * HelpStringDll
Definition: typelib.c:1125
INT helpstringcontext
Definition: typelib.h:73
INT varflags
Definition: typelib.h:65
INT helpstring
Definition: typelib.h:72
INT NameOffset
Definition: typelib.h:77
INT dispatchpos
Definition: typelib.h:83
INT nrtypeinfos
Definition: typelib.h:71
INT helpfile
Definition: typelib.h:78
INT CustomDataOffset
Definition: typelib.h:79
MSFT_pSeg pArrayDescriptions
Definition: typelib.h:112
MSFT_pSeg pImpInfo
Definition: typelib.h:100
MSFT_pSeg pTypdescTab
Definition: typelib.h:111
MSFT_pSeg pNametab
Definition: typelib.h:109
MSFT_pSeg pCDGuids
Definition: typelib.h:115
MSFT_pSeg pImpFiles
Definition: typelib.h:101
MSFT_pSeg pGuidTab
Definition: typelib.h:105
MSFT_pSeg pCustData
Definition: typelib.h:113
MSFT_pSeg pRefTab
Definition: typelib.h:102
MSFT_pSeg pTypeInfoTab
Definition: typelib.h:98
MSFT_pSeg pStringtab
Definition: typelib.h:110
INT res08
Definition: typelib.h:91
INT offset
Definition: typelib.h:89
INT res0c
Definition: typelib.h:92
INT length
Definition: typelib.h:90
SAFEARRAYBOUND rgsabound[1]
Definition: compat.h:2360
USHORT cDims
Definition: compat.h:2355
void * mapping
Definition: typelib.c:1311
unsigned int oStart
Definition: typelib.c:1308
unsigned int length
Definition: typelib.c:1310
MSFT_SegDir * pTblDir
Definition: typelib.c:1312
unsigned int pos
Definition: typelib.c:1309
ITypeLibImpl * pLibInfo
Definition: typelib.c:1313
VARIANT data
Definition: typelib.c:1069
struct list entry
Definition: typelib.c:1070
TLBGuid * guid
Definition: typelib.c:1068
int HelpStringContext
Definition: typelib.c:1213
FUNCDESC funcdesc
Definition: typelib.c:1209
const TLBString * Entry
Definition: typelib.c:1215
TLBParDesc * pParamDesc
Definition: typelib.c:1211
const TLBString * Name
Definition: typelib.c:1210
const TLBString * HelpString
Definition: typelib.c:1214
struct list custdata_list
Definition: typelib.c:1216
struct list entry
Definition: typelib.c:1063
UINT offset
Definition: typelib.c:1062
GUID guid
Definition: typelib.c:1060
INT hreftype
Definition: typelib.c:1061
TLBGuid * guid
Definition: typelib.c:1080
struct tagITypeLibImpl * pImpTypeLib
Definition: typelib.c:1088
WORD wVersionMinor
Definition: typelib.c:1086
WORD wVersionMajor
Definition: typelib.c:1085
struct list entry
Definition: typelib.c:1090
HREFTYPE hRef
Definition: typelib.c:1234
struct list custdata_list
Definition: typelib.c:1236
const TLBString * Name
Definition: typelib.c:1202
struct list custdata_list
Definition: typelib.c:1203
TLBGuid * guid
Definition: typelib.c:1183
HREFTYPE reference
Definition: typelib.c:1186
TLBImpLib * pImpTLInfo
Definition: typelib.c:1187
TYPEKIND tkind
Definition: typelib.c:1182
struct list entry
Definition: typelib.c:1191
struct list entry
Definition: typelib.c:1096
UINT offset
Definition: typelib.c:1095
int HelpStringContext
Definition: typelib.c:1226
const TLBString * HelpString
Definition: typelib.c:1227
VARDESC * vardesc_create
Definition: typelib.c:1223
struct list custdata_list
Definition: typelib.c:1228
VARDESC vardesc
Definition: typelib.c:1222
const TLBString * Name
Definition: typelib.c:1224
int HelpContext
Definition: typelib.c:1225
WMSFT_SegContents aux_seg
Definition: typelib.c:9289
WMSFT_SegContents typeinfo_seg
Definition: typelib.c:9275
WMSFT_SegContents namehash_seg
Definition: typelib.c:9281
WMSFT_SegContents ref_seg
Definition: typelib.c:9278
MSFT_Header header
Definition: typelib.c:9274
WMSFT_SegContents impinfo_seg
Definition: typelib.c:9277
WMSFT_SegContents arraydesc_seg
Definition: typelib.c:9285
WMSFT_SegContents impfile_seg
Definition: typelib.c:9276
WMSFT_SegContents custdata_seg
Definition: typelib.c:9286
WMSFT_SegContents guidhash_seg
Definition: typelib.c:9279
WMSFT_SegContents guid_seg
Definition: typelib.c:9280
WMSFT_SegContents string_seg
Definition: typelib.c:9283
MSFT_SegDir segdir
Definition: typelib.c:9288
WMSFT_SegContents cdguids_seg
Definition: typelib.c:9287
WMSFT_SegContents name_seg
Definition: typelib.c:9282
WMSFT_SegContents typdesc_seg
Definition: typelib.c:9284
ULONG name_offset
Definition: oleaut.c:792
ULONG help_len
Definition: oleaut.c:795
ULONG help_offset
Definition: oleaut.c:796
WORD minor_version
Definition: oleaut.c:798
ULONG name_len
Definition: oleaut.c:791
LANGID langid
Definition: oleaut.c:793
WORD major_version
Definition: oleaut.c:797
Definition: cmds.c:130
#define max(a, b)
Definition: svc.c:63
#define LIST_INIT(head)
Definition: queue.h:197
#define str_len
Definition: treelist.c:89
#define DWORD_PTR
Definition: treelist.c:76
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
int64_t LONGLONG
Definition: typedefs.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
Definition: pdh_main.c:94
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:962
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:847
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748
HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
Definition: variant.c:576
static unsigned stack_offset(compile_ctx_t *ctx)
Definition: compile.c:349
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
int ret
_In_ WDFCOLLECTION _In_ ULONG Index
#define V_INT(x)
Definition: webchild.h:78
type_kind
Definition: widltypes.h:217
@ TKIND_MODULE
Definition: widltypes.h:221
@ TKIND_COCLASS
Definition: widltypes.h:224
@ TKIND_RECORD
Definition: widltypes.h:220
@ TKIND_ENUM
Definition: widltypes.h:219
@ TKIND_UNION
Definition: widltypes.h:226
@ TKIND_ALIAS
Definition: widltypes.h:225
@ TKIND_DISPATCH
Definition: widltypes.h:223
@ TKIND_INTERFACE
Definition: widltypes.h:222
@ SYS_WIN16
Definition: widltypes.h:551
@ SYS_WIN32
Definition: widltypes.h:552
@ SYS_WIN64
Definition: widltypes.h:554
@ SYS_MAC
Definition: widltypes.h:553
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:367
void WINAPI DebugBreak(void)
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:369
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define OF_READ
Definition: winbase.h:116
#define DONT_RESOLVE_DLL_REFERENCES
Definition: winbase.h:366
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
_In_ PATHOBJ _In_ CLIPOBJ _In_ BRUSHOBJ _In_ POINTL _In_ MIX mix
Definition: winddi.h:3595
int HFILE
Definition: windef.h:298
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define TYPE_E_BADMODULEKIND
Definition: winerror.h:2544
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:2513
#define DISP_E_NONAMEDARGS
Definition: winerror.h:2516
#define TYPE_E_REGISTRYACCESS
Definition: winerror.h:2533
#define TYPE_E_ELEMENTNOTFOUND
Definition: winerror.h:2539
#define DISP_E_BADCALLEE
Definition: winerror.h:2525
#define TYPE_E_DLLFUNCTIONNOTFOUND
Definition: winerror.h:2543
#define E_NOINTERFACE
Definition: winerror.h:2364
#define DISP_E_BADVARTYPE
Definition: winerror.h:2517
#define TYPE_E_AMBIGUOUSNAME
Definition: winerror.h:2540
#define TYPE_E_INCONSISTENTPROPFUNCS
Definition: winerror.h:2553
#define DISP_E_BADPARAMCOUNT
Definition: winerror.h:2523
#define TYPE_E_TYPEMISMATCH
Definition: winerror.h:2548
#define STG_E_FILENOTFOUND
Definition: winerror.h:2565
#define DISP_E_NOTACOLLECTION
Definition: winerror.h:2526
#define TYPE_E_CANTLOADLIBRARY
Definition: winerror.h:2552
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:2512
#define TYPE_E_NAMECONFLICT
Definition: winerror.h:2541
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define E_UNEXPECTED
Definition: winerror.h:2456
#define DISP_E_EXCEPTION
Definition: winerror.h:2518
#define TYPE_E_IOERROR
Definition: winerror.h:2550
#define TYPE_E_INVALIDSTATE
Definition: winerror.h:2537
#define E_POINTER
Definition: winerror.h:2365
#define TYPE_E_LIBNOTREGISTERED
Definition: winerror.h:2534
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:2570
#define MB_PRECOMPOSED
Definition: winnls.h:281
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define FCONTROL
Definition: winuser.h:21
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
static FILE * outfile
Definition: wrjpgcom.c:81
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193