From f80db874d4e73616e74ff4a6c044c389f6dc7bf3 Mon Sep 17 00:00:00 2001 From: qingdoa daoo Date: Fri, 9 Jun 2006 18:02:04 +0800 Subject: [PATCH] oleaut32: Fix safearray data destruction. --- dlls/oleaut32/safearray.c | 22 ++++++++----- dlls/oleaut32/tests/safearray.c | 58 +++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/dlls/oleaut32/safearray.c b/dlls/oleaut32/safearray.c index cfebfbb1d5..0eb92da2e2 100644 --- a/dlls/oleaut32/safearray.c +++ b/dlls/oleaut32/safearray.c @@ -284,7 +284,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell) if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { - LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell * psa->cbElements; + LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell; while(ulCellCount--) { @@ -310,7 +310,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell) } else if (psa->fFeatures & FADF_BSTR) { - BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell * psa->cbElements; + BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell; while(ulCellCount--) { @@ -321,7 +321,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell) } else if (psa->fFeatures & FADF_VARIANT) { - VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell * psa->cbElements; + VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell; while(ulCellCount--) { @@ -1234,13 +1234,17 @@ HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa) if (psa->cLocks) return DISP_E_ARRAYISLOCKED; /* Can't delete a locked array */ - /* If static, keep pvData and don't free */ - if (psa->pvData && !(psa->fFeatures & FADF_STATIC)) - { - /* Delete the actual item data */ - if (FAILED(SAFEARRAY_DestroyData(psa, 0))) - return E_UNEXPECTED; + /* Delete the actual item data */ + if (FAILED(SAFEARRAY_DestroyData(psa, 0))) + return E_UNEXPECTED; + if (psa->pvData) + { + if (psa->fFeatures & FADF_STATIC) + { + ZeroMemory(psa->pvData, SAFEARRAY_GetCellCount(psa) * psa->cbElements); + return S_OK; + } /* If this is not a vector, free the data memory block */ if (!(psa->fFeatures & FADF_CREATEVECTOR)) { diff --git a/dlls/oleaut32/tests/safearray.c b/dlls/oleaut32/tests/safearray.c index c719c691ca..9fc4061b6e 100644 --- a/dlls/oleaut32/tests/safearray.c +++ b/dlls/oleaut32/tests/safearray.c @@ -335,8 +335,26 @@ static void test_safearray(void) ok(hres == S_OK, "SAPOI failed with hres %lx\n", hres); SafeArrayAccessData(a, (void **)&ptr2); ok(ptr1 - ptr2 == 14, "SAPOI got wrong ptr\n"); + *(WORD *)ptr1 = 0x55aa; SafeArrayUnaccessData(a); + bound.cElements = 10; + bound.lLbound = 1; + SafeArrayRedim(a, &bound); + ptr1 = NULL; + SafeArrayPtrOfIndex(a, indices, (void **)&ptr1); + ok(*(WORD *)ptr1 == 0x55aa, "Data not preserved when resizing array\n"); + + bound.cElements = 10; + bound.lLbound = 0; + SafeArrayRedim(a, &bound); + SafeArrayPtrOfIndex(a, indices, (void **)&ptr1); + ok(*(WORD *)ptr1 == 0, "Expanded area not zero-initialized\n"); + + indices[1] = 1; + SafeArrayPtrOfIndex(a, indices, (void **)&ptr1); + ok(*(WORD *)ptr1 == 0x55aa, "Data not preserved when resizing array\n"); + bounds[0].cElements = 0; bounds[0].lLbound = 1; bounds[1].cElements = 2; bounds[1].lLbound = 23; a = SafeArrayCreate(VT_I4,2,bounds); @@ -1130,6 +1148,39 @@ static void test_SafeArrayGetPutElement_IUnknown(void) ok(tunk_xref == 2,"Failed to decrement refcount of iface.\n"); } +static void test_SafeArrayRedim_IUnknown(void) +{ + SAFEARRAYBOUND sab; + LONG indices[1]; + SAFEARRAY *sa; + HRESULT hres; + LPUNKNOWN value; + + sab.lLbound = 1; + sab.cElements = 2; + sa = SafeArrayCreate(VT_UNKNOWN, 1, &sab); + ok(sa != NULL, "UNKNOWN test couldn't create array\n"); + if (!sa) + return; + + ok(sa->cbElements == sizeof(LPUNKNOWN), "LPUNKNOWN size mismatch\n"); + if (sa->cbElements != sizeof(LPUNKNOWN)) + return; + + indices[0] = 2; + xtunk_iface.lpvtbl = &xtunk_vtbl; + value = (LPUNKNOWN)&xtunk_iface; + tunk_xref = 1; + hres = SafeArrayPutElement(sa, indices, value); + ok(hres == S_OK, "Failed to put IUnknown element hres 0x%lx\n", hres); + ok(tunk_xref == 2,"Failed to increment refcount of iface.\n"); + sab.cElements = 1; + hres = SafeArrayRedim(sa, &sab); + ok(hres == S_OK, "Failed to shrink array hres 0x%lx\n", hres); + ok(tunk_xref == 1, "Failed to decrement refcount\n"); + SafeArrayDestroy(sa); +} + static void test_SafeArrayGetPutElement_VARIANT(void) { SAFEARRAYBOUND sab; @@ -1597,7 +1648,7 @@ static void test_SafeArrayDestroyData (void) SAFEARRAYBOUND sab; SAFEARRAY *sa; HRESULT hres; - int value = 0; + int value = 0xdeadbeef; long index[1]; void HUGEP *temp_pvData; @@ -1610,13 +1661,15 @@ static void test_SafeArrayDestroyData (void) index[0] = 1; SafeArrayPutElement (sa, index, &value); -/* SafeArrayDestroyData shouldn't do anything if FADF_STATIC is set. */ +/* SafeArrayDestroyData shouldn't free pvData if FADF_STATIC is set. */ sa->fFeatures |= FADF_STATIC; temp_pvData = sa->pvData; hres = SafeArrayDestroyData(sa); ok(hres == S_OK, "SADData FADF_STATIC failed, error code %lx.\n",hres); ok(sa->pvData == temp_pvData, "SADData FADF_STATIC: pvData=%p, expected %p (fFeatures = %d).\n", sa->pvData, temp_pvData, sa->fFeatures); + SafeArrayGetElement (sa, index, &value); + ok(value == 0, "Data not cleared after SADData\n"); /* Clear FADF_STATIC, now really destroy the data. */ sa->fFeatures ^= FADF_STATIC; @@ -1655,5 +1708,6 @@ START_TEST(safearray) test_SafeArrayGetPutElement(); test_SafeArrayGetPutElement_BSTR(); test_SafeArrayGetPutElement_IUnknown(); + test_SafeArrayRedim_IUnknown(); test_SafeArrayGetPutElement_VARIANT(); }