qingdoa daoo : oleaut32: Fix safearray data destruction.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Jun 9 11:16:42 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: f80db874d4e73616e74ff4a6c044c389f6dc7bf3
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=f80db874d4e73616e74ff4a6c044c389f6dc7bf3

Author: qingdoa daoo <qingdao33122 at yahoo.com>
Date:   Fri Jun  9 18:02:04 2006 +0800

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 cfebfbb..0eb92da 100644
--- a/dlls/oleaut32/safearray.c
+++ b/dlls/oleaut32/safearray.c
@@ -284,7 +284,7 @@ static HRESULT SAFEARRAY_DestroyData(SAF
 
     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(SAF
     }
     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(SAF
     }
     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(SAFE
   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 c719c69..9fc4061 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_
   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 (v
   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 (v
   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();
 }




More information about the wine-cvs mailing list