Piotr Caban : oleaut32: Reuse safearray passed to LPSAFEARRAY_UserUnmarshal if possible.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jan 14 11:10:26 CST 2016


Module: wine
Branch: master
Commit: c1974090c6d592535ea893d28d35b672d51e77ad
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c1974090c6d592535ea893d28d35b672d51e77ad

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Jan 13 09:51:32 2016 +0100

oleaut32: Reuse safearray passed to LPSAFEARRAY_UserUnmarshal if possible.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/oleaut32/tests/usrmarshal.c |  3 +--
 dlls/oleaut32/usrmarshal.c       | 24 +++++++++++++++++++++---
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c
index e5fb58c..d04a366 100644
--- a/dlls/oleaut32/tests/usrmarshal.c
+++ b/dlls/oleaut32/tests/usrmarshal.c
@@ -1371,8 +1371,7 @@ static void test_marshal_VARIANT(void)
     ok(next == buffer + expected, "got %p expect %p\n", next, buffer + expected);
     ok(V_VT(&v) == V_VT(&v2), "got vt %d expect %d\n", V_VT(&v), V_VT(&v2));
     ok(lpsa2 == lpsa_copy, "safearray should be reused\n");
-    todo_wine ok(mem == lpsa2->pvData, "safearray data should be reused\n");
-    if(mem != lpsa2->pvData) CoTaskMemFree(mem);
+    ok(mem == lpsa2->pvData, "safearray data should be reused\n");
     ok(SafeArrayGetDim(*V_ARRAYREF(&v)) == SafeArrayGetDim(*V_ARRAYREF(&v2)), "array dims differ\n");
     SafeArrayGetLBound(*V_ARRAYREF(&v), 1, &bound);
     SafeArrayGetLBound(*V_ARRAYREF(&v2), 1, &bound2);
diff --git a/dlls/oleaut32/usrmarshal.c b/dlls/oleaut32/usrmarshal.c
index 02f5f34..726dd96 100644
--- a/dlls/oleaut32/usrmarshal.c
+++ b/dlls/oleaut32/usrmarshal.c
@@ -1008,7 +1008,26 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
     wiresab = (SAFEARRAYBOUND *)Buffer;
     Buffer += sizeof(wiresab[0]) * wiresa->cDims;
 
-    if(vt)
+    if(*ppsa && (*ppsa)->cDims==wiresa->cDims)
+    {
+        if(((*ppsa)->fFeatures & ~FADF_AUTOSETFLAGS) != (wiresa->fFeatures & ~FADF_AUTOSETFLAGS))
+            RpcRaiseException(DISP_E_BADCALLEE);
+
+        if(SAFEARRAY_GetCellCount(*ppsa)*(*ppsa)->cbElements != cell_count*elem_mem_size(wiresa, sftype))
+        {
+            if((*ppsa)->fFeatures & (FADF_AUTO|FADF_STATIC|FADF_EMBEDDED|FADF_FIXEDSIZE))
+                RpcRaiseException(DISP_E_BADCALLEE);
+
+            hr = SafeArrayDestroyData(*ppsa);
+            if(FAILED(hr))
+                RpcRaiseException(hr);
+        }
+        memcpy((*ppsa)->rgsabound, wiresab, sizeof(*wiresab)*wiresa->cDims);
+
+        if((*ppsa)->fFeatures & FADF_HAVEVARTYPE)
+            ((DWORD*)(*ppsa))[-1] = vt;
+    }
+    else if(vt)
     {
         SafeArrayDestroy(*ppsa);
         *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL);
@@ -1028,11 +1047,10 @@ unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(ULONG *pFlags, unsigned char *B
     (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS));
     /* FIXME: there should be a limit on how large wiresa->cbElements can be */
     (*ppsa)->cbElements = elem_mem_size(wiresa, sftype);
-    (*ppsa)->cLocks = 0;
 
     /* SafeArrayCreateEx allocates the data for us, but
      * SafeArrayAllocDescriptor doesn't */
-    if(!vt)
+    if(!(*ppsa)->pvData)
     {
         hr = SafeArrayAllocData(*ppsa);
         if (FAILED(hr))




More information about the wine-cvs mailing list