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