Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenusrmarshal.c
Go to the documentation of this file.
00001 /* 00002 * Misc marshalling routines 00003 * 00004 * Copyright 2002 Ove Kaaven 00005 * Copyright 2003 Mike Hearn 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include <stdarg.h> 00023 #include <string.h> 00024 00025 #define COBJMACROS 00026 #define NONAMELESSUNION 00027 #define NONAMELESSSTRUCT 00028 00029 #include "windef.h" 00030 #include "winbase.h" 00031 #include "wingdi.h" 00032 #include "winuser.h" 00033 #include "winerror.h" 00034 00035 #include "ole2.h" 00036 #include "oleauto.h" 00037 #include "typelib.h" 00038 #include "ocidl.h" 00039 #include "wine/debug.h" 00040 00041 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00042 00043 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align)) 00044 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align)) 00045 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align) 00046 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align) 00047 00048 static void dump_user_flags(const ULONG *pFlags) 00049 { 00050 if (HIWORD(*pFlags) == NDR_LOCAL_DATA_REPRESENTATION) 00051 TRACE("MAKELONG(NDR_LOCAL_REPRESENTATION, "); 00052 else 00053 TRACE("MAKELONG(0x%04x, ", HIWORD(*pFlags)); 00054 switch (LOWORD(*pFlags)) 00055 { 00056 case MSHCTX_LOCAL: TRACE("MSHCTX_LOCAL)"); break; 00057 case MSHCTX_NOSHAREDMEM: TRACE("MSHCTX_NOSHAREDMEM)"); break; 00058 case MSHCTX_DIFFERENTMACHINE: TRACE("MSHCTX_DIFFERENTMACHINE)"); break; 00059 case MSHCTX_INPROC: TRACE("MSHCTX_INPROC)"); break; 00060 default: TRACE("%d)", LOWORD(*pFlags)); 00061 } 00062 } 00063 00064 /* CLEANLOCALSTORAGE */ 00065 00066 #define CLS_FUNCDESC 'f' 00067 #define CLS_LIBATTR 'l' 00068 #define CLS_TYPEATTR 't' 00069 #define CLS_VARDESC 'v' 00070 00071 ULONG WINAPI CLEANLOCALSTORAGE_UserSize(ULONG *pFlags, ULONG Start, CLEANLOCALSTORAGE *pstg) 00072 { 00073 ALIGN_LENGTH(Start, 3); 00074 return Start + sizeof(DWORD); 00075 } 00076 00077 unsigned char * WINAPI CLEANLOCALSTORAGE_UserMarshal(ULONG *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstg) 00078 { 00079 ALIGN_POINTER(Buffer, 3); 00080 *(DWORD*)Buffer = pstg->flags; 00081 switch(pstg->flags) 00082 { 00083 case CLS_LIBATTR: 00084 ITypeLib_ReleaseTLibAttr((ITypeLib*)pstg->pInterface, *(TLIBATTR**)pstg->pStorage); 00085 break; 00086 case CLS_TYPEATTR: 00087 ITypeInfo_ReleaseTypeAttr((ITypeInfo*)pstg->pInterface, *(TYPEATTR**)pstg->pStorage); 00088 break; 00089 case CLS_FUNCDESC: 00090 ITypeInfo_ReleaseFuncDesc((ITypeInfo*)pstg->pInterface, *(FUNCDESC**)pstg->pStorage); 00091 break; 00092 case CLS_VARDESC: 00093 ITypeInfo_ReleaseVarDesc((ITypeInfo*)pstg->pInterface, *(VARDESC**)pstg->pStorage); 00094 break; 00095 00096 default: 00097 ERR("Unknown type %x\n", pstg->flags); 00098 } 00099 00100 *(VOID**)pstg->pStorage = NULL; 00101 IUnknown_Release(pstg->pInterface); 00102 pstg->pInterface = NULL; 00103 00104 return Buffer + sizeof(DWORD); 00105 } 00106 00107 unsigned char * WINAPI CLEANLOCALSTORAGE_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstr) 00108 { 00109 ALIGN_POINTER(Buffer, 3); 00110 pstr->flags = *(DWORD*)Buffer; 00111 return Buffer + sizeof(DWORD); 00112 } 00113 00114 void WINAPI CLEANLOCALSTORAGE_UserFree(ULONG *pFlags, CLEANLOCALSTORAGE *pstr) 00115 { 00116 /* Nothing to do */ 00117 } 00118 00119 /* BSTR */ 00120 00121 typedef struct 00122 { 00123 DWORD len; /* No. of chars not including trailing '\0' */ 00124 DWORD byte_len; /* len * 2 or 0xffffffff if len == 0 */ 00125 DWORD len2; /* == len */ 00126 } bstr_wire_t; 00127 00128 ULONG WINAPI BSTR_UserSize(ULONG *pFlags, ULONG Start, BSTR *pstr) 00129 { 00130 TRACE("(%x,%d,%p) => %p\n", *pFlags, Start, pstr, *pstr); 00131 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr)); 00132 ALIGN_LENGTH(Start, 3); 00133 Start += sizeof(bstr_wire_t) + ((SysStringByteLen(*pstr) + 1) & ~1); 00134 TRACE("returning %d\n", Start); 00135 return Start; 00136 } 00137 00138 unsigned char * WINAPI BSTR_UserMarshal(ULONG *pFlags, unsigned char *Buffer, BSTR *pstr) 00139 { 00140 bstr_wire_t *header; 00141 DWORD len = SysStringByteLen(*pstr); 00142 00143 TRACE("(%x,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr); 00144 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr)); 00145 00146 ALIGN_POINTER(Buffer, 3); 00147 header = (bstr_wire_t*)Buffer; 00148 header->len = header->len2 = (len + 1) / 2; 00149 if (*pstr) 00150 { 00151 header->byte_len = len; 00152 memcpy(header + 1, *pstr, header->len * 2); 00153 } 00154 else 00155 header->byte_len = 0xffffffff; /* special case for a null bstr */ 00156 00157 return Buffer + sizeof(*header) + sizeof(OLECHAR) * header->len; 00158 } 00159 00160 unsigned char * WINAPI BSTR_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, BSTR *pstr) 00161 { 00162 bstr_wire_t *header; 00163 TRACE("(%x,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr); 00164 00165 ALIGN_POINTER(Buffer, 3); 00166 header = (bstr_wire_t*)Buffer; 00167 if(header->len != header->len2) 00168 FIXME("len %08x != len2 %08x\n", header->len, header->len2); 00169 00170 SysFreeString(*pstr); 00171 *pstr = NULL; 00172 00173 if(header->byte_len != 0xffffffff) 00174 *pstr = SysAllocStringByteLen((char*)(header + 1), header->byte_len); 00175 00176 if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr)); 00177 return Buffer + sizeof(*header) + sizeof(OLECHAR) * header->len; 00178 } 00179 00180 void WINAPI BSTR_UserFree(ULONG *pFlags, BSTR *pstr) 00181 { 00182 TRACE("(%x,%p) => %p\n", *pFlags, pstr, *pstr); 00183 SysFreeString(*pstr); 00184 *pstr = NULL; 00185 } 00186 00187 /* VARIANT */ 00188 00189 typedef struct 00190 { 00191 DWORD clSize; 00192 DWORD rpcReserverd; 00193 USHORT vt; 00194 USHORT wReserved1; 00195 USHORT wReserved2; 00196 USHORT wReserved3; 00197 DWORD switch_is; 00198 } variant_wire_t; 00199 00200 static unsigned int get_type_size(ULONG *pFlags, VARTYPE vt) 00201 { 00202 if (vt & VT_ARRAY) return 4; 00203 00204 switch (vt & ~VT_BYREF) { 00205 case VT_EMPTY: 00206 case VT_NULL: 00207 return 0; 00208 case VT_I1: 00209 case VT_UI1: 00210 return sizeof(CHAR); 00211 case VT_I2: 00212 case VT_UI2: 00213 return sizeof(SHORT); 00214 case VT_I4: 00215 case VT_UI4: 00216 return sizeof(LONG); 00217 case VT_INT: 00218 case VT_UINT: 00219 return sizeof(INT); 00220 case VT_R4: 00221 return sizeof(FLOAT); 00222 case VT_R8: 00223 return sizeof(DOUBLE); 00224 case VT_BOOL: 00225 return sizeof(VARIANT_BOOL); 00226 case VT_ERROR: 00227 return sizeof(SCODE); 00228 case VT_DATE: 00229 return sizeof(DATE); 00230 case VT_CY: 00231 return sizeof(CY); 00232 case VT_DECIMAL: 00233 return sizeof(DECIMAL); 00234 case VT_BSTR: 00235 return sizeof(ULONG); 00236 case VT_VARIANT: 00237 return sizeof(VARIANT); 00238 case VT_UNKNOWN: 00239 case VT_DISPATCH: 00240 case VT_RECORD: 00241 return 0; 00242 default: 00243 FIXME("unhandled VT %d\n", vt); 00244 return 0; 00245 } 00246 } 00247 00248 static unsigned int get_type_alignment(ULONG *pFlags, VARTYPE vt) 00249 { 00250 unsigned int size = get_type_size(pFlags, vt); 00251 if(vt & VT_BYREF) return 3; 00252 if(size == 0) return 0; 00253 if(size <= 4) return size - 1; 00254 return 7; 00255 } 00256 00257 static unsigned interface_variant_size(const ULONG *pFlags, REFIID riid, IUnknown *punk) 00258 { 00259 ULONG size = 0; 00260 HRESULT hr; 00261 00262 if (punk) 00263 { 00264 hr = CoGetMarshalSizeMax(&size, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL); 00265 if (FAILED(hr)) 00266 { 00267 ERR("interface variant buffer size calculation failed, HRESULT=0x%x\n", hr); 00268 return 0; 00269 } 00270 } 00271 size += sizeof(ULONG); /* we have to store the buffersize in the stream */ 00272 TRACE("wire-size extra of interface variant is %d\n", size); 00273 return size; 00274 } 00275 00276 static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar) 00277 { 00278 if (V_ISARRAY(pvar)) 00279 { 00280 if (V_ISBYREF(pvar)) 00281 return LPSAFEARRAY_UserSize(pFlags, Start, V_ARRAYREF(pvar)); 00282 else 00283 return LPSAFEARRAY_UserSize(pFlags, Start, &V_ARRAY(pvar)); 00284 } 00285 00286 switch (V_VT(pvar)) { 00287 case VT_BSTR: 00288 return BSTR_UserSize(pFlags, Start, &V_BSTR(pvar)); 00289 case VT_BSTR | VT_BYREF: 00290 return BSTR_UserSize(pFlags, Start, V_BSTRREF(pvar)); 00291 case VT_VARIANT | VT_BYREF: 00292 return VARIANT_UserSize(pFlags, Start, V_VARIANTREF(pvar)); 00293 case VT_UNKNOWN: 00294 return Start + interface_variant_size(pFlags, &IID_IUnknown, V_UNKNOWN(pvar)); 00295 case VT_UNKNOWN | VT_BYREF: 00296 return Start + interface_variant_size(pFlags, &IID_IUnknown, *V_UNKNOWNREF(pvar)); 00297 case VT_DISPATCH: 00298 return Start + interface_variant_size(pFlags, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar)); 00299 case VT_DISPATCH | VT_BYREF: 00300 return Start + interface_variant_size(pFlags, &IID_IDispatch, (IUnknown*)*V_DISPATCHREF(pvar)); 00301 case VT_RECORD: 00302 FIXME("wire-size record\n"); 00303 return Start; 00304 case VT_SAFEARRAY: 00305 case VT_SAFEARRAY | VT_BYREF: 00306 FIXME("wire-size safearray: shouldn't be marshaling this\n"); 00307 return Start; 00308 default: 00309 return Start; 00310 } 00311 } 00312 00313 /* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer. returns Buffer on failure, new position otherwise */ 00314 static unsigned char* interface_variant_marshal(const ULONG *pFlags, unsigned char *Buffer, 00315 REFIID riid, IUnknown *punk) 00316 { 00317 IStream *working; 00318 HGLOBAL working_mem; 00319 void *working_memlocked; 00320 unsigned char *oldpos; 00321 ULONG size; 00322 HRESULT hr; 00323 00324 TRACE("pFlags=%d, Buffer=%p, pUnk=%p\n", *pFlags, Buffer, punk); 00325 00326 if(!punk) 00327 { 00328 memset(Buffer, 0, sizeof(ULONG)); 00329 return Buffer + sizeof(ULONG); 00330 } 00331 00332 oldpos = Buffer; 00333 00334 /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers. 00335 * We create a stream on an HGLOBAL, so we can simply do a memcpy to move it to the buffer. 00336 * in rpcrt4/ndr_ole.c, a simple IStream implementation is wrapped around the buffer object, 00337 * but that would be overkill here, hence this implementation. We save the size because the unmarshal 00338 * code has no way to know how long the marshalled buffer is. */ 00339 00340 size = interface_variant_size(pFlags, riid, punk); 00341 00342 working_mem = GlobalAlloc(0, size); 00343 if (!working_mem) return oldpos; 00344 00345 hr = CreateStreamOnHGlobal(working_mem, TRUE, &working); 00346 if (hr != S_OK) { 00347 GlobalFree(working_mem); 00348 return oldpos; 00349 } 00350 00351 hr = CoMarshalInterface(working, riid, punk, LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL); 00352 if (hr != S_OK) { 00353 IStream_Release(working); /* this also releases the hglobal */ 00354 return oldpos; 00355 } 00356 00357 working_memlocked = GlobalLock(working_mem); 00358 memcpy(Buffer, &size, sizeof(ULONG)); /* copy the buffersize */ 00359 memcpy(Buffer + sizeof(ULONG), working_memlocked, size - sizeof(ULONG)); 00360 GlobalUnlock(working_mem); 00361 00362 IStream_Release(working); 00363 00364 /* size includes the ULONG for the size written above */ 00365 TRACE("done, size=%d\n", size); 00366 return Buffer + size; 00367 } 00368 00369 /* helper: called for VT_DISPATCH / VT_UNKNOWN variants to unmarshal the buffer. returns Buffer on failure, new position otherwise */ 00370 static unsigned char *interface_variant_unmarshal(const ULONG *pFlags, unsigned char *Buffer, 00371 REFIID riid, IUnknown **ppunk) 00372 { 00373 IStream *working; 00374 HGLOBAL working_mem; 00375 void *working_memlocked; 00376 unsigned char *oldpos; 00377 ULONG size; 00378 HRESULT hr; 00379 00380 TRACE("pFlags=%d, Buffer=%p, ppUnk=%p\n", *pFlags, Buffer, ppunk); 00381 00382 oldpos = Buffer; 00383 00384 /* get the buffersize */ 00385 memcpy(&size, Buffer, sizeof(ULONG)); 00386 TRACE("buffersize=%d\n", size); 00387 00388 if(!size) 00389 { 00390 *ppunk = NULL; 00391 return Buffer + sizeof(ULONG); 00392 } 00393 00394 working_mem = GlobalAlloc(0, size); 00395 if (!working_mem) return oldpos; 00396 00397 hr = CreateStreamOnHGlobal(working_mem, TRUE, &working); 00398 if (hr != S_OK) { 00399 GlobalFree(working_mem); 00400 return oldpos; 00401 } 00402 00403 working_memlocked = GlobalLock(working_mem); 00404 00405 /* now we copy the contents of the marshalling buffer to working_memlocked, unlock it, and demarshal the stream */ 00406 memcpy(working_memlocked, Buffer + sizeof(ULONG), size); 00407 GlobalUnlock(working_mem); 00408 00409 hr = CoUnmarshalInterface(working, riid, (void**)ppunk); 00410 if (hr != S_OK) { 00411 IStream_Release(working); 00412 return oldpos; 00413 } 00414 00415 IStream_Release(working); /* this also frees the underlying hglobal */ 00416 00417 /* size includes the ULONG for the size written above */ 00418 TRACE("done, processed=%d bytes\n", size); 00419 return Buffer + size; 00420 } 00421 00422 00423 ULONG WINAPI VARIANT_UserSize(ULONG *pFlags, ULONG Start, VARIANT *pvar) 00424 { 00425 int align; 00426 TRACE("(%x,%d,%p)\n", *pFlags, Start, pvar); 00427 TRACE("vt=%04x\n", V_VT(pvar)); 00428 00429 ALIGN_LENGTH(Start, 7); 00430 Start += sizeof(variant_wire_t); 00431 if(V_VT(pvar) & VT_BYREF) 00432 Start += 4; 00433 00434 align = get_type_alignment(pFlags, V_VT(pvar)); 00435 ALIGN_LENGTH(Start, align); 00436 if(V_VT(pvar) == (VT_VARIANT | VT_BYREF)) 00437 Start += 4; 00438 else 00439 Start += get_type_size(pFlags, V_VT(pvar)); 00440 Start = wire_extra_user_size(pFlags, Start, pvar); 00441 00442 TRACE("returning %d\n", Start); 00443 return Start; 00444 } 00445 00446 unsigned char * WINAPI VARIANT_UserMarshal(ULONG *pFlags, unsigned char *Buffer, VARIANT *pvar) 00447 { 00448 variant_wire_t *header; 00449 ULONG type_size; 00450 int align; 00451 unsigned char *Pos; 00452 00453 TRACE("(%x,%p,%p)\n", *pFlags, Buffer, pvar); 00454 TRACE("vt=%04x\n", V_VT(pvar)); 00455 00456 ALIGN_POINTER(Buffer, 7); 00457 00458 header = (variant_wire_t *)Buffer; 00459 00460 header->clSize = 0; /* fixed up at the end */ 00461 header->rpcReserverd = 0; 00462 header->vt = pvar->n1.n2.vt; 00463 header->wReserved1 = pvar->n1.n2.wReserved1; 00464 header->wReserved2 = pvar->n1.n2.wReserved2; 00465 header->wReserved3 = pvar->n1.n2.wReserved3; 00466 header->switch_is = pvar->n1.n2.vt; 00467 if(header->switch_is & VT_ARRAY) 00468 header->switch_is &= ~VT_TYPEMASK; 00469 00470 Pos = (unsigned char*)(header + 1); 00471 type_size = get_type_size(pFlags, V_VT(pvar)); 00472 align = get_type_alignment(pFlags, V_VT(pvar)); 00473 ALIGN_POINTER(Pos, align); 00474 00475 if(header->vt & VT_BYREF) 00476 { 00477 *(DWORD *)Pos = max(type_size, 4); 00478 Pos += 4; 00479 if((header->vt & VT_TYPEMASK) != VT_VARIANT) 00480 { 00481 memcpy(Pos, pvar->n1.n2.n3.byref, type_size); 00482 Pos += type_size; 00483 } 00484 else 00485 { 00486 *(DWORD*)Pos = 'U' | 's' << 8 | 'e' << 16 | 'r' << 24; 00487 Pos += 4; 00488 } 00489 } 00490 else 00491 { 00492 if((header->vt & VT_TYPEMASK) == VT_DECIMAL) 00493 memcpy(Pos, pvar, type_size); 00494 else 00495 memcpy(Pos, &pvar->n1.n2.n3, type_size); 00496 Pos += type_size; 00497 } 00498 00499 if(header->vt & VT_ARRAY) 00500 { 00501 if(header->vt & VT_BYREF) 00502 Pos = LPSAFEARRAY_UserMarshal(pFlags, Pos, V_ARRAYREF(pvar)); 00503 else 00504 Pos = LPSAFEARRAY_UserMarshal(pFlags, Pos, &V_ARRAY(pvar)); 00505 } 00506 else 00507 { 00508 switch (header->vt) 00509 { 00510 case VT_BSTR: 00511 Pos = BSTR_UserMarshal(pFlags, Pos, &V_BSTR(pvar)); 00512 break; 00513 case VT_BSTR | VT_BYREF: 00514 Pos = BSTR_UserMarshal(pFlags, Pos, V_BSTRREF(pvar)); 00515 break; 00516 case VT_VARIANT | VT_BYREF: 00517 Pos = VARIANT_UserMarshal(pFlags, Pos, V_VARIANTREF(pvar)); 00518 break; 00519 case VT_UNKNOWN: 00520 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */ 00521 Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, V_UNKNOWN(pvar)); 00522 break; 00523 case VT_UNKNOWN | VT_BYREF: 00524 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */ 00525 Pos = interface_variant_marshal(pFlags, Pos, &IID_IUnknown, *V_UNKNOWNREF(pvar)); 00526 break; 00527 case VT_DISPATCH: 00528 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */ 00529 Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar)); 00530 break; 00531 case VT_DISPATCH | VT_BYREF: 00532 /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */ 00533 Pos = interface_variant_marshal(pFlags, Pos, &IID_IDispatch, (IUnknown*)*V_DISPATCHREF(pvar)); 00534 break; 00535 case VT_RECORD: 00536 FIXME("handle BRECORD by val\n"); 00537 break; 00538 case VT_RECORD | VT_BYREF: 00539 FIXME("handle BRECORD by ref\n"); 00540 break; 00541 } 00542 } 00543 header->clSize = ((Pos - Buffer) + 7) >> 3; 00544 TRACE("marshalled size=%d\n", header->clSize); 00545 return Pos; 00546 } 00547 00548 unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, VARIANT *pvar) 00549 { 00550 variant_wire_t *header; 00551 ULONG type_size; 00552 int align; 00553 unsigned char *Pos; 00554 00555 TRACE("(%x,%p,%p)\n", *pFlags, Buffer, pvar); 00556 00557 ALIGN_POINTER(Buffer, 7); 00558 00559 header = (variant_wire_t *)Buffer; 00560 00561 Pos = (unsigned char*)(header + 1); 00562 type_size = get_type_size(pFlags, header->vt); 00563 align = get_type_alignment(pFlags, header->vt); 00564 ALIGN_POINTER(Pos, align); 00565 00566 if(header->vt & VT_BYREF) 00567 { 00568 ULONG mem_size; 00569 Pos += 4; 00570 00571 switch (header->vt & ~VT_BYREF) 00572 { 00573 /* these types have a different memory size compared to wire size */ 00574 case VT_UNKNOWN: 00575 case VT_DISPATCH: 00576 case VT_BSTR: 00577 mem_size = sizeof(void *); 00578 break; 00579 default: 00580 mem_size = type_size; 00581 break; 00582 } 00583 00584 if (V_VT(pvar) != header->vt) 00585 { 00586 VariantClear(pvar); 00587 V_BYREF(pvar) = CoTaskMemAlloc(mem_size); 00588 } 00589 else if (!V_BYREF(pvar)) 00590 V_BYREF(pvar) = CoTaskMemAlloc(mem_size); 00591 memcpy(V_BYREF(pvar), Pos, type_size); 00592 if((header->vt & VT_TYPEMASK) != VT_VARIANT) 00593 Pos += type_size; 00594 else 00595 Pos += 4; 00596 } 00597 else 00598 { 00599 VariantClear(pvar); 00600 if((header->vt & VT_TYPEMASK) == VT_DECIMAL) 00601 memcpy(pvar, Pos, type_size); 00602 else 00603 memcpy(&pvar->n1.n2.n3, Pos, type_size); 00604 Pos += type_size; 00605 } 00606 00607 pvar->n1.n2.vt = header->vt; 00608 pvar->n1.n2.wReserved1 = header->wReserved1; 00609 pvar->n1.n2.wReserved2 = header->wReserved2; 00610 pvar->n1.n2.wReserved3 = header->wReserved3; 00611 00612 if(header->vt & VT_ARRAY) 00613 { 00614 if(header->vt & VT_BYREF) 00615 Pos = LPSAFEARRAY_UserUnmarshal(pFlags, Pos, V_ARRAYREF(pvar)); 00616 else 00617 Pos = LPSAFEARRAY_UserUnmarshal(pFlags, Pos, &V_ARRAY(pvar)); 00618 } 00619 else 00620 { 00621 switch (header->vt) 00622 { 00623 case VT_BSTR: 00624 V_BSTR(pvar) = NULL; 00625 Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar)); 00626 break; 00627 case VT_BSTR | VT_BYREF: 00628 *V_BSTRREF(pvar) = NULL; 00629 Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar)); 00630 break; 00631 case VT_VARIANT | VT_BYREF: 00632 Pos = VARIANT_UserUnmarshal(pFlags, Pos, V_VARIANTREF(pvar)); 00633 break; 00634 case VT_UNKNOWN: 00635 /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */ 00636 Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, &V_UNKNOWN(pvar)); 00637 break; 00638 case VT_UNKNOWN | VT_BYREF: 00639 /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */ 00640 Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IUnknown, V_UNKNOWNREF(pvar)); 00641 break; 00642 case VT_DISPATCH: 00643 /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */ 00644 Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, (IUnknown**)&V_DISPATCH(pvar)); 00645 break; 00646 case VT_DISPATCH | VT_BYREF: 00647 /* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */ 00648 Pos = interface_variant_unmarshal(pFlags, Pos, &IID_IDispatch, (IUnknown**)V_DISPATCHREF(pvar)); 00649 break; 00650 case VT_RECORD: 00651 FIXME("handle BRECORD by val\n"); 00652 break; 00653 case VT_RECORD | VT_BYREF: 00654 FIXME("handle BRECORD by ref\n"); 00655 break; 00656 } 00657 } 00658 return Pos; 00659 } 00660 00661 void WINAPI VARIANT_UserFree(ULONG *pFlags, VARIANT *pvar) 00662 { 00663 VARTYPE vt = V_VT(pvar); 00664 PVOID ref = NULL; 00665 00666 TRACE("(%x,%p)\n", *pFlags, pvar); 00667 TRACE("vt=%04x\n", V_VT(pvar)); 00668 00669 if (vt & VT_BYREF) ref = pvar->n1.n2.n3.byref; 00670 00671 VariantClear(pvar); 00672 if (!ref) return; 00673 00674 if(vt & VT_ARRAY) 00675 { 00676 if (vt & VT_BYREF) 00677 LPSAFEARRAY_UserFree(pFlags, V_ARRAYREF(pvar)); 00678 else 00679 LPSAFEARRAY_UserFree(pFlags, &V_ARRAY(pvar)); 00680 } 00681 else 00682 { 00683 switch (vt) 00684 { 00685 case VT_BSTR | VT_BYREF: 00686 BSTR_UserFree(pFlags, V_BSTRREF(pvar)); 00687 break; 00688 case VT_VARIANT | VT_BYREF: 00689 VARIANT_UserFree(pFlags, V_VARIANTREF(pvar)); 00690 break; 00691 case VT_RECORD | VT_BYREF: 00692 FIXME("handle BRECORD by ref\n"); 00693 break; 00694 case VT_UNKNOWN | VT_BYREF: 00695 case VT_DISPATCH | VT_BYREF: 00696 IUnknown_Release(*V_UNKNOWNREF(pvar)); 00697 break; 00698 } 00699 } 00700 00701 CoTaskMemFree(ref); 00702 } 00703 00704 /* LPSAFEARRAY */ 00705 00706 /* Get the number of cells in a SafeArray */ 00707 static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa) 00708 { 00709 const SAFEARRAYBOUND* psab = psa->rgsabound; 00710 USHORT cCount = psa->cDims; 00711 ULONG ulNumCells = 1; 00712 00713 while (cCount--) 00714 { 00715 /* This is a valid bordercase. See testcases. -Marcus */ 00716 if (!psab->cElements) 00717 return 0; 00718 ulNumCells *= psab->cElements; 00719 psab++; 00720 } 00721 return ulNumCells; 00722 } 00723 00724 static inline SF_TYPE SAFEARRAY_GetUnionType(SAFEARRAY *psa) 00725 { 00726 VARTYPE vt; 00727 HRESULT hr; 00728 00729 hr = SafeArrayGetVartype(psa, &vt); 00730 if (FAILED(hr)) 00731 { 00732 if(psa->fFeatures & FADF_VARIANT) return SF_VARIANT; 00733 00734 switch(psa->cbElements) 00735 { 00736 case 1: vt = VT_I1; break; 00737 case 2: vt = VT_I2; break; 00738 case 4: vt = VT_I4; break; 00739 case 8: vt = VT_I8; break; 00740 default: 00741 RpcRaiseException(hr); 00742 } 00743 } 00744 00745 if (psa->fFeatures & FADF_HAVEIID) 00746 return SF_HAVEIID; 00747 00748 switch (vt) 00749 { 00750 case VT_I1: 00751 case VT_UI1: return SF_I1; 00752 case VT_BOOL: 00753 case VT_I2: 00754 case VT_UI2: return SF_I2; 00755 case VT_INT: 00756 case VT_UINT: 00757 case VT_I4: 00758 case VT_UI4: 00759 case VT_R4: return SF_I4; 00760 case VT_DATE: 00761 case VT_CY: 00762 case VT_R8: 00763 case VT_I8: 00764 case VT_UI8: return SF_I8; 00765 case VT_INT_PTR: 00766 case VT_UINT_PTR: return (sizeof(UINT_PTR) == 4 ? SF_I4 : SF_I8); 00767 case VT_BSTR: return SF_BSTR; 00768 case VT_DISPATCH: return SF_DISPATCH; 00769 case VT_VARIANT: return SF_VARIANT; 00770 case VT_UNKNOWN: return SF_UNKNOWN; 00771 /* Note: Return a non-zero size to indicate vt is valid. The actual size 00772 * of a UDT is taken from the result of IRecordInfo_GetSize(). 00773 */ 00774 case VT_RECORD: return SF_RECORD; 00775 default: return SF_ERROR; 00776 } 00777 } 00778 00779 static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype) 00780 { 00781 if (sftype == SF_BSTR) 00782 return sizeof(DWORD); 00783 else if (sftype == SF_VARIANT) 00784 return sizeof(variant_wire_t) - sizeof(DWORD); 00785 else 00786 return lpsa->cbElements; 00787 } 00788 00789 static DWORD elem_mem_size(wireSAFEARRAY wiresa, SF_TYPE sftype) 00790 { 00791 if (sftype == SF_BSTR) 00792 return sizeof(BSTR); 00793 else if (sftype == SF_VARIANT) 00794 return sizeof(VARIANT); 00795 else 00796 return wiresa->cbElements; 00797 } 00798 00799 ULONG WINAPI LPSAFEARRAY_UserSize(ULONG *pFlags, ULONG StartingSize, LPSAFEARRAY *ppsa) 00800 { 00801 ULONG size = StartingSize; 00802 00803 TRACE("("); dump_user_flags(pFlags); TRACE(", %d, %p\n", StartingSize, *ppsa); 00804 00805 ALIGN_LENGTH(size, 3); 00806 size += sizeof(ULONG); 00807 if (*ppsa) 00808 { 00809 SAFEARRAY *psa = *ppsa; 00810 ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); 00811 SF_TYPE sftype; 00812 HRESULT hr; 00813 00814 size += sizeof(ULONG); 00815 size += 2 * sizeof(USHORT) + 2 * sizeof(ULONG); 00816 00817 sftype = SAFEARRAY_GetUnionType(psa); 00818 size += sizeof(ULONG); 00819 00820 size += sizeof(ULONG); 00821 size += sizeof(ULONG); 00822 if (sftype == SF_HAVEIID) 00823 size += sizeof(IID); 00824 00825 size += sizeof(psa->rgsabound[0]) * psa->cDims; 00826 00827 size += sizeof(ULONG); 00828 00829 switch (sftype) 00830 { 00831 case SF_BSTR: 00832 { 00833 BSTR* lpBstr; 00834 00835 for (lpBstr = psa->pvData; ulCellCount; ulCellCount--, lpBstr++) 00836 size = BSTR_UserSize(pFlags, size, lpBstr); 00837 00838 break; 00839 } 00840 case SF_DISPATCH: 00841 case SF_UNKNOWN: 00842 case SF_HAVEIID: 00843 FIXME("size interfaces\n"); 00844 break; 00845 case SF_VARIANT: 00846 { 00847 VARIANT* lpVariant; 00848 00849 for (lpVariant = psa->pvData; ulCellCount; ulCellCount--, lpVariant++) 00850 size = VARIANT_UserSize(pFlags, size, lpVariant); 00851 00852 break; 00853 } 00854 case SF_RECORD: 00855 { 00856 IRecordInfo* pRecInfo = NULL; 00857 00858 hr = SafeArrayGetRecordInfo(psa, &pRecInfo); 00859 if (FAILED(hr)) 00860 RpcRaiseException(hr); 00861 00862 if (pRecInfo) 00863 { 00864 FIXME("size record info %p\n", pRecInfo); 00865 00866 IRecordInfo_Release(pRecInfo); 00867 } 00868 break; 00869 } 00870 case SF_I8: 00871 ALIGN_LENGTH(size, 7); 00872 /* fallthrough */ 00873 case SF_I1: 00874 case SF_I2: 00875 case SF_I4: 00876 size += ulCellCount * psa->cbElements; 00877 break; 00878 default: 00879 break; 00880 } 00881 00882 } 00883 00884 return size; 00885 } 00886 00887 unsigned char * WINAPI LPSAFEARRAY_UserMarshal(ULONG *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa) 00888 { 00889 HRESULT hr; 00890 00891 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", Buffer, *ppsa); 00892 00893 ALIGN_POINTER(Buffer, 3); 00894 *(ULONG *)Buffer = *ppsa ? 0x1 : 0x0; 00895 Buffer += sizeof(ULONG); 00896 if (*ppsa) 00897 { 00898 VARTYPE vt; 00899 SAFEARRAY *psa = *ppsa; 00900 ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); 00901 SF_TYPE sftype; 00902 GUID guid; 00903 00904 sftype = SAFEARRAY_GetUnionType(psa); 00905 00906 *(ULONG *)Buffer = psa->cDims; 00907 Buffer += sizeof(ULONG); 00908 *(USHORT *)Buffer = psa->cDims; 00909 Buffer += sizeof(USHORT); 00910 *(USHORT *)Buffer = psa->fFeatures; 00911 Buffer += sizeof(USHORT); 00912 *(ULONG *)Buffer = elem_wire_size(psa, sftype); 00913 Buffer += sizeof(ULONG); 00914 00915 hr = SafeArrayGetVartype(psa, &vt); 00916 if (FAILED(hr)) vt = 0; 00917 00918 *(ULONG *)Buffer = (USHORT)psa->cLocks | (vt << 16); 00919 Buffer += sizeof(ULONG); 00920 00921 *(ULONG *)Buffer = sftype; 00922 Buffer += sizeof(ULONG); 00923 00924 *(ULONG *)Buffer = ulCellCount; 00925 Buffer += sizeof(ULONG); 00926 *(ULONG *)Buffer = psa->pvData ? 0x2 : 0x0; 00927 Buffer += sizeof(ULONG); 00928 if (sftype == SF_HAVEIID) 00929 { 00930 SafeArrayGetIID(psa, &guid); 00931 memcpy(Buffer, &guid, sizeof(guid)); 00932 Buffer += sizeof(guid); 00933 } 00934 00935 memcpy(Buffer, psa->rgsabound, sizeof(psa->rgsabound[0]) * psa->cDims); 00936 Buffer += sizeof(psa->rgsabound[0]) * psa->cDims; 00937 00938 *(ULONG *)Buffer = ulCellCount; 00939 Buffer += sizeof(ULONG); 00940 00941 if (psa->pvData) 00942 { 00943 switch (sftype) 00944 { 00945 case SF_BSTR: 00946 { 00947 BSTR* lpBstr; 00948 00949 for (lpBstr = psa->pvData; ulCellCount; ulCellCount--, lpBstr++) 00950 Buffer = BSTR_UserMarshal(pFlags, Buffer, lpBstr); 00951 00952 break; 00953 } 00954 case SF_DISPATCH: 00955 case SF_UNKNOWN: 00956 case SF_HAVEIID: 00957 FIXME("marshal interfaces\n"); 00958 break; 00959 case SF_VARIANT: 00960 { 00961 VARIANT* lpVariant; 00962 00963 for (lpVariant = psa->pvData; ulCellCount; ulCellCount--, lpVariant++) 00964 Buffer = VARIANT_UserMarshal(pFlags, Buffer, lpVariant); 00965 00966 break; 00967 } 00968 case SF_RECORD: 00969 { 00970 IRecordInfo* pRecInfo = NULL; 00971 00972 hr = SafeArrayGetRecordInfo(psa, &pRecInfo); 00973 if (FAILED(hr)) 00974 RpcRaiseException(hr); 00975 00976 if (pRecInfo) 00977 { 00978 FIXME("write record info %p\n", pRecInfo); 00979 00980 IRecordInfo_Release(pRecInfo); 00981 } 00982 break; 00983 } 00984 00985 case SF_I8: 00986 ALIGN_POINTER(Buffer, 7); 00987 /* fallthrough */ 00988 case SF_I1: 00989 case SF_I2: 00990 case SF_I4: 00991 /* Just copy the data over */ 00992 memcpy(Buffer, psa->pvData, ulCellCount * psa->cbElements); 00993 Buffer += ulCellCount * psa->cbElements; 00994 break; 00995 default: 00996 break; 00997 } 00998 } 00999 01000 } 01001 return Buffer; 01002 } 01003 01004 #define FADF_AUTOSETFLAGS (FADF_HAVEIID | FADF_RECORD | FADF_HAVEVARTYPE | \ 01005 FADF_BSTR | FADF_UNKNOWN | FADF_DISPATCH | \ 01006 FADF_VARIANT | FADF_CREATEVECTOR) 01007 01008 unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa) 01009 { 01010 ULONG ptr; 01011 wireSAFEARRAY wiresa; 01012 ULONG cDims; 01013 HRESULT hr; 01014 SF_TYPE sftype; 01015 ULONG cell_count; 01016 GUID guid; 01017 VARTYPE vt; 01018 SAFEARRAYBOUND *wiresab; 01019 01020 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", Buffer, ppsa); 01021 01022 ALIGN_POINTER(Buffer, 3); 01023 ptr = *(ULONG *)Buffer; 01024 Buffer += sizeof(ULONG); 01025 01026 if (!ptr) 01027 { 01028 *ppsa = NULL; 01029 01030 TRACE("NULL safe array unmarshaled\n"); 01031 01032 return Buffer; 01033 } 01034 01035 cDims = *(ULONG *)Buffer; 01036 Buffer += sizeof(ULONG); 01037 01038 wiresa = (wireSAFEARRAY)Buffer; 01039 Buffer += 2 * sizeof(USHORT) + 2 * sizeof(ULONG); 01040 01041 if (cDims != wiresa->cDims) 01042 RpcRaiseException(RPC_S_INVALID_BOUND); 01043 01044 /* FIXME: there should be a limit on how large cDims can be */ 01045 01046 vt = HIWORD(wiresa->cLocks); 01047 01048 sftype = *(ULONG *)Buffer; 01049 Buffer += sizeof(ULONG); 01050 01051 cell_count = *(ULONG *)Buffer; 01052 Buffer += sizeof(ULONG); 01053 ptr = *(ULONG *)Buffer; 01054 Buffer += sizeof(ULONG); 01055 if (sftype == SF_HAVEIID) 01056 { 01057 memcpy(&guid, Buffer, sizeof(guid)); 01058 Buffer += sizeof(guid); 01059 } 01060 01061 wiresab = (SAFEARRAYBOUND *)Buffer; 01062 Buffer += sizeof(wiresab[0]) * wiresa->cDims; 01063 01064 if(vt) 01065 *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL); 01066 else 01067 { 01068 SafeArrayAllocDescriptor(wiresa->cDims, ppsa); 01069 if(*ppsa) 01070 memcpy((*ppsa)->rgsabound, wiresab, sizeof(SAFEARRAYBOUND) * wiresa->cDims); 01071 } 01072 if (!*ppsa) 01073 RpcRaiseException(E_OUTOFMEMORY); 01074 01075 /* be careful about which flags we set since they could be a security 01076 * risk */ 01077 (*ppsa)->fFeatures &= FADF_AUTOSETFLAGS; 01078 (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS)); 01079 /* FIXME: there should be a limit on how large wiresa->cbElements can be */ 01080 (*ppsa)->cbElements = elem_mem_size(wiresa, sftype); 01081 (*ppsa)->cLocks = LOWORD(wiresa->cLocks); 01082 01083 /* SafeArrayCreateEx allocates the data for us, but 01084 * SafeArrayAllocDescriptor doesn't */ 01085 if(!vt) 01086 { 01087 hr = SafeArrayAllocData(*ppsa); 01088 if (FAILED(hr)) 01089 RpcRaiseException(hr); 01090 } 01091 01092 if ((*(ULONG *)Buffer != cell_count) || (SAFEARRAY_GetCellCount(*ppsa) != cell_count)) 01093 RpcRaiseException(RPC_S_INVALID_BOUND); 01094 Buffer += sizeof(ULONG); 01095 01096 if (ptr) 01097 { 01098 switch (sftype) 01099 { 01100 case SF_BSTR: 01101 { 01102 BSTR* lpBstr; 01103 01104 for (lpBstr = (*ppsa)->pvData; cell_count; cell_count--, lpBstr++) 01105 Buffer = BSTR_UserUnmarshal(pFlags, Buffer, lpBstr); 01106 01107 break; 01108 } 01109 case SF_DISPATCH: 01110 case SF_UNKNOWN: 01111 case SF_HAVEIID: 01112 FIXME("marshal interfaces\n"); 01113 break; 01114 case SF_VARIANT: 01115 { 01116 VARIANT* lpVariant; 01117 01118 for (lpVariant = (*ppsa)->pvData; cell_count; cell_count--, lpVariant++) 01119 Buffer = VARIANT_UserUnmarshal(pFlags, Buffer, lpVariant); 01120 01121 break; 01122 } 01123 case SF_RECORD: 01124 { 01125 FIXME("set record info\n"); 01126 01127 break; 01128 } 01129 01130 case SF_I8: 01131 ALIGN_POINTER(Buffer, 7); 01132 /* fallthrough */ 01133 case SF_I1: 01134 case SF_I2: 01135 case SF_I4: 01136 /* Just copy the data over */ 01137 memcpy((*ppsa)->pvData, Buffer, cell_count * (*ppsa)->cbElements); 01138 Buffer += cell_count * (*ppsa)->cbElements; 01139 break; 01140 default: 01141 break; 01142 } 01143 } 01144 01145 TRACE("safe array unmarshaled: %p\n", *ppsa); 01146 01147 return Buffer; 01148 } 01149 01150 void WINAPI LPSAFEARRAY_UserFree(ULONG *pFlags, LPSAFEARRAY *ppsa) 01151 { 01152 TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *ppsa); 01153 01154 SafeArrayDestroy(*ppsa); 01155 } 01156 01157 01158 ULONG WINAPI HFONT_UserSize(ULONG *pFlags, ULONG Start, HFONT *phfont) 01159 { 01160 FIXME(":stub\n"); 01161 return 0; 01162 } 01163 01164 unsigned char * WINAPI HFONT_UserMarshal(ULONG *pFlags, unsigned char *Buffer, HFONT *phfont) 01165 { 01166 FIXME(":stub\n"); 01167 return NULL; 01168 } 01169 01170 unsigned char * WINAPI HFONT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffer, HFONT *phfont) 01171 { 01172 FIXME(":stub\n"); 01173 return NULL; 01174 } 01175 01176 void WINAPI HFONT_UserFree(ULONG *pFlags, HFONT *phfont) 01177 { 01178 FIXME(":stub\n"); 01179 return; 01180 } 01181 01182 01183 /* IDispatch */ 01184 /* exactly how Invoke is marshalled is not very clear to me yet, 01185 * but the way I've done it seems to work for me */ 01186 01187 HRESULT CALLBACK IDispatch_Invoke_Proxy( 01188 IDispatch* This, 01189 DISPID dispIdMember, 01190 REFIID riid, 01191 LCID lcid, 01192 WORD wFlags, 01193 DISPPARAMS* pDispParams, 01194 VARIANT* pVarResult, 01195 EXCEPINFO* pExcepInfo, 01196 UINT* puArgErr) 01197 { 01198 HRESULT hr; 01199 VARIANT VarResult; 01200 UINT* rgVarRefIdx = NULL; 01201 VARIANTARG* rgVarRef = NULL; 01202 UINT u, cVarRef; 01203 UINT uArgErr; 01204 EXCEPINFO ExcepInfo; 01205 01206 TRACE("(%p)->(%d,%s,%x,%x,%p,%p,%p,%p)\n", This, 01207 dispIdMember, debugstr_guid(riid), 01208 lcid, wFlags, pDispParams, pVarResult, 01209 pExcepInfo, puArgErr); 01210 01211 /* [out] args can't be null, use dummy vars if needed */ 01212 if (!pVarResult) pVarResult = &VarResult; 01213 if (!puArgErr) puArgErr = &uArgErr; 01214 if (!pExcepInfo) pExcepInfo = &ExcepInfo; 01215 01216 /* count by-ref args */ 01217 for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) { 01218 VARIANTARG* arg = &pDispParams->rgvarg[u]; 01219 if (V_ISBYREF(arg)) { 01220 cVarRef++; 01221 } 01222 } 01223 if (cVarRef) { 01224 rgVarRefIdx = CoTaskMemAlloc(sizeof(UINT)*cVarRef); 01225 rgVarRef = CoTaskMemAlloc(sizeof(VARIANTARG)*cVarRef); 01226 /* make list of by-ref args */ 01227 for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) { 01228 VARIANTARG* arg = &pDispParams->rgvarg[u]; 01229 if (V_ISBYREF(arg)) { 01230 rgVarRefIdx[cVarRef] = u; 01231 VariantInit(&rgVarRef[cVarRef]); 01232 VariantCopy(&rgVarRef[cVarRef], arg); 01233 VariantClear(arg); 01234 cVarRef++; 01235 } 01236 } 01237 } else { 01238 /* [out] args still can't be null, 01239 * but we can point these anywhere in this case, 01240 * since they won't be written to when cVarRef is 0 */ 01241 rgVarRefIdx = puArgErr; 01242 rgVarRef = pVarResult; 01243 } 01244 TRACE("passed by ref: %d args\n", cVarRef); 01245 hr = IDispatch_RemoteInvoke_Proxy(This, 01246 dispIdMember, 01247 riid, 01248 lcid, 01249 wFlags, 01250 pDispParams, 01251 pVarResult, 01252 pExcepInfo, 01253 puArgErr, 01254 cVarRef, 01255 rgVarRefIdx, 01256 rgVarRef); 01257 if (cVarRef) { 01258 for (u=0; u<cVarRef; u++) { 01259 unsigned i = rgVarRefIdx[u]; 01260 VariantCopy(&pDispParams->rgvarg[i], 01261 &rgVarRef[u]); 01262 VariantClear(&rgVarRef[u]); 01263 } 01264 CoTaskMemFree(rgVarRef); 01265 CoTaskMemFree(rgVarRefIdx); 01266 } 01267 01268 if(pExcepInfo == &ExcepInfo) 01269 { 01270 SysFreeString(pExcepInfo->bstrSource); 01271 SysFreeString(pExcepInfo->bstrDescription); 01272 SysFreeString(pExcepInfo->bstrHelpFile); 01273 } 01274 return hr; 01275 } 01276 01277 HRESULT __RPC_STUB IDispatch_Invoke_Stub( 01278 IDispatch* This, 01279 DISPID dispIdMember, 01280 REFIID riid, 01281 LCID lcid, 01282 DWORD dwFlags, 01283 DISPPARAMS* pDispParams, 01284 VARIANT* pVarResult, 01285 EXCEPINFO* pExcepInfo, 01286 UINT* pArgErr, 01287 UINT cVarRef, 01288 UINT* rgVarRefIdx, 01289 VARIANTARG* rgVarRef) 01290 { 01291 HRESULT hr = S_OK; 01292 VARIANTARG *rgvarg, *arg; 01293 UINT u; 01294 01295 /* initialize out parameters, so that they can be marshalled 01296 * in case the real Invoke doesn't initialize them */ 01297 VariantInit(pVarResult); 01298 memset(pExcepInfo, 0, sizeof(*pExcepInfo)); 01299 *pArgErr = 0; 01300 01301 /* let the real Invoke operate on a copy of the in parameters, 01302 * so we don't risk losing pointers to allocated memory */ 01303 rgvarg = pDispParams->rgvarg; 01304 arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs); 01305 if (!arg) return E_OUTOFMEMORY; 01306 01307 /* init all args so we can call VariantClear on all the args if the copy 01308 * below fails */ 01309 for (u = 0; u < pDispParams->cArgs; u++) 01310 VariantInit(&arg[u]); 01311 01312 for (u = 0; u < pDispParams->cArgs; u++) { 01313 hr = VariantCopy(&arg[u], &rgvarg[u]); 01314 if (FAILED(hr)) 01315 break; 01316 } 01317 01318 if (SUCCEEDED(hr)) { 01319 /* copy ref args to arg array */ 01320 for (u=0; u<cVarRef; u++) { 01321 unsigned i = rgVarRefIdx[u]; 01322 VariantCopy(&arg[i], &rgVarRef[u]); 01323 } 01324 01325 pDispParams->rgvarg = arg; 01326 01327 hr = IDispatch_Invoke(This, 01328 dispIdMember, 01329 riid, 01330 lcid, 01331 dwFlags, 01332 pDispParams, 01333 pVarResult, 01334 pExcepInfo, 01335 pArgErr); 01336 01337 /* copy ref args from arg array */ 01338 for (u=0; u<cVarRef; u++) { 01339 unsigned i = rgVarRefIdx[u]; 01340 VariantCopy(&rgVarRef[u], &arg[i]); 01341 } 01342 } 01343 01344 /* clear the duplicate argument list */ 01345 for (u=0; u<pDispParams->cArgs; u++) 01346 VariantClear(&arg[u]); 01347 01348 pDispParams->rgvarg = rgvarg; 01349 CoTaskMemFree(arg); 01350 01351 return hr; 01352 } 01353 01354 /* IEnumVARIANT */ 01355 01356 HRESULT CALLBACK IEnumVARIANT_Next_Proxy( 01357 IEnumVARIANT* This, 01358 ULONG celt, 01359 VARIANT* rgVar, 01360 ULONG* pCeltFetched) 01361 { 01362 ULONG fetched; 01363 if (!pCeltFetched) 01364 pCeltFetched = &fetched; 01365 return IEnumVARIANT_RemoteNext_Proxy(This, 01366 celt, 01367 rgVar, 01368 pCeltFetched); 01369 } 01370 01371 HRESULT __RPC_STUB IEnumVARIANT_Next_Stub( 01372 IEnumVARIANT* This, 01373 ULONG celt, 01374 VARIANT* rgVar, 01375 ULONG* pCeltFetched) 01376 { 01377 HRESULT hr; 01378 *pCeltFetched = 0; 01379 hr = IEnumVARIANT_Next(This, 01380 celt, 01381 rgVar, 01382 pCeltFetched); 01383 if (hr == S_OK) *pCeltFetched = celt; 01384 return hr; 01385 } 01386 01387 /* TypeInfo related freers */ 01388 01389 static void free_embedded_typedesc(TYPEDESC *tdesc); 01390 static void free_embedded_arraydesc(ARRAYDESC *adesc) 01391 { 01392 switch(adesc->tdescElem.vt) 01393 { 01394 case VT_PTR: 01395 case VT_SAFEARRAY: 01396 free_embedded_typedesc(adesc->tdescElem.u.lptdesc); 01397 CoTaskMemFree(adesc->tdescElem.u.lptdesc); 01398 break; 01399 case VT_CARRAY: 01400 free_embedded_arraydesc(adesc->tdescElem.u.lpadesc); 01401 CoTaskMemFree(adesc->tdescElem.u.lpadesc); 01402 break; 01403 } 01404 } 01405 01406 static void free_embedded_typedesc(TYPEDESC *tdesc) 01407 { 01408 switch(tdesc->vt) 01409 { 01410 case VT_PTR: 01411 case VT_SAFEARRAY: 01412 free_embedded_typedesc(tdesc->u.lptdesc); 01413 CoTaskMemFree(tdesc->u.lptdesc); 01414 break; 01415 case VT_CARRAY: 01416 free_embedded_arraydesc(tdesc->u.lpadesc); 01417 CoTaskMemFree(tdesc->u.lpadesc); 01418 break; 01419 } 01420 } 01421 01422 static void free_embedded_elemdesc(ELEMDESC *edesc) 01423 { 01424 free_embedded_typedesc(&edesc->tdesc); 01425 if(edesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) 01426 CoTaskMemFree(edesc->u.paramdesc.pparamdescex); 01427 } 01428 01429 /* ITypeComp */ 01430 01431 HRESULT CALLBACK ITypeComp_Bind_Proxy( 01432 ITypeComp* This, 01433 LPOLESTR szName, 01434 ULONG lHashVal, 01435 WORD wFlags, 01436 ITypeInfo** ppTInfo, 01437 DESCKIND* pDescKind, 01438 BINDPTR* pBindPtr) 01439 { 01440 FIXME("not implemented\n"); 01441 return E_FAIL; 01442 } 01443 01444 HRESULT __RPC_STUB ITypeComp_Bind_Stub( 01445 ITypeComp* This, 01446 LPOLESTR szName, 01447 ULONG lHashVal, 01448 WORD wFlags, 01449 ITypeInfo** ppTInfo, 01450 DESCKIND* pDescKind, 01451 LPFUNCDESC* ppFuncDesc, 01452 LPVARDESC* ppVarDesc, 01453 ITypeComp** ppTypeComp, 01454 CLEANLOCALSTORAGE* pDummy) 01455 { 01456 FIXME("not implemented\n"); 01457 return E_FAIL; 01458 } 01459 01460 HRESULT CALLBACK ITypeComp_BindType_Proxy( 01461 ITypeComp* This, 01462 LPOLESTR szName, 01463 ULONG lHashVal, 01464 ITypeInfo** ppTInfo, 01465 ITypeComp** ppTComp) 01466 { 01467 FIXME("not implemented\n"); 01468 return E_FAIL; 01469 } 01470 01471 HRESULT __RPC_STUB ITypeComp_BindType_Stub( 01472 ITypeComp* This, 01473 LPOLESTR szName, 01474 ULONG lHashVal, 01475 ITypeInfo** ppTInfo) 01476 { 01477 FIXME("not implemented\n"); 01478 return E_FAIL; 01479 } 01480 01481 /* ITypeInfo */ 01482 01483 HRESULT CALLBACK ITypeInfo_GetTypeAttr_Proxy( 01484 ITypeInfo* This, 01485 TYPEATTR** ppTypeAttr) 01486 01487 { 01488 CLEANLOCALSTORAGE stg; 01489 TRACE("(%p, %p)\n", This, ppTypeAttr); 01490 01491 stg.flags = 0; 01492 stg.pStorage = NULL; 01493 stg.pInterface = NULL; 01494 01495 return ITypeInfo_RemoteGetTypeAttr_Proxy(This, ppTypeAttr, &stg); 01496 } 01497 01498 HRESULT __RPC_STUB ITypeInfo_GetTypeAttr_Stub( 01499 ITypeInfo* This, 01500 LPTYPEATTR* ppTypeAttr, 01501 CLEANLOCALSTORAGE* pDummy) 01502 { 01503 HRESULT hr; 01504 TRACE("(%p, %p)\n", This, ppTypeAttr); 01505 01506 hr = ITypeInfo_GetTypeAttr(This, ppTypeAttr); 01507 if(hr != S_OK) 01508 return hr; 01509 01510 pDummy->flags = CLS_TYPEATTR; 01511 ITypeInfo_AddRef(This); 01512 pDummy->pInterface = (IUnknown*)This; 01513 pDummy->pStorage = ppTypeAttr; 01514 return hr; 01515 } 01516 01517 HRESULT CALLBACK ITypeInfo_GetFuncDesc_Proxy( 01518 ITypeInfo* This, 01519 UINT index, 01520 FUNCDESC** ppFuncDesc) 01521 { 01522 CLEANLOCALSTORAGE stg; 01523 TRACE("(%p, %d, %p)\n", This, index, ppFuncDesc); 01524 01525 stg.flags = 0; 01526 stg.pStorage = NULL; 01527 stg.pInterface = NULL; 01528 01529 return ITypeInfo_RemoteGetFuncDesc_Proxy(This, index, ppFuncDesc, &stg); 01530 } 01531 01532 HRESULT __RPC_STUB ITypeInfo_GetFuncDesc_Stub( 01533 ITypeInfo* This, 01534 UINT index, 01535 LPFUNCDESC* ppFuncDesc, 01536 CLEANLOCALSTORAGE* pDummy) 01537 { 01538 HRESULT hr; 01539 TRACE("(%p, %d, %p)\n", This, index, ppFuncDesc); 01540 01541 hr = ITypeInfo_GetFuncDesc(This, index, ppFuncDesc); 01542 if(hr != S_OK) 01543 return hr; 01544 01545 pDummy->flags = CLS_FUNCDESC; 01546 ITypeInfo_AddRef(This); 01547 pDummy->pInterface = (IUnknown*)This; 01548 pDummy->pStorage = ppFuncDesc; 01549 return hr; 01550 } 01551 01552 HRESULT CALLBACK ITypeInfo_GetVarDesc_Proxy( 01553 ITypeInfo* This, 01554 UINT index, 01555 VARDESC** ppVarDesc) 01556 { 01557 CLEANLOCALSTORAGE stg; 01558 TRACE("(%p, %d, %p)\n", This, index, ppVarDesc); 01559 01560 stg.flags = 0; 01561 stg.pStorage = NULL; 01562 stg.pInterface = NULL; 01563 01564 return ITypeInfo_RemoteGetVarDesc_Proxy(This, index, ppVarDesc, &stg); 01565 } 01566 01567 HRESULT __RPC_STUB ITypeInfo_GetVarDesc_Stub( 01568 ITypeInfo* This, 01569 UINT index, 01570 LPVARDESC* ppVarDesc, 01571 CLEANLOCALSTORAGE* pDummy) 01572 { 01573 HRESULT hr; 01574 TRACE("(%p, %d, %p)\n", This, index, ppVarDesc); 01575 01576 hr = ITypeInfo_GetVarDesc(This, index, ppVarDesc); 01577 if(hr != S_OK) 01578 return hr; 01579 01580 pDummy->flags = CLS_VARDESC; 01581 ITypeInfo_AddRef(This); 01582 pDummy->pInterface = (IUnknown*)This; 01583 pDummy->pStorage = ppVarDesc; 01584 return hr; 01585 } 01586 01587 HRESULT CALLBACK ITypeInfo_GetNames_Proxy( 01588 ITypeInfo* This, 01589 MEMBERID memid, 01590 BSTR* rgBstrNames, 01591 UINT cMaxNames, 01592 UINT* pcNames) 01593 { 01594 FIXME("not implemented\n"); 01595 return E_FAIL; 01596 } 01597 01598 HRESULT __RPC_STUB ITypeInfo_GetNames_Stub( 01599 ITypeInfo* This, 01600 MEMBERID memid, 01601 BSTR* rgBstrNames, 01602 UINT cMaxNames, 01603 UINT* pcNames) 01604 { 01605 FIXME("not implemented\n"); 01606 return E_FAIL; 01607 } 01608 01609 HRESULT CALLBACK ITypeInfo_GetIDsOfNames_Proxy( 01610 ITypeInfo* This, 01611 LPOLESTR* rgszNames, 01612 UINT cNames, 01613 MEMBERID* pMemId) 01614 { 01615 FIXME("not implemented\n"); 01616 return E_FAIL; 01617 } 01618 01619 HRESULT __RPC_STUB ITypeInfo_GetIDsOfNames_Stub( 01620 ITypeInfo* This) 01621 { 01622 FIXME("not implemented\n"); 01623 return E_FAIL; 01624 } 01625 01626 HRESULT CALLBACK ITypeInfo_Invoke_Proxy( 01627 ITypeInfo* This, 01628 PVOID pvInstance, 01629 MEMBERID memid, 01630 WORD wFlags, 01631 DISPPARAMS* pDispParams, 01632 VARIANT* pVarResult, 01633 EXCEPINFO* pExcepInfo, 01634 UINT* puArgErr) 01635 { 01636 FIXME("not implemented\n"); 01637 return E_FAIL; 01638 } 01639 01640 HRESULT __RPC_STUB ITypeInfo_Invoke_Stub( 01641 ITypeInfo* This) 01642 { 01643 FIXME("not implemented\n"); 01644 return E_FAIL; 01645 } 01646 01647 HRESULT CALLBACK ITypeInfo_GetDocumentation_Proxy( 01648 ITypeInfo* This, 01649 MEMBERID memid, 01650 BSTR* pBstrName, 01651 BSTR* pBstrDocString, 01652 DWORD* pdwHelpContext, 01653 BSTR* pBstrHelpFile) 01654 { 01655 DWORD help_context; 01656 BSTR name, doc_string, help_file; 01657 HRESULT hr; 01658 TRACE("(%p, %08x, %p, %p, %p, %p)\n", This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); 01659 01660 /* FIXME: presumably refPtrFlags is supposed to be a bitmask of which ptrs we actually want? */ 01661 hr = ITypeInfo_RemoteGetDocumentation_Proxy(This, memid, 0, &name, &doc_string, &help_context, &help_file); 01662 if(SUCCEEDED(hr)) 01663 { 01664 if(pBstrName) *pBstrName = name; 01665 else SysFreeString(name); 01666 01667 if(pBstrDocString) *pBstrDocString = doc_string; 01668 else SysFreeString(doc_string); 01669 01670 if(pBstrHelpFile) *pBstrHelpFile = help_file; 01671 else SysFreeString(help_file); 01672 01673 if(pdwHelpContext) *pdwHelpContext = help_context; 01674 } 01675 return hr; 01676 } 01677 01678 HRESULT __RPC_STUB ITypeInfo_GetDocumentation_Stub( 01679 ITypeInfo* This, 01680 MEMBERID memid, 01681 DWORD refPtrFlags, 01682 BSTR* pBstrName, 01683 BSTR* pBstrDocString, 01684 DWORD* pdwHelpContext, 01685 BSTR* pBstrHelpFile) 01686 { 01687 TRACE("(%p, %08x, %08x, %p, %p, %p, %p)\n", This, memid, refPtrFlags, pBstrName, pBstrDocString, 01688 pdwHelpContext, pBstrHelpFile); 01689 return ITypeInfo_GetDocumentation(This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); 01690 } 01691 01692 HRESULT CALLBACK ITypeInfo_GetDllEntry_Proxy( 01693 ITypeInfo* This, 01694 MEMBERID memid, 01695 INVOKEKIND invKind, 01696 BSTR* pBstrDllName, 01697 BSTR* pBstrName, 01698 WORD* pwOrdinal) 01699 { 01700 FIXME("not implemented\n"); 01701 return E_FAIL; 01702 } 01703 01704 HRESULT __RPC_STUB ITypeInfo_GetDllEntry_Stub( 01705 ITypeInfo* This, 01706 MEMBERID memid, 01707 INVOKEKIND invKind, 01708 DWORD refPtrFlags, 01709 BSTR* pBstrDllName, 01710 BSTR* pBstrName, 01711 WORD* pwOrdinal) 01712 { 01713 FIXME("not implemented\n"); 01714 return E_FAIL; 01715 } 01716 01717 HRESULT CALLBACK ITypeInfo_AddressOfMember_Proxy( 01718 ITypeInfo* This, 01719 MEMBERID memid, 01720 INVOKEKIND invKind, 01721 PVOID* ppv) 01722 { 01723 FIXME("not implemented\n"); 01724 return E_FAIL; 01725 } 01726 01727 HRESULT __RPC_STUB ITypeInfo_AddressOfMember_Stub( 01728 ITypeInfo* This) 01729 { 01730 FIXME("not implemented\n"); 01731 return E_FAIL; 01732 } 01733 01734 HRESULT CALLBACK ITypeInfo_CreateInstance_Proxy( 01735 ITypeInfo* This, 01736 IUnknown* pUnkOuter, 01737 REFIID riid, 01738 PVOID* ppvObj) 01739 { 01740 FIXME("not implemented\n"); 01741 return E_FAIL; 01742 } 01743 01744 HRESULT __RPC_STUB ITypeInfo_CreateInstance_Stub( 01745 ITypeInfo* This, 01746 REFIID riid, 01747 IUnknown** ppvObj) 01748 { 01749 FIXME("not implemented\n"); 01750 return E_FAIL; 01751 } 01752 01753 HRESULT CALLBACK ITypeInfo_GetContainingTypeLib_Proxy( 01754 ITypeInfo* This, 01755 ITypeLib** ppTLib, 01756 UINT* pIndex) 01757 { 01758 ITypeLib *pTL; 01759 UINT index; 01760 HRESULT hr; 01761 01762 TRACE("(%p, %p, %p)\n", This, ppTLib, pIndex ); 01763 01764 hr = ITypeInfo_RemoteGetContainingTypeLib_Proxy(This, &pTL, &index); 01765 if(SUCCEEDED(hr)) 01766 { 01767 if(pIndex) 01768 *pIndex = index; 01769 01770 if(ppTLib) 01771 *ppTLib = pTL; 01772 else 01773 ITypeLib_Release(pTL); 01774 } 01775 return hr; 01776 } 01777 01778 HRESULT __RPC_STUB ITypeInfo_GetContainingTypeLib_Stub( 01779 ITypeInfo* This, 01780 ITypeLib** ppTLib, 01781 UINT* pIndex) 01782 { 01783 TRACE("(%p, %p, %p)\n", This, ppTLib, pIndex ); 01784 return ITypeInfo_GetContainingTypeLib(This, ppTLib, pIndex); 01785 } 01786 01787 void CALLBACK ITypeInfo_ReleaseTypeAttr_Proxy( 01788 ITypeInfo* This, 01789 TYPEATTR* pTypeAttr) 01790 { 01791 TRACE("(%p, %p)\n", This, pTypeAttr); 01792 free_embedded_typedesc(&pTypeAttr->tdescAlias); 01793 CoTaskMemFree(pTypeAttr); 01794 } 01795 01796 HRESULT __RPC_STUB ITypeInfo_ReleaseTypeAttr_Stub( 01797 ITypeInfo* This) 01798 { 01799 TRACE("nothing to do\n"); 01800 return S_OK; 01801 } 01802 01803 void CALLBACK ITypeInfo_ReleaseFuncDesc_Proxy( 01804 ITypeInfo* This, 01805 FUNCDESC* pFuncDesc) 01806 { 01807 SHORT param; 01808 TRACE("(%p, %p)\n", This, pFuncDesc); 01809 01810 for(param = 0; param < pFuncDesc->cParams; param++) 01811 free_embedded_elemdesc(pFuncDesc->lprgelemdescParam + param); 01812 if(param) 01813 CoTaskMemFree(pFuncDesc->lprgelemdescParam); 01814 01815 free_embedded_elemdesc(&pFuncDesc->elemdescFunc); 01816 01817 if(pFuncDesc->cScodes != 0 && pFuncDesc->cScodes != -1) 01818 CoTaskMemFree(pFuncDesc->lprgscode); 01819 01820 CoTaskMemFree(pFuncDesc); 01821 } 01822 01823 HRESULT __RPC_STUB ITypeInfo_ReleaseFuncDesc_Stub( 01824 ITypeInfo* This) 01825 { 01826 TRACE("nothing to do\n"); 01827 return S_OK; 01828 } 01829 01830 void CALLBACK ITypeInfo_ReleaseVarDesc_Proxy( 01831 ITypeInfo* This, 01832 VARDESC* pVarDesc) 01833 { 01834 TRACE("(%p, %p)\n", This, pVarDesc); 01835 01836 CoTaskMemFree(pVarDesc->lpstrSchema); 01837 01838 if(pVarDesc->varkind == VAR_CONST) 01839 CoTaskMemFree(pVarDesc->u.lpvarValue); 01840 01841 free_embedded_elemdesc(&pVarDesc->elemdescVar); 01842 CoTaskMemFree(pVarDesc); 01843 } 01844 01845 HRESULT __RPC_STUB ITypeInfo_ReleaseVarDesc_Stub( 01846 ITypeInfo* This) 01847 { 01848 TRACE("nothing to do\n"); 01849 return S_OK; 01850 } 01851 01852 01853 /* ITypeInfo2 */ 01854 01855 HRESULT CALLBACK ITypeInfo2_GetDocumentation2_Proxy( 01856 ITypeInfo2* This, 01857 MEMBERID memid, 01858 LCID lcid, 01859 BSTR* pbstrHelpString, 01860 DWORD* pdwHelpStringContext, 01861 BSTR* pbstrHelpStringDll) 01862 { 01863 FIXME("not implemented\n"); 01864 return E_FAIL; 01865 } 01866 01867 HRESULT __RPC_STUB ITypeInfo2_GetDocumentation2_Stub( 01868 ITypeInfo2* This, 01869 MEMBERID memid, 01870 LCID lcid, 01871 DWORD refPtrFlags, 01872 BSTR* pbstrHelpString, 01873 DWORD* pdwHelpStringContext, 01874 BSTR* pbstrHelpStringDll) 01875 { 01876 FIXME("not implemented\n"); 01877 return E_FAIL; 01878 } 01879 01880 /* ITypeLib */ 01881 01882 UINT CALLBACK ITypeLib_GetTypeInfoCount_Proxy( 01883 ITypeLib* This) 01884 { 01885 UINT count = 0; 01886 TRACE("(%p)\n", This); 01887 01888 ITypeLib_RemoteGetTypeInfoCount_Proxy(This, &count); 01889 01890 return count; 01891 } 01892 01893 HRESULT __RPC_STUB ITypeLib_GetTypeInfoCount_Stub( 01894 ITypeLib* This, 01895 UINT* pcTInfo) 01896 { 01897 TRACE("(%p, %p)\n", This, pcTInfo); 01898 *pcTInfo = ITypeLib_GetTypeInfoCount(This); 01899 return S_OK; 01900 } 01901 01902 HRESULT CALLBACK ITypeLib_GetLibAttr_Proxy( 01903 ITypeLib* This, 01904 TLIBATTR** ppTLibAttr) 01905 { 01906 CLEANLOCALSTORAGE stg; 01907 TRACE("(%p, %p)\n", This, ppTLibAttr); 01908 01909 stg.flags = 0; 01910 stg.pStorage = NULL; 01911 stg.pInterface = NULL; 01912 01913 return ITypeLib_RemoteGetLibAttr_Proxy(This, ppTLibAttr, &stg); 01914 } 01915 01916 HRESULT __RPC_STUB ITypeLib_GetLibAttr_Stub( 01917 ITypeLib* This, 01918 LPTLIBATTR* ppTLibAttr, 01919 CLEANLOCALSTORAGE* pDummy) 01920 { 01921 HRESULT hr; 01922 TRACE("(%p, %p)\n", This, ppTLibAttr); 01923 01924 hr = ITypeLib_GetLibAttr(This, ppTLibAttr); 01925 if(hr != S_OK) 01926 return hr; 01927 01928 pDummy->flags = CLS_LIBATTR; 01929 ITypeLib_AddRef(This); 01930 pDummy->pInterface = (IUnknown*)This; 01931 pDummy->pStorage = ppTLibAttr; 01932 return hr; 01933 } 01934 01935 HRESULT CALLBACK ITypeLib_GetDocumentation_Proxy( 01936 ITypeLib* This, 01937 INT index, 01938 BSTR* pBstrName, 01939 BSTR* pBstrDocString, 01940 DWORD* pdwHelpContext, 01941 BSTR* pBstrHelpFile) 01942 { 01943 FIXME("not implemented\n"); 01944 return E_FAIL; 01945 } 01946 01947 HRESULT __RPC_STUB ITypeLib_GetDocumentation_Stub( 01948 ITypeLib* This, 01949 INT index, 01950 DWORD refPtrFlags, 01951 BSTR* pBstrName, 01952 BSTR* pBstrDocString, 01953 DWORD* pdwHelpContext, 01954 BSTR* pBstrHelpFile) 01955 { 01956 FIXME("not implemented\n"); 01957 return E_FAIL; 01958 } 01959 01960 HRESULT CALLBACK ITypeLib_IsName_Proxy( 01961 ITypeLib* This, 01962 LPOLESTR szNameBuf, 01963 ULONG lHashVal, 01964 BOOL* pfName) 01965 { 01966 FIXME("not implemented\n"); 01967 return E_FAIL; 01968 } 01969 01970 HRESULT __RPC_STUB ITypeLib_IsName_Stub( 01971 ITypeLib* This, 01972 LPOLESTR szNameBuf, 01973 ULONG lHashVal, 01974 BOOL* pfName, 01975 BSTR* pBstrLibName) 01976 { 01977 FIXME("not implemented\n"); 01978 return E_FAIL; 01979 } 01980 01981 HRESULT CALLBACK ITypeLib_FindName_Proxy( 01982 ITypeLib* This, 01983 LPOLESTR szNameBuf, 01984 ULONG lHashVal, 01985 ITypeInfo** ppTInfo, 01986 MEMBERID* rgMemId, 01987 USHORT* pcFound) 01988 { 01989 FIXME("not implemented\n"); 01990 return E_FAIL; 01991 } 01992 01993 HRESULT __RPC_STUB ITypeLib_FindName_Stub( 01994 ITypeLib* This, 01995 LPOLESTR szNameBuf, 01996 ULONG lHashVal, 01997 ITypeInfo** ppTInfo, 01998 MEMBERID* rgMemId, 01999 USHORT* pcFound, 02000 BSTR* pBstrLibName) 02001 { 02002 FIXME("not implemented\n"); 02003 return E_FAIL; 02004 } 02005 02006 void CALLBACK ITypeLib_ReleaseTLibAttr_Proxy( 02007 ITypeLib* This, 02008 TLIBATTR* pTLibAttr) 02009 { 02010 TRACE("(%p, %p)\n", This, pTLibAttr); 02011 CoTaskMemFree(pTLibAttr); 02012 } 02013 02014 HRESULT __RPC_STUB ITypeLib_ReleaseTLibAttr_Stub( 02015 ITypeLib* This) 02016 { 02017 TRACE("nothing to do\n"); 02018 return S_OK; 02019 } 02020 02021 02022 /* ITypeLib2 */ 02023 02024 HRESULT CALLBACK ITypeLib2_GetLibStatistics_Proxy( 02025 ITypeLib2* This, 02026 ULONG* pcUniqueNames, 02027 ULONG* pcchUniqueNames) 02028 { 02029 FIXME("not implemented\n"); 02030 return E_FAIL; 02031 } 02032 02033 HRESULT __RPC_STUB ITypeLib2_GetLibStatistics_Stub( 02034 ITypeLib2* This, 02035 ULONG* pcUniqueNames, 02036 ULONG* pcchUniqueNames) 02037 { 02038 FIXME("not implemented\n"); 02039 return E_FAIL; 02040 } 02041 02042 HRESULT CALLBACK ITypeLib2_GetDocumentation2_Proxy( 02043 ITypeLib2* This, 02044 INT index, 02045 LCID lcid, 02046 BSTR* pbstrHelpString, 02047 DWORD* pdwHelpStringContext, 02048 BSTR* pbstrHelpStringDll) 02049 { 02050 FIXME("not implemented\n"); 02051 return E_FAIL; 02052 } 02053 02054 HRESULT __RPC_STUB ITypeLib2_GetDocumentation2_Stub( 02055 ITypeLib2* This, 02056 INT index, 02057 LCID lcid, 02058 DWORD refPtrFlags, 02059 BSTR* pbstrHelpString, 02060 DWORD* pdwHelpStringContext, 02061 BSTR* pbstrHelpStringDll) 02062 { 02063 FIXME("not implemented\n"); 02064 return E_FAIL; 02065 } 02066 02067 HRESULT CALLBACK IPropertyBag_Read_Proxy( 02068 IPropertyBag* This, 02069 LPCOLESTR pszPropName, 02070 VARIANT *pVar, 02071 IErrorLog *pErrorLog) 02072 { 02073 IUnknown *pUnk = NULL; 02074 TRACE("(%p, %s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog); 02075 02076 if(!pVar) 02077 return E_POINTER; 02078 02079 if(V_VT(pVar) & (VT_BYREF | VT_ARRAY | VT_VECTOR)) 02080 { 02081 FIXME("Variant type %x is byref, array or vector. Not implemented.\n", V_VT(pVar)); 02082 return E_NOTIMPL; 02083 } 02084 02085 switch(V_VT(pVar)) 02086 { 02087 case VT_DISPATCH: 02088 pUnk = (IUnknown*)V_DISPATCH(pVar); 02089 break; 02090 case VT_UNKNOWN: 02091 pUnk = V_UNKNOWN(pVar); 02092 break; 02093 case VT_SAFEARRAY: 02094 FIXME("Safearray support not yet implemented.\n"); 02095 return E_NOTIMPL; 02096 default: 02097 FIXME("Unknown V_VT %d - support not yet implemented.\n", V_VT(pVar)); 02098 return E_NOTIMPL; 02099 } 02100 02101 return IPropertyBag_RemoteRead_Proxy(This, pszPropName, pVar, pErrorLog, 02102 V_VT(pVar), pUnk); 02103 } 02104 02105 HRESULT __RPC_STUB IPropertyBag_Read_Stub( 02106 IPropertyBag* This, 02107 LPCOLESTR pszPropName, 02108 VARIANT *pVar, 02109 IErrorLog *pErrorLog, 02110 DWORD varType, 02111 IUnknown *pUnkObj) 02112 { 02113 static const WCHAR emptyWstr[1] = {0}; 02114 IDispatch *disp; 02115 HRESULT hr; 02116 TRACE("(%p, %s, %p, %p, %x, %p)\n", This, debugstr_w(pszPropName), pVar, 02117 pErrorLog, varType, pUnkObj); 02118 02119 if(varType & (VT_BYREF | VT_ARRAY | VT_VECTOR)) 02120 { 02121 FIXME("Variant type %x is byref, array or vector. Not implemented.\n", V_VT(pVar)); 02122 return E_NOTIMPL; 02123 } 02124 02125 V_VT(pVar) = varType; 02126 switch(varType) 02127 { 02128 case VT_DISPATCH: 02129 hr = IUnknown_QueryInterface(pUnkObj, &IID_IDispatch, (LPVOID*)&disp); 02130 if(FAILED(hr)) 02131 return hr; 02132 IUnknown_Release(pUnkObj); 02133 V_DISPATCH(pVar) = disp; 02134 break; 02135 case VT_UNKNOWN: 02136 V_UNKNOWN(pVar) = pUnkObj; 02137 break; 02138 case VT_BSTR: 02139 V_BSTR(pVar) = SysAllocString(emptyWstr); 02140 break; 02141 case VT_SAFEARRAY: 02142 FIXME("Safearray support not yet implemented.\n"); 02143 return E_NOTIMPL; 02144 default: 02145 break; 02146 } 02147 hr = IPropertyBag_Read(This, pszPropName, pVar, pErrorLog); 02148 if(FAILED(hr)) 02149 VariantClear(pVar); 02150 02151 return hr; 02152 } 02153 02154 /* call_as/local stubs for ocidl.idl */ 02155 02156 HRESULT CALLBACK IClassFactory2_CreateInstanceLic_Proxy( 02157 IClassFactory2* This, 02158 IUnknown *pUnkOuter, 02159 IUnknown *pUnkReserved, 02160 REFIID riid, 02161 BSTR bstrKey, 02162 PVOID *ppvObj) 02163 { 02164 FIXME("not implemented\n"); 02165 return E_NOTIMPL; 02166 } 02167 02168 HRESULT __RPC_STUB IClassFactory2_CreateInstanceLic_Stub( 02169 IClassFactory2* This, 02170 REFIID riid, 02171 BSTR bstrKey, 02172 IUnknown **ppvObj) 02173 { 02174 FIXME("not implemented\n"); 02175 return E_NOTIMPL; 02176 } 02177 02178 HRESULT CALLBACK IEnumConnections_Next_Proxy( 02179 IEnumConnections* This, 02180 ULONG cConnections, 02181 LPCONNECTDATA rgcd, 02182 ULONG *pcFetched) 02183 { 02184 FIXME("not implemented\n"); 02185 return E_NOTIMPL; 02186 } 02187 02188 HRESULT __RPC_STUB IEnumConnections_Next_Stub( 02189 IEnumConnections* This, 02190 ULONG cConnections, 02191 LPCONNECTDATA rgcd, 02192 ULONG *pcFetched) 02193 { 02194 FIXME("not implemented\n"); 02195 return E_NOTIMPL; 02196 } 02197 02198 HRESULT CALLBACK IEnumConnectionPoints_Next_Proxy( 02199 IEnumConnectionPoints* This, 02200 ULONG cConnections, 02201 LPCONNECTIONPOINT *ppCP, 02202 ULONG *pcFetched) 02203 { 02204 FIXME("not implemented\n"); 02205 return E_NOTIMPL; 02206 } 02207 02208 HRESULT __RPC_STUB IEnumConnectionPoints_Next_Stub( 02209 IEnumConnectionPoints* This, 02210 ULONG cConnections, 02211 LPCONNECTIONPOINT *ppCP, 02212 ULONG *pcFetched) 02213 { 02214 FIXME("not implemented\n"); 02215 return E_NOTIMPL; 02216 } 02217 02218 HRESULT CALLBACK IPersistMemory_Load_Proxy( 02219 IPersistMemory* This, 02220 LPVOID pMem, 02221 ULONG cbSize) 02222 { 02223 FIXME("not implemented\n"); 02224 return E_NOTIMPL; 02225 } 02226 02227 HRESULT __RPC_STUB IPersistMemory_Load_Stub( 02228 IPersistMemory* This, 02229 BYTE *pMem, 02230 ULONG cbSize) 02231 { 02232 FIXME("not implemented\n"); 02233 return E_NOTIMPL; 02234 } 02235 02236 HRESULT CALLBACK IPersistMemory_Save_Proxy( 02237 IPersistMemory* This, 02238 LPVOID pMem, 02239 BOOL fClearDirty, 02240 ULONG cbSize) 02241 { 02242 FIXME("not implemented\n"); 02243 return E_NOTIMPL; 02244 } 02245 02246 HRESULT __RPC_STUB IPersistMemory_Save_Stub( 02247 IPersistMemory* This, 02248 BYTE *pMem, 02249 BOOL fClearDirty, 02250 ULONG cbSize) 02251 { 02252 FIXME("not implemented\n"); 02253 return E_NOTIMPL; 02254 } 02255 02256 void CALLBACK IAdviseSinkEx_OnViewStatusChange_Proxy( 02257 IAdviseSinkEx* This, 02258 DWORD dwViewStatus) 02259 { 02260 FIXME("not implemented\n"); 02261 } 02262 02263 HRESULT __RPC_STUB IAdviseSinkEx_OnViewStatusChange_Stub( 02264 IAdviseSinkEx* This, 02265 DWORD dwViewStatus) 02266 { 02267 FIXME("not implemented\n"); 02268 return E_NOTIMPL; 02269 } 02270 02271 HRESULT CALLBACK IEnumOleUndoUnits_Next_Proxy( 02272 IEnumOleUndoUnits* This, 02273 ULONG cElt, 02274 IOleUndoUnit **rgElt, 02275 ULONG *pcEltFetched) 02276 { 02277 FIXME("not implemented\n"); 02278 return E_NOTIMPL; 02279 } 02280 02281 HRESULT __RPC_STUB IEnumOleUndoUnits_Next_Stub( 02282 IEnumOleUndoUnits* This, 02283 ULONG cElt, 02284 IOleUndoUnit **rgElt, 02285 ULONG *pcEltFetched) 02286 { 02287 FIXME("not implemented\n"); 02288 return E_NOTIMPL; 02289 } 02290 02291 HRESULT CALLBACK IQuickActivate_QuickActivate_Proxy( 02292 IQuickActivate* This, 02293 QACONTAINER *pQaContainer, 02294 QACONTROL *pQaControl) 02295 { 02296 FIXME("not implemented\n"); 02297 return E_NOTIMPL; 02298 } 02299 02300 HRESULT __RPC_STUB IQuickActivate_QuickActivate_Stub( 02301 IQuickActivate* This, 02302 QACONTAINER *pQaContainer, 02303 QACONTROL *pQaControl) 02304 { 02305 FIXME("not implemented\n"); 02306 return E_NOTIMPL; 02307 } Generated on Sat May 26 2012 04:21:08 for ReactOS by
1.7.6.1
|