ntdll: Get rid of the main_file argument in LdrInitializeThunk.
[wine/multimedia.git] / dlls / oleaut32 / usrmarshal.c
blob242c3b1960a199fcb268aadedeff8d3435bc8841
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 static void dump_user_flags(unsigned long *pFlags)
67 if (HIWORD(*pFlags) == NDR_LOCAL_DATA_REPRESENTATION)
68 TRACE("MAKELONG(NDR_LOCAL_REPRESENTATION, ");
69 else
70 TRACE("MAKELONG(0x%04x, ", HIWORD(*pFlags));
71 switch (LOWORD(*pFlags))
73 case MSHCTX_LOCAL: TRACE("MSHCTX_LOCAL)"); break;
74 case MSHCTX_NOSHAREDMEM: TRACE("MSHCTX_NOSHAREDMEM)"); break;
75 case MSHCTX_DIFFERENTMACHINE: TRACE("MSHCTX_DIFFERENTMACHINE)"); break;
76 case MSHCTX_INPROC: TRACE("MSHCTX_INPROC)"); break;
77 default: TRACE("%d)", LOWORD(*pFlags));
81 /* CLEANLOCALSTORAGE */
82 /* I'm not sure how this is supposed to work yet */
84 unsigned long WINAPI CLEANLOCALSTORAGE_UserSize(unsigned long *pFlags, unsigned long Start, CLEANLOCALSTORAGE *pstg)
86 return Start + sizeof(DWORD);
89 unsigned char * WINAPI CLEANLOCALSTORAGE_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstg)
91 *(DWORD*)Buffer = 0;
92 return Buffer + sizeof(DWORD);
95 unsigned char * WINAPI CLEANLOCALSTORAGE_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstr)
97 return Buffer + sizeof(DWORD);
100 void WINAPI CLEANLOCALSTORAGE_UserFree(unsigned long *pFlags, CLEANLOCALSTORAGE *pstr)
104 /* BSTR */
106 unsigned long WINAPI BSTR_UserSize(unsigned long *pFlags, unsigned long Start, BSTR *pstr)
108 TRACE("(%lx,%ld,%p) => %p\n", *pFlags, Start, pstr, *pstr);
109 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
110 Start += sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (SysStringLen(*pstr) - 1);
111 TRACE("returning %ld\n", Start);
112 return Start;
115 unsigned char * WINAPI BSTR_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, BSTR *pstr)
117 wireBSTR str = (wireBSTR)Buffer;
119 TRACE("(%lx,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr);
120 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
121 str->fFlags = 0;
122 str->clSize = SysStringLen(*pstr);
123 if (str->clSize)
124 memcpy(&str->asData, *pstr, sizeof(OLECHAR) * str->clSize);
125 return Buffer + sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (str->clSize - 1);
128 unsigned char * WINAPI BSTR_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, BSTR *pstr)
130 wireBSTR str = (wireBSTR)Buffer;
131 TRACE("(%lx,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr);
132 if (str->clSize) {
133 SysReAllocStringLen(pstr, (OLECHAR*)&str->asData, str->clSize);
135 else if (*pstr) {
136 SysFreeString(*pstr);
137 *pstr = NULL;
139 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr));
140 return Buffer + sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (str->clSize - 1);
143 void WINAPI BSTR_UserFree(unsigned long *pFlags, BSTR *pstr)
145 TRACE("(%lx,%p) => %p\n", *pFlags, pstr, *pstr);
146 if (*pstr) {
147 SysFreeString(*pstr);
148 *pstr = NULL;
152 /* VARIANT */
153 /* I'm not too sure how to do this yet */
155 #define VARIANT_wiresize sizeof(struct _wireVARIANT)
157 static unsigned wire_size(VARTYPE vt)
159 if (vt & VT_ARRAY) return 0;
161 switch (vt & ~VT_BYREF) {
162 case VT_EMPTY:
163 case VT_NULL:
164 return 0;
165 case VT_I1:
166 case VT_UI1:
167 return sizeof(CHAR);
168 case VT_I2:
169 case VT_UI2:
170 return sizeof(SHORT);
171 case VT_I4:
172 case VT_UI4:
173 return sizeof(LONG);
174 case VT_INT:
175 case VT_UINT:
176 return sizeof(INT);
177 case VT_R4:
178 return sizeof(FLOAT);
179 case VT_R8:
180 return sizeof(DOUBLE);
181 case VT_BOOL:
182 return sizeof(VARIANT_BOOL);
183 case VT_ERROR:
184 return sizeof(SCODE);
185 case VT_DATE:
186 return sizeof(DATE);
187 case VT_CY:
188 return sizeof(CY);
189 case VT_DECIMAL:
190 return sizeof(DECIMAL);
191 case VT_BSTR:
192 case VT_VARIANT:
193 case VT_UNKNOWN:
194 case VT_DISPATCH:
195 case VT_SAFEARRAY:
196 case VT_RECORD:
197 return 0;
198 default:
199 FIXME("unhandled VT %d\n", vt);
200 return 0;
204 static unsigned interface_variant_size(unsigned long *pFlags, REFIID riid, VARIANT *pvar)
206 ULONG size;
207 HRESULT hr;
208 /* find the buffer size of the marshalled dispatch interface */
209 hr = CoGetMarshalSizeMax(&size, riid, V_UNKNOWN(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
210 if (FAILED(hr)) {
211 if (!V_DISPATCH(pvar))
212 WARN("NULL dispatch pointer\n");
213 else
214 ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%lx\n", hr);
215 return 0;
217 size += sizeof(ULONG); /* we have to store the buffersize in the stream */
218 TRACE("wire-size extra of dispatch variant is %ld\n", size);
219 return size;
222 static unsigned wire_extra(unsigned long *pFlags, VARIANT *pvar)
224 if (V_ISARRAY(pvar)) {
225 FIXME("wire-size safearray\n");
226 return 0;
228 switch (V_VT(pvar)) {
229 case VT_BSTR:
230 return BSTR_UserSize(pFlags, 0, &V_BSTR(pvar));
231 case VT_BSTR | VT_BYREF:
232 return BSTR_UserSize(pFlags, 0, V_BSTRREF(pvar));
233 case VT_SAFEARRAY:
234 case VT_SAFEARRAY | VT_BYREF:
235 FIXME("wire-size safearray\n");
236 return 0;
237 case VT_VARIANT | VT_BYREF:
238 return VARIANT_UserSize(pFlags, 0, V_VARIANTREF(pvar));
239 case VT_UNKNOWN:
240 return interface_variant_size(pFlags, &IID_IUnknown, pvar);
241 case VT_DISPATCH:
242 return interface_variant_size(pFlags, &IID_IDispatch, pvar);
243 case VT_RECORD:
244 FIXME("wire-size record\n");
245 return 0;
246 default:
247 return 0;
251 /* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer. returns Buffer on failure, new position otherwise */
252 static unsigned char* interface_variant_marshal(unsigned long *pFlags, unsigned char *Buffer, REFIID riid, VARIANT *pvar)
254 IStream *working;
255 HGLOBAL working_mem;
256 void *working_memlocked;
257 unsigned char *oldpos;
258 ULONG size;
259 HRESULT hr;
261 TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar);
263 oldpos = Buffer;
265 /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers.
266 * We create a stream on an HGLOBAL, so we can simply do a memcpy to move it to the buffer.
267 * in rpcrt4/ndr_ole.c, a simple IStream implementation is wrapped around the buffer object,
268 * but that would be overkill here, hence this implementation. We save the size because the unmarshal
269 * code has no way to know how long the marshalled buffer is. */
271 size = wire_extra(pFlags, pvar);
273 working_mem = GlobalAlloc(0, size);
274 if (!working_mem) return oldpos;
276 hr = CreateStreamOnHGlobal(working_mem, TRUE, &working);
277 if (hr != S_OK) {
278 GlobalFree(working_mem);
279 return oldpos;
282 hr = CoMarshalInterface(working, riid, V_UNKNOWN(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
283 if (hr != S_OK) {
284 IStream_Release(working); /* this also releases the hglobal */
285 return oldpos;
288 working_memlocked = GlobalLock(working_mem);
289 memcpy(Buffer, &size, sizeof(ULONG)); /* copy the buffersize */
290 Buffer += sizeof(ULONG);
291 memcpy(Buffer, working_memlocked, size);
292 GlobalUnlock(working_mem);
294 IStream_Release(working);
296 TRACE("done, size=%ld\n", sizeof(ULONG) + size);
297 return Buffer + sizeof(ULONG) + size;
300 /* helper: called for VT_DISPATCH / VT_UNKNOWN variants to unmarshal the buffer. returns Buffer on failure, new position otherwise */
301 static unsigned char *interface_variant_unmarshal(unsigned long *pFlags, unsigned char *Buffer, REFIID riid, VARIANT *pvar)
303 IStream *working;
304 HGLOBAL working_mem;
305 void *working_memlocked;
306 unsigned char *oldpos;
307 ULONG size;
308 HRESULT hr;
310 TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar);
312 oldpos = Buffer;
314 /* get the buffersize */
315 memcpy(&size, Buffer, sizeof(ULONG));
316 TRACE("buffersize=%ld\n", size);
317 Buffer += sizeof(ULONG);
319 working_mem = GlobalAlloc(0, size);
320 if (!working_mem) return oldpos;
322 hr = CreateStreamOnHGlobal(working_mem, TRUE, &working);
323 if (hr != S_OK) {
324 GlobalFree(working_mem);
325 return oldpos;
328 working_memlocked = GlobalLock(working_mem);
330 /* now we copy the contents of the marshalling buffer to working_memlocked, unlock it, and demarshal the stream */
331 memcpy(working_memlocked, Buffer, size);
332 GlobalUnlock(working_mem);
334 hr = CoUnmarshalInterface(working, riid, (void**)&V_UNKNOWN(pvar));
335 if (hr != S_OK) {
336 IStream_Release(working);
337 return oldpos;
340 IStream_Release(working); /* this also frees the underlying hglobal */
342 TRACE("done, processed=%ld bytes\n", sizeof(ULONG) + size);
343 return Buffer + sizeof(ULONG) + size;
347 unsigned long WINAPI VARIANT_UserSize(unsigned long *pFlags, unsigned long Start, VARIANT *pvar)
349 TRACE("(%lx,%ld,%p)\n", *pFlags, Start, pvar);
350 TRACE("vt=%04x\n", V_VT(pvar));
351 Start += VARIANT_wiresize + wire_extra(pFlags, pvar);
352 TRACE("returning %ld\n", Start);
353 return Start;
356 unsigned char * WINAPI VARIANT_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar)
358 wireVARIANT var = (wireVARIANT)Buffer;
359 unsigned size, extra;
360 unsigned char *Pos = Buffer + VARIANT_wiresize;
362 TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar);
363 TRACE("vt=%04x\n", V_VT(pvar));
365 memset(var, 0, sizeof(*var));
366 var->clSize = sizeof(*var);
367 var->vt = pvar->n1.n2.vt;
369 var->rpcReserved = var->vt;
370 if ((var->vt & VT_ARRAY) ||
371 ((var->vt & VT_TYPEMASK) == VT_SAFEARRAY))
372 var->vt = VT_ARRAY | (var->vt & VT_BYREF);
374 if (var->vt == VT_DECIMAL) {
375 /* special case because decVal is on a different level */
376 var->u.decVal = pvar->n1.decVal;
377 return Pos;
380 size = wire_size(V_VT(pvar));
381 extra = wire_extra(pFlags, pvar);
382 var->wReserved1 = pvar->n1.n2.wReserved1;
383 var->wReserved2 = pvar->n1.n2.wReserved2;
384 var->wReserved3 = pvar->n1.n2.wReserved3;
385 if (size) {
386 if (var->vt & VT_BYREF)
387 memcpy(&var->u.cVal, pvar->n1.n2.n3.byref, size);
388 else
389 memcpy(&var->u.cVal, &pvar->n1.n2.n3, size);
391 if (!extra) return Pos;
393 switch (var->vt) {
394 case VT_BSTR:
395 Pos = BSTR_UserMarshal(pFlags, Pos, &V_BSTR(pvar));
396 break;
397 case VT_BSTR | VT_BYREF:
398 Pos = BSTR_UserMarshal(pFlags, Pos, V_BSTRREF(pvar));
399 break;
400 case VT_VARIANT | VT_BYREF:
401 Pos = VARIANT_UserMarshal(pFlags, Pos, V_VARIANTREF(pvar));
402 break;
403 case VT_DISPATCH | VT_BYREF:
404 FIXME("handle DISPATCH by ref\n");
405 break;
406 case VT_UNKNOWN:
407 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
408 Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, pvar);
409 break;
410 case VT_DISPATCH:
411 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
412 Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, pvar);
413 break;
414 case VT_RECORD:
415 FIXME("handle BRECORD by val\n");
416 break;
417 case VT_RECORD | VT_BYREF:
418 FIXME("handle BRECORD by ref\n");
419 break;
420 default:
421 FIXME("handle unknown complex type\n");
422 break;
424 var->clSize = Pos - Buffer;
425 TRACE("marshalled size=%ld\n", var->clSize);
426 return Pos;
429 unsigned char * WINAPI VARIANT_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar)
431 wireVARIANT var = (wireVARIANT)Buffer;
432 unsigned size;
433 unsigned char *Pos = Buffer + VARIANT_wiresize;
435 TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar);
436 VariantInit(pvar);
437 pvar->n1.n2.vt = var->rpcReserved;
438 TRACE("marshalled: clSize=%ld, vt=%04x\n", var->clSize, var->vt);
439 TRACE("vt=%04x\n", V_VT(pvar));
440 TRACE("reserved: %d, %d, %d\n", var->wReserved1, var->wReserved2, var->wReserved3);
441 TRACE("val: %ld\n", var->u.lVal);
443 if (var->vt == VT_DECIMAL) {
444 /* special case because decVal is on a different level */
445 pvar->n1.decVal = var->u.decVal;
446 return Pos;
449 size = wire_size(V_VT(pvar));
450 pvar->n1.n2.wReserved1 = var->wReserved1;
451 pvar->n1.n2.wReserved2 = var->wReserved2;
452 pvar->n1.n2.wReserved3 = var->wReserved3;
453 if (size) {
454 if (var->vt & VT_BYREF) {
455 pvar->n1.n2.n3.byref = CoTaskMemAlloc(size);
456 memcpy(pvar->n1.n2.n3.byref, &var->u.cVal, size);
458 else
459 memcpy(&pvar->n1.n2.n3, &var->u.cVal, size);
461 if (var->clSize <= VARIANT_wiresize) return Pos;
463 switch (var->vt) {
464 case VT_BSTR:
465 Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar));
466 break;
467 case VT_BSTR | VT_BYREF:
468 pvar->n1.n2.n3.byref = CoTaskMemAlloc(sizeof(BSTR));
469 *(BSTR*)pvar->n1.n2.n3.byref = NULL;
470 Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar));
471 break;
472 case VT_VARIANT | VT_BYREF:
473 pvar->n1.n2.n3.byref = CoTaskMemAlloc(sizeof(VARIANT));
474 Pos = VARIANT_UserUnmarshal(pFlags, Pos, V_VARIANTREF(pvar));
475 break;
476 case VT_RECORD:
477 FIXME("handle BRECORD by val\n");
478 break;
479 case VT_RECORD | VT_BYREF:
480 FIXME("handle BRECORD by ref\n");
481 break;
482 case VT_UNKNOWN:
483 Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, pvar);
484 break;
485 case VT_DISPATCH:
486 Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, pvar);
487 break;
488 case VT_DISPATCH | VT_BYREF:
489 FIXME("handle DISPATCH by ref\n");
490 default:
491 FIXME("handle unknown complex type\n");
492 break;
494 if (Pos != Buffer + var->clSize) {
495 ERR("size difference during unmarshal\n");
497 return Buffer + var->clSize;
500 void WINAPI VARIANT_UserFree(unsigned long *pFlags, VARIANT *pvar)
502 VARTYPE vt = V_VT(pvar);
503 PVOID ref = NULL;
505 TRACE("(%lx,%p)\n", *pFlags, pvar);
506 TRACE("vt=%04x\n", V_VT(pvar));
508 if (vt & VT_BYREF) ref = pvar->n1.n2.n3.byref;
510 VariantClear(pvar);
511 if (!ref) return;
513 switch (vt) {
514 case VT_BSTR | VT_BYREF:
515 BSTR_UserFree(pFlags, ref);
516 break;
517 case VT_VARIANT | VT_BYREF:
518 VARIANT_UserFree(pFlags, ref);
519 break;
520 case VT_RECORD | VT_BYREF:
521 FIXME("handle BRECORD by ref\n");
522 break;
523 case VT_UNKNOWN:
524 case VT_DISPATCH:
525 IUnknown_Release(V_UNKNOWN(pvar));
526 break;
527 default:
528 FIXME("handle unknown complex type\n");
529 break;
532 CoTaskMemFree(ref);
535 /* LPSAFEARRAY */
537 /* Get the number of cells in a SafeArray */
538 static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa)
540 const SAFEARRAYBOUND* psab = psa->rgsabound;
541 USHORT cCount = psa->cDims;
542 ULONG ulNumCells = 1;
544 while (cCount--)
546 /* This is a valid bordercase. See testcases. -Marcus */
547 if (!psab->cElements)
548 return 0;
549 ulNumCells *= psab->cElements;
550 psab++;
552 return ulNumCells;
555 static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa)
557 VARTYPE vt;
558 HRESULT hr;
560 hr = SafeArrayGetVartype(psa, &vt);
561 if (FAILED(hr))
562 RpcRaiseException(hr);
564 if (psa->fFeatures & FADF_HAVEIID)
565 return SF_HAVEIID;
567 switch (vt)
569 case VT_I1:
570 case VT_UI1: return SF_I1;
571 case VT_BOOL:
572 case VT_I2:
573 case VT_UI2: return SF_I2;
574 case VT_INT:
575 case VT_UINT:
576 case VT_I4:
577 case VT_UI4:
578 case VT_R4: return SF_I4;
579 case VT_DATE:
580 case VT_CY:
581 case VT_R8:
582 case VT_I8:
583 case VT_UI8: return SF_I8;
584 case VT_INT_PTR:
585 case VT_UINT_PTR: return (sizeof(UINT_PTR) == 4 ? SF_I4 : SF_I8);
586 case VT_BSTR: return SF_BSTR;
587 case VT_DISPATCH: return SF_DISPATCH;
588 case VT_VARIANT: return SF_VARIANT;
589 case VT_UNKNOWN: return SF_UNKNOWN;
590 /* Note: Return a non-zero size to indicate vt is valid. The actual size
591 * of a UDT is taken from the result of IRecordInfo_GetSize().
593 case VT_RECORD: return SF_RECORD;
594 default: return SF_ERROR;
598 unsigned long WINAPI LPSAFEARRAY_UserSize(unsigned long *pFlags, unsigned long StartingSize, LPSAFEARRAY *ppsa)
600 unsigned long size = StartingSize;
602 TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n", StartingSize, *ppsa);
604 size += sizeof(ULONG_PTR);
605 if (*ppsa)
607 SAFEARRAY *psa = *ppsa;
608 ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
609 SF_TYPE sftype;
610 HRESULT hr;
612 size += sizeof(ULONG);
613 size += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
615 sftype = SAFEARRAY_GetUnionType(psa);
616 size += sizeof(ULONG);
618 size += sizeof(ULONG);
619 size += sizeof(ULONG_PTR);
620 if (sftype == SF_HAVEIID)
621 size += sizeof(IID);
623 size += sizeof(psa->rgsabound[0]) * psa->cDims;
625 size += sizeof(ULONG);
627 switch (sftype)
629 case SF_BSTR:
631 BSTR* lpBstr;
633 for (lpBstr = (BSTR*)psa->pvData; ulCellCount; ulCellCount--, lpBstr++)
634 size = BSTR_UserSize(pFlags, size, lpBstr);
636 break;
638 case SF_DISPATCH:
639 case SF_UNKNOWN:
640 case SF_HAVEIID:
641 FIXME("size interfaces\n");
642 break;
643 case SF_VARIANT:
645 VARIANT* lpVariant;
647 for (lpVariant = (VARIANT*)psa->pvData; ulCellCount; ulCellCount--, lpVariant++)
648 size = VARIANT_UserSize(pFlags, size, lpVariant);
650 break;
652 case SF_RECORD:
654 IRecordInfo* pRecInfo = NULL;
656 hr = SafeArrayGetRecordInfo(psa, &pRecInfo);
657 if (FAILED(hr))
658 RpcRaiseException(hr);
660 if (pRecInfo)
662 FIXME("size record info %p\n", pRecInfo);
664 IRecordInfo_Release(pRecInfo);
666 break;
668 case SF_I1:
669 case SF_I2:
670 case SF_I4:
671 case SF_I8:
672 size += ulCellCount * psa->cbElements;
673 break;
674 default:
675 break;
680 return size;
683 unsigned char * WINAPI LPSAFEARRAY_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa)
685 HRESULT hr;
687 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", Buffer, *ppsa);
689 *(ULONG_PTR *)Buffer = *ppsa ? TRUE : FALSE;
690 Buffer += sizeof(ULONG_PTR);
691 if (*ppsa)
693 VARTYPE vt;
694 SAFEARRAY *psa = *ppsa;
695 ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
696 wireSAFEARRAY wiresa;
697 SF_TYPE sftype;
698 GUID guid;
700 *(ULONG *)Buffer = psa->cDims;
701 Buffer += sizeof(ULONG);
702 wiresa = (wireSAFEARRAY)Buffer;
703 wiresa->cDims = psa->cDims;
704 wiresa->fFeatures = psa->fFeatures;
705 wiresa->cbElements = psa->cbElements;
707 hr = SafeArrayGetVartype(psa, &vt);
708 if (FAILED(hr))
709 RpcRaiseException(hr);
710 wiresa->cLocks = (USHORT)psa->cLocks | (vt << 16);
712 Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
714 sftype = SAFEARRAY_GetUnionType(psa);
715 *(ULONG *)Buffer = sftype;
716 Buffer += sizeof(ULONG);
718 *(ULONG *)Buffer = ulCellCount;
719 Buffer += sizeof(ULONG);
720 *(ULONG_PTR *)Buffer = (ULONG_PTR)psa->pvData;
721 Buffer += sizeof(ULONG_PTR);
722 if (sftype == SF_HAVEIID)
724 SafeArrayGetIID(psa, &guid);
725 memcpy(Buffer, &guid, sizeof(guid));
726 Buffer += sizeof(guid);
729 memcpy(Buffer, psa->rgsabound, sizeof(psa->rgsabound[0]) * psa->cDims);
730 Buffer += sizeof(psa->rgsabound[0]) * psa->cDims;
732 *(ULONG *)Buffer = ulCellCount;
733 Buffer += sizeof(ULONG);
735 if (psa->pvData)
737 switch (sftype)
739 case SF_BSTR:
741 BSTR* lpBstr;
743 for (lpBstr = (BSTR*)psa->pvData; ulCellCount; ulCellCount--, lpBstr++)
744 Buffer = BSTR_UserMarshal(pFlags, Buffer, lpBstr);
746 break;
748 case SF_DISPATCH:
749 case SF_UNKNOWN:
750 case SF_HAVEIID:
751 FIXME("marshal interfaces\n");
752 break;
753 case SF_VARIANT:
755 VARIANT* lpVariant;
757 for (lpVariant = (VARIANT*)psa->pvData; ulCellCount; ulCellCount--, lpVariant++)
758 Buffer = VARIANT_UserMarshal(pFlags, Buffer, lpVariant);
760 break;
762 case SF_RECORD:
764 IRecordInfo* pRecInfo = NULL;
766 hr = SafeArrayGetRecordInfo(psa, &pRecInfo);
767 if (FAILED(hr))
768 RpcRaiseException(hr);
770 if (pRecInfo)
772 FIXME("write record info %p\n", pRecInfo);
774 IRecordInfo_Release(pRecInfo);
776 break;
778 case SF_I1:
779 case SF_I2:
780 case SF_I4:
781 case SF_I8:
782 /* Just copy the data over */
783 memcpy(Buffer, psa->pvData, ulCellCount * psa->cbElements);
784 Buffer += ulCellCount * psa->cbElements;
785 break;
786 default:
787 break;
792 return Buffer;
795 #define FADF_AUTOSETFLAGS (FADF_HAVEIID | FADF_RECORD | FADF_HAVEVARTYPE | \
796 FADF_BSTR | FADF_UNKNOWN | FADF_DISPATCH | \
797 FADF_VARIANT | FADF_CREATEVECTOR)
799 unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa)
801 ULONG_PTR ptr;
802 wireSAFEARRAY wiresa;
803 ULONG cDims;
804 HRESULT hr;
805 SF_TYPE sftype;
806 ULONG cell_count;
807 GUID guid;
808 VARTYPE vt;
809 SAFEARRAYBOUND *wiresab;
811 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", Buffer, ppsa);
813 ptr = *(ULONG_PTR *)Buffer;
814 Buffer += sizeof(ULONG_PTR);
816 if (!ptr)
818 *ppsa = NULL;
820 TRACE("NULL safe array unmarshaled\n");
822 return Buffer;
825 cDims = *(ULONG *)Buffer;
826 Buffer += sizeof(ULONG);
828 wiresa = (wireSAFEARRAY)Buffer;
829 Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs);
831 if (cDims != wiresa->cDims)
832 RpcRaiseException(RPC_S_INVALID_BOUND);
834 /* FIXME: there should be a limit on how large cDims can be */
836 vt = HIWORD(wiresa->cLocks);
838 sftype = *(ULONG *)Buffer;
839 Buffer += sizeof(ULONG);
841 cell_count = *(ULONG *)Buffer;
842 Buffer += sizeof(ULONG);
843 ptr = *(ULONG_PTR *)Buffer;
844 Buffer += sizeof(ULONG_PTR);
845 if (sftype == SF_HAVEIID)
847 memcpy(&guid, Buffer, sizeof(guid));
848 Buffer += sizeof(guid);
851 wiresab = (SAFEARRAYBOUND *)Buffer;
852 Buffer += sizeof(wiresab[0]) * wiresa->cDims;
854 *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL);
855 if (!ppsa)
856 RpcRaiseException(E_OUTOFMEMORY);
858 /* be careful about which flags we set since they could be a security
859 * risk */
860 (*ppsa)->fFeatures = wiresa->fFeatures & ~(FADF_AUTOSETFLAGS);
861 /* FIXME: there should be a limit on how large wiresa->cbElements can be */
862 (*ppsa)->cbElements = wiresa->cbElements;
863 (*ppsa)->cLocks = LOWORD(wiresa->cLocks);
865 hr = SafeArrayAllocData(*ppsa);
866 if (FAILED(hr))
867 RpcRaiseException(hr);
869 if ((*(ULONG *)Buffer != cell_count) || (SAFEARRAY_GetCellCount(*ppsa) != cell_count))
870 RpcRaiseException(RPC_S_INVALID_BOUND);
871 Buffer += sizeof(ULONG);
873 if (ptr)
875 switch (sftype)
877 case SF_BSTR:
879 BSTR* lpBstr;
881 for (lpBstr = (BSTR*)(*ppsa)->pvData; cell_count; cell_count--, lpBstr++)
882 Buffer = BSTR_UserUnmarshal(pFlags, Buffer, lpBstr);
884 break;
886 case SF_DISPATCH:
887 case SF_UNKNOWN:
888 case SF_HAVEIID:
889 FIXME("marshal interfaces\n");
890 break;
891 case SF_VARIANT:
893 VARIANT* lpVariant;
895 for (lpVariant = (VARIANT*)(*ppsa)->pvData; cell_count; cell_count--, lpVariant++)
896 Buffer = VARIANT_UserUnmarshal(pFlags, Buffer, lpVariant);
898 break;
900 case SF_RECORD:
902 FIXME("set record info\n");
904 break;
906 case SF_I1:
907 case SF_I2:
908 case SF_I4:
909 case SF_I8:
910 /* Just copy the data over */
911 memcpy((*ppsa)->pvData, Buffer, cell_count * (*ppsa)->cbElements);
912 Buffer += cell_count * (*ppsa)->cbElements;
913 break;
914 default:
915 break;
919 TRACE("safe array unmarshaled: %p\n", *ppsa);
921 return Buffer;
924 void WINAPI LPSAFEARRAY_UserFree(unsigned long *pFlags, LPSAFEARRAY *ppsa)
926 TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *ppsa);
928 SafeArrayDestroy(*ppsa);
931 /* IDispatch */
932 /* exactly how Invoke is marshalled is not very clear to me yet,
933 * but the way I've done it seems to work for me */
935 HRESULT CALLBACK IDispatch_Invoke_Proxy(
936 IDispatch* This,
937 DISPID dispIdMember,
938 REFIID riid,
939 LCID lcid,
940 WORD wFlags,
941 DISPPARAMS* pDispParams,
942 VARIANT* pVarResult,
943 EXCEPINFO* pExcepInfo,
944 UINT* puArgErr)
946 HRESULT hr;
947 VARIANT VarResult;
948 UINT* rgVarRefIdx = NULL;
949 VARIANTARG* rgVarRef = NULL;
950 UINT u, cVarRef;
951 UINT uArgErr;
952 EXCEPINFO ExcepInfo;
954 TRACE("(%p)->(%ld,%s,%lx,%x,%p,%p,%p,%p)\n", This,
955 dispIdMember, debugstr_guid(riid),
956 lcid, wFlags, pDispParams, pVarResult,
957 pExcepInfo, puArgErr);
959 /* [out] args can't be null, use dummy vars if needed */
960 if (!pVarResult) pVarResult = &VarResult;
961 if (!puArgErr) puArgErr = &uArgErr;
962 if (!pExcepInfo) pExcepInfo = &ExcepInfo;
964 /* count by-ref args */
965 for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
966 VARIANTARG* arg = &pDispParams->rgvarg[u];
967 if (V_ISBYREF(arg)) {
968 cVarRef++;
971 if (cVarRef) {
972 rgVarRefIdx = CoTaskMemAlloc(sizeof(UINT)*cVarRef);
973 rgVarRef = CoTaskMemAlloc(sizeof(VARIANTARG)*cVarRef);
974 /* make list of by-ref args */
975 for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
976 VARIANTARG* arg = &pDispParams->rgvarg[u];
977 if (V_ISBYREF(arg)) {
978 rgVarRefIdx[cVarRef] = u;
979 VariantInit(&rgVarRef[cVarRef]);
980 cVarRef++;
983 } else {
984 /* [out] args still can't be null,
985 * but we can point these anywhere in this case,
986 * since they won't be written to when cVarRef is 0 */
987 rgVarRefIdx = puArgErr;
988 rgVarRef = pVarResult;
990 TRACE("passed by ref: %d args\n", cVarRef);
991 hr = IDispatch_RemoteInvoke_Proxy(This,
992 dispIdMember,
993 riid,
994 lcid,
995 wFlags,
996 pDispParams,
997 pVarResult,
998 pExcepInfo,
999 puArgErr,
1000 cVarRef,
1001 rgVarRefIdx,
1002 rgVarRef);
1003 if (cVarRef) {
1004 for (u=0; u<cVarRef; u++) {
1005 unsigned i = rgVarRefIdx[u];
1006 VariantCopy(&pDispParams->rgvarg[i],
1007 &rgVarRef[u]);
1008 VariantClear(&rgVarRef[u]);
1010 CoTaskMemFree(rgVarRef);
1011 CoTaskMemFree(rgVarRefIdx);
1014 if(pExcepInfo == &ExcepInfo)
1016 SysFreeString(pExcepInfo->bstrSource);
1017 SysFreeString(pExcepInfo->bstrDescription);
1018 SysFreeString(pExcepInfo->bstrHelpFile);
1020 return hr;
1023 HRESULT __RPC_STUB IDispatch_Invoke_Stub(
1024 IDispatch* This,
1025 DISPID dispIdMember,
1026 REFIID riid,
1027 LCID lcid,
1028 DWORD dwFlags,
1029 DISPPARAMS* pDispParams,
1030 VARIANT* pVarResult,
1031 EXCEPINFO* pExcepInfo,
1032 UINT* pArgErr,
1033 UINT cVarRef,
1034 UINT* rgVarRefIdx,
1035 VARIANTARG* rgVarRef)
1037 HRESULT hr = S_OK;
1038 VARIANTARG *rgvarg, *arg;
1039 UINT u;
1041 /* initialize out parameters, so that they can be marshalled
1042 * in case the real Invoke doesn't initialize them */
1043 VariantInit(pVarResult);
1044 memset(pExcepInfo, 0, sizeof(*pExcepInfo));
1045 *pArgErr = 0;
1047 /* let the real Invoke operate on a copy of the in parameters,
1048 * so we don't risk losing pointers to allocated memory */
1049 rgvarg = pDispParams->rgvarg;
1050 arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs);
1051 if (!arg) return E_OUTOFMEMORY;
1053 /* init all args so we can call VariantClear on all the args if the copy
1054 * below fails */
1055 for (u = 0; u < pDispParams->cArgs; u++)
1056 VariantInit(&arg[u]);
1058 for (u = 0; u < pDispParams->cArgs; u++) {
1059 hr = VariantCopy(&arg[u], &rgvarg[u]);
1060 if (FAILED(hr))
1061 break;
1064 if (SUCCEEDED(hr)) {
1065 pDispParams->rgvarg = arg;
1067 hr = IDispatch_Invoke(This,
1068 dispIdMember,
1069 riid,
1070 lcid,
1071 dwFlags,
1072 pDispParams,
1073 pVarResult,
1074 pExcepInfo,
1075 pArgErr);
1077 /* copy ref args to out list */
1078 for (u=0; u<cVarRef; u++) {
1079 unsigned i = rgVarRefIdx[u];
1080 VariantInit(&rgVarRef[u]);
1081 VariantCopy(&rgVarRef[u], &arg[i]);
1082 /* clear original if equal, to avoid double-free */
1083 if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
1084 VariantClear(&rgvarg[i]);
1088 /* clear the duplicate argument list */
1089 for (u=0; u<pDispParams->cArgs; u++)
1090 VariantClear(&arg[u]);
1092 pDispParams->rgvarg = rgvarg;
1093 CoTaskMemFree(arg);
1095 return hr;
1098 /* IEnumVARIANT */
1100 HRESULT CALLBACK IEnumVARIANT_Next_Proxy(
1101 IEnumVARIANT* This,
1102 ULONG celt,
1103 VARIANT* rgVar,
1104 ULONG* pCeltFetched)
1106 ULONG fetched;
1107 if (!pCeltFetched)
1108 pCeltFetched = &fetched;
1109 return IEnumVARIANT_RemoteNext_Proxy(This,
1110 celt,
1111 rgVar,
1112 pCeltFetched);
1115 HRESULT __RPC_STUB IEnumVARIANT_Next_Stub(
1116 IEnumVARIANT* This,
1117 ULONG celt,
1118 VARIANT* rgVar,
1119 ULONG* pCeltFetched)
1121 HRESULT hr;
1122 *pCeltFetched = 0;
1123 hr = IEnumVARIANT_Next(This,
1124 celt,
1125 rgVar,
1126 pCeltFetched);
1127 if (hr == S_OK) *pCeltFetched = celt;
1128 return hr;
1131 /* ITypeComp */
1133 HRESULT CALLBACK ITypeComp_Bind_Proxy(
1134 ITypeComp* This,
1135 LPOLESTR szName,
1136 ULONG lHashVal,
1137 WORD wFlags,
1138 ITypeInfo** ppTInfo,
1139 DESCKIND* pDescKind,
1140 BINDPTR* pBindPtr)
1142 FIXME("not implemented\n");
1143 return E_FAIL;
1146 HRESULT __RPC_STUB ITypeComp_Bind_Stub(
1147 ITypeComp* This,
1148 LPOLESTR szName,
1149 ULONG lHashVal,
1150 WORD wFlags,
1151 ITypeInfo** ppTInfo,
1152 DESCKIND* pDescKind,
1153 LPFUNCDESC* ppFuncDesc,
1154 LPVARDESC* ppVarDesc,
1155 ITypeComp** ppTypeComp,
1156 CLEANLOCALSTORAGE* pDummy)
1158 FIXME("not implemented\n");
1159 return E_FAIL;
1162 HRESULT CALLBACK ITypeComp_BindType_Proxy(
1163 ITypeComp* This,
1164 LPOLESTR szName,
1165 ULONG lHashVal,
1166 ITypeInfo** ppTInfo,
1167 ITypeComp** ppTComp)
1169 FIXME("not implemented\n");
1170 return E_FAIL;
1173 HRESULT __RPC_STUB ITypeComp_BindType_Stub(
1174 ITypeComp* This,
1175 LPOLESTR szName,
1176 ULONG lHashVal,
1177 ITypeInfo** ppTInfo)
1179 FIXME("not implemented\n");
1180 return E_FAIL;
1183 /* ITypeInfo */
1185 HRESULT CALLBACK ITypeInfo_GetTypeAttr_Proxy(
1186 ITypeInfo* This,
1187 TYPEATTR** ppTypeAttr)
1189 FIXME("not implemented\n");
1190 return E_FAIL;
1193 HRESULT __RPC_STUB ITypeInfo_GetTypeAttr_Stub(
1194 ITypeInfo* This,
1195 LPTYPEATTR* ppTypeAttr,
1196 CLEANLOCALSTORAGE* pDummy)
1198 FIXME("not implemented\n");
1199 return E_FAIL;
1202 HRESULT CALLBACK ITypeInfo_GetFuncDesc_Proxy(
1203 ITypeInfo* This,
1204 UINT index,
1205 FUNCDESC** ppFuncDesc)
1207 FIXME("not implemented\n");
1208 return E_FAIL;
1211 HRESULT __RPC_STUB ITypeInfo_GetFuncDesc_Stub(
1212 ITypeInfo* This,
1213 UINT index,
1214 LPFUNCDESC* ppFuncDesc,
1215 CLEANLOCALSTORAGE* pDummy)
1217 FIXME("not implemented\n");
1218 return E_FAIL;
1221 HRESULT CALLBACK ITypeInfo_GetVarDesc_Proxy(
1222 ITypeInfo* This,
1223 UINT index,
1224 VARDESC** ppVarDesc)
1226 FIXME("not implemented\n");
1227 return E_FAIL;
1230 HRESULT __RPC_STUB ITypeInfo_GetVarDesc_Stub(
1231 ITypeInfo* This,
1232 UINT index,
1233 LPVARDESC* ppVarDesc,
1234 CLEANLOCALSTORAGE* pDummy)
1236 FIXME("not implemented\n");
1237 return E_FAIL;
1240 HRESULT CALLBACK ITypeInfo_GetNames_Proxy(
1241 ITypeInfo* This,
1242 MEMBERID memid,
1243 BSTR* rgBstrNames,
1244 UINT cMaxNames,
1245 UINT* pcNames)
1247 FIXME("not implemented\n");
1248 return E_FAIL;
1251 HRESULT __RPC_STUB ITypeInfo_GetNames_Stub(
1252 ITypeInfo* This,
1253 MEMBERID memid,
1254 BSTR* rgBstrNames,
1255 UINT cMaxNames,
1256 UINT* pcNames)
1258 FIXME("not implemented\n");
1259 return E_FAIL;
1262 HRESULT CALLBACK ITypeInfo_GetIDsOfNames_Proxy(
1263 ITypeInfo* This,
1264 LPOLESTR* rgszNames,
1265 UINT cNames,
1266 MEMBERID* pMemId)
1268 FIXME("not implemented\n");
1269 return E_FAIL;
1272 HRESULT __RPC_STUB ITypeInfo_GetIDsOfNames_Stub(
1273 ITypeInfo* This)
1275 FIXME("not implemented\n");
1276 return E_FAIL;
1279 HRESULT CALLBACK ITypeInfo_Invoke_Proxy(
1280 ITypeInfo* This,
1281 PVOID pvInstance,
1282 MEMBERID memid,
1283 WORD wFlags,
1284 DISPPARAMS* pDispParams,
1285 VARIANT* pVarResult,
1286 EXCEPINFO* pExcepInfo,
1287 UINT* puArgErr)
1289 FIXME("not implemented\n");
1290 return E_FAIL;
1293 HRESULT __RPC_STUB ITypeInfo_Invoke_Stub(
1294 ITypeInfo* This)
1296 FIXME("not implemented\n");
1297 return E_FAIL;
1300 HRESULT CALLBACK ITypeInfo_GetDocumentation_Proxy(
1301 ITypeInfo* This,
1302 MEMBERID memid,
1303 BSTR* pBstrName,
1304 BSTR* pBstrDocString,
1305 DWORD* pdwHelpContext,
1306 BSTR* pBstrHelpFile)
1308 FIXME("not implemented\n");
1309 return E_FAIL;
1312 HRESULT __RPC_STUB ITypeInfo_GetDocumentation_Stub(
1313 ITypeInfo* This,
1314 MEMBERID memid,
1315 DWORD refPtrFlags,
1316 BSTR* pBstrName,
1317 BSTR* pBstrDocString,
1318 DWORD* pdwHelpContext,
1319 BSTR* pBstrHelpFile)
1321 FIXME("not implemented\n");
1322 return E_FAIL;
1325 HRESULT CALLBACK ITypeInfo_GetDllEntry_Proxy(
1326 ITypeInfo* This,
1327 MEMBERID memid,
1328 INVOKEKIND invKind,
1329 BSTR* pBstrDllName,
1330 BSTR* pBstrName,
1331 WORD* pwOrdinal)
1333 FIXME("not implemented\n");
1334 return E_FAIL;
1337 HRESULT __RPC_STUB ITypeInfo_GetDllEntry_Stub(
1338 ITypeInfo* This,
1339 MEMBERID memid,
1340 INVOKEKIND invKind,
1341 DWORD refPtrFlags,
1342 BSTR* pBstrDllName,
1343 BSTR* pBstrName,
1344 WORD* pwOrdinal)
1346 FIXME("not implemented\n");
1347 return E_FAIL;
1350 HRESULT CALLBACK ITypeInfo_AddressOfMember_Proxy(
1351 ITypeInfo* This,
1352 MEMBERID memid,
1353 INVOKEKIND invKind,
1354 PVOID* ppv)
1356 FIXME("not implemented\n");
1357 return E_FAIL;
1360 HRESULT __RPC_STUB ITypeInfo_AddressOfMember_Stub(
1361 ITypeInfo* This)
1363 FIXME("not implemented\n");
1364 return E_FAIL;
1367 HRESULT CALLBACK ITypeInfo_CreateInstance_Proxy(
1368 ITypeInfo* This,
1369 IUnknown* pUnkOuter,
1370 REFIID riid,
1371 PVOID* ppvObj)
1373 FIXME("not implemented\n");
1374 return E_FAIL;
1377 HRESULT __RPC_STUB ITypeInfo_CreateInstance_Stub(
1378 ITypeInfo* This,
1379 REFIID riid,
1380 IUnknown** ppvObj)
1382 FIXME("not implemented\n");
1383 return E_FAIL;
1386 HRESULT CALLBACK ITypeInfo_GetContainingTypeLib_Proxy(
1387 ITypeInfo* This,
1388 ITypeLib** ppTLib,
1389 UINT* pIndex)
1391 ITypeLib *pTL;
1392 UINT index;
1393 HRESULT hr;
1395 TRACE("(%p, %p, %p)\n", This, ppTLib, pIndex );
1397 hr = ITypeInfo_RemoteGetContainingTypeLib_Proxy(This, &pTL, &index);
1398 if(SUCCEEDED(hr))
1400 if(pIndex)
1401 *pIndex = index;
1403 if(ppTLib)
1404 *ppTLib = pTL;
1405 else
1406 ITypeLib_Release(pTL);
1408 return hr;
1411 HRESULT __RPC_STUB ITypeInfo_GetContainingTypeLib_Stub(
1412 ITypeInfo* This,
1413 ITypeLib** ppTLib,
1414 UINT* pIndex)
1416 TRACE("(%p, %p, %p)\n", This, ppTLib, pIndex );
1417 return ITypeInfo_GetContainingTypeLib(This, ppTLib, pIndex);
1420 void CALLBACK ITypeInfo_ReleaseTypeAttr_Proxy(
1421 ITypeInfo* This,
1422 TYPEATTR* pTypeAttr)
1424 FIXME("not implemented\n");
1427 HRESULT __RPC_STUB ITypeInfo_ReleaseTypeAttr_Stub(
1428 ITypeInfo* This)
1430 FIXME("not implemented\n");
1431 return E_FAIL;
1434 void CALLBACK ITypeInfo_ReleaseFuncDesc_Proxy(
1435 ITypeInfo* This,
1436 FUNCDESC* pFuncDesc)
1438 FIXME("not implemented\n");
1441 HRESULT __RPC_STUB ITypeInfo_ReleaseFuncDesc_Stub(
1442 ITypeInfo* This)
1444 FIXME("not implemented\n");
1445 return E_FAIL;
1448 void CALLBACK ITypeInfo_ReleaseVarDesc_Proxy(
1449 ITypeInfo* This,
1450 VARDESC* pVarDesc)
1452 FIXME("not implemented\n");
1455 HRESULT __RPC_STUB ITypeInfo_ReleaseVarDesc_Stub(
1456 ITypeInfo* This)
1458 FIXME("not implemented\n");
1459 return E_FAIL;
1463 /* ITypeInfo2 */
1465 HRESULT CALLBACK ITypeInfo2_GetDocumentation2_Proxy(
1466 ITypeInfo2* This,
1467 MEMBERID memid,
1468 LCID lcid,
1469 BSTR* pbstrHelpString,
1470 DWORD* pdwHelpStringContext,
1471 BSTR* pbstrHelpStringDll)
1473 FIXME("not implemented\n");
1474 return E_FAIL;
1477 HRESULT __RPC_STUB ITypeInfo2_GetDocumentation2_Stub(
1478 ITypeInfo2* This,
1479 MEMBERID memid,
1480 LCID lcid,
1481 DWORD refPtrFlags,
1482 BSTR* pbstrHelpString,
1483 DWORD* pdwHelpStringContext,
1484 BSTR* pbstrHelpStringDll)
1486 FIXME("not implemented\n");
1487 return E_FAIL;
1490 /* ITypeLib */
1492 UINT CALLBACK ITypeLib_GetTypeInfoCount_Proxy(
1493 ITypeLib* This)
1495 UINT count = 0;
1496 TRACE("(%p)\n", This);
1498 ITypeLib_RemoteGetTypeInfoCount_Proxy(This, &count);
1500 return count;
1503 HRESULT __RPC_STUB ITypeLib_GetTypeInfoCount_Stub(
1504 ITypeLib* This,
1505 UINT* pcTInfo)
1507 TRACE("(%p, %p)\n", This, pcTInfo);
1508 *pcTInfo = ITypeLib_GetTypeInfoCount(This);
1509 return S_OK;
1512 HRESULT CALLBACK ITypeLib_GetLibAttr_Proxy(
1513 ITypeLib* This,
1514 TLIBATTR** ppTLibAttr)
1516 CLEANLOCALSTORAGE stg;
1517 TRACE("(%p, %p)\n", This, ppTLibAttr);
1518 return ITypeLib_RemoteGetLibAttr_Proxy(This, ppTLibAttr, &stg);
1521 HRESULT __RPC_STUB ITypeLib_GetLibAttr_Stub(
1522 ITypeLib* This,
1523 LPTLIBATTR* ppTLibAttr,
1524 CLEANLOCALSTORAGE* pDummy)
1526 TRACE("(%p, %p)\n", This, ppTLibAttr);
1527 return ITypeLib_GetLibAttr(This, ppTLibAttr);
1530 HRESULT CALLBACK ITypeLib_GetDocumentation_Proxy(
1531 ITypeLib* This,
1532 INT index,
1533 BSTR* pBstrName,
1534 BSTR* pBstrDocString,
1535 DWORD* pdwHelpContext,
1536 BSTR* pBstrHelpFile)
1538 FIXME("not implemented\n");
1539 return E_FAIL;
1542 HRESULT __RPC_STUB ITypeLib_GetDocumentation_Stub(
1543 ITypeLib* This,
1544 INT index,
1545 DWORD refPtrFlags,
1546 BSTR* pBstrName,
1547 BSTR* pBstrDocString,
1548 DWORD* pdwHelpContext,
1549 BSTR* pBstrHelpFile)
1551 FIXME("not implemented\n");
1552 return E_FAIL;
1555 HRESULT CALLBACK ITypeLib_IsName_Proxy(
1556 ITypeLib* This,
1557 LPOLESTR szNameBuf,
1558 ULONG lHashVal,
1559 BOOL* pfName)
1561 FIXME("not implemented\n");
1562 return E_FAIL;
1565 HRESULT __RPC_STUB ITypeLib_IsName_Stub(
1566 ITypeLib* This,
1567 LPOLESTR szNameBuf,
1568 ULONG lHashVal,
1569 BOOL* pfName,
1570 BSTR* pBstrLibName)
1572 FIXME("not implemented\n");
1573 return E_FAIL;
1576 HRESULT CALLBACK ITypeLib_FindName_Proxy(
1577 ITypeLib* This,
1578 LPOLESTR szNameBuf,
1579 ULONG lHashVal,
1580 ITypeInfo** ppTInfo,
1581 MEMBERID* rgMemId,
1582 USHORT* pcFound)
1584 FIXME("not implemented\n");
1585 return E_FAIL;
1588 HRESULT __RPC_STUB ITypeLib_FindName_Stub(
1589 ITypeLib* This,
1590 LPOLESTR szNameBuf,
1591 ULONG lHashVal,
1592 ITypeInfo** ppTInfo,
1593 MEMBERID* rgMemId,
1594 USHORT* pcFound,
1595 BSTR* pBstrLibName)
1597 FIXME("not implemented\n");
1598 return E_FAIL;
1601 void CALLBACK ITypeLib_ReleaseTLibAttr_Proxy(
1602 ITypeLib* This,
1603 TLIBATTR* pTLibAttr)
1605 TRACE("(%p, %p)\n", This, pTLibAttr);
1606 CoTaskMemFree(pTLibAttr);
1609 HRESULT __RPC_STUB ITypeLib_ReleaseTLibAttr_Stub(
1610 ITypeLib* This)
1612 TRACE("nothing to do\n");
1613 return S_OK;
1617 /* ITypeLib2 */
1619 HRESULT CALLBACK ITypeLib2_GetLibStatistics_Proxy(
1620 ITypeLib2* This,
1621 ULONG* pcUniqueNames,
1622 ULONG* pcchUniqueNames)
1624 FIXME("not implemented\n");
1625 return E_FAIL;
1628 HRESULT __RPC_STUB ITypeLib2_GetLibStatistics_Stub(
1629 ITypeLib2* This,
1630 ULONG* pcUniqueNames,
1631 ULONG* pcchUniqueNames)
1633 FIXME("not implemented\n");
1634 return E_FAIL;
1637 HRESULT CALLBACK ITypeLib2_GetDocumentation2_Proxy(
1638 ITypeLib2* This,
1639 INT index,
1640 LCID lcid,
1641 BSTR* pbstrHelpString,
1642 DWORD* pdwHelpStringContext,
1643 BSTR* pbstrHelpStringDll)
1645 FIXME("not implemented\n");
1646 return E_FAIL;
1649 HRESULT __RPC_STUB ITypeLib2_GetDocumentation2_Stub(
1650 ITypeLib2* This,
1651 INT index,
1652 LCID lcid,
1653 DWORD refPtrFlags,
1654 BSTR* pbstrHelpString,
1655 DWORD* pdwHelpStringContext,
1656 BSTR* pbstrHelpStringDll)
1658 FIXME("not implemented\n");
1659 return E_FAIL;