Module: wine Branch: master Commit: 2dd3aa6293ef6b45be2fd69db81205d67cfb2252 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2dd3aa6293ef6b45be2fd69db8...
Author: Huw Davies huw@codeweavers.com Date: Tue Jan 30 12:39:37 2007 +0000
oleaut32: Fix marshaling of VARTYPE-less safearrays.
---
dlls/oleaut32/tests/usrmarshal.c | 38 ++++++++++++++++++++++++++++++++++++-- dlls/oleaut32/usrmarshal.c | 25 +++++++++++++++++++++---- 2 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c index e3f0065..9bc282d 100644 --- a/dlls/oleaut32/tests/usrmarshal.c +++ b/dlls/oleaut32/tests/usrmarshal.c @@ -46,7 +46,16 @@ static inline SF_TYPE get_union_type(SAF
hr = SafeArrayGetVartype(psa, &vt); if (FAILED(hr)) - return 0; + { + switch(psa->cbElements) + { + case 1: vt = VT_I1; break; + case 2: vt = VT_I2; break; + case 4: vt = VT_I4; break; + case 8: vt = VT_I8; break; + default: return 0; + } + }
if (psa->fFeatures & FADF_HAVEIID) return SF_HAVEIID; @@ -111,7 +120,9 @@ static void check_safearray(void *buffer return; }
- SafeArrayGetVartype(lpsa, &vt); + if(FAILED(SafeArrayGetVartype(lpsa, &vt))) + vt = 0; + sftype = get_union_type(lpsa); cell_count = get_cell_count(lpsa);
@@ -159,6 +170,8 @@ static void test_marshal_LPSAFEARRAY(voi SAFEARRAYBOUND sab; MIDL_STUB_MESSAGE stubMsg = { 0 }; USER_MARSHAL_CB umcb = { 0 }; + HRESULT hr; + VARTYPE vt;
umcb.Flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); umcb.pReserve = NULL; @@ -228,6 +241,27 @@ static void test_marshal_LPSAFEARRAY(voi
HeapFree(GetProcessHeap(), 0, buffer); SafeArrayDestroy(lpsa); + + /* VARTYPE-less arrays can be marshaled if cbElements is 1,2,4 or 8 as type SF_In */ + hr = SafeArrayAllocDescriptor(1, &lpsa); + ok(hr == S_OK, "saad failed %08x\n", hr); + lpsa->cbElements = 8; + lpsa->rgsabound[0].lLbound = 2; + lpsa->rgsabound[0].cElements = 48; + hr = SafeArrayAllocData(lpsa); + ok(hr == S_OK, "saad failed %08x\n", hr); + + hr = SafeArrayGetVartype(lpsa, &vt); + ok(hr == E_INVALIDARG, "ret %08x\n", hr); + + size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa); + ok(size == 432, "size %ld\n", size); + buffer = (unsigned char *)HeapAlloc(GetProcessHeap(), 0, size); + LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); + check_safearray(buffer, lpsa); + HeapFree(GetProcessHeap(), 0, buffer); + SafeArrayDestroyData(lpsa); + SafeArrayDestroyDescriptor(lpsa); }
static void check_bstr(void *buffer, BSTR b) diff --git a/dlls/oleaut32/usrmarshal.c b/dlls/oleaut32/usrmarshal.c index 02a3ed9..71d7d6b 100644 --- a/dlls/oleaut32/usrmarshal.c +++ b/dlls/oleaut32/usrmarshal.c @@ -696,7 +696,17 @@ static inline SF_TYPE SAFEARRAY_GetUnion
hr = SafeArrayGetVartype(psa, &vt); if (FAILED(hr)) - RpcRaiseException(hr); + { + switch(psa->cbElements) + { + case 1: vt = VT_I1; break; + case 2: vt = VT_I2; break; + case 4: vt = VT_I4; break; + case 8: vt = VT_I8; break; + default: + RpcRaiseException(hr); + } + }
if (psa->fFeatures & FADF_HAVEIID) return SF_HAVEIID; @@ -846,8 +856,8 @@ unsigned char * WINAPI LPSAFEARRAY_UserM wiresa->cbElements = psa->cbElements;
hr = SafeArrayGetVartype(psa, &vt); - if (FAILED(hr)) - RpcRaiseException(hr); + if (FAILED(hr)) vt = 0; + wiresa->cLocks = (USHORT)psa->cLocks | (vt << 16);
Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs); @@ -996,7 +1006,14 @@ unsigned char * WINAPI LPSAFEARRAY_UserU wiresab = (SAFEARRAYBOUND *)Buffer; Buffer += sizeof(wiresab[0]) * wiresa->cDims;
- *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL); + if(vt) + *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL); + else + { + SafeArrayAllocDescriptor(wiresa->cDims, ppsa); + if(*ppsa) + memcpy((*ppsa)->rgsabound, wiresab, sizeof(SAFEARRAYBOUND) * wiresa->cDims); + } if (!*ppsa) RpcRaiseException(E_OUTOFMEMORY);