diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c index e5fb58cd401..d04a366d3a6 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 02f5f34d0ef..726dd9690ba 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))