URLMonikerImpl_BindToStorage: Escape special characters.
[wine/multimedia.git] / dlls / oleaut32 / usrmarshal.c
blob8c5f1a889f8e1c51fcfd31a3cfbb0e86e5dce506
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 /* FIXME: not supposed to be here */
44 const CLSID CLSID_PSDispatch = {
45 0x20420, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46}
48 static CStdPSFactoryBuffer PSFactoryBuffer;
50 CSTDSTUBBUFFERRELEASE(&PSFactoryBuffer)
52 extern const ExtendedProxyFileInfo oaidl_ProxyFileInfo;
54 const ProxyFileInfo* OLEAUT32_ProxyFileList[] = {
55 &oaidl_ProxyFileInfo,
56 NULL
59 HRESULT OLEAUTPS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
61 return NdrDllGetClassObject(rclsid, riid, ppv, OLEAUT32_ProxyFileList,
62 &CLSID_PSDispatch, &PSFactoryBuffer);
65 /* CLEANLOCALSTORAGE */
66 /* I'm not sure how this is supposed to work yet */
68 unsigned long WINAPI CLEANLOCALSTORAGE_UserSize(unsigned long *pFlags, unsigned long Start, CLEANLOCALSTORAGE *pstg)
70 return Start + sizeof(DWORD);
73 unsigned char * WINAPI CLEANLOCALSTORAGE_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstg)
75 *(DWORD*)Buffer = 0;
76 return Buffer + sizeof(DWORD);
79 unsigned char * WINAPI CLEANLOCALSTORAGE_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstr)
81 return Buffer + sizeof(DWORD);
84 void WINAPI CLEANLOCALSTORAGE_UserFree(unsigned long *pFlags, CLEANLOCALSTORAGE *pstr)
88 /* BSTR */
90 unsigned long WINAPI BSTR_UserSize(unsigned long *pFlags, unsigned long Start, BSTR *pstr)
92 TRACE("(%lx,%ld,%p) => %p\n", *pFlags, Start, pstr, *pstr);
93 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
94 Start += sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (SysStringLen(*pstr) - 1);
95 TRACE("returning %ld\n", Start);
96 return Start;
99 unsigned char * WINAPI BSTR_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, BSTR *pstr)
101 wireBSTR str = (wireBSTR)Buffer;
103 TRACE("(%lx,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr);
104 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
105 str->fFlags = 0;
106 str->clSize = SysStringLen(*pstr);
107 if (str->clSize)
108 memcpy(&str->asData, *pstr, sizeof(OLECHAR) * str->clSize);
109 return Buffer + sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (str->clSize - 1);
112 unsigned char * WINAPI BSTR_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, BSTR *pstr)
114 wireBSTR str = (wireBSTR)Buffer;
115 TRACE("(%lx,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr);
116 if (str->clSize) {
117 SysReAllocStringLen(pstr, (OLECHAR*)&str->asData, str->clSize);
119 else if (*pstr) {
120 SysFreeString(*pstr);
121 *pstr = NULL;
123 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
124 return Buffer + sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (str->clSize - 1);
127 void WINAPI BSTR_UserFree(unsigned long *pFlags, BSTR *pstr)
129 TRACE("(%lx,%p) => %p\n", *pFlags, pstr, *pstr);
130 if (*pstr) {
131 SysFreeString(*pstr);
132 *pstr = NULL;
136 /* VARIANT */
137 /* I'm not too sure how to do this yet */
139 #define VARIANT_wiresize sizeof(struct _wireVARIANT)
141 static unsigned wire_size(VARTYPE vt)
143 if (vt & VT_ARRAY) return 0;
145 switch (vt & ~VT_BYREF) {
146 case VT_EMPTY:
147 case VT_NULL:
148 return 0;
149 case VT_I1:
150 case VT_UI1:
151 return sizeof(CHAR);
152 case VT_I2:
153 case VT_UI2:
154 return sizeof(SHORT);
155 case VT_I4:
156 case VT_UI4:
157 return sizeof(LONG);
158 case VT_INT:
159 case VT_UINT:
160 return sizeof(INT);
161 case VT_R4:
162 return sizeof(FLOAT);
163 case VT_R8:
164 return sizeof(DOUBLE);
165 case VT_BOOL:
166 return sizeof(VARIANT_BOOL);
167 case VT_ERROR:
168 return sizeof(SCODE);
169 case VT_DATE:
170 return sizeof(DATE);
171 case VT_CY:
172 return sizeof(CY);
173 case VT_DECIMAL:
174 return sizeof(DECIMAL);
175 case VT_BSTR:
176 case VT_VARIANT:
177 case VT_UNKNOWN:
178 case VT_DISPATCH:
179 case VT_SAFEARRAY:
180 case VT_RECORD:
181 return 0;
182 default:
183 FIXME("unhandled VT %d\n", vt);
184 return 0;
188 static unsigned wire_extra(unsigned long *pFlags, VARIANT *pvar)
190 ULONG size;
191 HRESULT hr;
193 if (V_ISARRAY(pvar)) {
194 FIXME("wire-size safearray\n");
195 return 0;
197 switch (V_VT(pvar)) {
198 case VT_BSTR:
199 return BSTR_UserSize(pFlags, 0, &V_BSTR(pvar));
200 case VT_BSTR | VT_BYREF:
201 return BSTR_UserSize(pFlags, 0, V_BSTRREF(pvar));
202 case VT_SAFEARRAY:
203 case VT_SAFEARRAY | VT_BYREF:
204 FIXME("wire-size safearray\n");
205 return 0;
206 case VT_VARIANT | VT_BYREF:
207 return VARIANT_UserSize(pFlags, 0, V_VARIANTREF(pvar));
208 case VT_UNKNOWN:
209 case VT_DISPATCH:
210 /* find the buffer size of the marshalled dispatch interface */
211 hr = CoGetMarshalSizeMax(&size, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
212 if (FAILED(hr)) {
213 if (!V_DISPATCH(pvar))
214 WARN("NULL dispatch pointer\n");
215 else
216 ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%lx\n", hr);
217 return 0;
219 size += sizeof(ULONG); /* we have to store the buffersize in the stream */
220 TRACE("wire-size extra of dispatch variant is %ld\n", size);
221 return size;
222 case VT_RECORD:
223 FIXME("wire-size record\n");
224 return 0;
225 default:
226 return 0;
230 /* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer. returns Buffer on failure, new position otherwise */
231 static unsigned char* dispatch_variant_marshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar) {
232 IStream *working;
233 HGLOBAL working_mem;
234 void *working_memlocked;
235 unsigned char *oldpos;
236 ULONG size;
237 HRESULT hr;
239 TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar);
241 oldpos = Buffer;
243 /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers.
244 * We create a stream on an HGLOBAL, so we can simply do a memcpy to move it to the buffer.
245 * in rpcrt4/ndr_ole.c, a simple IStream implementation is wrapped around the buffer object,
246 * but that would be overkill here, hence this implementation. We save the size because the unmarshal
247 * code has no way to know how long the marshalled buffer is. */
249 size = wire_extra(pFlags, pvar);
251 working_mem = GlobalAlloc(0, size);
252 if (!working_mem) return oldpos;
254 hr = CreateStreamOnHGlobal(working_mem, TRUE, &working);
255 if (hr != S_OK) {
256 GlobalFree(working_mem);
257 return oldpos;
260 hr = CoMarshalInterface(working, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
261 if (hr != S_OK) {
262 IStream_Release(working); /* this also releases the hglobal */
263 return oldpos;
266 working_memlocked = GlobalLock(working_mem);
267 memcpy(Buffer, &size, sizeof(ULONG)); /* copy the buffersize */
268 Buffer += sizeof(ULONG);
269 memcpy(Buffer, working_memlocked, size);
270 GlobalUnlock(working_mem);
272 IStream_Release(working);
274 TRACE("done, size=%ld\n", sizeof(ULONG) + size);
275 return Buffer + sizeof(ULONG) + size;
278 /* helper: called for VT_DISPATCH variants to unmarshal the buffer back into a dispatch variant. returns Buffer on failure, new position otherwise */
279 static unsigned char *dispatch_variant_unmarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar) {
280 IStream *working;
281 HGLOBAL working_mem;
282 void *working_memlocked;
283 unsigned char *oldpos;
284 ULONG size;
285 HRESULT hr;
287 TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar);
289 oldpos = Buffer;
291 /* get the buffersize */
292 memcpy(&size, Buffer, sizeof(ULONG));
293 TRACE("buffersize=%ld\n", size);
294 Buffer += sizeof(ULONG);
296 working_mem = GlobalAlloc(0, size);
297 if (!working_mem) return oldpos;
299 hr = CreateStreamOnHGlobal(working_mem, TRUE, &working);
300 if (hr != S_OK) {
301 GlobalFree(working_mem);
302 return oldpos;
305 working_memlocked = GlobalLock(working_mem);
307 /* now we copy the contents of the marshalling buffer to working_memlocked, unlock it, and demarshal the stream */
308 memcpy(working_memlocked, Buffer, size);
309 GlobalUnlock(working_mem);
311 hr = CoUnmarshalInterface(working, &IID_IDispatch, (void**)&V_DISPATCH(pvar));
312 if (hr != S_OK) {
313 IStream_Release(working);
314 return oldpos;
317 IStream_Release(working); /* this also frees the underlying hglobal */
319 TRACE("done, processed=%ld bytes\n", sizeof(ULONG) + size);
320 return Buffer + sizeof(ULONG) + size;
324 unsigned long WINAPI VARIANT_UserSize(unsigned long *pFlags, unsigned long Start, VARIANT *pvar)
326 TRACE("(%lx,%ld,%p)\n", *pFlags, Start, pvar);
327 TRACE("vt=%04x\n", V_VT(pvar));
328 Start += VARIANT_wiresize + wire_extra(pFlags, pvar);
329 TRACE("returning %ld\n", Start);
330 return Start;
333 unsigned char * WINAPI VARIANT_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar)
335 wireVARIANT var = (wireVARIANT)Buffer;
336 unsigned size, extra;
337 unsigned char *Pos = Buffer + VARIANT_wiresize;
339 TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar);
340 TRACE("vt=%04x\n", V_VT(pvar));
342 memset(var, 0, sizeof(*var));
343 var->clSize = sizeof(*var);
344 var->vt = pvar->n1.n2.vt;
346 var->rpcReserved = var->vt;
347 if ((var->vt & VT_ARRAY) ||
348 ((var->vt & VT_TYPEMASK) == VT_SAFEARRAY))
349 var->vt = VT_ARRAY | (var->vt & VT_BYREF);
351 if (var->vt == VT_DECIMAL) {
352 /* special case because decVal is on a different level */
353 var->u.decVal = pvar->n1.decVal;
354 return Pos;
357 size = wire_size(V_VT(pvar));
358 extra = wire_extra(pFlags, pvar);
359 var->wReserved1 = pvar->n1.n2.wReserved1;
360 var->wReserved2 = pvar->n1.n2.wReserved2;
361 var->wReserved3 = pvar->n1.n2.wReserved3;
362 if (size) {
363 if (var->vt & VT_BYREF)
364 memcpy(&var->u.cVal, pvar->n1.n2.n3.byref, size);
365 else
366 memcpy(&var->u.cVal, &pvar->n1.n2.n3, size);
368 if (!extra) return Pos;
370 switch (var->vt) {
371 case VT_BSTR:
372 Pos = BSTR_UserMarshal(pFlags, Pos, &V_BSTR(pvar));
373 break;
374 case VT_BSTR | VT_BYREF:
375 Pos = BSTR_UserMarshal(pFlags, Pos, V_BSTRREF(pvar));
376 break;
377 case VT_VARIANT | VT_BYREF:
378 Pos = VARIANT_UserMarshal(pFlags, Pos, V_VARIANTREF(pvar));
379 break;
380 case VT_DISPATCH | VT_BYREF:
381 FIXME("handle DISPATCH by ref\n");
382 break;
383 case VT_DISPATCH:
384 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
385 Pos = dispatch_variant_marshal(pFlags, Pos, pvar);
386 break;
387 case VT_RECORD:
388 FIXME("handle BRECORD by val\n");
389 break;
390 case VT_RECORD | VT_BYREF:
391 FIXME("handle BRECORD by ref\n");
392 break;
393 default:
394 FIXME("handle unknown complex type\n");
395 break;
397 var->clSize = Pos - Buffer;
398 TRACE("marshalled size=%ld\n", var->clSize);
399 return Pos;
402 unsigned char * WINAPI VARIANT_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar)
404 wireVARIANT var = (wireVARIANT)Buffer;
405 unsigned size;
406 unsigned char *Pos = Buffer + VARIANT_wiresize;
408 TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar);
409 VariantInit(pvar);
410 pvar->n1.n2.vt = var->rpcReserved;
411 TRACE("marshalled: clSize=%ld, vt=%04x\n", var->clSize, var->vt);
412 TRACE("vt=%04x\n", V_VT(pvar));
413 TRACE("reserved: %d, %d, %d\n", var->wReserved1, var->wReserved2, var->wReserved3);
414 TRACE("val: %ld\n", var->u.lVal);
416 if (var->vt == VT_DECIMAL) {
417 /* special case because decVal is on a different level */
418 pvar->n1.decVal = var->u.decVal;
419 return Pos;
422 size = wire_size(V_VT(pvar));
423 pvar->n1.n2.wReserved1 = var->wReserved1;
424 pvar->n1.n2.wReserved2 = var->wReserved2;
425 pvar->n1.n2.wReserved3 = var->wReserved3;
426 if (size) {
427 if (var->vt & VT_BYREF) {
428 pvar->n1.n2.n3.byref = CoTaskMemAlloc(size);
429 memcpy(pvar->n1.n2.n3.byref, &var->u.cVal, size);
431 else
432 memcpy(&pvar->n1.n2.n3, &var->u.cVal, size);
434 if (var->clSize <= VARIANT_wiresize) return Pos;
436 switch (var->vt) {
437 case VT_BSTR:
438 Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar));
439 break;
440 case VT_BSTR | VT_BYREF:
441 pvar->n1.n2.n3.byref = CoTaskMemAlloc(sizeof(BSTR));
442 *(BSTR*)pvar->n1.n2.n3.byref = NULL;
443 Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar));
444 break;
445 case VT_VARIANT | VT_BYREF:
446 pvar->n1.n2.n3.byref = CoTaskMemAlloc(sizeof(VARIANT));
447 Pos = VARIANT_UserUnmarshal(pFlags, Pos, V_VARIANTREF(pvar));
448 break;
449 case VT_RECORD:
450 FIXME("handle BRECORD by val\n");
451 break;
452 case VT_RECORD | VT_BYREF:
453 FIXME("handle BRECORD by ref\n");
454 break;
455 case VT_DISPATCH:
456 Pos = dispatch_variant_unmarshal(pFlags, Pos, pvar);
457 break;
458 case VT_DISPATCH | VT_BYREF:
459 FIXME("handle DISPATCH by ref\n");
460 default:
461 FIXME("handle unknown complex type\n");
462 break;
464 if (Pos != Buffer + var->clSize) {
465 ERR("size difference during unmarshal\n");
467 return Buffer + var->clSize;
470 void WINAPI VARIANT_UserFree(unsigned long *pFlags, VARIANT *pvar)
472 VARTYPE vt = V_VT(pvar);
473 PVOID ref = NULL;
475 TRACE("(%lx,%p)\n", *pFlags, pvar);
476 TRACE("vt=%04x\n", V_VT(pvar));
478 if (vt & VT_BYREF) ref = pvar->n1.n2.n3.byref;
480 VariantClear(pvar);
481 if (!ref) return;
483 switch (vt) {
484 case VT_BSTR | VT_BYREF:
485 BSTR_UserFree(pFlags, ref);
486 break;
487 case VT_VARIANT | VT_BYREF:
488 VARIANT_UserFree(pFlags, ref);
489 break;
490 case VT_RECORD | VT_BYREF:
491 FIXME("handle BRECORD by ref\n");
492 break;
493 default:
494 FIXME("handle unknown complex type\n");
495 break;
498 CoTaskMemFree(ref);
501 /* IDispatch */
502 /* exactly how Invoke is marshalled is not very clear to me yet,
503 * but the way I've done it seems to work for me */
505 HRESULT CALLBACK IDispatch_Invoke_Proxy(
506 IDispatch* This,
507 DISPID dispIdMember,
508 REFIID riid,
509 LCID lcid,
510 WORD wFlags,
511 DISPPARAMS* pDispParams,
512 VARIANT* pVarResult,
513 EXCEPINFO* pExcepInfo,
514 UINT* puArgErr)
516 HRESULT hr;
517 VARIANT VarResult;
518 UINT* rgVarRefIdx = NULL;
519 VARIANTARG* rgVarRef = NULL;
520 UINT u, cVarRef;
521 UINT uArgErr;
523 TRACE("(%p)->(%ld,%s,%lx,%x,%p,%p,%p,%p)\n", This,
524 dispIdMember, debugstr_guid(riid),
525 lcid, wFlags, pDispParams, pVarResult,
526 pExcepInfo, puArgErr);
528 /* [out] args can't be null, use dummy vars if needed */
529 if (!pVarResult) pVarResult = &VarResult;
530 if (!puArgErr) puArgErr = &uArgErr;
532 /* count by-ref args */
533 for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
534 VARIANTARG* arg = &pDispParams->rgvarg[u];
535 if (V_ISBYREF(arg)) {
536 cVarRef++;
539 if (cVarRef) {
540 rgVarRefIdx = CoTaskMemAlloc(sizeof(UINT)*cVarRef);
541 rgVarRef = CoTaskMemAlloc(sizeof(VARIANTARG)*cVarRef);
542 /* make list of by-ref args */
543 for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
544 VARIANTARG* arg = &pDispParams->rgvarg[u];
545 if (V_ISBYREF(arg)) {
546 rgVarRefIdx[cVarRef] = u;
547 VariantInit(&rgVarRef[cVarRef]);
548 cVarRef++;
551 } else {
552 /* [out] args still can't be null,
553 * but we can point these anywhere in this case,
554 * since they won't be written to when cVarRef is 0 */
555 rgVarRefIdx = puArgErr;
556 rgVarRef = pVarResult;
558 TRACE("passed by ref: %d args\n", cVarRef);
559 hr = IDispatch_RemoteInvoke_Proxy(This,
560 dispIdMember,
561 riid,
562 lcid,
563 wFlags,
564 pDispParams,
565 pVarResult,
566 pExcepInfo,
567 puArgErr,
568 cVarRef,
569 rgVarRefIdx,
570 rgVarRef);
571 if (cVarRef) {
572 for (u=0; u<cVarRef; u++) {
573 unsigned i = rgVarRefIdx[u];
574 VariantCopy(&pDispParams->rgvarg[i],
575 &rgVarRef[u]);
576 VariantClear(&rgVarRef[u]);
578 CoTaskMemFree(rgVarRef);
579 CoTaskMemFree(rgVarRefIdx);
581 return hr;
584 HRESULT __RPC_STUB IDispatch_Invoke_Stub(
585 IDispatch* This,
586 DISPID dispIdMember,
587 REFIID riid,
588 LCID lcid,
589 DWORD dwFlags,
590 DISPPARAMS* pDispParams,
591 VARIANT* pVarResult,
592 EXCEPINFO* pExcepInfo,
593 UINT* pArgErr,
594 UINT cVarRef,
595 UINT* rgVarRefIdx,
596 VARIANTARG* rgVarRef)
598 HRESULT hr = S_OK;
599 VARIANTARG *rgvarg, *arg;
600 UINT u;
602 /* initialize out parameters, so that they can be marshalled
603 * in case the real Invoke doesn't initialize them */
604 VariantInit(pVarResult);
605 memset(pExcepInfo, 0, sizeof(*pExcepInfo));
606 *pArgErr = 0;
608 /* let the real Invoke operate on a copy of the in parameters,
609 * so we don't risk losing pointers to allocated memory */
610 rgvarg = pDispParams->rgvarg;
611 arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs);
612 if (!arg) return E_OUTOFMEMORY;
614 /* init all args so we can call VariantClear on all the args if the copy
615 * below fails */
616 for (u = 0; u < pDispParams->cArgs; u++)
617 VariantInit(&arg[u]);
619 for (u = 0; u < pDispParams->cArgs; u++) {
620 hr = VariantCopy(&arg[u], &rgvarg[u]);
621 if (FAILED(hr))
622 break;
625 if (SUCCEEDED(hr)) {
626 pDispParams->rgvarg = arg;
628 hr = IDispatch_Invoke(This,
629 dispIdMember,
630 riid,
631 lcid,
632 dwFlags,
633 pDispParams,
634 pVarResult,
635 pExcepInfo,
636 pArgErr);
638 /* copy ref args to out list */
639 for (u=0; u<cVarRef; u++) {
640 unsigned i = rgVarRefIdx[u];
641 VariantInit(&rgVarRef[u]);
642 VariantCopy(&rgVarRef[u], &arg[i]);
643 /* clear original if equal, to avoid double-free */
644 if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
645 VariantClear(&rgvarg[i]);
649 /* clear the duplicate argument list */
650 for (u=0; u<pDispParams->cArgs; u++)
651 VariantClear(&arg[u]);
653 pDispParams->rgvarg = rgvarg;
654 CoTaskMemFree(arg);
656 return hr;
659 /* IEnumVARIANT */
661 HRESULT CALLBACK IEnumVARIANT_Next_Proxy(
662 IEnumVARIANT* This,
663 ULONG celt,
664 VARIANT* rgVar,
665 ULONG* pCeltFetched)
667 ULONG fetched;
668 if (!pCeltFetched)
669 pCeltFetched = &fetched;
670 return IEnumVARIANT_RemoteNext_Proxy(This,
671 celt,
672 rgVar,
673 pCeltFetched);
676 HRESULT __RPC_STUB IEnumVARIANT_Next_Stub(
677 IEnumVARIANT* This,
678 ULONG celt,
679 VARIANT* rgVar,
680 ULONG* pCeltFetched)
682 HRESULT hr;
683 *pCeltFetched = 0;
684 hr = IEnumVARIANT_Next(This,
685 celt,
686 rgVar,
687 pCeltFetched);
688 if (hr == S_OK) *pCeltFetched = celt;
689 return hr;
692 /* ITypeComp */
694 HRESULT CALLBACK ITypeComp_Bind_Proxy(
695 ITypeComp* This,
696 LPOLESTR szName,
697 ULONG lHashVal,
698 WORD wFlags,
699 ITypeInfo** ppTInfo,
700 DESCKIND* pDescKind,
701 BINDPTR* pBindPtr)
703 FIXME("not implemented\n");
704 return E_FAIL;
707 HRESULT __RPC_STUB ITypeComp_Bind_Stub(
708 ITypeComp* This,
709 LPOLESTR szName,
710 ULONG lHashVal,
711 WORD wFlags,
712 ITypeInfo** ppTInfo,
713 DESCKIND* pDescKind,
714 LPFUNCDESC* ppFuncDesc,
715 LPVARDESC* ppVarDesc,
716 ITypeComp** ppTypeComp,
717 CLEANLOCALSTORAGE* pDummy)
719 FIXME("not implemented\n");
720 return E_FAIL;
723 HRESULT CALLBACK ITypeComp_BindType_Proxy(
724 ITypeComp* This,
725 LPOLESTR szName,
726 ULONG lHashVal,
727 ITypeInfo** ppTInfo,
728 ITypeComp** ppTComp)
730 FIXME("not implemented\n");
731 return E_FAIL;
734 HRESULT __RPC_STUB ITypeComp_BindType_Stub(
735 ITypeComp* This,
736 LPOLESTR szName,
737 ULONG lHashVal,
738 ITypeInfo** ppTInfo)
740 FIXME("not implemented\n");
741 return E_FAIL;
744 /* ITypeInfo */
746 HRESULT CALLBACK ITypeInfo_GetTypeAttr_Proxy(
747 ITypeInfo* This,
748 TYPEATTR** ppTypeAttr)
750 FIXME("not implemented\n");
751 return E_FAIL;
754 HRESULT __RPC_STUB ITypeInfo_GetTypeAttr_Stub(
755 ITypeInfo* This,
756 LPTYPEATTR* ppTypeAttr,
757 CLEANLOCALSTORAGE* pDummy)
759 FIXME("not implemented\n");
760 return E_FAIL;
763 HRESULT CALLBACK ITypeInfo_GetFuncDesc_Proxy(
764 ITypeInfo* This,
765 UINT index,
766 FUNCDESC** ppFuncDesc)
768 FIXME("not implemented\n");
769 return E_FAIL;
772 HRESULT __RPC_STUB ITypeInfo_GetFuncDesc_Stub(
773 ITypeInfo* This,
774 UINT index,
775 LPFUNCDESC* ppFuncDesc,
776 CLEANLOCALSTORAGE* pDummy)
778 FIXME("not implemented\n");
779 return E_FAIL;
782 HRESULT CALLBACK ITypeInfo_GetVarDesc_Proxy(
783 ITypeInfo* This,
784 UINT index,
785 VARDESC** ppVarDesc)
787 FIXME("not implemented\n");
788 return E_FAIL;
791 HRESULT __RPC_STUB ITypeInfo_GetVarDesc_Stub(
792 ITypeInfo* This,
793 UINT index,
794 LPVARDESC* ppVarDesc,
795 CLEANLOCALSTORAGE* pDummy)
797 FIXME("not implemented\n");
798 return E_FAIL;
801 HRESULT CALLBACK ITypeInfo_GetNames_Proxy(
802 ITypeInfo* This,
803 MEMBERID memid,
804 BSTR* rgBstrNames,
805 UINT cMaxNames,
806 UINT* pcNames)
808 FIXME("not implemented\n");
809 return E_FAIL;
812 HRESULT __RPC_STUB ITypeInfo_GetNames_Stub(
813 ITypeInfo* This,
814 MEMBERID memid,
815 BSTR* rgBstrNames,
816 UINT cMaxNames,
817 UINT* pcNames)
819 FIXME("not implemented\n");
820 return E_FAIL;
823 HRESULT CALLBACK ITypeInfo_GetIDsOfNames_Proxy(
824 ITypeInfo* This,
825 LPOLESTR* rgszNames,
826 UINT cNames,
827 MEMBERID* pMemId)
829 FIXME("not implemented\n");
830 return E_FAIL;
833 HRESULT __RPC_STUB ITypeInfo_GetIDsOfNames_Stub(
834 ITypeInfo* This)
836 FIXME("not implemented\n");
837 return E_FAIL;
840 HRESULT CALLBACK ITypeInfo_Invoke_Proxy(
841 ITypeInfo* This,
842 PVOID pvInstance,
843 MEMBERID memid,
844 WORD wFlags,
845 DISPPARAMS* pDispParams,
846 VARIANT* pVarResult,
847 EXCEPINFO* pExcepInfo,
848 UINT* puArgErr)
850 FIXME("not implemented\n");
851 return E_FAIL;
854 HRESULT __RPC_STUB ITypeInfo_Invoke_Stub(
855 ITypeInfo* This)
857 FIXME("not implemented\n");
858 return E_FAIL;
861 HRESULT CALLBACK ITypeInfo_GetDocumentation_Proxy(
862 ITypeInfo* This,
863 MEMBERID memid,
864 BSTR* pBstrName,
865 BSTR* pBstrDocString,
866 DWORD* pdwHelpContext,
867 BSTR* pBstrHelpFile)
869 FIXME("not implemented\n");
870 return E_FAIL;
873 HRESULT __RPC_STUB ITypeInfo_GetDocumentation_Stub(
874 ITypeInfo* This,
875 MEMBERID memid,
876 DWORD refPtrFlags,
877 BSTR* pBstrName,
878 BSTR* pBstrDocString,
879 DWORD* pdwHelpContext,
880 BSTR* pBstrHelpFile)
882 FIXME("not implemented\n");
883 return E_FAIL;
886 HRESULT CALLBACK ITypeInfo_GetDllEntry_Proxy(
887 ITypeInfo* This,
888 MEMBERID memid,
889 INVOKEKIND invKind,
890 BSTR* pBstrDllName,
891 BSTR* pBstrName,
892 WORD* pwOrdinal)
894 FIXME("not implemented\n");
895 return E_FAIL;
898 HRESULT __RPC_STUB ITypeInfo_GetDllEntry_Stub(
899 ITypeInfo* This,
900 MEMBERID memid,
901 INVOKEKIND invKind,
902 DWORD refPtrFlags,
903 BSTR* pBstrDllName,
904 BSTR* pBstrName,
905 WORD* pwOrdinal)
907 FIXME("not implemented\n");
908 return E_FAIL;
911 HRESULT CALLBACK ITypeInfo_AddressOfMember_Proxy(
912 ITypeInfo* This,
913 MEMBERID memid,
914 INVOKEKIND invKind,
915 PVOID* ppv)
917 FIXME("not implemented\n");
918 return E_FAIL;
921 HRESULT __RPC_STUB ITypeInfo_AddressOfMember_Stub(
922 ITypeInfo* This)
924 FIXME("not implemented\n");
925 return E_FAIL;
928 HRESULT CALLBACK ITypeInfo_CreateInstance_Proxy(
929 ITypeInfo* This,
930 IUnknown* pUnkOuter,
931 REFIID riid,
932 PVOID* ppvObj)
934 FIXME("not implemented\n");
935 return E_FAIL;
938 HRESULT __RPC_STUB ITypeInfo_CreateInstance_Stub(
939 ITypeInfo* This,
940 REFIID riid,
941 IUnknown** ppvObj)
943 FIXME("not implemented\n");
944 return E_FAIL;
947 HRESULT CALLBACK ITypeInfo_GetContainingTypeLib_Proxy(
948 ITypeInfo* This,
949 ITypeLib** ppTLib,
950 UINT* pIndex)
952 FIXME("not implemented\n");
953 return E_FAIL;
956 HRESULT __RPC_STUB ITypeInfo_GetContainingTypeLib_Stub(
957 ITypeInfo* This,
958 ITypeLib** ppTLib,
959 UINT* pIndex)
961 FIXME("not implemented\n");
962 return E_FAIL;
965 void CALLBACK ITypeInfo_ReleaseTypeAttr_Proxy(
966 ITypeInfo* This,
967 TYPEATTR* pTypeAttr)
969 FIXME("not implemented\n");
972 HRESULT __RPC_STUB ITypeInfo_ReleaseTypeAttr_Stub(
973 ITypeInfo* This)
975 FIXME("not implemented\n");
976 return E_FAIL;
979 void CALLBACK ITypeInfo_ReleaseFuncDesc_Proxy(
980 ITypeInfo* This,
981 FUNCDESC* pFuncDesc)
983 FIXME("not implemented\n");
986 HRESULT __RPC_STUB ITypeInfo_ReleaseFuncDesc_Stub(
987 ITypeInfo* This)
989 FIXME("not implemented\n");
990 return E_FAIL;
993 void CALLBACK ITypeInfo_ReleaseVarDesc_Proxy(
994 ITypeInfo* This,
995 VARDESC* pVarDesc)
997 FIXME("not implemented\n");
1000 HRESULT __RPC_STUB ITypeInfo_ReleaseVarDesc_Stub(
1001 ITypeInfo* This)
1003 FIXME("not implemented\n");
1004 return E_FAIL;
1008 /* ITypeInfo2 */
1010 HRESULT CALLBACK ITypeInfo2_GetDocumentation2_Proxy(
1011 ITypeInfo2* This,
1012 MEMBERID memid,
1013 LCID lcid,
1014 BSTR* pbstrHelpString,
1015 DWORD* pdwHelpStringContext,
1016 BSTR* pbstrHelpStringDll)
1018 FIXME("not implemented\n");
1019 return E_FAIL;
1022 HRESULT __RPC_STUB ITypeInfo2_GetDocumentation2_Stub(
1023 ITypeInfo2* This,
1024 MEMBERID memid,
1025 LCID lcid,
1026 DWORD refPtrFlags,
1027 BSTR* pbstrHelpString,
1028 DWORD* pdwHelpStringContext,
1029 BSTR* pbstrHelpStringDll)
1031 FIXME("not implemented\n");
1032 return E_FAIL;
1035 /* ITypeLib */
1037 UINT CALLBACK ITypeLib_GetTypeInfoCount_Proxy(
1038 ITypeLib* This)
1040 FIXME("not implemented\n");
1041 return E_FAIL;
1044 HRESULT __RPC_STUB ITypeLib_GetTypeInfoCount_Stub(
1045 ITypeLib* This,
1046 UINT* pcTInfo)
1048 FIXME("not implemented\n");
1049 return E_FAIL;
1052 HRESULT CALLBACK ITypeLib_GetLibAttr_Proxy(
1053 ITypeLib* This,
1054 TLIBATTR** ppTLibAttr)
1056 FIXME("not implemented\n");
1057 return E_FAIL;
1060 HRESULT __RPC_STUB ITypeLib_GetLibAttr_Stub(
1061 ITypeLib* This,
1062 LPTLIBATTR* ppTLibAttr,
1063 CLEANLOCALSTORAGE* pDummy)
1065 FIXME("not implemented\n");
1066 return E_FAIL;
1069 HRESULT CALLBACK ITypeLib_GetDocumentation_Proxy(
1070 ITypeLib* This,
1071 INT index,
1072 BSTR* pBstrName,
1073 BSTR* pBstrDocString,
1074 DWORD* pdwHelpContext,
1075 BSTR* pBstrHelpFile)
1077 FIXME("not implemented\n");
1078 return E_FAIL;
1081 HRESULT __RPC_STUB ITypeLib_GetDocumentation_Stub(
1082 ITypeLib* This,
1083 INT index,
1084 DWORD refPtrFlags,
1085 BSTR* pBstrName,
1086 BSTR* pBstrDocString,
1087 DWORD* pdwHelpContext,
1088 BSTR* pBstrHelpFile)
1090 FIXME("not implemented\n");
1091 return E_FAIL;
1094 HRESULT CALLBACK ITypeLib_IsName_Proxy(
1095 ITypeLib* This,
1096 LPOLESTR szNameBuf,
1097 ULONG lHashVal,
1098 BOOL* pfName)
1100 FIXME("not implemented\n");
1101 return E_FAIL;
1104 HRESULT __RPC_STUB ITypeLib_IsName_Stub(
1105 ITypeLib* This,
1106 LPOLESTR szNameBuf,
1107 ULONG lHashVal,
1108 BOOL* pfName,
1109 BSTR* pBstrLibName)
1111 FIXME("not implemented\n");
1112 return E_FAIL;
1115 HRESULT CALLBACK ITypeLib_FindName_Proxy(
1116 ITypeLib* This,
1117 LPOLESTR szNameBuf,
1118 ULONG lHashVal,
1119 ITypeInfo** ppTInfo,
1120 MEMBERID* rgMemId,
1121 USHORT* pcFound)
1123 FIXME("not implemented\n");
1124 return E_FAIL;
1127 HRESULT __RPC_STUB ITypeLib_FindName_Stub(
1128 ITypeLib* This,
1129 LPOLESTR szNameBuf,
1130 ULONG lHashVal,
1131 ITypeInfo** ppTInfo,
1132 MEMBERID* rgMemId,
1133 USHORT* pcFound,
1134 BSTR* pBstrLibName)
1136 FIXME("not implemented\n");
1137 return E_FAIL;
1140 void CALLBACK ITypeLib_ReleaseTLibAttr_Proxy(
1141 ITypeLib* This,
1142 TLIBATTR* pTLibAttr)
1144 FIXME("not implemented\n");
1147 HRESULT __RPC_STUB ITypeLib_ReleaseTLibAttr_Stub(
1148 ITypeLib* This)
1150 FIXME("not implemented\n");
1151 return E_FAIL;
1155 /* ITypeLib2 */
1157 HRESULT CALLBACK ITypeLib2_GetLibStatistics_Proxy(
1158 ITypeLib2* This,
1159 ULONG* pcUniqueNames,
1160 ULONG* pcchUniqueNames)
1162 FIXME("not implemented\n");
1163 return E_FAIL;
1166 HRESULT __RPC_STUB ITypeLib2_GetLibStatistics_Stub(
1167 ITypeLib2* This,
1168 ULONG* pcUniqueNames,
1169 ULONG* pcchUniqueNames)
1171 FIXME("not implemented\n");
1172 return E_FAIL;
1175 HRESULT CALLBACK ITypeLib2_GetDocumentation2_Proxy(
1176 ITypeLib2* This,
1177 INT index,
1178 LCID lcid,
1179 BSTR* pbstrHelpString,
1180 DWORD* pdwHelpStringContext,
1181 BSTR* pbstrHelpStringDll)
1183 FIXME("not implemented\n");
1184 return E_FAIL;
1187 HRESULT __RPC_STUB ITypeLib2_GetDocumentation2_Stub(
1188 ITypeLib2* This,
1189 INT index,
1190 LCID lcid,
1191 DWORD refPtrFlags,
1192 BSTR* pbstrHelpString,
1193 DWORD* pdwHelpStringContext,
1194 BSTR* pbstrHelpStringDll)
1196 FIXME("not implemented\n");
1197 return E_FAIL;