diff --git a/dlls/oleaut32/safearray.c b/dlls/oleaut32/safearray.c index 57a0d107c82..71f8c696b15 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 faec23ebe0f..064b038f7a9 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; \