mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
oleaut32: Fix safearray data destruction.
This commit is contained in:
parent
ad5e02e604
commit
f80db874d4
2 changed files with 69 additions and 11 deletions
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue