Huw Davies : oleaut32: Fix marshaling of VARTYPE-less safearrays.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Feb 5 07:44:58 CST 2007
Module: wine
Branch: master
Commit: 2dd3aa6293ef6b45be2fd69db81205d67cfb2252
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2dd3aa6293ef6b45be2fd69db81205d67cfb2252
Author: Huw Davies <huw at 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);
More information about the wine-cvs
mailing list