oleaut32: Fix safearray data destruction.

This commit is contained in:
qingdoa daoo 2006-06-09 18:02:04 +08:00 committed by Alexandre Julliard
parent ad5e02e604
commit f80db874d4
2 changed files with 69 additions and 11 deletions

View File

@ -284,7 +284,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH))
{ {
LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell * psa->cbElements; LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell;
while(ulCellCount--) while(ulCellCount--)
{ {
@ -310,7 +310,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
} }
else if (psa->fFeatures & FADF_BSTR) else if (psa->fFeatures & FADF_BSTR)
{ {
BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell * psa->cbElements; BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell;
while(ulCellCount--) while(ulCellCount--)
{ {
@ -321,7 +321,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell)
} }
else if (psa->fFeatures & FADF_VARIANT) else if (psa->fFeatures & FADF_VARIANT)
{ {
VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell * psa->cbElements; VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell;
while(ulCellCount--) while(ulCellCount--)
{ {
@ -1234,13 +1234,17 @@ HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa)
if (psa->cLocks) if (psa->cLocks)
return DISP_E_ARRAYISLOCKED; /* Can't delete a locked array */ return DISP_E_ARRAYISLOCKED; /* Can't delete a locked array */
/* If static, keep pvData and don't free */ /* Delete the actual item data */
if (psa->pvData && !(psa->fFeatures & FADF_STATIC)) 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 this is not a vector, free the data memory block */
if (!(psa->fFeatures & FADF_CREATEVECTOR)) if (!(psa->fFeatures & FADF_CREATEVECTOR))
{ {

View File

@ -335,8 +335,26 @@ static void test_safearray(void)
ok(hres == S_OK, "SAPOI failed with hres %lx\n", hres); ok(hres == S_OK, "SAPOI failed with hres %lx\n", hres);
SafeArrayAccessData(a, (void **)&ptr2); SafeArrayAccessData(a, (void **)&ptr2);
ok(ptr1 - ptr2 == 14, "SAPOI got wrong ptr\n"); ok(ptr1 - ptr2 == 14, "SAPOI got wrong ptr\n");
*(WORD *)ptr1 = 0x55aa;
SafeArrayUnaccessData(a); 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[0].cElements = 0; bounds[0].lLbound = 1;
bounds[1].cElements = 2; bounds[1].lLbound = 23; bounds[1].cElements = 2; bounds[1].lLbound = 23;
a = SafeArrayCreate(VT_I4,2,bounds); 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"); 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) static void test_SafeArrayGetPutElement_VARIANT(void)
{ {
SAFEARRAYBOUND sab; SAFEARRAYBOUND sab;
@ -1597,7 +1648,7 @@ static void test_SafeArrayDestroyData (void)
SAFEARRAYBOUND sab; SAFEARRAYBOUND sab;
SAFEARRAY *sa; SAFEARRAY *sa;
HRESULT hres; HRESULT hres;
int value = 0; int value = 0xdeadbeef;
long index[1]; long index[1];
void HUGEP *temp_pvData; void HUGEP *temp_pvData;
@ -1610,13 +1661,15 @@ static void test_SafeArrayDestroyData (void)
index[0] = 1; index[0] = 1;
SafeArrayPutElement (sa, index, &value); 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; sa->fFeatures |= FADF_STATIC;
temp_pvData = sa->pvData; temp_pvData = sa->pvData;
hres = SafeArrayDestroyData(sa); hres = SafeArrayDestroyData(sa);
ok(hres == S_OK, "SADData FADF_STATIC failed, error code %lx.\n",hres); 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", ok(sa->pvData == temp_pvData, "SADData FADF_STATIC: pvData=%p, expected %p (fFeatures = %d).\n",
sa->pvData, temp_pvData, sa->fFeatures); 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. */ /* Clear FADF_STATIC, now really destroy the data. */
sa->fFeatures ^= FADF_STATIC; sa->fFeatures ^= FADF_STATIC;
@ -1655,5 +1708,6 @@ START_TEST(safearray)
test_SafeArrayGetPutElement(); test_SafeArrayGetPutElement();
test_SafeArrayGetPutElement_BSTR(); test_SafeArrayGetPutElement_BSTR();
test_SafeArrayGetPutElement_IUnknown(); test_SafeArrayGetPutElement_IUnknown();
test_SafeArrayRedim_IUnknown();
test_SafeArrayGetPutElement_VARIANT(); test_SafeArrayGetPutElement_VARIANT();
} }