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