oleaut32: Implement GetFuncDesc_Proxy and friends.
[wine.git] / dlls / oleaut32 / usrmarshal.c
blobf71aeac1ae493e0cd3e8947d62fe896295bba5b0
1 /*
2 * Misc marshalling routines
4 * Copyright 2002 Ove Kaaven
5 * Copyright 2003 Mike Hearn
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdarg.h>
23 #include <string.h>
25 #define COBJMACROS
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "winerror.h"
35 #include "ole2.h"
36 #include "oleauto.h"
37 #include "rpcproxy.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ole);
42 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
43 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
44 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
45 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
47 /* FIXME: not supposed to be here */
49 const CLSID CLSID_PSDispatch = {
50 0x20420, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
53 static CStdPSFactoryBuffer PSFactoryBuffer;
55 CSTDSTUBBUFFERRELEASE(&PSFactoryBuffer)
57 extern const ExtendedProxyFileInfo oaidl_ProxyFileInfo;
59 const ProxyFileInfo* OLEAUT32_ProxyFileList[] = {
60 &oaidl_ProxyFileInfo,
61 NULL
64 HRESULT OLEAUTPS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
66 return NdrDllGetClassObject(rclsid, riid, ppv, OLEAUT32_ProxyFileList,
67 &CLSID_PSDispatch, &PSFactoryBuffer);
70 static void dump_user_flags(unsigned long *pFlags)
72 if (HIWORD(*pFlags) == NDR_LOCAL_DATA_REPRESENTATION)
73 TRACE("MAKELONG(NDR_LOCAL_REPRESENTATION, ");
74 else
75 TRACE("MAKELONG(0x%04x, ", HIWORD(*pFlags));
76 switch (LOWORD(*pFlags))
78 case MSHCTX_LOCAL: TRACE("MSHCTX_LOCAL)"); break;
79 case MSHCTX_NOSHAREDMEM: TRACE("MSHCTX_NOSHAREDMEM)"); break;
80 case MSHCTX_DIFFERENTMACHINE: TRACE("MSHCTX_DIFFERENTMACHINE)"); break;
81 case MSHCTX_INPROC: TRACE("MSHCTX_INPROC)"); break;
82 default: TRACE("%d)", LOWORD(*pFlags));
86 /* CLEANLOCALSTORAGE */
88 #define CLS_FUNCDESC 0x66
89 #define CLS_LIBATTR 0x6c
90 #define CLS_TYPEATTR 0x74
91 #define CLS_VARDESC 0x76
93 unsigned long WINAPI CLEANLOCALSTORAGE_UserSize(unsigned long *pFlags, unsigned long Start, CLEANLOCALSTORAGE *pstg)
95 ALIGN_LENGTH(Start, 3);
96 return Start + sizeof(DWORD);
99 unsigned char * WINAPI CLEANLOCALSTORAGE_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstg)
101 ALIGN_POINTER(Buffer, 3);
102 *(DWORD*)Buffer = pstg->flags;
103 switch(pstg->flags)
105 case CLS_LIBATTR:
106 ITypeLib_ReleaseTLibAttr((ITypeLib*)pstg->pInterface, *(TLIBATTR**)pstg->pStorage);
107 break;
108 case CLS_TYPEATTR:
109 ITypeInfo_ReleaseTypeAttr((ITypeInfo*)pstg->pInterface, *(TYPEATTR**)pstg->pStorage);
110 break;
111 case CLS_FUNCDESC:
112 ITypeInfo_ReleaseFuncDesc((ITypeInfo*)pstg->pInterface, *(FUNCDESC**)pstg->pStorage);
113 break;
114 case CLS_VARDESC:
115 ITypeInfo_ReleaseVarDesc((ITypeInfo*)pstg->pInterface, *(VARDESC**)pstg->pStorage);
116 break;
118 default:
119 ERR("Unknown type %lx\n", pstg->flags);
122 *(VOID**)pstg->pStorage = NULL;
123 IUnknown_Release(pstg->pInterface);
124 pstg->pInterface = NULL;
126 return Buffer + sizeof(DWORD);
129 unsigned char * WINAPI CLEANLOCALSTORAGE_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstr)
131 ALIGN_POINTER(Buffer, 3);
132 pstr->flags = *(DWORD*)Buffer;
133 return Buffer + sizeof(DWORD);
136 void WINAPI CLEANLOCALSTORAGE_UserFree(unsigned long *pFlags, CLEANLOCALSTORAGE *pstr)
138 /* Nothing to do */
141 /* BSTR */
143 unsigned long WINAPI BSTR_UserSize(unsigned long *pFlags, unsigned long Start, BSTR *pstr)
145 TRACE("(%lx,%ld,%p) => %p\n", *pFlags, Start, pstr, *pstr);
146 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
147 Start += sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (SysStringLen(*pstr) - 1);
148 TRACE("returning %ld\n", Start);
149 return Start;
152 unsigned char * WINAPI BSTR_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, BSTR *pstr)
154 wireBSTR str = (wireBSTR)Buffer;
156 TRACE("(%lx,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr);
157 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
158 str->fFlags = 0;
159 str->clSize = SysStringLen(*pstr);
160 if (str->clSize)
161 memcpy(&str->asData, *pstr, sizeof(OLECHAR) * str->clSize);
162 return Buffer + sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (str->clSize - 1);
165 unsigned char * WINAPI BSTR_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, BSTR *pstr)
167 wireBSTR str = (wireBSTR)Buffer;
168 TRACE("(%lx,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr);
169 if (str->clSize) {
170 SysReAllocStringLen(pstr, (OLECHAR*)&str->asData, str->clSize);
172 else if (*pstr) {
173 SysFreeString(*pstr);
174 *pstr = NULL;
176 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
177 return Buffer + sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (str->clSize - 1);
180 void WINAPI BSTR_UserFree(unsigned long *pFlags, BSTR *pstr)
182 TRACE("(%lx,%p) => %p\n", *pFlags, pstr, *pstr);
183 if (*pstr) {
184 SysFreeString(*pstr);
185 *pstr = NULL;
189 /* VARIANT */
190 /* I'm not too sure how to do this yet */
192 #define VARIANT_wiresize sizeof(struct _wireVARIANT)
194 static unsigned wire_size(VARTYPE vt)
196 if (vt & VT_ARRAY) return 0;
198 switch (vt & ~VT_BYREF) {
199 case VT_EMPTY:
200 case VT_NULL:
201 return 0;
202 case VT_I1:
203 case VT_UI1:
204 return sizeof(CHAR);
205 case VT_I2:
206 case VT_UI2:
207 return sizeof(SHORT);
208 case VT_I4:
209 case VT_UI4:
210 return sizeof(LONG);
211 case VT_INT:
212 case VT_UINT:
213 return sizeof(INT);
214 case VT_R4:
215 return sizeof(FLOAT);
216 case VT_R8:
217 return sizeof(DOUBLE);
218 case VT_BOOL:
219 return sizeof(VARIANT_BOOL);
220 case VT_ERROR:
221 return sizeof(SCODE);
222 case VT_DATE:
223 return sizeof(DATE);
224 case VT_CY:
225 return sizeof(CY);
226 case VT_DECIMAL:
227 return sizeof(DECIMAL);
228 case VT_BSTR:
229 case VT_VARIANT:
230 case VT_UNKNOWN:
231 case VT_DISPATCH:
232 case VT_SAFEARRAY:
233 case VT_RECORD:
234 return 0;
235 default:
236 FIXME("unhandled VT %d\n", vt);
237 return 0;
241 static unsigned interface_variant_size(unsigned long *pFlags, REFIID riid, VARIANT *pvar)
243 ULONG size;
244 HRESULT hr;
245 /* find the buffer size of the marshalled dispatch interface */
246 hr = CoGetMarshalSizeMax(&size, riid, V_UNKNOWN(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
247 if (FAILED(hr)) {
248 if (!V_DISPATCH(pvar))
249 WARN("NULL dispatch pointer\n");
250 else
251 ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%lx\n", hr);
252 return 0;
254 size += sizeof(ULONG); /* we have to store the buffersize in the stream */
255 TRACE("wire-size extra of dispatch variant is %ld\n", size);
256 return size;
259 static unsigned wire_extra(unsigned long *pFlags, VARIANT *pvar)
261 if (V_ISARRAY(pvar)) {
262 FIXME("wire-size safearray\n");
263 return 0;
265 switch (V_VT(pvar)) {
266 case VT_BSTR:
267 return BSTR_UserSize(pFlags, 0, &V_BSTR(pvar));
268 case VT_BSTR | VT_BYREF:
269 return BSTR_UserSize(pFlags, 0, V_BSTRREF(pvar));
270 case VT_SAFEARRAY:
271 case VT_SAFEARRAY | VT_BYREF:
272 FIXME("wire-size safearray\n");
273 return 0;
274 case VT_VARIANT | VT_BYREF:
275 return VARIANT_UserSize(pFlags, 0, V_VARIANTREF(pvar));
276 case VT_UNKNOWN:
277 return interface_variant_size(pFlags, &IID_IUnknown, pvar);
278 case VT_DISPATCH:
279 return interface_variant_size(pFlags, &IID_IDispatch, pvar);
280 case VT_RECORD:
281 FIXME("wire-size record\n");
282 return 0;
283 default:
284 return 0;
288 /* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer. returns Buffer on failure, new position otherwise */
289 static unsigned char* interface_variant_marshal(unsigned long *pFlags, unsigned char *Buffer, REFIID riid, VARIANT *pvar)
291 IStream *working;
292 HGLOBAL working_mem;
293 void *working_memlocked;
294 unsigned char *oldpos;
295 ULONG size;
296 HRESULT hr;
298 TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar);
300 oldpos = Buffer;
302 /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers.
303 * We create a stream on an HGLOBAL, so we can simply do a memcpy to move it to the buffer.
304 * in rpcrt4/ndr_ole.c, a simple IStream implementation is wrapped around the buffer object,
305 * but that would be overkill here, hence this implementation. We save the size because the unmarshal
306 * code has no way to know how long the marshalled buffer is. */
308 size = wire_extra(pFlags, pvar);
310 working_mem = GlobalAlloc(0, size);
311 if (!working_mem) return oldpos;
313 hr = CreateStreamOnHGlobal(working_mem, TRUE, &working);
314 if (hr != S_OK) {
315 GlobalFree(working_mem);
316 return oldpos;
319 hr = CoMarshalInterface(working, riid, V_UNKNOWN(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
320 if (hr != S_OK) {
321 IStream_Release(working); /* this also releases the hglobal */
322 return oldpos;
325 working_memlocked = GlobalLock(working_mem);
326 memcpy(Buffer, &size, sizeof(ULONG)); /* copy the buffersize */
327 memcpy(Buffer + sizeof(ULONG), working_memlocked, size);
328 GlobalUnlock(working_mem);
330 IStream_Release(working);
332 /* size includes the ULONG for the size written above */
333 TRACE("done, size=%ld\n", size);
334 return Buffer + size;
337 /* helper: called for VT_DISPATCH / VT_UNKNOWN variants to unmarshal the buffer. returns Buffer on failure, new position otherwise */
338 static unsigned char *interface_variant_unmarshal(unsigned long *pFlags, unsigned char *Buffer, REFIID riid, VARIANT *pvar)
340 IStream *working;
341 HGLOBAL working_mem;
342 void *working_memlocked;
343 unsigned char *oldpos;
344 ULONG size;
345 HRESULT hr;
347 TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar);
349 oldpos = Buffer;
351 /* get the buffersize */
352 memcpy(&size, Buffer, sizeof(ULONG));
353 TRACE("buffersize=%ld\n", size);
355 working_mem = GlobalAlloc(0, size);
356 if (!working_mem) return oldpos;
358 hr = CreateStreamOnHGlobal(working_mem, TRUE, &working);
359 if (hr != S_OK) {
360 GlobalFree(working_mem);
361 return oldpos;
364 working_memlocked = GlobalLock(working_mem);
366 /* now we copy the contents of the marshalling buffer to working_memlocked, unlock it, and demarshal the stream */
367 memcpy(working_memlocked, Buffer + sizeof(ULONG), size);
368 GlobalUnlock(working_mem);
370 hr = CoUnmarshalInterface(working, riid, (void**)&V_UNKNOWN(pvar));
371 if (hr != S_OK) {
372 IStream_Release(working);
373 return oldpos;
376 IStream_Release(working); /* this also frees the underlying hglobal */
378 /* size includes the ULONG for the size written above */
379 TRACE("done, processed=%ld bytes\n", size);
380 return Buffer + size;
384 unsigned long WINAPI VARIANT_UserSize(unsigned long *pFlags, unsigned long Start, VARIANT *pvar)
386 TRACE("(%lx,%ld,%p)\n", *pFlags, Start, pvar);
387 TRACE("vt=%04x\n", V_VT(pvar));
388 Start += VARIANT_wiresize + wire_extra(pFlags, pvar);
389 TRACE("returning %ld\n", Start);
390 return Start;
393 unsigned char * WINAPI VARIANT_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar)
395 wireVARIANT var = (wireVARIANT)Buffer;
396 unsigned size, extra;
397 unsigned char *Pos = Buffer + VARIANT_wiresize;
399 TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar);
400 TRACE("vt=%04x\n", V_VT(pvar));
402 memset(var, 0, sizeof(*var));
403 var->clSize = sizeof(*var);
404 var->vt = pvar->n1.n2.vt;
406 var->rpcReserved = var->vt;
407 if ((var->vt & VT_ARRAY) ||
408 ((var->vt & VT_TYPEMASK) == VT_SAFEARRAY))
409 var->vt = VT_ARRAY | (var->vt & VT_BYREF);
411 if (var->vt == VT_DECIMAL) {
412 /* special case because decVal is on a different level */
413 var->u.decVal = pvar->n1.decVal;
414 return Pos;
417 size = wire_size(V_VT(pvar));
418 extra = wire_extra(pFlags, pvar);
419 var->wReserved1 = pvar->n1.n2.wReserved1;
420 var->wReserved2 = pvar->n1.n2.wReserved2;
421 var->wReserved3 = pvar->n1.n2.wReserved3;
422 if (size) {
423 if (var->vt & VT_BYREF)
424 memcpy(&var->u.cVal, pvar->n1.n2.n3.byref, size);
425 else
426 memcpy(&var->u.cVal, &pvar->n1.n2.n3, size);
428 if (!extra) return Pos;
430 switch (var->vt) {
431 case VT_BSTR:
432 Pos = BSTR_UserMarshal(pFlags, Pos, &V_BSTR(pvar));
433 break;
434 case VT_BSTR | VT_BYREF:
435 Pos = BSTR_UserMarshal(pFlags, Pos, V_BSTRREF(pvar));
436 break;
437 case VT_VARIANT | VT_BYREF:
438 Pos = VARIANT_UserMarshal(pFlags, Pos, V_VARIANTREF(pvar));
439 break;
440 case VT_DISPATCH | VT_BYREF:
441 FIXME("handle DISPATCH by ref\n");
442 break;
443 case VT_UNKNOWN:
444 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
445 Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, pvar);
446 break;
447 case VT_DISPATCH:
448 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
449 Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, pvar);
450 break;
451 case VT_RECORD:
452 FIXME("handle BRECORD by val\n");
453 break;
454 case VT_RECORD | VT_BYREF:
455 FIXME("handle BRECORD by ref\n");
456 break;
457 default:
458 FIXME("handle unknown complex type\n");
459 break;
461 var->clSize = Pos - Buffer;
462 TRACE("marshalled size=%ld\n", var->clSize);
463 return Pos;
466 unsigned char * WINAPI VARIANT_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar)
468 wireVARIANT var = (wireVARIANT)Buffer;
469 unsigned size;
470 unsigned char *Pos = Buffer + VARIANT_wiresize;
472 TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar);
473 VariantInit(pvar);
474 pvar->n1.n2.vt = var->rpcReserved;
475 TRACE("marshalled: clSize=%ld, vt=%04x\n", var->clSize, var->vt);
476 TRACE("vt=%04x\n", V_VT(pvar));
477 TRACE("reserved: %d, %d, %d\n", var->wReserved1, var->wReserved2, var->wReserved3);
478 TRACE("val: %ld\n", var->u.lVal);
480 if (var->vt == VT_DECIMAL) {
481 /* special case because decVal is on a different level */
482 pvar->n1.decVal = var->u.decVal;
483 return Pos;
486 size = wire_size(V_VT(pvar));
487 pvar->n1.n2.wReserved1 = var->wReserved1;
488 pvar->n1.n2.wReserved2 = var->wReserved2;
489 pvar->n1.n2.wReserved3 = var->wReserved3;
490 if (size) {
491 if (var->vt & VT_BYREF) {
492 pvar->n1.n2.n3.byref = CoTaskMemAlloc(size);
493 memcpy(pvar->n1.n2.n3.byref, &var->u.cVal, size);
495 else
496 memcpy(&pvar->n1.n2.n3, &var->u.cVal, size);
498 if (var->clSize <= VARIANT_wiresize) return Pos;
500 switch (var->vt) {
501 case VT_BSTR:
502 V_BSTR(pvar) = NULL;
503 Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar));
504 break;
505 case VT_BSTR | VT_BYREF:
506 pvar->n1.n2.n3.byref = CoTaskMemAlloc(sizeof(BSTR));
507 *(BSTR*)V_BYREF(pvar) = NULL;
508 Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar));
509 break;
510 case VT_VARIANT | VT_BYREF:
511 pvar->n1.n2.n3.byref = CoTaskMemAlloc(sizeof(VARIANT));
512 Pos = VARIANT_UserUnmarshal(pFlags, Pos, V_VARIANTREF(pvar));
513 break;
514 case VT_RECORD:
515 FIXME("handle BRECORD by val\n");
516 break;
517 case VT_RECORD | VT_BYREF:
518 FIXME("handle BRECORD by ref\n");
519 break;
520 case VT_UNKNOWN:
521 Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, pvar);
522 break;
523 case VT_DISPATCH:
524 Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, pvar);
525 break;
526 case VT_DISPATCH | VT_BYREF:
527 FIXME("handle DISPATCH by ref\n");
528 default:
529 FIXME("handle unknown complex type\n");
530 break;
532 if (Pos != Buffer + var->clSize) {
533 ERR("size difference during unmarshal\n");
535 return Buffer + var->clSize;
538 void WINAPI VARIANT_UserFree(unsigned long *pFlags, VARIANT *pvar)
540 VARTYPE vt = V_VT(pvar);
541 PVOID ref = NULL;
543 TRACE("(%lx,%p)\n", *pFlags, pvar);
544 TRACE("vt=%04x\n", V_VT(pvar));
546 if (vt & VT_BYREF) ref = pvar->n1.n2.n3.byref;
548 VariantClear(pvar);
549 if (!ref) return;
551 switch (vt) {
552 case VT_BSTR | VT_BYREF:
553 BSTR_UserFree(pFlags, ref);
554 break;
555 case VT_VARIANT | VT_BYREF:
556 VARIANT_UserFree(pFlags, ref);
557 break;
558 case VT_RECORD | VT_BYREF:
559 FIXME("handle BRECORD by ref\n");
560 break;
561 case VT_UNKNOWN:
562 case VT_DISPATCH:
563 IUnknown_Release(V_UNKNOWN(pvar));
564 break;
565 default:
566 FIXME("handle unknown complex type\n");
567 break;
570 CoTaskMemFree(ref);
573 /* LPSAFEARRAY */
575 /* Get the number of cells in a SafeArray */
576 static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa)
578 const SAFEARRAYBOUND* psab = psa->rgsabound;
579 USHORT cCount = psa->cDims;
580 ULONG ulNumCells = 1;
582 while (cCount--)
584 /* This is a valid bordercase. See testcases. -Marcus */
585 if (!psab->cElements)
586 return 0;
587 ulNumCells *= psab->cElements;
588 psab++;
590 return ulNumCells;
593 static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa)
595 VARTYPE vt;
596 HRESULT hr;
598 hr = SafeArrayGetVartype(psa, &vt);
599 if (FAILED(hr))
600 RpcRaiseException(hr);
602 if (psa->fFeatures & FADF_HAVEIID)
603 return SF_HAVEIID;
605 switch (vt)
607 case VT_I1:
608 case VT_UI1: return SF_I1;
609 case VT_BOOL:
610 case VT_I2:
611 case VT_UI2: return SF_I2;
612 case VT_INT:
613 case VT_UINT:
614 case VT_I4:
615 case VT_UI4:
616 case VT_R4: return SF_I4;
617 case VT_DATE:
618 case VT_CY:
619 case VT_R8:
620 case VT_I8:
621 case VT_UI8: return SF_I8;
622 case VT_INT_PTR:
623 case VT_UINT_PTR: return (sizeof(UINT_PTR) == 4 ? SF_I4 : SF_I8);
624 case VT_BSTR: return SF_BSTR;
625 case VT_DISPATCH: return SF_DISPATCH;
626 case VT_VARIANT: return SF_VARIANT;
627 case VT_UNKNOWN: return SF_UNKNOWN;
628 /* Note: Return a non-zero size to indicate vt is valid. The actual size
629 * of a UDT is taken from the result of IRecordInfo_GetSize().
631 case VT_RECORD: return SF_RECORD;
632 default: return SF_ERROR;
636 unsigned long WINAPI LPSAFEARRAY_UserSize(unsigned long *pFlags, unsigned long StartingSize, LPSAFEARRAY *ppsa)
638 unsigned long size = StartingSize;
640 TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n", StartingSize, *ppsa);
642 size += sizeof(ULONG_PTR);
643 if (*ppsa)
645 SAFEARRAY *psa = *ppsa;
646 ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
647 SF_TYPE sftype;
648 HRESULT hr;
650 size += sizeof(ULONG);
651 size += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
653 sftype = SAFEARRAY_GetUnionType(psa);
654 size += sizeof(ULONG);
656 size += sizeof(ULONG);
657 size += sizeof(ULONG_PTR);
658 if (sftype == SF_HAVEIID)
659 size += sizeof(IID);
661 size += sizeof(psa->rgsabound[0]) * psa->cDims;
663 size += sizeof(ULONG);
665 switch (sftype)
667 case SF_BSTR:
669 BSTR* lpBstr;
671 for (lpBstr = (BSTR*)psa->pvData; ulCellCount; ulCellCount--, lpBstr++)
672 size = BSTR_UserSize(pFlags, size, lpBstr);
674 break;
676 case SF_DISPATCH:
677 case SF_UNKNOWN:
678 case SF_HAVEIID:
679 FIXME("size interfaces\n");
680 break;
681 case SF_VARIANT:
683 VARIANT* lpVariant;
685 for (lpVariant = (VARIANT*)psa->pvData; ulCellCount; ulCellCount--, lpVariant++)
686 size = VARIANT_UserSize(pFlags, size, lpVariant);
688 break;
690 case SF_RECORD:
692 IRecordInfo* pRecInfo = NULL;
694 hr = SafeArrayGetRecordInfo(psa, &pRecInfo);
695 if (FAILED(hr))
696 RpcRaiseException(hr);
698 if (pRecInfo)
700 FIXME("size record info %p\n", pRecInfo);
702 IRecordInfo_Release(pRecInfo);
704 break;
706 case SF_I1:
707 case SF_I2:
708 case SF_I4:
709 case SF_I8:
710 size += ulCellCount * psa->cbElements;
711 break;
712 default:
713 break;
718 return size;
721 unsigned char * WINAPI LPSAFEARRAY_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa)
723 HRESULT hr;
725 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", Buffer, *ppsa);
727 *(ULONG_PTR *)Buffer = *ppsa ? TRUE : FALSE;
728 Buffer += sizeof(ULONG_PTR);
729 if (*ppsa)
731 VARTYPE vt;
732 SAFEARRAY *psa = *ppsa;
733 ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
734 wireSAFEARRAY wiresa;
735 SF_TYPE sftype;
736 GUID guid;
738 *(ULONG *)Buffer = psa->cDims;
739 Buffer += sizeof(ULONG);
740 wiresa = (wireSAFEARRAY)Buffer;
741 wiresa->cDims = psa->cDims;
742 wiresa->fFeatures = psa->fFeatures;
743 wiresa->cbElements = psa->cbElements;
745 hr = SafeArrayGetVartype(psa, &vt);
746 if (FAILED(hr))
747 RpcRaiseException(hr);
748 wiresa->cLocks = (USHORT)psa->cLocks | (vt << 16);
750 Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
752 sftype = SAFEARRAY_GetUnionType(psa);
753 *(ULONG *)Buffer = sftype;
754 Buffer += sizeof(ULONG);
756 *(ULONG *)Buffer = ulCellCount;
757 Buffer += sizeof(ULONG);
758 *(ULONG_PTR *)Buffer = (ULONG_PTR)psa->pvData;
759 Buffer += sizeof(ULONG_PTR);
760 if (sftype == SF_HAVEIID)
762 SafeArrayGetIID(psa, &guid);
763 memcpy(Buffer, &guid, sizeof(guid));
764 Buffer += sizeof(guid);
767 memcpy(Buffer, psa->rgsabound, sizeof(psa->rgsabound[0]) * psa->cDims);
768 Buffer += sizeof(psa->rgsabound[0]) * psa->cDims;
770 *(ULONG *)Buffer = ulCellCount;
771 Buffer += sizeof(ULONG);
773 if (psa->pvData)
775 switch (sftype)
777 case SF_BSTR:
779 BSTR* lpBstr;
781 for (lpBstr = (BSTR*)psa->pvData; ulCellCount; ulCellCount--, lpBstr++)
782 Buffer = BSTR_UserMarshal(pFlags, Buffer, lpBstr);
784 break;
786 case SF_DISPATCH:
787 case SF_UNKNOWN:
788 case SF_HAVEIID:
789 FIXME("marshal interfaces\n");
790 break;
791 case SF_VARIANT:
793 VARIANT* lpVariant;
795 for (lpVariant = (VARIANT*)psa->pvData; ulCellCount; ulCellCount--, lpVariant++)
796 Buffer = VARIANT_UserMarshal(pFlags, Buffer, lpVariant);
798 break;
800 case SF_RECORD:
802 IRecordInfo* pRecInfo = NULL;
804 hr = SafeArrayGetRecordInfo(psa, &pRecInfo);
805 if (FAILED(hr))
806 RpcRaiseException(hr);
808 if (pRecInfo)
810 FIXME("write record info %p\n", pRecInfo);
812 IRecordInfo_Release(pRecInfo);
814 break;
816 case SF_I1:
817 case SF_I2:
818 case SF_I4:
819 case SF_I8:
820 /* Just copy the data over */
821 memcpy(Buffer, psa->pvData, ulCellCount * psa->cbElements);
822 Buffer += ulCellCount * psa->cbElements;
823 break;
824 default:
825 break;
830 return Buffer;
833 #define FADF_AUTOSETFLAGS (FADF_HAVEIID | FADF_RECORD | FADF_HAVEVARTYPE | \
834 FADF_BSTR | FADF_UNKNOWN | FADF_DISPATCH | \
835 FADF_VARIANT | FADF_CREATEVECTOR)
837 unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa)
839 ULONG_PTR ptr;
840 wireSAFEARRAY wiresa;
841 ULONG cDims;
842 HRESULT hr;
843 SF_TYPE sftype;
844 ULONG cell_count;
845 GUID guid;
846 VARTYPE vt;
847 SAFEARRAYBOUND *wiresab;
849 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", Buffer, ppsa);
851 ptr = *(ULONG_PTR *)Buffer;
852 Buffer += sizeof(ULONG_PTR);
854 if (!ptr)
856 *ppsa = NULL;
858 TRACE("NULL safe array unmarshaled\n");
860 return Buffer;
863 cDims = *(ULONG *)Buffer;
864 Buffer += sizeof(ULONG);
866 wiresa = (wireSAFEARRAY)Buffer;
867 Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
869 if (cDims != wiresa->cDims)
870 RpcRaiseException(RPC_S_INVALID_BOUND);
872 /* FIXME: there should be a limit on how large cDims can be */
874 vt = HIWORD(wiresa->cLocks);
876 sftype = *(ULONG *)Buffer;
877 Buffer += sizeof(ULONG);
879 cell_count = *(ULONG *)Buffer;
880 Buffer += sizeof(ULONG);
881 ptr = *(ULONG_PTR *)Buffer;
882 Buffer += sizeof(ULONG_PTR);
883 if (sftype == SF_HAVEIID)
885 memcpy(&guid, Buffer, sizeof(guid));
886 Buffer += sizeof(guid);
889 wiresab = (SAFEARRAYBOUND *)Buffer;
890 Buffer += sizeof(wiresab[0]) * wiresa->cDims;
892 *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL);
893 if (!*ppsa)
894 RpcRaiseException(E_OUTOFMEMORY);
896 /* be careful about which flags we set since they could be a security
897 * risk */
898 (*ppsa)->fFeatures = wiresa->fFeatures & ~(FADF_AUTOSETFLAGS);
899 /* FIXME: there should be a limit on how large wiresa->cbElements can be */
900 (*ppsa)->cbElements = wiresa->cbElements;
901 (*ppsa)->cLocks = LOWORD(wiresa->cLocks);
903 hr = SafeArrayAllocData(*ppsa);
904 if (FAILED(hr))
905 RpcRaiseException(hr);
907 if ((*(ULONG *)Buffer != cell_count) || (SAFEARRAY_GetCellCount(*ppsa) != cell_count))
908 RpcRaiseException(RPC_S_INVALID_BOUND);
909 Buffer += sizeof(ULONG);
911 if (ptr)
913 switch (sftype)
915 case SF_BSTR:
917 BSTR* lpBstr;
919 for (lpBstr = (BSTR*)(*ppsa)->pvData; cell_count; cell_count--, lpBstr++)
920 Buffer = BSTR_UserUnmarshal(pFlags, Buffer, lpBstr);
922 break;
924 case SF_DISPATCH:
925 case SF_UNKNOWN:
926 case SF_HAVEIID:
927 FIXME("marshal interfaces\n");
928 break;
929 case SF_VARIANT:
931 VARIANT* lpVariant;
933 for (lpVariant = (VARIANT*)(*ppsa)->pvData; cell_count; cell_count--, lpVariant++)
934 Buffer = VARIANT_UserUnmarshal(pFlags, Buffer, lpVariant);
936 break;
938 case SF_RECORD:
940 FIXME("set record info\n");
942 break;
944 case SF_I1:
945 case SF_I2:
946 case SF_I4:
947 case SF_I8:
948 /* Just copy the data over */
949 memcpy((*ppsa)->pvData, Buffer, cell_count * (*ppsa)->cbElements);
950 Buffer += cell_count * (*ppsa)->cbElements;
951 break;
952 default:
953 break;
957 TRACE("safe array unmarshaled: %p\n", *ppsa);
959 return Buffer;
962 void WINAPI LPSAFEARRAY_UserFree(unsigned long *pFlags, LPSAFEARRAY *ppsa)
964 TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *ppsa);
966 SafeArrayDestroy(*ppsa);
969 /* IDispatch */
970 /* exactly how Invoke is marshalled is not very clear to me yet,
971 * but the way I've done it seems to work for me */
973 HRESULT CALLBACK IDispatch_Invoke_Proxy(
974 IDispatch* This,
975 DISPID dispIdMember,
976 REFIID riid,
977 LCID lcid,
978 WORD wFlags,
979 DISPPARAMS* pDispParams,
980 VARIANT* pVarResult,
981 EXCEPINFO* pExcepInfo,
982 UINT* puArgErr)
984 HRESULT hr;
985 VARIANT VarResult;
986 UINT* rgVarRefIdx = NULL;
987 VARIANTARG* rgVarRef = NULL;
988 UINT u, cVarRef;
989 UINT uArgErr;
990 EXCEPINFO ExcepInfo;
992 TRACE("(%p)->(%ld,%s,%lx,%x,%p,%p,%p,%p)\n", This,
993 dispIdMember, debugstr_guid(riid),
994 lcid, wFlags, pDispParams, pVarResult,
995 pExcepInfo, puArgErr);
997 /* [out] args can't be null, use dummy vars if needed */
998 if (!pVarResult) pVarResult = &VarResult;
999 if (!puArgErr) puArgErr = &uArgErr;
1000 if (!pExcepInfo) pExcepInfo = &ExcepInfo;
1002 /* count by-ref args */
1003 for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
1004 VARIANTARG* arg = &pDispParams->rgvarg[u];
1005 if (V_ISBYREF(arg)) {
1006 cVarRef++;
1009 if (cVarRef) {
1010 rgVarRefIdx = CoTaskMemAlloc(sizeof(UINT)*cVarRef);
1011 rgVarRef = CoTaskMemAlloc(sizeof(VARIANTARG)*cVarRef);
1012 /* make list of by-ref args */
1013 for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
1014 VARIANTARG* arg = &pDispParams->rgvarg[u];
1015 if (V_ISBYREF(arg)) {
1016 rgVarRefIdx[cVarRef] = u;
1017 VariantInit(&rgVarRef[cVarRef]);
1018 cVarRef++;
1021 } else {
1022 /* [out] args still can't be null,
1023 * but we can point these anywhere in this case,
1024 * since they won't be written to when cVarRef is 0 */
1025 rgVarRefIdx = puArgErr;
1026 rgVarRef = pVarResult;
1028 TRACE("passed by ref: %d args\n", cVarRef);
1029 hr = IDispatch_RemoteInvoke_Proxy(This,
1030 dispIdMember,
1031 riid,
1032 lcid,
1033 wFlags,
1034 pDispParams,
1035 pVarResult,
1036 pExcepInfo,
1037 puArgErr,
1038 cVarRef,
1039 rgVarRefIdx,
1040 rgVarRef);
1041 if (cVarRef) {
1042 for (u=0; u<cVarRef; u++) {
1043 unsigned i = rgVarRefIdx[u];
1044 VariantCopy(&pDispParams->rgvarg[i],
1045 &rgVarRef[u]);
1046 VariantClear(&rgVarRef[u]);
1048 CoTaskMemFree(rgVarRef);
1049 CoTaskMemFree(rgVarRefIdx);
1052 if(pExcepInfo == &ExcepInfo)
1054 SysFreeString(pExcepInfo->bstrSource);
1055 SysFreeString(pExcepInfo->bstrDescription);
1056 SysFreeString(pExcepInfo->bstrHelpFile);
1058 return hr;
1061 HRESULT __RPC_STUB IDispatch_Invoke_Stub(
1062 IDispatch* This,
1063 DISPID dispIdMember,
1064 REFIID riid,
1065 LCID lcid,
1066 DWORD dwFlags,
1067 DISPPARAMS* pDispParams,
1068 VARIANT* pVarResult,
1069 EXCEPINFO* pExcepInfo,
1070 UINT* pArgErr,
1071 UINT cVarRef,
1072 UINT* rgVarRefIdx,
1073 VARIANTARG* rgVarRef)
1075 HRESULT hr = S_OK;
1076 VARIANTARG *rgvarg, *arg;
1077 UINT u;
1079 /* initialize out parameters, so that they can be marshalled
1080 * in case the real Invoke doesn't initialize them */
1081 VariantInit(pVarResult);
1082 memset(pExcepInfo, 0, sizeof(*pExcepInfo));
1083 *pArgErr = 0;
1085 /* let the real Invoke operate on a copy of the in parameters,
1086 * so we don't risk losing pointers to allocated memory */
1087 rgvarg = pDispParams->rgvarg;
1088 arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs);
1089 if (!arg) return E_OUTOFMEMORY;
1091 /* init all args so we can call VariantClear on all the args if the copy
1092 * below fails */
1093 for (u = 0; u < pDispParams->cArgs; u++)
1094 VariantInit(&arg[u]);
1096 for (u = 0; u < pDispParams->cArgs; u++) {
1097 hr = VariantCopy(&arg[u], &rgvarg[u]);
1098 if (FAILED(hr))
1099 break;
1102 if (SUCCEEDED(hr)) {
1103 pDispParams->rgvarg = arg;
1105 hr = IDispatch_Invoke(This,
1106 dispIdMember,
1107 riid,
1108 lcid,
1109 dwFlags,
1110 pDispParams,
1111 pVarResult,
1112 pExcepInfo,
1113 pArgErr);
1115 /* copy ref args to out list */
1116 for (u=0; u<cVarRef; u++) {
1117 unsigned i = rgVarRefIdx[u];
1118 VariantInit(&rgVarRef[u]);
1119 VariantCopy(&rgVarRef[u], &arg[i]);
1120 /* clear original if equal, to avoid double-free */
1121 if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
1122 VariantClear(&rgvarg[i]);
1126 /* clear the duplicate argument list */
1127 for (u=0; u<pDispParams->cArgs; u++)
1128 VariantClear(&arg[u]);
1130 pDispParams->rgvarg = rgvarg;
1131 CoTaskMemFree(arg);
1133 return hr;
1136 /* IEnumVARIANT */
1138 HRESULT CALLBACK IEnumVARIANT_Next_Proxy(
1139 IEnumVARIANT* This,
1140 ULONG celt,
1141 VARIANT* rgVar,
1142 ULONG* pCeltFetched)
1144 ULONG fetched;
1145 if (!pCeltFetched)
1146 pCeltFetched = &fetched;
1147 return IEnumVARIANT_RemoteNext_Proxy(This,
1148 celt,
1149 rgVar,
1150 pCeltFetched);
1153 HRESULT __RPC_STUB IEnumVARIANT_Next_Stub(
1154 IEnumVARIANT* This,
1155 ULONG celt,
1156 VARIANT* rgVar,
1157 ULONG* pCeltFetched)
1159 HRESULT hr;
1160 *pCeltFetched = 0;
1161 hr = IEnumVARIANT_Next(This,
1162 celt,
1163 rgVar,
1164 pCeltFetched);
1165 if (hr == S_OK) *pCeltFetched = celt;
1166 return hr;
1169 /* TypeInfo related freers */
1171 static void free_embedded_typedesc(TYPEDESC *tdesc);
1172 static void free_embedded_arraydesc(ARRAYDESC *adesc)
1174 switch(adesc->tdescElem.vt)
1176 case VT_PTR:
1177 case VT_SAFEARRAY:
1178 free_embedded_typedesc(adesc->tdescElem.u.lptdesc);
1179 CoTaskMemFree(adesc->tdescElem.u.lptdesc);
1180 break;
1181 case VT_CARRAY:
1182 free_embedded_arraydesc(adesc->tdescElem.u.lpadesc);
1183 CoTaskMemFree(adesc->tdescElem.u.lpadesc);
1184 break;
1188 static void free_embedded_typedesc(TYPEDESC *tdesc)
1190 switch(tdesc->vt)
1192 case VT_PTR:
1193 case VT_SAFEARRAY:
1194 free_embedded_typedesc(tdesc->u.lptdesc);
1195 CoTaskMemFree(tdesc->u.lptdesc);
1196 break;
1197 case VT_CARRAY:
1198 free_embedded_arraydesc(tdesc->u.lpadesc);
1199 CoTaskMemFree(tdesc->u.lpadesc);
1200 break;
1204 static void free_embedded_elemdesc(ELEMDESC *edesc)
1206 free_embedded_typedesc(&edesc->tdesc);
1207 if(edesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
1208 CoTaskMemFree(edesc->u.paramdesc.pparamdescex);
1211 /* ITypeComp */
1213 HRESULT CALLBACK ITypeComp_Bind_Proxy(
1214 ITypeComp* This,
1215 LPOLESTR szName,
1216 ULONG lHashVal,
1217 WORD wFlags,
1218 ITypeInfo** ppTInfo,
1219 DESCKIND* pDescKind,
1220 BINDPTR* pBindPtr)
1222 FIXME("not implemented\n");
1223 return E_FAIL;
1226 HRESULT __RPC_STUB ITypeComp_Bind_Stub(
1227 ITypeComp* This,
1228 LPOLESTR szName,
1229 ULONG lHashVal,
1230 WORD wFlags,
1231 ITypeInfo** ppTInfo,
1232 DESCKIND* pDescKind,
1233 LPFUNCDESC* ppFuncDesc,
1234 LPVARDESC* ppVarDesc,
1235 ITypeComp** ppTypeComp,
1236 CLEANLOCALSTORAGE* pDummy)
1238 FIXME("not implemented\n");
1239 return E_FAIL;
1242 HRESULT CALLBACK ITypeComp_BindType_Proxy(
1243 ITypeComp* This,
1244 LPOLESTR szName,
1245 ULONG lHashVal,
1246 ITypeInfo** ppTInfo,
1247 ITypeComp** ppTComp)
1249 FIXME("not implemented\n");
1250 return E_FAIL;
1253 HRESULT __RPC_STUB ITypeComp_BindType_Stub(
1254 ITypeComp* This,
1255 LPOLESTR szName,
1256 ULONG lHashVal,
1257 ITypeInfo** ppTInfo)
1259 FIXME("not implemented\n");
1260 return E_FAIL;
1263 /* ITypeInfo */
1265 HRESULT CALLBACK ITypeInfo_GetTypeAttr_Proxy(
1266 ITypeInfo* This,
1267 TYPEATTR** ppTypeAttr)
1270 CLEANLOCALSTORAGE stg;
1271 TRACE("(%p, %p)\n", This, ppTypeAttr);
1273 stg.flags = 0;
1274 stg.pStorage = NULL;
1275 stg.pInterface = NULL;
1277 return ITypeInfo_RemoteGetTypeAttr_Proxy(This, ppTypeAttr, &stg);
1280 HRESULT __RPC_STUB ITypeInfo_GetTypeAttr_Stub(
1281 ITypeInfo* This,
1282 LPTYPEATTR* ppTypeAttr,
1283 CLEANLOCALSTORAGE* pDummy)
1285 HRESULT hr;
1286 TRACE("(%p, %p)\n", This, ppTypeAttr);
1288 hr = ITypeInfo_GetTypeAttr(This, ppTypeAttr);
1289 if(hr != S_OK)
1290 return hr;
1292 pDummy->flags = CLS_TYPEATTR;
1293 ITypeInfo_AddRef(This);
1294 pDummy->pInterface = (IUnknown*)This;
1295 pDummy->pStorage = ppTypeAttr;
1296 return hr;
1299 HRESULT CALLBACK ITypeInfo_GetFuncDesc_Proxy(
1300 ITypeInfo* This,
1301 UINT index,
1302 FUNCDESC** ppFuncDesc)
1304 CLEANLOCALSTORAGE stg;
1305 TRACE("(%p, %d, %p)\n", This, index, ppFuncDesc);
1307 stg.flags = 0;
1308 stg.pStorage = NULL;
1309 stg.pInterface = NULL;
1311 return ITypeInfo_RemoteGetFuncDesc_Proxy(This, index, ppFuncDesc, &stg);
1314 HRESULT __RPC_STUB ITypeInfo_GetFuncDesc_Stub(
1315 ITypeInfo* This,
1316 UINT index,
1317 LPFUNCDESC* ppFuncDesc,
1318 CLEANLOCALSTORAGE* pDummy)
1320 HRESULT hr;
1321 TRACE("(%p, %d, %p)\n", This, index, ppFuncDesc);
1323 hr = ITypeInfo_GetFuncDesc(This, index, ppFuncDesc);
1324 if(hr != S_OK)
1325 return hr;
1327 pDummy->flags = CLS_FUNCDESC;
1328 ITypeInfo_AddRef(This);
1329 pDummy->pInterface = (IUnknown*)This;
1330 pDummy->pStorage = ppFuncDesc;
1331 return hr;
1334 HRESULT CALLBACK ITypeInfo_GetVarDesc_Proxy(
1335 ITypeInfo* This,
1336 UINT index,
1337 VARDESC** ppVarDesc)
1339 FIXME("not implemented\n");
1340 return E_FAIL;
1343 HRESULT __RPC_STUB ITypeInfo_GetVarDesc_Stub(
1344 ITypeInfo* This,
1345 UINT index,
1346 LPVARDESC* ppVarDesc,
1347 CLEANLOCALSTORAGE* pDummy)
1349 FIXME("not implemented\n");
1350 return E_FAIL;
1353 HRESULT CALLBACK ITypeInfo_GetNames_Proxy(
1354 ITypeInfo* This,
1355 MEMBERID memid,
1356 BSTR* rgBstrNames,
1357 UINT cMaxNames,
1358 UINT* pcNames)
1360 FIXME("not implemented\n");
1361 return E_FAIL;
1364 HRESULT __RPC_STUB ITypeInfo_GetNames_Stub(
1365 ITypeInfo* This,
1366 MEMBERID memid,
1367 BSTR* rgBstrNames,
1368 UINT cMaxNames,
1369 UINT* pcNames)
1371 FIXME("not implemented\n");
1372 return E_FAIL;
1375 HRESULT CALLBACK ITypeInfo_GetIDsOfNames_Proxy(
1376 ITypeInfo* This,
1377 LPOLESTR* rgszNames,
1378 UINT cNames,
1379 MEMBERID* pMemId)
1381 FIXME("not implemented\n");
1382 return E_FAIL;
1385 HRESULT __RPC_STUB ITypeInfo_GetIDsOfNames_Stub(
1386 ITypeInfo* This)
1388 FIXME("not implemented\n");
1389 return E_FAIL;
1392 HRESULT CALLBACK ITypeInfo_Invoke_Proxy(
1393 ITypeInfo* This,
1394 PVOID pvInstance,
1395 MEMBERID memid,
1396 WORD wFlags,
1397 DISPPARAMS* pDispParams,
1398 VARIANT* pVarResult,
1399 EXCEPINFO* pExcepInfo,
1400 UINT* puArgErr)
1402 FIXME("not implemented\n");
1403 return E_FAIL;
1406 HRESULT __RPC_STUB ITypeInfo_Invoke_Stub(
1407 ITypeInfo* This)
1409 FIXME("not implemented\n");
1410 return E_FAIL;
1413 HRESULT CALLBACK ITypeInfo_GetDocumentation_Proxy(
1414 ITypeInfo* This,
1415 MEMBERID memid,
1416 BSTR* pBstrName,
1417 BSTR* pBstrDocString,
1418 DWORD* pdwHelpContext,
1419 BSTR* pBstrHelpFile)
1421 FIXME("not implemented\n");
1422 return E_FAIL;
1425 HRESULT __RPC_STUB ITypeInfo_GetDocumentation_Stub(
1426 ITypeInfo* This,
1427 MEMBERID memid,
1428 DWORD refPtrFlags,
1429 BSTR* pBstrName,
1430 BSTR* pBstrDocString,
1431 DWORD* pdwHelpContext,
1432 BSTR* pBstrHelpFile)
1434 FIXME("not implemented\n");
1435 return E_FAIL;
1438 HRESULT CALLBACK ITypeInfo_GetDllEntry_Proxy(
1439 ITypeInfo* This,
1440 MEMBERID memid,
1441 INVOKEKIND invKind,
1442 BSTR* pBstrDllName,
1443 BSTR* pBstrName,
1444 WORD* pwOrdinal)
1446 FIXME("not implemented\n");
1447 return E_FAIL;
1450 HRESULT __RPC_STUB ITypeInfo_GetDllEntry_Stub(
1451 ITypeInfo* This,
1452 MEMBERID memid,
1453 INVOKEKIND invKind,
1454 DWORD refPtrFlags,
1455 BSTR* pBstrDllName,
1456 BSTR* pBstrName,
1457 WORD* pwOrdinal)
1459 FIXME("not implemented\n");
1460 return E_FAIL;
1463 HRESULT CALLBACK ITypeInfo_AddressOfMember_Proxy(
1464 ITypeInfo* This,
1465 MEMBERID memid,
1466 INVOKEKIND invKind,
1467 PVOID* ppv)
1469 FIXME("not implemented\n");
1470 return E_FAIL;
1473 HRESULT __RPC_STUB ITypeInfo_AddressOfMember_Stub(
1474 ITypeInfo* This)
1476 FIXME("not implemented\n");
1477 return E_FAIL;
1480 HRESULT CALLBACK ITypeInfo_CreateInstance_Proxy(
1481 ITypeInfo* This,
1482 IUnknown* pUnkOuter,
1483 REFIID riid,
1484 PVOID* ppvObj)
1486 FIXME("not implemented\n");
1487 return E_FAIL;
1490 HRESULT __RPC_STUB ITypeInfo_CreateInstance_Stub(
1491 ITypeInfo* This,
1492 REFIID riid,
1493 IUnknown** ppvObj)
1495 FIXME("not implemented\n");
1496 return E_FAIL;
1499 HRESULT CALLBACK ITypeInfo_GetContainingTypeLib_Proxy(
1500 ITypeInfo* This,
1501 ITypeLib** ppTLib,
1502 UINT* pIndex)
1504 ITypeLib *pTL;
1505 UINT index;
1506 HRESULT hr;
1508 TRACE("(%p, %p, %p)\n", This, ppTLib, pIndex );
1510 hr = ITypeInfo_RemoteGetContainingTypeLib_Proxy(This, &pTL, &index);
1511 if(SUCCEEDED(hr))
1513 if(pIndex)
1514 *pIndex = index;
1516 if(ppTLib)
1517 *ppTLib = pTL;
1518 else
1519 ITypeLib_Release(pTL);
1521 return hr;
1524 HRESULT __RPC_STUB ITypeInfo_GetContainingTypeLib_Stub(
1525 ITypeInfo* This,
1526 ITypeLib** ppTLib,
1527 UINT* pIndex)
1529 TRACE("(%p, %p, %p)\n", This, ppTLib, pIndex );
1530 return ITypeInfo_GetContainingTypeLib(This, ppTLib, pIndex);
1533 void CALLBACK ITypeInfo_ReleaseTypeAttr_Proxy(
1534 ITypeInfo* This,
1535 TYPEATTR* pTypeAttr)
1537 TRACE("(%p, %p)\n", This, pTypeAttr);
1538 free_embedded_typedesc(&pTypeAttr->tdescAlias);
1539 CoTaskMemFree(pTypeAttr);
1542 HRESULT __RPC_STUB ITypeInfo_ReleaseTypeAttr_Stub(
1543 ITypeInfo* This)
1545 TRACE("nothing to do\n");
1546 return S_OK;
1549 void CALLBACK ITypeInfo_ReleaseFuncDesc_Proxy(
1550 ITypeInfo* This,
1551 FUNCDESC* pFuncDesc)
1553 SHORT param;
1554 TRACE("(%p, %p)\n", This, pFuncDesc);
1556 for(param = 0; param < pFuncDesc->cParams; param++)
1557 free_embedded_elemdesc(pFuncDesc->lprgelemdescParam + param);
1558 if(param)
1559 CoTaskMemFree(pFuncDesc->lprgelemdescParam);
1561 free_embedded_elemdesc(&pFuncDesc->elemdescFunc);
1563 if(pFuncDesc->cScodes != 0 && pFuncDesc->cScodes != -1)
1564 CoTaskMemFree(pFuncDesc->lprgscode);
1566 CoTaskMemFree(pFuncDesc);
1569 HRESULT __RPC_STUB ITypeInfo_ReleaseFuncDesc_Stub(
1570 ITypeInfo* This)
1572 TRACE("nothing to do\n");
1573 return S_OK;
1576 void CALLBACK ITypeInfo_ReleaseVarDesc_Proxy(
1577 ITypeInfo* This,
1578 VARDESC* pVarDesc)
1580 FIXME("not implemented\n");
1583 HRESULT __RPC_STUB ITypeInfo_ReleaseVarDesc_Stub(
1584 ITypeInfo* This)
1586 FIXME("not implemented\n");
1587 return E_FAIL;
1591 /* ITypeInfo2 */
1593 HRESULT CALLBACK ITypeInfo2_GetDocumentation2_Proxy(
1594 ITypeInfo2* This,
1595 MEMBERID memid,
1596 LCID lcid,
1597 BSTR* pbstrHelpString,
1598 DWORD* pdwHelpStringContext,
1599 BSTR* pbstrHelpStringDll)
1601 FIXME("not implemented\n");
1602 return E_FAIL;
1605 HRESULT __RPC_STUB ITypeInfo2_GetDocumentation2_Stub(
1606 ITypeInfo2* This,
1607 MEMBERID memid,
1608 LCID lcid,
1609 DWORD refPtrFlags,
1610 BSTR* pbstrHelpString,
1611 DWORD* pdwHelpStringContext,
1612 BSTR* pbstrHelpStringDll)
1614 FIXME("not implemented\n");
1615 return E_FAIL;
1618 /* ITypeLib */
1620 UINT CALLBACK ITypeLib_GetTypeInfoCount_Proxy(
1621 ITypeLib* This)
1623 UINT count = 0;
1624 TRACE("(%p)\n", This);
1626 ITypeLib_RemoteGetTypeInfoCount_Proxy(This, &count);
1628 return count;
1631 HRESULT __RPC_STUB ITypeLib_GetTypeInfoCount_Stub(
1632 ITypeLib* This,
1633 UINT* pcTInfo)
1635 TRACE("(%p, %p)\n", This, pcTInfo);
1636 *pcTInfo = ITypeLib_GetTypeInfoCount(This);
1637 return S_OK;
1640 HRESULT CALLBACK ITypeLib_GetLibAttr_Proxy(
1641 ITypeLib* This,
1642 TLIBATTR** ppTLibAttr)
1644 CLEANLOCALSTORAGE stg;
1645 TRACE("(%p, %p)\n", This, ppTLibAttr);
1647 stg.flags = 0;
1648 stg.pStorage = NULL;
1649 stg.pInterface = NULL;
1651 return ITypeLib_RemoteGetLibAttr_Proxy(This, ppTLibAttr, &stg);
1654 HRESULT __RPC_STUB ITypeLib_GetLibAttr_Stub(
1655 ITypeLib* This,
1656 LPTLIBATTR* ppTLibAttr,
1657 CLEANLOCALSTORAGE* pDummy)
1659 HRESULT hr;
1660 TRACE("(%p, %p)\n", This, ppTLibAttr);
1662 hr = ITypeLib_GetLibAttr(This, ppTLibAttr);
1663 if(hr != S_OK)
1664 return hr;
1666 pDummy->flags = CLS_LIBATTR;
1667 ITypeLib_AddRef(This);
1668 pDummy->pInterface = (IUnknown*)This;
1669 pDummy->pStorage = ppTLibAttr;
1670 return hr;
1673 HRESULT CALLBACK ITypeLib_GetDocumentation_Proxy(
1674 ITypeLib* This,
1675 INT index,
1676 BSTR* pBstrName,
1677 BSTR* pBstrDocString,
1678 DWORD* pdwHelpContext,
1679 BSTR* pBstrHelpFile)
1681 FIXME("not implemented\n");
1682 return E_FAIL;
1685 HRESULT __RPC_STUB ITypeLib_GetDocumentation_Stub(
1686 ITypeLib* This,
1687 INT index,
1688 DWORD refPtrFlags,
1689 BSTR* pBstrName,
1690 BSTR* pBstrDocString,
1691 DWORD* pdwHelpContext,
1692 BSTR* pBstrHelpFile)
1694 FIXME("not implemented\n");
1695 return E_FAIL;
1698 HRESULT CALLBACK ITypeLib_IsName_Proxy(
1699 ITypeLib* This,
1700 LPOLESTR szNameBuf,
1701 ULONG lHashVal,
1702 BOOL* pfName)
1704 FIXME("not implemented\n");
1705 return E_FAIL;
1708 HRESULT __RPC_STUB ITypeLib_IsName_Stub(
1709 ITypeLib* This,
1710 LPOLESTR szNameBuf,
1711 ULONG lHashVal,
1712 BOOL* pfName,
1713 BSTR* pBstrLibName)
1715 FIXME("not implemented\n");
1716 return E_FAIL;
1719 HRESULT CALLBACK ITypeLib_FindName_Proxy(
1720 ITypeLib* This,
1721 LPOLESTR szNameBuf,
1722 ULONG lHashVal,
1723 ITypeInfo** ppTInfo,
1724 MEMBERID* rgMemId,
1725 USHORT* pcFound)
1727 FIXME("not implemented\n");
1728 return E_FAIL;
1731 HRESULT __RPC_STUB ITypeLib_FindName_Stub(
1732 ITypeLib* This,
1733 LPOLESTR szNameBuf,
1734 ULONG lHashVal,
1735 ITypeInfo** ppTInfo,
1736 MEMBERID* rgMemId,
1737 USHORT* pcFound,
1738 BSTR* pBstrLibName)
1740 FIXME("not implemented\n");
1741 return E_FAIL;
1744 void CALLBACK ITypeLib_ReleaseTLibAttr_Proxy(
1745 ITypeLib* This,
1746 TLIBATTR* pTLibAttr)
1748 TRACE("(%p, %p)\n", This, pTLibAttr);
1749 CoTaskMemFree(pTLibAttr);
1752 HRESULT __RPC_STUB ITypeLib_ReleaseTLibAttr_Stub(
1753 ITypeLib* This)
1755 TRACE("nothing to do\n");
1756 return S_OK;
1760 /* ITypeLib2 */
1762 HRESULT CALLBACK ITypeLib2_GetLibStatistics_Proxy(
1763 ITypeLib2* This,
1764 ULONG* pcUniqueNames,
1765 ULONG* pcchUniqueNames)
1767 FIXME("not implemented\n");
1768 return E_FAIL;
1771 HRESULT __RPC_STUB ITypeLib2_GetLibStatistics_Stub(
1772 ITypeLib2* This,
1773 ULONG* pcUniqueNames,
1774 ULONG* pcchUniqueNames)
1776 FIXME("not implemented\n");
1777 return E_FAIL;
1780 HRESULT CALLBACK ITypeLib2_GetDocumentation2_Proxy(
1781 ITypeLib2* This,
1782 INT index,
1783 LCID lcid,
1784 BSTR* pbstrHelpString,
1785 DWORD* pdwHelpStringContext,
1786 BSTR* pbstrHelpStringDll)
1788 FIXME("not implemented\n");
1789 return E_FAIL;
1792 HRESULT __RPC_STUB ITypeLib2_GetDocumentation2_Stub(
1793 ITypeLib2* This,
1794 INT index,
1795 LCID lcid,
1796 DWORD refPtrFlags,
1797 BSTR* pbstrHelpString,
1798 DWORD* pdwHelpStringContext,
1799 BSTR* pbstrHelpStringDll)
1801 FIXME("not implemented\n");
1802 return E_FAIL;