Nikolay Sivov : oleaut32: Mask out certain features on array copy.

Alexandre Julliard julliard at winehq.org
Thu Jan 9 12:52:49 CST 2014


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Jan  8 21:39:42 2014 +0400

oleaut32: Mask out certain features on array copy.

---

 dlls/oleaut32/safearray.c       |   23 +++++++---
 dlls/oleaut32/tests/safearray.c |   94 +++++++++++++++++++++++++++++++++++----
 2 files changed, 102 insertions(+), 15 deletions(-)

diff --git a/dlls/oleaut32/safearray.c b/dlls/oleaut32/safearray.c
index 57a0d10..71f8c69 100644
--- a/dlls/oleaut32/safearray.c
+++ b/dlls/oleaut32/safearray.c
@@ -85,6 +85,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(variant);
 /* Undocumented hidden space before the start of a SafeArray descriptor */
 #define SAFEARRAY_HIDDEN_SIZE sizeof(GUID)
 
+/* features listed here are not propagated to newly created array or data copy
+   created with SafeArrayCopy()/SafeArrayCopyData() */
+static const USHORT ignored_copy_features =
+        FADF_AUTO |
+        FADF_STATIC |
+        FADF_EMBEDDED |
+        FADF_FIXEDSIZE |
+        FADF_CREATEVECTOR;
+
 /* Allocate memory */
 static inline LPVOID SAFEARRAY_Malloc(ULONG ulSize)
 {
@@ -349,8 +358,7 @@ static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest)
   {
     ULONG ulCellCount = SAFEARRAY_GetCellCount(psa);
 
-    dest->fFeatures = (dest->fFeatures & FADF_CREATEVECTOR) |
-                      (psa->fFeatures & ~(FADF_CREATEVECTOR|FADF_DATADELETED));
+    dest->fFeatures = (dest->fFeatures & FADF_CREATEVECTOR) | (psa->fFeatures & ~ignored_copy_features);
 
     if (psa->fFeatures & FADF_VARIANT)
     {
@@ -1273,6 +1281,7 @@ HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa)
  */
 HRESULT WINAPI SafeArrayCopyData(SAFEARRAY *psaSource, SAFEARRAY *psaTarget)
 {
+  HRESULT hr;
   int dim;
 
   TRACE("(%p,%p)\n", psaSource, psaTarget);
@@ -1288,10 +1297,10 @@ HRESULT WINAPI SafeArrayCopyData(SAFEARRAY *psaSource, SAFEARRAY *psaTarget)
        psaTarget->rgsabound[dim].cElements)
       return E_INVALIDARG;
 
-  if (SUCCEEDED(SAFEARRAY_DestroyData(psaTarget, 0)) &&
-      SUCCEEDED(SAFEARRAY_CopyData(psaSource, psaTarget)))
-    return S_OK;
-  return E_UNEXPECTED;
+  hr = SAFEARRAY_DestroyData(psaTarget, 0);
+  if (FAILED(hr)) return hr;
+
+  return SAFEARRAY_CopyData(psaSource, psaTarget);
 }
 
 /************************************************************************
@@ -1371,7 +1380,7 @@ HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut)
     hRet = SafeArrayAllocDescriptor(psa->cDims, ppsaOut);
     if (SUCCEEDED(hRet))
     {
-      (*ppsaOut)->fFeatures = psa->fFeatures & ~FADF_CREATEVECTOR;
+      (*ppsaOut)->fFeatures = psa->fFeatures & ~ignored_copy_features;
       (*ppsaOut)->cbElements = psa->cbElements;
     }
   }
diff --git a/dlls/oleaut32/tests/safearray.c b/dlls/oleaut32/tests/safearray.c
index faec23e..064b038 100644
--- a/dlls/oleaut32/tests/safearray.c
+++ b/dlls/oleaut32/tests/safearray.c
@@ -39,6 +39,10 @@
 #include "wtypes.h"
 #include "oleauto.h"
 
+#ifndef FADF_CREATEVECTOR
+  const USHORT FADF_CREATEVECTOR = 0x2000;
+#endif
+
 static HMODULE hOleaut32;
 
 static HRESULT (WINAPI *pSafeArrayAllocDescriptorEx)(VARTYPE,UINT,SAFEARRAY**);
@@ -57,6 +61,14 @@ static BOOL has_i8;
 /* Has INT_PTR/UINT_PTR type? */
 static BOOL has_int_ptr;
 
+static const USHORT ignored_copy_features[] =
+    {
+        FADF_AUTO,
+        FADF_STATIC,
+        FADF_EMBEDDED,
+        FADF_FIXEDSIZE
+    };
+
 #define START_REF_COUNT 1
 #define RECORD_SIZE 64
 #define RECORD_SIZE_FAIL 17
@@ -1250,14 +1262,13 @@ static void test_SafeArrayGetPutElement_VARIANT(void)
   ok(hres == S_OK, "got 0x%08x\n", hres);
 }
 
-
 static void test_SafeArrayCopyData(void)
 {
   SAFEARRAYBOUND sab[4];
   SAFEARRAY *sa;
   SAFEARRAY *sacopy;
   HRESULT hres;
-  int dimension,size=1;
+  int dimension, size = 1, i;
 
   if (!pSafeArrayCopyData)
   {
@@ -1330,17 +1341,52 @@ static void test_SafeArrayCopyData(void)
 
   hres = SafeArrayCopy(sa, &sacopy);
   ok(hres == S_OK, "copy failed hres 0x%x\n", hres);
-  if (hres == S_OK)
+  ok(SafeArrayGetElemsize(sa) == SafeArrayGetElemsize(sacopy),"elemsize wrong\n");
+  ok(SafeArrayGetDim(sa) == SafeArrayGetDim(sacopy),"dimensions wrong\n");
+  ok(!memcmp(sa->pvData, sacopy->pvData, size * sizeof(int)), "compared different\n");
+  hres = SafeArrayDestroy(sacopy);
+  ok(hres == S_OK, "got 0x%08x\n", hres);
+
+  sacopy = SafeArrayCreate(VT_INT, NUM_DIMENSIONS, sab);
+  ok(sacopy != NULL, "Copy test couldn't create copy array\n");
+  ok(sacopy->fFeatures == FADF_HAVEVARTYPE, "0x%04x\n", sacopy->fFeatures);
+
+  for (i = 0; i < sizeof(ignored_copy_features)/sizeof(USHORT); i++)
   {
-    ok(SafeArrayGetElemsize(sa) == SafeArrayGetElemsize(sacopy),"elemsize wrong\n");
-    ok(SafeArrayGetDim(sa) == SafeArrayGetDim(sacopy),"dimensions wrong\n");
-    ok(!memcmp(sa->pvData, sacopy->pvData, size * sizeof(int)), "compared different\n");
-    hres = SafeArrayDestroy(sacopy);
-    ok(hres == S_OK, "got 0x%08x\n", hres);
+      USHORT feature = ignored_copy_features[i];
+      USHORT orig = sacopy->fFeatures;
+
+      sa->fFeatures |= feature;
+      hres = SafeArrayCopyData(sa, sacopy);
+      ok(hres == S_OK, "got 0x%08x\n", hres);
+      ok(sacopy->fFeatures == orig && orig == FADF_HAVEVARTYPE, "got features 0x%04x\n", sacopy->fFeatures);
+      sa->fFeatures &= ~feature;
   }
 
+  hres = SafeArrayDestroy(sacopy);
+  ok(hres == S_OK, "got 0x%08x\n", hres);
   hres = SafeArrayDestroy(sa);
   ok(hres == S_OK, "got 0x%08x\n", hres);
+
+  /* copy data from a vector */
+  sa = SafeArrayCreateVector(VT_UI1, 0, 2);
+
+  sacopy = SafeArrayCreateVector(VT_UI1, 0, 2);
+  ok(sa->fFeatures == (FADF_HAVEVARTYPE|FADF_CREATEVECTOR), "got 0x%08x\n", sa->fFeatures);
+  ok(sacopy->fFeatures == (FADF_HAVEVARTYPE|FADF_CREATEVECTOR), "got 0x%08x\n", sacopy->fFeatures);
+  hres = SafeArrayCopyData(sa, sacopy);
+  ok(hres == S_OK, "got 0x%08x\n", hres);
+  ok(sacopy->fFeatures == (FADF_HAVEVARTYPE|FADF_CREATEVECTOR), "got 0x%04x\n", sacopy->fFeatures);
+  SafeArrayDestroy(sacopy);
+
+  sacopy = SafeArrayCreate(VT_UI1, NUM_DIMENSIONS, sab);
+  ok(sacopy != NULL, "Copy test couldn't create copy array\n");
+  ok(sacopy->fFeatures == FADF_HAVEVARTYPE, "0x%04x\n", sacopy->fFeatures);
+  hres = SafeArrayCopyData(sa, sacopy);
+  ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
+  SafeArrayDestroy(sacopy);
+
+  SafeArrayDestroy(sa);
 }
 
 static void test_SafeArrayCreateEx(void)
@@ -1541,6 +1587,7 @@ static void test_SafeArrayCopy(void)
   SAFEARRAY *sa, *sa2;
   VARIANTARG vSrc, vDst;
   HRESULT hres;
+  int i;
 
   sab.lLbound = 0;
   sab.cElements = 10;
@@ -1605,6 +1652,37 @@ static void test_SafeArrayCopy(void)
   ok(hres == S_OK, "got 0x%08x\n", hres);
   hres = SafeArrayDestroy(sa);
   ok(hres == S_OK, "got 0x%08x\n", hres);
+
+  /* test feature copy */
+  hres = SafeArrayAllocDescriptor(1, &sa);
+  ok(hres == S_OK, "SafeArrayAllocDescriptor failed with error 0x%08x\n", hres);
+  ok(sa->fFeatures == 0, "got src features 0x%04x\n", sa->fFeatures);
+  sa->cbElements = 16;
+
+  for (i = 0; i < sizeof(ignored_copy_features)/sizeof(USHORT); i++)
+  {
+      USHORT feature = ignored_copy_features[i];
+
+      sa->fFeatures |= feature;
+      hres = SafeArrayCopy(sa, &sa2);
+      ok(hres == S_OK, "got 0x%08x\n", hres);
+      ok(sa2->fFeatures == 0, "got features 0x%04x\n", sa2->fFeatures);
+      hres = SafeArrayDestroy(sa2);
+      ok(hres == S_OK, "got 0x%08x\n", hres);
+      sa->fFeatures &= ~feature;
+  }
+
+  SafeArrayDestroy(sa);
+
+  /* copy from a vector */
+  sa = SafeArrayCreateVector(VT_UI1, 0, 2);
+  ok(sa->fFeatures == (FADF_HAVEVARTYPE|FADF_CREATEVECTOR), "got 0x%08x\n", hres);
+  hres = SafeArrayCopy(sa, &sa2);
+  ok(hres == S_OK, "got 0x%08x\n", hres);
+  ok(sa2->fFeatures == FADF_HAVEVARTYPE, "got 0x%04x\n", sa2->fFeatures);
+
+  SafeArrayDestroy(sa2);
+  SafeArrayDestroy(sa);
 }
 
 #define MKARRAY(low,num,typ) sab.lLbound = low; sab.cElements = num; \




More information about the wine-cvs mailing list