ReactOS 0.4.17-dev-573-g8315b8c
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#include "winerror.h"
58#include "windef.h"
59#include "winbase.h"
60#include "winnls.h"
61#include "winreg.h"
62#include "winuser.h"
63#include "winternl.h"
64#include "lzexpand.h"
65
66#include "objbase.h"
67#include "typelib.h"
68#include "wine/debug.h"
69#include "variant.h"
70#include "wine/asm.h"
71#include "wine/list.h"
72
75
76static const BOOL is_win64 = sizeof(void *) > sizeof(int);
77
78typedef struct
79{
82 WORD flags;
83 WORD id;
85 WORD usage;
87
88typedef struct
89{
90 WORD type_id; /* Type identifier */
91 WORD count; /* Number of resources of this type */
92 DWORD resloader; /* SetResourceHandler() */
93 /*
94 * Name info array.
95 */
97
98static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt);
99static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr);
100static void TLB_FreeVarDesc(VARDESC*);
101
102/****************************************************************************
103 * FromLExxx
104 *
105 * Takes p_iVal (which is in little endian) and returns it
106 * in the host machine's byte order.
107 */
108#ifdef WORDS_BIGENDIAN
109static WORD FromLEWord(WORD p_iVal)
110{
111 return (((p_iVal & 0x00FF) << 8) |
112 ((p_iVal & 0xFF00) >> 8));
113}
114
115
116static DWORD FromLEDWord(DWORD p_iVal)
117{
118 return (((p_iVal & 0x000000FF) << 24) |
119 ((p_iVal & 0x0000FF00) << 8) |
120 ((p_iVal & 0x00FF0000) >> 8) |
121 ((p_iVal & 0xFF000000) >> 24));
122}
123#else
124#define FromLEWord(X) (X)
125#define FromLEDWord(X) (X)
126#endif
127
128#define DISPATCH_HREF_OFFSET 0x01000000
129#define DISPATCH_HREF_MASK 0xff000000
130
131/****************************************************************************
132 * FromLExxx
133 *
134 * Fix byte order in any structure if necessary
135 */
136#ifdef WORDS_BIGENDIAN
137static void FromLEWords(void *p_Val, int p_iSize)
138{
139 WORD *Val = p_Val;
140
141 p_iSize /= sizeof(WORD);
142
143 while (p_iSize) {
144 *Val = FromLEWord(*Val);
145 Val++;
146 p_iSize--;
147 }
148}
149
150
151static void FromLEDWords(void *p_Val, int p_iSize)
152{
153 DWORD *Val = p_Val;
154
155 p_iSize /= sizeof(DWORD);
156
157 while (p_iSize) {
158 *Val = FromLEDWord(*Val);
159 Val++;
160 p_iSize--;
161 }
162}
163#else
164#define FromLEWords(X,Y) /*nothing*/
165#define FromLEDWords(X,Y) /*nothing*/
166#endif
167
168/*
169 * Find a typelib key which matches a requested maj.min version.
170 */
171static BOOL find_typelib_key( REFGUID guid, WORD *wMaj, WORD *wMin )
172{
173 WCHAR buffer[60];
174 char key_name[16];
175 DWORD len, i;
176 INT best_maj = -1, best_min = -1;
177 HKEY hkey;
178
179 lstrcpyW( buffer, L"Typelib\\" );
181
183 return FALSE;
184
185 len = sizeof(key_name);
186 i = 0;
187 while (RegEnumKeyExA(hkey, i++, key_name, &len, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
188 {
189 INT v_maj, v_min;
190
191 if (sscanf(key_name, "%x.%x", &v_maj, &v_min) == 2)
192 {
193 TRACE("found %s: %x.%x\n", debugstr_w(buffer), v_maj, v_min);
194
195 if (*wMaj == 0xffff && *wMin == 0xffff)
196 {
197 if (v_maj > best_maj) best_maj = v_maj;
198 if (v_min > best_min) best_min = v_min;
199 }
200 else if (*wMaj == v_maj)
201 {
202 best_maj = v_maj;
203
204 if (*wMin == v_min)
205 {
206 best_min = v_min;
207 break; /* exact match */
208 }
209 if (*wMin != 0xffff && v_min >= *wMin && v_min > best_min) best_min = v_min;
210 }
211 }
212 len = sizeof(key_name);
213 }
214 RegCloseKey( hkey );
215
216 TRACE("found best_maj %d, best_min %d\n", best_maj, best_min);
217
218 if (*wMaj == 0xffff && *wMin == 0xffff)
219 {
220 if (best_maj >= 0 && best_min >= 0)
221 {
222 *wMaj = best_maj;
223 *wMin = best_min;
224 return TRUE;
225 }
226 }
227
228 if (*wMaj == best_maj && best_min >= 0)
229 {
230 *wMin = best_min;
231 return TRUE;
232 }
233 return FALSE;
234}
235
236/* get the path of a typelib key, in the form "Typelib\<guid>\<maj>.<min>" */
237/* buffer must be at least 60 characters long */
239{
240 lstrcpyW( buffer, L"Typelib\\" );
242 swprintf( buffer + lstrlenW(buffer), 20, L"\\%x.%x", wMaj, wMin );
243 return buffer;
244}
245
246/* get the path of an interface key, in the form "Interface\<guid>" */
247/* buffer must be at least 50 characters long */
249{
250 lstrcpyW( buffer, L"Interface\\" );
252 return buffer;
253}
254
255/* get the lcid subkey for a typelib, in the form "<lcid>\<syskind>" */
256/* buffer must be at least 16 characters long */
258{
259 swprintf( buffer, 16, L"%lx\\", lcid );
260 switch(syskind)
261 {
262 case SYS_WIN16: lstrcatW( buffer, L"win16" ); break;
263 case SYS_WIN32: lstrcatW( buffer, L"win32" ); break;
264 case SYS_WIN64: lstrcatW( buffer, L"win64" ); break;
265 default:
266 TRACE("Typelib is for unsupported syskind %i\n", syskind);
267 return NULL;
268 }
269 return buffer;
270}
271
272static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib);
273
275{
276 ULONG size;
277 DWORD res;
281 WORD flags;
286};
287
288/* Get the path to a registered type library. Helper for QueryPathOfRegTypeLib. */
290 SYSKIND syskind, LCID lcid, BSTR *path, BOOL redir )
291{
293 LCID myLCID = lcid;
294 HKEY hkey;
295 WCHAR buffer[60];
297 LONG res;
298
299 TRACE_(typelib)("%s, %x.%x, %#lx, %p\n", debugstr_guid(guid), wMaj, wMin, lcid, path);
300
301 if (redir)
302 {
303 ACTCTX_SECTION_KEYED_DATA data;
304
305 data.cbSize = sizeof(data);
306 if (FindActCtxSectionGuid( 0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, guid, &data ))
307 {
308 struct tlibredirect_data *tlib = (struct tlibredirect_data*)data.lpData;
309 WCHAR *nameW;
310 DWORD len;
311
312 if ((wMaj != 0xffff || wMin != 0xffff) && (tlib->major_version != wMaj || tlib->minor_version < wMin))
314
315 nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
317 if (!len) return TYPE_E_LIBNOTREGISTERED;
318
319 TRACE_(typelib)("got path from context %s\n", debugstr_w(Path));
321 return S_OK;
322 }
323 }
324
325 if (!find_typelib_key( guid, &wMaj, &wMin )) return TYPE_E_LIBNOTREGISTERED;
326 get_typelib_key( guid, wMaj, wMin, buffer );
327
330 {
331 TRACE_(typelib)("%s not found\n", debugstr_w(buffer));
333 }
334 else if (res != ERROR_SUCCESS)
335 {
336 TRACE_(typelib)("failed to open %s for read access\n", debugstr_w(buffer));
338 }
339
340 while (hr != S_OK)
341 {
342 LONG dwPathLen = sizeof(Path);
343
344 get_lcid_subkey( myLCID, syskind, buffer );
345
346 if (RegQueryValueW(hkey, buffer, Path, &dwPathLen))
347 {
348 if (!lcid)
349 break;
350 else if (myLCID == lcid)
351 {
352 /* try with sub-langid */
353 myLCID = SUBLANGID(lcid);
354 }
355 else if ((myLCID == SUBLANGID(lcid)) && myLCID)
356 {
357 /* try with system langid */
358 myLCID = 0;
359 }
360 else
361 {
362 break;
363 }
364 }
365 else
366 {
368 hr = S_OK;
369 }
370 }
371 RegCloseKey( hkey );
372 TRACE_(typelib)("-- %#lx\n", hr);
373 return hr;
374}
375
376/****************************************************************************
377 * QueryPathOfRegTypeLib [OLEAUT32.164]
378 *
379 * Gets the path to a registered type library.
380 *
381 * PARAMS
382 * guid [I] referenced guid
383 * wMaj [I] major version
384 * wMin [I] minor version
385 * lcid [I] locale id
386 * path [O] path of typelib
387 *
388 * RETURNS
389 * Success: S_OK.
390 * Failure: If the type library is not registered then TYPE_E_LIBNOTREGISTERED
391 * or TYPE_E_REGISTRYACCESS if the type library registration key couldn't be
392 * opened.
393 */
395{
396 BOOL redir = TRUE;
398 if(SUCCEEDED(hres))
399 return hres;
400 redir = FALSE;
401 return query_typelib_path( guid, wMaj, wMin, is_win64 ? SYS_WIN32 : SYS_WIN64, lcid, path, redir );
402}
403
404/******************************************************************************
405 * CreateTypeLib [OLEAUT32.160] creates a typelib
406 *
407 * RETURNS
408 * Success: S_OK
409 * Failure: Status
410 */
412 SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib
413) {
414 FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
415 return E_FAIL;
416}
417
418/******************************************************************************
419 * LoadTypeLib [OLEAUT32.161]
420 *
421 * Loads a type library
422 *
423 * PARAMS
424 * szFile [I] Name of file to load from.
425 * pptLib [O] Pointer that receives ITypeLib object on success.
426 *
427 * RETURNS
428 * Success: S_OK
429 * Failure: Status
430 *
431 * SEE
432 * LoadTypeLibEx, LoadRegTypeLib, CreateTypeLib.
433 */
434HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib * *pptLib)
435{
436 TRACE("(%s,%p)\n",debugstr_w(szFile), pptLib);
437 return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
438}
439
440/******************************************************************************
441 * LoadTypeLibEx [OLEAUT32.183]
442 *
443 * Loads and optionally registers a type library
444 *
445 * RETURNS
446 * Success: S_OK
447 * Failure: Status
448 */
450 LPCOLESTR szFile, /* [in] Name of file to load from */
451 REGKIND regkind, /* [in] Specify kind of registration */
452 ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
453{
455 HRESULT res;
456
457 TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
458
459 if (!szFile || !pptLib)
460 return E_INVALIDARG;
461
462 *pptLib = NULL;
463
464 res = TLB_ReadTypeLib(szFile, szPath, MAX_PATH + 1, (ITypeLib2**)pptLib);
465
466 if (SUCCEEDED(res))
467 switch(regkind)
468 {
469 case REGKIND_DEFAULT:
470 /* don't register typelibs supplied with full path. Experimentation confirms the following */
471 if (((szFile[0] == '\\') && (szFile[1] == '\\')) ||
472 (szFile[0] && (szFile[1] == ':'))) break;
473 /* else fall-through */
474
475 case REGKIND_REGISTER:
476 if (FAILED(res = RegisterTypeLib(*pptLib, szPath, NULL)))
477 {
478 ITypeLib_Release(*pptLib);
479 *pptLib = 0;
480 }
481 break;
482 case REGKIND_NONE:
483 break;
484 }
485
486 TRACE(" returns %#lx\n",res);
487 return res;
488}
489
490/******************************************************************************
491 * LoadRegTypeLib [OLEAUT32.162]
492 *
493 * Loads a registered type library.
494 *
495 * PARAMS
496 * rguid [I] GUID of the registered type library.
497 * wVerMajor [I] major version.
498 * wVerMinor [I] minor version.
499 * lcid [I] locale ID.
500 * ppTLib [O] pointer that receives an ITypeLib object on success.
501 *
502 * RETURNS
503 * Success: S_OK.
504 * Failure: Any HRESULT code returned from QueryPathOfRegTypeLib or
505 * LoadTypeLib.
506 */
508 REFGUID rguid,
509 WORD wVerMajor,
510 WORD wVerMinor,
511 LCID lcid,
512 ITypeLib **ppTLib)
513{
514 BSTR bstr=NULL;
515 HRESULT res;
516
517 *ppTLib = NULL;
518
519 res = QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);
520
521 if(SUCCEEDED(res))
522 {
523 res= LoadTypeLib(bstr, ppTLib);
524 SysFreeString(bstr);
525
526 if ((wVerMajor!=0xffff || wVerMinor!=0xffff) && *ppTLib)
527 {
528 TLIBATTR *attr;
529
530 res = ITypeLib_GetLibAttr(*ppTLib, &attr);
531 if (res == S_OK)
532 {
533 BOOL mismatch = attr->wMajorVerNum != wVerMajor || attr->wMinorVerNum < wVerMinor;
534 ITypeLib_ReleaseTLibAttr(*ppTLib, attr);
535
536 if (mismatch)
537 {
538 ITypeLib_Release(*ppTLib);
539 *ppTLib = NULL;
541 }
542 }
543 }
544 }
545
546 TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
547
548 return res;
549}
550
551static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *tattr, DWORD flag)
552{
553 WCHAR keyName[60];
554 HKEY key, subKey;
555
556 get_interface_key( &tattr->guid, keyName );
557 if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
559 {
560 const WCHAR *proxy_clsid;
561
562 if (tattr->typekind == TKIND_INTERFACE || (tattr->wTypeFlags & TYPEFLAG_FDUAL))
563 proxy_clsid = L"{00020424-0000-0000-C000-000000000046}";
564 else
565 proxy_clsid = L"{00020420-0000-0000-C000-000000000046}";
566
567 if (name)
569 (BYTE *)name, (lstrlenW(name)+1) * sizeof(OLECHAR));
570
571 if (!RegCreateKeyExW(key, L"ProxyStubClsid", 0, NULL, 0, KEY_WRITE | flag, NULL, &subKey, NULL))
572 {
573 RegSetValueExW(subKey, NULL, 0, REG_SZ, (const BYTE *)proxy_clsid, (lstrlenW(proxy_clsid) + 1) * sizeof(WCHAR));
574 RegCloseKey(subKey);
575 }
576
577 if (!RegCreateKeyExW(key, L"ProxyStubClsid32", 0, NULL, 0, KEY_WRITE | flag, NULL, &subKey, NULL))
578 {
579 RegSetValueExW(subKey, NULL, 0, REG_SZ, (const BYTE *)proxy_clsid, (lstrlenW(proxy_clsid) + 1) * sizeof(WCHAR));
580 RegCloseKey(subKey);
581 }
582
583 if (RegCreateKeyExW(key, L"TypeLib", 0, NULL, 0,
584 KEY_WRITE | flag, NULL, &subKey, NULL) == ERROR_SUCCESS)
585 {
586 WCHAR buffer[40];
587
588 StringFromGUID2(&libattr->guid, buffer, 40);
589 RegSetValueExW(subKey, NULL, 0, REG_SZ,
590 (BYTE *)buffer, (lstrlenW(buffer)+1) * sizeof(WCHAR));
591 swprintf(buffer, ARRAY_SIZE(buffer), L"%x.%x", libattr->wMajorVerNum, libattr->wMinorVerNum);
592 RegSetValueExW(subKey, L"Version", 0, REG_SZ, (BYTE *)buffer, (lstrlenW(buffer)+1) * sizeof(WCHAR));
593 RegCloseKey(subKey);
594 }
595
597 }
598}
599
600/******************************************************************************
601 * RegisterTypeLib [OLEAUT32.163]
602 * Adds information about a type library to the System Registry
603 * NOTES
604 * Docs: ITypeLib FAR * ptlib
605 * Docs: OLECHAR FAR* szFullPath
606 * Docs: OLECHAR FAR* szHelpDir
607 *
608 * RETURNS
609 * Success: S_OK
610 * Failure: Status
611 */
612HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const WCHAR *szHelpDir)
613{
614 HRESULT res;
615 TLIBATTR *attr;
616 WCHAR keyName[60];
617 WCHAR tmp[16];
618 HKEY key, subKey;
619 UINT types, tidx;
620 TYPEKIND kind;
621 DWORD disposition;
622
623 if (ptlib == NULL || szFullPath == NULL)
624 return E_INVALIDARG;
625
626 if (FAILED(ITypeLib_GetLibAttr(ptlib, &attr)))
627 return E_FAIL;
628
629 get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName );
630
631 res = S_OK;
632 if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
634 {
635 LPOLESTR doc;
636 LPOLESTR libName;
637
638 /* Set the human-readable name of the typelib to
639 the typelib's doc, if it exists, else to the typelib's name. */
640 if (FAILED(ITypeLib_GetDocumentation(ptlib, -1, &libName, &doc, NULL, NULL)))
641 res = E_FAIL;
642 else if (doc || libName)
643 {
644 WCHAR *name = doc ? doc : libName;
645
646 if (RegSetValueExW(key, NULL, 0, REG_SZ,
647 (BYTE *)name, (lstrlenW(name)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
648 res = E_FAIL;
649
650 SysFreeString(doc);
651 SysFreeString(libName);
652 }
653
654 /* Make up the name of the typelib path subkey */
655 if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;
656
657 /* Create the typelib path subkey */
658 if (res == S_OK && RegCreateKeyExW(key, tmp, 0, NULL, 0,
659 KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
660 {
661 if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
662 (BYTE *)szFullPath, (lstrlenW(szFullPath)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
663 res = E_FAIL;
664
665 RegCloseKey(subKey);
666 }
667 else
668 res = E_FAIL;
669
670 /* Create the flags subkey */
671 if (res == S_OK && RegCreateKeyExW(key, L"FLAGS", 0, NULL, 0,
672 KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
673 {
674 WCHAR buf[20];
675
676 /* FIXME: is %u correct? */
677 swprintf(buf, ARRAY_SIZE(buf), L"%u", attr->wLibFlags);
678 if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
679 (BYTE *)buf, (lstrlenW(buf) + 1)*sizeof(WCHAR) ) != ERROR_SUCCESS)
680 res = E_FAIL;
681
682 RegCloseKey(subKey);
683 }
684 else
685 res = E_FAIL;
686
687 /* create the helpdir subkey */
688 if (res == S_OK && RegCreateKeyExW(key, L"HELPDIR", 0, NULL, 0,
689 KEY_WRITE, NULL, &subKey, &disposition) == ERROR_SUCCESS)
690 {
691 BSTR freeHelpDir = NULL;
693
694 /* if we created a new key, and helpDir was null, set the helpdir
695 to the directory which contains the typelib. However,
696 if we just opened an existing key, we leave the helpdir alone */
697 if ((disposition == REG_CREATED_NEW_KEY) && (szHelpDir == NULL)) {
698 szHelpDir = freeHelpDir = SysAllocString(szFullPath);
699 file_name = wcsrchr(szHelpDir, '\\');
700 if (file_name && file_name[1]) {
701 /* possible remove a numeric \index (resource-id) */
702 WCHAR *end_ptr = file_name + 1;
703 while ('0' <= *end_ptr && *end_ptr <= '9') end_ptr++;
704 if (!*end_ptr)
705 {
706 *file_name = 0;
707 file_name = wcsrchr(szHelpDir, '\\');
708 }
709 }
710 if (file_name)
711 *file_name = 0;
712 }
713
714 /* if we have an szHelpDir, set it! */
715 if (szHelpDir != NULL) {
716 if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
717 (BYTE *)szHelpDir, (lstrlenW(szHelpDir)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) {
718 res = E_FAIL;
719 }
720 }
721
722 SysFreeString(freeHelpDir);
723 RegCloseKey(subKey);
724 } else {
725 res = E_FAIL;
726 }
727
729 }
730 else
731 res = E_FAIL;
732
733 /* register OLE Automation-compatible interfaces for this typelib */
734 types = ITypeLib_GetTypeInfoCount(ptlib);
735 for (tidx=0; tidx<types; tidx++) {
736 if (SUCCEEDED(ITypeLib_GetTypeInfoType(ptlib, tidx, &kind))) {
737 LPOLESTR name = NULL;
738 ITypeInfo *tinfo = NULL;
739
740 ITypeLib_GetDocumentation(ptlib, tidx, &name, NULL, NULL, NULL);
741
742 switch (kind) {
743 case TKIND_INTERFACE:
744 TRACE_(typelib)("%d: interface %s\n", tidx, debugstr_w(name));
745 ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
746 break;
747
748 case TKIND_DISPATCH:
749 TRACE_(typelib)("%d: dispinterface %s\n", tidx, debugstr_w(name));
750 ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
751 break;
752
753 default:
754 TRACE_(typelib)("%d: %s\n", tidx, debugstr_w(name));
755 break;
756 }
757
758 if (tinfo) {
759 TYPEATTR *tattr = NULL;
760 ITypeInfo_GetTypeAttr(tinfo, &tattr);
761
762 if (tattr) {
763 TRACE_(typelib)("guid=%s, flags=%04x (",
764 debugstr_guid(&tattr->guid),
765 tattr->wTypeFlags);
766
767 if (TRACE_ON(typelib)) {
768#define XX(x) if (TYPEFLAG_##x & tattr->wTypeFlags) MESSAGE(#x"|");
769 XX(FAPPOBJECT);
770 XX(FCANCREATE);
771 XX(FLICENSED);
772 XX(FPREDECLID);
773 XX(FHIDDEN);
774 XX(FCONTROL);
775 XX(FDUAL);
776 XX(FNONEXTENSIBLE);
777 XX(FOLEAUTOMATION);
778 XX(FRESTRICTED);
779 XX(FAGGREGATABLE);
780 XX(FREPLACEABLE);
781 XX(FDISPATCHABLE);
782 XX(FREVERSEBIND);
783 XX(FPROXY);
784#undef XX
785 MESSAGE("\n");
786 }
787
788 /* Register all dispinterfaces (which includes dual interfaces) and
789 oleautomation interfaces */
790 if ((kind == TKIND_INTERFACE && (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
791 kind == TKIND_DISPATCH)
792 {
794 DWORD opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
795
796 /* register interface<->typelib coupling */
797 TLB_register_interface(attr, name, tattr, 0);
798
799 /* register TLBs into the opposite registry view, too */
800 if(opposite == KEY_WOW64_32KEY ||
802 TLB_register_interface(attr, name, tattr, opposite);
803 }
804
805 ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
806 }
807
808 ITypeInfo_Release(tinfo);
809 }
810
812 }
813 }
814
815 ITypeLib_ReleaseTLibAttr(ptlib, attr);
816
817 return res;
818}
819
821{
822 WCHAR subKeyName[50];
823 HKEY subKey;
824
825 /* the path to the type */
826 get_interface_key( guid, subKeyName );
827
828 /* Delete its bits */
829 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE | flag, &subKey) != ERROR_SUCCESS)
830 return;
831
832 RegDeleteKeyW(subKey, L"ProxyStubClsid");
833 RegDeleteKeyW(subKey, L"ProxyStubClsid32");
834 RegDeleteKeyW(subKey, L"TypeLib");
835 RegCloseKey(subKey);
836 RegDeleteKeyExW(HKEY_CLASSES_ROOT, subKeyName, flag, 0);
837}
838
839/******************************************************************************
840 * UnRegisterTypeLib [OLEAUT32.186]
841 * Removes information about a type library from the System Registry
842 * NOTES
843 *
844 * RETURNS
845 * Success: S_OK
846 * Failure: Status
847 */
849 REFGUID libid, /* [in] Guid of the library */
850 WORD wVerMajor, /* [in] major version */
851 WORD wVerMinor, /* [in] minor version */
852 LCID lcid, /* [in] locale id */
853 SYSKIND syskind)
854{
855 BSTR tlibPath = NULL;
856 DWORD tmpLength;
857 WCHAR keyName[60];
858 WCHAR subKeyName[50];
859 int result = S_OK;
860 DWORD i = 0;
861 BOOL deleteOtherStuff;
862 HKEY key = NULL;
863 TYPEATTR* typeAttr = NULL;
864 TYPEKIND kind;
865 ITypeInfo* typeInfo = NULL;
866 ITypeLib* typeLib = NULL;
867 int numTypes;
868
869 TRACE("(IID: %s)\n",debugstr_guid(libid));
870
871 /* Create the path to the key */
872 get_typelib_key( libid, wVerMajor, wVerMinor, keyName );
873
874 if (syskind != SYS_WIN16 && syskind != SYS_WIN32 && syskind != SYS_WIN64)
875 {
876 TRACE("Unsupported syskind %i\n", syskind);
878 goto end;
879 }
880
881 /* get the path to the typelib on disk */
882 if (query_typelib_path(libid, wVerMajor, wVerMinor, syskind, lcid, &tlibPath, FALSE) != S_OK) {
884 goto end;
885 }
886
887 /* Try and open the key to the type library. */
890 goto end;
891 }
892
893 /* Try and load the type library */
894 if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib) != S_OK) {
896 goto end;
897 }
898
899 /* remove any types registered with this typelib */
900 numTypes = ITypeLib_GetTypeInfoCount(typeLib);
901 for (i=0; i<numTypes; i++) {
902 /* get the kind of type */
903 if (ITypeLib_GetTypeInfoType(typeLib, i, &kind) != S_OK) {
904 goto enddeleteloop;
905 }
906
907 /* skip non-interfaces, and get type info for the type */
908 if ((kind != TKIND_INTERFACE) && (kind != TKIND_DISPATCH)) {
909 goto enddeleteloop;
910 }
911 if (ITypeLib_GetTypeInfo(typeLib, i, &typeInfo) != S_OK) {
912 goto enddeleteloop;
913 }
914 if (ITypeInfo_GetTypeAttr(typeInfo, &typeAttr) != S_OK) {
915 goto enddeleteloop;
916 }
917
918 if ((kind == TKIND_INTERFACE && (typeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
919 kind == TKIND_DISPATCH)
920 {
922 REGSAM opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY);
923
924 TLB_unregister_interface(&typeAttr->guid, 0);
925
926 /* unregister TLBs into the opposite registry view, too */
927 if(opposite == KEY_WOW64_32KEY ||
929 TLB_unregister_interface(&typeAttr->guid, opposite);
930 }
931 }
932
933enddeleteloop:
934 if (typeAttr) ITypeInfo_ReleaseTypeAttr(typeInfo, typeAttr);
935 typeAttr = NULL;
936 if (typeInfo) ITypeInfo_Release(typeInfo);
937 typeInfo = NULL;
938 }
939
940 /* Now, delete the type library path subkey */
941 get_lcid_subkey( lcid, syskind, subKeyName );
942 RegDeleteKeyW(key, subKeyName);
943 *wcsrchr( subKeyName, '\\' ) = 0; /* remove last path component */
944 RegDeleteKeyW(key, subKeyName);
945
946 /* check if there is anything besides the FLAGS/HELPDIR keys.
947 If there is, we don't delete them */
948 tmpLength = ARRAY_SIZE(subKeyName);
949 deleteOtherStuff = TRUE;
950 i = 0;
951 while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
952 tmpLength = ARRAY_SIZE(subKeyName);
953
954 /* if its not FLAGS or HELPDIR, then we must keep the rest of the key */
955 if (!wcscmp(subKeyName, L"FLAGS")) continue;
956 if (!wcscmp(subKeyName, L"HELPDIR")) continue;
957 deleteOtherStuff = FALSE;
958 break;
959 }
960
961 /* only delete the other parts of the key if we're absolutely sure */
962 if (deleteOtherStuff) {
963 RegDeleteKeyW(key, L"FLAGS");
964 RegDeleteKeyW(key, L"HELPDIR");
966 key = NULL;
967
969 *wcsrchr( keyName, '\\' ) = 0; /* remove last path component */
971 }
972
973end:
974 SysFreeString(tlibPath);
975 if (typeLib) ITypeLib_Release(typeLib);
976 if (key) RegCloseKey(key);
977 return result;
978}
979
980/******************************************************************************
981 * RegisterTypeLibForUser [OLEAUT32.442]
982 * Adds information about a type library to the user registry
983 * NOTES
984 * Docs: ITypeLib FAR * ptlib
985 * Docs: OLECHAR FAR* szFullPath
986 * Docs: OLECHAR FAR* szHelpDir
987 *
988 * RETURNS
989 * Success: S_OK
990 * Failure: Status
991 */
993 ITypeLib * ptlib, /* [in] Pointer to the library*/
994 OLECHAR * szFullPath, /* [in] full Path of the library*/
995 OLECHAR * szHelpDir) /* [in] dir to the helpfile for the library,
996 may be NULL*/
997{
998 FIXME("(%p, %s, %s) registering the typelib system-wide\n", ptlib,
999 debugstr_w(szFullPath), debugstr_w(szHelpDir));
1000 return RegisterTypeLib(ptlib, szFullPath, szHelpDir);
1001}
1002
1003/******************************************************************************
1004 * UnRegisterTypeLibForUser [OLEAUT32.443]
1005 * Removes information about a type library from the user registry
1006 *
1007 * RETURNS
1008 * Success: S_OK
1009 * Failure: Status
1010 */
1012 REFGUID libid, /* [in] GUID of the library */
1013 WORD wVerMajor, /* [in] major version */
1014 WORD wVerMinor, /* [in] minor version */
1015 LCID lcid, /* [in] locale id */
1016 SYSKIND syskind)
1017{
1018 FIXME("%s, %u, %u, %#lx, %u unregistering the typelib system-wide\n",
1019 debugstr_guid(libid), wVerMajor, wVerMinor, lcid, syskind);
1020 return UnRegisterTypeLib(libid, wVerMajor, wVerMinor, lcid, syskind);
1021}
1022
1023/*======================= ITypeLib implementation =======================*/
1024
1025typedef struct tagTLBGuid {
1029 struct list entry;
1031
1032typedef struct tagTLBCustData
1033{
1036 struct list entry;
1038
1039/* data structure for import typelibs */
1040typedef struct tagTLBImpLib
1041{
1042 int offset; /* offset in the file (MSFT)
1043 offset in nametable (SLTG)
1044 just used to identify library while reading
1045 data from file */
1046 TLBGuid *guid; /* libid */
1047 BSTR name; /* name */
1048
1049 LCID lcid; /* lcid of imported typelib */
1050
1051 WORD wVersionMajor; /* major version number */
1052 WORD wVersionMinor; /* minor version number */
1053
1054 struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib, or
1055 NULL if not yet loaded */
1056 struct list entry;
1058
1059typedef struct tagTLBString {
1062 struct list entry;
1064
1065/* internal ITypeLib data */
1066typedef struct tagITypeLibImpl
1067{
1080
1081 /* strings can be stored in tlb as multibyte strings BUT they are *always*
1082 * exported to the application as a UNICODE string.
1083 */
1087
1093 int TypeInfoCount; /* nr of typeinfo's in librarry */
1097 int ctTypeDesc; /* number of items in type desc array */
1098 TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the
1099 library. Only used while reading MSFT
1100 typelibs */
1101 struct list ref_list; /* list of ref types in this typelib */
1102 HREFTYPE dispatch_href; /* reference to IDispatch, -1 if unused */
1103
1104
1105 /* typelibs are cached, keyed by path and index, so store the linked list info within them */
1106 struct list entry;
1110
1111static const ITypeLib2Vtbl tlbvt;
1112static const ITypeCompVtbl tlbtcvt;
1113static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl;
1114
1116{
1117 return CONTAINING_RECORD(iface, ITypeLibImpl, ITypeLib2_iface);
1118}
1119
1121{
1122 return impl_from_ITypeLib2((ITypeLib2*)iface);
1123}
1124
1126{
1127 return CONTAINING_RECORD(iface, ITypeLibImpl, ITypeComp_iface);
1128}
1129
1131{
1132 return CONTAINING_RECORD(iface, ITypeLibImpl, ICreateTypeLib2_iface);
1133}
1134
1135/* ITypeLib methods */
1136static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength);
1137static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength);
1138
1139/*======================= ITypeInfo implementation =======================*/
1140
1141/* data for referenced types */
1142typedef struct tagTLBRefType
1143{
1144 INT index; /* Type index for internal ref or for external ref
1145 it the format is SLTG. -2 indicates to
1146 use guid */
1147
1148 TYPEKIND tkind;
1149 TLBGuid *guid; /* guid of the referenced type */
1150 /* if index == TLB_REF_USE_GUID */
1151
1152 HREFTYPE reference; /* The href of this ref */
1153 TLBImpLib *pImpTLInfo; /* If ref is external ptr to library data
1154 TLB_REF_INTERNAL for internal refs
1155 TLB_REF_NOT_FOUND for broken refs */
1156
1157 struct list entry;
1159
1160#define TLB_REF_USE_GUID -2
1161
1162#define TLB_REF_INTERNAL (void*)-2
1163#define TLB_REF_NOT_FOUND (void*)-1
1164
1165/* internal Parameter data */
1166typedef struct tagTLBParDesc
1167{
1171
1172/* internal Function data */
1173typedef struct tagTLBFuncDesc
1174{
1175 FUNCDESC funcdesc; /* lots of info on the function and its attributes. */
1176 const TLBString *Name; /* the name of this function */
1177 TLBParDesc *pParamDesc; /* array with param names and custom data */
1181 const TLBString *Entry; /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */
1184
1185/* internal Variable data */
1186typedef struct tagTLBVarDesc
1187{
1188 VARDESC vardesc; /* lots of info on the variable and its attributes. */
1189 VARDESC *vardesc_create; /* additional data needed for storing VARDESC */
1190 const TLBString *Name; /* the name of this variable */
1196
1197/* internal implemented interface data */
1198typedef struct tagTLBImplType
1199{
1200 HREFTYPE hRef; /* hRef of interface */
1201 int implflags; /* IMPLFLAG_*s */
1204
1205/* internal TypeInfo data */
1206typedef struct tagITypeInfoImpl
1207{
1214
1216 TYPEATTR typeattr;
1217 TYPEDESC *tdescAlias;
1218
1219 ITypeLibImpl * pTypeLib; /* back pointer to typelib */
1220 int index; /* index in this typelib; */
1221 HREFTYPE hreftype; /* hreftype for app object binding */
1222 /* type libs seem to store the doc strings in ascii
1223 * so why should we do it in unicode?
1224 */
1231
1232 /* functions */
1234
1235 /* variables */
1237
1238 /* Implemented Interfaces */
1240
1244
1246{
1247 return CONTAINING_RECORD(iface, ITypeInfoImpl, ITypeComp_iface);
1248}
1249
1251{
1252 return CONTAINING_RECORD(iface, ITypeInfoImpl, ITypeInfo2_iface);
1253}
1254
1256{
1257 return impl_from_ITypeInfo2((ITypeInfo2*)iface);
1258}
1259
1261{
1262 return CONTAINING_RECORD(iface, ITypeInfoImpl, ICreateTypeInfo2_iface);
1263}
1264
1265static const ITypeInfo2Vtbl tinfvt;
1266static const ITypeCompVtbl tcompvt;
1267static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl;
1268
1271
1272typedef struct tagTLBContext
1273{
1274 unsigned int oStart; /* start of TLB in file */
1275 unsigned int pos; /* current pos */
1276 unsigned int length; /* total length */
1277 void *mapping; /* memory mapping */
1281
1282
1283static inline BSTR TLB_get_bstr(const TLBString *str)
1284{
1285 return str != NULL ? str->str : NULL;
1286}
1287
1288static inline int TLB_str_memcmp(void *left, const TLBString *str, DWORD len)
1289{
1290 if(!str)
1291 return 1;
1292 return memcmp(left, str->str, len);
1293}
1294
1295static inline const GUID *TLB_get_guidref(const TLBGuid *guid)
1296{
1297 return guid != NULL ? &guid->guid : NULL;
1298}
1299
1300static inline const GUID *TLB_get_guid_null(const TLBGuid *guid)
1301{
1302 return guid != NULL ? &guid->guid : &GUID_NULL;
1303}
1304
1305static int get_ptr_size(SYSKIND syskind)
1306{
1307 switch(syskind){
1308 case SYS_WIN64:
1309 return 8;
1310 case SYS_WIN32:
1311 case SYS_MAC:
1312 case SYS_WIN16:
1313 return 4;
1314 }
1315 WARN("Unhandled syskind: 0x%x\n", syskind);
1316 return 4;
1317}
1318
1319/*
1320 debug
1321*/
1322static void dump_TypeDesc(const TYPEDESC *pTD,char *szVarType) {
1323 if (pTD->vt & VT_RESERVED)
1324 szVarType += strlen(strcpy(szVarType, "reserved | "));
1325 if (pTD->vt & VT_BYREF)
1326 szVarType += strlen(strcpy(szVarType, "ref to "));
1327 if (pTD->vt & VT_ARRAY)
1328 szVarType += strlen(strcpy(szVarType, "array of "));
1329 if (pTD->vt & VT_VECTOR)
1330 szVarType += strlen(strcpy(szVarType, "vector of "));
1331 switch(pTD->vt & VT_TYPEMASK) {
1332 case VT_UI1: sprintf(szVarType, "VT_UI1"); break;
1333 case VT_I2: sprintf(szVarType, "VT_I2"); break;
1334 case VT_I4: sprintf(szVarType, "VT_I4"); break;
1335 case VT_R4: sprintf(szVarType, "VT_R4"); break;
1336 case VT_R8: sprintf(szVarType, "VT_R8"); break;
1337 case VT_BOOL: sprintf(szVarType, "VT_BOOL"); break;
1338 case VT_ERROR: sprintf(szVarType, "VT_ERROR"); break;
1339 case VT_CY: sprintf(szVarType, "VT_CY"); break;
1340 case VT_DATE: sprintf(szVarType, "VT_DATE"); break;
1341 case VT_BSTR: sprintf(szVarType, "VT_BSTR"); break;
1342 case VT_UNKNOWN: sprintf(szVarType, "VT_UNKNOWN"); break;
1343 case VT_DISPATCH: sprintf(szVarType, "VT_DISPATCH"); break;
1344 case VT_I1: sprintf(szVarType, "VT_I1"); break;
1345 case VT_UI2: sprintf(szVarType, "VT_UI2"); break;
1346 case VT_UI4: sprintf(szVarType, "VT_UI4"); break;
1347 case VT_INT: sprintf(szVarType, "VT_INT"); break;
1348 case VT_UINT: sprintf(szVarType, "VT_UINT"); break;
1349 case VT_VARIANT: sprintf(szVarType, "VT_VARIANT"); break;
1350 case VT_VOID: sprintf(szVarType, "VT_VOID"); break;
1351 case VT_HRESULT: sprintf(szVarType, "VT_HRESULT"); break;
1352 case VT_USERDEFINED: sprintf(szVarType, "VT_USERDEFINED ref = %lx", pTD->hreftype); break;
1353 case VT_LPSTR: sprintf(szVarType, "VT_LPSTR"); break;
1354 case VT_LPWSTR: sprintf(szVarType, "VT_LPWSTR"); break;
1355 case VT_PTR: sprintf(szVarType, "ptr to ");
1356 dump_TypeDesc(pTD->lptdesc, szVarType + 7);
1357 break;
1358 case VT_SAFEARRAY: sprintf(szVarType, "safearray of ");
1359 dump_TypeDesc(pTD->lptdesc, szVarType + 13);
1360 break;
1361 case VT_CARRAY: sprintf(szVarType, "%d dim array of ",
1362 pTD->lpadesc->cDims); /* FIXME print out sizes */
1363 dump_TypeDesc(&pTD->lpadesc->tdescElem, szVarType + strlen(szVarType));
1364 break;
1365
1366 default: sprintf(szVarType, "unknown(%d)", pTD->vt & VT_TYPEMASK); break;
1367 }
1368}
1369
1370static void dump_ELEMDESC(const ELEMDESC *edesc) {
1371 char buf[200];
1372 USHORT flags = edesc->paramdesc.wParamFlags;
1373 dump_TypeDesc(&edesc->tdesc,buf);
1374 MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc->tdesc.vt,buf);
1375 MESSAGE("\t\tu.paramdesc.wParamFlags");
1376 if (!flags) MESSAGE(" PARAMFLAGS_NONE");
1377 if (flags & PARAMFLAG_FIN) MESSAGE(" PARAMFLAG_FIN");
1378 if (flags & PARAMFLAG_FOUT) MESSAGE(" PARAMFLAG_FOUT");
1379 if (flags & PARAMFLAG_FLCID) MESSAGE(" PARAMFLAG_FLCID");
1380 if (flags & PARAMFLAG_FRETVAL) MESSAGE(" PARAMFLAG_FRETVAL");
1381 if (flags & PARAMFLAG_FOPT) MESSAGE(" PARAMFLAG_FOPT");
1382 if (flags & PARAMFLAG_FHASDEFAULT) MESSAGE(" PARAMFLAG_FHASDEFAULT");
1383 if (flags & PARAMFLAG_FHASCUSTDATA) MESSAGE(" PARAMFLAG_FHASCUSTDATA");
1384 MESSAGE("\n\t\tu.paramdesc.lpex %p\n",edesc->paramdesc.pparamdescex);
1385}
1386static void dump_FUNCDESC(const FUNCDESC *funcdesc) {
1387 int i;
1388 MESSAGE("memid is %#lx\n", funcdesc->memid);
1389 for (i=0;i<funcdesc->cParams;i++) {
1390 MESSAGE("Param %d:\n",i);
1391 dump_ELEMDESC(funcdesc->lprgelemdescParam+i);
1392 }
1393 MESSAGE("\tfunckind: %d (",funcdesc->funckind);
1394 switch (funcdesc->funckind) {
1395 case FUNC_VIRTUAL: MESSAGE("virtual");break;
1396 case FUNC_PUREVIRTUAL: MESSAGE("pure virtual");break;
1397 case FUNC_NONVIRTUAL: MESSAGE("nonvirtual");break;
1398 case FUNC_STATIC: MESSAGE("static");break;
1399 case FUNC_DISPATCH: MESSAGE("dispatch");break;
1400 default: MESSAGE("unknown");break;
1401 }
1402 MESSAGE(")\n\tinvkind: %d (",funcdesc->invkind);
1403 switch (funcdesc->invkind) {
1404 case INVOKE_FUNC: MESSAGE("func");break;
1405 case INVOKE_PROPERTYGET: MESSAGE("property get");break;
1406 case INVOKE_PROPERTYPUT: MESSAGE("property put");break;
1407 case INVOKE_PROPERTYPUTREF: MESSAGE("property put ref");break;
1408 }
1409 MESSAGE(")\n\tcallconv: %d (",funcdesc->callconv);
1410 switch (funcdesc->callconv) {
1411 case CC_CDECL: MESSAGE("cdecl");break;
1412 case CC_PASCAL: MESSAGE("pascal");break;
1413 case CC_STDCALL: MESSAGE("stdcall");break;
1414 case CC_SYSCALL: MESSAGE("syscall");break;
1415 default:break;
1416 }
1417 MESSAGE(")\n\toVft: %d\n", funcdesc->oVft);
1418 MESSAGE("\tcParamsOpt: %d\n", funcdesc->cParamsOpt);
1419 MESSAGE("\twFlags: %x\n", funcdesc->wFuncFlags);
1420
1421 MESSAGE("\telemdescFunc (return value type):\n");
1422 dump_ELEMDESC(&funcdesc->elemdescFunc);
1423}
1424
1425static const char * const typekind_desc[] =
1426{
1427 "TKIND_ENUM",
1428 "TKIND_RECORD",
1429 "TKIND_MODULE",
1430 "TKIND_INTERFACE",
1431 "TKIND_DISPATCH",
1432 "TKIND_COCLASS",
1433 "TKIND_ALIAS",
1434 "TKIND_UNION",
1435 "TKIND_MAX"
1436};
1437
1439{
1440 int i;
1441 MESSAGE("%s(%u)\n", debugstr_w(TLB_get_bstr(pfd->Name)), pfd->funcdesc.cParams);
1442 for (i=0;i<pfd->funcdesc.cParams;i++)
1443 MESSAGE("\tparm%d: %s\n",i,debugstr_w(TLB_get_bstr(pfd->pParamDesc[i].Name)));
1444
1445
1446 dump_FUNCDESC(&(pfd->funcdesc));
1447
1448 MESSAGE("\thelpstring: %s\n", debugstr_w(TLB_get_bstr(pfd->HelpString)));
1449 if(pfd->Entry == NULL)
1450 MESSAGE("\tentry: (null)\n");
1451 else if(pfd->Entry == (void*)-1)
1452 MESSAGE("\tentry: invalid\n");
1453 else if(IS_INTRESOURCE(pfd->Entry))
1454 MESSAGE("\tentry: %p\n", pfd->Entry);
1455 else
1456 MESSAGE("\tentry: %s\n", debugstr_w(TLB_get_bstr(pfd->Entry)));
1457}
1459{
1460 while (n)
1461 {
1463 ++pfd;
1464 --n;
1465 }
1466}
1467static void dump_TLBVarDesc(const TLBVarDesc * pvd, UINT n)
1468{
1469 while (n)
1470 {
1471 TRACE_(typelib)("%s\n", debugstr_w(TLB_get_bstr(pvd->Name)));
1472 ++pvd;
1473 --n;
1474 }
1475}
1476
1477static void dump_TLBImpLib(const TLBImpLib *import)
1478{
1479 TRACE_(typelib)("%s %s\n", debugstr_guid(TLB_get_guidref(import->guid)),
1480 debugstr_w(import->name));
1481 TRACE_(typelib)("v%d.%d lcid %#lx offset=%x\n", import->wVersionMajor, import->wVersionMinor, import->lcid, import->offset);
1482}
1483
1484static void dump_TLBRefType(const ITypeLibImpl *pTL)
1485{
1486 TLBRefType *ref;
1487
1489 {
1490 TRACE_(typelib)("href:%#lx\n", ref->reference);
1491 if(ref->index == -1)
1493 else
1494 TRACE_(typelib)("type no: %d\n", ref->index);
1495
1496 if(ref->pImpTLInfo != TLB_REF_INTERNAL && ref->pImpTLInfo != TLB_REF_NOT_FOUND)
1497 {
1498 TRACE_(typelib)("in lib\n");
1499 dump_TLBImpLib(ref->pImpTLInfo);
1500 }
1501 }
1502}
1503
1504static void dump_TLBImplType(const TLBImplType * impl, UINT n)
1505{
1506 if(!impl)
1507 return;
1508 while (n) {
1509 TRACE_(typelib)("implementing/inheriting interface hRef = %lx implflags %x\n",
1510 impl->hRef, impl->implflags);
1511 ++impl;
1512 --n;
1513 }
1514}
1515
1516static void dump_DispParms(const DISPPARAMS * pdp)
1517{
1518 unsigned int index;
1519
1520 TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
1521
1522 if (pdp->cNamedArgs && pdp->rgdispidNamedArgs)
1523 {
1524 TRACE("named args:\n");
1525 for (index = 0; index < pdp->cNamedArgs; index++)
1526 TRACE( "\t0x%lx\n", pdp->rgdispidNamedArgs[index] );
1527 }
1528
1529 if (pdp->cArgs && pdp->rgvarg)
1530 {
1531 TRACE("args:\n");
1532 for (index = 0; index < pdp->cArgs; index++)
1533 TRACE(" [%d] %s\n", index, debugstr_variant(pdp->rgvarg+index));
1534 }
1535}
1536
1537static void dump_TypeInfo(const ITypeInfoImpl * pty)
1538{
1539 TRACE("%p ref %lu\n", pty, pty->ref);
1541 TRACE("attr:%s\n", debugstr_guid(TLB_get_guidref(pty->guid)));
1542 TRACE("kind:%s\n", typekind_desc[pty->typeattr.typekind]);
1543 TRACE("fct:%u var:%u impl:%u\n", pty->typeattr.cFuncs, pty->typeattr.cVars, pty->typeattr.cImplTypes);
1544 TRACE("wTypeFlags: 0x%04x\n", pty->typeattr.wTypeFlags);
1545 TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
1546 if (pty->typeattr.typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(TLB_get_bstr(pty->DllName)));
1547 if (TRACE_ON(ole))
1548 dump_TLBFuncDesc(pty->funcdescs, pty->typeattr.cFuncs);
1549 dump_TLBVarDesc(pty->vardescs, pty->typeattr.cVars);
1550 dump_TLBImplType(pty->impltypes, pty->typeattr.cImplTypes);
1551}
1552
1553static void dump_VARDESC(const VARDESC *v)
1554{
1555 MESSAGE("memid %ld\n",v->memid);
1556 MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema));
1557 MESSAGE("oInst %ld\n", v->oInst);
1558 dump_ELEMDESC(&(v->elemdescVar));
1559 MESSAGE("wVarFlags %x\n",v->wVarFlags);
1560 MESSAGE("varkind %d\n",v->varkind);
1561}
1562
1563static TYPEDESC std_typedesc[VT_LPWSTR+1] =
1564{
1565 /* VT_LPWSTR is largest type that, may appear in type description */
1566 {{0}, VT_EMPTY}, {{0}, VT_NULL}, {{0}, VT_I2}, {{0}, VT_I4},
1567 {{0}, VT_R4}, {{0}, VT_R8}, {{0}, VT_CY}, {{0}, VT_DATE},
1568 {{0}, VT_BSTR}, {{0}, VT_DISPATCH}, {{0}, VT_ERROR}, {{0}, VT_BOOL},
1569 {{0}, VT_VARIANT},{{0}, VT_UNKNOWN}, {{0}, VT_DECIMAL}, {{0}, 15}, /* unused in VARENUM */
1570 {{0}, VT_I1}, {{0}, VT_UI1}, {{0}, VT_UI2}, {{0}, VT_UI4},
1571 {{0}, VT_I8}, {{0}, VT_UI8}, {{0}, VT_INT}, {{0}, VT_UINT},
1572 {{0}, VT_VOID}, {{0}, VT_HRESULT}, {{0}, VT_PTR}, {{0}, VT_SAFEARRAY},
1573 {{0}, VT_CARRAY}, {{0}, VT_USERDEFINED}, {{0}, VT_LPSTR}, {{0}, VT_LPWSTR}
1574};
1575
1576static void TLB_abort(void)
1577{
1578 DebugBreak();
1579}
1580
1581/* returns the size required for a deep copy of a typedesc into a
1582 * flat buffer */
1583static SIZE_T TLB_SizeTypeDesc( const TYPEDESC *tdesc, BOOL alloc_initial_space )
1584{
1585 SIZE_T size = 0;
1586
1587 if (alloc_initial_space)
1588 size += sizeof(TYPEDESC);
1589
1590 switch (tdesc->vt)
1591 {
1592 case VT_PTR:
1593 case VT_SAFEARRAY:
1594 size += TLB_SizeTypeDesc(tdesc->lptdesc, TRUE);
1595 break;
1596 case VT_CARRAY:
1597 size += FIELD_OFFSET(ARRAYDESC, rgbounds[tdesc->lpadesc->cDims]);
1598 size += TLB_SizeTypeDesc(&tdesc->lpadesc->tdescElem, FALSE);
1599 break;
1600 }
1601 return size;
1602}
1603
1604/* deep copy a typedesc into a flat buffer */
1605static void *TLB_CopyTypeDesc( TYPEDESC *dest, const TYPEDESC *src, void *buffer )
1606{
1607 if (!dest)
1608 {
1609 dest = buffer;
1610 buffer = (char *)buffer + sizeof(TYPEDESC);
1611 }
1612
1613 *dest = *src;
1614
1615 switch (src->vt)
1616 {
1617 case VT_PTR:
1618 case VT_SAFEARRAY:
1619 dest->lptdesc = buffer;
1620 buffer = TLB_CopyTypeDesc(NULL, src->lptdesc, buffer);
1621 break;
1622 case VT_CARRAY:
1623 dest->lpadesc = buffer;
1624 memcpy(dest->lpadesc, src->lpadesc, FIELD_OFFSET(ARRAYDESC, rgbounds[src->lpadesc->cDims]));
1625 buffer = (char *)buffer + FIELD_OFFSET(ARRAYDESC, rgbounds[src->lpadesc->cDims]);
1626 buffer = TLB_CopyTypeDesc(&dest->lpadesc->tdescElem, &src->lpadesc->tdescElem, buffer);
1627 break;
1628 }
1629 return buffer;
1630}
1631
1632/* free custom data allocated by MSFT_CustData */
1633static inline void TLB_FreeCustData(struct list *custdata_list)
1634{
1635 TLBCustData *cd, *cdn;
1636 LIST_FOR_EACH_ENTRY_SAFE(cd, cdn, custdata_list, TLBCustData, entry)
1637 {
1638 list_remove(&cd->entry);
1639 VariantClear(&cd->data);
1640 free(cd);
1641 }
1642}
1643
1644static BSTR TLB_MultiByteToBSTR(const char *ptr)
1645{
1646 DWORD len;
1647 BSTR ret;
1648
1649 len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, 0);
1650 ret = SysAllocStringLen(NULL, len - 1);
1651 if (!ret) return ret;
1653 return ret;
1654}
1655
1657{
1658 int i;
1659
1660 for (i = 0; i < typeinfo->typeattr.cFuncs; ++i)
1661 {
1662 if (typeinfo->funcdescs[i].funcdesc.memid == memid)
1663 return &typeinfo->funcdescs[i];
1664 }
1665
1666 return NULL;
1667}
1668
1669static inline TLBFuncDesc *TLB_get_funcdesc_by_memberid_invkind(ITypeInfoImpl *typeinfo, MEMBERID memid, INVOKEKIND invkind)
1670{
1671 int i;
1672
1673 for (i = 0; i < typeinfo->typeattr.cFuncs; ++i)
1674 {
1675 if (typeinfo->funcdescs[i].funcdesc.memid == memid && typeinfo->funcdescs[i].funcdesc.invkind == invkind)
1676 return &typeinfo->funcdescs[i];
1677 }
1678
1679 return NULL;
1680}
1681
1683{
1684 int i;
1685
1686 for (i = 0; i < typeinfo->typeattr.cVars; ++i)
1687 {
1688 if (typeinfo->vardescs[i].vardesc.memid == memid)
1689 return &typeinfo->vardescs[i];
1690 }
1691
1692 return NULL;
1693}
1694
1696{
1697 int i;
1698
1699 for (i = 0; i < typeinfo->typeattr.cVars; ++i)
1700 {
1701 if (!lstrcmpiW(TLB_get_bstr(typeinfo->vardescs[i].Name), name))
1702 return &typeinfo->vardescs[i];
1703 }
1704
1705 return NULL;
1706}
1707
1708static inline TLBCustData *TLB_get_custdata_by_guid(const struct list *custdata_list, REFGUID guid)
1709{
1710 TLBCustData *cust_data;
1711 LIST_FOR_EACH_ENTRY(cust_data, custdata_list, TLBCustData, entry)
1712 if(IsEqualIID(TLB_get_guid_null(cust_data->guid), guid))
1713 return cust_data;
1714 return NULL;
1715}
1716
1718{
1719 int i;
1720
1721 for (i = 0; i < typelib->TypeInfoCount; ++i)
1722 {
1723 if (!lstrcmpiW(TLB_get_bstr(typelib->typeinfos[i]->Name), name))
1724 return typelib->typeinfos[i];
1725 }
1726
1727 return NULL;
1728}
1729
1731{
1732 list_init(&var_desc->custdata_list);
1733}
1734
1736{
1737 TLBVarDesc *ret;
1738
1739 ret = calloc(n, sizeof(TLBVarDesc));
1740 if(!ret)
1741 return NULL;
1742
1743 while(n){
1745 --n;
1746 }
1747
1748 return ret;
1749}
1750
1752{
1753 TLBParDesc *ret;
1754
1755 ret = calloc(n, sizeof(TLBParDesc));
1756 if(!ret)
1757 return NULL;
1758
1759 while(n){
1760 list_init(&ret[n-1].custdata_list);
1761 --n;
1762 }
1763
1764 return ret;
1765}
1766
1768{
1769 list_init(&func_desc->custdata_list);
1770}
1771
1773{
1775
1776 ret = calloc(n, sizeof(TLBFuncDesc));
1777 if(!ret)
1778 return NULL;
1779
1780 while(n){
1782 --n;
1783 }
1784
1785 return ret;
1786}
1787
1789{
1790 list_init(&impl->custdata_list);
1791}
1792
1794{
1796
1797 ret = calloc(n, sizeof(TLBImplType));
1798 if(!ret)
1799 return NULL;
1800
1801 while(n){
1803 --n;
1804 }
1805
1806 return ret;
1807}
1808
1810 const GUID *new_guid, HREFTYPE hreftype)
1811{
1812 TLBGuid *guid;
1813
1815 if (IsEqualGUID(&guid->guid, new_guid))
1816 return guid;
1817 }
1818
1819 guid = malloc(sizeof(TLBGuid));
1820 if (!guid)
1821 return NULL;
1822
1823 memcpy(&guid->guid, new_guid, sizeof(GUID));
1824 guid->hreftype = hreftype;
1825
1826 list_add_tail(guid_list, &guid->entry);
1827
1828 return guid;
1829}
1830
1831static HRESULT TLB_set_custdata(struct list *custdata_list, TLBGuid *tlbguid, VARIANT *var)
1832{
1833 TLBCustData *cust_data;
1834
1835 switch(V_VT(var)){
1836 case VT_I4:
1837 case VT_R4:
1838 case VT_UI4:
1839 case VT_INT:
1840 case VT_UINT:
1841 case VT_HRESULT:
1842 case VT_BSTR:
1843 break;
1844 default:
1845 return DISP_E_BADVARTYPE;
1846 }
1847
1848 cust_data = TLB_get_custdata_by_guid(custdata_list, TLB_get_guid_null(tlbguid));
1849
1850 if (!cust_data) {
1851 cust_data = malloc(sizeof(TLBCustData));
1852 if (!cust_data)
1853 return E_OUTOFMEMORY;
1854
1855 cust_data->guid = tlbguid;
1856 VariantInit(&cust_data->data);
1857
1858 list_add_tail(custdata_list, &cust_data->entry);
1859 }else
1860 VariantClear(&cust_data->data);
1861
1862 return VariantCopy(&cust_data->data, var);
1863}
1864
1865/* Used to update list pointers after list itself was moved. */
1866static void TLB_relink_custdata(struct list *custdata_list)
1867{
1868 if (custdata_list->prev == custdata_list->next)
1869 list_init(custdata_list);
1870 else
1871 {
1872 custdata_list->prev->next = custdata_list;
1873 custdata_list->next->prev = custdata_list;
1874 }
1875}
1876
1878{
1879 TLBString *str;
1880
1881 if(!new_str)
1882 return NULL;
1883
1885 if (wcscmp(str->str, new_str) == 0)
1886 return str;
1887 }
1888
1889 str = malloc(sizeof(TLBString));
1890 if (!str)
1891 return NULL;
1892
1893 str->str = SysAllocString(new_str);
1894 if (!str->str) {
1895 free(str);
1896 return NULL;
1897 }
1898
1899 list_add_tail(string_list, &str->entry);
1900
1901 return str;
1902}
1903
1905 ULONG *size, WORD *align)
1906{
1908 TYPEATTR *attr;
1909 HRESULT hr;
1910
1911 hr = ITypeInfo2_GetRefTypeInfo(&info->ITypeInfo2_iface, href, &other);
1912 if(FAILED(hr))
1913 return hr;
1914
1915 hr = ITypeInfo_GetTypeAttr(other, &attr);
1916 if(FAILED(hr)){
1917 ITypeInfo_Release(other);
1918 return hr;
1919 }
1920
1921 if(size)
1922 *size = attr->cbSizeInstance;
1923 if(align)
1924 *align = attr->cbAlignment;
1925
1926 ITypeInfo_ReleaseTypeAttr(other, attr);
1927 ITypeInfo_Release(other);
1928
1929 return S_OK;
1930}
1931
1933 TYPEDESC *tdesc, ULONG *size, WORD *align)
1934{
1935 ULONG i, sub, ptr_size;
1936 HRESULT hr;
1937
1938 ptr_size = get_ptr_size(sys);
1939
1940 switch(tdesc->vt){
1941 case VT_VOID:
1942 *size = 0;
1943 break;
1944 case VT_I1:
1945 case VT_UI1:
1946 *size = 1;
1947 break;
1948 case VT_I2:
1949 case VT_BOOL:
1950 case VT_UI2:
1951 *size = 2;
1952 break;
1953 case VT_I4:
1954 case VT_R4:
1955 case VT_ERROR:
1956 case VT_UI4:
1957 case VT_INT:
1958 case VT_UINT:
1959 case VT_HRESULT:
1960 *size = 4;
1961 break;
1962 case VT_R8:
1963 case VT_I8:
1964 case VT_UI8:
1965 *size = 8;
1966 break;
1967 case VT_BSTR:
1968 case VT_DISPATCH:
1969 case VT_UNKNOWN:
1970 case VT_PTR:
1971 case VT_SAFEARRAY:
1972 case VT_LPSTR:
1973 case VT_LPWSTR:
1974 *size = ptr_size;
1975 break;
1976 case VT_DATE:
1977 *size = sizeof(DATE);
1978 break;
1979 case VT_VARIANT:
1980 *size = sizeof(VARIANT);
1981 if(get_ptr_size(sys) != sizeof(void*))
1982 *size += is_win64 ? -8 : 8; /* 32-bit VARIANT is 8 bytes smaller than 64-bit VARIANT */
1983 break;
1984 case VT_DECIMAL:
1985 *size = sizeof(DECIMAL);
1986 break;
1987 case VT_CY:
1988 *size = sizeof(CY);
1989 break;
1990 case VT_CARRAY:
1991 *size = 0;
1992 for(i = 0; i < tdesc->lpadesc->cDims; ++i)
1993 *size += tdesc->lpadesc->rgbounds[i].cElements;
1994 hr = TLB_size_instance(info, sys, &tdesc->lpadesc->tdescElem, &sub, align);
1995 if(FAILED(hr))
1996 return hr;
1997 *size *= sub;
1998 return S_OK;
1999 case VT_USERDEFINED:
2000 return TLB_get_size_from_hreftype(info, tdesc->hreftype, size, align);
2001 default:
2002 FIXME("Unsized VT: 0x%x\n", tdesc->vt);
2003 return E_FAIL;
2004 }
2005
2006 if(align){
2007 if(*size < 4)
2008 *align = *size;
2009 else
2010 *align = 4;
2011 }
2012
2013 return S_OK;
2014}
2015
2016/**********************************************************************
2017 *
2018 * Functions for reading MSFT typelibs (those created by CreateTypeLib2)
2019 */
2020
2021static inline void MSFT_Seek(TLBContext *pcx, LONG where)
2022{
2023 if (where != DO_NOT_SEEK)
2024 {
2025 where += pcx->oStart;
2026 if (where > pcx->length)
2027 {
2028 /* FIXME */
2029 ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
2030 TLB_abort();
2031 }
2032 pcx->pos = where;
2033 }
2034}
2035
2036/* read function */
2037static DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, LONG where )
2038{
2039 TRACE_(typelib)("pos=0x%08x len %#lx, %u, %u, %#lx\n",
2040 pcx->pos, count, pcx->oStart, pcx->length, where);
2041
2042 MSFT_Seek(pcx, where);
2043 if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
2044 memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
2045 pcx->pos += count;
2046 return count;
2047}
2048
2050 LONG where )
2051{
2052 DWORD ret;
2053
2054 ret = MSFT_Read(buffer, count, pcx, where);
2056
2057 return ret;
2058}
2059
2061 LONG where )
2062{
2063 DWORD ret;
2064
2065 ret = MSFT_Read(buffer, count, pcx, where);
2067
2068 return ret;
2069}
2070
2072{
2073 TLBGuid *guid;
2075 int offs = 0;
2076
2077 MSFT_Seek(pcx, pcx->pTblDir->pGuidTab.offset);
2078 while (1) {
2079 if (offs >= pcx->pTblDir->pGuidTab.length)
2080 return S_OK;
2081
2083
2084 guid = malloc(sizeof(TLBGuid));
2085
2086 guid->offset = offs;
2087 guid->guid = entry.guid;
2088 guid->hreftype = entry.hreftype;
2089
2090 list_add_tail(&pcx->pLibInfo->guid_list, &guid->entry);
2091
2092 offs += sizeof(MSFT_GuidEntry);
2093 }
2094}
2095
2097{
2098 TLBGuid *ret;
2099
2101 if(ret->offset == offset){
2102 TRACE_(typelib)("%s\n", debugstr_guid(&ret->guid));
2103 return ret;
2104 }
2105 }
2106
2107 return NULL;
2108}
2109
2110static HREFTYPE MSFT_ReadHreftype( TLBContext *pcx, int offset )
2111{
2112 MSFT_NameIntro niName;
2113
2114 if (offset < 0)
2115 {
2116 ERR_(typelib)("bad offset %d\n", offset);
2117 return -1;
2118 }
2119
2120 MSFT_ReadLEDWords(&niName, sizeof(niName), pcx,
2122
2123 return niName.hreftype;
2124}
2125
2127{
2128 char *string;
2129 MSFT_NameIntro intro;
2130 INT16 len_piece;
2131 int offs = 0, lengthInChars;
2132
2133 MSFT_Seek(pcx, pcx->pTblDir->pNametab.offset);
2134 while (1) {
2135 TLBString *tlbstr;
2136
2137 if (offs >= pcx->pTblDir->pNametab.length)
2138 return S_OK;
2139
2140 MSFT_ReadLEWords(&intro, sizeof(MSFT_NameIntro), pcx, DO_NOT_SEEK);
2141 intro.namelen &= 0xFF;
2142 len_piece = intro.namelen + sizeof(MSFT_NameIntro);
2143 if(len_piece % 4)
2144 len_piece = (len_piece + 4) & ~0x3;
2145 if(len_piece < 8)
2146 len_piece = 8;
2147
2148 string = malloc(len_piece + 1);
2149 MSFT_Read(string, len_piece - sizeof(MSFT_NameIntro), pcx, DO_NOT_SEEK);
2150 string[intro.namelen] = '\0';
2151
2153 string, -1, NULL, 0);
2154 if (!lengthInChars) {
2155 free(string);
2156 return E_UNEXPECTED;
2157 }
2158
2159 tlbstr = malloc(sizeof(TLBString));
2160
2161 tlbstr->offset = offs;
2162 tlbstr->str = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR));
2163 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, tlbstr->str, lengthInChars);
2164
2165 free(string);
2166
2167 list_add_tail(&pcx->pLibInfo->name_list, &tlbstr->entry);
2168
2169 offs += len_piece;
2170 }
2171}
2172
2174{
2175 TLBString *tlbstr;
2176
2178 if (tlbstr->offset == offset) {
2179 TRACE_(typelib)("%s\n", debugstr_w(tlbstr->str));
2180 return tlbstr;
2181 }
2182 }
2183
2184 return NULL;
2185}
2186
2188{
2189 TLBString *tlbstr;
2190
2192 if (tlbstr->offset == offset) {
2193 TRACE_(typelib)("%s\n", debugstr_w(tlbstr->str));
2194 return tlbstr;
2195 }
2196 }
2197
2198 return NULL;
2199}
2200
2201/*
2202 * read a value and fill a VARIANT structure
2203 */
2204static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
2205{
2206 int size;
2207
2208 TRACE_(typelib)("\n");
2209
2210 if(offset <0) { /* data are packed in here */
2211 V_VT(pVar) = (offset & 0x7c000000 )>> 26;
2212 V_I4(pVar) = offset & 0x3ffffff;
2213 return;
2214 }
2215 MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
2216 pcx->pTblDir->pCustData.offset + offset );
2217 TRACE_(typelib)("Vartype = %x\n", V_VT(pVar));
2218 switch (V_VT(pVar)){
2219 case VT_EMPTY: /* FIXME: is this right? */
2220 case VT_NULL: /* FIXME: is this right? */
2221 case VT_I2 : /* this should not happen */
2222 case VT_I4 :
2223 case VT_R4 :
2224 case VT_ERROR :
2225 case VT_BOOL :
2226 case VT_I1 :
2227 case VT_UI1 :
2228 case VT_UI2 :
2229 case VT_UI4 :
2230 case VT_INT :
2231 case VT_UINT :
2232 case VT_VOID : /* FIXME: is this right? */
2233 case VT_HRESULT :
2234 size=4; break;
2235 case VT_R8 :
2236 case VT_CY :
2237 case VT_DATE :
2238 case VT_I8 :
2239 case VT_UI8 :
2240 case VT_DECIMAL : /* FIXME: is this right? */
2241 case VT_FILETIME :
2242 size=8;break;
2243 /* pointer types with known behaviour */
2244 case VT_BSTR :{
2245 char * ptr;
2246 MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
2247 if(size == -1){
2248 V_BSTR(pVar) = NULL;
2249 }else{
2250 int len;
2251 ptr = calloc(1, size);
2252 MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);
2256 free(ptr);
2257 }
2258 }
2259 size=-4; break;
2260 /* FIXME: this will not work AT ALL when the variant contains a pointer */
2261 case VT_DISPATCH :
2262 case VT_VARIANT :
2263 case VT_UNKNOWN :
2264 case VT_PTR :
2265 case VT_SAFEARRAY :
2266 case VT_CARRAY :
2267 case VT_USERDEFINED :
2268 case VT_LPSTR :
2269 case VT_LPWSTR :
2270 case VT_BLOB :
2271 case VT_STREAM :
2272 case VT_STORAGE :
2273 case VT_STREAMED_OBJECT :
2274 case VT_STORED_OBJECT :
2275 case VT_BLOB_OBJECT :
2276 case VT_CF :
2277 case VT_CLSID :
2278 default:
2279 size=0;
2280 FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
2281 V_VT(pVar));
2282 }
2283
2284 if(size>0) /* (big|small) endian correct? */
2285 MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );
2286 return;
2287}
2288/*
2289 * create a linked list with custom data
2290 */
2291static int MSFT_CustData( TLBContext *pcx, int offset, struct list *custdata_list)
2292{
2294 TLBCustData* pNew;
2295 int count=0;
2296
2297 TRACE_(typelib)("\n");
2298
2299 if (pcx->pTblDir->pCDGuids.offset < 0) return 0;
2300
2301 while(offset >=0){
2302 count++;
2303 pNew = calloc(1, sizeof(TLBCustData));
2304 MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset);
2305 pNew->guid = MSFT_ReadGuid(entry.GuidOffset, pcx);
2306 MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
2307 list_add_head(custdata_list, &pNew->entry);
2308 offset = entry.next;
2309 }
2310 return count;
2311}
2312
2313static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd)
2314{
2315 if(type <0)
2316 pTd->vt=type & VT_TYPEMASK;
2317 else
2318 *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
2319
2320 TRACE_(typelib)("vt type = %X\n", pTd->vt);
2321}
2322
2323static BOOL TLB_is_propgetput(INVOKEKIND invkind)
2324{
2325 return (invkind == INVOKE_PROPERTYGET ||
2326 invkind == INVOKE_PROPERTYPUT ||
2327 invkind == INVOKE_PROPERTYPUTREF);
2328}
2329
2330static void
2332 ITypeInfoImpl* pTI,
2333 int cFuncs,
2334 int cVars,
2335 int offset,
2336 TLBFuncDesc** pptfd)
2337{
2338 /*
2339 * member information is stored in a data structure at offset
2340 * indicated by the memoffset field of the typeinfo structure
2341 * There are several distinctive parts.
2342 * The first part starts with a field that holds the total length
2343 * of this (first) part excluding this field. Then follow the records,
2344 * for each member there is one record.
2345 *
2346 * The first entry is always the length of the record (including this
2347 * length word).
2348 * The rest of the record depends on the type of the member. If there is
2349 * a field indicating the member type (function, variable, interface, etc)
2350 * I have not found it yet. At this time we depend on the information
2351 * in the type info and the usual order how things are stored.
2352 *
2353 * Second follows an array sized nrMEM*sizeof(INT) with a member id
2354 * for each member;
2355 *
2356 * Third is an equal sized array with file offsets to the name entry
2357 * of each member.
2358 *
2359 * The fourth and last (?) part is an array with offsets to the records
2360 * in the first part of this file segment.
2361 */
2362
2363 int infolen, nameoffset, reclength, i;
2364 int recoffset = offset + sizeof(INT);
2365
2366 char *recbuf = malloc(0xffff);
2367 MSFT_FuncRecord *pFuncRec = (MSFT_FuncRecord*)recbuf;
2368 TLBFuncDesc *ptfd_prev = NULL, *ptfd;
2369
2370 TRACE_(typelib)("\n");
2371
2372 MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);
2373
2374 *pptfd = TLBFuncDesc_Alloc(cFuncs);
2375 ptfd = *pptfd;
2376 for ( i = 0; i < cFuncs ; i++ )
2377 {
2378 int optional;
2379
2380 /* name, eventually add to a hash table */
2381 MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
2382 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
2383
2384 /* read the function information record */
2385 MSFT_ReadLEDWords(&reclength, sizeof(pFuncRec->Info), pcx, recoffset);
2386
2387 reclength &= 0xffff;
2388
2390
2391 /* size without argument data */
2392 optional = reclength - pFuncRec->nrargs*sizeof(MSFT_ParameterInfo);
2393 if (pFuncRec->FKCCIC & 0x1000)
2394 optional -= pFuncRec->nrargs * sizeof(INT);
2395
2396 if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpContext))
2397 ptfd->helpcontext = pFuncRec->HelpContext;
2398
2399 if (optional > FIELD_OFFSET(MSFT_FuncRecord, oHelpString))
2400 ptfd->HelpString = MSFT_ReadString(pcx, pFuncRec->oHelpString);
2401
2402 if (optional > FIELD_OFFSET(MSFT_FuncRecord, oEntry))
2403 {
2404 if (pFuncRec->FKCCIC & 0x2000 )
2405 {
2406 if (!IS_INTRESOURCE(pFuncRec->oEntry))
2407 ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->oEntry);
2408 ptfd->Entry = (TLBString*)(DWORD_PTR)LOWORD(pFuncRec->oEntry);
2409 }
2410 else
2411 ptfd->Entry = MSFT_ReadString(pcx, pFuncRec->oEntry);
2412 }
2413 else
2414 ptfd->Entry = (TLBString*)-1;
2415
2416 if (optional > FIELD_OFFSET(MSFT_FuncRecord, HelpStringContext))
2417 ptfd->HelpStringContext = pFuncRec->HelpStringContext;
2418
2419 if (optional > FIELD_OFFSET(MSFT_FuncRecord, oCustData) && pFuncRec->FKCCIC & 0x80)
2420 MSFT_CustData(pcx, pFuncRec->oCustData, &ptfd->custdata_list);
2421
2422 /* fill the FuncDesc Structure */
2423 MSFT_ReadLEDWords( & ptfd->funcdesc.memid, sizeof(INT), pcx,
2424 offset + infolen + ( i + 1) * sizeof(INT));
2425
2426 ptfd->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
2427 ptfd->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF;
2428 ptfd->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF;
2429 ptfd->funcdesc.cParams = pFuncRec->nrargs ;
2430 ptfd->funcdesc.cParamsOpt = pFuncRec->nroargs ;
2431 if (ptfd->funcdesc.funckind == FUNC_DISPATCH)
2432 ptfd->funcdesc.oVft = 0;
2433 else
2434 ptfd->funcdesc.oVft = (unsigned short)(pFuncRec->VtableOffset & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
2435 ptfd->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
2436
2437 /* nameoffset is sometimes -1 on the second half of a propget/propput
2438 * pair of functions */
2439 if ((nameoffset == -1) && (i > 0) &&
2440 TLB_is_propgetput(ptfd_prev->funcdesc.invkind) &&
2441 TLB_is_propgetput(ptfd->funcdesc.invkind))
2442 ptfd->Name = ptfd_prev->Name;
2443 else
2444 ptfd->Name = MSFT_ReadName(pcx, nameoffset);
2445
2446 MSFT_GetTdesc(pcx,
2447 pFuncRec->DataType,
2448 &ptfd->funcdesc.elemdescFunc.tdesc);
2449
2450 /* do the parameters/arguments */
2451 if(pFuncRec->nrargs)
2452 {
2453 int j = 0;
2454 MSFT_ParameterInfo paraminfo;
2455
2456 ptfd->funcdesc.lprgelemdescParam =
2457 calloc(pFuncRec->nrargs, sizeof(ELEMDESC) + sizeof(PARAMDESCEX));
2458
2459 ptfd->pParamDesc = TLBParDesc_Constructor(pFuncRec->nrargs);
2460
2461 MSFT_ReadLEDWords(&paraminfo, sizeof(paraminfo), pcx,
2462 recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
2463
2464 for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
2465 {
2466 ELEMDESC *elemdesc = &ptfd->funcdesc.lprgelemdescParam[j];
2467
2468 MSFT_GetTdesc(pcx,
2469 paraminfo.DataType,
2470 &elemdesc->tdesc);
2471
2472 elemdesc->paramdesc.wParamFlags = paraminfo.Flags;
2473
2474 /* name */
2475 if (paraminfo.oName != -1)
2476 ptfd->pParamDesc[j].Name =
2477 MSFT_ReadName( pcx, paraminfo.oName );
2478 TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w(TLB_get_bstr(ptfd->pParamDesc[j].Name)));
2479
2480 /* default value */
2481 if ( (elemdesc->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) &&
2482 (pFuncRec->FKCCIC & 0x1000) )
2483 {
2484 INT* pInt = (INT *)((char *)pFuncRec +
2485 reclength -
2486 (pFuncRec->nrargs * 4) * sizeof(INT) );
2487
2488 PARAMDESC* pParamDesc = &elemdesc->paramdesc;
2489
2490 pParamDesc->pparamdescex = (PARAMDESCEX*)(ptfd->funcdesc.lprgelemdescParam+pFuncRec->nrargs)+j;
2491 pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);
2492
2493 MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
2494 pInt[j], pcx);
2495 }
2496 else
2497 elemdesc->paramdesc.pparamdescex = NULL;
2498
2499 /* custom info */
2500 if (optional > (FIELD_OFFSET(MSFT_FuncRecord, oArgCustData) +
2501 j*sizeof(pFuncRec->oArgCustData[0])) &&
2502 pFuncRec->FKCCIC & 0x80 )
2503 {
2504 MSFT_CustData(pcx,
2505 pFuncRec->oArgCustData[j],
2506 &ptfd->pParamDesc[j].custdata_list);
2507 }
2508
2509 /* SEEK value = jump to offset,
2510 * from there jump to the end of record,
2511 * go back by (j-1) arguments
2512 */
2513 MSFT_ReadLEDWords( &paraminfo ,
2514 sizeof(MSFT_ParameterInfo), pcx,
2515 recoffset + reclength - ((pFuncRec->nrargs - j - 1)
2516 * sizeof(MSFT_ParameterInfo)));
2517 }
2518 }
2519
2520 /* scode is not used: archaic win16 stuff FIXME: right? */
2521 ptfd->funcdesc.cScodes = 0 ;
2522 ptfd->funcdesc.lprgscode = NULL ;
2523
2524 ptfd_prev = ptfd;
2525 ++ptfd;
2526 recoffset += reclength;
2527 }
2528 free(recbuf);
2529}
2530
2531static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
2532 int cVars, int offset, TLBVarDesc ** pptvd)
2533{
2534 int infolen, nameoffset, reclength;
2535 char recbuf[256];
2536 MSFT_VarRecord *pVarRec = (MSFT_VarRecord*)recbuf;
2537 TLBVarDesc *ptvd;
2538 int i;
2539 int recoffset;
2540
2541 TRACE_(typelib)("\n");
2542
2543 ptvd = *pptvd = TLBVarDesc_Alloc(cVars);
2544 MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
2545 MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
2546 ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
2547 recoffset += offset+sizeof(INT);
2548 for(i=0;i<cVars;i++, ++ptvd){
2549 /* name, eventually add to a hash table */
2550 MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
2551 offset + infolen + (2*cFuncs + cVars + i + 1) * sizeof(INT));
2552 ptvd->Name=MSFT_ReadName(pcx, nameoffset);
2553 /* read the variable information record */
2554 MSFT_ReadLEDWords(&reclength, sizeof(pVarRec->Info), pcx, recoffset);
2555 reclength &= 0xff;
2557
2558 /* optional data */
2559 if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpContext))
2560 ptvd->HelpContext = pVarRec->HelpContext;
2561
2562 if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpString))
2563 ptvd->HelpString = MSFT_ReadString(pcx, pVarRec->HelpString);
2564
2565 if (reclength > FIELD_OFFSET(MSFT_VarRecord, oCustData))
2566 MSFT_CustData(pcx, pVarRec->oCustData, &ptvd->custdata_list);
2567
2568 if(reclength > FIELD_OFFSET(MSFT_VarRecord, HelpStringContext))
2569 ptvd->HelpStringContext = pVarRec->HelpStringContext;
2570
2571 /* fill the VarDesc Structure */
2572 MSFT_ReadLEDWords(&ptvd->vardesc.memid, sizeof(INT), pcx,
2573 offset + infolen + (cFuncs + i + 1) * sizeof(INT));
2574 ptvd->vardesc.varkind = pVarRec->VarKind;
2575 ptvd->vardesc.wVarFlags = pVarRec->Flags;
2576 MSFT_GetTdesc(pcx, pVarRec->DataType,
2577 &ptvd->vardesc.elemdescVar.tdesc);
2578/* ptvd->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
2579 if(pVarRec->VarKind == VAR_CONST ){
2580 ptvd->vardesc.lpvarValue = calloc(1, sizeof(VARIANT));
2581 MSFT_ReadValue(ptvd->vardesc.lpvarValue,
2582 pVarRec->OffsValue, pcx);
2583 } else
2584 ptvd->vardesc.oInst=pVarRec->OffsValue;
2585 recoffset += reclength;
2586 }
2587}
2588
2589/* process Implemented Interfaces of a com class */
2591 int offset)
2592{
2593 int i;
2594 MSFT_RefRecord refrec;
2595 TLBImplType *pImpl;
2596
2597 TRACE_(typelib)("\n");
2598
2600 pImpl = pTI->impltypes;
2601 for(i=0;i<count;i++){
2602 if(offset<0) break; /* paranoia */
2603 MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
2604 pImpl->hRef = refrec.reftype;
2605 pImpl->implflags=refrec.flags;
2606 MSFT_CustData(pcx, refrec.oCustData, &pImpl->custdata_list);
2607 offset=refrec.onext;
2608 ++pImpl;
2609 }
2610}
2611
2612/* when a typelib is loaded in a different 32/64-bit mode, we need to resize pointers
2613 * and some structures, and fix the alignment */
2615{
2616 if(info->typeattr.typekind == TKIND_ALIAS){
2617 switch(info->tdescAlias->vt){
2618 case VT_BSTR:
2619 case VT_DISPATCH:
2620 case VT_UNKNOWN:
2621 case VT_PTR:
2622 case VT_SAFEARRAY:
2623 case VT_LPSTR:
2624 case VT_LPWSTR:
2625 info->typeattr.cbSizeInstance = sizeof(void*);
2626 info->typeattr.cbAlignment = sizeof(void*);
2627 break;
2628 case VT_CARRAY:
2629 case VT_USERDEFINED:
2631 &info->typeattr.cbSizeInstance, &info->typeattr.cbAlignment);
2632 break;
2633 case VT_VARIANT:
2634 info->typeattr.cbSizeInstance = sizeof(VARIANT);
2635 info->typeattr.cbAlignment = sizeof(void *);
2636 break;
2637 default:
2638 if(info->typeattr.cbSizeInstance < sizeof(void*))
2639 info->typeattr.cbAlignment = info->typeattr.cbSizeInstance;
2640 else
2641 info->typeattr.cbAlignment = sizeof(void*);
2642 break;
2643 }
2644 }else if(info->typeattr.typekind == TKIND_INTERFACE ||
2645 info->typeattr.typekind == TKIND_DISPATCH ||
2646 info->typeattr.typekind == TKIND_COCLASS){
2647 info->typeattr.cbSizeInstance = sizeof(void*);
2648 info->typeattr.cbAlignment = sizeof(void*);
2649 }
2650}
2651
2652/*
2653 * process a typeinfo record
2654 */
2656 TLBContext *pcx,
2657 int count,
2658 ITypeLibImpl * pLibInfo)
2659{
2660 MSFT_TypeInfoBase tiBase;
2661 ITypeInfoImpl *ptiRet;
2662
2663 TRACE_(typelib)("count=%u\n", count);
2664
2665 ptiRet = ITypeInfoImpl_Constructor();
2666 MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx ,
2667 pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
2668
2669/* this is where we are coming from */
2670 ptiRet->pTypeLib = pLibInfo;
2671 ptiRet->index=count;
2672
2673 ptiRet->guid = MSFT_ReadGuid(tiBase.posguid, pcx);
2674 ptiRet->typeattr.lcid = pLibInfo->set_lcid; /* FIXME: correct? */
2675 ptiRet->typeattr.lpstrSchema = NULL; /* reserved */
2676 ptiRet->typeattr.cbSizeInstance = tiBase.size;
2677 ptiRet->typeattr.typekind = tiBase.typekind & 0xF;
2678 ptiRet->typeattr.cFuncs = LOWORD(tiBase.cElement);
2679 ptiRet->typeattr.cVars = HIWORD(tiBase.cElement);
2680 ptiRet->typeattr.cbAlignment = (tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
2681 ptiRet->typeattr.wTypeFlags = tiBase.flags;
2682 ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version);
2683 ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version);
2684 ptiRet->typeattr.cImplTypes = tiBase.cImplTypes;
2685 ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft;
2686 if (ptiRet->typeattr.typekind == TKIND_ALIAS) {
2687 TYPEDESC tmp;
2688 MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
2689 ptiRet->tdescAlias = malloc(TLB_SizeTypeDesc(&tmp, TRUE));
2690 TLB_CopyTypeDesc(NULL, &tmp, ptiRet->tdescAlias);
2691 }
2692
2693/* FIXME: */
2694/* IDLDESC idldescType; *//* never saw this one != zero */
2695
2696/* name, eventually add to a hash table */
2697 ptiRet->Name=MSFT_ReadName(pcx, tiBase.NameOffset);
2698 ptiRet->hreftype = MSFT_ReadHreftype(pcx, tiBase.NameOffset);
2699 TRACE_(typelib)("reading %s\n", debugstr_w(TLB_get_bstr(ptiRet->Name)));
2700 /* help info */
2701 ptiRet->DocString=MSFT_ReadString(pcx, tiBase.docstringoffs);
2703 ptiRet->dwHelpContext=tiBase.helpcontext;
2704
2705 if (ptiRet->typeattr.typekind == TKIND_MODULE)
2706 ptiRet->DllName = MSFT_ReadString(pcx, tiBase.datatype1);
2707
2708/* note: InfoType's Help file and HelpStringDll come from the containing
2709 * library. Further HelpString and Docstring appear to be the same thing :(
2710 */
2711 /* functions */
2712 if(ptiRet->typeattr.cFuncs >0 )
2713 MSFT_DoFuncs(pcx, ptiRet, ptiRet->typeattr.cFuncs,
2714 ptiRet->typeattr.cVars,
2715 tiBase.memoffset, &ptiRet->funcdescs);
2716 /* variables */
2717 if(ptiRet->typeattr.cVars >0 )
2718 MSFT_DoVars(pcx, ptiRet, ptiRet->typeattr.cFuncs,
2719 ptiRet->typeattr.cVars,
2720 tiBase.memoffset, &ptiRet->vardescs);
2721 if(ptiRet->typeattr.cImplTypes >0 ) {
2722 switch(ptiRet->typeattr.typekind)
2723 {
2724 case TKIND_COCLASS:
2725 MSFT_DoImplTypes(pcx, ptiRet, ptiRet->typeattr.cImplTypes,
2726 tiBase.datatype1);
2727 break;
2728 case TKIND_DISPATCH:
2729 /* This is not -1 when the interface is a non-base dual interface or
2730 when a dispinterface wraps an interface, i.e., the idl 'dispinterface x {interface y;};'.
2731 Note however that GetRefTypeOfImplType(0) always returns a ref to IDispatch and
2732 not this interface.
2733 */
2734
2735 if (tiBase.datatype1 != -1)
2736 {
2737 ptiRet->impltypes = TLBImplType_Alloc(1);
2738 ptiRet->impltypes[0].hRef = tiBase.datatype1;
2739 }
2740 break;
2741 default:
2742 ptiRet->impltypes = TLBImplType_Alloc(1);
2743 ptiRet->impltypes[0].hRef = tiBase.datatype1;
2744 break;
2745 }
2746 }
2747 MSFT_CustData(pcx, tiBase.oCustData, ptiRet->pcustdata_list);
2748
2749 TRACE_(typelib)("%s guid: %s kind:%s\n",
2750 debugstr_w(TLB_get_bstr(ptiRet->Name)),
2752 typekind_desc[ptiRet->typeattr.typekind]);
2753 if (TRACE_ON(typelib))
2754 dump_TypeInfo(ptiRet);
2755
2756 return ptiRet;
2757}
2758
2760{
2761 char *string;
2762 INT16 len_str, len_piece;
2763 int offs = 0, lengthInChars;
2764
2765 MSFT_Seek(pcx, pcx->pTblDir->pStringtab.offset);
2766 while (1) {
2767 TLBString *tlbstr;
2768
2769 if (offs >= pcx->pTblDir->pStringtab.length)
2770 return S_OK;
2771
2772 MSFT_ReadLEWords(&len_str, sizeof(INT16), pcx, DO_NOT_SEEK);
2773 len_piece = len_str + sizeof(INT16);
2774 if(len_piece % 4)
2775 len_piece = (len_piece + 4) & ~0x3;
2776 if(len_piece < 8)
2777 len_piece = 8;
2778
2779 string = malloc(len_piece + 1);
2780 MSFT_Read(string, len_piece - sizeof(INT16), pcx, DO_NOT_SEEK);
2781 string[len_str] = '\0';
2782
2784 string, -1, NULL, 0);
2785 if (!lengthInChars) {
2786 free(string);
2787 return E_UNEXPECTED;
2788 }
2789
2790 tlbstr = malloc(sizeof(TLBString));
2791
2792 tlbstr->offset = offs;
2793 tlbstr->str = SysAllocStringByteLen(NULL, lengthInChars * sizeof(WCHAR));
2794 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, tlbstr->str, lengthInChars);
2795
2796 free(string);
2797
2798 list_add_tail(&pcx->pLibInfo->string_list, &tlbstr->entry);
2799
2800 offs += len_piece;
2801 }
2802}
2803
2805{
2806 TLBRefType *ref;
2807 int offs = 0;
2808
2809 MSFT_Seek(pcx, pcx->pTblDir->pImpInfo.offset);
2810 while (offs < pcx->pTblDir->pImpInfo.length) {
2811 MSFT_ImpInfo impinfo;
2812 TLBImpLib *pImpLib;
2813
2814 MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx, DO_NOT_SEEK);
2815
2816 ref = calloc(1, sizeof(TLBRefType));
2817 list_add_tail(&pcx->pLibInfo->ref_list, &ref->entry);
2818
2820 if(pImpLib->offset==impinfo.oImpFile)
2821 break;
2822
2823 if(&pImpLib->entry != &pcx->pLibInfo->implib_list){
2824 ref->reference = offs;
2825 ref->pImpTLInfo = pImpLib;
2826 if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
2827 ref->guid = MSFT_ReadGuid(impinfo.oGuid, pcx);
2828 TRACE("importing by guid %s\n", debugstr_guid(TLB_get_guidref(ref->guid)));
2829 ref->index = TLB_REF_USE_GUID;
2830 } else
2831 ref->index = impinfo.oGuid;
2832 }else{
2833 ERR("Cannot find a reference\n");
2834 ref->reference = -1;
2835 ref->pImpTLInfo = TLB_REF_NOT_FOUND;
2836 }
2837
2838 offs += sizeof(impinfo);
2839 }
2840
2841 return S_OK;
2842}
2843
2844/* Because type library parsing has some degree of overhead, and some apps repeatedly load the same
2845 * typelibs over and over, we cache them here. According to MSDN Microsoft have a similar scheme in
2846 * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable
2847 * tradeoff here.
2848 */
2852{
2853 0, 0, &cache_section,
2855 0, 0, { (DWORD_PTR)(__FILE__ ": typelib loader cache") }
2856};
2857static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 };
2858
2859
2860typedef struct TLB_PEFile
2861{
2869
2871{
2872 return CONTAINING_RECORD(iface, TLB_PEFile, IUnknown_iface);
2873}
2874
2876{
2878 {
2879 *ppv = iface;
2880 IUnknown_AddRef(iface);
2881 return S_OK;
2882 }
2883 *ppv = NULL;
2884 return E_NOINTERFACE;
2885}
2886
2888{
2890 return InterlockedIncrement(&This->refs);
2891}
2892
2894{
2896 ULONG refs = InterlockedDecrement(&This->refs);
2897 if (!refs)
2898 {
2899 if (This->typelib_global)
2900 FreeResource(This->typelib_global);
2901 if (This->dll)
2902 FreeLibrary(This->dll);
2903 free(This);
2904 }
2905 return refs;
2906}
2907
2908static const IUnknownVtbl TLB_PEFile_Vtable =
2909{
2913};
2914
2915static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
2916{
2919
2920 This = malloc(sizeof(TLB_PEFile));
2921 if (!This)
2922 return E_OUTOFMEMORY;
2923
2924 This->IUnknown_iface.lpVtbl = &TLB_PEFile_Vtable;
2925 This->refs = 1;
2926 This->dll = NULL;
2927 This->typelib_resource = NULL;
2928 This->typelib_global = NULL;
2929 This->typelib_base = NULL;
2930
2933
2934 if (This->dll)
2935 {
2936 This->typelib_resource = FindResourceW(This->dll, MAKEINTRESOURCEW(index), L"TYPELIB");
2937 if (This->typelib_resource)
2938 {
2939 This->typelib_global = LoadResource(This->dll, This->typelib_resource);
2940 if (This->typelib_global)
2941 {
2942 This->typelib_base = LockResource(This->typelib_global);
2943
2944 if (This->typelib_base)
2945 {
2946 *pdwTLBLength = SizeofResource(This->dll, This->typelib_resource);
2947 *ppBase = This->typelib_base;
2948 *ppFile = &This->IUnknown_iface;
2949 return S_OK;
2950 }
2951 }
2952 }
2953
2954 TRACE("No TYPELIB resource found\n");
2955 hr = E_FAIL;
2956 }
2957
2958 TLB_PEFile_Release(&This->IUnknown_iface);
2959 return hr;
2960}
2961
2962typedef struct TLB_NEFile
2963{
2968
2970{
2971 return CONTAINING_RECORD(iface, TLB_NEFile, IUnknown_iface);
2972}
2973
2975{
2977 {
2978 *ppv = iface;
2979 IUnknown_AddRef(iface);
2980 return S_OK;
2981 }
2982 *ppv = NULL;
2983 return E_NOINTERFACE;
2984}
2985
2987{
2989 return InterlockedIncrement(&This->refs);
2990}
2991
2993{
2995 ULONG refs = InterlockedDecrement(&This->refs);
2996 if (!refs)
2997 {
2998 free(This->typelib_base);
2999 free(This);
3000 }
3001 return refs;
3002}
3003
3004static const IUnknownVtbl TLB_NEFile_Vtable =
3005{
3009};
3010
3011/***********************************************************************
3012 * read_xx_header [internal]
3013 */
3014static int read_xx_header( HFILE lzfd )
3015{
3016 IMAGE_DOS_HEADER mzh;
3017 char magic[3];
3018
3019 LZSeek( lzfd, 0, SEEK_SET );
3020 if ( sizeof(mzh) != LZRead( lzfd, (LPSTR)&mzh, sizeof(mzh) ) )
3021 return 0;
3022 if ( mzh.e_magic != IMAGE_DOS_SIGNATURE )
3023 return 0;
3024
3025 LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
3026 if ( 2 != LZRead( lzfd, magic, 2 ) )
3027 return 0;
3028
3029 LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
3030
3031 if ( magic[0] == 'N' && magic[1] == 'E' )
3032 return IMAGE_OS2_SIGNATURE;
3033 if ( magic[0] == 'P' && magic[1] == 'E' )
3034 return IMAGE_NT_SIGNATURE;
3035
3036 magic[2] = '\0';
3037 WARN("Can't handle %s files.\n", magic );
3038 return 0;
3039}
3040
3041
3042/***********************************************************************
3043 * find_ne_resource [internal]
3044 */
3045static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
3046 DWORD *resLen, DWORD *resOff )
3047{
3048 IMAGE_OS2_HEADER nehd;
3049 NE_TYPEINFO *typeInfo;
3050 NE_NAMEINFO *nameInfo;
3051 DWORD nehdoffset;
3052 LPBYTE resTab;
3053 DWORD resTabSize;
3054 int count;
3055
3056 /* Read in NE header */
3057 nehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
3058 if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return FALSE;
3059
3060 resTabSize = nehd.ne_restab - nehd.ne_rsrctab;
3061 if ( !resTabSize )
3062 {
3063 TRACE("No resources in NE dll\n" );
3064 return FALSE;
3065 }
3066
3067 /* Read in resource table */
3068 resTab = malloc( resTabSize );
3069 if ( !resTab ) return FALSE;
3070
3071 LZSeek( lzfd, nehd.ne_rsrctab + nehdoffset, SEEK_SET );
3072 if ( resTabSize != LZRead( lzfd, (char*)resTab, resTabSize ) )
3073 {
3074 free( resTab );
3075 return FALSE;
3076 }
3077
3078 /* Find resource */
3079 typeInfo = (NE_TYPEINFO *)(resTab + 2);
3080
3081 if (!IS_INTRESOURCE(typeid)) /* named type */
3082 {
3083 BYTE len = strlen( typeid );
3084 while (typeInfo->type_id)
3085 {
3086 if (!(typeInfo->type_id & 0x8000))
3087 {
3088 BYTE *p = resTab + typeInfo->type_id;
3089 if ((*p == len) && !_strnicmp( (char*)p+1, typeid, len )) goto found_type;
3090 }
3091 typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
3092 typeInfo->count * sizeof(NE_NAMEINFO));
3093 }
3094 }
3095 else /* numeric type id */
3096 {
3097 WORD id = LOWORD(typeid) | 0x8000;
3098 while (typeInfo->type_id)
3099 {
3100 if (typeInfo->type_id == id) goto found_type;
3101 typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
3102 typeInfo->count * sizeof(NE_NAMEINFO));
3103 }
3104 }
3105 TRACE("No typeid entry found for %p\n", typeid );
3106 free( resTab );
3107 return FALSE;
3108
3109 found_type:
3110 nameInfo = (NE_NAMEINFO *)(typeInfo + 1);
3111
3112 if (!IS_INTRESOURCE(resid)) /* named resource */
3113 {
3114 BYTE len = strlen( resid );
3115 for (count = typeInfo->count; count > 0; count--, nameInfo++)
3116 {
3117 BYTE *p = resTab + nameInfo->id;
3118 if (nameInfo->id & 0x8000) continue;
3119 if ((*p == len) && !_strnicmp( (char*)p+1, resid, len )) goto found_name;
3120 }
3121 }
3122 else /* numeric resource id */
3123 {
3124 WORD id = LOWORD(resid) | 0x8000;
3125 for (count = typeInfo->count; count > 0; count--, nameInfo++)
3126 if (nameInfo->id == id) goto found_name;
3127 }
3128 TRACE("No resid entry found for %p\n", typeid );
3129 free( resTab );
3130 return FALSE;
3131
3132 found_name:
3133 /* Return resource data */
3134 if ( resLen ) *resLen = nameInfo->length << *(WORD *)resTab;
3135 if ( resOff ) *resOff = nameInfo->offset << *(WORD *)resTab;
3136
3137 free( resTab );
3138 return TRUE;
3139}
3140
3141static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile){
3142
3143 HFILE lzfd = -1;
3144 OFSTRUCT ofs;
3147
3148 This = malloc(sizeof(TLB_NEFile));
3149 if (!This) return E_OUTOFMEMORY;
3150
3151 This->IUnknown_iface.lpVtbl = &TLB_NEFile_Vtable;
3152 This->refs = 1;
3153 This->typelib_base = NULL;
3154
3155 lzfd = LZOpenFileW( (LPWSTR)path, &ofs, OF_READ );
3156 if ( lzfd >= 0 && read_xx_header( lzfd ) == IMAGE_OS2_SIGNATURE )
3157 {
3159 if( find_ne_resource( lzfd, "TYPELIB", MAKEINTRESOURCEA(index), &reslen, &offset ) )
3160 {
3161 This->typelib_base = malloc(reslen);
3162 if( !This->typelib_base )
3163 hr = E_OUTOFMEMORY;
3164 else
3165 {
3166 LZSeek( lzfd, offset, SEEK_SET );
3167 reslen = LZRead( lzfd, This->typelib_base, reslen );
3168 LZClose( lzfd );
3169 *ppBase = This->typelib_base;
3170 *pdwTLBLength = reslen;
3171 *ppFile = &This->IUnknown_iface;
3172 return S_OK;
3173 }
3174 }
3175 }
3176
3177 if( lzfd >= 0) LZClose( lzfd );
3178 TLB_NEFile_Release(&This->IUnknown_iface);
3179 return hr;
3180}
3181
3182typedef struct TLB_Mapping
3183{
3190
3192{
3193 return CONTAINING_RECORD(iface, TLB_Mapping, IUnknown_iface);
3194}
3195
3197{
3199 {
3200 *ppv = iface;
3201 IUnknown_AddRef(iface);
3202 return S_OK;
3203 }
3204 *ppv = NULL;
3205 return E_NOINTERFACE;
3206}
3207
3209{
3211 return InterlockedIncrement(&This->refs);
3212}
3213
3215{
3217 ULONG refs = InterlockedDecrement(&This->refs);
3218 if (!refs)
3219 {
3220 if (This->typelib_base)
3221 UnmapViewOfFile(This->typelib_base);
3222 if (This->mapping)
3223 CloseHandle(This->mapping);
3224 if (This->file != INVALID_HANDLE_VALUE)
3225 CloseHandle(This->file);
3226 free(This);
3227 }
3228 return refs;
3229}
3230
3231static const IUnknownVtbl TLB_Mapping_Vtable =
3232{
3236};
3237
3238static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
3239{
3241
3242 This = malloc(sizeof(TLB_Mapping));
3243 if (!This)
3244 return E_OUTOFMEMORY;
3245
3246 This->IUnknown_iface.lpVtbl = &TLB_Mapping_Vtable;
3247 This->refs = 1;
3248 This->file = INVALID_HANDLE_VALUE;
3249 This->mapping = NULL;
3250 This->typelib_base = NULL;
3251
3253 if (INVALID_HANDLE_VALUE != This->file)
3254 {
3255 This->mapping = CreateFileMappingW(This->file, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
3256 if (This->mapping)
3257 {
3258 This->typelib_base = MapViewOfFile(This->mapping, FILE_MAP_READ, 0, 0, 0);
3259 if(This->typelib_base)
3260 {
3261 /* retrieve file size */
3262 *pdwTLBLength = GetFileSize(This->file, NULL);
3263 *ppBase = This->typelib_base;
3264 *ppFile = &This->IUnknown_iface;
3265 return S_OK;
3266 }
3267 }
3268 }
3269
3270 IUnknown_Release(&This->IUnknown_iface);
3272}
3273
3274/****************************************************************************
3275 * TLB_ReadTypeLib
3276 *
3277 * find the type of the typelib file and map the typelib resource into
3278 * the memory
3279 */
3280
3281#define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */
3282static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib)
3283{
3285 HRESULT ret;
3286 INT index = 1;
3287 LPWSTR index_str, file = (LPWSTR)pszFileName;
3288 LPVOID pBase = NULL;
3289 DWORD dwTLBLength = 0;
3290 IUnknown *pFile = NULL;
3291 HANDLE h;
3292
3293 *ppTypeLib = NULL;
3294
3295 index_str = wcsrchr(pszFileName, '\\');
3296 if(index_str && *++index_str != '\0')
3297 {
3298 LPWSTR end_ptr;
3299 LONG idx = wcstol(index_str, &end_ptr, 10);
3300 if(*end_ptr == '\0')
3301 {
3302 int str_len = index_str - pszFileName - 1;
3303 index = idx;
3304 file = malloc((str_len + 1) * sizeof(WCHAR));
3305 memcpy(file, pszFileName, str_len * sizeof(WCHAR));
3306 file[str_len] = 0;
3307 }
3308 }
3309
3310 if(!SearchPathW(NULL, file, NULL, cchPath, pszPath, NULL))
3311 {
3312 if(wcschr(file, '\\'))
3313 {
3314 lstrcpyW(pszPath, file);
3315 }
3316 else
3317 {
3318 int len = GetSystemDirectoryW(pszPath, cchPath);
3319 pszPath[len] = '\\';
3320 memcpy(pszPath + len + 1, file, (lstrlenW(file) + 1) * sizeof(WCHAR));
3321 }
3322 }
3323
3324 if(file != pszFileName) free(file);
3325
3327 if(h != INVALID_HANDLE_VALUE){
3329 CloseHandle(h);
3330 }
3331
3332 TRACE_(typelib)("File %s index %d\n", debugstr_w(pszPath), index);
3333
3334 /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */
3337 {
3338 if (!wcsicmp(entry->path, pszPath) && entry->index == index)
3339 {
3340 TRACE("cache hit\n");
3341 *ppTypeLib = &entry->ITypeLib2_iface;
3342 ITypeLib2_AddRef(*ppTypeLib);
3344 return S_OK;
3345 }
3346 }
3348
3349 /* now actually load and parse the typelib */
3350
3351 ret = TLB_PEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
3353 ret = TLB_NEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
3355 ret = TLB_Mapping_Open(pszPath, &pBase, &dwTLBLength, &pFile);
3356 if (SUCCEEDED(ret))
3357 {
3358 if (dwTLBLength >= 4)
3359 {
3360 DWORD dwSignature = FromLEDWord(*((DWORD*) pBase));
3361 if (dwSignature == MSFT_SIGNATURE)
3362 *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
3363 else if (dwSignature == SLTG_SIGNATURE)
3364 *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
3365 else
3366 {
3367 FIXME("Header type magic %#lx not supported.\n", dwSignature);
3369 }
3370 }
3371 else
3373 IUnknown_Release(pFile);
3374 }
3375
3376 if(*ppTypeLib) {
3377 ITypeLibImpl *impl = impl_from_ITypeLib2(*ppTypeLib);
3378
3379 TRACE("adding to cache\n");
3380 impl->path = wcsdup(pszPath);
3381 /* We should really canonicalise the path here. */
3382 impl->index = index;
3383
3384 /* FIXME: check if it has added already in the meantime */
3386 list_add_head(&tlb_cache, &impl->entry);
3388 ret = S_OK;
3389 }
3390 else
3391 {
3392 if(ret != E_FAIL)
3393 ERR("Loading of typelib %s failed with error %ld\n", debugstr_w(pszFileName), GetLastError());
3394
3396 }
3397
3398
3399 return ret;
3400}
3401
3402/*================== ITypeLib(2) Methods ===================================*/
3403
3405{
3406 ITypeLibImpl* pTypeLibImpl;
3407
3408 pTypeLibImpl = calloc(1, sizeof(ITypeLibImpl));
3409 if (!pTypeLibImpl) return NULL;
3410
3411 pTypeLibImpl->ITypeLib2_iface.lpVtbl = &tlbvt;
3412 pTypeLibImpl->ITypeComp_iface.lpVtbl = &tlbtcvt;
3413 pTypeLibImpl->ICreateTypeLib2_iface.lpVtbl = &CreateTypeLib2Vtbl;
3414 pTypeLibImpl->ref = 1;
3415
3416 list_init(&pTypeLibImpl->implib_list);
3417 list_init(&pTypeLibImpl->custdata_list);
3418 list_init(&pTypeLibImpl->name_list);
3419 list_init(&pTypeLibImpl->string_list);
3420 list_init(&pTypeLibImpl->guid_list);
3421 list_init(&pTypeLibImpl->ref_list);
3422 pTypeLibImpl->dispatch_href = -1;
3423
3424 return pTypeLibImpl;
3425}
3426
3427/****************************************************************************
3428 * ITypeLib2_Constructor_MSFT
3429 *
3430 * loading an MSFT typelib from an in-memory image
3431 */
3433{
3434 TLBContext cx;
3435 LONG lPSegDir;
3436 MSFT_Header tlbHeader;
3437 MSFT_SegDir tlbSegDir;
3438 ITypeLibImpl * pTypeLibImpl;
3439 int i;
3440
3441 TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength);
3442
3443 pTypeLibImpl = TypeLibImpl_Constructor();
3444 if (!pTypeLibImpl) return NULL;
3445
3446 /* get pointer to beginning of typelib data */
3447 cx.pos = 0;
3448 cx.oStart=0;
3449 cx.mapping = pLib;
3450 cx.pLibInfo = pTypeLibImpl;
3451 cx.length = dwTLBLength;
3452
3453 /* read header */
3454 MSFT_ReadLEDWords(&tlbHeader, sizeof(tlbHeader), &cx, 0);
3455 TRACE_(typelib)("header:\n");
3456 TRACE_(typelib)("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
3457 if (tlbHeader.magic1 != MSFT_SIGNATURE) {
3458 FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
3459 return NULL;
3460 }
3461 TRACE_(typelib)("\tdispatchpos = 0x%x\n", tlbHeader.dispatchpos);
3462
3463 /* there is a small amount of information here until the next important
3464 * part:
3465 * the segment directory . Try to calculate the amount of data */
3466 lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);
3467
3468 /* now read the segment directory */
3469 TRACE("read segment directory (at %ld)\n",lPSegDir);
3470 MSFT_ReadLEDWords(&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
3471 cx.pTblDir = &tlbSegDir;
3472
3473 /* just check two entries */
3474 if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
3475 {
3476 ERR("cannot find the table directory, ptr %#lx\n",lPSegDir);
3477 free(pTypeLibImpl);
3478 return NULL;
3479 }
3480
3484
3485 /* now fill our internal data */
3486 /* TLIBATTR fields */
3487 pTypeLibImpl->guid = MSFT_ReadGuid(tlbHeader.posguid, &cx);
3488
3489 pTypeLibImpl->syskind = tlbHeader.varflags & 0x0f; /* check the mask */
3490 pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind);
3491 pTypeLibImpl->ver_major = LOWORD(tlbHeader.version);
3492 pTypeLibImpl->ver_minor = HIWORD(tlbHeader.version);
3493 pTypeLibImpl->libflags = ((WORD) tlbHeader.flags & 0xffff) /* check mask */ | LIBFLAG_FHASDISKIMAGE;
3494
3495 pTypeLibImpl->set_lcid = tlbHeader.lcid2;
3496 pTypeLibImpl->lcid = tlbHeader.lcid;
3497
3498 /* name, eventually add to a hash table */
3499 pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset);
3500
3501 /* help info */
3502 pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring);
3503 pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile);
3504
3505 if( tlbHeader.varflags & HELPDLLFLAG)
3506 {
3507 int offset;
3508 MSFT_ReadLEDWords(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
3509 pTypeLibImpl->HelpStringDll = MSFT_ReadString(&cx, offset);
3510 }
3511
3512 pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;
3513
3514 /* custom data */
3515 if(tlbHeader.CustomDataOffset >= 0)
3516 {
3517 MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->custdata_list);
3518 }
3519
3520 /* fill in type descriptions */
3521 if(tlbSegDir.pTypdescTab.length > 0)
3522 {
3523 int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
3524 INT16 td[4];
3525 pTypeLibImpl->ctTypeDesc = cTD;
3526 pTypeLibImpl->pTypeDesc = calloc(cTD, sizeof(TYPEDESC));
3527 MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
3528 for(i=0; i<cTD; )
3529 {
3530 /* FIXME: add several sanity checks here */
3531 pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
3532 if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
3533 {
3534 /* FIXME: check safearray */
3535 if(td[3] < 0)
3536 pTypeLibImpl->pTypeDesc[i].lptdesc = &std_typedesc[td[2]];
3537 else
3538 pTypeLibImpl->pTypeDesc[i].lptdesc = &pTypeLibImpl->pTypeDesc[td[2]/8];
3539 }
3540 else if(td[0] == VT_CARRAY)
3541 {
3542 /* array descr table here */
3543 pTypeLibImpl->pTypeDesc[i].lpadesc = (void *)(INT_PTR)td[2]; /* temp store offset in*/
3544 }
3545 else if(td[0] == VT_USERDEFINED)
3546 {
3547 pTypeLibImpl->pTypeDesc[i].hreftype = MAKELONG(td[2],td[3]);
3548 }
3549 if(++i<cTD) MSFT_ReadLEWords(td, sizeof(td), &cx, DO_NOT_SEEK);
3550 }
3551
3552 /* second time around to fill the array subscript info */
3553 for(i=0;i<cTD;i++)
3554 {
3555 if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
3556 if(tlbSegDir.pArrayDescriptions.offset>0)
3557 {
3558 MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (INT_PTR)pTypeLibImpl->pTypeDesc[i].lpadesc);
3559 pTypeLibImpl->pTypeDesc[i].lpadesc = calloc(1, sizeof(ARRAYDESC) + sizeof(SAFEARRAYBOUND) * (td[3] - 1));
3560
3561 if(td[1]<0)
3562 pTypeLibImpl->pTypeDesc[i].lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK;
3563 else
3564 pTypeLibImpl->pTypeDesc[i].lpadesc->tdescElem = cx.pLibInfo->pTypeDesc[td[0]/(2*sizeof(INT))];
3565
3566 pTypeLibImpl->pTypeDesc[i].lpadesc->cDims = td[2];
3567
3568 for(j = 0; j<td[2]; j++)
3569 {
3570 MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].lpadesc->rgbounds[j].cElements,
3571 sizeof(INT), &cx, DO_NOT_SEEK);
3572 MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].lpadesc->rgbounds[j].lLbound,
3573 sizeof(INT), &cx, DO_NOT_SEEK);
3574 }
3575 }
3576 else
3577 {
3578 pTypeLibImpl->pTypeDesc[i].lpadesc = NULL;
3579 ERR("didn't find array description data\n");
3580 }
3581 }
3582 }
3583
3584 /* imported type libs */
3585 if(tlbSegDir.pImpFiles.offset>0)
3586 {
3587 TLBImpLib *pImpLib;
3588 int oGuid, offset = tlbSegDir.pImpFiles.offset;
3589 UINT16 size;
3590
3591 while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
3592 {
3593 char *name;
3594
3595 pImpLib = calloc(1, sizeof(TLBImpLib));
3596 pImpLib->offset = offset - tlbSegDir.pImpFiles.offset;
3597 MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset);
3598
3599 MSFT_ReadLEDWords(&pImpLib->lcid, sizeof(LCID), &cx, DO_NOT_SEEK);
3600 MSFT_ReadLEWords(&pImpLib->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK);
3601 MSFT_ReadLEWords(&pImpLib->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK);
3602 MSFT_ReadLEWords(& size, sizeof(UINT16), &cx, DO_NOT_SEEK);
3603
3604 size >>= 2;
3605 name = calloc(1, size + 1);
3607 pImpLib->name = TLB_MultiByteToBSTR(name);
3608 free(name);
3609
3610 pImpLib->guid = MSFT_ReadGuid(oGuid, &cx);
3611 offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3;
3612
3613 list_add_tail(&pTypeLibImpl->implib_list, &pImpLib->entry);
3614 }
3615 }
3616
3618
3619 pTypeLibImpl->dispatch_href = tlbHeader.dispatchpos;
3620
3621 /* type infos */
3622 if(tlbHeader.nrtypeinfos >= 0 )
3623 {
3624 ITypeInfoImpl **ppTI;
3625
3626 ppTI = pTypeLibImpl->typeinfos = calloc(tlbHeader.nrtypeinfos, sizeof(ITypeInfoImpl*));
3627
3628 for(i = 0; i < tlbHeader.nrtypeinfos; i++)
3629 {
3630 *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl);
3631
3632 ++ppTI;
3633 (pTypeLibImpl->TypeInfoCount)++;
3634 }
3635 }
3636
3637 if (pTypeLibImpl->ptr_size != sizeof(void *))
3638 {
3639 for(i = 0; i < pTypeLibImpl->TypeInfoCount; ++i)
3640 TLB_fix_typeinfo_ptr_size(pTypeLibImpl->typeinfos[i]);
3641 }
3642
3643 TRACE("(%p)\n", pTypeLibImpl);
3644 return &pTypeLibImpl->ITypeLib2_iface;
3645}
3646
3647
3648static BOOL TLB_GUIDFromString(const char *str, GUID *guid)
3649{
3650 char b[3];
3651 int i;
3652 short s;
3653
3654 if(sscanf(str, "%lx-%hx-%hx-%hx", &guid->Data1, &guid->Data2, &guid->Data3, &s) != 4) {
3655 FIXME("Can't parse guid %s\n", debugstr_guid(guid));
3656 return FALSE;
3657 }
3658
3659 guid->Data4[0] = s >> 8;
3660 guid->Data4[1] = s & 0xff;
3661
3662 b[2] = '\0';
3663 for(i = 0; i < 6; i++) {
3664 memcpy(b, str + 24 + 2 * i, 2);
3665 guid->Data4[i + 2] = strtol(b, NULL, 16);
3666 }
3667 return TRUE;
3668}
3669
3670static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib)
3671{
3672 WORD bytelen;
3673 DWORD len;
3674 BSTR tmp_str;
3675
3676 *pStr = NULL;
3677 bytelen = *(const WORD*)ptr;
3678 if(bytelen == 0xffff) return 2;
3679
3680 len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, NULL, 0);
3681 tmp_str = SysAllocStringLen(NULL, len);
3682 if (tmp_str) {
3683 MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, tmp_str, len);
3684 *pStr = TLB_append_str(&lib->string_list, tmp_str);
3685 SysFreeString(tmp_str);
3686 }
3687 return bytelen + 2;
3688}
3689
3690static WORD SLTG_ReadStringA(const char *ptr, char **str)
3691{
3692 WORD bytelen;
3693
3694 *str = NULL;
3695 bytelen = *(const WORD*)ptr;
3696 if(bytelen == 0xffff) return 2;
3697 *str = malloc(bytelen + 1);
3698 memcpy(*str, ptr + 2, bytelen);
3699 (*str)[bytelen] = '\0';
3700 return bytelen + 2;
3701}
3702
3703static TLBString *SLTG_ReadName(const char *pNameTable, int offset, ITypeLibImpl *lib)
3704{
3705 BSTR tmp_str;
3706 TLBString *tlbstr;
3707
3708 LIST_FOR_EACH_ENTRY(tlbstr, &lib->name_list, TLBString, entry) {
3709 if (tlbstr->offset == offset)
3710 return tlbstr;
3711 }
3712
3713 tmp_str = TLB_MultiByteToBSTR(pNameTable + offset);
3714 tlbstr = TLB_append_str(&lib->name_list, tmp_str);
3715 SysFreeString(tmp_str);
3716
3717 return tlbstr;
3718}
3719
3720static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl)
3721{
3722 char *ptr = pLibBlk;
3723 WORD w;
3724
3725 if((w = *(WORD*)ptr) != SLTG_LIBBLK_MAGIC) {
3726 FIXME("libblk magic = %04x\n", w);
3727 return 0;
3728 }
3729
3730 ptr += 6;
3731 if((w = *(WORD*)ptr) != 0xffff) {
3732 FIXME("LibBlk.res06 = %04x. Assuming string and skipping\n", w);
3733 ptr += w;
3734 }
3735 ptr += 2;
3736
3737 ptr += SLTG_ReadString(ptr, &pTypeLibImpl->DocString, pTypeLibImpl);
3738
3739 ptr += SLTG_ReadString(ptr, &pTypeLibImpl->HelpFile, pTypeLibImpl);
3740
3741 pTypeLibImpl->dwHelpContext = *(DWORD*)ptr;
3742 ptr += 4;
3743
3744 pTypeLibImpl->syskind = *(WORD*)ptr;
3745 pTypeLibImpl->ptr_size = get_ptr_size(pTypeLibImpl->syskind);
3746 ptr += 2;
3747
3749 pTypeLibImpl->lcid = pTypeLibImpl->set_lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0);
3750 else
3751 pTypeLibImpl->lcid = pTypeLibImpl->set_lcid = 0;
3752 ptr += 2;
3753
3754 ptr += 4; /* skip res12 */
3755
3756 pTypeLibImpl->libflags = *(WORD*)ptr;
3757 ptr += 2;
3758
3759 pTypeLibImpl->ver_major = *(WORD*)ptr;
3760 ptr += 2;
3761
3762 pTypeLibImpl->ver_minor = *(WORD*)ptr;
3763 ptr += 2;
3764
3765 pTypeLibImpl->guid = TLB_append_guid(&pTypeLibImpl->guid_list, (GUID*)ptr, -2);
3766 ptr += sizeof(GUID);
3767
3768 return ptr - (char*)pLibBlk;
3769}
3770
3771/* stores a mapping between the sltg typeinfo's references and the typelib's HREFTYPEs */
3772typedef struct
3773{
3774 unsigned int num;
3775 HREFTYPE refs[1];
3777
3779 HREFTYPE *typelib_ref)
3780{
3781 if(table && typeinfo_ref < table->num)
3782 {
3783 *typelib_ref = table->refs[typeinfo_ref];
3784 return S_OK;
3785 }
3786
3787 ERR_(typelib)("Unable to find reference\n");
3788 *typelib_ref = -1;
3789 return E_FAIL;
3790}
3791
3792static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_lookup_t *ref_lookup)
3793{
3794 BOOL done = FALSE;
3795
3796 while(!done) {
3797 if((*pType & 0xe00) == 0xe00) {
3798 pTD->vt = VT_PTR;
3799 pTD->lptdesc = calloc(1, sizeof(TYPEDESC));
3800 pTD = pTD->lptdesc;
3801 }
3802 switch(*pType & 0x3f) {
3803 case VT_PTR:
3804 pTD->vt = VT_PTR;
3805 pTD->lptdesc = calloc(1, sizeof(TYPEDESC));
3806 pTD = pTD->lptdesc;
3807 break;
3808
3809 case VT_USERDEFINED:
3810 pTD->vt = VT_USERDEFINED;
3811 sltg_get_typelib_ref(ref_lookup, *(++pType) / 4, &pTD->hreftype);
3812 done = TRUE;
3813 break;
3814
3815 case VT_CARRAY:
3816 {
3817 /* *(pType+1) is offset to a SAFEARRAY, *(pType+2) is type of
3818 array */
3819
3820 SAFEARRAY *pSA = (SAFEARRAY *)(pBlk + *(++pType));
3821
3822 pTD->vt = VT_CARRAY;
3823 pTD->lpadesc = calloc(1, sizeof(ARRAYDESC) + (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND));
3824 pTD->lpadesc->cDims = pSA->cDims;
3825 memcpy(pTD->lpadesc->rgbounds, pSA->rgsabound,
3826 pSA->cDims * sizeof(SAFEARRAYBOUND));
3827
3828 pTD = &pTD->lpadesc->tdescElem;
3829 break;
3830 }
3831
3832 case VT_SAFEARRAY:
3833 {
3834 /* FIXME: *(pType+1) gives an offset to SAFEARRAY, is this
3835 useful? */
3836
3837 pType++;
3838 pTD->vt = VT_SAFEARRAY;
3839 pTD->lptdesc = calloc(1, sizeof(TYPEDESC));
3840 pTD = pTD->lptdesc;
3841 break;
3842 }
3843 default:
3844 pTD->vt = *pType & 0x3f;
3845 done = TRUE;
3846 break;
3847 }
3848 pType++;
3849 }
3850 return pType;
3851}
3852
3853static WORD *SLTG_DoElem(WORD *pType, char *pBlk,
3854 ELEMDESC *pElem, const sltg_ref_lookup_t *ref_lookup)
3855{
3856 /* Handle [in/out] first */
3857 if((*pType & 0xc000) == 0xc000)
3858 pElem->paramdesc.wParamFlags = PARAMFLAG_NONE;
3859 else if(*pType & 0x8000)
3860 pElem->paramdesc.wParamFlags = PARAMFLAG_FIN | PARAMFLAG_FOUT;
3861 else if(*pType & 0x4000)
3862 pElem->paramdesc.wParamFlags = PARAMFLAG_FOUT;
3863 else
3864 pElem->paramdesc.wParamFlags = PARAMFLAG_FIN;
3865
3866 if(*pType & 0x2000)
3867 pElem->paramdesc.wParamFlags |= PARAMFLAG_FLCID;
3868
3869 if(*pType & 0x80)
3870 pElem->paramdesc.wParamFlags |= PARAMFLAG_FRETVAL;
3871
3872 return SLTG_DoType(pType, pBlk, &pElem->tdesc, ref_lookup);
3873}
3874
3875
3877 char *pNameTable)
3878{
3879 unsigned int ref;
3880 char *name;
3881 TLBRefType *ref_type;
3883 HREFTYPE typelib_ref;
3884
3885 if(pRef->magic != SLTG_REF_MAGIC) {
3886 FIXME("Ref magic = %x\n", pRef->magic);
3887 return NULL;
3888 }
3889 name = ( (char*)pRef->names + pRef->number);
3890
3891 table = malloc(sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0]));
3892 table->num = pRef->number >> 3;
3893
3894 /* FIXME should scan the existing list and reuse matching refs added by previous typeinfos */
3895
3896 /* We don't want the first href to be 0 */
3897 typelib_ref = (list_count(&pTL->ref_list) + 1) << 2;
3898
3899 for(ref = 0; ref < pRef->number >> 3; ref++) {
3900 char *refname;
3901 unsigned int lib_offs, type_num;
3902
3903 ref_type = calloc(1, sizeof(TLBRefType));
3904
3905 name += SLTG_ReadStringA(name, &refname);
3906 if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2)
3907 FIXME_(typelib)("Can't sscanf ref\n");
3908 if(lib_offs != 0xffff) {
3909 TLBImpLib *import;
3910
3912 if(import->offset == lib_offs)
3913 break;
3914
3915 if(&import->entry == &pTL->implib_list) {
3916 char fname[MAX_PATH+1];
3917 int len;
3918 GUID tmpguid;
3919
3920 import = calloc(1, sizeof(*import));
3921 import->offset = lib_offs;
3922 TLB_GUIDFromString( pNameTable + lib_offs + 4, &tmpguid);
3923 import->guid = TLB_append_guid(&pTL->guid_list, &tmpguid, 2);
3924 if(sscanf(pNameTable + lib_offs + 40, "}#%hd.%hd#%lx#%s",
3925 &import->wVersionMajor,
3926 &import->wVersionMinor,
3927 &import->lcid, fname) != 4) {
3928 FIXME_(typelib)("can't sscanf ref %s\n",
3929 pNameTable + lib_offs + 40);
3930 }
3931 len = strlen(fname);
3932 if(fname[len-1] != '#')
3933 FIXME("fname = %s\n", fname);
3934 fname[len-1] = '\0';
3935 import->name = TLB_MultiByteToBSTR(fname);
3936 list_add_tail(&pTL->implib_list, &import->entry);
3937 }
3938 ref_type->pImpTLInfo = import;
3939
3940 /* Store a reference to IDispatch */
3941 if(pTL->dispatch_href == -1 && IsEqualGUID(&import->guid->guid, &IID_StdOle) && type_num == 4)
3942 pTL->dispatch_href = typelib_ref;
3943
3944 } else { /* internal ref */
3945 ref_type->pImpTLInfo = TLB_REF_INTERNAL;
3946 }
3947 ref_type->reference = typelib_ref;
3948 ref_type->index = type_num;
3949
3950 free(refname);
3951 list_add_tail(&pTL->ref_list, &ref_type->entry);
3952
3953 table->refs[ref] = typelib_ref;
3954 typelib_ref += 4;
3955 }
3956 if((BYTE)*name != SLTG_REF_MAGIC)
3957 FIXME_(typelib)("End of ref block magic = %x\n", *name);
3958 dump_TLBRefType(pTL);
3959 return table;
3960}
3961
3962static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
3963 BOOL OneOnly, const sltg_ref_lookup_t *ref_lookup)
3964{
3966 TLBImplType *pImplType;
3967 /* I don't really get this structure, usually it's 0x16 bytes
3968 long, but iuser.tlb contains some that are 0x18 bytes long.
3969 That's ok because we can use the next ptr to jump to the next
3970 one. But how do we know the length of the last one? The WORD
3971 at offs 0x8 might be the clue. For now I'm just assuming that
3972 the last one is the regular 0x16 bytes. */
3973
3974 info = (SLTG_ImplInfo*)pBlk;
3975 while(1){
3976 pTI->typeattr.cImplTypes++;
3977 if(info->next == 0xffff)
3978 break;
3979 info = (SLTG_ImplInfo*)(pBlk + info->next);
3980 }
3981
3982 info = (SLTG_ImplInfo*)pBlk;
3983 pTI->impltypes = TLBImplType_Alloc(pTI->typeattr.cImplTypes);
3984 pImplType = pTI->impltypes;
3985 while(1) {
3986 sltg_get_typelib_ref(ref_lookup, info->ref, &pImplType->hRef);
3987 pImplType->implflags = info->impltypeflags;
3988 ++pImplType;
3989
3990 if(info->next == 0xffff)
3991 break;
3992 if(OneOnly)
3993 FIXME_(typelib)("Interface inheriting more than one interface\n");
3994 info = (SLTG_ImplInfo*)(pBlk + info->next);
3995 }
3996 info++; /* see comment at top of function */
3997 return (char*)info;
3998}
3999
4000static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars,
4001 const char *pNameTable, const sltg_ref_lookup_t *ref_lookup)
4002{
4003 TLBVarDesc *pVarDesc;
4004 const TLBString *prevName = NULL;
4005 SLTG_Variable *pItem;
4006 unsigned short i;
4007 WORD *pType;
4008
4009 pVarDesc = pTI->vardescs = TLBVarDesc_Alloc(cVars);
4010
4011 for(pItem = (SLTG_Variable *)pFirstItem, i = 0; i < cVars;
4012 pItem = (SLTG_Variable *)(pBlk + pItem->next), i++, ++pVarDesc) {
4013
4014 pVarDesc->vardesc.memid = pItem->memid;
4015
4016 if (pItem->magic != SLTG_VAR_MAGIC &&
4017 pItem->magic != SLTG_VAR_WITH_FLAGS_MAGIC) {
4018 FIXME_(typelib)("var magic = %02x\n", pItem->magic);
4019 return;
4020 }
4021
4022 if (pItem->name == 0xfffe)
4023 pVarDesc->Name = prevName;
4024 else
4025 pVarDesc->Name = SLTG_ReadName(pNameTable, pItem->name, pTI->pTypeLib);
4026
4027 TRACE_(typelib)("name: %s\n", debugstr_w(TLB_get_bstr(pVarDesc->Name)));
4028 TRACE_(typelib)("byte_offs = 0x%x\n", pItem->byte_offs);
4029 TRACE_(typelib)("memid = %#lx\n", pItem->memid);
4030
4031 if(pItem->flags & 0x02)
4032 pType = &pItem->type;
4033 else
4034 pType = (WORD*)(pBlk + pItem->type);
4035
4036 if (pItem->flags & ~0xda)
4037 FIXME_(typelib)("unhandled flags = %02x\n", pItem->flags & ~0xda);
4038
4039 SLTG_DoElem(pType, pBlk,
4040 &pVarDesc->vardesc.elemdescVar, ref_lookup);
4041
4042 if (TRACE_ON(typelib)) {
4043 char buf[300];
4044 dump_TypeDesc(&pVarDesc->vardesc.elemdescVar.tdesc, buf);
4045 TRACE_(typelib)("elemdescVar: %s\n", buf);
4046 }
4047
4048 if (pItem->flags & 0x40) {
4049 TRACE_(typelib)("VAR_DISPATCH\n");
4050 pVarDesc->vardesc.varkind = VAR_DISPATCH;
4051 }
4052 else if (pItem->flags & 0x10) {
4053 TRACE_(typelib)("VAR_CONST\n");
4054 pVarDesc->vardesc.varkind = VAR_CONST;
4055 pVarDesc->vardesc.lpvarValue = malloc(sizeof(VARIANT));
4056 V_VT(pVarDesc->vardesc.lpvarValue) = VT_INT;
4057 if (pItem->flags & 0x08)
4058 V_INT(pVarDesc->vardesc.lpvarValue) = pItem->byte_offs;
4059 else {
4060 switch (pVarDesc->vardesc.elemdescVar.tdesc.vt)
4061 {
4062 case VT_LPSTR:
4063 case VT_LPWSTR:
4064 case VT_BSTR:
4065 {
4066 WORD len = *(WORD *)(pBlk + pItem->byte_offs);
4067 BSTR str;
4068 TRACE_(typelib)("len = %u\n", len);
4069 if (len == 0xffff) {
4070 str = NULL;
4071 } else {
4072 INT alloc_len = MultiByteToWideChar(CP_ACP, 0, pBlk + pItem->byte_offs + 2, len, NULL, 0);
4073 str = SysAllocStringLen(NULL, alloc_len);
4074 MultiByteToWideChar(CP_ACP, 0, pBlk + pItem->byte_offs + 2, len, str, alloc_len);
4075 }
4076 V_VT(pVarDesc->vardesc.lpvarValue) = VT_BSTR;
4077 V_BSTR(pVarDesc->vardesc.lpvarValue) = str;
4078 break;
4079 }
4080 case VT_I2:
4081 case VT_UI2:
4082 case VT_I4:
4083 case VT_UI4:
4084 case VT_INT:
4085 case VT_UINT:
4086 V_INT(pVarDesc->vardesc.lpvarValue) =
4087 *(INT*)(pBlk + pItem->byte_offs);
4088 break;
4089 default:
4090 FIXME_(typelib)("VAR_CONST unimplemented for type %d\n", pVarDesc->vardesc.elemdescVar.tdesc.vt);
4091 }
4092 }
4093 }
4094 else {
4095 TRACE_(typelib)("VAR_PERINSTANCE\n");
4096 pVarDesc->vardesc.oInst = pItem->byte_offs;
4097 pVarDesc->vardesc.varkind = VAR_PERINSTANCE;
4098 }
4099
4100 if (pItem->magic == SLTG_VAR_WITH_FLAGS_MAGIC)
4101 pVarDesc->vardesc.wVarFlags = pItem->varflags;
4102
4103 if (pItem->flags & 0x80)
4104 pVarDesc->vardesc.wVarFlags |= VARFLAG_FREADONLY;
4105
4106 prevName = pVarDesc->Name;
4107 }
4108 pTI->typeattr.cVars = cVars;
4109}
4110
4111static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
4112 unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup)
4113{
4114 SLTG_Function *pFunc;
4115 unsigned short i;
4116 TLBFuncDesc *pFuncDesc;
4117
4118 pTI->funcdescs = TLBFuncDesc_Alloc(cFuncs);
4119
4120 pFuncDesc = pTI->funcdescs;
4121 for(pFunc = (SLTG_Function*)pFirstItem, i = 0; i < cFuncs && pFunc != (SLTG_Function*)0xFFFF;
4122 pFunc = (SLTG_Function*)(pBlk + pFunc->next), i++, ++pFuncDesc) {
4123
4124 int param;
4125 WORD *pType, *pArg;
4126
4127 switch (pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT) {
4129 pFuncDesc->funcdesc.funckind = FUNC_PUREVIRTUAL;
4130 break;
4132 pFuncDesc->funcdesc.funckind = FUNC_DISPATCH;
4133 break;
4135 pFuncDesc->funcdesc.funckind = FUNC_STATIC;
4136 break;
4137 default:
4138 FIXME("unimplemented func magic = %02x\n", pFunc->magic & ~SLTG_FUNCTION_FLAGS_PRESENT);
4139 continue;
4140 }
4141 pFuncDesc->Name = SLTG_ReadName(pNameTable, pFunc->name, pTI->pTypeLib);
4142
4143 pFuncDesc->funcdesc.memid = pFunc->dispid;
4144 pFuncDesc->funcdesc.invkind = pFunc->inv >> 4;
4145 pFuncDesc->funcdesc.callconv = pFunc->nacc & 0x7;
4146 pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3;
4147 pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
4148 if (pFuncDesc->funcdesc.funckind == FUNC_DISPATCH)
4149 pFuncDesc->funcdesc.oVft = 0;
4150 else
4151 pFuncDesc->funcdesc.oVft = (unsigned short)(pFunc->vtblpos & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
4152
4154 pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;
4155
4156 if(pFunc->retnextopt & 0x80)
4157 pType = &pFunc->rettype;
4158 else
4159 pType = (WORD*)(pBlk + pFunc->rettype);
4160
4161 SLTG_DoElem(pType, pBlk, &pFuncDesc->funcdesc.elemdescFunc, ref_lookup);
4162
4163 pFuncDesc->funcdesc.lprgelemdescParam =
4164 calloc(pFuncDesc->funcdesc.cParams, sizeof(ELEMDESC));
4165 pFuncDesc->pParamDesc = TLBParDesc_Constructor(pFuncDesc->funcdesc.cParams);
4166
4167 pArg = (WORD*)(pBlk + pFunc->arg_off);
4168
4169 for(param = 0; param < pFuncDesc->funcdesc.cParams; param++) {
4170 char *paramName = pNameTable + *pArg;
4171 BOOL HaveOffs;
4172 /* If arg type follows then paramName points to the 2nd
4173 letter of the name, else the next WORD is an offset to
4174 the arg type and paramName points to the first letter.
4175 So let's take one char off paramName and see if we're
4176 pointing at an alphanumeric char. However if *pArg is
4177 0xffff or 0xfffe then the param has no name, the former
4178 meaning that the next WORD is the type, the latter
4179 meaning that the next WORD is an offset to the type. */
4180
4181 HaveOffs = FALSE;
4182 if(*pArg == 0xffff)
4183 paramName = NULL;
4184 else if(*pArg == 0xfffe) {
4185 paramName = NULL;
4186 HaveOffs = TRUE;
4187 }
4188 else if(paramName[-1] && !isalnum(paramName[-1]))
4189 HaveOffs = TRUE;
4190
4191 pArg++;
4192
4193 if(HaveOffs) { /* the next word is an offset to type */
4194 pType = (WORD*)(pBlk + *pArg);
4195 SLTG_DoElem(pType, pBlk,
4196 &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
4197 pArg++;
4198 } else {
4199 if(paramName)
4200 paramName--;
4201 pArg = SLTG_DoElem(pArg, pBlk,
4202 &pFuncDesc->funcdesc.lprgelemdescParam[param], ref_lookup);
4203 }
4204
4205 /* Are we an optional param ? */
4206 if(pFuncDesc->funcdesc.cParams - param <=
4207 pFuncDesc->funcdesc.cParamsOpt)
4208 pFuncDesc->funcdesc.lprgelemdescParam[param].paramdesc.wParamFlags |= PARAMFLAG_FOPT;
4209
4210 if(paramName) {
4211 pFuncDesc->pParamDesc[param].Name = SLTG_ReadName(pNameTable,
4212 paramName - pNameTable, pTI->pTypeLib);
4213 } else {
4214 pFuncDesc->pParamDesc[param].Name = pFuncDesc->Name;
4215 }
4216 }
4217 }
4218 pTI->typeattr.cFuncs = cFuncs;
4219}
4220
4221static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
4222 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4223 SLTG_TypeInfoTail *pTITail)
4224{
4225 char *pFirstItem;
4226 sltg_ref_lookup_t *ref_lookup = NULL;
4227
4228 if(pTIHeader->href_table != 0xffffffff) {
4229 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4230 pNameTable);
4231 }
4232
4233 pFirstItem = pBlk;
4234
4235 if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
4236 SLTG_DoImpls(pFirstItem, pTI, FALSE, ref_lookup);
4237 }
4238 free(ref_lookup);
4239}
4240
4241
4242static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
4243 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4244 const SLTG_TypeInfoTail *pTITail)
4245{
4246 char *pFirstItem;
4247 sltg_ref_lookup_t *ref_lookup = NULL;
4248
4249 if(pTIHeader->href_table != 0xffffffff) {
4250 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4251 pNameTable);
4252 }
4253
4254 pFirstItem = pBlk;
4255
4256 if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
4257 SLTG_DoImpls(pFirstItem, pTI, TRUE, ref_lookup);
4258 }
4259
4260 if (pTITail->funcs_off != 0xffff)
4261 SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
4262
4263 free(ref_lookup);
4264
4265 if (TRACE_ON(typelib))
4266 dump_TLBFuncDesc(pTI->funcdescs, pTI->typeattr.cFuncs);
4267}
4268
4269static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
4270 const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4271 const SLTG_TypeInfoTail *pTITail)
4272{
4273 SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL);
4274}
4275
4276static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
4277 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4278 const SLTG_TypeInfoTail *pTITail)
4279{
4280 WORD *pType;
4281 sltg_ref_lookup_t *ref_lookup = NULL;
4282
4283 if (pTITail->simple_alias) {
4284 /* if simple alias, no more processing required */
4285 pTI->tdescAlias = calloc(1, sizeof(TYPEDESC));
4286 pTI->tdescAlias->vt = pTITail->tdescalias_vt;
4287 return;
4288 }
4289
4290 if(pTIHeader->href_table != 0xffffffff) {
4291 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4292 pNameTable);
4293 }
4294
4295 /* otherwise it is an offset to a type */
4296 pType = (WORD *)(pBlk + pTITail->tdescalias_vt);
4297
4298 pTI->tdescAlias = malloc(sizeof(TYPEDESC));
4299 SLTG_DoType(pType, pBlk, pTI->tdescAlias, ref_lookup);
4300
4301 free(ref_lookup);
4302}
4303
4304static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
4305 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4306 const SLTG_TypeInfoTail *pTITail)
4307{
4308 sltg_ref_lookup_t *ref_lookup = NULL;
4309 if (pTIHeader->href_table != 0xffffffff)
4310 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4311 pNameTable);
4312
4313 if (pTITail->vars_off != 0xffff)
4314 SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup);
4315
4316 if (pTITail->funcs_off != 0xffff)
4317 SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
4318
4319 if (pTITail->impls_off != 0xffff)
4320 SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);
4321
4322 /* this is necessary to cope with MSFT typelibs that set cFuncs to the number
4323 * of dispinterface functions including the IDispatch ones, so
4324 * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
4325 pTI->typeattr.cbSizeVft = pTI->typeattr.cFuncs * pTI->pTypeLib->ptr_size;
4326
4327 free(ref_lookup);
4328 if (TRACE_ON(typelib))
4329 dump_TLBFuncDesc(pTI->funcdescs, pTI->typeattr.cFuncs);
4330}
4331
4332static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
4333 const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4334 const SLTG_TypeInfoTail *pTITail)
4335{
4336 SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL);
4337}
4338
4339static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
4340 char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
4341 const SLTG_TypeInfoTail *pTITail)
4342{
4343 sltg_ref_lookup_t *ref_lookup = NULL;
4344 if (pTIHeader->href_table != 0xffffffff)
4345 ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
4346 pNameTable);
4347
4348 if (pTITail->vars_off != 0xffff)
4349 SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup);
4350
4351 if (pTITail->funcs_off != 0xffff)
4352 SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
4353 free(ref_lookup);
4354 if (TRACE_ON(typelib))
4355 dump_TypeInfo(pTI);
4356}
4357
4358/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
4359 manageable copy of it into this */
4360typedef struct {
4367 char *extra;
4373
4374/****************************************************************************
4375 * ITypeLib2_Constructor_SLTG
4376 *
4377 * loading a SLTG typelib from an in-memory image
4378 */
4380{
4381 ITypeLibImpl *pTypeLibImpl;
4383 SLTG_BlkEntry *pBlkEntry;
4384 SLTG_Magic *pMagic;
4386 SLTG_Pad9 *pPad9;
4387 LPVOID pBlk, pFirstBlk;
4388 SLTG_LibBlk *pLibBlk;
4389 SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks;
4390 char *pAfterOTIBlks = NULL;
4391 char *pNameTable, *ptr;
4392 int i;
4393 DWORD len, order;
4394 ITypeInfoImpl **ppTypeInfoImpl;
4395
4396 TRACE_(typelib)("%p, TLB length = %ld\n", pLib, dwTLBLength);
4397
4398
4399 pTypeLibImpl = TypeLibImpl_Constructor();
4400 if (!pTypeLibImpl) return NULL;
4401
4402 pHeader = pLib;
4403
4404 TRACE_(typelib)("header:\n");
4405 TRACE_(typelib)("\tmagic %#lx, file blocks = %d\n", pHeader->SLTG_magic,
4406 pHeader->nrOfFileBlks );
4407 if (pHeader->SLTG_magic != SLTG_SIGNATURE)
4408 {
4409 FIXME_(typelib)("Header type magic %#lx not supported.\n", pHeader->SLTG_magic);
4410 return NULL;
4411 }
4412
4413 /* There are pHeader->nrOfFileBlks - 2 TypeInfo records in this typelib */
4414 pTypeLibImpl->TypeInfoCount = pHeader->nrOfFileBlks - 2;
4415
4416 /* This points to pHeader->nrOfFileBlks - 1 of SLTG_BlkEntry */
4417 pBlkEntry = (SLTG_BlkEntry*)(pHeader + 1);
4418
4419 /* Next we have a magic block */
4420 pMagic = (SLTG_Magic*)(pBlkEntry + pHeader->nrOfFileBlks - 1);
4421
4422 /* Let's see if we're still in sync */
4424 sizeof(SLTG_COMPOBJ_MAGIC))) {
4425 FIXME_(typelib)("CompObj magic = %s\n", pMagic->CompObj_magic);
4426 return NULL;
4427 }
4428 if(memcmp(pMagic->dir_magic, SLTG_DIR_MAGIC,
4429 sizeof(SLTG_DIR_MAGIC))) {
4430 FIXME_(typelib)("dir magic = %s\n", pMagic->dir_magic);
4431 return NULL;
4432 }
4433
4434 pIndex = (SLTG_Index*)(pMagic+1);
4435
4436 pPad9 = (SLTG_Pad9*)(pIndex + pTypeLibImpl->TypeInfoCount);
4437
4438 pFirstBlk = pPad9 + 1;
4439
4440 /* We'll set up a ptr to the main library block, which is the last one. */
4441
4442 for(pBlk = pFirstBlk, order = pHeader->first_blk - 1;
4443 pBlkEntry[order].next != 0;
4444 order = pBlkEntry[order].next - 1) {
4445 pBlk = (char*)pBlk + pBlkEntry[order].len;
4446 }
4447 pLibBlk = pBlk;
4448
4449 len = SLTG_ReadLibBlk(pLibBlk, pTypeLibImpl);
4450
4451 /* Now there are 0x40 bytes of 0xffff with the numbers 0 to TypeInfoCount
4452 interspersed */
4453
4454 len += 0x40;
4455
4456 /* And now TypeInfoCount of SLTG_OtherTypeInfo */
4457
4458 pOtherTypeInfoBlks = calloc(pTypeLibImpl->TypeInfoCount, sizeof(*pOtherTypeInfoBlks));
4459
4460
4461 ptr = (char*)pLibBlk + len;
4462
4463 for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) {
4464 WORD w, extra;
4465 len = 0;
4466
4467 pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr;
4468
4469 w = *(WORD*)(ptr + 2);
4470 if(w != 0xffff) {
4471 len += w;
4472 pOtherTypeInfoBlks[i].index_name = malloc(w + 1);
4473 memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w);
4474 pOtherTypeInfoBlks[i].index_name[w] = '\0';
4475 }
4476 w = *(WORD*)(ptr + 4 + len);
4477 if(w != 0xffff) {
4478 TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w));
4479 len += w;
4480 pOtherTypeInfoBlks[i].other_name = malloc(w + 1);
4481 memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w);
4482 pOtherTypeInfoBlks[i].other_name[w] = '\0';
4483 }
4484 pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6);
4485 pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8);
4486 extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len);
4487 if(extra) {
4488 pOtherTypeInfoBlks[i].extra = malloc(extra);
4489 memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra);
4490 len += extra;
4491 }
4492 pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len);
4493 pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len);
4494 pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len);
4495 memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID));
4496 len += sizeof(SLTG_OtherTypeInfo);
4497 ptr += len;
4498 }
4499
4500 pAfterOTIBlks = ptr;
4501
4502 /* Skip this WORD and get the next DWORD */
4503 len = *(DWORD*)(pAfterOTIBlks + 2);
4504
4505 /* Now add this to pLibBLk look at what we're pointing at and
4506 possibly add 0x20, then add 0x216, sprinkle a bit a magic
4507 dust and we should be pointing at the beginning of the name
4508 table */
4509
4510 pNameTable = (char*)pLibBlk + len;
4511
4512 switch(*(WORD*)pNameTable) {
4513 case 0xffff:
4514 break;
4515 case 0x0200:
4516 pNameTable += 0x20;
4517 break;
4518 default:
4519 FIXME_(typelib)("pNameTable jump = %x\n", *(WORD*)pNameTable);
4520 break;
4521 }
4522
4523 pNameTable += 0x216;
4524
4525 pNameTable += 2;
4526
4527 TRACE_(typelib)("Library name is %s\n", pNameTable + pLibBlk->name);
4528
4529 pTypeLibImpl->Name = SLTG_ReadName(pNameTable, pLibBlk->name, pTypeLibImpl);
4530
4531
4532 /* Hopefully we now have enough ptrs set up to actually read in
4533 some TypeInfos. It's not clear which order to do them in, so
4534 I'll just follow the links along the BlkEntry chain and read
4535 them in the order in which they are in the file */
4536
4537 pTypeLibImpl->typeinfos = calloc(pTypeLibImpl->TypeInfoCount, sizeof(ITypeInfoImpl*));
4538 ppTypeInfoImpl = pTypeLibImpl->typeinfos;
4539
4540 for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0;
4541 pBlkEntry[order].next != 0;
4542 order = pBlkEntry[order].next - 1, i++) {
4543
4544 SLTG_TypeInfoHeader *pTIHeader;
4545 SLTG_TypeInfoTail *pTITail;
4546 SLTG_MemberHeader *pMemHeader;
4547
4548 if(strcmp(pBlkEntry[order].index_string + (char*)pMagic, pOtherTypeInfoBlks[i].index_name)) {
4549 FIXME_(typelib)("Index strings don't match\n");
4550 free(pOtherTypeInfoBlks);
4551 return NULL;
4552 }
4553
4554 pTIHeader = pBlk;
4555 if(pTIHeader->magic != SLTG_TIHEADER_MAGIC) {
4556 FIXME_(typelib)("TypeInfoHeader magic = %04x\n", pTIHeader->magic);
4557 free(pOtherTypeInfoBlks);
4558 return NULL;
4559 }
4560 TRACE_(typelib)("pTIHeader->res06 = %lx, pTIHeader->res0e = %lx, "
4561 "pTIHeader->res16 = %lx, pTIHeader->res1e = %lx\n",
4562 pTIHeader->res06, pTIHeader->res0e, pTIHeader->res16, pTIHeader->res1e);
4563
4564 *ppTypeInfoImpl = ITypeInfoImpl_Constructor();
4565 (*ppTypeInfoImpl)->pTypeLib = pTypeLibImpl;
4566 (*ppTypeInfoImpl)->index = i;
4567 (*ppTypeInfoImpl)->Name = SLTG_ReadName(pNameTable, pOtherTypeInfoBlks[i].name_offs, pTypeLibImpl);
4568 (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext;
4569 (*ppTypeInfoImpl)->guid = TLB_append_guid(&pTypeLibImpl->guid_list, &pOtherTypeInfoBlks[i].uuid, 2);
4570 (*ppTypeInfoImpl)->typeattr.typekind = pTIHeader->typekind;
4571 (*ppTypeInfoImpl)->typeattr.wMajorVerNum = pTIHeader->major_version;
4572 (*ppTypeInfoImpl)->typeattr.wMinorVerNum = pTIHeader->minor_version;
4573 (*ppTypeInfoImpl)->typeattr.wTypeFlags =
4574 (pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5);
4575
4576 if((*ppTypeInfoImpl)->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
4577 (*ppTypeInfoImpl)->typeattr.typekind = TKIND_DISPATCH;
4578
4579 if((pTIHeader->typeflags1 & 7) != 2)
4580 FIXME_(typelib)("typeflags1 = %02x\n", pTIHeader->typeflags1);
4581 if(pTIHeader->typeflags3 != 2)
4582 FIXME_(typelib)("typeflags3 = %02x\n", pTIHeader->typeflags3);
4583
4584 TRACE_(typelib)("TypeInfo %s of kind %s guid %s typeflags %04x\n",
4585 debugstr_w(TLB_get_bstr((*ppTypeInfoImpl)->Name)),
4586 typekind_desc[pTIHeader->typekind],
4587 debugstr_guid(TLB_get_guidref((*ppTypeInfoImpl)->guid)),
4588 (*ppTypeInfoImpl)->typeattr.wTypeFlags);
4589
4590 pMemHeader = (SLTG_MemberHeader*)((char *)pBlk + pTIHeader->elem_table);
4591
4592 pTITail = (SLTG_TypeInfoTail*)((char *)(pMemHeader + 1) + pMemHeader->cbExtra);
4593
4594 (*ppTypeInfoImpl)->typeattr.cbAlignment = pTITail->cbAlignment;
4595 (*ppTypeInfoImpl)->typeattr.cbSizeInstance = pTITail->cbSizeInstance;
4596 (*ppTypeInfoImpl)->typeattr.cbSizeVft = pTITail->cbSizeVft;
4597
4598 switch(pTIHeader->typekind) {
4599 case TKIND_ENUM:
4600 SLTG_ProcessEnum((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4601 pTIHeader, pTITail);
4602 break;
4603
4604 case TKIND_RECORD:
4605 SLTG_ProcessRecord((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4606 pTIHeader, pTITail);
4607 break;
4608
4609 case TKIND_INTERFACE:
4610 SLTG_ProcessInterface((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4611 pTIHeader, pTITail);
4612 break;
4613
4614 case TKIND_COCLASS:
4615 SLTG_ProcessCoClass((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4616 pTIHeader, pTITail);
4617 break;
4618
4619 case TKIND_ALIAS:
4620 SLTG_ProcessAlias((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4621 pTIHeader, pTITail);
4622 break;
4623
4624 case TKIND_DISPATCH:
4625 SLTG_ProcessDispatch((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4626 pTIHeader, pTITail);
4627 break;
4628
4629 case TKIND_MODULE:
4630 SLTG_ProcessModule((char *)(pMemHeader + 1), *ppTypeInfoImpl, pNameTable,
4631 pTIHeader, pTITail);
4632 break;
4633
4634 default:
4635 FIXME("Not processing typekind %d\n", pTIHeader->typekind);
4636 break;
4637
4638 }
4639
4640 /* could get cFuncs, cVars and cImplTypes from here
4641 but we've already set those */
4642#define X(x) TRACE_(typelib)("tt "#x": %x\n",pTITail->res##x);
4643 X(06);
4644 X(16);
4645 X(18);
4646 X(1a);
4647 X(1e);
4648 X(24);
4649 X(26);
4650 X(2a);
4651 X(2c);
4652 X(2e);
4653 X(30);
4654 X(32);
4655 X(34);
4656#undef X
4657 ++ppTypeInfoImpl;
4658 pBlk = (char*)pBlk + pBlkEntry[order].len;
4659 }
4660
4661 if(i != pTypeLibImpl->TypeInfoCount) {
4662 FIXME("Somehow processed %d TypeInfos\n", i);
4663 free(pOtherTypeInfoBlks);
4664 return NULL;
4665 }
4666
4667 free(pOtherTypeInfoBlks);
4668 return &pTypeLibImpl->ITypeLib2_iface;
4669}
4670
4672{
4674
4675 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
4676
4678 IsEqualIID(riid,&IID_ITypeLib)||
4679 IsEqualIID(riid,&IID_ITypeLib2))
4680 {
4681 *ppv = &This->ITypeLib2_iface;
4682 }
4683 else if(IsEqualIID(riid, &IID_ICreateTypeLib) ||
4684 IsEqualIID(riid, &IID_ICreateTypeLib2))
4685 {
4686 *ppv = &This->ICreateTypeLib2_iface;
4687 }
4688 else
4689 {
4690 *ppv = NULL;
4691 TRACE("-- Interface: E_NOINTERFACE\n");
4692 return E_NOINTERFACE;
4693 }
4694
4695 IUnknown_AddRef((IUnknown*)*ppv);
4696 return S_OK;
4697}
4698
4700{
4703
4704 TRACE("%p, refcount %lu.\n", iface, ref);
4705
4706 return ref;
4707}
4708
4710{
4712 ULONG ref;
4713
4715 ref = InterlockedDecrement(&This->ref);
4716
4717 TRACE("%p, refcount %lu.\n", iface, ref);
4718
4719 if (!ref)
4720 {
4721 TLBImpLib *pImpLib, *pImpLibNext;
4722 TLBRefType *ref_type, *ref_type_next;
4723 TLBString *tlbstr, *tlbstr_next;
4724 TLBGuid *tlbguid, *tlbguid_next;
4725 int i;
4726
4727 /* remove cache entry */
4728 if(This->path)
4729 {
4730 TRACE("removing from cache list\n");
4731 if(This->entry.next)
4732 list_remove(&This->entry);
4733 free(This->path);
4734 }
4735 TRACE(" destroying ITypeLib(%p)\n",This);
4736
4737 LIST_FOR_EACH_ENTRY_SAFE(tlbstr, tlbstr_next, &This->string_list, TLBString, entry) {
4738 list_remove(&tlbstr->entry);
4739 SysFreeString(tlbstr->str);
4740 free(tlbstr);
4741 }
4742
4743 LIST_FOR_EACH_ENTRY_SAFE(tlbstr, tlbstr_next, &This->name_list, TLBString, entry) {
4744 list_remove(&tlbstr->entry);
4745 SysFreeString(tlbstr->str);
4746 free(tlbstr);
4747 }
4748
4749 LIST_FOR_EACH_ENTRY_SAFE(tlbguid, tlbguid_next, &This->guid_list, TLBGuid, entry) {
4750 list_remove(&tlbguid->entry);
4751 free(tlbguid);
4752 }
4753
4754 TLB_FreeCustData(&This->custdata_list);
4755
4756 for (i = 0; i < This->ctTypeDesc; i++)
4757 if (This->pTypeDesc[i].vt == VT_CARRAY)
4758 free(This->pTypeDesc[i].lpadesc);
4759
4760 free(This->pTypeDesc);
4761
4762 LIST_FOR_EACH_ENTRY_SAFE(pImpLib, pImpLibNext, &This->implib_list, TLBImpLib, entry)
4763 {
4764 if (pImpLib->pImpTypeLib)
4765 ITypeLib2_Release(&pImpLib->pImpTypeLib->ITypeLib2_iface);
4766 SysFreeString(pImpLib->name);
4767
4768 list_remove(&pImpLib->entry);
4769 free(pImpLib);
4770 }
4771
4772 LIST_FOR_EACH_ENTRY_SAFE(ref_type, ref_type_next, &This->ref_list, TLBRefType, entry)
4773 {
4774 list_remove(&ref_type->entry);
4775 free(ref_type);
4776 }
4777
4778 for (i = 0; i < This->TypeInfoCount; ++i){
4779 free(This->typeinfos[i]->tdescAlias);
4780 ITypeInfoImpl_Destroy(This->typeinfos[i]);
4781 }
4782 free(This->typeinfos);
4783 free(This);
4784 }
4785
4787 return ref;
4788}
4789
4790/* ITypeLib::GetTypeInfoCount
4791 *
4792 * Returns the number of type descriptions in the type library
4793 */
4795{
4797 TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
4798 return This->TypeInfoCount;
4799}
4800
4801/* ITypeLib::GetTypeInfo
4802 *
4803 * retrieves the specified type description in the library.
4804 */
4806 ITypeLib2 *iface,
4807 UINT index,
4808 ITypeInfo **ppTInfo)
4809{
4811
4812 TRACE("%p %u %p\n", This, index, ppTInfo);
4813
4814 if(!ppTInfo)
4815 return E_INVALIDARG;
4816
4817 if(index >= This->TypeInfoCount)
4819
4820 *ppTInfo = (ITypeInfo *)&This->typeinfos[index]->ITypeInfo2_iface;
4821 ITypeInfo_AddRef(*ppTInfo);
4822
4823 return S_OK;
4824}
4825
4826
4827/* ITypeLibs::GetTypeInfoType
4828 *
4829 * Retrieves the type of a type description.
4830 */
4832 ITypeLib2 *iface,
4833 UINT index,
4834 TYPEKIND *pTKind)
4835{
4837
4838 TRACE("(%p, %d, %p)\n", This, index, pTKind);
4839
4840 if(!pTKind)
4841 return E_INVALIDARG;
4842
4843 if(index >= This->TypeInfoCount)
4845
4846 *pTKind = This->typeinfos[index]->typeattr.typekind;
4847
4848 return S_OK;
4849}
4850
4851/* ITypeLib::GetTypeInfoOfGuid
4852 *
4853 * Retrieves the type description that corresponds to the specified GUID.
4854 *
4855 */
4857 ITypeLib2 *iface,
4858 REFGUID guid,
4859 ITypeInfo **ppTInfo)
4860{
4862 int i;
4863
4864 TRACE("%p %s %p\n", This, debugstr_guid(guid), ppTInfo);
4865
4866 for(i = 0; i < This->TypeInfoCount; ++i){
4867 if(IsEqualIID(TLB_get_guid_null(This->typeinfos[i]->guid), guid)){
4868 *ppTInfo = (ITypeInfo *)&This->typeinfos[i]->ITypeInfo2_iface;
4869 ITypeInfo_AddRef(*ppTInfo);
4870 return S_OK;
4871 }
4872 }
4873
4875}
4876
4877/* ITypeLib::GetLibAttr
4878 *
4879 * Retrieves the structure that contains the library's attributes.
4880 *
4881 */
4883 ITypeLib2 *iface,
4884 LPTLIBATTR *attr)
4885{
4887
4888 TRACE("(%p, %p)\n", This, attr);
4889
4890 if (!attr) return E_INVALIDARG;
4891
4892 *attr = malloc(sizeof(**attr));
4893 if (!*attr) return E_OUTOFMEMORY;
4894
4895 (*attr)->guid = *TLB_get_guid_null(This->guid);
4896 (*attr)->lcid = This->set_lcid;
4897 (*attr)->syskind = This->syskind;
4898 (*attr)->wMajorVerNum = This->ver_major;
4899 (*attr)->wMinorVerNum = This->ver_minor;
4900 (*attr)->wLibFlags = This->libflags;
4901
4902 return S_OK;
4903}
4904
4905/* ITypeLib::GetTypeComp
4906 *
4907 * Enables a client compiler to bind to a library's types, variables,
4908 * constants, and global functions.
4909 *
4910 */
4912 ITypeLib2 *iface,
4913 ITypeComp **ppTComp)
4914{
4916
4917 TRACE("(%p)->(%p)\n",This,ppTComp);
4918 *ppTComp = &This->ITypeComp_iface;
4919 ITypeComp_AddRef(*ppTComp);
4920
4921 return S_OK;
4922}
4923
4924/* ITypeLib::GetDocumentation
4925 *
4926 * Retrieves the library's documentation string, the complete Help file name
4927 * and path, and the context identifier for the library Help topic in the Help
4928 * file.
4929 *
4930 * On a successful return all non-null BSTR pointers will have been set,
4931 * possibly to NULL.
4932 */
4934 ITypeLib2 *iface,
4935 INT index,
4936 BSTR *pBstrName,
4937 BSTR *pBstrDocString,
4938 DWORD *pdwHelpContext,
4939 BSTR *pBstrHelpFile)
4940{
4943 ITypeInfo *pTInfo;
4944
4945 TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n",
4946 This, index,
4947 pBstrName, pBstrDocString,
4948 pdwHelpContext, pBstrHelpFile);
4949
4950 if(index<0)
4951 {
4952 /* documentation for the typelib */
4953 if(pBstrName)
4954 {
4955 if (This->Name)
4956 {
4957 if(!(*pBstrName = SysAllocString(TLB_get_bstr(This->Name))))
4958 goto memerr1;
4959 }
4960 else
4961 *pBstrName = NULL;
4962 }
4963 if(pBstrDocString)
4964 {
4965 if (This->DocString)
4966 {
4967 if(!(*pBstrDocString = SysAllocString(TLB_get_bstr(This->DocString))))
4968 goto memerr2;
4969 }
4970 else
4971 *pBstrDocString = NULL;
4972 }
4973 if(pdwHelpContext)
4974 {
4975 *pdwHelpContext = This->dwHelpContext;
4976 }
4977 if(pBstrHelpFile)
4978 {
4979 if (This->HelpFile)
4980 {
4981 if(!(*pBstrHelpFile = SysAllocString(TLB_get_bstr(This->HelpFile))))
4982 goto memerr3;
4983 }
4984 else
4985 *pBstrHelpFile = NULL;
4986 }
4987
4988 result = S_OK;
4989 }
4990 else
4991 {
4992 /* for a typeinfo */
4993 result = ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
4994
4995 if(SUCCEEDED(result))
4996 {
4997 result = ITypeInfo_GetDocumentation(pTInfo,
4999 pBstrName,
5000 pBstrDocString,
5001 pdwHelpContext, pBstrHelpFile);
5002
5003 ITypeInfo_Release(pTInfo);
5004 }
5005 }
5006 return result;
5007memerr3:
5008 if (pBstrDocString) SysFreeString (*pBstrDocString);
5009memerr2:
5010 if (pBstrName) SysFreeString (*pBstrName);
5011memerr1:
5013}
5014
5015/* ITypeLib::IsName
5016 *
5017 * Indicates whether a passed-in string contains the name of a type or member
5018 * described in the library.
5019 *
5020 */
5022 ITypeLib2 *iface,
5023 LPOLESTR szNameBuf,
5024 ULONG lHashVal,
5025 BOOL *pfName)
5026{
5028 int tic;
5029 UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR), fdc, vrc;
5030
5031 TRACE("%p, %s, %#lx, %p.\n", iface, debugstr_w(szNameBuf), lHashVal, pfName);
5032
5033 *pfName=TRUE;
5034 for(tic = 0; tic < This->TypeInfoCount; ++tic){
5035 ITypeInfoImpl *pTInfo = This->typeinfos[tic];
5036 if(!TLB_str_memcmp(szNameBuf, pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
5037 for(fdc = 0; fdc < pTInfo->typeattr.cFuncs; ++fdc) {
5038 TLBFuncDesc *pFInfo = &pTInfo->funcdescs[fdc];
5039 int pc;
5040 if(!TLB_str_memcmp(szNameBuf, pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
5041 for(pc=0; pc < pFInfo->funcdesc.cParams; pc++){
5042 if(!TLB_str_memcmp(szNameBuf, pFInfo->pParamDesc[pc].Name, nNameBufLen))
5043 goto ITypeLib2_fnIsName_exit;
5044 }
5045 }
5046 for(vrc = 0; vrc < pTInfo->typeattr.cVars; ++vrc){
5047 TLBVarDesc *pVInfo = &pTInfo->vardescs[vrc];
5048 if(!TLB_str_memcmp(szNameBuf, pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
5049 }
5050
5051 }
5052 *pfName=FALSE;
5053
5054ITypeLib2_fnIsName_exit:
5055 TRACE("(%p)slow! search for %s: %sfound!\n", This,
5056 debugstr_w(szNameBuf), *pfName ? "" : "NOT ");
5057
5058 return S_OK;
5059}
5060
5061/* ITypeLib::FindName
5062 *
5063 * Finds occurrences of a type description in a type library. This may be used
5064 * to quickly verify that a name exists in a type library.
5065 *
5066 */
5068 ITypeLib2 *iface,
5069 LPOLESTR name,
5070 ULONG hash,
5071 ITypeInfo **ppTInfo,
5072 MEMBERID *memid,
5073 UINT16 *found)
5074{
5076 int tic;
5077 UINT count = 0;
5078 UINT len;
5079
5080 TRACE("%p, %s %#lx, %p, %p, %p.\n", iface, debugstr_w(name), hash, ppTInfo, memid, found);
5081
5082 if ((!name && hash == 0) || !ppTInfo || !memid || !found)
5083 return E_INVALIDARG;
5084
5085 len = (lstrlenW(name) + 1)*sizeof(WCHAR);
5086 for(tic = 0; count < *found && tic < This->TypeInfoCount; ++tic) {
5087 ITypeInfoImpl *pTInfo = This->typeinfos[tic];
5088 TLBVarDesc *var;
5089 UINT fdc;
5090
5091 if(!TLB_str_memcmp(name, pTInfo->Name, len)) {
5092 memid[count] = MEMBERID_NIL;
5093 goto ITypeLib2_fnFindName_exit;
5094 }
5095
5096 for(fdc = 0; fdc < pTInfo->typeattr.cFuncs; ++fdc) {
5097 TLBFuncDesc *func = &pTInfo->funcdescs[fdc];
5098
5099 if(!TLB_str_memcmp(name, func->Name, len)) {
5100 memid[count] = func->funcdesc.memid;
5101 goto ITypeLib2_fnFindName_exit;
5102 }
5103 }
5104
5105 var = TLB_get_vardesc_by_name(pTInfo, name);
5106 if (var) {
5107 memid[count] = var->vardesc.memid;
5108 goto ITypeLib2_fnFindName_exit;
5109 }
5110
5111 continue;
5112ITypeLib2_fnFindName_exit:
5113 ITypeInfo2_AddRef(&pTInfo->ITypeInfo2_iface);
5114 ppTInfo[count] = (ITypeInfo *)&pTInfo->ITypeInfo2_iface;
5115 count++;
5116 }
5117 TRACE("found %d typeinfos\n", count);
5118
5119 *found = count;
5120
5121 return S_OK;
5122}
5123
5124/* ITypeLib::ReleaseTLibAttr
5125 *
5126 * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
5127 *
5128 */
5130 ITypeLib2 *iface,
5131 TLIBATTR *pTLibAttr)
5132{
5134 TRACE("(%p)->(%p)\n", This, pTLibAttr);
5135 free(pTLibAttr);
5136}
5137
5138/* ITypeLib2::GetCustData
5139 *
5140 * gets the custom data
5141 */
5143 ITypeLib2 * iface,
5144 REFGUID guid,
5145 VARIANT *pVarVal)
5146{
5148 TLBCustData *pCData;
5149
5150 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(guid), pVarVal);
5151
5152 pCData = TLB_get_custdata_by_guid(&This->custdata_list, guid);
5153 if(!pCData)
5155
5156 VariantInit(pVarVal);
5157 VariantCopy(pVarVal, &pCData->data);
5158
5159 return S_OK;
5160}
5161
5162/* ITypeLib2::GetLibStatistics
5163 *
5164 * Returns statistics about a type library that are required for efficient
5165 * sizing of hash tables.
5166 *
5167 */
5169 ITypeLib2 * iface,
5170 ULONG *pcUniqueNames,
5171 ULONG *pcchUniqueNames)
5172{
5174
5175 FIXME("(%p): stub!\n", This);
5176
5177 if(pcUniqueNames) *pcUniqueNames=1;
5178 if(pcchUniqueNames) *pcchUniqueNames=1;
5179 return S_OK;
5180}
5181
5182/* ITypeLib2::GetDocumentation2
5183 *
5184 * Retrieves the library's documentation string, the complete Help file name
5185 * and path, the localization context to use, and the context ID for the
5186 * library Help topic in the Help file.
5187 *
5188 */
5190 ITypeLib2 * iface,
5191 INT index,
5192 LCID lcid,
5193 BSTR *pbstrHelpString,
5194 DWORD *pdwHelpStringContext,
5195 BSTR *pbstrHelpStringDll)
5196{
5199 ITypeInfo *pTInfo;
5200
5201 FIXME("%p, %d, %#lx, partially implemented stub!\n", iface, index, lcid);
5202
5203 /* the help string should be obtained from the helpstringdll,
5204 * using the _DLLGetDocumentation function, based on the supplied
5205 * lcid. Nice to do sometime...
5206 */
5207 if(index<0)
5208 {
5209 /* documentation for the typelib */
5210 if(pbstrHelpString)
5211 *pbstrHelpString=SysAllocString(TLB_get_bstr(This->DocString));
5212 if(pdwHelpStringContext)
5213 *pdwHelpStringContext=This->dwHelpContext;
5214 if(pbstrHelpStringDll)
5215 *pbstrHelpStringDll=SysAllocString(TLB_get_bstr(This->HelpStringDll));
5216
5217 result = S_OK;
5218 }
5219 else
5220 {
5221 /* for a typeinfo */
5222 result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
5223
5224 if(SUCCEEDED(result))
5225 {
5226 ITypeInfo2 * pTInfo2;
5227 result = ITypeInfo_QueryInterface(pTInfo,
5228 &IID_ITypeInfo2,
5229 (LPVOID*) &pTInfo2);
5230
5231 if(SUCCEEDED(result))
5232 {
5233 result = ITypeInfo2_GetDocumentation2(pTInfo2,
5235 lcid,
5236 pbstrHelpString,
5237 pdwHelpStringContext,
5238 pbstrHelpStringDll);
5239
5240 ITypeInfo2_Release(pTInfo2);
5241 }
5242
5243 ITypeInfo_Release(pTInfo);
5244 }
5245 }
5246 return result;
5247}
5248
5249static HRESULT TLB_copy_all_custdata(const struct list *custdata_list, CUSTDATA *pCustData)
5250{
5251 TLBCustData *pCData;
5252 unsigned int ct;
5253 CUSTDATAITEM *cdi;
5254 HRESULT hr = S_OK;
5255
5256 ct = list_count(custdata_list);
5257
5258 pCustData->prgCustData = CoTaskMemAlloc(ct * sizeof(CUSTDATAITEM));
5259 if(!pCustData->prgCustData)
5260 return E_OUTOFMEMORY;
5261
5262 pCustData->cCustData = ct;
5263
5264 cdi = pCustData->prgCustData;
5265 LIST_FOR_EACH_ENTRY(pCData, custdata_list, TLBCustData, entry){
5266 cdi->guid = *TLB_get_guid_null(pCData->guid);
5267 VariantInit(&cdi->varValue);
5268 hr = VariantCopy(&cdi->varValue, &pCData->data);
5269 if(FAILED(hr)) break;
5270 ++cdi;
5271 }
5272
5273 return hr;
5274}
5275
5276
5277/* ITypeLib2::GetAllCustData
5278 *
5279 * Gets all custom data items for the library.
5280 *
5281 */
5283 ITypeLib2 * iface,
5284 CUSTDATA *pCustData)
5285{
5287 TRACE("(%p)->(%p)\n", This, pCustData);
5288 return TLB_copy_all_custdata(&This->custdata_list, pCustData);
5289}
5290
5291static const ITypeLib2Vtbl tlbvt = {
5305
5310 };
5311
5312
5314{
5316
5317 return ITypeLib2_QueryInterface(&This->ITypeLib2_iface, riid, ppv);
5318}
5319
5321{
5323
5324 return ITypeLib2_AddRef(&This->ITypeLib2_iface);
5325}
5326
5328{
5330
5331 return ITypeLib2_Release(&This->ITypeLib2_iface);
5332}
5333
5335 ITypeComp * iface,
5336 OLECHAR * szName,
5337 ULONG lHash,
5338 WORD wFlags,
5339 ITypeInfo ** ppTInfo,
5340 DESCKIND * pDescKind,
5341 BINDPTR * pBindPtr)
5342{
5344 BOOL typemismatch = FALSE;
5345 int i;
5346
5347 TRACE("%p, %s, %#lx, %#x, %p, %p, %p.\n", iface, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
5348
5349 *pDescKind = DESCKIND_NONE;
5350 pBindPtr->lptcomp = NULL;
5351 *ppTInfo = NULL;
5352
5353 for(i = 0; i < This->TypeInfoCount; ++i){
5354 ITypeInfoImpl *pTypeInfo = This->typeinfos[i];
5355 TRACE("testing %s\n", debugstr_w(TLB_get_bstr(pTypeInfo->Name)));
5356
5357 /* FIXME: check wFlags here? */
5358 /* FIXME: we should use a hash table to look this info up using lHash
5359 * instead of an O(n) search */
5360 if ((pTypeInfo->typeattr.typekind == TKIND_ENUM) ||
5361 (pTypeInfo->typeattr.typekind == TKIND_MODULE))
5362 {
5363 if (pTypeInfo->Name && !wcscmp(pTypeInfo->Name->str, szName))
5364 {
5365 *pDescKind = DESCKIND_TYPECOMP;
5366 pBindPtr->lptcomp = &pTypeInfo->ITypeComp_iface;
5367 ITypeComp_AddRef(pBindPtr->lptcomp);
5368 TRACE("module or enum: %s\n", debugstr_w(szName));
5369 return S_OK;
5370 }
5371 }
5372
5373 if ((pTypeInfo->typeattr.typekind == TKIND_MODULE) ||
5374 (pTypeInfo->typeattr.typekind == TKIND_ENUM))
5375 {
5376 ITypeComp *pSubTypeComp = &pTypeInfo->ITypeComp_iface;
5377 HRESULT hr;
5378
5379 hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
5380 if (SUCCEEDED(hr) && (*pDescKind != DESCKIND_NONE))
5381 {
5382 TRACE("found in module or in enum: %s\n", debugstr_w(szName));
5383 return S_OK;
5384 }
5385 else if (hr == TYPE_E_TYPEMISMATCH)
5386 typemismatch = TRUE;
5387 }
5388
5389 if ((pTypeInfo->typeattr.typekind == TKIND_COCLASS) &&
5390 (pTypeInfo->typeattr.wTypeFlags & TYPEFLAG_FAPPOBJECT))
5391 {
5392 ITypeComp *pSubTypeComp = &pTypeInfo->ITypeComp_iface;
5393 HRESULT hr;
5394 ITypeInfo *subtypeinfo;
5395 BINDPTR subbindptr;
5396 DESCKIND subdesckind;
5397
5398 hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags,
5399 &subtypeinfo, &subdesckind, &subbindptr);
5400 if (SUCCEEDED(hr) && (subdesckind != DESCKIND_NONE))
5401 {
5402 TYPEDESC tdesc_appobject;
5403 const VARDESC vardesc_appobject =
5404 {
5405 -2, /* memid */
5406 NULL, /* lpstrSchema */
5407 {
5408 0 /* oInst */
5409 },
5410 {
5411 /* ELEMDESC */
5412 {
5413 /* TYPEDESC */
5414 {
5415 &tdesc_appobject
5416 },
5417 VT_PTR
5418 },
5419 },
5420 0, /* wVarFlags */
5421 VAR_STATIC /* varkind */
5422 };
5423
5424 tdesc_appobject.hreftype = pTypeInfo->hreftype;
5425 tdesc_appobject.vt = VT_USERDEFINED;
5426
5427 TRACE("found in implicit app object: %s\n", debugstr_w(szName));
5428
5429 /* cleanup things filled in by Bind call so we can put our
5430 * application object data in there instead */
5431 switch (subdesckind)
5432 {
5433 case DESCKIND_FUNCDESC:
5434 ITypeInfo_ReleaseFuncDesc(subtypeinfo, subbindptr.lpfuncdesc);
5435 break;
5436 case DESCKIND_VARDESC:
5437 ITypeInfo_ReleaseVarDesc(subtypeinfo, subbindptr.lpvardesc);
5438 break;
5439 default:
5440 break;
5441 }
5442 if (subtypeinfo) ITypeInfo_Release(subtypeinfo);
5443
5444 if (pTypeInfo->hreftype == -1)
5445 FIXME("no hreftype for interface %p\n", pTypeInfo);
5446
5447 hr = TLB_AllocAndInitVarDesc(&vardesc_appobject, &pBindPtr->lpvardesc);
5448 if (FAILED(hr))
5449 return hr;
5450
5451 *pDescKind = DESCKIND_IMPLICITAPPOBJ;
5452 *ppTInfo = (ITypeInfo *)&pTypeInfo->ITypeInfo2_iface;
5453 ITypeInfo_AddRef(*ppTInfo);
5454 return S_OK;
5455 }
5456 else if (hr == TYPE_E_TYPEMISMATCH)
5457 typemismatch = TRUE;
5458 }
5459 }
5460
5461 if (typemismatch)
5462 {
5463 TRACE("type mismatch %s\n", debugstr_w(szName));
5464 return TYPE_E_TYPEMISMATCH;
5465 }
5466 else
5467 {
5468 TRACE("name not found %s\n", debugstr_w(szName));
5469 return S_OK;
5470 }
5471}
5472
5474 ITypeComp * iface,
5475 OLECHAR * szName,
5476 ULONG lHash,
5477 ITypeInfo ** ppTInfo,
5478 ITypeComp ** ppTComp)
5479{
5482
5483 TRACE("%p, %s, %#lx, %p, %p.\n", iface, debugstr_w(szName), lHash, ppTInfo, ppTComp);
5484
5485 if(!szName || !ppTInfo || !ppTComp)
5486 return E_INVALIDARG;
5487
5489 if(!info){
5490 *ppTInfo = NULL;
5491 *ppTComp = NULL;
5492 return S_OK;
5493 }
5494
5495 *ppTInfo = (ITypeInfo *)&info->ITypeInfo2_iface;
5496 ITypeInfo_AddRef(*ppTInfo);
5497 *ppTComp = &info->ITypeComp_iface;
5498 ITypeComp_AddRef(*ppTComp);
5499
5500 return S_OK;
5501}
5502
5503static const ITypeCompVtbl tlbtcvt =
5504{
5505
5509
5512};
5513
5514/*================== ITypeInfo(2) Methods ===================================*/
5516{
5517 ITypeInfoImpl *pTypeInfoImpl;
5518
5519 pTypeInfoImpl = calloc(1, sizeof(ITypeInfoImpl));
5520 if (pTypeInfoImpl)
5521 {
5522 pTypeInfoImpl->ITypeInfo2_iface.lpVtbl = &tinfvt;
5523 pTypeInfoImpl->ITypeComp_iface.lpVtbl = &tcompvt;
5524 pTypeInfoImpl->ICreateTypeInfo2_iface.lpVtbl = &CreateTypeInfo2Vtbl;
5525 pTypeInfoImpl->ref = 0;
5526 pTypeInfoImpl->hreftype = -1;
5527 pTypeInfoImpl->typeattr.memidConstructor = MEMBERID_NIL;
5528 pTypeInfoImpl->typeattr.memidDestructor = MEMBERID_NIL;
5529 pTypeInfoImpl->pcustdata_list = &pTypeInfoImpl->custdata_list;
5530 list_init(pTypeInfoImpl->pcustdata_list);
5531 }
5532 TRACE("(%p)\n", pTypeInfoImpl);
5533 return pTypeInfoImpl;
5534}
5535
5536/* ITypeInfo::QueryInterface
5537 */
5539 ITypeInfo2 *iface,
5540 REFIID riid,
5541 VOID **ppvObject)
5542{
5544
5545 TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
5546
5547 *ppvObject=NULL;
5549 IsEqualIID(riid,&IID_ITypeInfo)||
5550 IsEqualIID(riid,&IID_ITypeInfo2))
5551 *ppvObject = &This->ITypeInfo2_iface;
5552 else if(IsEqualIID(riid, &IID_ICreateTypeInfo) ||
5553 IsEqualIID(riid, &IID_ICreateTypeInfo2))
5554 *ppvObject = &This->ICreateTypeInfo2_iface;
5555 else if(IsEqualIID(riid, &IID_ITypeComp))
5556 *ppvObject = &This->ITypeComp_iface;
5557
5558 if(*ppvObject){
5559 IUnknown_AddRef((IUnknown*)*ppvObject);
5560 TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
5561 return S_OK;
5562 }
5563 TRACE("-- Interface: E_NOINTERFACE\n");
5564 return E_NOINTERFACE;
5565}
5566
5568{
5571
5572 TRACE("%p, refcount %lu.\n", iface, ref);
5573
5574 if (ref == 1 /* incremented from 0 */)
5575 ITypeLib2_AddRef(&This->pTypeLib->ITypeLib2_iface);
5576
5577 return ref;
5578}
5579
5581{
5582 unsigned int i;
5583
5584 for (i = 0; i < func->funcdesc.cParams; ++i)
5585 {
5586 ELEMDESC *elemdesc = &func->funcdesc.lprgelemdescParam[i];
5587 if (elemdesc->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
5588 VariantClear(&elemdesc->paramdesc.pparamdescex->varDefaultValue);
5589 TLB_FreeCustData(&func->pParamDesc[i].custdata_list);
5590 }
5591 free(func->funcdesc.lprgelemdescParam);
5592 free(func->pParamDesc);
5593 TLB_FreeCustData(&func->custdata_list);
5594}
5595
5597{
5598 UINT i;
5599
5600 TRACE("destroying ITypeInfo(%p)\n",This);
5601
5602 for (i = 0; i < This->typeattr.cFuncs; ++i)
5603 {
5604 typeinfo_release_funcdesc(&This->funcdescs[i]);
5605 }
5606 free(This->funcdescs);
5607
5608 for(i = 0; i < This->typeattr.cVars; ++i)
5609 {
5610 TLBVarDesc *pVInfo = &This->vardescs[i];
5611 if (pVInfo->vardesc_create) {
5613 } else if (pVInfo->vardesc.varkind == VAR_CONST) {
5614 VariantClear(pVInfo->vardesc.lpvarValue);
5615 free(pVInfo->vardesc.lpvarValue);
5616 }
5618 }
5619 free(This->vardescs);
5620
5621 if(This->impltypes){
5622 for (i = 0; i < This->typeattr.cImplTypes; ++i){
5623 TLBImplType *pImpl = &This->impltypes[i];
5625 }
5626 free(This->impltypes);
5627 }
5628
5629 TLB_FreeCustData(&This->custdata_list);
5630
5631 free(This);
5632}
5633
5635{
5638
5639 TRACE("%p, refcount %lu.\n", iface, ref);
5640
5641 if (!ref)
5642 {
5643 BOOL not_attached_to_typelib = This->not_attached_to_typelib;
5644 ITypeLib2_Release(&This->pTypeLib->ITypeLib2_iface);
5645 if (not_attached_to_typelib)
5646 free(This);
5647 /* otherwise This will be freed when typelib is freed */
5648 }
5649
5650 return ref;
5651}
5652
5654 LPTYPEATTR *ppTypeAttr)
5655{
5657 SIZE_T size;
5658
5659 TRACE("(%p)\n",This);
5660
5661 size = sizeof(**ppTypeAttr);
5662 if (This->typeattr.typekind == TKIND_ALIAS && This->tdescAlias)
5663 size += TLB_SizeTypeDesc(This->tdescAlias, FALSE);
5664
5665 *ppTypeAttr = malloc(size);
5666 if (!*ppTypeAttr)
5667 return E_OUTOFMEMORY;
5668
5669 **ppTypeAttr = This->typeattr;
5670 (*ppTypeAttr)->guid = *TLB_get_guid_null(This->guid);
5671
5672 if (This->tdescAlias)
5673 TLB_CopyTypeDesc(&(*ppTypeAttr)->tdescAlias, This->tdescAlias, *ppTypeAttr + 1);
5674
5675 if((*ppTypeAttr)->typekind == TKIND_DISPATCH) {
5676 /* This should include all the inherited funcs */
5677 (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / This->pTypeLib->ptr_size;
5678 /* This is always the size of IDispatch's vtbl */
5679 (*ppTypeAttr)->cbSizeVft = sizeof(IDispatchVtbl);
5680 (*ppTypeAttr)->wTypeFlags &= ~TYPEFLAG_FOLEAUTOMATION;
5681 }
5682 return S_OK;
5683}
5684
5685/* ITypeInfo::GetTypeComp
5686 *
5687 * Retrieves the ITypeComp interface for the type description, which enables a
5688 * client compiler to bind to the type description's members.
5689 *
5690 */
5692 ITypeComp * *ppTComp)
5693{
5695
5696 TRACE("(%p)->(%p)\n", This, ppTComp);
5697
5698 *ppTComp = &This->ITypeComp_iface;
5699 ITypeComp_AddRef(*ppTComp);
5700 return S_OK;
5701}
5702
5703static SIZE_T TLB_SizeElemDesc( const ELEMDESC *elemdesc )
5704{
5705 SIZE_T size = TLB_SizeTypeDesc(&elemdesc->tdesc, FALSE);
5706 if (elemdesc->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
5707 size += sizeof(*elemdesc->paramdesc.pparamdescex);
5708 return size;
5709}
5710
5711static HRESULT TLB_CopyElemDesc( const ELEMDESC *src, ELEMDESC *dest, char **buffer )
5712{
5713 *dest = *src;
5714 *buffer = TLB_CopyTypeDesc(&dest->tdesc, &src->tdesc, *buffer);
5715 if (src->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
5716 {
5717 const PARAMDESCEX *pparamdescex_src = src->paramdesc.pparamdescex;
5718 PARAMDESCEX *pparamdescex_dest = dest->paramdesc.pparamdescex = (PARAMDESCEX *)*buffer;
5719 *buffer += sizeof(PARAMDESCEX);
5720 *pparamdescex_dest = *pparamdescex_src;
5721 pparamdescex_dest->cBytes = sizeof(PARAMDESCEX);
5722 VariantInit(&pparamdescex_dest->varDefaultValue);
5723 return VariantCopy(&pparamdescex_dest->varDefaultValue,
5724 (VARIANTARG *)&pparamdescex_src->varDefaultValue);
5725 }
5726 else
5727 dest->paramdesc.pparamdescex = NULL;
5728 return S_OK;
5729}
5730
5732{
5733 if (V_VT(var) == VT_INT)
5734 return VariantChangeType(var, var, 0, VT_I4);
5735 else if (V_VT(var) == VT_UINT)
5736 return VariantChangeType(var, var, 0, VT_UI4);
5737
5738 return S_OK;
5739}
5740
5741static void TLB_FreeElemDesc( ELEMDESC *elemdesc )
5742{
5743 if (elemdesc->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
5744 VariantClear(&elemdesc->paramdesc.pparamdescex->varDefaultValue);
5745}
5746
5747static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_ptr, BOOL dispinterface )
5748{
5749 FUNCDESC *dest;
5750 char *buffer;
5751 SIZE_T size = sizeof(*src);
5752 SHORT i;
5753 HRESULT hr;
5754
5755 size += sizeof(*src->lprgscode) * src->cScodes;
5756 size += TLB_SizeElemDesc(&src->elemdescFunc);
5757 for (i = 0; i < src->cParams; i++)
5758 {
5759 size += sizeof(ELEMDESC);
5760 size += TLB_SizeElemDesc(&src->lprgelemdescParam[i]);
5761 }
5762
5763 dest = (FUNCDESC *)SysAllocStringByteLen(NULL, size);
5764 if (!dest) return E_OUTOFMEMORY;
5765
5766 *dest = *src;
5767 if (dispinterface) /* overwrite funckind */
5768 dest->funckind = FUNC_DISPATCH;
5769 buffer = (char *)(dest + 1);
5770
5771 dest->oVft = dest->oVft & 0xFFFC;
5772
5773 if (dest->cScodes) {
5774 dest->lprgscode = (SCODE *)buffer;
5775 memcpy(dest->lprgscode, src->lprgscode, sizeof(*src->lprgscode) * src->cScodes);
5776 buffer += sizeof(*src->lprgscode) * src->cScodes;
5777 } else
5778 dest->lprgscode = NULL;
5779
5780 hr = TLB_CopyElemDesc(&src->elemdescFunc, &dest->elemdescFunc, &buffer);
5781 if (FAILED(hr))
5782 {
5784 return hr;
5785 }
5786
5787 if (dest->cParams) {
5788 dest->lprgelemdescParam = (ELEMDESC *)buffer;
5789 buffer += sizeof(ELEMDESC) * src->cParams;
5790 for (i = 0; i < src->cParams; i++)
5791 {
5792 hr = TLB_CopyElemDesc(&src->lprgelemdescParam[i], &dest->lprgelemdescParam[i], &buffer);
5793 if (FAILED(hr))
5794 break;
5795 }
5796 if (FAILED(hr))
5797 {
5798 /* undo the above actions */
5799 for (i = i - 1; i >= 0; i--)
5800 TLB_FreeElemDesc(&dest->lprgelemdescParam[i]);
5801 TLB_FreeElemDesc(&dest->elemdescFunc);
5803 return hr;
5804 }
5805 } else
5806 dest->lprgelemdescParam = NULL;
5807
5808 /* special treatment for dispinterface FUNCDESC based on an interface FUNCDESC.
5809 * This accounts for several arguments that are separate in the signature of
5810 * IDispatch::Invoke, rather than passed in DISPPARAMS::rgvarg[] */
5811 if (dispinterface && (src->funckind != FUNC_DISPATCH))
5812 {
5813 /* functions that have a [retval] parameter return this value into pVarResult.
5814 * [retval] is always the last parameter (if present) */
5815 if (dest->cParams &&
5816 (dest->lprgelemdescParam[dest->cParams - 1].paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
5817 {
5818 ELEMDESC *elemdesc = &dest->lprgelemdescParam[dest->cParams - 1];
5819 if (elemdesc->tdesc.vt != VT_PTR)
5820 {
5821 ERR("elemdesc should have started with VT_PTR instead of:\n");
5822 if (ERR_ON(ole))
5823 dump_ELEMDESC(elemdesc);
5824 return E_UNEXPECTED;
5825 }
5826
5827 /* the type pointed to by this [retval] becomes elemdescFunc,
5828 * i.e. the function signature's return type.
5829 * We are using a flat buffer so there is no danger of leaking memory */
5830 dest->elemdescFunc.tdesc = *elemdesc->tdesc.lptdesc;
5831
5832 /* remove the last parameter */
5833 dest->cParams--;
5834 }
5835 else if (dest->elemdescFunc.tdesc.vt == VT_HRESULT)
5836 /* Even if not otherwise replaced HRESULT is returned in pExcepInfo->scode,
5837 * not pVarResult. So the function signature should show no return value. */
5838 dest->elemdescFunc.tdesc.vt = VT_VOID;
5839
5840 /* The now-last (except [retval], removed above) parameter might be labeled [lcid].
5841 * If so it will be supplied from Invoke(lcid), so also not via DISPPARAMS::rgvarg */
5842 if (dest->cParams && (dest->lprgelemdescParam[dest->cParams - 1].paramdesc.wParamFlags & PARAMFLAG_FLCID))
5843 dest->cParams--;
5844 }
5845
5846 *dest_ptr = dest;
5847 return S_OK;
5848}
5849
5850static void TLB_FreeVarDesc(VARDESC *var_desc)
5851{
5852 TLB_FreeElemDesc(&var_desc->elemdescVar);
5853 if (var_desc->varkind == VAR_CONST)
5854 VariantClear(var_desc->lpvarValue);
5855 SysFreeString((BSTR)var_desc);
5856}
5857
5858/* internal function to make the inherited interfaces' methods appear
5859 * part of the interface */
5861 UINT index, const TLBFuncDesc **ppFuncDesc, UINT *funcs, UINT *hrefoffset)
5862{
5864 HRESULT hr;
5865 UINT implemented_funcs = 0;
5866
5867 if (funcs)
5868 *funcs = 0;
5869 else
5870 *hrefoffset = DISPATCH_HREF_OFFSET;
5871
5872 if(This->impltypes)
5873 {
5874 ITypeInfo *pSubTypeInfo;
5875 UINT sub_funcs;
5876
5877 hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pSubTypeInfo);
5878 if (FAILED(hr))
5879 return hr;
5880
5882 index,
5883 ppFuncDesc,
5884 &sub_funcs, hrefoffset);
5885 implemented_funcs += sub_funcs;
5886 ITypeInfo_Release(pSubTypeInfo);
5887 if (SUCCEEDED(hr))
5888 return hr;
5889 *hrefoffset += DISPATCH_HREF_OFFSET;
5890 }
5891
5892 if (funcs)
5893 *funcs = implemented_funcs + This->typeattr.cFuncs;
5894 else
5895 *hrefoffset = 0;
5896
5897 if (index < implemented_funcs)
5898 return E_INVALIDARG;
5899 index -= implemented_funcs;
5900
5901 if (index >= This->typeattr.cFuncs)
5903
5904 *ppFuncDesc = &This->funcdescs[index];
5905 return S_OK;
5906}
5907
5908static HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const TLBFuncDesc **func_desc, UINT *hrefoffset )
5909{
5911
5912 if (This->typeattr.typekind == TKIND_DISPATCH)
5913 return ITypeInfoImpl_GetInternalDispatchFuncDesc(iface, index, func_desc, NULL, hrefoffset);
5914
5915 if (index >= This->typeattr.cFuncs)
5917
5918 *func_desc = &This->funcdescs[index];
5919 return S_OK;
5920}
5921
5922static inline void ITypeInfoImpl_ElemDescAddHrefOffset( LPELEMDESC pElemDesc, UINT hrefoffset)
5923{
5924 TYPEDESC *pTypeDesc = &pElemDesc->tdesc;
5925 while (TRUE)
5926 {
5927 switch (pTypeDesc->vt)
5928 {
5929 case VT_USERDEFINED:
5930 pTypeDesc->hreftype += hrefoffset;
5931 return;
5932 case VT_PTR:
5933 case VT_SAFEARRAY:
5934 pTypeDesc = pTypeDesc->lptdesc;
5935 break;
5936 case VT_CARRAY:
5937 pTypeDesc = &pTypeDesc->lpadesc->tdescElem;
5938 break;
5939 default:
5940 return;
5941 }
5942 }
5943}
5944
5945static inline void ITypeInfoImpl_FuncDescAddHrefOffset( LPFUNCDESC pFuncDesc, UINT hrefoffset)
5946{
5947 SHORT i;
5948 for (i = 0; i < pFuncDesc->cParams; i++)
5949 ITypeInfoImpl_ElemDescAddHrefOffset(&pFuncDesc->lprgelemdescParam[i], hrefoffset);
5950 ITypeInfoImpl_ElemDescAddHrefOffset(&pFuncDesc->elemdescFunc, hrefoffset);
5951}
5952
5953/* ITypeInfo::GetFuncDesc
5954 *
5955 * Retrieves the FUNCDESC structure that contains information about a
5956 * specified function.
5957 *
5958 */
5960 LPFUNCDESC *ppFuncDesc)
5961{
5963 const TLBFuncDesc *internal_funcdesc;
5964 HRESULT hr;
5965 UINT hrefoffset = 0;
5966
5967 TRACE("(%p) index %d\n", This, index);
5968
5969 if (!ppFuncDesc)
5970 return E_INVALIDARG;
5971
5972 if (This->needs_layout)
5973 ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface);
5974
5976 &internal_funcdesc, &hrefoffset);
5977 if (FAILED(hr))
5978 {
5979 WARN("description for function %d not found\n", index);
5980 return hr;
5981 }
5982
5984 &internal_funcdesc->funcdesc,
5985 ppFuncDesc,
5986 This->typeattr.typekind == TKIND_DISPATCH);
5987
5988 if ((This->typeattr.typekind == TKIND_DISPATCH) && hrefoffset)
5989 ITypeInfoImpl_FuncDescAddHrefOffset(*ppFuncDesc, hrefoffset);
5990
5991 TRACE("-- %#lx.\n", hr);
5992 return hr;
5993}
5994
5995static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
5996{
5997 VARDESC *dest;
5998 char *buffer;
5999 SIZE_T size = sizeof(*src);
6000 HRESULT hr;
6001
6002 if (src->lpstrSchema) size += (lstrlenW(src->lpstrSchema) + 1) * sizeof(WCHAR);
6003 if (src->varkind == VAR_CONST)
6004 size += sizeof(VARIANT);
6005 size += TLB_SizeElemDesc(&src->elemdescVar);
6006
6007 dest = (VARDESC *)SysAllocStringByteLen(NULL, size);
6008 if (!dest) return E_OUTOFMEMORY;
6009
6010 *dest = *src;
6011 buffer = (char *)(dest + 1);
6012 if (src->lpstrSchema)
6013 {
6014 int len;
6015 dest->lpstrSchema = (LPOLESTR)buffer;
6016 len = lstrlenW(src->lpstrSchema);
6017 memcpy(dest->lpstrSchema, src->lpstrSchema, (len + 1) * sizeof(WCHAR));
6018 buffer += (len + 1) * sizeof(WCHAR);
6019 }
6020
6021 if (src->varkind == VAR_CONST)
6022 {
6023 HRESULT hr;
6024
6025 dest->lpvarValue = (VARIANT *)buffer;
6026 *dest->lpvarValue = *src->lpvarValue;
6027 buffer += sizeof(VARIANT);
6028 VariantInit(dest->lpvarValue);
6029 hr = VariantCopy(dest->lpvarValue, src->lpvarValue);
6030 if (FAILED(hr))
6031 {
6033 return hr;
6034 }
6035 }
6036 hr = TLB_CopyElemDesc(&src->elemdescVar, &dest->elemdescVar, &buffer);
6037 if (FAILED(hr))
6038 {
6039 if (src->varkind == VAR_CONST)
6040 VariantClear(dest->lpvarValue);
6042 return hr;
6043 }
6044 *dest_ptr = dest;
6045 return S_OK;
6046}
6047
6048/* ITypeInfo::GetVarDesc
6049 *
6050 * Retrieves a VARDESC structure that describes the specified variable.
6051 *
6052 */
6054 LPVARDESC *ppVarDesc)
6055{
6057 const TLBVarDesc *pVDesc = &This->vardescs[index];
6058
6059 TRACE("(%p) index %d\n", This, index);
6060
6061 if(index >= This->typeattr.cVars)
6063
6064 if (This->needs_layout)
6065 ICreateTypeInfo2_LayOut(&This->ICreateTypeInfo2_iface);
6066
6067 return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc);
6068}
6069
6070/* internal function to make the inherited interfaces' methods appear
6071 * part of the interface, remembering if the top-level was dispinterface */
6072static HRESULT typeinfo_getnames( ITypeInfo *iface, MEMBERID memid, BSTR *names,
6073 UINT max_names, UINT *num_names, BOOL dispinterface)
6074{
6076 const TLBFuncDesc *func_desc;
6077 const TLBVarDesc *var_desc;
6078 int i;
6079
6080 *num_names = 0;
6081
6082 func_desc = TLB_get_funcdesc_by_memberid(This, memid);
6083 if (func_desc)
6084 {
6085 UINT params = func_desc->funcdesc.cParams;
6086 if (!max_names || !func_desc->Name)
6087 return S_OK;
6088
6089 *names = SysAllocString(TLB_get_bstr(func_desc->Name));
6090 ++(*num_names);
6091
6092 if (dispinterface && (func_desc->funcdesc.funckind != FUNC_DISPATCH))
6093 {
6094 /* match the rewriting of special trailing parameters in TLB_AllocAndInitFuncDesc */
6095 if ((params > 0) && (func_desc->funcdesc.lprgelemdescParam[params - 1].paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
6096 --params; /* Invoke(pVarResult) supplies the [retval] parameter, so it's hidden from DISPPARAMS */
6097 if ((params > 0) && (func_desc->funcdesc.lprgelemdescParam[params - 1].paramdesc.wParamFlags & PARAMFLAG_FLCID))
6098 --params; /* Invoke(lcid) supplies the [lcid] parameter, so it's hidden from DISPPARAMS */
6099 }
6100
6101 for (i = 0; i < params; i++)
6102 {
6103 if (*num_names >= max_names || !func_desc->pParamDesc[i].Name)
6104 return S_OK;
6105 names[*num_names] = SysAllocString(TLB_get_bstr(func_desc->pParamDesc[i].Name));
6106 ++(*num_names);
6107 }
6108 return S_OK;
6109 }
6110
6111 var_desc = TLB_get_vardesc_by_memberid(This, memid);
6112 if (var_desc)
6113 {
6114 *names = SysAllocString(TLB_get_bstr(var_desc->Name));
6115 *num_names = 1;
6116 }
6117 else
6118 {
6119 if (This->impltypes &&
6120 (This->typeattr.typekind == TKIND_INTERFACE || This->typeattr.typekind == TKIND_DISPATCH))
6121 {
6122 /* recursive search */
6125 result = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &parent);
6126 if (SUCCEEDED(result))
6127 {
6128 result = typeinfo_getnames(parent, memid, names, max_names, num_names, dispinterface);
6129 ITypeInfo_Release(parent);
6130 return result;
6131 }
6132 WARN("Could not search inherited interface!\n");
6133 }
6134 else
6135 {
6136 WARN("no names found\n");
6137 }
6138 *num_names = 0;
6140 }
6141 return S_OK;
6142}
6143
6144/* ITypeInfo_GetNames
6145 *
6146 * Retrieves the variable with the specified member ID (or the name of the
6147 * property or method and its parameters) that correspond to the specified
6148 * function ID.
6149 */
6150static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
6151 BSTR *names, UINT max_names, UINT *num_names)
6152{
6154
6155 TRACE("%p, %#lx, %p, %d, %p\n", iface, memid, names, max_names, num_names);
6156
6157 if (!names) return E_INVALIDARG;
6158
6159 return typeinfo_getnames((ITypeInfo *)iface, memid, names, max_names, num_names,
6160 This->typeattr.typekind == TKIND_DISPATCH);
6161}
6162
6163/* ITypeInfo::GetRefTypeOfImplType
6164 *
6165 * If a type description describes a COM class, it retrieves the type
6166 * description of the implemented interface types. For an interface,
6167 * GetRefTypeOfImplType returns the type information for inherited interfaces,
6168 * if any exist.
6169 *
6170 */
6172 ITypeInfo2 *iface,
6173 UINT index,
6174 HREFTYPE *pRefType)
6175{
6177 HRESULT hr = S_OK;
6178
6179 TRACE("(%p) index %d\n", This, index);
6180 if (TRACE_ON(ole)) dump_TypeInfo(This);
6181
6182 if(index==(UINT)-1)
6183 {
6184 /* only valid on dual interfaces;
6185 retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH
6186 */
6187
6188 if (This->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
6189 {
6190 *pRefType = -2;
6191 }
6192 else
6193 {
6195 }
6196 }
6197 else if(index == 0 && This->typeattr.typekind == TKIND_DISPATCH)
6198 {
6199 /* All TKIND_DISPATCHs are made to look like they inherit from IDispatch */
6200 *pRefType = This->pTypeLib->dispatch_href;
6201 }
6202 else
6203 {
6204 if(index >= This->typeattr.cImplTypes)
6206 else{
6207 *pRefType = This->impltypes[index].hRef;
6208 if (This->typeattr.typekind == TKIND_INTERFACE)
6209 *pRefType |= 0x2;
6210 }
6211 }
6212
6213 if(TRACE_ON(ole))
6214 {
6215 if(SUCCEEDED(hr))
6216 TRACE("SUCCESS -- hRef %#lx.\n", *pRefType );
6217 else
6218 TRACE("FAILURE -- hresult %#lx.\n", hr);
6219 }
6220
6221 return hr;
6222}
6223
6224/* ITypeInfo::GetImplTypeFlags
6225 *
6226 * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
6227 * or base interface in a type description.
6228 */
6230 UINT index, INT *pImplTypeFlags)
6231{
6233
6234 TRACE("(%p) index %d\n", This, index);
6235
6236 if(!pImplTypeFlags)
6237 return E_INVALIDARG;
6238
6239 if(This->typeattr.typekind == TKIND_DISPATCH && index == 0){
6240 *pImplTypeFlags = 0;
6241 return S_OK;
6242 }
6243
6244 if(index >= This->typeattr.cImplTypes)
6246
6247 *pImplTypeFlags = This->impltypes[index].implflags;
6248
6249 return S_OK;
6250}
6251
6252/* GetIDsOfNames
6253 * Maps between member names and member IDs, and parameter names and
6254 * parameter IDs.
6255 */
6257 LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
6258{
6260 const TLBVarDesc *pVDesc;
6262 UINT i, fdc;
6263
6264 TRACE("%p, %s, %d.\n", iface, debugstr_w(*rgszNames), cNames);
6265
6266 /* init out parameters in case of failure */
6267 for (i = 0; i < cNames; i++)
6268 pMemId[i] = MEMBERID_NIL;
6269
6270 for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc) {
6271 int j;
6272 const TLBFuncDesc *pFDesc = &This->funcdescs[fdc];
6273 if(!lstrcmpiW(*rgszNames, TLB_get_bstr(pFDesc->Name))) {
6274 if(cNames) *pMemId=pFDesc->funcdesc.memid;
6275 for(i=1; i < cNames; i++){
6276 for(j=0; j<pFDesc->funcdesc.cParams; j++)
6277 if(!lstrcmpiW(rgszNames[i],TLB_get_bstr(pFDesc->pParamDesc[j].Name)))
6278 break;
6279 if( j<pFDesc->funcdesc.cParams)
6280 pMemId[i]=j;
6281 else
6283 };
6284 TRACE("-- %#lx.\n", ret);
6285 return ret;
6286 }
6287 }
6288 pVDesc = TLB_get_vardesc_by_name(This, *rgszNames);
6289 if(pVDesc){
6290 if(cNames)
6291 *pMemId = pVDesc->vardesc.memid;
6292 return ret;
6293 }
6294 /* not found, see if it can be found in an inherited interface */
6295 if(This->impltypes) {
6296 /* recursive search */
6297 ITypeInfo *pTInfo;
6298 ret = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
6299 if(SUCCEEDED(ret)){
6300 ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
6301 ITypeInfo_Release(pTInfo);
6302 return ret;
6303 }
6304 WARN("Could not search inherited interface!\n");
6305 } else
6306 WARN("no names found\n");
6307 return DISP_E_UNKNOWNNAME;
6308}
6309
6310
6311#ifdef __i386__
6312
6313extern LONGLONG call_method( void *func, int nb_args, const DWORD *args, int *stack_offset );
6314extern double call_double_method( void *func, int nb_args, const DWORD *args, int *stack_offset );
6315
6316HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
6317 UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
6318{
6319 int argspos = 0, stack_offset;
6320 void *func;
6321 UINT i;
6322 DWORD *args;
6323
6324 TRACE("(%p, %Id, %d, %d, %d, %p, %p, %p (vt=%d))\n",
6325 pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
6326 pvargResult, V_VT(pvargResult));
6327
6328 if (cc != CC_STDCALL && cc != CC_CDECL)
6329 {
6330 FIXME("unsupported calling convention %d\n",cc);
6331 return E_INVALIDARG;
6332 }
6333
6334 /* maximum size for an argument is sizeof(VARIANT) */
6335 args = malloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 );
6336
6337 if (pvInstance)
6338 {
6339 const FARPROC *vtable = *(FARPROC **)pvInstance;
6340 func = vtable[oVft/sizeof(void *)];
6341 args[argspos++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
6342 }
6343 else func = (void *)oVft;
6344
6345 switch (vtReturn)
6346 {
6347 case VT_DECIMAL:
6348 case VT_VARIANT:
6349 args[argspos++] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */
6350 break;
6351 case VT_HRESULT:
6352 WARN("invalid return type %u\n", vtReturn);
6353 free( args );
6354 return E_INVALIDARG;
6355 default:
6356 break;
6357 }
6358
6359 for (i = 0; i < cActuals; i++)
6360 {
6361 VARIANT *arg = prgpvarg[i];
6362
6363 switch (prgvt[i])
6364 {
6365 case VT_EMPTY:
6366 break;
6367 case VT_I8:
6368 case VT_UI8:
6369 case VT_R8:
6370 case VT_DATE:
6371 case VT_CY:
6372 memcpy( &args[argspos], &V_I8(arg), sizeof(V_I8(arg)) );
6373 argspos += sizeof(V_I8(arg)) / sizeof(DWORD);
6374 break;
6375 case VT_DECIMAL:
6376 case VT_VARIANT:
6377 memcpy( &args[argspos], arg, sizeof(*arg) );
6378 argspos += sizeof(*arg) / sizeof(DWORD);
6379 break;
6380 case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
6381 args[argspos++] = V_BOOL(arg);
6382 break;
6383 default:
6384 args[argspos++] = V_UI4(arg);
6385 break;
6386 }
6387 TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
6388 }
6389
6390 switch (vtReturn)
6391 {
6392 case VT_EMPTY:
6393 case VT_DECIMAL:
6394 case VT_VARIANT:
6395 call_method( func, argspos, args, &stack_offset );
6396 break;
6397 case VT_R4:
6398 V_R4(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
6399 break;
6400 case VT_R8:
6401 case VT_DATE:
6402 V_R8(pvargResult) = call_double_method( func, argspos, args, &stack_offset );
6403 break;
6404 case VT_I8:
6405 case VT_UI8:
6406 case VT_CY:
6407 V_UI8(pvargResult) = call_method( func, argspos, args, &stack_offset );
6408 break;
6409 default:
6410 V_UI4(pvargResult) = call_method( func, argspos, args, &stack_offset );
6411 break;
6412 }
6413 free( args );
6414 if (stack_offset && cc == CC_STDCALL)
6415 {
6416 WARN( "stack pointer off by %d\n", stack_offset );
6417 return DISP_E_BADCALLEE;
6418 }
6419 if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
6420 TRACE("retval: %s\n", debugstr_variant(pvargResult));
6421 return S_OK;
6422}
6423
6424#elif defined(__x86_64__)
6425
6426extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args );
6427extern double CDECL call_double_method( void *func, int nb_args, const DWORD_PTR *args );
6428
6429HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
6430 UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
6431{
6432 int argspos = 0;
6433 UINT i;
6434 DWORD_PTR *args;
6435 void *func;
6436
6437 TRACE("%p, %Id, %d, %d, %d, %p, %p, %p (vt=%d).\n",
6438 pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
6439 pvargResult, V_VT(pvargResult));
6440
6441 if (cc != CC_STDCALL && cc != CC_CDECL)
6442 {
6443 FIXME("unsupported calling convention %d\n",cc);
6444 return E_INVALIDARG;
6445 }
6446
6447 /* maximum size for an argument is sizeof(DWORD_PTR) */
6448 args = malloc( sizeof(DWORD_PTR) * (cActuals + 2) );
6449
6450 if (pvInstance)
6451 {
6452 const FARPROC *vtable = *(FARPROC **)pvInstance;
6453 func = vtable[oVft/sizeof(void *)];
6454 args[argspos++] = (DWORD_PTR)pvInstance; /* the This pointer is always the first parameter */
6455 }
6456 else func = (void *)oVft;
6457
6458 switch (vtReturn)
6459 {
6460 case VT_DECIMAL:
6461 case VT_VARIANT:
6462 args[argspos++] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */
6463 break;
6464 case VT_HRESULT:
6465 WARN("invalid return type %u\n", vtReturn);
6466 free( args );
6467 return E_INVALIDARG;
6468 default:
6469 break;
6470 }
6471
6472 for (i = 0; i < cActuals; i++)
6473 {
6474 VARIANT *arg = prgpvarg[i];
6475
6476 switch (prgvt[i])
6477 {
6478 case VT_DECIMAL:
6479 case VT_VARIANT:
6480 args[argspos++] = (ULONG_PTR)arg;
6481 break;
6482 case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
6483 args[argspos++] = V_BOOL(arg);
6484 break;
6485 default:
6486 args[argspos++] = V_UI8(arg);
6487 break;
6488 }
6489 TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
6490 }
6491
6492 switch (vtReturn)
6493 {
6494 case VT_R4:
6495 V_R4(pvargResult) = call_double_method( func, argspos, args );
6496 break;
6497 case VT_R8:
6498 case VT_DATE:
6499 V_R8(pvargResult) = call_double_method( func, argspos, args );
6500 break;
6501 case VT_DECIMAL:
6502 case VT_VARIANT:
6503 call_method( func, argspos, args );
6504 break;
6505 default:
6506 V_UI8(pvargResult) = call_method( func, argspos, args );
6507 break;
6508 }
6509 free( args );
6510 if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
6511 TRACE("retval: %s\n", debugstr_variant(pvargResult));
6512 return S_OK;
6513}
6514
6515#elif defined(__arm__)
6516
6517extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
6518extern float CDECL call_float_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
6519extern double CDECL call_double_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args );
6520
6521HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
6522 UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
6523{
6524 int argspos;
6525 void *func;
6526 UINT i;
6527 DWORD *args;
6528 struct {
6529 union {
6530 float s[16];
6531 double d[8];
6532 } sd;
6533 DWORD r[4];
6534 } regs;
6535 int rcount; /* 32-bit register index count */
6536 int scount = 0; /* single-precision float register index count */
6537 int dcount = 0; /* double-precision float register index count */
6538
6539 TRACE("(%p, %Id, %d, %d, %d, %p, %p, %p (vt=%d))\n",
6540 pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
6541
6542 if (cc != CC_STDCALL && cc != CC_CDECL)
6543 {
6544 FIXME("unsupported calling convention %d\n",cc);
6545 return E_INVALIDARG;
6546 }
6547
6548 argspos = 0;
6549 rcount = 0;
6550
6551 if (pvInstance)
6552 {
6553 const FARPROC *vtable = *(FARPROC **)pvInstance;
6554 func = vtable[oVft/sizeof(void *)];
6555 regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
6556 }
6557 else func = (void *)oVft;
6558
6559 /* Determine if we need to pass a pointer for the return value as arg 0. If so, do that */
6560 /* first as it will need to be in the 'r' registers: */
6561 switch (vtReturn)
6562 {
6563 case VT_DECIMAL:
6564 case VT_VARIANT:
6565 regs.r[rcount++] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */
6566 break;
6567 case VT_HRESULT:
6568 WARN("invalid return type %u\n", vtReturn);
6569 return E_INVALIDARG;
6570 default: /* And all others are in 'r', 's', or 'd' registers or have no return value */
6571 break;
6572 }
6573
6574 /* maximum size for an argument is sizeof(VARIANT). Also allow for return pointer and stack alignment. */
6575 args = malloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 4 );
6576
6577 for (i = 0; i < cActuals; i++)
6578 {
6579 VARIANT *arg = prgpvarg[i];
6580 DWORD *pdwarg = (DWORD *)(arg); /* a reinterpret_cast of the variant, used for copying structures when they are split between registers and stack */
6581 int ntemp; /* Used for counting words split between registers and stack */
6582
6583 switch (prgvt[i])
6584 {
6585 case VT_R8: /* these must be 8-byte aligned, and put in 'd' regs or stack, as they are double-floats */
6586 case VT_DATE:
6587 dcount = max( (scount + 1) / 2, dcount );
6588 if (dcount < 8)
6589 {
6590 regs.sd.d[dcount++] = V_R8(arg);
6591 }
6592 else
6593 {
6594 argspos += (argspos % 2); /* align argspos to 8-bytes */
6595 memcpy( &args[argspos], &V_R8(arg), sizeof(V_R8(arg)) );
6596 argspos += sizeof(V_R8(arg)) / sizeof(DWORD);
6597 }
6598 break;
6599 case VT_I8: /* these must be 8-byte aligned, and put in 'r' regs or stack, as they are long-longs */
6600 case VT_UI8:
6601 case VT_CY:
6602 if (rcount < 3)
6603 {
6604 rcount += (rcount % 2); /* align rcount to 8-byte register pair */
6605 memcpy( &regs.r[rcount], &V_UI8(arg), sizeof(V_UI8(arg)) );
6606 rcount += sizeof(V_UI8(arg)) / sizeof(DWORD);
6607 }
6608 else
6609 {
6610 rcount = 4; /* Make sure we flag that all 'r' regs are full */
6611 argspos += (argspos % 2); /* align argspos to 8-bytes */
6612 memcpy( &args[argspos], &V_UI8(arg), sizeof(V_UI8(arg)) );
6613 argspos += sizeof(V_UI8(arg)) / sizeof(DWORD);
6614 }
6615 break;
6616 case VT_DECIMAL: /* these structures are 8-byte aligned, and put in 'r' regs or stack, can be split between the two */
6617 case VT_VARIANT:
6618 /* 8-byte align 'r' and/or stack: */
6619 if (rcount < 3)
6620 rcount += (rcount % 2);
6621 else
6622 {
6623 rcount = 4;
6624 argspos += (argspos % 2);
6625 }
6626 ntemp = sizeof(*arg) / sizeof(DWORD);
6627 while (ntemp > 0)
6628 {
6629 if (rcount < 4)
6630 regs.r[rcount++] = *pdwarg++;
6631 else
6632 args[argspos++] = *pdwarg++;
6633 --ntemp;
6634 }
6635 break;
6636 case VT_R4: /* these must be 4-byte aligned, and put in 's' regs or stack, as they are single-floats */
6637 if (!(scount % 2)) scount = max( scount, dcount * 2 );
6638 if (scount < 16)
6639 regs.sd.s[scount++] = V_R4(arg);
6640 else
6641 args[argspos++] = V_UI4(arg);
6642 break;
6643 /* extend parameters to 32 bits */
6644 case VT_I1:
6645 if (rcount < 4) regs.r[rcount++] = V_I1(arg);
6646 else args[argspos++] = V_I1(arg);
6647 break;
6648 case VT_UI1:
6649 if (rcount < 4) regs.r[rcount++] = V_UI1(arg);
6650 else args[argspos++] = V_UI1(arg);
6651 break;
6652 case VT_I2:
6653 if (rcount < 4) regs.r[rcount++] = V_I2(arg);
6654 else args[argspos++] = V_I2(arg);
6655 break;
6656 case VT_UI2:
6657 if (rcount < 4) regs.r[rcount++] = V_UI2(arg);
6658 else args[argspos++] = V_UI2(arg);
6659 break;
6660 case VT_BOOL:
6661 if (rcount < 4) regs.r[rcount++] = V_BOOL(arg);
6662 else args[argspos++] = V_BOOL(arg);
6663 break;
6664 default:
6665 if (rcount < 4) regs.r[rcount++] = V_UI4(arg);
6666 else args[argspos++] = V_UI4(arg);
6667 break;
6668 }
6669 TRACE("arg %u: type %s %s\n", i, debugstr_vt(prgvt[i]), debugstr_variant(arg));
6670 }
6671
6672 argspos += (argspos % 2); /* Make sure stack function alignment is 8-byte */
6673
6674 switch (vtReturn)
6675 {
6676 case VT_DECIMAL: /* DECIMAL and VARIANT already have a pointer argument passed (see above) */
6677 case VT_VARIANT:
6678 call_method( func, argspos, args, (DWORD*)&regs );
6679 break;
6680 case VT_R4:
6681 V_R4(pvargResult) = call_float_method( func, argspos, args, (DWORD*)&regs );
6682 break;
6683 case VT_R8:
6684 case VT_DATE:
6685 V_R8(pvargResult) = call_double_method( func, argspos, args, (DWORD*)&regs );
6686 break;
6687 case VT_I8:
6688 case VT_UI8:
6689 case VT_CY:
6690 V_UI8(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
6691 break;
6692 default:
6693 V_UI4(pvargResult) = call_method( func, argspos, args, (DWORD*)&regs );
6694 break;
6695 }
6696 free( args );
6697 if (vtReturn != VT_VARIANT) V_VT(pvargResult) = vtReturn;
6698 TRACE("retval: %s\n", debugstr_variant(pvargResult));
6699 return S_OK;
6700}
6701
6702#elif defined(__aarch64__)
6703
6704extern DWORD_PTR CDECL call_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
6705extern float CDECL call_float_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
6706extern double CDECL call_double_method( void *func, int nb_stk_args, const DWORD_PTR *stk_args, const DWORD_PTR *reg_args );
6707
6708HRESULT WINAPI DispCallFunc( void *instance, ULONG_PTR offset, CALLCONV cc, VARTYPE ret_type, UINT count,
6709 VARTYPE *types, VARIANTARG **vargs, VARIANT *result )
6710{
6711 int argspos;
6712 void *func;
6713 UINT i;
6714 DWORD_PTR *args;
6715 struct
6716 {
6717 union
6718 {
6719 float f;
6720 double d;
6721 } fp[8];
6722 DWORD_PTR x[9];
6723 } regs;
6724 int rcount; /* 64-bit register index count */
6725 int fpcount = 0; /* float register index count */
6726
6727 TRACE("(%p, %Id, %d, %d, %d, %p, %p, %p (vt=%d))\n",
6728 instance, offset, cc, ret_type, count, types, vargs, result, V_VT(result));
6729
6730 if (cc != CC_STDCALL && cc != CC_CDECL)
6731 {
6732 FIXME("unsupported calling convention %d\n",cc);
6733 return E_INVALIDARG;
6734 }
6735
6736 argspos = 0;
6737 rcount = 0;
6738
6739 if (instance)
6740 {
6741 const FARPROC *vtable = *(FARPROC **)instance;
6742 func = vtable[offset/sizeof(void *)];
6743 regs.x[rcount++] = (DWORD_PTR)instance; /* the This pointer is always the first parameter */
6744 }
6745 else func = (void *)offset;
6746
6747 /* maximum size for an argument is 16 */
6748 args = malloc( 16 * count );
6749
6750 for (i = 0; i < count; i++)
6751 {
6752 VARIANT *arg = vargs[i];
6753
6754 switch (types[i])
6755 {
6756 case VT_R4:
6757 if (fpcount < 8) regs.fp[fpcount++].f = V_R4(arg);
6758 else *(float *)&args[argspos++] = V_R4(arg);
6759 break;
6760 case VT_R8:
6761 case VT_DATE:
6762 if (fpcount < 8) regs.fp[fpcount++].d = V_R8(arg);
6763 else *(double *)&args[argspos++] = V_R8(arg);
6764 break;
6765 case VT_DECIMAL:
6766 if (rcount < 7)
6767 {
6768 memcpy( &regs.x[rcount], arg, sizeof(*arg) );
6769 rcount += 2;
6770 }
6771 else
6772 {
6773 memcpy( &args[argspos], arg, sizeof(*arg) );
6774 argspos += 2;
6775 }
6776 break;
6777 case VT_VARIANT:
6778 if (rcount < 8) regs.x[rcount++] = (DWORD_PTR)arg;
6779 else args[argspos++] = (DWORD_PTR)arg;
6780 break;
6781 case VT_BOOL: /* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
6782 if (rcount < 8) regs.x[rcount++] = V_BOOL(arg);
6783 else args[argspos++] = V_BOOL(arg);
6784 break;
6785 default:
6786 if (rcount < 8) regs.x[rcount++] = V_UI8(arg);
6787 else args[argspos++] = V_UI8(arg);
6788 break;
6789 }
6790 TRACE("arg %u: type %s %s\n", i, debugstr_vt(types[i]), debugstr_variant(arg));
6791 }
6792
6793 argspos += (argspos % 2); /* Make sure stack function alignment is 16-byte */
6794
6795 switch (ret_type)
6796 {
6797 case VT_HRESULT:
6798 free( args );
6799 return E_INVALIDARG;
6800 case VT_DECIMAL:
6801 case VT_VARIANT:
6802 regs.x[8] = (DWORD_PTR)result; /* x8 is a pointer to the result */
6803 call_method( func, argspos, args, (DWORD_PTR *)&regs );
6804 break;
6805 case VT_R4:
6806 V_R4(result) = call_float_method( func, argspos, args, (DWORD_PTR *)&regs );
6807 break;
6808 case VT_R8:
6809 case VT_DATE:
6810 V_R8(result) = call_double_method( func, argspos, args, (DWORD_PTR *)&regs );
6811 break;
6812 default:
6813 V_UI8(result) = call_method( func, argspos, args, (DWORD_PTR *)&regs );
6814 break;
6815 }
6816 free( args );
6817 if (ret_type != VT_VARIANT) V_VT(result) = ret_type;
6818 TRACE("retval: %s\n", debugstr_variant(result));
6819 return S_OK;
6820}
6821
6822#else /* __aarch64__ */
6823
6824HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn,
6825 UINT cActuals, VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult )
6826{
6827 FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
6828 pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
6829 return E_NOTIMPL;
6830}
6831
6832#endif
6833
6834static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
6835{
6836 HRESULT hr = S_OK;
6837 ITypeInfo *tinfo2 = NULL;
6838 TYPEATTR *tattr = NULL;
6839
6840 hr = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->hreftype, &tinfo2);
6841 if (hr)
6842 {
6843 ERR("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, hr %#lx.\n", tdesc->hreftype, hr);
6844 return hr;
6845 }
6846 hr = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
6847 if (hr)
6848 {
6849 ERR("ITypeInfo_GetTypeAttr failed, hr %#lx.\n", hr);
6850 ITypeInfo_Release(tinfo2);
6851 return hr;
6852 }
6853
6854 switch (tattr->typekind)
6855 {
6856 case TKIND_ENUM:
6857 *vt |= VT_I4;
6858 break;
6859
6860 case TKIND_ALIAS:
6861 hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
6862 break;
6863
6864 case TKIND_INTERFACE:
6865 if (tattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE)
6866 *vt |= VT_DISPATCH;
6867 else
6868 *vt |= VT_UNKNOWN;
6869 break;
6870
6871 case TKIND_DISPATCH:
6872 *vt |= VT_DISPATCH;
6873 break;
6874
6875 case TKIND_COCLASS:
6876 *vt |= VT_DISPATCH;
6877 break;
6878
6879 case TKIND_RECORD:
6880 FIXME("TKIND_RECORD unhandled.\n");
6881 hr = E_NOTIMPL;
6882 break;
6883
6884 case TKIND_UNION:
6885 FIXME("TKIND_UNION unhandled.\n");
6886 hr = E_NOTIMPL;
6887 break;
6888
6889 default:
6890 FIXME("TKIND %d unhandled.\n",tattr->typekind);
6891 hr = E_NOTIMPL;
6892 break;
6893 }
6894 ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
6895 ITypeInfo_Release(tinfo2);
6896 return hr;
6897}
6898
6899static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
6900{
6901 HRESULT hr = S_OK;
6902
6903 /* enforce only one level of pointer indirection */
6904 if (!(*vt & VT_BYREF) && !(*vt & VT_ARRAY) && (tdesc->vt == VT_PTR))
6905 {
6906 tdesc = tdesc->lptdesc;
6907
6908 /* munch VT_PTR -> VT_USERDEFINED(interface) into VT_UNKNOWN or
6909 * VT_DISPATCH and VT_PTR -> VT_PTR -> VT_USERDEFINED(interface) into
6910 * VT_BYREF|VT_DISPATCH or VT_BYREF|VT_UNKNOWN */
6911 if ((tdesc->vt == VT_USERDEFINED) ||
6912 ((tdesc->vt == VT_PTR) && (tdesc->lptdesc->vt == VT_USERDEFINED)))
6913 {
6914 VARTYPE vt_userdefined = 0;
6915 const TYPEDESC *tdesc_userdefined = tdesc;
6916 if (tdesc->vt == VT_PTR)
6917 {
6918 vt_userdefined = VT_BYREF;
6919 tdesc_userdefined = tdesc->lptdesc;
6920 }
6921 hr = userdefined_to_variantvt(tinfo, tdesc_userdefined, &vt_userdefined);
6922 if ((hr == S_OK) &&
6923 (((vt_userdefined & VT_TYPEMASK) == VT_UNKNOWN) ||
6924 ((vt_userdefined & VT_TYPEMASK) == VT_DISPATCH)))
6925 {
6926 *vt |= vt_userdefined;
6927 return S_OK;
6928 }
6929 }
6930 *vt = VT_BYREF;
6931 }
6932
6933 switch (tdesc->vt)
6934 {
6935 case VT_HRESULT:
6936 *vt |= VT_ERROR;
6937 break;
6938 case VT_USERDEFINED:
6939 hr = userdefined_to_variantvt(tinfo, tdesc, vt);
6940 break;
6941 case VT_VOID:
6942 case VT_CARRAY:
6943 case VT_PTR:
6944 case VT_LPSTR:
6945 case VT_LPWSTR:
6946 ERR("cannot convert type %d into variant VT\n", tdesc->vt);
6948 break;
6949 case VT_SAFEARRAY:
6950 *vt |= VT_ARRAY;
6951 hr = typedescvt_to_variantvt(tinfo, tdesc->lptdesc, vt);
6952 break;
6953 case VT_INT:
6954 *vt |= VT_I4;
6955 break;
6956 case VT_UINT:
6957 *vt |= VT_UI4;
6958 break;
6959 default:
6960 *vt |= tdesc->vt;
6961 break;
6962 }
6963 return hr;
6964}
6965
6966static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
6967{
6968 ITypeInfo *tinfo2;
6969 TYPEATTR *tattr;
6970 HRESULT hres;
6971 int flags, i;
6972
6973 hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
6974 if(FAILED(hres))
6975 return hres;
6976
6977 hres = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
6978 if(FAILED(hres)) {
6979 ITypeInfo_Release(tinfo2);
6980 return hres;
6981 }
6982
6983 switch(tattr->typekind) {
6984 case TKIND_ALIAS:
6985 hres = get_iface_guid(tinfo2, tattr->tdescAlias.hreftype, guid);
6986 break;
6987
6988 case TKIND_INTERFACE:
6989 case TKIND_DISPATCH:
6990 *guid = tattr->guid;
6991 break;
6992
6993 case TKIND_COCLASS:
6994 for (i = 0; i < tattr->cImplTypes; i++)
6995 {
6996 ITypeInfo_GetImplTypeFlags(tinfo2, i, &flags);
6997 if (flags & IMPLTYPEFLAG_FDEFAULT)
6998 break;
6999 }
7000
7001 if (i == tattr->cImplTypes)
7002 i = 0;
7003
7004 hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href);
7005 if (SUCCEEDED(hres))
7006 hres = get_iface_guid(tinfo2, href, guid);
7007 break;
7008
7009 default:
7010 ERR("Unexpected typekind %d\n", tattr->typekind);
7012 }
7013
7014 ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
7015 ITypeInfo_Release(tinfo2);
7016 return hres;
7017}
7018
7019static inline BOOL func_restricted( const FUNCDESC *desc )
7020{
7021 return (desc->wFuncFlags & FUNCFLAG_FRESTRICTED) && (desc->memid >= 0);
7022}
7023
7024#define INVBUF_ELEMENT_SIZE \
7025 (sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *) + sizeof(VARTYPE))
7026#define INVBUF_GET_ARG_ARRAY(buffer, params) (buffer)
7027#define INVBUF_GET_MISSING_ARG_ARRAY(buffer, params) \
7028 ((VARIANTARG *)((char *)(buffer) + sizeof(VARIANTARG) * (params)))
7029#define INVBUF_GET_ARG_PTR_ARRAY(buffer, params) \
7030 ((VARIANTARG **)((char *)(buffer) + (sizeof(VARIANTARG) + sizeof(VARIANTARG)) * (params)))
7031#define INVBUF_GET_ARG_TYPE_ARRAY(buffer, params) \
7032 ((VARTYPE *)((char *)(buffer) + (sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *)) * (params)))
7033
7035 ITypeInfo2 *iface,
7036 VOID *pIUnk,
7037 MEMBERID memid,
7038 UINT16 wFlags,
7039 DISPPARAMS *pDispParams,
7040 VARIANT *pVarResult,
7041 EXCEPINFO *pExcepInfo,
7042 UINT *pArgErr)
7043{
7045 int i, j;
7046 unsigned int var_index;
7047 TYPEKIND type_kind;
7048 HRESULT hres;
7049 const TLBFuncDesc *pFuncInfo;
7050 UINT fdc;
7051
7052 TRACE("%p, %p, %ld, %#x, %p, %p, %p, %p.\n", iface, pIUnk, memid, wFlags, pDispParams,
7053 pVarResult, pExcepInfo, pArgErr);
7054
7055 if( This->typeattr.wTypeFlags & TYPEFLAG_FRESTRICTED )
7056 return DISP_E_MEMBERNOTFOUND;
7057
7058 if (!pDispParams)
7059 {
7060 ERR("NULL pDispParams not allowed\n");
7061 return E_INVALIDARG;
7062 }
7063
7064 dump_DispParms(pDispParams);
7065
7066 if (pDispParams->cNamedArgs > pDispParams->cArgs)
7067 {
7068 ERR("named argument array cannot be bigger than argument array (%d/%d)\n",
7069 pDispParams->cNamedArgs, pDispParams->cArgs);
7070 return E_INVALIDARG;
7071 }
7072
7073 /* we do this instead of using GetFuncDesc since it will return a fake
7074 * FUNCDESC for dispinterfaces and we want the real function description */
7075 for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
7076 pFuncInfo = &This->funcdescs[fdc];
7077 if ((memid == pFuncInfo->funcdesc.memid) &&
7078 (wFlags & pFuncInfo->funcdesc.invkind) &&
7079 !func_restricted( &pFuncInfo->funcdesc ))
7080 break;
7081 }
7082
7083 if (fdc < This->typeattr.cFuncs) {
7084 const FUNCDESC *func_desc = &pFuncInfo->funcdesc;
7085
7086 if (TRACE_ON(ole))
7087 {
7088 TRACE("invoking:\n");
7089 dump_TLBFuncDescOne(pFuncInfo);
7090 }
7091
7092 switch (func_desc->funckind) {
7093 case FUNC_PUREVIRTUAL:
7094 case FUNC_VIRTUAL: {
7095 void *buffer = calloc(func_desc->cParams, INVBUF_ELEMENT_SIZE);
7096 VARIANT varresult;
7097 VARIANT retval = {{{0}}}; /* pointer for storing byref retvals in */
7098 VARIANTARG **prgpvarg = INVBUF_GET_ARG_PTR_ARRAY(buffer, func_desc->cParams);
7099 VARIANTARG *rgvarg = INVBUF_GET_ARG_ARRAY(buffer, func_desc->cParams);
7100 VARTYPE *rgvt = INVBUF_GET_ARG_TYPE_ARRAY(buffer, func_desc->cParams);
7101 VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
7102 UINT cNamedArgs = pDispParams->cNamedArgs;
7103 DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs;
7104 UINT vargs_converted=0;
7105 SAFEARRAY *a;
7106
7107 hres = S_OK;
7108
7109 if (func_desc->invkind & (INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF))
7110 {
7111 if (!cNamedArgs || (rgdispidNamedArgs[0] != DISPID_PROPERTYPUT))
7112 {
7113 ERR("first named arg for property put invocation must be DISPID_PROPERTYPUT\n");
7115 goto func_fail;
7116 }
7117 }
7118
7119 if (func_desc->cParamsOpt < 0 && cNamedArgs)
7120 {
7121 ERR("functions with the vararg attribute do not support named arguments\n");
7123 goto func_fail;
7124 }
7125
7126 for (i = 0; i < func_desc->cParams; i++)
7127 {
7128 TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
7129 hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc, &rgvt[i]);
7130 if (FAILED(hres))
7131 goto func_fail;
7132 }
7133
7134 TRACE("changing args\n");
7135 for (i = 0; i < func_desc->cParams; i++)
7136 {
7137 USHORT wParamFlags = func_desc->lprgelemdescParam[i].paramdesc.wParamFlags;
7138 TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
7139 VARIANTARG *src_arg;
7140
7141 if (wParamFlags & PARAMFLAG_FLCID)
7142 {
7143 prgpvarg[i] = &rgvarg[i];
7144 V_VT(prgpvarg[i]) = VT_I4;
7145 V_I4(prgpvarg[i]) = This->pTypeLib->lcid;
7146 continue;
7147 }
7148
7149 src_arg = NULL;
7150
7151 for (j = 0; j < cNamedArgs; j++)
7152 {
7153 if (rgdispidNamedArgs[j] == i || (i == func_desc->cParams-1 && rgdispidNamedArgs[j] == DISPID_PROPERTYPUT))
7154 {
7155 src_arg = &pDispParams->rgvarg[j];
7156 break;
7157 }
7158 }
7159
7160 if (!src_arg && vargs_converted + cNamedArgs < pDispParams->cArgs)
7161 {
7162 src_arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
7163 vargs_converted++;
7164 }
7165
7166 if (wParamFlags & PARAMFLAG_FRETVAL)
7167 {
7168 /* under most conditions the caller is not allowed to
7169 * pass in a dispparam arg in the index of what would be
7170 * the retval parameter. however, there is an exception
7171 * where the extra parameter is used in an extra
7172 * IDispatch::Invoke below */
7173 if ((i < pDispParams->cArgs) &&
7174 ((func_desc->cParams != 1) || !pVarResult ||
7175 !(func_desc->invkind & INVOKE_PROPERTYGET)))
7176 {
7178 break;
7179 }
7180
7181 /* note: this check is placed so that if the caller passes
7182 * in a VARIANTARG for the retval we just ignore it, like
7183 * native does */
7184 if (i == func_desc->cParams - 1)
7185 {
7186 prgpvarg[i] = &rgvarg[i];
7187 V_BYREF(prgpvarg[i]) = &retval;
7188 V_VT(prgpvarg[i]) = rgvt[i];
7189 }
7190 else
7191 {
7192 ERR("[retval] parameter must be the last parameter of the method (%d/%d)\n", i, func_desc->cParams);
7194 break;
7195 }
7196 }
7197 else if (src_arg && !((wParamFlags & PARAMFLAG_FOPT) &&
7198 V_VT(src_arg) == VT_ERROR && V_ERROR(src_arg) == DISP_E_PARAMNOTFOUND))
7199 {
7200 TRACE("%s\n", debugstr_variant(src_arg));
7201
7202 if(rgvt[i]!=V_VT(src_arg))
7203 {
7204 if (rgvt[i] == VT_VARIANT)
7205 hres = VariantCopy(&rgvarg[i], src_arg);
7206 else if (rgvt[i] == (VT_VARIANT | VT_BYREF))
7207 {
7208 if (rgvt[i] == V_VT(src_arg))
7209 V_VARIANTREF(&rgvarg[i]) = V_VARIANTREF(src_arg);
7210 else
7211 {
7212 if (wParamFlags & PARAMFLAG_FIN)
7213 hres = VariantCopy(&missing_arg[i], src_arg);
7214 V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
7215 }
7216 V_VT(&rgvarg[i]) = rgvt[i];
7217 }
7218 else if ((rgvt[i] == (VT_VARIANT | VT_ARRAY) || rgvt[i] == (VT_VARIANT | VT_ARRAY | VT_BYREF)) && func_desc->cParamsOpt < 0)
7219 {
7220 SAFEARRAYBOUND bound;
7221 VARIANT *v;
7222
7223 bound.lLbound = 0;
7224 bound.cElements = pDispParams->cArgs-i;
7225 if (!(a = SafeArrayCreate(VT_VARIANT, 1, &bound)))
7226 {
7227 ERR("SafeArrayCreate failed\n");
7228 break;
7229 }
7231 if (hres != S_OK)
7232 {
7233 ERR("SafeArrayAccessData failed with %#lx.\n", hres);
7235 break;
7236 }
7237 for (j = 0; j < bound.cElements; j++)
7238 VariantCopy(&v[j], &pDispParams->rgvarg[pDispParams->cArgs - 1 - i - j]);
7240 if (hres != S_OK)
7241 {
7242 ERR("SafeArrayUnaccessData failed with %#lx.\n", hres);
7244 break;
7245 }
7246 if (rgvt[i] & VT_BYREF)
7247 V_BYREF(&rgvarg[i]) = &a;
7248 else
7249 V_ARRAY(&rgvarg[i]) = a;
7250 V_VT(&rgvarg[i]) = rgvt[i];
7251 }
7252 else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
7253 {
7254 if (wParamFlags & PARAMFLAG_FIN)
7255 hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
7256 else
7257 V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF;
7258 V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
7259 V_VT(&rgvarg[i]) = rgvt[i];
7260 }
7261 else if ((rgvt[i] & VT_BYREF) && (rgvt[i] == V_VT(src_arg)))
7262 {
7263 V_BYREF(&rgvarg[i]) = V_BYREF(src_arg);
7264 V_VT(&rgvarg[i]) = rgvt[i];
7265 }
7266 else
7267 {
7268 /* FIXME: this doesn't work for VT_BYREF arguments if
7269 * they are not the same type as in the paramdesc */
7270 V_VT(&rgvarg[i]) = V_VT(src_arg);
7271 hres = VariantChangeType(&rgvarg[i], src_arg, 0, rgvt[i]);
7272 V_VT(&rgvarg[i]) = rgvt[i];
7273 }
7274
7275 if (FAILED(hres))
7276 {
7277 ERR("failed to convert param %d to %s from %s\n", i,
7278 debugstr_vt(rgvt[i]), debugstr_variant(src_arg));
7279 break;
7280 }
7281 prgpvarg[i] = &rgvarg[i];
7282 }
7283 else
7284 {
7285 prgpvarg[i] = src_arg;
7286 }
7287
7288 if((tdesc->vt == VT_USERDEFINED || (tdesc->vt == VT_PTR && tdesc->lptdesc->vt == VT_USERDEFINED))
7289 && (V_VT(prgpvarg[i]) == VT_DISPATCH || V_VT(prgpvarg[i]) == VT_UNKNOWN)
7290 && V_UNKNOWN(prgpvarg[i])) {
7291 IUnknown *userdefined_iface;
7292 GUID guid;
7293
7294 if (tdesc->vt == VT_PTR)
7295 tdesc = tdesc->lptdesc;
7296
7297 hres = get_iface_guid((ITypeInfo*)iface, tdesc->hreftype, &guid);
7298 if(FAILED(hres))
7299 break;
7300
7301 hres = IUnknown_QueryInterface(V_UNKNOWN(prgpvarg[i]), &guid, (void**)&userdefined_iface);
7302 if(FAILED(hres)) {
7303 ERR("argument does not support %s interface\n", debugstr_guid(&guid));
7304 break;
7305 }
7306
7307 IUnknown_Release(V_UNKNOWN(prgpvarg[i]));
7308 V_UNKNOWN(prgpvarg[i]) = userdefined_iface;
7309 }
7310 }
7311 else if (wParamFlags & PARAMFLAG_FOPT)
7312 {
7313 VARIANTARG *arg;
7314 arg = prgpvarg[i] = &rgvarg[i];
7315 if (wParamFlags & PARAMFLAG_FHASDEFAULT)
7316 {
7317 hres = VariantCopy(arg, &func_desc->lprgelemdescParam[i].paramdesc.pparamdescex->varDefaultValue);
7318 if (FAILED(hres))
7319 break;
7320 }
7321 else
7322 {
7323 /* if the function wants a pointer to a variant then
7324 * set that up, otherwise just pass the VT_ERROR in
7325 * the argument by value */
7326 if (rgvt[i] & VT_BYREF)
7327 {
7328 V_VT(&missing_arg[i]) = VT_ERROR;
7329 V_ERROR(&missing_arg[i]) = DISP_E_PARAMNOTFOUND;
7330
7332 V_VARIANTREF(arg) = &missing_arg[i];
7333 }
7334 else
7335 {
7336 V_VT(arg) = VT_ERROR;
7338 }
7339 }
7340 }
7341 else if (func_desc->cParamsOpt < 0 && ((rgvt[i] & ~VT_BYREF) == (VT_VARIANT | VT_ARRAY)))
7342 {
7344 if (FAILED(hres)) break;
7345 if (rgvt[i] & VT_BYREF)
7346 V_BYREF(&rgvarg[i]) = &a;
7347 else
7348 V_ARRAY(&rgvarg[i]) = a;
7349 V_VT(&rgvarg[i]) = rgvt[i];
7350 prgpvarg[i] = &rgvarg[i];
7351 }
7352 else
7353 {
7355 break;
7356 }
7357 }
7358 if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
7359
7360 /* VT_VOID is a special case for return types, so it is not
7361 * handled in the general function */
7362 if (func_desc->elemdescFunc.tdesc.vt == VT_VOID)
7363 V_VT(&varresult) = VT_EMPTY;
7364 else
7365 {
7366 V_VT(&varresult) = 0;
7367 hres = typedescvt_to_variantvt((ITypeInfo *)iface, &func_desc->elemdescFunc.tdesc, &V_VT(&varresult));
7368 if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
7369 }
7370
7371 hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, func_desc->callconv,
7372 V_VT(&varresult), func_desc->cParams, rgvt,
7373 prgpvarg, &varresult);
7374
7375 vargs_converted = 0;
7376
7377 for (i = 0; i < func_desc->cParams; i++)
7378 {
7379 USHORT wParamFlags = func_desc->lprgelemdescParam[i].paramdesc.wParamFlags;
7380
7381 if (wParamFlags & PARAMFLAG_FLCID)
7382 continue;
7383 else if (wParamFlags & PARAMFLAG_FRETVAL)
7384 {
7385 TRACE("[retval] value: %s\n", debugstr_variant(prgpvarg[i]));
7386
7387 if (pVarResult)
7388 {
7389 VariantInit(pVarResult);
7390 /* deref return value */
7391 hres = VariantCopyInd(pVarResult, prgpvarg[i]);
7392 }
7393
7394 VARIANT_ClearInd(prgpvarg[i]);
7395 }
7396 else if (vargs_converted < pDispParams->cArgs)
7397 {
7398 VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
7399 if (wParamFlags & PARAMFLAG_FOUT)
7400 {
7401 if ((rgvt[i] & VT_BYREF) && !(V_VT(arg) & VT_BYREF))
7402 {
7403 hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg));
7404
7405 if (FAILED(hres))
7406 {
7407 ERR("failed to convert param %d to vt %d\n", i,
7408 V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
7409 break;
7410 }
7411 }
7412 }
7413 else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
7414 func_desc->cParamsOpt < 0 &&
7415 i == func_desc->cParams-1)
7416 {
7417 SAFEARRAY *a = V_ARRAY(prgpvarg[i]);
7418 LONG ubound;
7419 VARIANT *v;
7420 hres = SafeArrayGetUBound(a, 1, &ubound);
7421 if (hres != S_OK)
7422 {
7423 ERR("SafeArrayGetUBound failed with %#lx.\n", hres);
7424 break;
7425 }
7427 if (hres != S_OK)
7428 {
7429 ERR("SafeArrayAccessData failed with %#lx.\n", hres);
7430 break;
7431 }
7432 for (j = 0; j <= ubound; j++)
7433 VariantClear(&v[j]);
7435 if (hres != S_OK)
7436 {
7437 ERR("SafeArrayUnaccessData failed with %#lx.\n", hres);
7438 break;
7439 }
7440 }
7441 VariantClear(&rgvarg[i]);
7442 vargs_converted++;
7443 }
7444 else if (wParamFlags & PARAMFLAG_FOPT)
7445 {
7446 if (wParamFlags & PARAMFLAG_FHASDEFAULT)
7447 VariantClear(&rgvarg[i]);
7448 }
7449
7450 VariantClear(&missing_arg[i]);
7451 }
7452
7453 if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
7454 {
7455 WARN("invoked function failed with error %#lx.\n", V_ERROR(&varresult));
7457 if (pExcepInfo)
7458 {
7459 IErrorInfo *pErrorInfo;
7460 pExcepInfo->scode = V_ERROR(&varresult);
7461 if (GetErrorInfo(0, &pErrorInfo) == S_OK)
7462 {
7463 IErrorInfo_GetDescription(pErrorInfo, &pExcepInfo->bstrDescription);
7464 IErrorInfo_GetHelpFile(pErrorInfo, &pExcepInfo->bstrHelpFile);
7465 IErrorInfo_GetSource(pErrorInfo, &pExcepInfo->bstrSource);
7466 IErrorInfo_GetHelpContext(pErrorInfo, &pExcepInfo->dwHelpContext);
7467
7468 IErrorInfo_Release(pErrorInfo);
7469 }
7470 }
7471 }
7472 if (V_VT(&varresult) != VT_ERROR)
7473 {
7474 TRACE("varresult value: %s\n", debugstr_variant(&varresult));
7475
7476 if (pVarResult)
7477 {
7478 VariantClear(pVarResult);
7479 *pVarResult = varresult;
7480 }
7481 else
7482 VariantClear(&varresult);
7483 }
7484
7485 if (SUCCEEDED(hres) && pVarResult && (func_desc->cParams == 1) &&
7486 (func_desc->invkind & INVOKE_PROPERTYGET) &&
7487 (func_desc->lprgelemdescParam[0].paramdesc.wParamFlags & PARAMFLAG_FRETVAL) &&
7488 (pDispParams->cArgs != 0))
7489 {
7490 if (V_VT(pVarResult) == VT_DISPATCH)
7491 {
7492 IDispatch *pDispatch = V_DISPATCH(pVarResult);
7493 /* Note: not VariantClear; we still need the dispatch
7494 * pointer to be valid */
7495 VariantInit(pVarResult);
7496 hres = IDispatch_Invoke(pDispatch, DISPID_VALUE, &IID_NULL,
7498 pDispParams, pVarResult, pExcepInfo, pArgErr);
7499 IDispatch_Release(pDispatch);
7500 }
7501 else
7502 {
7503 VariantClear(pVarResult);
7505 }
7506 }
7507
7508func_fail:
7509 free(buffer);
7510 break;
7511 }
7512 case FUNC_DISPATCH: {
7513 IDispatch *disp;
7514
7515 hres = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp);
7516 if (SUCCEEDED(hres)) {
7517 FIXME("Calling Invoke in IDispatch iface. untested!\n");
7518 hres = IDispatch_Invoke(
7519 disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,wFlags,pDispParams,
7520 pVarResult,pExcepInfo,pArgErr
7521 );
7522 if (FAILED(hres))
7523 FIXME("IDispatch::Invoke failed with %#lx. (Could be not a real error?)\n", hres);
7524 IDispatch_Release(disp);
7525 } else
7526 FIXME("FUNC_DISPATCH used on object without IDispatch iface?\n");
7527 break;
7528 }
7529 default:
7530 FIXME("Unknown function invocation type %d\n", func_desc->funckind);
7531 hres = E_FAIL;
7532 break;
7533 }
7534
7535 TRACE("-- %#lx\n", hres);
7536 return hres;
7537
7538 } else if(SUCCEEDED(hres = ITypeInfo2_GetVarIndexOfMemId(iface, memid, &var_index))) {
7539 VARDESC *var_desc;
7540
7541 hres = ITypeInfo2_GetVarDesc(iface, var_index, &var_desc);
7542 if(FAILED(hres)) return hres;
7543
7544 FIXME("varseek: Found memid, but variable-based invoking not supported\n");
7545 dump_VARDESC(var_desc);
7546 ITypeInfo2_ReleaseVarDesc(iface, var_desc);
7547 return E_NOTIMPL;
7548 }
7549
7550 /* not found, check for special error cases */
7551 for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc)
7552 {
7553 const FUNCDESC *func_desc = &This->funcdescs[fdc].funcdesc;
7554 if (memid == func_desc->memid)
7555 {
7556 if ((wFlags & INVOKE_PROPERTYPUT) && (func_desc->invkind & INVOKE_PROPERTYGET))
7557 {
7558 int count_inputs = 0;
7559 for (i = 0; i < func_desc->cParams; i++)
7560 {
7561 USHORT wParamFlags = func_desc->lprgelemdescParam[i].paramdesc.wParamFlags;
7562 if (!(wParamFlags & PARAMFLAG_FRETVAL))
7563 count_inputs++;
7564 }
7565
7566 if (count_inputs == 0 || pDispParams->cArgs == count_inputs + 1)
7567 return DISP_E_BADPARAMCOUNT;
7568 }
7569 }
7570 }
7571
7572 /* not found, look for it in inherited interfaces */
7573 ITypeInfo2_GetTypeKind(iface, &type_kind);
7575 if(This->impltypes) {
7576 /* recursive search */
7577 ITypeInfo *pTInfo;
7578 hres = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
7579 if(SUCCEEDED(hres)){
7580 hres = ITypeInfo_Invoke(pTInfo,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr);
7581 ITypeInfo_Release(pTInfo);
7582 return hres;
7583 }
7584 WARN("Could not search inherited interface!\n");
7585 }
7586 }
7587 WARN("did not find member id %ld, flags 0x%x!\n", memid, wFlags);
7588 return DISP_E_MEMBERNOTFOUND;
7589}
7590
7591/* ITypeInfo::GetDocumentation
7592 *
7593 * Retrieves the documentation string, the complete Help file name and path,
7594 * and the context ID for the Help topic for a specified type description.
7595 *
7596 * (Can be tested by the Visual Basic Editor in Word for instance.)
7597 */
7599 MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
7600 DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
7601{
7603 const TLBFuncDesc *pFDesc;
7604 const TLBVarDesc *pVDesc;
7605 TRACE("%p, %ld, %p, %p, %p, %p.\n",
7606 iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
7607 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
7608 if(pBstrName)
7609 *pBstrName=SysAllocString(TLB_get_bstr(This->Name));
7610 if(pBstrDocString)
7611 *pBstrDocString=SysAllocString(TLB_get_bstr(This->DocString));
7612 if(pdwHelpContext)
7613 *pdwHelpContext=This->dwHelpContext;
7614 if(pBstrHelpFile)
7615 *pBstrHelpFile=SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
7616 return S_OK;
7617 }else {/* for a member */
7618 pFDesc = TLB_get_funcdesc_by_memberid(This, memid);
7619 if(pFDesc){
7620 if(pBstrName)
7621 *pBstrName = SysAllocString(TLB_get_bstr(pFDesc->Name));
7622 if(pBstrDocString)
7623 *pBstrDocString=SysAllocString(TLB_get_bstr(pFDesc->HelpString));
7624 if(pdwHelpContext)
7625 *pdwHelpContext=pFDesc->helpcontext;
7626 if(pBstrHelpFile)
7627 *pBstrHelpFile = SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
7628 return S_OK;
7629 }
7630 pVDesc = TLB_get_vardesc_by_memberid(This, memid);
7631 if(pVDesc){
7632 if(pBstrName)
7633 *pBstrName = SysAllocString(TLB_get_bstr(pVDesc->Name));
7634 if(pBstrDocString)
7635 *pBstrDocString=SysAllocString(TLB_get_bstr(pVDesc->HelpString));
7636 if(pdwHelpContext)
7637 *pdwHelpContext=pVDesc->HelpContext;
7638 if(pBstrHelpFile)
7639 *pBstrHelpFile = SysAllocString(TLB_get_bstr(This->pTypeLib->HelpFile));
7640 return S_OK;
7641 }
7642 }
7643
7644 if(This->impltypes &&
7645 (This->typeattr.typekind == TKIND_INTERFACE || This->typeattr.typekind == TKIND_DISPATCH)) {
7646 /* recursive search */
7647 ITypeInfo *pTInfo;
7649 result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo);
7650 if(SUCCEEDED(result)) {
7651 result = ITypeInfo_GetDocumentation(pTInfo, memid, pBstrName,
7652 pBstrDocString, pdwHelpContext, pBstrHelpFile);
7653 ITypeInfo_Release(pTInfo);
7654 return result;
7655 }
7656 WARN("Could not search inherited interface!\n");
7657 }
7658
7659 WARN("member %ld not found\n", memid);
7661}
7662
7663/* ITypeInfo::GetDllEntry
7664 *
7665 * Retrieves a description or specification of an entry point for a function
7666 * in a DLL.
7667 */
7668static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid,
7669 INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
7670 WORD *pwOrdinal)
7671{
7673 const TLBFuncDesc *pFDesc;
7674
7675 TRACE("%p, %#lx, %d, %p, %p, %p.\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
7676
7677 if (pBstrDllName) *pBstrDllName = NULL;
7678 if (pBstrName) *pBstrName = NULL;
7679 if (pwOrdinal) *pwOrdinal = 0;
7680
7681 if (This->typeattr.typekind != TKIND_MODULE)
7682 return TYPE_E_BADMODULEKIND;
7683
7684 pFDesc = TLB_get_funcdesc_by_memberid_invkind(This, memid, invKind);
7685 if (!pFDesc) return TYPE_E_ELEMENTNOTFOUND;
7686
7688 if (TRACE_ON(ole)) dump_TLBFuncDescOne(pFDesc);
7689
7690 if (pBstrDllName) *pBstrDllName = SysAllocString(TLB_get_bstr(This->DllName));
7691
7692 if (!IS_INTRESOURCE(pFDesc->Entry) && (pFDesc->Entry != (void*)-1))
7693 {
7694 if (pBstrName) *pBstrName = SysAllocString(TLB_get_bstr(pFDesc->Entry));
7695 if (pwOrdinal) *pwOrdinal = -1;
7696 }
7697 else
7698 {
7699 if (pBstrName) *pBstrName = NULL;
7700 if (pwOrdinal) *pwOrdinal = LOWORD(pFDesc->Entry);
7701 }
7702 return S_OK;
7703}
7704
7705/* internal function to make the inherited interfaces' methods appear
7706 * part of the interface */
7708 HREFTYPE *hRefType, ITypeInfo **ppTInfo)
7709{
7711 HRESULT hr;
7712
7713 TRACE("%p, %#lx.\n", iface, *hRefType);
7714
7715 if (This->impltypes && (*hRefType & DISPATCH_HREF_MASK))
7716 {
7717 ITypeInfo *pSubTypeInfo;
7718
7719 hr = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pSubTypeInfo);
7720 if (FAILED(hr))
7721 return hr;
7722
7724 hRefType, ppTInfo);
7725 ITypeInfo_Release(pSubTypeInfo);
7726 if (SUCCEEDED(hr))
7727 return hr;
7728 }
7729 *hRefType -= DISPATCH_HREF_OFFSET;
7730
7731 if (!(*hRefType & DISPATCH_HREF_MASK))
7732 return ITypeInfo_GetRefTypeInfo(iface, *hRefType, ppTInfo);
7733 else
7734 return E_FAIL;
7735}
7736
7737/* ITypeInfo::GetRefTypeInfo
7738 *
7739 * If a type description references other type descriptions, it retrieves
7740 * the referenced type descriptions.
7741 */
7743 ITypeInfo2 *iface,
7744 HREFTYPE hRefType,
7745 ITypeInfo **ppTInfo)
7746{
7750 TLBRefType *ref_type;
7751 UINT i;
7752
7753 if(!ppTInfo)
7754 return E_INVALIDARG;
7755
7756 if ((INT)hRefType < 0) {
7757 ITypeInfoImpl *pTypeInfoImpl;
7758
7759 if (!(This->typeattr.wTypeFlags & TYPEFLAG_FDUAL) ||
7760 !(This->typeattr.typekind == TKIND_INTERFACE ||
7761 This->typeattr.typekind == TKIND_DISPATCH))
7763
7764 /* when we meet a DUAL typeinfo, we must create the alternate
7765 * version of it.
7766 */
7767 pTypeInfoImpl = ITypeInfoImpl_Constructor();
7768
7769 *pTypeInfoImpl = *This;
7770 pTypeInfoImpl->ref = 0;
7771 list_init(&pTypeInfoImpl->custdata_list);
7772
7773 if (This->typeattr.typekind == TKIND_INTERFACE)
7774 pTypeInfoImpl->typeattr.typekind = TKIND_DISPATCH;
7775 else
7776 pTypeInfoImpl->typeattr.typekind = TKIND_INTERFACE;
7777
7778 *ppTInfo = (ITypeInfo *)&pTypeInfoImpl->ITypeInfo2_iface;
7779 /* the AddRef implicitly adds a reference to the parent typelib, which
7780 * stops the copied data from being destroyed until the new typeinfo's
7781 * refcount goes to zero, but we need to signal to the new instance to
7782 * not free its data structures when it is destroyed */
7783 pTypeInfoImpl->not_attached_to_typelib = TRUE;
7784 ITypeInfo_AddRef(*ppTInfo);
7785
7786 TRACE("got dual interface %p\n", *ppTInfo);
7787 return S_OK;
7788 }
7789
7790 if ((hRefType & DISPATCH_HREF_MASK) && (This->typeattr.typekind == TKIND_DISPATCH))
7791 return ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &hRefType, ppTInfo);
7792
7793 if(!(hRefType & 0x1))
7794 {
7795 for(i = 0; i < This->pTypeLib->TypeInfoCount; ++i)
7796 {
7797 if (This->pTypeLib->typeinfos[i]->hreftype == (hRefType&(~0x3)))
7798 {
7799 result = S_OK;
7800 type_info = (ITypeInfo*)&This->pTypeLib->typeinfos[i]->ITypeInfo2_iface;
7801 ITypeInfo_AddRef(type_info);
7802 break;
7803 }
7804 }
7805 }
7806
7807 if (!type_info)
7808 {
7809 ITypeLib *pTLib = NULL;
7810
7811 LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry)
7812 {
7813 if(ref_type->reference == (hRefType & (~0x3)))
7814 break;
7815 }
7816 if(&ref_type->entry == &This->pTypeLib->ref_list)
7817 {
7818 FIXME("Can't find pRefType for ref %lx\n", hRefType);
7819 return E_FAIL;
7820 }
7821
7822 if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) {
7823 UINT Index;
7824 TRACE("internal reference\n");
7825 result = ITypeInfo2_GetContainingTypeLib(iface, &pTLib, &Index);
7826 } else {
7827 if(ref_type->pImpTLInfo->pImpTypeLib) {
7828 TRACE("typeinfo in imported typelib that is already loaded\n");
7829 pTLib = (ITypeLib*)&ref_type->pImpTLInfo->pImpTypeLib->ITypeLib2_iface;
7830 ITypeLib_AddRef(pTLib);
7831 result = S_OK;
7832 } else {
7833 /* Search in cached typelibs */
7835
7838 {
7839 if (entry->guid
7840 && IsEqualIID(&entry->guid->guid, TLB_get_guid_null(ref_type->pImpTLInfo->guid))
7841 && entry->ver_major == ref_type->pImpTLInfo->wVersionMajor
7842 && entry->ver_minor == ref_type->pImpTLInfo->wVersionMinor
7843 && entry->set_lcid == ref_type->pImpTLInfo->lcid)
7844 {
7845 TRACE("got cached %p\n", entry);
7846 pTLib = (ITypeLib*)&entry->ITypeLib2_iface;
7847 ITypeLib_AddRef(pTLib);
7848 result = S_OK;
7849 break;
7850 }
7851 }
7853
7854 if (!pTLib)
7855 {
7856 BSTR libnam;
7857
7858 /* Search on disk */
7860 ref_type->pImpTLInfo->wVersionMajor,
7861 ref_type->pImpTLInfo->wVersionMinor,
7862 This->pTypeLib->syskind,
7863 ref_type->pImpTLInfo->lcid, &libnam, TRUE);
7864 if (FAILED(result))
7865 libnam = SysAllocString(ref_type->pImpTLInfo->name);
7866
7867 result = LoadTypeLib(libnam, &pTLib);
7868 SysFreeString(libnam);
7869 }
7870
7871 if(SUCCEEDED(result)) {
7872 ref_type->pImpTLInfo->pImpTypeLib = impl_from_ITypeLib(pTLib);
7873 ITypeLib_AddRef(pTLib);
7874 }
7875 }
7876 }
7877 if(SUCCEEDED(result)) {
7878 if(ref_type->index == TLB_REF_USE_GUID)
7879 result = ITypeLib_GetTypeInfoOfGuid(pTLib, TLB_get_guid_null(ref_type->guid), &type_info);
7880 else
7881 result = ITypeLib_GetTypeInfo(pTLib, ref_type->index, &type_info);
7882 }
7883 if (pTLib != NULL)
7884 ITypeLib_Release(pTLib);
7885 if (FAILED(result))
7886 {
7887 WARN("(%p) failed hreftype %#lx.\n", iface, hRefType);
7888 return result;
7889 }
7890 }
7891
7892 if ((hRefType & 0x2) && SUCCEEDED(ITypeInfo_GetRefTypeInfo(type_info, -2, ppTInfo)))
7893 ITypeInfo_Release(type_info);
7894 else *ppTInfo = type_info;
7895
7896 TRACE("%p, hreftype %#lx, loaded %s (%p)\n", iface, hRefType,
7897 SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
7898 return result;
7899}
7900
7901/* ITypeInfo::AddressOfMember
7902 *
7903 * Retrieves the addresses of static functions or variables, such as those
7904 * defined in a DLL.
7905 */
7907 MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
7908{
7909 HRESULT hr;
7910 BSTR dll, entry;
7911 WORD ordinal;
7913
7914 TRACE("%p, %lx, %#x, %p.\n", iface, memid, invKind, ppv);
7915
7916 hr = ITypeInfo2_GetDllEntry(iface, memid, invKind, &dll, &entry, &ordinal);
7917 if (FAILED(hr))
7918 return hr;
7919
7920 module = LoadLibraryW(dll);
7921 if (!module)
7922 {
7923 ERR("couldn't load %s\n", debugstr_w(dll));
7924 SysFreeString(dll);
7926 return STG_E_FILENOTFOUND;
7927 }
7928 /* FIXME: store library somewhere where we can free it */
7929
7930 if (entry)
7931 {
7932 LPSTR entryA;
7934 entryA = malloc(len);
7935 WideCharToMultiByte(CP_ACP, 0, entry, -1, entryA, len, NULL, NULL);
7936
7937 *ppv = GetProcAddress(module, entryA);
7938 if (!*ppv)
7939 ERR("function not found %s\n", debugstr_a(entryA));
7940
7941 free(entryA);
7942 }
7943 else
7944 {
7946 if (!*ppv)
7947 ERR("function not found %d\n", ordinal);
7948 }
7949
7950 SysFreeString(dll);
7952
7953 if (!*ppv)
7955
7956 return S_OK;
7957}
7958
7959/* ITypeInfo::CreateInstance
7960 *
7961 * Creates a new instance of a type that describes a component object class
7962 * (coclass).
7963 */
7965 IUnknown *pOuterUnk, REFIID riid, VOID **ppvObj)
7966{
7968 HRESULT hr;
7969 TYPEATTR *pTA;
7970
7971 TRACE("(%p)->(%p, %s, %p)\n", This, pOuterUnk, debugstr_guid(riid), ppvObj);
7972
7973 *ppvObj = NULL;
7974
7975 if(pOuterUnk)
7976 {
7977 WARN("Not able to aggregate\n");
7978 return CLASS_E_NOAGGREGATION;
7979 }
7980
7981 hr = ITypeInfo2_GetTypeAttr(iface, &pTA);
7982 if(FAILED(hr)) return hr;
7983
7984 if(pTA->typekind != TKIND_COCLASS)
7985 {
7986 WARN("CreateInstance on typeinfo of type %x\n", pTA->typekind);
7987 hr = E_INVALIDARG;
7988 goto end;
7989 }
7990
7991 hr = S_FALSE;
7992 if(pTA->wTypeFlags & TYPEFLAG_FAPPOBJECT)
7993 {
7994 IUnknown *pUnk;
7995 hr = GetActiveObject(&pTA->guid, NULL, &pUnk);
7996 TRACE("GetActiveObject rets %#lx.\n", hr);
7997 if(hr == S_OK)
7998 {
7999 hr = IUnknown_QueryInterface(pUnk, riid, ppvObj);
8000 IUnknown_Release(pUnk);
8001 }
8002 }
8003
8004 if(hr != S_OK)
8005 hr = CoCreateInstance(&pTA->guid, NULL,
8006 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
8007 riid, ppvObj);
8008
8009end:
8010 ITypeInfo2_ReleaseTypeAttr(iface, pTA);
8011 return hr;
8012}
8013
8014/* ITypeInfo::GetMops
8015 *
8016 * Retrieves marshalling information.
8017 */
8018static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid, BSTR *pBstrMops)
8019{
8020 FIXME("%p, %ld stub!\n", iface, memid);
8021 *pBstrMops = NULL;
8022 return S_OK;
8023}
8024
8025/* ITypeInfo::GetContainingTypeLib
8026 *
8027 * Retrieves the containing type library and the index of the type description
8028 * within that type library.
8029 */
8031 ITypeLib * *ppTLib, UINT *pIndex)
8032{
8034
8035 /* If a pointer is null, we simply ignore it, the ATL in particular passes pIndex as 0 */
8036 if (pIndex) {
8037 *pIndex=This->index;
8038 TRACE("returning pIndex=%d\n", *pIndex);
8039 }
8040
8041 if (ppTLib) {
8042 *ppTLib = (ITypeLib *)&This->pTypeLib->ITypeLib2_iface;
8043 ITypeLib_AddRef(*ppTLib);
8044 TRACE("returning ppTLib=%p\n", *ppTLib);
8045 }
8046
8047 return S_OK;
8048}
8049
8050/* ITypeInfo::ReleaseTypeAttr
8051 *
8052 * Releases a TYPEATTR previously returned by Get
8053 *
8054 */
8056 TYPEATTR* pTypeAttr)
8057{
8059 TRACE("(%p)->(%p)\n", This, pTypeAttr);
8060 free(pTypeAttr);
8061}
8062
8063/* ITypeInfo::ReleaseFuncDesc
8064 *
8065 * Releases a FUNCDESC previously returned by GetFuncDesc. *
8066 */
8068 ITypeInfo2 *iface,
8069 FUNCDESC *pFuncDesc)
8070{
8072 SHORT i;
8073
8074 TRACE("(%p)->(%p)\n", This, pFuncDesc);
8075
8076 for (i = 0; i < pFuncDesc->cParams; i++)
8077 TLB_FreeElemDesc(&pFuncDesc->lprgelemdescParam[i]);
8078 TLB_FreeElemDesc(&pFuncDesc->elemdescFunc);
8079
8080 SysFreeString((BSTR)pFuncDesc);
8081}
8082
8083/* ITypeInfo::ReleaseVarDesc
8084 *
8085 * Releases a VARDESC previously returned by GetVarDesc.
8086 */
8088 VARDESC *pVarDesc)
8089{
8091 TRACE("(%p)->(%p)\n", This, pVarDesc);
8092
8093 TLB_FreeVarDesc(pVarDesc);
8094}
8095
8096/* ITypeInfo2::GetTypeKind
8097 *
8098 * Returns the TYPEKIND enumeration quickly, without doing any allocations.
8099 *
8100 */
8102 TYPEKIND *pTypeKind)
8103{
8105 *pTypeKind = This->typeattr.typekind;
8106 TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
8107 return S_OK;
8108}
8109
8110/* ITypeInfo2::GetTypeFlags
8111 *
8112 * Returns the type flags without any allocations. This returns a DWORD type
8113 * flag, which expands the type flags without growing the TYPEATTR (type
8114 * attribute).
8115 *
8116 */
8118{
8120 TRACE("%p, %p.\n", iface, pTypeFlags);
8121 *pTypeFlags=This->typeattr.wTypeFlags;
8122 return S_OK;
8123}
8124
8125/* ITypeInfo2::GetFuncIndexOfMemId
8126 * Binds to a specific member based on a known DISPID, where the member name
8127 * is not known (for example, when binding to a default member).
8128 *
8129 */
8131 MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
8132{
8134 UINT fdc;
8136
8137 for (fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
8138 const TLBFuncDesc *pFuncInfo = &This->funcdescs[fdc];
8139 if(memid == pFuncInfo->funcdesc.memid && (invKind & pFuncInfo->funcdesc.invkind))
8140 break;
8141 }
8142 if(fdc < This->typeattr.cFuncs) {
8143 *pFuncIndex = fdc;
8144 result = S_OK;
8145 } else
8147
8148 TRACE("%p, %#lx, %#x, hr %#lx.\n", iface, memid, invKind, result);
8149 return result;
8150}
8151
8152/* TypeInfo2::GetVarIndexOfMemId
8153 *
8154 * Binds to a specific member based on a known DISPID, where the member name
8155 * is not known (for example, when binding to a default member).
8156 *
8157 */
8159 MEMBERID memid, UINT *pVarIndex)
8160{
8162 TLBVarDesc *pVarInfo;
8163
8164 TRACE("%p, %ld, %p.\n", iface, memid, pVarIndex);
8165
8166 pVarInfo = TLB_get_vardesc_by_memberid(This, memid);
8167 if(!pVarInfo)
8169
8170 *pVarIndex = (pVarInfo - This->vardescs);
8171
8172 return S_OK;
8173}
8174
8175/* ITypeInfo2::GetCustData
8176 *
8177 * Gets the custom data
8178 */
8180 ITypeInfo2 * iface,
8181 REFGUID guid,
8182 VARIANT *pVarVal)
8183{
8185 TLBCustData *pCData;
8186
8187 TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal);
8188
8189 if(!guid || !pVarVal)
8190 return E_INVALIDARG;
8191
8192 pCData = TLB_get_custdata_by_guid(This->pcustdata_list, guid);
8193
8194 VariantInit( pVarVal);
8195 if (pCData)
8196 VariantCopy( pVarVal, &pCData->data);
8197 else
8198 VariantClear( pVarVal );
8199 return S_OK;
8200}
8201
8202/* ITypeInfo2::GetFuncCustData
8203 *
8204 * Gets the custom data
8205 */
8207 ITypeInfo2 * iface,
8208 UINT index,
8209 REFGUID guid,
8210 VARIANT *pVarVal)
8211{
8213 const TLBFuncDesc *desc;
8215 UINT hrefoffset;
8216 HRESULT hr;
8217
8218 TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal);
8219
8220 hr = ITypeInfoImpl_GetInternalFuncDesc((ITypeInfo *)iface, index, &desc, &hrefoffset);
8221 if (FAILED(hr))
8222 {
8223 WARN("description for function %d not found\n", index);
8224 return hr;
8225 }
8226
8227 VariantInit(pVarVal);
8228 data = TLB_get_custdata_by_guid(&desc->custdata_list, guid);
8229 return data ? VariantCopy(pVarVal, &data->data) : S_OK;
8230}
8231
8232/* ITypeInfo2::GetParamCustData
8233 *
8234 * Gets the custom data
8235 */
8237 ITypeInfo2 * iface,
8238 UINT indexFunc,
8239 UINT indexParam,
8240 REFGUID guid,
8241 VARIANT *pVarVal)
8242{
8244 const TLBFuncDesc *pFDesc;
8245 TLBCustData *pCData;
8246 UINT hrefoffset;
8247 HRESULT hr;
8248
8249 TRACE("%p %u %u %s %p\n", This, indexFunc, indexParam,
8250 debugstr_guid(guid), pVarVal);
8251
8252 hr = ITypeInfoImpl_GetInternalFuncDesc((ITypeInfo *)iface, indexFunc, &pFDesc, &hrefoffset);
8253 if (FAILED(hr))
8254 return hr;
8255
8256 if(indexParam >= pFDesc->funcdesc.cParams)
8258
8259 pCData = TLB_get_custdata_by_guid(&pFDesc->pParamDesc[indexParam].custdata_list, guid);
8260 if(!pCData)
8262
8263 VariantInit(pVarVal);
8264 VariantCopy(pVarVal, &pCData->data);
8265
8266 return S_OK;
8267}
8268
8269/* ITypeInfo2::GetVarCustData
8270 *
8271 * Gets the custom data
8272 */
8274 ITypeInfo2 * iface,
8275 UINT index,
8276 REFGUID guid,
8277 VARIANT *pVarVal)
8278{
8280 TLBCustData *pCData;
8281 TLBVarDesc *pVDesc = &This->vardescs[index];
8282
8283 TRACE("%p %s %p\n", This, debugstr_guid(guid), pVarVal);
8284
8285 if(index >= This->typeattr.cVars)
8287
8288 pCData = TLB_get_custdata_by_guid(&pVDesc->custdata_list, guid);
8289 if(!pCData)
8291
8292 VariantInit(pVarVal);
8293 VariantCopy(pVarVal, &pCData->data);
8294
8295 return S_OK;
8296}
8297
8298/* ITypeInfo2::GetImplCustData
8299 *
8300 * Gets the custom data
8301 */
8303 ITypeInfo2 * iface,
8304 UINT index,
8305 REFGUID guid,
8306 VARIANT *pVarVal)
8307{
8309 TLBCustData *pCData;
8310 TLBImplType *pRDesc = &This->impltypes[index];
8311
8312 TRACE("%p %u %s %p\n", This, index, debugstr_guid(guid), pVarVal);
8313
8314 if(index >= This->typeattr.cImplTypes)
8316
8317 pCData = TLB_get_custdata_by_guid(&pRDesc->custdata_list, guid);
8318 if(!pCData)
8320
8321 VariantInit(pVarVal);
8322 VariantCopy(pVarVal, &pCData->data);
8323
8324 return S_OK;
8325}
8326
8327/* ITypeInfo2::GetDocumentation2
8328 *
8329 * Retrieves the documentation string, the complete Help file name and path,
8330 * the localization context to use, and the context ID for the library Help
8331 * topic in the Help file.
8332 *
8333 */
8335 ITypeInfo2 * iface,
8336 MEMBERID memid,
8337 LCID lcid,
8338 BSTR *pbstrHelpString,
8339 DWORD *pdwHelpStringContext,
8340 BSTR *pbstrHelpStringDll)
8341{
8343 const TLBFuncDesc *pFDesc;
8344 const TLBVarDesc *pVDesc;
8345 TRACE("%p, %ld, %#lx, %p, %p, %p.\n",
8346 iface, memid, lcid, pbstrHelpString, pdwHelpStringContext,
8347 pbstrHelpStringDll );
8348 /* the help string should be obtained from the helpstringdll,
8349 * using the _DLLGetDocumentation function, based on the supplied
8350 * lcid. Nice to do sometime...
8351 */
8352 if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
8353 if(pbstrHelpString)
8354 *pbstrHelpString=SysAllocString(TLB_get_bstr(This->Name));
8355 if(pdwHelpStringContext)
8356 *pdwHelpStringContext=This->dwHelpStringContext;
8357 if(pbstrHelpStringDll)
8358 *pbstrHelpStringDll=
8359 SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
8360 return S_OK;
8361 }else {/* for a member */
8362 pFDesc = TLB_get_funcdesc_by_memberid(This, memid);
8363 if(pFDesc){
8364 if(pbstrHelpString)
8365 *pbstrHelpString=SysAllocString(TLB_get_bstr(pFDesc->HelpString));
8366 if(pdwHelpStringContext)
8367 *pdwHelpStringContext=pFDesc->HelpStringContext;
8368 if(pbstrHelpStringDll)
8369 *pbstrHelpStringDll=
8370 SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
8371 return S_OK;
8372 }
8373 pVDesc = TLB_get_vardesc_by_memberid(This, memid);
8374 if(pVDesc){
8375 if(pbstrHelpString)
8376 *pbstrHelpString=SysAllocString(TLB_get_bstr(pVDesc->HelpString));
8377 if(pdwHelpStringContext)
8378 *pdwHelpStringContext=pVDesc->HelpStringContext;
8379 if(pbstrHelpStringDll)
8380 *pbstrHelpStringDll=
8381 SysAllocString(TLB_get_bstr(This->pTypeLib->HelpStringDll));/* FIXME */
8382 return S_OK;
8383 }
8384 }
8386}
8387
8388/* ITypeInfo2::GetAllCustData
8389 *
8390 * Gets all custom data items for the Type info.
8391 *
8392 */
8394 ITypeInfo2 * iface,
8395 CUSTDATA *pCustData)
8396{
8398
8399 TRACE("%p %p\n", This, pCustData);
8400
8401 return TLB_copy_all_custdata(This->pcustdata_list, pCustData);
8402}
8403
8404/* ITypeInfo2::GetAllFuncCustData
8405 *
8406 * Gets all custom data items for the specified Function
8407 *
8408 */
8410 ITypeInfo2 * iface,
8411 UINT index,
8412 CUSTDATA *pCustData)
8413{
8415 const TLBFuncDesc *pFDesc;
8416 UINT hrefoffset;
8417 HRESULT hr;
8418
8419 TRACE("%p %u %p\n", This, index, pCustData);
8420
8421 hr = ITypeInfoImpl_GetInternalFuncDesc((ITypeInfo *)iface, index, &pFDesc, &hrefoffset);
8422 if (FAILED(hr))
8423 return hr;
8424
8425 return TLB_copy_all_custdata(&pFDesc->custdata_list, pCustData);
8426}
8427
8428/* ITypeInfo2::GetAllParamCustData
8429 *
8430 * Gets all custom data items for the Functions
8431 *
8432 */
8434 UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
8435{
8437 const TLBFuncDesc *pFDesc;
8438 UINT hrefoffset;
8439 HRESULT hr;
8440
8441 TRACE("%p %u %u %p\n", This, indexFunc, indexParam, pCustData);
8442
8443 hr = ITypeInfoImpl_GetInternalFuncDesc((ITypeInfo *)iface, indexFunc, &pFDesc, &hrefoffset);
8444 if (FAILED(hr))
8445 return hr;
8446
8447 if(indexParam >= pFDesc->funcdesc.cParams)
8449
8450 return TLB_copy_all_custdata(&pFDesc->pParamDesc[indexParam].custdata_list, pCustData);
8451}
8452
8453/* ITypeInfo2::GetAllVarCustData
8454 *
8455 * Gets all custom data items for the specified Variable
8456 *
8457 */
8459 UINT index, CUSTDATA *pCustData)
8460{
8462 TLBVarDesc * pVDesc = &This->vardescs[index];
8463
8464 TRACE("%p %u %p\n", This, index, pCustData);
8465
8466 if(index >= This->typeattr.cVars)
8468
8469 return TLB_copy_all_custdata(&pVDesc->custdata_list, pCustData);
8470}
8471
8472/* ITypeInfo2::GetAllImplCustData
8473 *
8474 * Gets all custom data items for the specified implementation type
8475 *
8476 */
8478 ITypeInfo2 * iface,
8479 UINT index,
8480 CUSTDATA *pCustData)
8481{
8483 TLBImplType *pRDesc = &This->impltypes[index];
8484
8485 TRACE("%p %u %p\n", This, index, pCustData);
8486
8487 if(index >= This->typeattr.cImplTypes)
8489
8490 return TLB_copy_all_custdata(&pRDesc->custdata_list, pCustData);
8491}
8492
8493static const ITypeInfo2Vtbl tinfvt =
8494{
8495
8499
8519
8535};
8536
8537/******************************************************************************
8538 * CreateDispTypeInfo [OLEAUT32.31]
8539 *
8540 * Build type information for an object so it can be called through an
8541 * IDispatch interface.
8542 *
8543 * RETURNS
8544 * Success: S_OK. pptinfo contains the created ITypeInfo object.
8545 * Failure: E_INVALIDARG, if one or more arguments is invalid.
8546 *
8547 * NOTES
8548 * This call allows an objects methods to be accessed through IDispatch, by
8549 * building an ITypeInfo object that IDispatch can use to call through.
8550 */
8552 INTERFACEDATA *pidata, /* [I] Description of the interface to build type info for */
8553 LCID lcid, /* [I] Locale Id */
8554 ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
8555{
8556 ITypeInfoImpl *pTIClass, *pTIIface;
8557 ITypeLibImpl *pTypeLibImpl;
8558 unsigned int param, func;
8559 TLBFuncDesc *pFuncDesc;
8560 TLBRefType *ref;
8561
8562 TRACE("\n");
8563 pTypeLibImpl = TypeLibImpl_Constructor();
8564 if (!pTypeLibImpl) return E_FAIL;
8565
8566 pTypeLibImpl->TypeInfoCount = 2;
8567 pTypeLibImpl->typeinfos = calloc(pTypeLibImpl->TypeInfoCount, sizeof(ITypeInfoImpl*));
8568
8569 pTIIface = pTypeLibImpl->typeinfos[0] = ITypeInfoImpl_Constructor();
8570 pTIIface->pTypeLib = pTypeLibImpl;
8571 pTIIface->index = 0;
8572 pTIIface->Name = NULL;
8573 pTIIface->dwHelpContext = -1;
8574 pTIIface->guid = NULL;
8575 pTIIface->typeattr.lcid = lcid;
8576 pTIIface->typeattr.typekind = TKIND_INTERFACE;
8577 pTIIface->typeattr.wMajorVerNum = 0;
8578 pTIIface->typeattr.wMinorVerNum = 0;
8579 pTIIface->typeattr.cbAlignment = 2;
8580 pTIIface->typeattr.cbSizeInstance = -1;
8581 pTIIface->typeattr.cbSizeVft = -1;
8582 pTIIface->typeattr.cFuncs = 0;
8583 pTIIface->typeattr.cImplTypes = 0;
8584 pTIIface->typeattr.cVars = 0;
8585 pTIIface->typeattr.wTypeFlags = 0;
8586 pTIIface->hreftype = 0;
8587
8588 pTIIface->funcdescs = TLBFuncDesc_Alloc(pidata->cMembers);
8589 pFuncDesc = pTIIface->funcdescs;
8590 for(func = 0; func < pidata->cMembers; func++) {
8591 METHODDATA *md = pidata->pmethdata + func;
8592 pFuncDesc->Name = TLB_append_str(&pTypeLibImpl->name_list, md->szName);
8593 pFuncDesc->funcdesc.memid = md->dispid;
8594 pFuncDesc->funcdesc.lprgscode = NULL;
8595 pFuncDesc->funcdesc.funckind = FUNC_VIRTUAL;
8596 pFuncDesc->funcdesc.invkind = md->wFlags;
8597 pFuncDesc->funcdesc.callconv = md->cc;
8598 pFuncDesc->funcdesc.cParams = md->cArgs;
8599 pFuncDesc->funcdesc.cParamsOpt = 0;
8600 pFuncDesc->funcdesc.oVft = md->iMeth * sizeof(void *);
8601 pFuncDesc->funcdesc.cScodes = 0;
8602 pFuncDesc->funcdesc.wFuncFlags = 0;
8603 pFuncDesc->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
8604 pFuncDesc->funcdesc.elemdescFunc.paramdesc.wParamFlags = PARAMFLAG_NONE;
8605 pFuncDesc->funcdesc.elemdescFunc.paramdesc.pparamdescex = NULL;
8606 pFuncDesc->funcdesc.lprgelemdescParam = calloc(md->cArgs, sizeof(ELEMDESC));
8607 pFuncDesc->pParamDesc = TLBParDesc_Constructor(md->cArgs);
8608 for(param = 0; param < md->cArgs; param++) {
8609 pFuncDesc->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt;
8610 pFuncDesc->pParamDesc[param].Name = TLB_append_str(&pTypeLibImpl->name_list, md->ppdata[param].szName);
8611 }
8612 pFuncDesc->helpcontext = 0;
8613 pFuncDesc->HelpStringContext = 0;
8614 pFuncDesc->HelpString = NULL;
8615 pFuncDesc->Entry = NULL;
8616 list_init(&pFuncDesc->custdata_list);
8617 pTIIface->typeattr.cFuncs++;
8618 ++pFuncDesc;
8619 }
8620
8621 dump_TypeInfo(pTIIface);
8622
8623 pTIClass = pTypeLibImpl->typeinfos[1] = ITypeInfoImpl_Constructor();
8624 pTIClass->pTypeLib = pTypeLibImpl;
8625 pTIClass->index = 1;
8626 pTIClass->Name = NULL;
8627 pTIClass->dwHelpContext = -1;
8628 pTIClass->guid = NULL;
8629 pTIClass->typeattr.lcid = lcid;
8630 pTIClass->typeattr.typekind = TKIND_COCLASS;
8631 pTIClass->typeattr.wMajorVerNum = 0;
8632 pTIClass->typeattr.wMinorVerNum = 0;
8633 pTIClass->typeattr.cbAlignment = 2;
8634 pTIClass->typeattr.cbSizeInstance = -1;
8635 pTIClass->typeattr.cbSizeVft = -1;
8636 pTIClass->typeattr.cFuncs = 0;
8637 pTIClass->typeattr.cImplTypes = 1;
8638 pTIClass->typeattr.cVars = 0;
8639 pTIClass->typeattr.wTypeFlags = 0;
8640 pTIClass->hreftype = sizeof(MSFT_TypeInfoBase);
8641
8642 pTIClass->impltypes = TLBImplType_Alloc(1);
8643
8644 ref = calloc(1, sizeof(*ref));
8645 ref->pImpTLInfo = TLB_REF_INTERNAL;
8646 list_add_head(&pTypeLibImpl->ref_list, &ref->entry);
8647
8648 dump_TypeInfo(pTIClass);
8649
8650 *pptinfo = (ITypeInfo *)&pTIClass->ITypeInfo2_iface;
8651
8652 ITypeInfo_AddRef(*pptinfo);
8653 ITypeLib2_Release(&pTypeLibImpl->ITypeLib2_iface);
8654
8655 return S_OK;
8656
8657}
8658
8660{
8662
8663 return ITypeInfo2_QueryInterface(&This->ITypeInfo2_iface, riid, ppv);
8664}
8665
8667{
8669
8670 return ITypeInfo2_AddRef(&This->ITypeInfo2_iface);
8671}
8672
8674{
8676
8677 return ITypeInfo2_Release(&This->ITypeInfo2_iface);
8678}
8679
8681 ITypeComp * iface,
8682 OLECHAR * szName,
8683 ULONG lHash,
8684 WORD wFlags,
8685 ITypeInfo ** ppTInfo,
8686 DESCKIND * pDescKind,
8687 BINDPTR * pBindPtr)
8688{
8690 const TLBFuncDesc *pFDesc;
8691 const TLBVarDesc *pVDesc;
8693 UINT fdc;
8694
8695 TRACE("%p, %s, %#lx, 0x%x, %p, %p, %p.\n", iface, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
8696
8697 *pDescKind = DESCKIND_NONE;
8698 pBindPtr->lpfuncdesc = NULL;
8699 *ppTInfo = NULL;
8700
8701 for(fdc = 0; fdc < This->typeattr.cFuncs; ++fdc){
8702 pFDesc = &This->funcdescs[fdc];
8703 if (!lstrcmpiW(TLB_get_bstr(pFDesc->Name), szName)) {
8704 if (!wFlags || (pFDesc->funcdesc.invkind & wFlags))
8705 break;
8706 else
8707 /* name found, but wrong flags */
8709 }
8710 }
8711
8712 if (fdc < This->typeattr.cFuncs)
8713 {
8715 &pFDesc->funcdesc,
8716 &pBindPtr->lpfuncdesc,
8717 This->typeattr.typekind == TKIND_DISPATCH);
8718 if (FAILED(hr))
8719 return hr;
8720 *pDescKind = DESCKIND_FUNCDESC;
8721 *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface;
8722 ITypeInfo_AddRef(*ppTInfo);
8723 return S_OK;
8724 } else {
8726 if(pVDesc){
8727 HRESULT hr = TLB_AllocAndInitVarDesc(&pVDesc->vardesc, &pBindPtr->lpvardesc);
8728 if (FAILED(hr))
8729 return hr;
8730 *pDescKind = DESCKIND_VARDESC;
8731 *ppTInfo = (ITypeInfo *)&This->ITypeInfo2_iface;
8732 ITypeInfo_AddRef(*ppTInfo);
8733 return S_OK;
8734 }
8735 }
8736
8737 if (hr == DISP_E_MEMBERNOTFOUND && This->impltypes) {
8738 /* recursive search */
8739 ITypeInfo *pTInfo;
8740 ITypeComp *pTComp;
8741 HRESULT hr;
8742 hr=ITypeInfo2_GetRefTypeInfo(&This->ITypeInfo2_iface, This->impltypes[0].hRef, &pTInfo);
8743 if (SUCCEEDED(hr))
8744 {
8745 hr = ITypeInfo_GetTypeComp(pTInfo,&pTComp);
8746 ITypeInfo_Release(pTInfo);
8747 }
8748 if (SUCCEEDED(hr))
8749 {
8750 hr = ITypeComp_Bind(pTComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
8751 ITypeComp_Release(pTComp);
8752 if (SUCCEEDED(hr) && *pDescKind == DESCKIND_FUNCDESC &&
8753 This->typeattr.typekind == TKIND_DISPATCH)
8754 {
8755 FUNCDESC *tmp = pBindPtr->lpfuncdesc;
8756 hr = TLB_AllocAndInitFuncDesc(tmp, &pBindPtr->lpfuncdesc, TRUE);
8757 SysFreeString((BSTR)tmp);
8758 }
8759 return hr;
8760 }
8761 WARN("Could not search inherited interface!\n");
8762 }
8764 hr = S_OK;
8765 TRACE("did not find member with name %s, flags 0x%x\n", debugstr_w(szName), wFlags);
8766 return hr;
8767}
8768
8770 ITypeComp * iface,
8771 OLECHAR * szName,
8772 ULONG lHash,
8773 ITypeInfo ** ppTInfo,
8774 ITypeComp ** ppTComp)
8775{
8776 TRACE("%s, %#lx, %p, %p.\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
8777
8778 /* strange behaviour (does nothing) but like the
8779 * original */
8780
8781 if (!ppTInfo || !ppTComp)
8782 return E_POINTER;
8783
8784 *ppTInfo = NULL;
8785 *ppTComp = NULL;
8786
8787 return S_OK;
8788}
8789
8790static const ITypeCompVtbl tcompvt =
8791{
8792
8796
8799};
8800
8801HRESULT WINAPI CreateTypeLib2(SYSKIND syskind, LPCOLESTR szFile,
8802 ICreateTypeLib2** ppctlib)
8803{
8805 HRESULT hres;
8806
8807 TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib);
8808
8809 if (!szFile) return E_INVALIDARG;
8810
8812 if (!This)
8813 return E_OUTOFMEMORY;
8814
8815 This->lcid = GetSystemDefaultLCID();
8816 This->syskind = syskind;
8817 This->ptr_size = get_ptr_size(syskind);
8818
8819 This->path = wcsdup(szFile);
8820 if (!This->path) {
8821 ITypeLib2_Release(&This->ITypeLib2_iface);
8822 return E_OUTOFMEMORY;
8823 }
8824
8825 hres = ITypeLib2_QueryInterface(&This->ITypeLib2_iface, &IID_ICreateTypeLib2, (LPVOID*)ppctlib);
8826 ITypeLib2_Release(&This->ITypeLib2_iface);
8827 return hres;
8828}
8829
8831 REFIID riid, void **object)
8832{
8834
8835 return ITypeLib2_QueryInterface(&This->ITypeLib2_iface, riid, object);
8836}
8837
8839{
8841
8842 return ITypeLib2_AddRef(&This->ITypeLib2_iface);
8843}
8844
8846{
8848
8849 return ITypeLib2_Release(&This->ITypeLib2_iface);
8850}
8851
8853 LPOLESTR name, TYPEKIND kind, ICreateTypeInfo **ctinfo)
8854{
8857 HRESULT hres;
8858
8859 TRACE("%p %s %d %p\n", This, wine_dbgstr_w(name), kind, ctinfo);
8860
8861 if (!ctinfo || !name)
8862 return E_INVALIDARG;
8863
8865 if (info)
8866 return TYPE_E_NAMECONFLICT;
8867
8868 This->typeinfos = realloc(This->typeinfos, sizeof(ITypeInfoImpl*) * (This->TypeInfoCount + 1));
8869
8870 info = This->typeinfos[This->TypeInfoCount] = ITypeInfoImpl_Constructor();
8871
8872 info->pTypeLib = This;
8873 info->Name = TLB_append_str(&This->name_list, name);
8874 info->index = This->TypeInfoCount;
8875 info->typeattr.typekind = kind;
8876 info->typeattr.cbAlignment = 4;
8877
8878 switch (info->typeattr.typekind) {
8879 case TKIND_ENUM:
8880 case TKIND_INTERFACE:
8881 case TKIND_DISPATCH:
8882 case TKIND_COCLASS:
8883 info->typeattr.cbSizeInstance = This->ptr_size;
8884 break;
8885 case TKIND_RECORD:
8886 case TKIND_UNION:
8887 info->typeattr.cbSizeInstance = 0;
8888 break;
8889 case TKIND_MODULE:
8890 info->typeattr.cbSizeInstance = 2;
8891 break;
8892 case TKIND_ALIAS:
8893 info->typeattr.cbSizeInstance = -0x75;
8894 break;
8895 default:
8896 FIXME("unrecognized typekind %d\n", info->typeattr.typekind);
8897 info->typeattr.cbSizeInstance = 0xdeadbeef;
8898 break;
8899 }
8900
8901 hres = ITypeInfo2_QueryInterface(&info->ITypeInfo2_iface,
8902 &IID_ICreateTypeInfo, (void **)ctinfo);
8903 if (FAILED(hres)) {
8904 ITypeInfo2_Release(&info->ITypeInfo2_iface);
8905 return hres;
8906 }
8907
8908 info->hreftype = info->index * sizeof(MSFT_TypeInfoBase);
8909
8910 ++This->TypeInfoCount;
8911
8912 return S_OK;
8913}
8914
8916 LPOLESTR name)
8917{
8919
8920 TRACE("%p %s\n", This, wine_dbgstr_w(name));
8921
8922 if (!name)
8923 return E_INVALIDARG;
8924
8925 This->Name = TLB_append_str(&This->name_list, name);
8926
8927 return S_OK;
8928}
8929
8931 WORD majorVerNum, WORD minorVerNum)
8932{
8934
8935 TRACE("%p %d %d\n", This, majorVerNum, minorVerNum);
8936
8937 This->ver_major = majorVerNum;
8938 This->ver_minor = minorVerNum;
8939
8940 return S_OK;
8941}
8942
8944 REFGUID guid)
8945{
8947
8948 TRACE("%p %s\n", This, debugstr_guid(guid));
8949
8950 This->guid = TLB_append_guid(&This->guid_list, guid, -2);
8951
8952 return S_OK;
8953}
8954
8956 LPOLESTR doc)
8957{
8959
8960 TRACE("%p %s\n", This, wine_dbgstr_w(doc));
8961
8962 if (!doc)
8963 return E_INVALIDARG;
8964
8965 This->DocString = TLB_append_str(&This->string_list, doc);
8966
8967 return S_OK;
8968}
8969
8971 LPOLESTR helpFileName)
8972{
8974
8975 TRACE("%p %s\n", This, wine_dbgstr_w(helpFileName));
8976
8977 if (!helpFileName)
8978 return E_INVALIDARG;
8979
8980 This->HelpFile = TLB_append_str(&This->string_list, helpFileName);
8981
8982 return S_OK;
8983}
8984
8986 DWORD helpContext)
8987{
8989
8990 TRACE("%p, %ld.\n", iface, helpContext);
8991
8992 This->dwHelpContext = helpContext;
8993
8994 return S_OK;
8995}
8996
8998 LCID lcid)
8999{
9001
9002 TRACE("%p, %#lx.\n", iface, lcid);
9003
9004 This->set_lcid = lcid;
9005
9006 return S_OK;
9007}
9008
9010 UINT libFlags)
9011{
9013
9014 TRACE("%p %x\n", This, libFlags);
9015
9016 This->libflags = libFlags;
9017
9018 return S_OK;
9019}
9020
9021typedef struct tagWMSFT_SegContents {
9023 void *data;
9025
9026typedef struct tagWMSFT_TLBFile {
9044
9047{
9048 TLBString *str;
9049 UINT last_offs;
9050 char *data;
9051
9052 file->string_seg.len = 0;
9053 LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) {
9054 int size;
9055
9056 size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str), NULL, 0, NULL, NULL);
9057 if (size == 0)
9058 return E_UNEXPECTED;
9059
9060 size += sizeof(INT16);
9061 if (size % 4)
9062 size = (size + 4) & ~0x3;
9063 if (size < 8)
9064 size = 8;
9065
9066 file->string_seg.len += size;
9067
9068 /* temporarily use str->offset to store the length of the aligned,
9069 * converted string */
9070 str->offset = size;
9071 }
9072
9073 file->string_seg.data = data = malloc(file->string_seg.len);
9074
9075 last_offs = 0;
9076 LIST_FOR_EACH_ENTRY(str, &This->string_list, TLBString, entry) {
9077 int size;
9078
9079 size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str),
9080 data + sizeof(INT16), file->string_seg.len - last_offs - sizeof(INT16), NULL, NULL);
9081 if (size == 0) {
9082 free(file->string_seg.data);
9083 file->string_seg.data = NULL;
9084 return E_UNEXPECTED;
9085 }
9086
9087 *((INT16*)data) = size;
9088
9089 memset(data + sizeof(INT16) + size, 0x57, str->offset - size - sizeof(INT16));
9090
9091 size = str->offset;
9092 data += size;
9093 str->offset = last_offs;
9094 last_offs += size;
9095 }
9096
9097 return S_OK;
9098}
9099
9102{
9103 TLBString *str;
9104 UINT last_offs;
9105 char *data;
9106 MSFT_NameIntro *last_intro = NULL;
9107
9108 file->header.nametablecount = 0;
9109 file->header.nametablechars = 0;
9110
9111 file->name_seg.len = 0;
9112 LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) {
9113 int size;
9114
9115 size = lstrlenW(str->str);
9116 file->header.nametablechars += size;
9117 file->header.nametablecount++;
9118
9119 size = WideCharToMultiByte(CP_ACP, 0, str->str, size, NULL, 0, NULL, NULL);
9120 if (size == 0)
9121 return E_UNEXPECTED;
9122
9123 size += sizeof(MSFT_NameIntro);
9124 if (size % 4)
9125 size = (size + 4) & ~0x3;
9126 if (size < 8)
9127 size = 8;
9128
9129 file->name_seg.len += size;
9130
9131 /* temporarily use str->offset to store the length of the aligned,
9132 * converted string */
9133 str->offset = size;
9134 }
9135
9136 /* Allocate bigger buffer so we can temporarily NULL terminate the name */
9137 file->name_seg.data = data = malloc(file->name_seg.len + 1);
9138
9139 last_offs = 0;
9140 LIST_FOR_EACH_ENTRY(str, &This->name_list, TLBString, entry) {
9141 int size, hash;
9143
9144 size = WideCharToMultiByte(CP_ACP, 0, str->str, lstrlenW(str->str),
9145 data + sizeof(MSFT_NameIntro),
9146 file->name_seg.len - last_offs - sizeof(MSFT_NameIntro), NULL, NULL);
9147 if (size == 0) {
9148 free(file->name_seg.data);
9149 return E_UNEXPECTED;
9150 }
9151 data[sizeof(MSFT_NameIntro) + size] = '\0';
9152
9153 intro->hreftype = -1; /* TODO? */
9154 intro->namelen = size & 0xFF;
9155 /* TODO: namelen & 0xFF00 == ??? maybe HREF type indicator? */
9156 hash = LHashValOfNameSysA(This->syskind, This->lcid, data + sizeof(MSFT_NameIntro));
9157 intro->namelen |= hash << 16;
9158 intro->next_hash = ((DWORD*)file->namehash_seg.data)[hash & 0x7f];
9159 ((DWORD*)file->namehash_seg.data)[hash & 0x7f] = last_offs;
9160
9161 memset(data + sizeof(MSFT_NameIntro) + size, 0x57,
9162 str->offset - size - sizeof(MSFT_NameIntro));
9163
9164 /* update str->offset to actual value to use in other
9165 * compilation functions that require positions within
9166 * the string table */
9167 last_intro = intro;
9168 size = str->offset;
9169 data += size;
9170 str->offset = last_offs;
9171 last_offs += size;
9172 }
9173
9174 if(last_intro)
9175 last_intro->hreftype = 0; /* last one is 0? */
9176
9177 return S_OK;
9178}
9179
9180static inline int hash_guid(GUID *guid)
9181{
9182 int i, hash = 0;
9183
9184 for (i = 0; i < 8; i ++)
9185 hash ^= ((const short *)guid)[i];
9186
9187 return hash & 0x1f;
9188}
9189
9191{
9192 TLBGuid *guid;
9194 DWORD offs;
9195 int hash_key, *guidhashtab;
9196
9197 file->guid_seg.len = sizeof(MSFT_GuidEntry) * list_count(&This->guid_list);
9198 file->guid_seg.data = malloc(file->guid_seg.len);
9199
9200 entry = file->guid_seg.data;
9201 offs = 0;
9202 guidhashtab = file->guidhash_seg.data;
9203 LIST_FOR_EACH_ENTRY(guid, &This->guid_list, TLBGuid, entry){
9204 memcpy(&entry->guid, &guid->guid, sizeof(GUID));
9205 entry->hreftype = guid->hreftype;
9206
9207 hash_key = hash_guid(&guid->guid);
9208 entry->next_hash = guidhashtab[hash_key];
9209 guidhashtab[hash_key] = offs;
9210
9211 guid->offset = offs;
9212 offs += sizeof(MSFT_GuidEntry);
9213 ++entry;
9214 }
9215
9216 return S_OK;
9217}
9218
9220{
9221 VARIANT v = *value;
9222 VARTYPE arg_type = V_VT(value);
9223 int mask = 0;
9224 HRESULT hres;
9225 DWORD ret = file->custdata_seg.len;
9226
9227 if(arg_type == VT_INT)
9228 arg_type = VT_I4;
9229 if(arg_type == VT_UINT)
9230 arg_type = VT_UI4;
9231
9232 v = *value;
9233 if(V_VT(value) != arg_type) {
9234 hres = VariantChangeType(&v, value, 0, arg_type);
9235 if(FAILED(hres)){
9236 ERR("VariantChangeType failed: %#lx.\n", hres);
9237 return -1;
9238 }
9239 }
9240
9241 /* Check if default value can be stored in-place */
9242 switch(arg_type){
9243 case VT_I4:
9244 case VT_UI4:
9245 mask = 0x3ffffff;
9246 if(V_UI4(&v) > 0x3ffffff)
9247 break;
9248 /* fall through */
9249 case VT_I1:
9250 case VT_UI1:
9251 case VT_BOOL:
9252 if(!mask)
9253 mask = 0xff;
9254 /* fall through */
9255 case VT_I2:
9256 case VT_UI2:
9257 if(!mask)
9258 mask = 0xffff;
9259 return ((0x80 + 0x4 * V_VT(value)) << 24) | (V_UI4(&v) & mask);
9260 }
9261
9262 /* have to allocate space in custdata_seg */
9263 switch(arg_type) {
9264 case VT_I4:
9265 case VT_R4:
9266 case VT_UI4:
9267 case VT_INT:
9268 case VT_UINT:
9269 case VT_HRESULT:
9270 case VT_PTR: {
9271 /* Construct the data to be allocated */
9272 int *data;
9273
9274 if(file->custdata_seg.data){
9275 file->custdata_seg.data = realloc(file->custdata_seg.data, file->custdata_seg.len + sizeof(int) * 2);
9276 data = (int *)(((char *)file->custdata_seg.data) + file->custdata_seg.len);
9277 file->custdata_seg.len += sizeof(int) * 2;
9278 }else{
9279 file->custdata_seg.len = sizeof(int) * 2;
9280 data = file->custdata_seg.data = malloc(file->custdata_seg.len);
9281 }
9282
9283 data[0] = V_VT(value) + (V_UI4(&v) << 16);
9284 data[1] = (V_UI4(&v) >> 16) + 0x57570000;
9285
9286 /* TODO: Check if the encoded data is already present in custdata_seg */
9287
9288 return ret;
9289 }
9290
9291 case VT_BSTR: {
9292 int mb_len = WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), SysStringLen(V_BSTR(&v)), NULL, 0, NULL, NULL );
9293 int i, len = (6 + mb_len + 3) & ~0x3;
9294 char *data;
9295
9296 if(file->custdata_seg.data){
9297 file->custdata_seg.data = realloc(file->custdata_seg.data, file->custdata_seg.len + len);
9298 data = ((char *)file->custdata_seg.data) + file->custdata_seg.len;
9299 file->custdata_seg.len += len;
9300 }else{
9301 file->custdata_seg.len = len;
9302 data = file->custdata_seg.data = malloc(file->custdata_seg.len);
9303 }
9304
9305 *((unsigned short *)data) = V_VT(value);
9306 *((unsigned int *)(data+2)) = mb_len;
9307 WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), SysStringLen(V_BSTR(&v)), &data[6], mb_len, NULL, NULL);
9308 for (i = 6 + mb_len; i < len; i++)
9309 data[i] = 0x57;
9310
9311 /* TODO: Check if the encoded data is already present in custdata_seg */
9312
9313 return ret;
9314 }
9315 default:
9316 FIXME("Argument type not yet handled\n");
9317 return -1;
9318 }
9319}
9320
9321static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *out_mix, INT16 *out_size);
9322
9324{
9325 DWORD offs = file->arraydesc_seg.len;
9326 DWORD *encoded;
9327 USHORT i;
9328
9329 /* TODO: we should check for duplicates, but that's harder because each
9330 * chunk is variable length (really we should store TYPEDESC and ARRAYDESC
9331 * at the library-level) */
9332
9333 file->arraydesc_seg.len += (2 + desc->cDims * 2) * sizeof(DWORD);
9334 file->arraydesc_seg.data = realloc(file->arraydesc_seg.data, file->arraydesc_seg.len);
9335 encoded = (DWORD*)((char *)file->arraydesc_seg.data + offs);
9336
9337 encoded[0] = WMSFT_append_typedesc(&desc->tdescElem, file, NULL, NULL);
9338 encoded[1] = desc->cDims | ((desc->cDims * 2 * sizeof(DWORD)) << 16);
9339 for(i = 0; i < desc->cDims; ++i){
9340 encoded[2 + i * 2] = desc->rgbounds[i].cElements;
9341 encoded[2 + i * 2 + 1] = desc->rgbounds[i].lLbound;
9342 }
9343
9344 return offs;
9345}
9346
9348{
9349 DWORD junk;
9350 INT16 junk2;
9351 DWORD offs = 0;
9352 DWORD encoded[2];
9353 VARTYPE vt, subtype;
9354 char *data;
9355
9356 if(!desc)
9357 return -1;
9358
9359 if(!out_mix)
9360 out_mix = &junk;
9361 if(!out_size)
9362 out_size = &junk2;
9363
9364 vt = desc->vt & VT_TYPEMASK;
9365
9366 if(vt == VT_PTR || vt == VT_SAFEARRAY){
9367 DWORD mix;
9368 encoded[1] = WMSFT_append_typedesc(desc->lptdesc, file, &mix, out_size);
9369 encoded[0] = desc->vt | ((mix | VT_BYREF) << 16);
9370 *out_mix = 0x7FFF;
9371 *out_size += 2 * sizeof(DWORD);
9372 }else if(vt == VT_CARRAY){
9373 encoded[0] = desc->vt | (0x7FFE << 16);
9374 encoded[1] = WMSFT_append_arraydesc(desc->lpadesc, file);
9375 *out_mix = 0x7FFE;
9376 }else if(vt == VT_USERDEFINED){
9377 encoded[0] = desc->vt | (0x7FFF << 16);
9378 encoded[1] = desc->hreftype;
9379 *out_mix = 0x7FFF; /* FIXME: Should get TYPEKIND of the hreftype, e.g. TKIND_ENUM => VT_I4 */
9380 }else{
9381 TRACE("Mixing in-place, VT: 0x%x\n", desc->vt);
9382
9383 switch(vt){
9384 case VT_INT:
9385 subtype = VT_I4;
9386 break;
9387 case VT_UINT:
9388 subtype = VT_UI4;
9389 break;
9390 case VT_VOID:
9391 subtype = VT_EMPTY;
9392 break;
9393 default:
9394 subtype = vt;
9395 break;
9396 }
9397
9398 *out_mix = subtype;
9399 return 0x80000000 | (subtype << 16) | desc->vt;
9400 }
9401
9402 data = file->typdesc_seg.data;
9403 while(offs < file->typdesc_seg.len){
9404 if(!memcmp(&data[offs], encoded, sizeof(encoded)))
9405 return offs;
9406 offs += sizeof(encoded);
9407 }
9408
9409 file->typdesc_seg.len += sizeof(encoded);
9410 data = file->typdesc_seg.data = realloc(file->typdesc_seg.data, file->typdesc_seg.len);
9411
9412 memcpy(&data[offs], encoded, sizeof(encoded));
9413
9414 return offs;
9415}
9416
9417static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *file)
9418{
9419 WMSFT_SegContents *cdguids_seg = &file->cdguids_seg;
9420 DWORD ret = cdguids_seg->len, offs;
9421 MSFT_CDGuid *cdguid;
9422 TLBCustData *cd;
9423
9424 if(list_empty(custdata_list))
9425 return -1;
9426
9427 cdguids_seg->len += sizeof(MSFT_CDGuid) * list_count(custdata_list);
9428 cdguids_seg->data = realloc(cdguids_seg->data, cdguids_seg->len);
9429 cdguid = (MSFT_CDGuid*)((char*)cdguids_seg->data + ret);
9430
9431 offs = ret + sizeof(MSFT_CDGuid);
9432 LIST_FOR_EACH_ENTRY(cd, custdata_list, TLBCustData, entry){
9433 cdguid->GuidOffset = cd->guid->offset;
9434 cdguid->DataOffset = WMSFT_encode_variant(&cd->data, file);
9435 cdguid->next = offs;
9436 offs += sizeof(MSFT_CDGuid);
9437 ++cdguid;
9438 }
9439
9440 --cdguid;
9441 cdguid->next = -1;
9442
9443 return ret;
9444}
9445
9448{
9449 WMSFT_SegContents *aux_seg = &file->aux_seg;
9450 DWORD ret = aux_seg->len, i, j, recorded_size = 0, extra_size = 0;
9451 MSFT_VarRecord *varrecord;
9452 MSFT_FuncRecord *funcrecord;
9453 MEMBERID *memid;
9454 DWORD *name, *offsets, offs;
9455
9456 for(i = 0; i < info->typeattr.cFuncs; ++i){
9457 TLBFuncDesc *desc = &info->funcdescs[i];
9458
9459 recorded_size += 6 * sizeof(INT); /* mandatory fields */
9460
9461 /* optional fields */
9462 /* TODO: oArgCustData - FuncSetCustData not impl yet */
9463 if(!list_empty(&desc->custdata_list))
9464 recorded_size += 7 * sizeof(INT);
9465 else if(desc->HelpStringContext != 0)
9466 recorded_size += 6 * sizeof(INT);
9467 /* res9? resA? */
9468 else if(desc->Entry)
9469 recorded_size += 3 * sizeof(INT);
9470 else if(desc->HelpString)
9471 recorded_size += 2 * sizeof(INT);
9472 else if(desc->helpcontext)
9473 recorded_size += sizeof(INT);
9474
9475 recorded_size += desc->funcdesc.cParams * sizeof(MSFT_ParameterInfo);
9476
9477 for(j = 0; j < desc->funcdesc.cParams; ++j){
9478 if(desc->funcdesc.lprgelemdescParam[j].paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT){
9479 recorded_size += desc->funcdesc.cParams * sizeof(INT);
9480 break;
9481 }
9482 }
9483
9484 extra_size += 2 * sizeof(INT); /* memberid, name offs */
9485 }
9486
9487 for(i = 0; i < info->typeattr.cVars; ++i){
9488 TLBVarDesc *desc = &info->vardescs[i];
9489
9490 recorded_size += 5 * sizeof(INT); /* mandatory fields */
9491
9492 /* optional fields */
9493 if(desc->HelpStringContext != 0)
9494 recorded_size += 5 * sizeof(INT);
9495 else if(!list_empty(&desc->custdata_list))
9496 recorded_size += 4 * sizeof(INT);
9497 /* res9? */
9498 else if(desc->HelpString)
9499 recorded_size += 2 * sizeof(INT);
9500 else if(desc->HelpContext != 0)
9501 recorded_size += sizeof(INT);
9502
9503 extra_size += 2 * sizeof(INT); /* memberid, name offs */
9504 }
9505
9506 if(!recorded_size && !extra_size)
9507 return ret;
9508
9509 extra_size += sizeof(INT); /* total aux size for this typeinfo */
9510
9511 aux_seg->len += recorded_size + extra_size;
9512
9513 aux_seg->len += sizeof(INT) * (info->typeattr.cVars + info->typeattr.cFuncs); /* offsets at the end */
9514
9515 aux_seg->data = realloc(aux_seg->data, aux_seg->len);
9516
9517 *((DWORD*)((char *)aux_seg->data + ret)) = recorded_size;
9518
9519 offsets = (DWORD*)((char *)aux_seg->data + ret + recorded_size + extra_size);
9520 offs = 0;
9521
9522 funcrecord = (MSFT_FuncRecord*)(((char *)aux_seg->data) + ret + sizeof(INT));
9523 for(i = 0; i < info->typeattr.cFuncs; ++i){
9524 TLBFuncDesc *desc = &info->funcdescs[i];
9525 DWORD size = 6 * sizeof(INT), paramdefault_size = 0, *paramdefault;
9526
9527 funcrecord->funcdescsize = sizeof(desc->funcdesc) + desc->funcdesc.cParams * sizeof(ELEMDESC);
9528 funcrecord->DataType = WMSFT_append_typedesc(&desc->funcdesc.elemdescFunc.tdesc, file, NULL, &funcrecord->funcdescsize);
9529 funcrecord->Flags = desc->funcdesc.wFuncFlags;
9530 funcrecord->VtableOffset = desc->funcdesc.oVft;
9531
9532 /* FKCCIC:
9533 * XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
9534 * ^^^funckind
9535 * ^^^ ^invkind
9536 * ^has_cust_data
9537 * ^^^^callconv
9538 * ^has_param_defaults
9539 * ^oEntry_is_intresource
9540 */
9541 funcrecord->FKCCIC =
9542 desc->funcdesc.funckind |
9543 (desc->funcdesc.invkind << 3) |
9544 (list_empty(&desc->custdata_list) ? 0 : 0x80) |
9545 (desc->funcdesc.callconv << 8);
9546
9547 if(desc->Entry && desc->Entry != (TLBString*)-1 && IS_INTRESOURCE(desc->Entry))
9548 funcrecord->FKCCIC |= 0x2000;
9549
9550 for(j = 0; j < desc->funcdesc.cParams; ++j){
9551 if(desc->funcdesc.lprgelemdescParam[j].paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT){
9552 paramdefault_size = sizeof(INT) * desc->funcdesc.cParams;
9553 funcrecord->funcdescsize += sizeof(PARAMDESCEX);
9554 }
9555 }
9556 if(paramdefault_size > 0)
9557 funcrecord->FKCCIC |= 0x1000;
9558
9559 funcrecord->nrargs = desc->funcdesc.cParams;
9560 funcrecord->nroargs = desc->funcdesc.cParamsOpt;
9561
9562 /* optional fields */
9563 /* res9? resA? */
9564 if(!list_empty(&desc->custdata_list)){
9565 size += 7 * sizeof(INT);
9566 funcrecord->HelpContext = desc->helpcontext;
9567 if(desc->HelpString)
9568 funcrecord->oHelpString = desc->HelpString->offset;
9569 else
9570 funcrecord->oHelpString = -1;
9571 if(!desc->Entry)
9572 funcrecord->oEntry = -1;
9573 else if(IS_INTRESOURCE(desc->Entry))
9574 funcrecord->oEntry = LOWORD(desc->Entry);
9575 else
9576 funcrecord->oEntry = desc->Entry->offset;
9577 funcrecord->res9 = -1;
9578 funcrecord->resA = -1;
9579 funcrecord->HelpStringContext = desc->HelpStringContext;
9580 funcrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
9581 }else if(desc->HelpStringContext != 0){
9582 size += 6 * sizeof(INT);
9583 funcrecord->HelpContext = desc->helpcontext;
9584 if(desc->HelpString)
9585 funcrecord->oHelpString = desc->HelpString->offset;
9586 else
9587 funcrecord->oHelpString = -1;
9588 if(!desc->Entry)
9589 funcrecord->oEntry = -1;
9590 else if(IS_INTRESOURCE(desc->Entry))
9591 funcrecord->oEntry = LOWORD(desc->Entry);
9592 else
9593 funcrecord->oEntry = desc->Entry->offset;
9594 funcrecord->res9 = -1;
9595 funcrecord->resA = -1;
9596 funcrecord->HelpStringContext = desc->HelpStringContext;
9597 }else if(desc->Entry){
9598 size += 3 * sizeof(INT);
9599 funcrecord->HelpContext = desc->helpcontext;
9600 if(desc->HelpString)
9601 funcrecord->oHelpString = desc->HelpString->offset;
9602 else
9603 funcrecord->oHelpString = -1;
9604 if(!desc->Entry)
9605 funcrecord->oEntry = -1;
9606 else if(IS_INTRESOURCE(desc->Entry))
9607 funcrecord->oEntry = LOWORD(desc->Entry);
9608 else
9609 funcrecord->oEntry = desc->Entry->offset;
9610 }else if(desc->HelpString){
9611 size += 2 * sizeof(INT);
9612 funcrecord->HelpContext = desc->helpcontext;
9613 funcrecord->oHelpString = desc->HelpString->offset;
9614 }else if(desc->helpcontext){
9615 size += sizeof(INT);
9616 funcrecord->HelpContext = desc->helpcontext;
9617 }
9618
9619 paramdefault = (DWORD*)((char *)funcrecord + size);
9620 size += paramdefault_size;
9621
9622 for(j = 0; j < desc->funcdesc.cParams; ++j){
9623 MSFT_ParameterInfo *info = (MSFT_ParameterInfo*)(((char *)funcrecord) + size);
9624
9625 info->DataType = WMSFT_append_typedesc(&desc->funcdesc.lprgelemdescParam[j].tdesc, file, NULL, &funcrecord->funcdescsize);
9626 if(desc->pParamDesc[j].Name)
9627 info->oName = desc->pParamDesc[j].Name->offset;
9628 else
9629 info->oName = -1;
9630 info->Flags = desc->funcdesc.lprgelemdescParam[j].paramdesc.wParamFlags;
9631
9632 if(paramdefault_size){
9633 if(desc->funcdesc.lprgelemdescParam[j].paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
9634 *paramdefault = WMSFT_encode_variant(&desc->funcdesc.lprgelemdescParam[j].paramdesc.pparamdescex->varDefaultValue, file);
9635 else if(paramdefault_size)
9636 *paramdefault = -1;
9637 ++paramdefault;
9638 }
9639
9640 size += sizeof(MSFT_ParameterInfo);
9641 }
9642
9643 funcrecord->Info = size | (i << 16); /* is it just the index? */
9644
9645 *offsets = offs;
9646 offs += size;
9647 ++offsets;
9648
9649 funcrecord = (MSFT_FuncRecord*)(((char*)funcrecord) + size);
9650 }
9651
9652 varrecord = (MSFT_VarRecord*)funcrecord;
9653 for(i = 0; i < info->typeattr.cVars; ++i){
9654 TLBVarDesc *desc = &info->vardescs[i];
9655 DWORD size = 5 * sizeof(INT);
9656
9657 varrecord->vardescsize = sizeof(desc->vardesc);
9658 varrecord->DataType = WMSFT_append_typedesc(&desc->vardesc.elemdescVar.tdesc, file, NULL, &varrecord->vardescsize);
9659 varrecord->Flags = desc->vardesc.wVarFlags;
9660 varrecord->VarKind = desc->vardesc.varkind;
9661
9662 if(desc->vardesc.varkind == VAR_CONST){
9663 varrecord->vardescsize += sizeof(VARIANT);
9664 varrecord->OffsValue = WMSFT_encode_variant(desc->vardesc.lpvarValue, file);
9665 }else
9666 varrecord->OffsValue = desc->vardesc.oInst;
9667
9668 /* res9? */
9669 if(desc->HelpStringContext != 0){
9670 size += 5 * sizeof(INT);
9671 varrecord->HelpContext = desc->HelpContext;
9672 if(desc->HelpString)
9673 varrecord->HelpString = desc->HelpString->offset;
9674 else
9675 varrecord->HelpString = -1;
9676 varrecord->res9 = -1;
9677 varrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
9678 varrecord->HelpStringContext = desc->HelpStringContext;
9679 }else if(!list_empty(&desc->custdata_list)){
9680 size += 4 * sizeof(INT);
9681 varrecord->HelpContext = desc->HelpContext;
9682 if(desc->HelpString)
9683 varrecord->HelpString = desc->HelpString->offset;
9684 else
9685 varrecord->HelpString = -1;
9686 varrecord->res9 = -1;
9687 varrecord->oCustData = WMSFT_compile_custdata(&desc->custdata_list, file);
9688 }else if(desc->HelpString){
9689 size += 2 * sizeof(INT);
9690 varrecord->HelpContext = desc->HelpContext;
9691 if(desc->HelpString)
9692 varrecord->HelpString = desc->HelpString->offset;
9693 else
9694 varrecord->HelpString = -1;
9695 }else if(desc->HelpContext != 0){
9696 size += sizeof(INT);
9697 varrecord->HelpContext = desc->HelpContext;
9698 }
9699
9700 varrecord->Info = size | (i << 16);
9701
9702 *offsets = offs;
9703 offs += size;
9704 ++offsets;
9705
9706 varrecord = (MSFT_VarRecord*)(((char*)varrecord) + size);
9707 }
9708
9709 memid = (MEMBERID*)varrecord;
9710 for(i = 0; i < info->typeattr.cFuncs; ++i){
9711 TLBFuncDesc *desc = &info->funcdescs[i];
9712 *memid = desc->funcdesc.memid;
9713 ++memid;
9714 }
9715 for(i = 0; i < info->typeattr.cVars; ++i){
9716 TLBVarDesc *desc = &info->vardescs[i];
9717 *memid = desc->vardesc.memid;
9718 ++memid;
9719 }
9720
9721 name = (DWORD*)memid;
9722 for(i = 0; i < info->typeattr.cFuncs; ++i){
9723 TLBFuncDesc *desc = &info->funcdescs[i];
9724 if(desc->Name)
9725 *name = desc->Name->offset;
9726 else
9727 *name = -1;
9728 ++name;
9729 }
9730 for(i = 0; i < info->typeattr.cVars; ++i){
9731 TLBVarDesc *desc = &info->vardescs[i];
9732 if(desc->Name)
9733 *name = desc->Name->offset;
9734 else
9735 *name = -1;
9736 ++name;
9737 }
9738
9739 return ret;
9740}
9741
9742typedef struct tagWMSFT_RefChunk {
9748
9750{
9751 DWORD offs = file->ref_seg.len, i;
9753
9754 file->ref_seg.len += info->typeattr.cImplTypes * sizeof(WMSFT_RefChunk);
9755 file->ref_seg.data = realloc(file->ref_seg.data, file->ref_seg.len);
9756
9757 chunk = (WMSFT_RefChunk*)((char*)file->ref_seg.data + offs);
9758
9759 for(i = 0; i < info->typeattr.cImplTypes; ++i){
9760 chunk->href = info->impltypes[i].hRef;
9761 chunk->res04 = info->impltypes[i].implflags;
9762 chunk->res08 = -1;
9763 if(i < info->typeattr.cImplTypes - 1)
9764 chunk->next = offs + sizeof(WMSFT_RefChunk) * (i + 1);
9765 else
9766 chunk->next = -1;
9767 ++chunk;
9768 }
9769
9770 return offs;
9771}
9772
9774{
9775 DWORD size;
9776
9777 size = sizeof(MSFT_TypeInfoBase);
9778
9779 if(data){
9781 if(info->typeattr.wTypeFlags & TYPEFLAG_FDUAL)
9782 base->typekind = TKIND_DISPATCH;
9783 else
9784 base->typekind = info->typeattr.typekind;
9785 base->typekind |= index << 16; /* TODO: There are some other flags here */
9786 base->typekind |= (info->typeattr.cbAlignment << 11) | (info->typeattr.cbAlignment << 6);
9788 base->res2 = 0;
9789 base->res3 = 0;
9790 base->res4 = 3;
9791 base->res5 = 0;
9792 base->cElement = (info->typeattr.cVars << 16) | info->typeattr.cFuncs;
9793 base->res7 = 0;
9794 base->res8 = 0;
9795 base->res9 = 0;
9796 base->resA = 0;
9797 if(info->guid)
9798 base->posguid = info->guid->offset;
9799 else
9800 base->posguid = -1;
9801 base->flags = info->typeattr.wTypeFlags;
9802 if(info->Name) {
9803 base->NameOffset = info->Name->offset;
9804
9805 ((unsigned char*)file->name_seg.data)[info->Name->offset+9] = 0x38;
9806 *(HREFTYPE*)((unsigned char*)file->name_seg.data+info->Name->offset) = info->hreftype;
9807 }else {
9808 base->NameOffset = -1;
9809 }
9810 base->version = (info->typeattr.wMinorVerNum << 16) | info->typeattr.wMajorVerNum;
9811 if(info->DocString)
9812 base->docstringoffs = info->DocString->offset;
9813 else
9814 base->docstringoffs = -1;
9815 base->helpstringcontext = info->dwHelpStringContext;
9816 base->helpcontext = info->dwHelpContext;
9817 base->oCustData = WMSFT_compile_custdata(info->pcustdata_list, file);
9818 base->cImplTypes = info->typeattr.cImplTypes;
9819 base->cbSizeVft = info->typeattr.cbSizeVft;
9820 base->size = info->typeattr.cbSizeInstance;
9821 if(info->typeattr.typekind == TKIND_COCLASS){
9823 }else if(info->typeattr.typekind == TKIND_ALIAS){
9824 base->datatype1 = WMSFT_append_typedesc(info->tdescAlias, file, NULL, NULL);
9825 }else if(info->typeattr.typekind == TKIND_MODULE){
9826 if(info->DllName)
9827 base->datatype1 = info->DllName->offset;
9828 else
9829 base->datatype1 = -1;
9830 }else{
9831 if(info->typeattr.cImplTypes > 0)
9832 base->datatype1 = info->impltypes[0].hRef;
9833 else
9834 base->datatype1 = -1;
9835 }
9836 base->datatype2 = index; /* FIXME: i think there's more here */
9837 base->res18 = 0;
9838 base->res19 = -1;
9839 }
9840
9841 return size;
9842}
9843
9845{
9846 UINT i;
9847
9848 file->typeinfo_seg.len = 0;
9849 for(i = 0; i < This->TypeInfoCount; ++i){
9850 ITypeInfoImpl *info = This->typeinfos[i];
9851 *junk = file->typeinfo_seg.len;
9852 ++junk;
9853 file->typeinfo_seg.len += WMSFT_compile_typeinfo(info, i, NULL, NULL);
9854 }
9855
9856 file->typeinfo_seg.data = malloc(file->typeinfo_seg.len);
9857 memset(file->typeinfo_seg.data, 0x96, file->typeinfo_seg.len);
9858
9859 file->aux_seg.len = 0;
9860 file->aux_seg.data = NULL;
9861
9862 file->typeinfo_seg.len = 0;
9863 for(i = 0; i < This->TypeInfoCount; ++i){
9864 ITypeInfoImpl *info = This->typeinfos[i];
9865 file->typeinfo_seg.len += WMSFT_compile_typeinfo(info, i, file,
9866 ((char *)file->typeinfo_seg.data) + file->typeinfo_seg.len);
9867 }
9868}
9869
9870typedef struct tagWMSFT_ImpFile {
9875
9877{
9878 TLBImpLib *implib;
9879 WMSFT_ImpFile *impfile;
9880 char *data;
9881 DWORD last_offs = 0;
9882
9883 file->impfile_seg.len = 0;
9884 LIST_FOR_EACH_ENTRY(implib, &This->implib_list, TLBImpLib, entry){
9885 int size = 0;
9886
9887 if(implib->name){
9888 WCHAR *path = wcsrchr(implib->name, '\\');
9889 if(path)
9890 ++path;
9891 else
9892 path = implib->name;
9894 if (size == 0)
9895 ERR("failed to convert wide string: %s\n", debugstr_w(path));
9896 }
9897
9898 size += sizeof(INT16);
9899 if (size % 4)
9900 size = (size + 4) & ~0x3;
9901 if (size < 8)
9902 size = 8;
9903
9904 file->impfile_seg.len += sizeof(WMSFT_ImpFile) + size;
9905 }
9906
9907 data = file->impfile_seg.data = malloc(file->impfile_seg.len);
9908
9909 LIST_FOR_EACH_ENTRY(implib, &This->implib_list, TLBImpLib, entry){
9910 int strlen = 0, size;
9911
9912 impfile = (WMSFT_ImpFile*)data;
9913 impfile->guid_offs = implib->guid->offset;
9914 impfile->lcid = implib->lcid;
9915 impfile->version = (implib->wVersionMinor << 16) | implib->wVersionMajor;
9916
9917 data += sizeof(WMSFT_ImpFile);
9918
9919 if(implib->name){
9920 WCHAR *path= wcsrchr(implib->name, '\\');
9921 if(path)
9922 ++path;
9923 else
9924 path = implib->name;
9926 data + sizeof(INT16), file->impfile_seg.len - last_offs - sizeof(INT16), NULL, NULL);
9927 if (strlen == 0)
9928 ERR("failed to convert wide string: %s\n", debugstr_w(path));
9929 }
9930
9931 *((INT16*)data) = (strlen << 2) | 1; /* FIXME: is that a flag, or what? */
9932
9933 size = strlen + sizeof(INT16);
9934 if (size % 4)
9935 size = (size + 4) & ~0x3;
9936 if (size < 8)
9937 size = 8;
9938 memset(data + sizeof(INT16) + strlen, 0x57, size - strlen - sizeof(INT16));
9939
9940 data += size;
9941 implib->offset = last_offs;
9942 last_offs += size + sizeof(WMSFT_ImpFile);
9943 }
9944}
9945
9947{
9949 TLBRefType *ref_type;
9950 UINT i = 0;
9951
9953
9954 file->impinfo_seg.len = sizeof(MSFT_ImpInfo) * list_count(&This->ref_list);
9955 info = file->impinfo_seg.data = malloc(file->impinfo_seg.len);
9956
9957 LIST_FOR_EACH_ENTRY(ref_type, &This->ref_list, TLBRefType, entry){
9958 info->flags = i | ((ref_type->tkind & 0xFF) << 24);
9959 if(ref_type->index == TLB_REF_USE_GUID){
9961 info->oGuid = ref_type->guid->offset;
9962 }else
9963 info->oGuid = ref_type->index;
9964 info->oImpFile = ref_type->pImpTLInfo->offset;
9965 ++i;
9966 ++info;
9967 }
9968}
9969
9971{
9972 file->guidhash_seg.len = 0x80;
9973 file->guidhash_seg.data = malloc(file->guidhash_seg.len);
9974 memset(file->guidhash_seg.data, 0xFF, file->guidhash_seg.len);
9975}
9976
9978{
9979 file->namehash_seg.len = 0x200;
9980 file->namehash_seg.data = malloc(file->namehash_seg.len);
9981 memset(file->namehash_seg.data, 0xFF, file->namehash_seg.len);
9982}
9983
9984static void tmp_fill_segdir_seg(MSFT_pSeg *segdir, WMSFT_SegContents *contents, DWORD *running_offset)
9985{
9986 if(contents && contents->len){
9987 segdir->offset = *running_offset;
9988 segdir->length = contents->len;
9989 *running_offset += segdir->length;
9990 }else{
9991 segdir->offset = -1;
9992 segdir->length = 0;
9993 }
9994
9995 /* TODO: do these ever change? */
9996 segdir->res08 = -1;
9997 segdir->res0c = 0xf;
9998}
9999
10001{
10002 DWORD written;
10003 if(segment)
10004 WriteFile(outfile, segment->data, segment->len, &written, NULL);
10005}
10006
10008 DWORD file_len)
10009{
10010 DWORD i;
10011 MSFT_TypeInfoBase *base = (MSFT_TypeInfoBase *)file->typeinfo_seg.data;
10012
10013 for(i = 0; i < This->TypeInfoCount; ++i){
10014 base->memoffset += file_len;
10015 ++base;
10016 }
10017
10018 return S_OK;
10019}
10020
10022{
10023 free(file->typeinfo_seg.data);
10024 free(file->guidhash_seg.data);
10025 free(file->guid_seg.data);
10026 free(file->ref_seg.data);
10027 free(file->impinfo_seg.data);
10028 free(file->impfile_seg.data);
10029 free(file->namehash_seg.data);
10030 free(file->name_seg.data);
10031 free(file->string_seg.data);
10032 free(file->typdesc_seg.data);
10033 free(file->arraydesc_seg.data);
10034 free(file->custdata_seg.data);
10035 free(file->cdguids_seg.data);
10036 free(file->aux_seg.data);
10037}
10038
10040{
10043 DWORD written, junk_size, junk_offs, running_offset;
10044 BOOL br;
10046 HRESULT hres;
10047 DWORD *junk;
10048 UINT i;
10049
10050 TRACE("%p\n", This);
10051
10052 for(i = 0; i < This->TypeInfoCount; ++i)
10053 if(This->typeinfos[i]->needs_layout)
10054 ICreateTypeInfo2_LayOut(&This->typeinfos[i]->ICreateTypeInfo2_iface);
10055
10056 memset(&file, 0, sizeof(file));
10057
10058 file.header.magic1 = 0x5446534D;
10059 file.header.magic2 = 0x00010002;
10060 file.header.lcid = This->set_lcid ? This->set_lcid : MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
10061 file.header.lcid2 = This->set_lcid;
10062 file.header.varflags = 0x40 | This->syskind;
10063 if (This->HelpFile)
10064 file.header.varflags |= 0x10;
10065 if (This->HelpStringDll)
10066 file.header.varflags |= HELPDLLFLAG;
10067 file.header.version = (This->ver_minor << 16) | This->ver_major;
10068 file.header.flags = This->libflags;
10069 file.header.helpstringcontext = 0; /* TODO - SetHelpStringContext not implemented yet */
10070 file.header.helpcontext = This->dwHelpContext;
10071 file.header.res44 = 0x20;
10072 file.header.res48 = 0x80;
10073 file.header.dispatchpos = This->dispatch_href;
10074
10076 /* do name and string compilation to get offsets for other compilations */
10078 if (FAILED(hres)){
10080 return hres;
10081 }
10082
10084 if (FAILED(hres)){
10086 return hres;
10087 }
10088
10091 if (FAILED(hres)){
10093 return hres;
10094 }
10095
10096 if(This->HelpFile)
10097 file.header.helpfile = This->HelpFile->offset;
10098 else
10099 file.header.helpfile = -1;
10100
10101 if(This->DocString)
10102 file.header.helpstring = This->DocString->offset;
10103 else
10104 file.header.helpstring = -1;
10105
10106 /* do some more segment compilation */
10107 file.header.nimpinfos = list_count(&This->ref_list);
10108 file.header.nrtypeinfos = This->TypeInfoCount;
10109
10110 if(This->Name)
10111 file.header.NameOffset = This->Name->offset;
10112 else
10113 file.header.NameOffset = -1;
10114
10115 file.header.CustomDataOffset = WMSFT_compile_custdata(&This->custdata_list, &file);
10116
10117 if(This->guid)
10118 file.header.posguid = This->guid->offset;
10119 else
10120 file.header.posguid = -1;
10121
10122 junk_size = file.header.nrtypeinfos * sizeof(DWORD);
10123 if(file.header.varflags & HELPDLLFLAG)
10124 junk_size += sizeof(DWORD);
10125 if(junk_size){
10126 junk = calloc(1, junk_size);
10127 if(file.header.varflags & HELPDLLFLAG){
10128 *junk = This->HelpStringDll->offset;
10129 junk_offs = 1;
10130 }else
10131 junk_offs = 0;
10132 }else{
10133 junk = NULL;
10134 junk_offs = 0;
10135 }
10136
10137 WMSFT_compile_typeinfo_seg(This, &file, junk + junk_offs);
10139
10140 running_offset = 0;
10141
10142 TRACE("header at: 0x%lx\n", running_offset);
10143 running_offset += sizeof(file.header);
10144
10145 TRACE("junk at: 0x%lx\n", running_offset);
10146 running_offset += junk_size;
10147
10148 TRACE("segdir at: 0x%lx\n", running_offset);
10149 running_offset += sizeof(file.segdir);
10150
10151 TRACE("typeinfo at: 0x%lx\n", running_offset);
10152 tmp_fill_segdir_seg(&file.segdir.pTypeInfoTab, &file.typeinfo_seg, &running_offset);
10153
10154 TRACE("guidhashtab at: 0x%lx\n", running_offset);
10155 tmp_fill_segdir_seg(&file.segdir.pGuidHashTab, &file.guidhash_seg, &running_offset);
10156
10157 TRACE("guidtab at: 0x%lx\n", running_offset);
10158 tmp_fill_segdir_seg(&file.segdir.pGuidTab, &file.guid_seg, &running_offset);
10159
10160 TRACE("reftab at: 0x%lx\n", running_offset);
10161 tmp_fill_segdir_seg(&file.segdir.pRefTab, &file.ref_seg, &running_offset);
10162
10163 TRACE("impinfo at: 0x%lx\n", running_offset);
10164 tmp_fill_segdir_seg(&file.segdir.pImpInfo, &file.impinfo_seg, &running_offset);
10165
10166 TRACE("impfiles at: 0x%lx\n", running_offset);
10167 tmp_fill_segdir_seg(&file.segdir.pImpFiles, &file.impfile_seg, &running_offset);
10168
10169 TRACE("namehashtab at: 0x%lx\n", running_offset);
10170 tmp_fill_segdir_seg(&file.segdir.pNameHashTab, &file.namehash_seg, &running_offset);
10171
10172 TRACE("nametab at: 0x%lx\n", running_offset);
10173 tmp_fill_segdir_seg(&file.segdir.pNametab, &file.name_seg, &running_offset);
10174
10175 TRACE("stringtab at: 0x%lx\n", running_offset);
10176 tmp_fill_segdir_seg(&file.segdir.pStringtab, &file.string_seg, &running_offset);
10177
10178 TRACE("typdesc at: 0x%lx\n", running_offset);
10179 tmp_fill_segdir_seg(&file.segdir.pTypdescTab, &file.typdesc_seg, &running_offset);
10180
10181 TRACE("arraydescriptions at: 0x%lx\n", running_offset);
10182 tmp_fill_segdir_seg(&file.segdir.pArrayDescriptions, &file.arraydesc_seg, &running_offset);
10183
10184 TRACE("custdata at: 0x%lx\n", running_offset);
10185 tmp_fill_segdir_seg(&file.segdir.pCustData, &file.custdata_seg, &running_offset);
10186
10187 TRACE("cdguids at: 0x%lx\n", running_offset);
10188 tmp_fill_segdir_seg(&file.segdir.pCDGuids, &file.cdguids_seg, &running_offset);
10189
10190 TRACE("res0e at: 0x%lx\n", running_offset);
10191 tmp_fill_segdir_seg(&file.segdir.res0e, NULL, &running_offset);
10192
10193 TRACE("res0f at: 0x%lx\n", running_offset);
10194 tmp_fill_segdir_seg(&file.segdir.res0f, NULL, &running_offset);
10195
10196 TRACE("aux_seg at: 0x%lx\n", running_offset);
10197
10198 WMSFT_fixup_typeinfos(This, &file, running_offset);
10199
10204 free(junk);
10205 return TYPE_E_IOERROR;
10206 }
10207
10208 br = WriteFile(outfile, &file.header, sizeof(file.header), &written, NULL);
10209 if (!br) {
10212 free(junk);
10213 return TYPE_E_IOERROR;
10214 }
10215
10216 br = WriteFile(outfile, junk, junk_size, &written, NULL);
10217 free(junk);
10218 if (!br) {
10221 return TYPE_E_IOERROR;
10222 }
10223
10224 br = WriteFile(outfile, &file.segdir, sizeof(file.segdir), &written, NULL);
10225 if (!br) {
10228 return TYPE_E_IOERROR;
10229 }
10230
10231 WMSFT_write_segment(outfile, &file.typeinfo_seg);
10232 WMSFT_write_segment(outfile, &file.guidhash_seg);
10233 WMSFT_write_segment(outfile, &file.guid_seg);
10234 WMSFT_write_segment(outfile, &file.ref_seg);
10235 WMSFT_write_segment(outfile, &file.impinfo_seg);
10236 WMSFT_write_segment(outfile, &file.impfile_seg);
10237 WMSFT_write_segment(outfile, &file.namehash_seg);
10238 WMSFT_write_segment(outfile, &file.name_seg);
10239 WMSFT_write_segment(outfile, &file.string_seg);
10240 WMSFT_write_segment(outfile, &file.typdesc_seg);
10241 WMSFT_write_segment(outfile, &file.arraydesc_seg);
10242 WMSFT_write_segment(outfile, &file.custdata_seg);
10243 WMSFT_write_segment(outfile, &file.cdguids_seg);
10244 WMSFT_write_segment(outfile, &file.aux_seg);
10245
10247
10249
10250 return S_OK;
10251}
10252
10254 LPOLESTR name)
10255{
10257 FIXME("%p %s - stub\n", This, wine_dbgstr_w(name));
10258 return E_NOTIMPL;
10259}
10260
10262 REFGUID guid, VARIANT *varVal)
10263{
10265 TLBGuid *tlbguid;
10266
10267 TRACE("%p %s %p\n", This, debugstr_guid(guid), varVal);
10268
10269 if (!guid || !varVal)
10270 return E_INVALIDARG;
10271
10272 tlbguid = TLB_append_guid(&This->guid_list, guid, -1);
10273
10274 return TLB_set_custdata(&This->custdata_list, tlbguid, varVal);
10275}
10276
10278 ULONG helpStringContext)
10279{
10280 FIXME("%p, %lu - stub\n", iface, helpStringContext);
10281 return E_NOTIMPL;
10282}
10283
10285 LPOLESTR filename)
10286{
10288 TRACE("%p %s\n", This, wine_dbgstr_w(filename));
10289
10290 if (!filename)
10291 return E_INVALIDARG;
10292
10293 This->HelpStringDll = TLB_append_str(&This->string_list, filename);
10294
10295 return S_OK;
10296}
10297
10298static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl = {
10316};
10317
10319 REFIID riid, void **object)
10320{
10322
10323 return ITypeInfo2_QueryInterface(&This->ITypeInfo2_iface, riid, object);
10324}
10325
10327{
10329
10330 return ITypeInfo2_AddRef(&This->ITypeInfo2_iface);
10331}
10332
10334{
10336
10337 return ITypeInfo2_Release(&This->ITypeInfo2_iface);
10338}
10339
10341 REFGUID guid)
10342{
10344
10345 TRACE("%p %s\n", This, debugstr_guid(guid));
10346
10347 This->guid = TLB_append_guid(&This->pTypeLib->guid_list, guid, This->hreftype);
10348
10349 return S_OK;
10350}
10351
10353 UINT typeFlags)
10354{
10356 WORD old_flags;
10357 HRESULT hres;
10358
10359 TRACE("%p %x\n", This, typeFlags);
10360
10361 if (typeFlags & TYPEFLAG_FDUAL) {
10364 HREFTYPE hreftype;
10365 HRESULT hres;
10366
10367 hres = LoadTypeLib(L"stdole2.tlb", &stdole);
10368 if(FAILED(hres))
10369 return hres;
10370
10371 hres = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &dispatch);
10372 ITypeLib_Release(stdole);
10373 if(FAILED(hres))
10374 return hres;
10375
10376 hres = ICreateTypeInfo2_AddRefTypeInfo(iface, dispatch, &hreftype);
10377 ITypeInfo_Release(dispatch);
10378 if(FAILED(hres))
10379 return hres;
10380 }
10381
10382 old_flags = This->typeattr.wTypeFlags;
10383 This->typeattr.wTypeFlags = typeFlags;
10384
10385 hres = ICreateTypeInfo2_LayOut(iface);
10386 if (FAILED(hres)) {
10387 This->typeattr.wTypeFlags = old_flags;
10388 return hres;
10389 }
10390
10391 return S_OK;
10392}
10393
10395 LPOLESTR doc)
10396{
10398
10399 TRACE("%p %s\n", This, wine_dbgstr_w(doc));
10400
10401 if (!doc)
10402 return E_INVALIDARG;
10403
10404 This->DocString = TLB_append_str(&This->pTypeLib->string_list, doc);
10405
10406 return S_OK;
10407}
10408
10410 DWORD helpContext)
10411{
10413
10414 TRACE("%p, %ld.\n", iface, helpContext);
10415
10416 This->dwHelpContext = helpContext;
10417
10418 return S_OK;
10419}
10420
10422 WORD majorVerNum, WORD minorVerNum)
10423{
10425
10426 TRACE("%p %d %d\n", This, majorVerNum, minorVerNum);
10427
10428 This->typeattr.wMajorVerNum = majorVerNum;
10429 This->typeattr.wMinorVerNum = minorVerNum;
10430
10431 return S_OK;
10432}
10433
10435 ITypeInfo *typeInfo, HREFTYPE *refType)
10436{
10438 UINT index;
10440 TLBRefType *ref_type;
10441 TLBImpLib *implib;
10442 TYPEATTR *typeattr;
10443 TLIBATTR *libattr;
10444 HRESULT hres;
10445
10446 TRACE("%p %p %p\n", This, typeInfo, refType);
10447
10448 if (!typeInfo || !refType)
10449 return E_INVALIDARG;
10450
10451 hres = ITypeInfo_GetContainingTypeLib(typeInfo, &container, &index);
10452 if (FAILED(hres))
10453 return hres;
10454
10455 if (container == (ITypeLib*)&This->pTypeLib->ITypeLib2_iface) {
10457
10458 ITypeLib_Release(container);
10459
10460 *refType = target->hreftype;
10461
10462 return S_OK;
10463 }
10464
10465 hres = ITypeLib_GetLibAttr(container, &libattr);
10466 if (FAILED(hres)) {
10467 ITypeLib_Release(container);
10468 return hres;
10469 }
10470
10471 LIST_FOR_EACH_ENTRY(implib, &This->pTypeLib->implib_list, TLBImpLib, entry){
10472 if(IsEqualGUID(&implib->guid->guid, &libattr->guid) &&
10473 implib->lcid == libattr->lcid &&
10474 implib->wVersionMajor == libattr->wMajorVerNum &&
10475 implib->wVersionMinor == libattr->wMinorVerNum)
10476 break;
10477 }
10478
10479 if(&implib->entry == &This->pTypeLib->implib_list){
10480 implib = calloc(1, sizeof(TLBImpLib));
10481
10482 if((ITypeLib2Vtbl*)container->lpVtbl == &tlbvt){
10483 const ITypeLibImpl *our_container = impl_from_ITypeLib2((ITypeLib2*)container);
10484 implib->name = SysAllocString(our_container->path);
10485 }else{
10486 hres = QueryPathOfRegTypeLib(&libattr->guid, libattr->wMajorVerNum,
10487 libattr->wMinorVerNum, libattr->lcid, &implib->name);
10488 if(FAILED(hres)){
10489 implib->name = NULL;
10490 TRACE("QueryPathOfRegTypeLib failed, no name stored: %#lx.\n", hres);
10491 }
10492 }
10493
10494 implib->guid = TLB_append_guid(&This->pTypeLib->guid_list, &libattr->guid, 2);
10495 implib->lcid = libattr->lcid;
10496 implib->wVersionMajor = libattr->wMajorVerNum;
10497 implib->wVersionMinor = libattr->wMinorVerNum;
10498
10499 list_add_tail(&This->pTypeLib->implib_list, &implib->entry);
10500 }
10501
10502 ITypeLib_ReleaseTLibAttr(container, libattr);
10503 ITypeLib_Release(container);
10504
10505 hres = ITypeInfo_GetTypeAttr(typeInfo, &typeattr);
10506 if (FAILED(hres))
10507 return hres;
10508
10509 index = 0;
10510 LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry){
10511 if(ref_type->index == TLB_REF_USE_GUID &&
10512 IsEqualGUID(&ref_type->guid->guid, &typeattr->guid) &&
10513 ref_type->tkind == typeattr->typekind)
10514 break;
10515 ++index;
10516 }
10517
10518 if(&ref_type->entry == &This->pTypeLib->ref_list){
10519 ref_type = calloc(1, sizeof(TLBRefType));
10520
10521 ref_type->tkind = typeattr->typekind;
10522 ref_type->pImpTLInfo = implib;
10523 ref_type->reference = index * sizeof(MSFT_ImpInfo);
10524
10525 ref_type->index = TLB_REF_USE_GUID;
10526
10527 ref_type->guid = TLB_append_guid(&This->pTypeLib->guid_list, &typeattr->guid, ref_type->reference+1);
10528
10529 list_add_tail(&This->pTypeLib->ref_list, &ref_type->entry);
10530 }
10531
10532 ITypeInfo_ReleaseTypeAttr(typeInfo, typeattr);
10533
10534 *refType = ref_type->reference | 0x1;
10535
10536 if(IsEqualGUID(&ref_type->guid->guid, &IID_IDispatch))
10537 This->pTypeLib->dispatch_href = *refType;
10538
10539 return S_OK;
10540}
10541
10543 UINT index, FUNCDESC *funcDesc)
10544{
10546 TLBFuncDesc tmp_func_desc, *func_desc;
10547 int buf_size, i;
10548 char *buffer;
10549 HRESULT hres;
10550
10551 TRACE("%p %u %p\n", This, index, funcDesc);
10552
10553 if (!funcDesc || funcDesc->oVft & 3)
10554 return E_INVALIDARG;
10555
10556 switch (This->typeattr.typekind) {
10557 case TKIND_MODULE:
10558 if (funcDesc->funckind != FUNC_STATIC)
10559 return TYPE_E_BADMODULEKIND;
10560 break;
10561 case TKIND_DISPATCH:
10562 if (funcDesc->funckind != FUNC_DISPATCH)
10563 return TYPE_E_BADMODULEKIND;
10564 break;
10565 default:
10566 if (funcDesc->funckind != FUNC_PUREVIRTUAL)
10567 return TYPE_E_BADMODULEKIND;
10568 }
10569
10570 if (index > This->typeattr.cFuncs)
10572
10573 if (funcDesc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF) &&
10574 !funcDesc->cParams)
10576
10577 if(This->pTypeLib->syskind == SYS_WIN64 &&
10578 funcDesc->oVft % 8 != 0)
10579 return E_INVALIDARG;
10580
10581 memset(&tmp_func_desc, 0, sizeof(tmp_func_desc));
10582 TLBFuncDesc_Constructor(&tmp_func_desc);
10583
10584 tmp_func_desc.funcdesc = *funcDesc;
10585
10586 if (tmp_func_desc.funcdesc.oVft != 0)
10587 tmp_func_desc.funcdesc.oVft |= 1;
10588
10589 if (funcDesc->cScodes && funcDesc->lprgscode) {
10590 tmp_func_desc.funcdesc.lprgscode = malloc(sizeof(SCODE) * funcDesc->cScodes);
10591 memcpy(tmp_func_desc.funcdesc.lprgscode, funcDesc->lprgscode, sizeof(SCODE) * funcDesc->cScodes);
10592 } else {
10593 tmp_func_desc.funcdesc.lprgscode = NULL;
10594 tmp_func_desc.funcdesc.cScodes = 0;
10595 }
10596
10597 buf_size = TLB_SizeElemDesc(&funcDesc->elemdescFunc);
10598 for (i = 0; i < funcDesc->cParams; ++i) {
10599 buf_size += sizeof(ELEMDESC);
10600 buf_size += TLB_SizeElemDesc(funcDesc->lprgelemdescParam + i);
10601 }
10602 tmp_func_desc.funcdesc.lprgelemdescParam = malloc(buf_size);
10603 buffer = (char*)(tmp_func_desc.funcdesc.lprgelemdescParam + funcDesc->cParams);
10604
10605 hres = TLB_CopyElemDesc(&funcDesc->elemdescFunc, &tmp_func_desc.funcdesc.elemdescFunc, &buffer);
10606 if (FAILED(hres)) {
10607 free(tmp_func_desc.funcdesc.lprgelemdescParam);
10608 free(tmp_func_desc.funcdesc.lprgscode);
10609 return hres;
10610 }
10611
10612 for (i = 0; i < funcDesc->cParams; ++i) {
10613 hres = TLB_CopyElemDesc(funcDesc->lprgelemdescParam + i,
10614 tmp_func_desc.funcdesc.lprgelemdescParam + i, &buffer);
10615 if (FAILED(hres)) {
10616 free(tmp_func_desc.funcdesc.lprgelemdescParam);
10617 free(tmp_func_desc.funcdesc.lprgscode);
10618 return hres;
10619 }
10620 if (tmp_func_desc.funcdesc.lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT &&
10621 tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_VARIANT &&
10622 tmp_func_desc.funcdesc.lprgelemdescParam[i].tdesc.vt != VT_USERDEFINED){
10623 hres = TLB_SanitizeVariant(&tmp_func_desc.funcdesc.lprgelemdescParam[i].paramdesc.pparamdescex->varDefaultValue);
10624 if (FAILED(hres)) {
10625 free(tmp_func_desc.funcdesc.lprgelemdescParam);
10626 free(tmp_func_desc.funcdesc.lprgscode);
10627 return hres;
10628 }
10629 }
10630 }
10631
10632 tmp_func_desc.pParamDesc = TLBParDesc_Constructor(funcDesc->cParams);
10633
10634 if (This->funcdescs) {
10635 This->funcdescs = realloc(This->funcdescs, sizeof(TLBFuncDesc) * (This->typeattr.cFuncs + 1));
10636
10637 if (index < This->typeattr.cFuncs) {
10638 memmove(This->funcdescs + index + 1, This->funcdescs + index,
10639 (This->typeattr.cFuncs - index) * sizeof(TLBFuncDesc));
10640 func_desc = This->funcdescs + index;
10641 } else
10642 func_desc = This->funcdescs + This->typeattr.cFuncs;
10643
10644 /* move custdata lists to the new memory location */
10645 for(i = 0; i < This->typeattr.cFuncs + 1; ++i){
10646 if(index != i)
10647 TLB_relink_custdata(&This->funcdescs[i].custdata_list);
10648 }
10649 } else
10650 func_desc = This->funcdescs = malloc(sizeof(TLBFuncDesc));
10651
10652 memcpy(func_desc, &tmp_func_desc, sizeof(tmp_func_desc));
10653 list_init(&func_desc->custdata_list);
10654
10655 ++This->typeattr.cFuncs;
10656
10657 This->needs_layout = TRUE;
10658
10659 return S_OK;
10660}
10661
10663 UINT index, HREFTYPE refType)
10664{
10666 TLBImplType *impl_type;
10667 HRESULT hres;
10668
10669 TRACE("%p, %u, %ld.\n", iface, index, refType);
10670
10671 switch(This->typeattr.typekind){
10672 case TKIND_COCLASS: {
10673 if (index == -1) {
10674 FIXME("Unhandled index: -1\n");
10675 return E_NOTIMPL;
10676 }
10677
10678 if(index != This->typeattr.cImplTypes)
10680
10681 break;
10682 }
10683 case TKIND_INTERFACE:
10684 case TKIND_DISPATCH:
10685 if (index != 0 || This->typeattr.cImplTypes)
10687 break;
10688 default:
10689 FIXME("Unimplemented typekind: %d\n", This->typeattr.typekind);
10690 return E_NOTIMPL;
10691 }
10692
10693 if (This->impltypes){
10694 UINT i;
10695
10696 This->impltypes = realloc(This->impltypes, sizeof(TLBImplType) * (This->typeattr.cImplTypes + 1));
10697
10698 if (index < This->typeattr.cImplTypes) {
10699 memmove(This->impltypes + index + 1, This->impltypes + index,
10700 (This->typeattr.cImplTypes - index) * sizeof(TLBImplType));
10701 impl_type = This->impltypes + index;
10702 } else
10703 impl_type = This->impltypes + This->typeattr.cImplTypes;
10704
10705 /* move custdata lists to the new memory location */
10706 for(i = 0; i < This->typeattr.cImplTypes + 1; ++i){
10707 if(index != i)
10708 TLB_relink_custdata(&This->impltypes[i].custdata_list);
10709 }
10710 } else
10711 impl_type = This->impltypes = malloc(sizeof(TLBImplType));
10712
10713 memset(impl_type, 0, sizeof(TLBImplType));
10714 TLBImplType_Constructor(impl_type);
10715 impl_type->hRef = refType;
10716
10717 ++This->typeattr.cImplTypes;
10718
10719 if((refType & (~0x3)) == (This->pTypeLib->dispatch_href & (~0x3)))
10720 This->typeattr.wTypeFlags |= TYPEFLAG_FDISPATCHABLE;
10721
10722 hres = ICreateTypeInfo2_LayOut(iface);
10723 if (FAILED(hres))
10724 return hres;
10725
10726 return S_OK;
10727}
10728
10730 UINT index, INT implTypeFlags)
10731{
10733 TLBImplType *impl_type = &This->impltypes[index];
10734
10735 TRACE("%p %u %x\n", This, index, implTypeFlags);
10736
10737 if (This->typeattr.typekind != TKIND_COCLASS)
10738 return TYPE_E_BADMODULEKIND;
10739
10740 if (index >= This->typeattr.cImplTypes)
10742
10743 impl_type->implflags = implTypeFlags;
10744
10745 return S_OK;
10746}
10747
10750{
10752
10753 TRACE("%p %d\n", This, alignment);
10754
10755 This->typeattr.cbAlignment = alignment;
10756
10757 return S_OK;
10758}
10759
10761 LPOLESTR schema)
10762{
10764
10765 TRACE("%p %s\n", This, wine_dbgstr_w(schema));
10766
10767 if (!schema)
10768 return E_INVALIDARG;
10769
10770 This->Schema = TLB_append_str(&This->pTypeLib->string_list, schema);
10771
10772 This->typeattr.lpstrSchema = This->Schema->str;
10773
10774 return S_OK;
10775}
10776
10778 UINT index, VARDESC *varDesc)
10779{
10781 TLBVarDesc *var_desc;
10782 HRESULT hr;
10783
10784 TRACE("%p %u %p\n", This, index, varDesc);
10785
10786 if (This->vardescs){
10787 UINT i;
10788
10789 This->vardescs = realloc(This->vardescs, sizeof(TLBVarDesc) * (This->typeattr.cVars + 1));
10790
10791 if (index < This->typeattr.cVars) {
10792 memmove(This->vardescs + index + 1, This->vardescs + index,
10793 (This->typeattr.cVars - index) * sizeof(TLBVarDesc));
10794 var_desc = This->vardescs + index;
10795 } else {
10796 var_desc = This->vardescs + This->typeattr.cVars;
10797 memset(var_desc, 0, sizeof(TLBVarDesc));
10798 }
10799
10800 /* move custdata lists to the new memory location */
10801 for(i = 0; i < This->typeattr.cVars + 1; ++i){
10802 if(index != i)
10803 TLB_relink_custdata(&This->vardescs[i].custdata_list);
10804 }
10805 } else
10806 var_desc = This->vardescs = calloc(1, sizeof(TLBVarDesc));
10807
10808 TLBVarDesc_Constructor(var_desc);
10809 hr = TLB_AllocAndInitVarDesc(varDesc, &var_desc->vardesc_create);
10810 if (FAILED(hr))
10811 return hr;
10812 var_desc->vardesc = *var_desc->vardesc_create;
10813
10814 ++This->typeattr.cVars;
10815
10816 This->needs_layout = TRUE;
10817
10818 return S_OK;
10819}
10820
10822 UINT index, LPOLESTR *names, UINT numNames)
10823{
10825 TLBFuncDesc *func_desc = &This->funcdescs[index];
10826 int i;
10827
10828 TRACE("%p %u %p %u\n", This, index, names, numNames);
10829
10830 if (!names)
10831 return E_INVALIDARG;
10832
10833 if (index >= This->typeattr.cFuncs || numNames == 0)
10835
10836 if (func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)){
10837 if(numNames > func_desc->funcdesc.cParams)
10839 } else
10840 if(numNames > func_desc->funcdesc.cParams + 1)
10842
10843 for(i = 0; i < This->typeattr.cFuncs; ++i) {
10844 TLBFuncDesc *iter = &This->funcdescs[i];
10845 if (iter->Name && !wcscmp(TLB_get_bstr(iter->Name), *names)) {
10846 if (iter->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) &&
10847 func_desc->funcdesc.invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF | INVOKE_PROPERTYGET) &&
10848 func_desc->funcdesc.invkind != iter->funcdesc.invkind)
10849 continue;
10850 return TYPE_E_AMBIGUOUSNAME;
10851 }
10852 }
10853
10854 func_desc->Name = TLB_append_str(&This->pTypeLib->name_list, *names);
10855
10856 for (i = 1; i < numNames; ++i) {
10857 TLBParDesc *par_desc = func_desc->pParamDesc + i - 1;
10858 par_desc->Name = TLB_append_str(&This->pTypeLib->name_list, *(names + i));
10859 }
10860
10861 return S_OK;
10862}
10863
10865 UINT index, LPOLESTR name)
10866{
10868
10869 TRACE("%p %u %s\n", This, index, wine_dbgstr_w(name));
10870
10871 if(!name)
10872 return E_INVALIDARG;
10873
10874 if(index >= This->typeattr.cVars)
10876
10877 This->vardescs[index].Name = TLB_append_str(&This->pTypeLib->name_list, name);
10878 return S_OK;
10879}
10880
10882 TYPEDESC *tdescAlias)
10883{
10885 HRESULT hr;
10886
10887 TRACE("%p %p\n", This, tdescAlias);
10888
10889 if(!tdescAlias)
10890 return E_INVALIDARG;
10891
10892 if(This->typeattr.typekind != TKIND_ALIAS)
10893 return TYPE_E_BADMODULEKIND;
10894
10895 hr = TLB_size_instance(This, This->pTypeLib->syskind, tdescAlias, &This->typeattr.cbSizeInstance, &This->typeattr.cbAlignment);
10896 if(FAILED(hr))
10897 return hr;
10898
10899 free(This->tdescAlias);
10900 This->tdescAlias = malloc(TLB_SizeTypeDesc(tdescAlias, TRUE));
10901 TLB_CopyTypeDesc(NULL, tdescAlias, This->tdescAlias);
10902
10903 return S_OK;
10904}
10905
10907 UINT index, LPOLESTR dllName, LPOLESTR procName)
10908{
10910 FIXME("%p %u %s %s - stub\n", This, index, wine_dbgstr_w(dllName), wine_dbgstr_w(procName));
10911 return E_NOTIMPL;
10912}
10913
10915 UINT index, LPOLESTR docString)
10916{
10918 TLBFuncDesc *func_desc = &This->funcdescs[index];
10919
10920 TRACE("%p %u %s\n", This, index, wine_dbgstr_w(docString));
10921
10922 if(!docString)
10923 return E_INVALIDARG;
10924
10925 if(index >= This->typeattr.cFuncs)
10927
10928 func_desc->HelpString = TLB_append_str(&This->pTypeLib->string_list, docString);
10929
10930 return S_OK;
10931}
10932
10934 UINT index, LPOLESTR docString)
10935{
10937 TLBVarDesc *var_desc = &This->vardescs[index];
10938
10939 TRACE("%p %u %s\n", This, index, wine_dbgstr_w(docString));
10940
10941 if(!docString)
10942 return E_INVALIDARG;
10943
10944 if(index >= This->typeattr.cVars)
10946
10947 var_desc->HelpString = TLB_append_str(&This->pTypeLib->string_list, docString);
10948
10949 return S_OK;
10950}
10951
10953 UINT index, DWORD helpContext)
10954{
10956 TLBFuncDesc *func_desc = &This->funcdescs[index];
10957
10958 TRACE("%p, %u, %ld.\n", iface, index, helpContext);
10959
10960 if(index >= This->typeattr.cFuncs)
10962
10963 func_desc->helpcontext = helpContext;
10964
10965 return S_OK;
10966}
10967
10969 UINT index, DWORD helpContext)
10970{
10972 TLBVarDesc *var_desc = &This->vardescs[index];
10973
10974 TRACE("%p, %u, %ld.\n", iface, index, helpContext);
10975
10976 if(index >= This->typeattr.cVars)
10978
10979 var_desc->HelpContext = helpContext;
10980
10981 return S_OK;
10982}
10983
10985 UINT index, BSTR bstrMops)
10986{
10988 FIXME("%p %u %s - stub\n", This, index, wine_dbgstr_w(bstrMops));
10989 return E_NOTIMPL;
10990}
10991
10993 IDLDESC *idlDesc)
10994{
10996
10997 TRACE("%p %p\n", This, idlDesc);
10998
10999 if (!idlDesc)
11000 return E_INVALIDARG;
11001
11002 This->typeattr.idldescType.dwReserved = idlDesc->dwReserved;
11003 This->typeattr.idldescType.wIDLFlags = idlDesc->wIDLFlags;
11004
11005 return S_OK;
11006}
11007
11009{
11011 ITypeInfo2 *tinfo = &This->ITypeInfo2_iface;
11012 TLBFuncDesc *func_desc;
11013 UINT user_vft = 0, i, depth = 0;
11014 HRESULT hres = S_OK;
11015
11016 TRACE("%p\n", This);
11017
11018 This->needs_layout = FALSE;
11019
11020 if (This->typeattr.typekind == TKIND_INTERFACE) {
11021 ITypeInfo *inh;
11022 TYPEATTR *attr;
11023 HREFTYPE inh_href;
11024
11025 hres = ITypeInfo2_GetRefTypeOfImplType(tinfo, 0, &inh_href);
11026
11027 if (SUCCEEDED(hres)) {
11028 hres = ITypeInfo2_GetRefTypeInfo(tinfo, inh_href, &inh);
11029
11030 if (SUCCEEDED(hres)) {
11031 hres = ITypeInfo_GetTypeAttr(inh, &attr);
11032 if (FAILED(hres)) {
11033 ITypeInfo_Release(inh);
11034 return hres;
11035 }
11036 This->typeattr.cbSizeVft = attr->cbSizeVft;
11037 ITypeInfo_ReleaseTypeAttr(inh, attr);
11038
11039 do{
11040 ++depth;
11041 hres = ITypeInfo_GetRefTypeOfImplType(inh, 0, &inh_href);
11042 if(SUCCEEDED(hres)){
11043 ITypeInfo *next;
11044 hres = ITypeInfo_GetRefTypeInfo(inh, inh_href, &next);
11045 if(SUCCEEDED(hres)){
11046 ITypeInfo_Release(inh);
11047 inh = next;
11048 }
11049 }
11050 }while(SUCCEEDED(hres));
11051 hres = S_OK;
11052
11053 ITypeInfo_Release(inh);
11054 } else if (hres == TYPE_E_ELEMENTNOTFOUND) {
11055 This->typeattr.cbSizeVft = 0;
11056 hres = S_OK;
11057 } else
11058 return hres;
11059 } else if (hres == TYPE_E_ELEMENTNOTFOUND) {
11060 This->typeattr.cbSizeVft = 0;
11061 hres = S_OK;
11062 } else
11063 return hres;
11064 } else if (This->typeattr.typekind == TKIND_DISPATCH)
11065 This->typeattr.cbSizeVft = 7 * This->pTypeLib->ptr_size;
11066 else
11067 This->typeattr.cbSizeVft = 0;
11068
11069 func_desc = This->funcdescs;
11070 i = 0;
11071 while (i < This->typeattr.cFuncs) {
11072 if (!(func_desc->funcdesc.oVft & 0x1))
11073 func_desc->funcdesc.oVft = This->typeattr.cbSizeVft;
11074
11075 if ((func_desc->funcdesc.oVft & 0xFFFC) > user_vft)
11076 user_vft = func_desc->funcdesc.oVft & 0xFFFC;
11077
11078 This->typeattr.cbSizeVft += This->pTypeLib->ptr_size;
11079
11080 if (func_desc->funcdesc.memid == MEMBERID_NIL) {
11081 TLBFuncDesc *iter;
11082 UINT j = 0;
11083 BOOL reset = FALSE;
11084
11085 func_desc->funcdesc.memid = 0x60000000 + (depth << 16) + i;
11086
11087 iter = This->funcdescs;
11088 while (j < This->typeattr.cFuncs) {
11089 if (iter != func_desc && iter->funcdesc.memid == func_desc->funcdesc.memid) {
11090 if (!reset) {
11091 func_desc->funcdesc.memid = 0x60000000 + (depth << 16) + This->typeattr.cFuncs;
11092 reset = TRUE;
11093 } else
11094 ++func_desc->funcdesc.memid;
11095 iter = This->funcdescs;
11096 j = 0;
11097 } else {
11098 ++iter;
11099 ++j;
11100 }
11101 }
11102 }
11103
11104 ++func_desc;
11105 ++i;
11106 }
11107
11108 if (user_vft > This->typeattr.cbSizeVft)
11109 This->typeattr.cbSizeVft = user_vft + This->pTypeLib->ptr_size;
11110
11111 for(i = 0; i < This->typeattr.cVars; ++i){
11112 TLBVarDesc *var_desc = &This->vardescs[i];
11113 if(var_desc->vardesc.memid == MEMBERID_NIL){
11114 UINT j = 0;
11115 BOOL reset = FALSE;
11116 TLBVarDesc *iter;
11117
11118 var_desc->vardesc.memid = 0x40000000 + (depth << 16) + i;
11119
11120 iter = This->vardescs;
11121 while (j < This->typeattr.cVars) {
11122 if (iter != var_desc && iter->vardesc.memid == var_desc->vardesc.memid) {
11123 if (!reset) {
11124 var_desc->vardesc.memid = 0x40000000 + (depth << 16) + This->typeattr.cVars;
11125 reset = TRUE;
11126 } else
11127 ++var_desc->vardesc.memid;
11128 iter = This->vardescs;
11129 j = 0;
11130 } else {
11131 ++iter;
11132 ++j;
11133 }
11134 }
11135 }
11136 }
11137
11138 return hres;
11139}
11140
11142 UINT index)
11143{
11145 unsigned int i;
11146
11147 TRACE("%p %u\n", This, index);
11148
11149 if (index >= This->typeattr.cFuncs)
11151
11152 typeinfo_release_funcdesc(&This->funcdescs[index]);
11153
11154 --This->typeattr.cFuncs;
11155 if (index != This->typeattr.cFuncs)
11156 {
11157 memmove(This->funcdescs + index, This->funcdescs + index + 1,
11158 sizeof(*This->funcdescs) * (This->typeattr.cFuncs - index));
11159 for (i = index; i < This->typeattr.cFuncs; ++i)
11160 TLB_relink_custdata(&This->funcdescs[i].custdata_list);
11161 }
11162
11163 This->needs_layout = TRUE;
11164
11165 return S_OK;
11166}
11167
11169 MEMBERID memid, INVOKEKIND invKind)
11170{
11171 FIXME("%p, %#lx, %d - stub\n", iface, memid, invKind);
11172 return E_NOTIMPL;
11173}
11174
11176 UINT index)
11177{
11178 FIXME("%p, %u - stub\n", iface, index);
11179 return E_NOTIMPL;
11180}
11181
11183 MEMBERID memid)
11184{
11185 FIXME("%p, %#lx - stub\n", iface, memid);
11186 return E_NOTIMPL;
11187}
11188
11190 UINT index)
11191{
11193 int i;
11194
11195 TRACE("%p %u\n", This, index);
11196
11197 if (index >= This->typeattr.cImplTypes)
11199
11200 TLB_FreeCustData(&This->impltypes[index].custdata_list);
11201 --This->typeattr.cImplTypes;
11202
11203 if (index < This->typeattr.cImplTypes)
11204 {
11205 memmove(This->impltypes + index, This->impltypes + index + 1, (This->typeattr.cImplTypes - index) *
11206 sizeof(*This->impltypes));
11207 for (i = index; i < This->typeattr.cImplTypes; ++i)
11208 TLB_relink_custdata(&This->impltypes[i].custdata_list);
11209 }
11210
11211 return S_OK;
11212}
11213
11215 REFGUID guid, VARIANT *varVal)
11216{
11217 TLBGuid *tlbguid;
11218
11220
11221 TRACE("%p %s %p\n", This, debugstr_guid(guid), varVal);
11222
11223 if (!guid || !varVal)
11224 return E_INVALIDARG;
11225
11226 tlbguid = TLB_append_guid(&This->pTypeLib->guid_list, guid, -1);
11227
11228 return TLB_set_custdata(This->pcustdata_list, tlbguid, varVal);
11229}
11230
11232 UINT index, REFGUID guid, VARIANT *varVal)
11233{
11235 FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
11236 return E_NOTIMPL;
11237}
11238
11240 UINT funcIndex, UINT paramIndex, REFGUID guid, VARIANT *varVal)
11241{
11243 FIXME("%p %u %u %s %p - stub\n", This, funcIndex, paramIndex, debugstr_guid(guid), varVal);
11244 return E_NOTIMPL;
11245}
11246
11248 UINT index, REFGUID guid, VARIANT *varVal)
11249{
11251 FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
11252 return E_NOTIMPL;
11253}
11254
11256 UINT index, REFGUID guid, VARIANT *varVal)
11257{
11259 FIXME("%p %u %s %p - stub\n", This, index, debugstr_guid(guid), varVal);
11260 return E_NOTIMPL;
11261}
11262
11264 ULONG helpStringContext)
11265{
11267
11268 TRACE("%p, %lu.\n", iface, helpStringContext);
11269
11270 This->dwHelpStringContext = helpStringContext;
11271
11272 return S_OK;
11273}
11274
11276 UINT index, ULONG helpStringContext)
11277{
11278 FIXME("%p, %u, %lu - stub\n", iface, index, helpStringContext);
11279 return E_NOTIMPL;
11280}
11281
11283 UINT index, ULONG helpStringContext)
11284{
11285 FIXME("%p, %u, %lu - stub\n", iface, index, helpStringContext);
11286 return E_NOTIMPL;
11287}
11288
11290{
11291 FIXME("%p - stub\n", iface);
11292 return E_NOTIMPL;
11293}
11294
11296 LPOLESTR name)
11297{
11299
11300 TRACE("%p %s\n", This, wine_dbgstr_w(name));
11301
11302 if (!name)
11303 return E_INVALIDARG;
11304
11305 This->Name = TLB_append_str(&This->pTypeLib->name_list, name);
11306
11307 return S_OK;
11308}
11309
11310static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl = {
11352};
11353
11354/******************************************************************************
11355 * ClearCustData (OLEAUT32.171)
11356 *
11357 * Clear a custom data type's data.
11358 *
11359 * PARAMS
11360 * lpCust [I] The custom data type instance
11361 *
11362 * RETURNS
11363 * Nothing.
11364 */
11365void WINAPI ClearCustData(CUSTDATA *lpCust)
11366{
11367 if (lpCust && lpCust->cCustData)
11368 {
11369 if (lpCust->prgCustData)
11370 {
11371 DWORD i;
11372
11373 for (i = 0; i < lpCust->cCustData; i++)
11374 VariantClear(&lpCust->prgCustData[i].varValue);
11375
11376 CoTaskMemFree(lpCust->prgCustData);
11377 lpCust->prgCustData = NULL;
11378 }
11379 lpCust->cCustData = 0;
11380 }
11381}
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
unsigned short UINT16
Definition: actypes.h:129
short INT16
Definition: actypes.h:130
_Check_return_ _Ret_maybenull_ _In_ size_t alignment
Definition: align.cpp:48
#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
#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
struct list * next
Definition: list.h:38
struct list * prev
Definition: list.h:39
#define md
Definition: compat-1.3.h:2013
struct __type_info type_info
#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 realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_SUCCESS
Definition: deptool.c:10
static LPVOID LPUNKNOWN
Definition: dinput.c:53
#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
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
HRESULT WINAPI GetErrorInfo(ULONG reserved, IErrorInfo **error_info)
Definition: errorinfo.c:346
void *WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
#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 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 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 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 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
@ 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 lstrlenW
Definition: compat.h:750
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
BOOL WINAPI WriteFile(_In_ HANDLE hFile, _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, _In_ DWORD nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped)
Definition: rw.c:25
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:2232
DWORD WINAPI GetFinalPathNameByHandleW(_In_ HANDLE hFile, _Out_writes_(cchFilePath) LPWSTR lpszFilePath, _In_ DWORD cchFilePath, _In_ DWORD dwFlags)
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
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
LCID WINAPI GetSystemDefaultLCID(void)
Definition: locale.c:1235
#define IS_INTRESOURCE(x)
Definition: loader.c:613
LCID lcid
Definition: locale.c:5660
GUID guid
Definition: version.c:147
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
int CDECL isalnum(int c)
Definition: ctype.c:214
_ACRTIMP __msvcrt_long __cdecl wcstol(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2752
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define SEEK_CUR
Definition: stdio.h:44
_ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl sscanf(const char *, const char *,...) __WINE_CRT_SCANF_ATTR(2
_ACRTIMP __msvcrt_long __cdecl strtol(const char *, char **, int)
Definition: string.c:1838
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
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 SafeArrayAllocDescriptorEx(VARTYPE vt, UINT cDims, SAFEARRAY **ppsaOut)
Definition: safearray.c:521
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:1260
static void TLBFuncDesc_Constructor(TLBFuncDesc *func_desc)
Definition: typelib.c:1767
struct tagITypeInfoImpl ITypeInfoImpl
HRESULT WINAPI CreateTypeLib(SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib **ppctlib)
Definition: typelib.c:411
static HRESULT WINAPI ITypeLib2_fnGetTypeComp(ITypeLib2 *iface, ITypeComp **ppTComp)
Definition: typelib.c:4911
static TLBGuid * TLB_append_guid(struct list *guid_list, const GUID *new_guid, HREFTYPE hreftype)
Definition: typelib.c:1809
static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(ITypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8302
void WINAPI ClearCustData(CUSTDATA *lpCust)
Definition: typelib.c:11365
static SIZE_T TLB_SizeElemDesc(const ELEMDESC *elemdesc)
Definition: typelib.c:5703
static HRESULT WINAPI ITypeLib2_fnGetLibAttr(ITypeLib2 *iface, LPTLIBATTR *attr)
Definition: typelib.c:4882
static WCHAR * get_interface_key(REFGUID guid, WCHAR *buffer)
Definition: typelib.c:248
static HRESULT WINAPI ITypeInfo_fnGetVarDesc(ITypeInfo2 *iface, UINT index, LPVARDESC *ppVarDesc)
Definition: typelib.c:6053
static HRESULT MSFT_ReadAllGuids(TLBContext *pcx)
Definition: typelib.c:2071
static HRESULT WINAPI ITypeInfo_fnInvoke(ITypeInfo2 *iface, VOID *pIUnk, MEMBERID memid, UINT16 wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *pArgErr)
Definition: typelib.c:7034
static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(ITypeLib2 *iface, REFGUID guid, ITypeInfo **ppTInfo)
Definition: typelib.c:4856
static TLBGuid * MSFT_ReadGuid(int offset, TLBContext *pcx)
Definition: typelib.c:2096
static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(ITypeInfo2 *iface, MEMBERID memid, LCID lcid, BSTR *pbstrHelpString, DWORD *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
Definition: typelib.c:8334
static ULONG WINAPI TLB_Mapping_Release(IUnknown *iface)
Definition: typelib.c:3214
static WORD SLTG_ReadString(const char *ptr, const TLBString **pStr, ITypeLibImpl *lib)
Definition: typelib.c:3670
static void TLB_unregister_interface(GUID *guid, REGSAM flag)
Definition: typelib.c:820
static int TLB_str_memcmp(void *left, const TLBString *str, DWORD len)
Definition: typelib.c:1288
static WORD SLTG_ReadStringA(const char *ptr, char **str)
Definition: typelib.c:3690
static TLBVarDesc * TLB_get_vardesc_by_memberid(ITypeInfoImpl *typeinfo, MEMBERID memid)
Definition: typelib.c:1682
static void MSFT_ReadValue(VARIANT *pVar, int offset, TLBContext *pcx)
Definition: typelib.c:2204
static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 *iface)
Definition: typelib.c:10039
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType(ICreateTypeInfo2 *iface, UINT index)
Definition: typelib.c:11189
static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4242
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(ICreateTypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11231
static const ITypeCompVtbl tlbtcvt
Definition: typelib.c:1112
static void TLBVarDesc_Constructor(TLBVarDesc *var_desc)
Definition: typelib.c:1730
struct tagTLBString TLBString
static int MSFT_CustData(TLBContext *pcx, int offset, struct list *custdata_list)
Definition: typelib.c:2291
static TLBImplType * TLBImplType_Alloc(UINT n)
Definition: typelib.c:1793
static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface)
Definition: typelib.c:10333
static HRESULT WINAPI ITypeComp_fnQueryInterface(ITypeComp *iface, REFIID riid, LPVOID *ppv)
Definition: typelib.c:8659
static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4269
static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema(ICreateTypeInfo2 *iface, LPOLESTR schema)
Definition: typelib.c:10760
static HRESULT WINAPI ITypeComp_fnBindType(ITypeComp *iface, OLECHAR *szName, ULONG lHash, ITypeInfo **ppTInfo, ITypeComp **ppTComp)
Definition: typelib.c:8769
static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 *iface, REFGUID guid)
Definition: typelib.c:8943
static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(ITypeInfo2 *iface, UINT index, CUSTDATA *pCustData)
Definition: typelib.c:8409
static void WMSFT_free_file(WMSFT_TLBFile *file)
Definition: typelib.c:10021
static ITypeInfoImpl * TLB_get_typeinfo_by_name(ITypeLibImpl *typelib, const OLECHAR *name)
Definition: typelib.c:1717
static HRESULT WMSFT_fixup_typeinfos(ITypeLibImpl *This, WMSFT_TLBFile *file, DWORD file_len)
Definition: typelib.c:10007
static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId(ITypeInfo2 *iface, MEMBERID memid, UINT *pVarIndex)
Definition: typelib.c:8158
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext(ICreateTypeInfo2 *iface, UINT index, DWORD helpContext)
Definition: typelib.c:10952
static ITypeInfoImpl * MSFT_DoTypeInfo(TLBContext *pcx, int count, ITypeLibImpl *pLibInfo)
Definition: typelib.c:2655
#define FromLEDWords(X, Y)
Definition: typelib.c:165
static void tmp_fill_segdir_seg(MSFT_pSeg *segdir, WMSFT_SegContents *contents, DWORD *running_offset)
Definition: typelib.c:9984
static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib)
Definition: typelib.c:3282
static HRESULT MSFT_ReadAllStrings(TLBContext *pcx)
Definition: typelib.c:2759
static ULONG WINAPI ITypeInfo_fnAddRef(ITypeInfo2 *iface)
Definition: typelib.c:5567
static TLBFuncDesc * TLB_get_funcdesc_by_memberid(ITypeInfoImpl *typeinfo, MEMBERID memid)
Definition: typelib.c:1656
static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion(ICreateTypeInfo2 *iface, WORD majorVerNum, WORD minorVerNum)
Definition: typelib.c:10421
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT typeFlags)
Definition: typelib.c:10352
static HRESULT WMSFT_compile_guids(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9190
static HRESULT WINAPI ICreateTypeLib2_fnSetName(ICreateTypeLib2 *iface, LPOLESTR name)
Definition: typelib.c:8915
static char * SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, BOOL OneOnly, const sltg_ref_lookup_t *ref_lookup)
Definition: typelib.c:3962
static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd)
Definition: typelib.c:2313
static HRESULT WINAPI ITypeLibComp_fnBindType(ITypeComp *iface, OLECHAR *szName, ULONG lHash, ITypeInfo **ppTInfo, ITypeComp **ppTComp)
Definition: typelib.c:5473
static HRESULT TLB_set_custdata(struct list *custdata_list, TLBGuid *tlbguid, VARIANT *var)
Definition: typelib.c:1831
static void TLB_FreeVarDesc(VARDESC *)
Definition: typelib.c:5850
static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags(ITypeInfo2 *iface, ULONG *pTypeFlags)
Definition: typelib.c:8117
static void typeinfo_release_funcdesc(TLBFuncDesc *func)
Definition: typelib.c:5580
static HRESULT WINAPI TLB_PEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: typelib.c:2875
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 *iface, DWORD helpContext)
Definition: typelib.c:8985
static WCHAR * get_typelib_key(REFGUID guid, WORD wMaj, WORD wMin, WCHAR *buffer)
Definition: typelib.c:238
static HRESULT WINAPI ITypeLibComp_fnBind(ITypeComp *iface, OLECHAR *szName, ULONG lHash, WORD wFlags, ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
Definition: typelib.c:5334
static DWORD WMSFT_append_typedesc(TYPEDESC *desc, WMSFT_TLBFile *file, DWORD *out_mix, INT16 *out_size)
Definition: typelib.c:9347
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 *iface, LPOLESTR helpFileName)
Definition: typelib.c:8970
static const IUnknownVtbl TLB_Mapping_Vtable
Definition: typelib.c:3231
static void dump_TypeInfo(const ITypeInfoImpl *pty)
Definition: typelib.c:1537
static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(ITypeInfo2 *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo)
Definition: typelib.c:7742
static ITypeLibImpl * impl_from_ITypeLib(ITypeLib *iface)
Definition: typelib.c:1120
static ITypeLibImpl * TypeLibImpl_Constructor(void)
Definition: typelib.c:3404
static void TLBImplType_Constructor(TLBImplType *impl)
Definition: typelib.c:1788
static void dump_ELEMDESC(const ELEMDESC *edesc)
Definition: typelib.c:1370
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias(ICreateTypeInfo2 *iface, TYPEDESC *tdescAlias)
Definition: typelib.c:10881
static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(ITypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8206
static const GUID * TLB_get_guidref(const TLBGuid *guid)
Definition: typelib.c:1295
static void ITypeInfoImpl_FuncDescAddHrefOffset(LPFUNCDESC pFuncDesc, UINT hrefoffset)
Definition: typelib.c:5945
static TLBString * TLB_append_str(struct list *string_list, BSTR new_str)
Definition: typelib.c:1877
static DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, LONG where)
Definition: typelib.c:2037
static HRESULT WINAPI ITypeInfo2_fnGetTypeKind(ITypeInfo2 *iface, TYPEKIND *pTypeKind)
Definition: typelib.c:8101
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName(ICreateTypeInfo2 *iface, UINT index, LPOLESTR name)
Definition: typelib.c:10864
static HRESULT WINAPI ICreateTypeLib2_fnSetCustData(ICreateTypeLib2 *iface, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:10261
#define DISPATCH_HREF_OFFSET
Definition: typelib.c:128
static void WMSFT_compile_impinfo(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9946
static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(ITypeLib2 *iface, UINT index, ITypeInfo **ppTInfo)
Definition: typelib.c:4805
static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags(ICreateTypeInfo2 *iface, UINT index, INT implTypeFlags)
Definition: typelib.c:10729
struct tagTLBContext TLBContext
static void TLB_relink_custdata(struct list *custdata_list)
Definition: typelib.c:1866
static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface)
Definition: typelib.c:8845
static void dump_TLBVarDesc(const TLBVarDesc *pvd, UINT n)
Definition: typelib.c:1467
#define FromLEDWord(X)
Definition: typelib.c:125
static void WINAPI ITypeInfo_fnReleaseFuncDesc(ITypeInfo2 *iface, FUNCDESC *pFuncDesc)
Definition: typelib.c:8067
static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData(ITypeInfo2 *iface, UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
Definition: typelib.c:8433
static HRESULT TLB_Mapping_Open(LPCWSTR path, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
Definition: typelib.c:3238
static void MSFT_DoFuncs(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, int cVars, int offset, TLBFuncDesc **pptfd)
Definition: typelib.c:2331
static HRESULT WINAPI ITypeLib2_fnGetAllCustData(ITypeLib2 *iface, CUSTDATA *pCustData)
Definition: typelib.c:5282
static HRESULT sltg_get_typelib_ref(const sltg_ref_lookup_t *table, DWORD typeinfo_ref, HREFTYPE *typelib_ref)
Definition: typelib.c:3778
static TLBVarDesc * TLB_get_vardesc_by_name(ITypeInfoImpl *typeinfo, const OLECHAR *name)
Definition: typelib.c:1695
static SIZE_T TLB_SizeTypeDesc(const TYPEDESC *tdesc, BOOL alloc_initial_space)
Definition: typelib.c:1583
static int read_xx_header(HFILE lzfd)
Definition: typelib.c:3014
static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4339
static ULONG WINAPI ITypeComp_fnAddRef(ITypeComp *iface)
Definition: typelib.c:8666
static UINT WINAPI ITypeLib2_fnGetTypeInfoCount(ITypeLib2 *iface)
Definition: typelib.c:4794
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc(ICreateTypeInfo2 *iface, UINT index)
Definition: typelib.c:11141
static const IUnknownVtbl TLB_NEFile_Vtable
Definition: typelib.c:3004
static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 *iface, LPOLESTR doc)
Definition: typelib.c:8955
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext(ICreateTypeInfo2 *iface, UINT index, ULONG helpStringContext)
Definition: typelib.c:11282
static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, const char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4332
static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData(ICreateTypeInfo2 *iface, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11214
static void dump_TLBRefType(const ITypeLibImpl *pTL)
Definition: typelib.c:1484
static HRESULT WINAPI ITypeInfo_fnGetMops(ITypeInfo2 *iface, MEMBERID memid, BSTR *pBstrMops)
Definition: typelib.c:8018
static const ITypeCompVtbl tcompvt
Definition: typelib.c:1266
static HRESULT TLB_size_instance(ITypeInfoImpl *info, SYSKIND sys, TYPEDESC *tdesc, ULONG *size, WORD *align)
Definition: typelib.c:1932
HRESULT WINAPI CreateDispTypeInfo(INTERFACEDATA *pidata, LCID lcid, ITypeInfo **pptinfo)
Definition: typelib.c:8551
static const IUnknownVtbl TLB_PEFile_Vtable
Definition: typelib.c:2908
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString(ICreateTypeInfo2 *iface, UINT index, LPOLESTR docString)
Definition: typelib.c:10933
static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cFuncs, char *pNameTable, const sltg_ref_lookup_t *ref_lookup)
Definition: typelib.c:4111
static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags(ITypeInfo2 *iface, UINT index, INT *pImplTypeFlags)
Definition: typelib.c:6229
static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(ITypeInfo2 *iface, UINT indexFunc, UINT indexParam, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8236
static HRESULT WINAPI ITypeLib2_fnGetDocumentation(ITypeLib2 *iface, INT index, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
Definition: typelib.c:4933
static HRESULT WINAPI ITypeInfo_fnGetTypeComp(ITypeInfo2 *iface, ITypeComp **ppTComp)
Definition: typelib.c:5691
static TYPEDESC std_typedesc[VT_LPWSTR+1]
Definition: typelib.c:1563
static const ITypeInfo2Vtbl tinfvt
Definition: typelib.c:1265
static WCHAR * get_lcid_subkey(LCID lcid, SYSKIND syskind, WCHAR *buffer)
Definition: typelib.c:257
HRESULT WINAPI LoadRegTypeLib(REFGUID rguid, WORD wVerMajor, WORD wVerMinor, LCID lcid, ITypeLib **ppTLib)
Definition: typelib.c:507
#define X(x)
static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, int cVars, int offset, TLBVarDesc **pptvd)
Definition: typelib.c:2531
HRESULT WINAPI CreateTypeLib2(SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib2 **ppctlib)
Definition: typelib.c:8801
static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(ITypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8273
static HRESULT WINAPI ITypeInfo_fnCreateInstance(ITypeInfo2 *iface, IUnknown *pOuterUnk, REFIID riid, VOID **ppvObj)
Definition: typelib.c:7964
static BOOL find_typelib_key(REFGUID guid, WORD *wMaj, WORD *wMin)
Definition: typelib.c:171
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext(ICreateTypeInfo2 *iface, UINT index, ULONG helpStringContext)
Definition: typelib.c:11275
static HRESULT TLB_PEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
Definition: typelib.c:2915
static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl)
Definition: typelib.c:3720
static BSTR TLB_get_bstr(const TLBString *str)
Definition: typelib.c:1283
static void TLB_fix_typeinfo_ptr_size(ITypeInfoImpl *info)
Definition: typelib.c:2614
static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(ITypeLib2 *iface, INT index, LCID lcid, BSTR *pbstrHelpString, DWORD *pdwHelpStringContext, BSTR *pbstrHelpStringDll)
Definition: typelib.c:5189
static void WMSFT_write_segment(HANDLE outfile, WMSFT_SegContents *segment)
Definition: typelib.c:10000
HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const WCHAR *szHelpDir)
Definition: typelib.c:612
static void dump_TLBImpLib(const TLBImpLib *import)
Definition: typelib.c:1477
static TLBFuncDesc * TLB_get_funcdesc_by_memberid_invkind(ITypeInfoImpl *typeinfo, MEMBERID memid, INVOKEKIND invkind)
Definition: typelib.c:1669
#define INVBUF_GET_ARG_PTR_ARRAY(buffer, params)
Definition: typelib.c:7029
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll(ICreateTypeLib2 *iface, LPOLESTR filename)
Definition: typelib.c:10284
static HRESULT WINAPI ITypeInfo_fnGetNames(ITypeInfo2 *iface, MEMBERID memid, BSTR *names, UINT max_names, UINT *num_names)
Definition: typelib.c:6150
HRESULT WINAPI DispCallFunc(void *pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals, VARTYPE *prgvt, VARIANTARG **prgpvarg, VARIANT *pvargResult)
Definition: typelib.c:6824
static ULONG WINAPI TLB_NEFile_AddRef(IUnknown *iface)
Definition: typelib.c:2986
static void ITypeInfoImpl_ElemDescAddHrefOffset(LPELEMDESC pElemDesc, UINT hrefoffset)
Definition: typelib.c:5922
static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData(ITypeInfo2 *iface, UINT index, CUSTDATA *pCustData)
Definition: typelib.c:8458
static void WINAPI ITypeInfo_fnReleaseVarDesc(ITypeInfo2 *iface, VARDESC *pVarDesc)
Definition: typelib.c:8087
static ITypeLib2 * ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
Definition: typelib.c:4379
static void * TLB_CopyTypeDesc(TYPEDESC *dest, const TYPEDESC *src, void *buffer)
Definition: typelib.c:1605
static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames(ITypeInfo2 *iface, LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
Definition: typelib.c:6256
static void MSFT_Seek(TLBContext *pcx, LONG where)
Definition: typelib.c:2021
struct tagWMSFT_TLBFile WMSFT_TLBFile
static void TLB_register_interface(TLIBATTR *libattr, LPOLESTR name, TYPEATTR *tattr, DWORD flag)
Definition: typelib.c:551
static const BOOL is_win64
Definition: typelib.c:76
static DWORD WMSFT_append_arraydesc(ARRAYDESC *desc, WMSFT_TLBFile *file)
Definition: typelib.c:9323
static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile)
Definition: typelib.c:3141
static HRESULT WMSFT_compile_names(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9100
static TLBString * MSFT_ReadString(TLBContext *pcx, int offset)
Definition: typelib.c:2187
static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext(ICreateTypeInfo2 *iface, ULONG helpStringContext)
Definition: typelib.c:11263
static HRESULT WINAPI ICreateTypeInfo2_fnSetMops(ICreateTypeInfo2 *iface, UINT index, BSTR bstrMops)
Definition: typelib.c:10984
struct tagTLBGuid TLBGuid
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId(ICreateTypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind)
Definition: typelib.c:11168
static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib(ITypeInfo2 *iface, ITypeLib **ppTLib, UINT *pIndex)
Definition: typelib.c:8030
static ULONG WINAPI ITypeComp_fnRelease(ITypeComp *iface)
Definition: typelib.c:8673
#define XX(x)
static CRITICAL_SECTION_DEBUG cache_section_debug
Definition: typelib.c:2851
static HRESULT TLB_AllocAndInitFuncDesc(const FUNCDESC *src, FUNCDESC **dest_ptr, BOOL dispinterface)
Definition: typelib.c:5747
#define INVBUF_GET_MISSING_ARG_ARRAY(buffer, params)
Definition: typelib.c:7027
static TLB_PEFile * pefile_impl_from_IUnknown(IUnknown *iface)
Definition: typelib.c:2870
static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, int offset)
Definition: typelib.c:2590
static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface, UINT index, FUNCDESC *funcDesc)
Definition: typelib.c:10542
static HRESULT MSFT_ReadAllNames(TLBContext *pcx)
Definition: typelib.c:2126
static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc(ICreateTypeInfo2 *iface, UINT index, VARDESC *varDesc)
Definition: typelib.c:10777
static HRESULT WINAPI ITypeLibComp_fnQueryInterface(ITypeComp *iface, REFIID riid, LPVOID *ppv)
Definition: typelib.c:5313
static TLB_Mapping * mapping_impl_from_IUnknown(IUnknown *iface)
Definition: typelib.c:3191
static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext(ICreateTypeInfo2 *iface, DWORD helpContext)
Definition: typelib.c:10409
static void dump_TypeDesc(const TYPEDESC *pTD, char *szVarType)
Definition: typelib.c:1322
struct tagWMSFT_SegContents WMSFT_SegContents
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData(ICreateTypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11247
HRESULT WINAPI LoadTypeLibEx(LPCOLESTR szFile, REGKIND regkind, ITypeLib **pptLib)
Definition: typelib.c:449
#define INVBUF_ELEMENT_SIZE
Definition: typelib.c:7024
HRESULT WINAPI QueryPathOfRegTypeLib(REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path)
Definition: typelib.c:394
static HRESULT query_typelib_path(REFGUID guid, WORD wMaj, WORD wMin, SYSKIND syskind, LCID lcid, BSTR *path, BOOL redir)
Definition: typelib.c:289
static void dump_VARDESC(const VARDESC *v)
Definition: typelib.c:1553
static ITypeLibImpl * impl_from_ICreateTypeLib2(ICreateTypeLib2 *iface)
Definition: typelib.c:1130
static TLBVarDesc * TLBVarDesc_Alloc(UINT n)
Definition: typelib.c:1735
struct tagWMSFT_ImpFile WMSFT_ImpFile
struct tagITypeLibImpl ITypeLibImpl
static ITypeInfoImpl * ITypeInfoImpl_Constructor(void)
Definition: typelib.c:5515
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc(ICreateTypeInfo2 *iface, UINT index)
Definition: typelib.c:11175
static TLBCustData * TLB_get_custdata_by_guid(const struct list *custdata_list, REFGUID guid)
Definition: typelib.c:1708
#define FromLEWord(X)
Definition: typelib.c:124
static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(ITypeLib2 *iface, UINT index, TYPEKIND *pTKind)
Definition: typelib.c:4831
static TLBString * SLTG_ReadName(const char *pNameTable, int offset, ITypeLibImpl *lib)
Definition: typelib.c:3703
static BOOL find_ne_resource(HFILE lzfd, LPCSTR typeid, LPCSTR resid, DWORD *resLen, DWORD *resOff)
Definition: typelib.c:3045
static HRESULT WINAPI ITypeLib2_fnIsName(ITypeLib2 *iface, LPOLESTR szNameBuf, ULONG lHashVal, BOOL *pfName)
Definition: typelib.c:5021
static void WMSFT_compile_guidhash(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9970
static VOID WINAPI ITypeLib2_fnReleaseTLibAttr(ITypeLib2 *iface, TLIBATTR *pTLibAttr)
Definition: typelib.c:5129
static void dump_TLBImplType(const TLBImplType *impl, UINT n)
Definition: typelib.c:1504
static HRESULT WINAPI ITypeInfo_fnAddressOfMember(ITypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
Definition: typelib.c:7906
static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
Definition: typelib.c:6834
static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 *iface, WORD majorVerNum, WORD minorVerNum)
Definition: typelib.c:8930
static void dump_DispParms(const DISPPARAMS *pdp)
Definition: typelib.c:1516
#define TLB_REF_USE_GUID
Definition: typelib.c:1160
static struct list tlb_cache
Definition: typelib.c:2849
static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
Definition: typelib.c:5634
static DWORD WMSFT_compile_typeinfo_aux(ITypeInfoImpl *info, WMSFT_TLBFile *file)
Definition: typelib.c:9446
static void ITypeInfoImpl_Destroy(ITypeInfoImpl *This)
Definition: typelib.c:5596
static HRESULT WINAPI ICreateTypeInfo2_fnSetName(ICreateTypeInfo2 *iface, LPOLESTR name)
Definition: typelib.c:11295
static ULONG WINAPI TLB_PEFile_AddRef(IUnknown *iface)
Definition: typelib.c:2887
static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo(ICreateTypeLib2 *iface, LPOLESTR name)
Definition: typelib.c:10253
static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid)
Definition: typelib.c:6966
static CRITICAL_SECTION cache_section
Definition: typelib.c:2850
static ITypeLibImpl * impl_from_ITypeLib2(ITypeLib2 *iface)
Definition: typelib.c:1115
static HRESULT WINAPI ITypeInfo_fnQueryInterface(ITypeInfo2 *iface, REFIID riid, VOID **ppvObject)
Definition: typelib.c:5538
static ULONG WINAPI TLB_PEFile_Release(IUnknown *iface)
Definition: typelib.c:2893
static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(ITypeInfo2 *iface, UINT index, CUSTDATA *pCustData)
Definition: typelib.c:8477
static const ITypeLib2Vtbl tlbvt
Definition: typelib.c:1111
static sltg_ref_lookup_t * SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, char *pNameTable)
Definition: typelib.c:3876
static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString(ICreateTypeInfo2 *iface, LPOLESTR doc)
Definition: typelib.c:10394
static ULONG WINAPI TLB_NEFile_Release(IUnknown *iface)
Definition: typelib.c:2992
static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType(ICreateTypeInfo2 *iface, UINT index, HREFTYPE refType)
Definition: typelib.c:10662
static BOOL TLB_is_propgetput(INVOKEKIND invkind)
Definition: typelib.c:2323
#define TLB_REF_INTERNAL
Definition: typelib.c:1162
HRESULT WINAPI RegisterTypeLibForUser(ITypeLib *ptlib, OLECHAR *szFullPath, OLECHAR *szHelpDir)
Definition: typelib.c:992
static void WMSFT_compile_impfile(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9876
static void WMSFT_compile_namehash(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9977
HRESULT WINAPI UnRegisterTypeLib(REFGUID libid, WORD wVerMajor, WORD wVerMinor, LCID lcid, SYSKIND syskind)
Definition: typelib.c:848
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames(ICreateTypeInfo2 *iface, UINT index, LPOLESTR *names, UINT numNames)
Definition: typelib.c:10821
static ULONG WINAPI ITypeLibComp_fnAddRef(ITypeComp *iface)
Definition: typelib.c:5320
static int get_ptr_size(SYSKIND syskind)
Definition: typelib.c:1305
static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 *iface, REFIID riid, void **ppv)
Definition: typelib.c:4671
static BOOL func_restricted(const FUNCDESC *desc)
Definition: typelib.c:7019
static HRESULT TLB_CopyElemDesc(const ELEMDESC *src, ELEMDESC *dest, char **buffer)
Definition: typelib.c:5711
static HRESULT typeinfo_getnames(ITypeInfo *iface, MEMBERID memid, BSTR *names, UINT max_names, UINT *num_names, BOOL dispinterface)
Definition: typelib.c:6072
static ITypeInfoImpl * impl_from_ITypeInfo2(ITypeInfo2 *iface)
Definition: typelib.c:1250
static ITypeInfoImpl * info_impl_from_ITypeComp(ITypeComp *iface)
Definition: typelib.c:1245
static HRESULT WINAPI ITypeInfo_fnGetFuncDesc(ITypeInfo2 *iface, UINT index, LPFUNCDESC *ppFuncDesc)
Definition: typelib.c:5959
static HRESULT WINAPI ITypeInfo_fnGetTypeAttr(ITypeInfo2 *iface, LPTYPEATTR *ppTypeAttr)
Definition: typelib.c:5653
static HRESULT WINAPI ITypeLib2_fnFindName(ITypeLib2 *iface, LPOLESTR name, ULONG hash, ITypeInfo **ppTInfo, MEMBERID *memid, UINT16 *found)
Definition: typelib.c:5067
static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4304
static HRESULT WINAPI ITypeInfo_fnGetDocumentation(ITypeInfo2 *iface, MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
Definition: typelib.c:7598
static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 *iface, UINT libFlags)
Definition: typelib.c:9009
static WORD * SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem, const sltg_ref_lookup_t *ref_lookup)
Definition: typelib.c:3853
struct tagTLBImpLib TLBImpLib
static ITypeLibImpl * impl_from_ITypeComp(ITypeComp *iface)
Definition: typelib.c:1125
static const char *const typekind_desc[]
Definition: typelib.c:1425
static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr)
Definition: typelib.c:5995
static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 *iface)
Definition: typelib.c:4699
struct tagTLBRefType TLBRefType
static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo(ICreateTypeLib2 *iface, LPOLESTR name, TYPEKIND kind, ICreateTypeInfo **ctinfo)
Definition: typelib.c:8852
static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(ITypeLib2 *iface, ULONG *pcUniqueNames, ULONG *pcchUniqueNames)
Definition: typelib.c:5168
static HRESULT WINAPI ITypeInfo_fnGetDllEntry(ITypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
Definition: typelib.c:7668
static const GUID * TLB_get_guid_null(const TLBGuid *guid)
Definition: typelib.c:1300
static void WINAPI ITypeInfo_fnReleaseTypeAttr(ITypeInfo2 *iface, TYPEATTR *pTypeAttr)
Definition: typelib.c:8055
static HRESULT TLB_SanitizeVariant(VARIANT *var)
Definition: typelib.c:5731
static HRESULT WINAPI ITypeLib2_fnGetCustData(ITypeLib2 *iface, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:5142
struct tagWMSFT_RefChunk WMSFT_RefChunk
static DWORD WMSFT_compile_custdata(struct list *custdata_list, WMSFT_TLBFile *file)
Definition: typelib.c:9417
static HRESULT WINAPI ICreateTypeInfo2_fnLayOut(ICreateTypeInfo2 *iface)
Definition: typelib.c:11008
static ITypeLib2 * ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
Definition: typelib.c:3432
static DWORD MSFT_ReadLEWords(void *buffer, DWORD count, TLBContext *pcx, LONG where)
Definition: typelib.c:2060
static const ICreateTypeInfo2Vtbl CreateTypeInfo2Vtbl
Definition: typelib.c:1267
static void dump_FUNCDESC(const FUNCDESC *funcdesc)
Definition: typelib.c:1386
static HRESULT ITypeInfoImpl_GetDispatchRefTypeInfo(ITypeInfo *iface, HREFTYPE *hRefType, ITypeInfo **ppTInfo)
Definition: typelib.c:7707
struct tagTLBCustData TLBCustData
struct tagTLBImplType TLBImplType
static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment(ICreateTypeInfo2 *iface, WORD alignment)
Definition: typelib.c:10748
static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(ITypeInfo2 *iface, CUSTDATA *pCustData)
Definition: typelib.c:8393
static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(ICreateTypeInfo2 *iface, UINT funcIndex, UINT paramIndex, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11239
static DWORD MSFT_ReadLEDWords(void *buffer, DWORD count, TLBContext *pcx, LONG where)
Definition: typelib.c:2049
static void dump_TLBFuncDesc(const TLBFuncDesc *pfd, UINT n)
Definition: typelib.c:1458
static HRESULT WINAPI ITypeComp_fnBind(ITypeComp *iface, OLECHAR *szName, ULONG lHash, WORD wFlags, ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
Definition: typelib.c:8680
static HRESULT ITypeInfoImpl_GetInternalFuncDesc(ITypeInfo *iface, UINT index, const TLBFuncDesc **func_desc, UINT *hrefoffset)
Definition: typelib.c:5908
static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface(ICreateTypeLib2 *iface, REFIID riid, void **object)
Definition: typelib.c:8830
static DWORD WMSFT_encode_variant(VARIANT *value, WMSFT_TLBFile *file)
Definition: typelib.c:9219
static ULONG WINAPI TLB_Mapping_AddRef(IUnknown *iface)
Definition: typelib.c:3208
static WORD * SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, const sltg_ref_lookup_t *ref_lookup)
Definition: typelib.c:3792
static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId(ICreateTypeInfo2 *iface, MEMBERID memid)
Definition: typelib.c:11182
static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData(ICreateTypeInfo2 *iface, UINT index, REFGUID guid, VARIANT *varVal)
Definition: typelib.c:11255
static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, const SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4276
static BOOL TLB_GUIDFromString(const char *str, GUID *guid)
Definition: typelib.c:3648
static ITypeInfoImpl * impl_from_ITypeInfo(ITypeInfo *iface)
Definition: typelib.c:1255
static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid)
Definition: typelib.c:10340
static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface)
Definition: typelib.c:10326
#define INVBUF_GET_ARG_ARRAY(buffer, params)
Definition: typelib.c:7026
static HREFTYPE MSFT_ReadHreftype(TLBContext *pcx, int offset)
Definition: typelib.c:2110
static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface)
Definition: typelib.c:8838
static TLBString * MSFT_ReadName(TLBContext *pcx, int offset)
Definition: typelib.c:2173
#define INVBUF_GET_ARG_TYPE_ARRAY(buffer, params)
Definition: typelib.c:7031
static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, SLTG_TypeInfoTail *pTITail)
Definition: typelib.c:4221
static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
Definition: typelib.c:6899
static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId(ITypeInfo2 *iface, MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
Definition: typelib.c:8130
static HRESULT WMSFT_compile_strings(ITypeLibImpl *This, WMSFT_TLBFile *file)
Definition: typelib.c:9045
static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate(ICreateTypeInfo2 *iface)
Definition: typelib.c:11289
HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib **pptLib)
Definition: typelib.c:434
struct tagTLBParDesc TLBParDesc
static ULONG WINAPI ITypeLibComp_fnRelease(ITypeComp *iface)
Definition: typelib.c:5327
HRESULT WINAPI UnRegisterTypeLibForUser(REFGUID libid, WORD wVerMajor, WORD wVerMinor, LCID lcid, SYSKIND syskind)
Definition: typelib.c:1011
static HRESULT TLB_get_size_from_hreftype(ITypeInfoImpl *info, HREFTYPE href, ULONG *size, WORD *align)
Definition: typelib.c:1904
static void TLB_FreeElemDesc(ELEMDESC *elemdesc)
Definition: typelib.c:5741
#define SLTG_SIGNATURE
Definition: typelib.c:3281
static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, const char *pNameTable, const sltg_ref_lookup_t *ref_lookup)
Definition: typelib.c:4000
static int hash_guid(GUID *guid)
Definition: typelib.c:9180
static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext(ICreateTypeLib2 *iface, ULONG helpStringContext)
Definition: typelib.c:10277
#define FromLEWords(X, Y)
Definition: typelib.c:164
static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString(ICreateTypeInfo2 *iface, UINT index, LPOLESTR docString)
Definition: typelib.c:10914
static TLBFuncDesc * TLBFuncDesc_Alloc(UINT n)
Definition: typelib.c:1772
static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 *iface)
Definition: typelib.c:4709
static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo(ICreateTypeInfo2 *iface, ITypeInfo *typeInfo, HREFTYPE *refType)
Definition: typelib.c:10434
static HRESULT MSFT_ReadAllRefs(TLBContext *pcx)
Definition: typelib.c:2804
static TLB_NEFile * nefile_impl_from_IUnknown(IUnknown *iface)
Definition: typelib.c:2969
#define TLB_REF_NOT_FOUND
Definition: typelib.c:1163
static void WMSFT_compile_typeinfo_seg(ITypeLibImpl *This, WMSFT_TLBFile *file, DWORD *junk)
Definition: typelib.c:9844
static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext(ICreateTypeInfo2 *iface, UINT index, DWORD helpContext)
Definition: typelib.c:10968
static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 *iface, LCID lcid)
Definition: typelib.c:8997
static const ICreateTypeLib2Vtbl CreateTypeLib2Vtbl
Definition: typelib.c:1113
static HRESULT WINAPI TLB_NEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: typelib.c:2974
struct tagTLBFuncDesc TLBFuncDesc
static void TLB_FreeCustData(struct list *custdata_list)
Definition: typelib.c:1633
static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry(ICreateTypeInfo2 *iface, UINT index, LPOLESTR dllName, LPOLESTR procName)
Definition: typelib.c:10906
static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(ITypeInfo2 *iface, UINT index, HREFTYPE *pRefType)
Definition: typelib.c:6171
static BSTR TLB_MultiByteToBSTR(const char *ptr)
Definition: typelib.c:1644
#define DISPATCH_HREF_MASK
Definition: typelib.c:129
static DWORD WMSFT_compile_typeinfo(ITypeInfoImpl *info, INT16 index, WMSFT_TLBFile *file, char *data)
Definition: typelib.c:9773
static DWORD WMSFT_compile_typeinfo_ref(ITypeInfoImpl *info, WMSFT_TLBFile *file)
Definition: typelib.c:9749
static HRESULT ITypeInfoImpl_GetInternalDispatchFuncDesc(ITypeInfo *iface, UINT index, const TLBFuncDesc **ppFuncDesc, UINT *funcs, UINT *hrefoffset)
Definition: typelib.c:5860
static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc(ICreateTypeInfo2 *iface, IDLDESC *idlDesc)
Definition: typelib.c:10992
static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface(ICreateTypeInfo2 *iface, REFIID riid, void **object)
Definition: typelib.c:10318
static void TLB_abort(void)
Definition: typelib.c:1576
static HRESULT WINAPI ITypeInfo2_fnGetCustData(ITypeInfo2 *iface, REFGUID guid, VARIANT *pVarVal)
Definition: typelib.c:8179
static HRESULT WINAPI TLB_Mapping_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: typelib.c:3196
static HRESULT TLB_copy_all_custdata(const struct list *custdata_list, CUSTDATA *pCustData)
Definition: typelib.c:5249
struct tagTLBVarDesc TLBVarDesc
static void dump_TLBFuncDescOne(const TLBFuncDesc *pfd)
Definition: typelib.c:1438
static TLBParDesc * TLBParDesc_Constructor(UINT n)
Definition: typelib.c:1751
struct tagMSFT_ImpInfo MSFT_ImpInfo
#define SLTG_FUNCTION_FLAGS_PRESENT
Definition: typelib.h:497
#define SLTG_REF_MAGIC
Definition: typelib.h:542
#define SLTG_COMPOBJ_MAGIC
Definition: typelib.h:333
#define SLTG_TIHEADER_MAGIC
Definition: typelib.h:420
#define SLTG_FUNCTION_MAGIC
Definition: typelib.h:498
#define DO_NOT_SEEK
Definition: typelib.h:31
#define SLTG_STATIC_FUNCTION_MAGIC
Definition: typelib.h:500
struct tagMSFT_TypeInfoBase MSFT_TypeInfoBase
#define SLTG_IMPL_MAGIC
Definition: typelib.h:567
#define SLTG_LIBBLK_MAGIC
Definition: typelib.h:380
#define SLTG_VAR_WITH_FLAGS_MAGIC
Definition: typelib.h:583
#define HELPDLLFLAG
Definition: typelib.h:30
#define SLTG_DISPATCH_FUNCTION_MAGIC
Definition: typelib.h:499
#define SLTG_DIR_MAGIC
Definition: typelib.h:334
#define MSFT_IMPINFO_OFFSET_IS_GUID
Definition: typelib.h:174
#define SLTG_VAR_MAGIC
Definition: typelib.h:582
#define MSFT_SIGNATURE
Definition: typelib.h:56
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define swprintf
Definition: precomp.h:40
static const char * debugstr_variant(const VARIANT *var)
Definition: dom.c:505
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
#define ULONG_PTR
Definition: config.h:101
int align(int length, int align)
Definition: dsound8.c:36
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
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 count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
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
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
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
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
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
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
GLuint id
Definition: glext.h:5910
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
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
unsigned int UINT
Definition: sysinfo.c:13
FxContextHeader * pHeader
Definition: handleapi.cpp:604
type_id
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
@ extra
Definition: id3.c:95
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
Definition: msctf.idl:532
#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
BOOL is_wow64
Definition: main.c:38
#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
int HFILE
Definition: minwindef.h:222
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define MESSAGE
Definition: options.h:86
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
Definition: sprintf.c:45
#define FILE_NAME_NORMALIZED
#define VOLUME_NAME_DOS
static const DWORD ptr_size
Definition: registry.c:58
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
const char * var
Definition: shader.c:5666
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:72
static char * dest
Definition: rtl.c:149
static void * vtable[]
Definition: typelib.c:1500
static OLECHAR OLECHAR *static SYSKIND
Definition: typelib.c:87
static const char * contents
Definition: parser.c:511
static VARIANTARG static DISPID
Definition: ordinal.c:49
static LPCWSTR file_name
Definition: protocol.c:152
static const GUID * guid_list[]
Definition: metadata.c:3117
int other
Definition: msacm.c:1376
_Out_ PULONG _Out_ PULONG pIndex
Definition: ndis.h:4565
#define SEC_COMMIT
Definition: mmtypes.h:100
#define KEY_READ
Definition: nt_native.h:1026
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1087
#define KEY_WRITE
Definition: nt_native.h:1034
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
#define LOCALE_USER_DEFAULT
#define MAKELCID(lgid, srtid)
HRESULT WINAPI DECLSPEC_HOTPATCH GetActiveObject(REFCLSID rcid, LPVOID preserved, LPUNKNOWN *ppunk)
Definition: oleaut.c:591
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:240
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:198
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:273
BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len)
Definition: oleaut.c:430
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:341
#define V_ERROR(A)
Definition: oleauto.h:241
#define V_UI1(A)
Definition: oleauto.h:266
#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_INT(A)
Definition: oleauto.h:251
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_UI2(A)
Definition: oleauto.h:268
#define V_I1(A)
Definition: oleauto.h:243
#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
const GUID IID_IDispatch
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
#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
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
static unsigned __int64 next
Definition: rand_nt.c:6
#define calloc
Definition: rosglue.h:14
const WCHAR * str
#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
strcpy
Definition: string.h:131
#define ERR_ON(ch)
Definition: debug.h:390
__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:48
#define memset(x, y, z)
Definition: compat.h:39
@ LIBFLAG_FHASDISKIMAGE
Definition: actctx.c:76
#define args
Definition: format.c:66
DataType
Definition: simd.h:252
#define TRACE(s)
Definition: solgame.cpp:4
@ CC_CDECL
Definition: spec2def.c:95
@ CC_STDCALL
Definition: spec2def.c:94
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 offset
Definition: version.c:49
WORD length
Definition: version.c:50
WORD id
Definition: version.c:52
WORD type_id
Definition: version.c:59
WORD count
Definition: version.c:60
WORD rettype
Definition: typelib.h:487
WORD arg_off
Definition: typelib.h:482
WORD vtblpos
Definition: typelib.h:488
WORD funcflags
Definition: typelib.h:489
DWORD dispid
Definition: typelib.h:479
BYTE magic
Definition: typelib.h:475
BYTE retnextopt
Definition: typelib.h:484
WORD name
Definition: typelib.h:366
CHAR dir_magic[4]
Definition: typelib.h:330
CHAR CompObj_magic[9]
Definition: typelib.h:329
SLTG_Name names[1]
Definition: typelib.h:528
BYTE magic
Definition: typelib.h:503
DWORD number
Definition: typelib.h:522
WORD cbSizeInstance
Definition: typelib.h:439
WORD tdescalias_vt
Definition: typelib.h:433
WORD byte_offs
Definition: typelib.h:574
BYTE flags
Definition: typelib.h:571
BYTE magic
Definition: typelib.h:570
WORD varflags
Definition: typelib.h:579
DWORD memid
Definition: typelib.h:576
LONG refs
Definition: typelib.c:3185
HANDLE file
Definition: typelib.c:3186
LPVOID typelib_base
Definition: typelib.c:3188
HANDLE mapping
Definition: typelib.c:3187
IUnknown IUnknown_iface
Definition: typelib.c:3184
IUnknown IUnknown_iface
Definition: typelib.c:2964
LPVOID typelib_base
Definition: typelib.c:2966
LONG refs
Definition: typelib.c:2965
HMODULE dll
Definition: typelib.c:2864
LONG refs
Definition: typelib.c:2863
IUnknown IUnknown_iface
Definition: typelib.c:2862
HGLOBAL typelib_global
Definition: typelib.c:2866
LPVOID typelib_base
Definition: typelib.c:2867
HRSRC typelib_resource
Definition: typelib.c:2865
Definition: scsiwmi.h:51
Definition: match.c:390
Definition: cookie.c:202
Definition: fci.c:127
Definition: _hash_fun.h:40
unsigned int index
Definition: notification.c:74
Definition: copy.c:22
Definition: name.c:39
Definition: send.c:48
unsigned int num
Definition: typelib.c:3774
METHODDATA * pmethdata
Definition: oleauto.h:919
const TLBString * DocString
Definition: typelib.c:1226
DWORD dwHelpContext
Definition: typelib.c:1229
BOOL not_attached_to_typelib
Definition: typelib.c:1212
const TLBString * Name
Definition: typelib.c:1225
struct list * pcustdata_list
Definition: typelib.c:1241
const TLBString * DllName
Definition: typelib.c:1227
ITypeInfo2 ITypeInfo2_iface
Definition: typelib.c:1208
const TLBString * Schema
Definition: typelib.c:1228
TYPEATTR typeattr
Definition: typelib.c:1216
TYPEDESC * tdescAlias
Definition: typelib.c:1217
TLBFuncDesc * funcdescs
Definition: typelib.c:1233
DWORD dwHelpStringContext
Definition: typelib.c:1230
ITypeLibImpl * pTypeLib
Definition: typelib.c:1219
ITypeComp ITypeComp_iface
Definition: typelib.c:1209
TLBGuid * guid
Definition: typelib.c:1215
TLBVarDesc * vardescs
Definition: typelib.c:1236
struct list custdata_list
Definition: typelib.c:1242
ICreateTypeInfo2 ICreateTypeInfo2_iface
Definition: typelib.c:1210
TLBImplType * impltypes
Definition: typelib.c:1239
HREFTYPE hreftype
Definition: typelib.c:1221
const TLBString * Name
Definition: typelib.c:1088
struct list guid_list
Definition: typelib.c:1086
ICreateTypeLib2 ICreateTypeLib2_iface
Definition: typelib.c:1070
ITypeLib2 ITypeLib2_iface
Definition: typelib.c:1068
const TLBString * HelpFile
Definition: typelib.c:1090
struct list custdata_list
Definition: typelib.c:1095
SYSKIND syskind
Definition: typelib.c:1074
TYPEDESC * pTypeDesc
Definition: typelib.c:1098
DWORD dwHelpContext
Definition: typelib.c:1092
TLBGuid * guid
Definition: typelib.c:1072
struct list name_list
Definition: typelib.c:1085
struct list entry
Definition: typelib.c:1106
WCHAR * path
Definition: typelib.c:1107
struct list implib_list
Definition: typelib.c:1096
const TLBString * DocString
Definition: typelib.c:1089
HREFTYPE dispatch_href
Definition: typelib.c:1102
struct list ref_list
Definition: typelib.c:1101
struct tagITypeInfoImpl ** typeinfos
Definition: typelib.c:1094
struct list string_list
Definition: typelib.c:1084
ITypeComp ITypeComp_iface
Definition: typelib.c:1069
const TLBString * HelpStringDll
Definition: typelib.c:1091
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:1277
unsigned int oStart
Definition: typelib.c:1274
unsigned int length
Definition: typelib.c:1276
MSFT_SegDir * pTblDir
Definition: typelib.c:1278
unsigned int pos
Definition: typelib.c:1275
ITypeLibImpl * pLibInfo
Definition: typelib.c:1279
VARIANT data
Definition: typelib.c:1035
struct list entry
Definition: typelib.c:1036
TLBGuid * guid
Definition: typelib.c:1034
int HelpStringContext
Definition: typelib.c:1179
FUNCDESC funcdesc
Definition: typelib.c:1175
const TLBString * Entry
Definition: typelib.c:1181
TLBParDesc * pParamDesc
Definition: typelib.c:1177
const TLBString * Name
Definition: typelib.c:1176
const TLBString * HelpString
Definition: typelib.c:1180
struct list custdata_list
Definition: typelib.c:1182
struct list entry
Definition: typelib.c:1029
UINT offset
Definition: typelib.c:1028
GUID guid
Definition: typelib.c:1026
INT hreftype
Definition: typelib.c:1027
TLBGuid * guid
Definition: typelib.c:1046
struct tagITypeLibImpl * pImpTypeLib
Definition: typelib.c:1054
WORD wVersionMinor
Definition: typelib.c:1052
WORD wVersionMajor
Definition: typelib.c:1051
struct list entry
Definition: typelib.c:1056
HREFTYPE hRef
Definition: typelib.c:1200
struct list custdata_list
Definition: typelib.c:1202
const TLBString * Name
Definition: typelib.c:1168
struct list custdata_list
Definition: typelib.c:1169
TLBGuid * guid
Definition: typelib.c:1149
HREFTYPE reference
Definition: typelib.c:1152
TLBImpLib * pImpTLInfo
Definition: typelib.c:1153
TYPEKIND tkind
Definition: typelib.c:1148
struct list entry
Definition: typelib.c:1157
struct list entry
Definition: typelib.c:1062
UINT offset
Definition: typelib.c:1061
int HelpStringContext
Definition: typelib.c:1192
const TLBString * HelpString
Definition: typelib.c:1193
VARDESC * vardesc_create
Definition: typelib.c:1189
struct list custdata_list
Definition: typelib.c:1194
VARDESC vardesc
Definition: typelib.c:1188
const TLBString * Name
Definition: typelib.c:1190
int HelpContext
Definition: typelib.c:1191
WMSFT_SegContents aux_seg
Definition: typelib.c:9042
WMSFT_SegContents typeinfo_seg
Definition: typelib.c:9028
WMSFT_SegContents namehash_seg
Definition: typelib.c:9034
WMSFT_SegContents ref_seg
Definition: typelib.c:9031
MSFT_Header header
Definition: typelib.c:9027
WMSFT_SegContents impinfo_seg
Definition: typelib.c:9030
WMSFT_SegContents arraydesc_seg
Definition: typelib.c:9038
WMSFT_SegContents impfile_seg
Definition: typelib.c:9029
WMSFT_SegContents custdata_seg
Definition: typelib.c:9039
WMSFT_SegContents guidhash_seg
Definition: typelib.c:9032
WMSFT_SegContents guid_seg
Definition: typelib.c:9033
WMSFT_SegContents string_seg
Definition: typelib.c:9036
MSFT_SegDir segdir
Definition: typelib.c:9041
WMSFT_SegContents cdguids_seg
Definition: typelib.c:9040
WMSFT_SegContents name_seg
Definition: typelib.c:9035
WMSFT_SegContents typdesc_seg
Definition: typelib.c:9037
Definition: tools.h:99
ULONG name_offset
Definition: oleaut.c:790
ULONG help_len
Definition: oleaut.c:793
ULONG help_offset
Definition: oleaut.c:794
WORD minor_version
Definition: oleaut.c:796
ULONG name_len
Definition: oleaut.c:789
LANGID langid
Definition: oleaut.c:791
WORD major_version
Definition: oleaut.c:795
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
const char * LPCSTR
Definition: typedefs.h:52
int32_t INT_PTR
Definition: typedefs.h:64
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
int64_t LONGLONG
Definition: typedefs.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
char * LPSTR
Definition: typedefs.h:51
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:96
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, const VARIANTARG *pvargSrc)
Definition: variant.c:724
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, const VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:939
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:626
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, const VARIANTARG *pvargSrc)
Definition: variant.c:823
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:547
HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
Definition: variant.c:554
static unsigned stack_offset(compile_ctx_t *ctx)
Definition: compile.c:367
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
int retval
Definition: wcstombs.cpp:91
_In_ WDFCOLLECTION _In_ ULONG Index
type_kind
Definition: widltypes.h:232
@ TKIND_MODULE
Definition: widltypes.h:236
@ TKIND_COCLASS
Definition: widltypes.h:239
@ TKIND_RECORD
Definition: widltypes.h:235
@ TKIND_ENUM
Definition: widltypes.h:234
@ TKIND_UNION
Definition: widltypes.h:241
@ TKIND_ALIAS
Definition: widltypes.h:240
@ TKIND_DISPATCH
Definition: widltypes.h:238
@ TKIND_INTERFACE
Definition: widltypes.h:237
@ SYS_WIN16
Definition: widltypes.h:646
@ SYS_WIN32
Definition: widltypes.h:647
@ SYS_WIN64
Definition: widltypes.h:649
@ SYS_MAC
Definition: widltypes.h:648
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:338
void WINAPI DebugBreak(void)
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:340
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define OF_READ
Definition: winbase.h:119
#define DONT_RESOLVE_DLL_REFERENCES
Definition: winbase.h:337
WINBASEAPI _In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon_undoc.h:337
_In_ PATHOBJ _In_ CLIPOBJ _In_ BRUSHOBJ _In_ POINTL _In_ MIX mix
Definition: winddi.h:3595
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define TYPE_E_BADMODULEKIND
Definition: winerror.h:3647
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:3616
#define DISP_E_NONAMEDARGS
Definition: winerror.h:3619
#define TYPE_E_REGISTRYACCESS
Definition: winerror.h:3636
#define TYPE_E_ELEMENTNOTFOUND
Definition: winerror.h:3642
#define DISP_E_BADCALLEE
Definition: winerror.h:3628
#define TYPE_E_DLLFUNCTIONNOTFOUND
Definition: winerror.h:3646
#define E_NOINTERFACE
Definition: winerror.h:3479
#define DISP_E_BADVARTYPE
Definition: winerror.h:3620
#define TYPE_E_AMBIGUOUSNAME
Definition: winerror.h:3643
#define TYPE_E_INCONSISTENTPROPFUNCS
Definition: winerror.h:3656
#define DISP_E_BADPARAMCOUNT
Definition: winerror.h:3626
#define TYPE_E_TYPEMISMATCH
Definition: winerror.h:3651
#define STG_E_FILENOTFOUND
Definition: winerror.h:3660
#define DISP_E_NOTACOLLECTION
Definition: winerror.h:3629
#define TYPE_E_CANTLOADLIBRARY
Definition: winerror.h:3655
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:3615
#define TYPE_E_NAMECONFLICT
Definition: winerror.h:3644
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define E_UNEXPECTED
Definition: winerror.h:3528
#define DISP_E_EXCEPTION
Definition: winerror.h:3621
#define TYPE_E_IOERROR
Definition: winerror.h:3653
#define TYPE_E_INVALIDSTATE
Definition: winerror.h:3640
#define E_POINTER
Definition: winerror.h:3480
#define TYPE_E_LIBNOTREGISTERED
Definition: winerror.h:3637
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:3618
#define STG_E_INSUFFICIENTMEMORY
Definition: winerror.h:3665
#define MB_PRECOMPOSED
Definition: winnls.h:309
ACCESS_MASK REGSAM
Definition: winreg.h:76
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#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
unsigned char BYTE
Definition: xxhash.c:193