ole32: Add VT_ARRAY support to PropVariant.

Signed-off-by: Sven Baars <sven.wine@gmail.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Sven Baars 2019-05-30 11:39:33 +02:00 committed by Alexandre Julliard
parent 3c9104f961
commit e3aae365a9
2 changed files with 70 additions and 19 deletions

View File

@ -2797,6 +2797,25 @@ static inline HRESULT PROPVARIANT_ValidateType(VARTYPE vt)
case VT_FILETIME|VT_VECTOR:
case VT_CF|VT_VECTOR:
case VT_CLSID|VT_VECTOR:
case VT_ARRAY|VT_I1:
case VT_ARRAY|VT_UI1:
case VT_ARRAY|VT_I2:
case VT_ARRAY|VT_UI2:
case VT_ARRAY|VT_I4:
case VT_ARRAY|VT_UI4:
case VT_ARRAY|VT_INT:
case VT_ARRAY|VT_UINT:
case VT_ARRAY|VT_R4:
case VT_ARRAY|VT_R8:
case VT_ARRAY|VT_CY:
case VT_ARRAY|VT_DATE:
case VT_ARRAY|VT_BSTR:
case VT_ARRAY|VT_BOOL:
case VT_ARRAY|VT_DECIMAL:
case VT_ARRAY|VT_DISPATCH:
case VT_ARRAY|VT_UNKNOWN:
case VT_ARRAY|VT_ERROR:
case VT_ARRAY|VT_VARIANT:
return S_OK;
}
WARN("Bad type %d\n", vt);
@ -2908,6 +2927,8 @@ HRESULT WINAPI PropVariantClear(PROPVARIANT * pvar) /* [in/out] */
CoTaskMemFree(pvar->u.capropvar.pElems);
}
}
else if (pvar->vt & VT_ARRAY)
hr = SafeArrayDestroy(pvar->u.parray);
else
{
WARN("Invalid/unsupported type %d\n", pvar->vt);
@ -3088,6 +3109,11 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
else
CopyMemory(pvarDest->u.capropvar.pElems, pvarSrc->u.capropvar.pElems, len * elemSize);
}
else if (pvarSrc->vt & VT_ARRAY)
{
pvarDest->u.uhVal.QuadPart = 0;
return SafeArrayCopy(pvarSrc->u.parray, &pvarDest->u.parray);
}
else
WARN("Invalid/unsupported type %d\n", pvarSrc->vt);
}

View File

@ -46,28 +46,28 @@ static const struct valid_mapping
{
{ PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_EMPTY */
{ PROP_V0 , PROP_INV, PROP_INV, PROP_INV }, /* VT_NULL */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_I2 */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_I4 */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_R4 */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_R8 */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_CY */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_DATE */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_BSTR */
{ PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_DISPATCH */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_ERROR */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_BOOL */
{ PROP_V1 | PROP_TODO , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_VARIANT */
{ PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_UNKNOWN */
{ PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_DECIMAL */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_I2 */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_I4 */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_R4 */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_R8 */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_CY */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_DATE */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_BSTR */
{ PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_DISPATCH */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_ERROR */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_BOOL */
{ PROP_V1 | PROP_TODO , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_VARIANT */
{ PROP_V1 , PROP_V1, PROP_INV, PROP_V1 | PROP_TODO }, /* VT_UNKNOWN */
{ PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_DECIMAL */
{ PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* 15 */
{ PROP_V1 , PROP_V1 | PROP_TODO , PROP_V1 , PROP_V1 | PROP_TODO }, /* VT_I1 */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI1 */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI2 */
{ PROP_V0 , PROP_V1 | PROP_TODO , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI4 */
{ PROP_V1 , PROP_V1 , PROP_V1 , PROP_V1 | PROP_TODO }, /* VT_I1 */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI1 */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI2 */
{ PROP_V0 , PROP_V1 , PROP_V0 , PROP_V1 | PROP_TODO }, /* VT_UI4 */
{ PROP_V0 , PROP_V1A | PROP_TODO, PROP_V0 , PROP_V1A | PROP_TODO }, /* VT_I8 */
{ PROP_V0 , PROP_V1A | PROP_TODO, PROP_V0 , PROP_V1A | PROP_TODO }, /* VT_UI8 */
{ PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_INT */
{ PROP_V1 , PROP_V1 | PROP_TODO , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_UINT */
{ PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_INT */
{ PROP_V1 , PROP_V1 , PROP_INV, PROP_V1 | PROP_TODO }, /* VT_UINT */
{ PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_VOID */
{ PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_HRESULT */
{ PROP_INV, PROP_INV, PROP_INV, PROP_INV }, /* VT_PTR */
@ -351,6 +351,9 @@ static void test_copy(void)
struct unk_impl unk_obj = {{&unk_vtbl}, 1};
PROPVARIANT propvarSrc;
PROPVARIANT propvarDst;
SAFEARRAY *sa;
SAFEARRAYBOUND sabound;
LONG saindex;
HRESULT hr;
propvarSrc.vt = VT_BSTR;
@ -392,6 +395,28 @@ static void test_copy(void)
ok(hr == S_OK, "PropVariantClear(...VT_UNKNOWN...) failed: 0x%08x.\n", hr);
ok(unk_obj.ref == 1, "got wrong refcount: %d.\n", unk_obj.ref);
memset(&propvarSrc, 0, sizeof(propvarSrc));
sabound.lLbound = 0;
sabound.cElements = 2;
sa = SafeArrayCreate(VT_UNKNOWN, 1, &sabound);
saindex = 0;
SafeArrayPutElement(sa, &saindex, &unk_obj.IUnknown_iface);
saindex = 1;
SafeArrayPutElement(sa, &saindex, &unk_obj.IUnknown_iface);
ok(unk_obj.ref == 3, "got wrong refcount: %d.\n", unk_obj.ref);
propvarSrc.vt = VT_ARRAY | VT_UNKNOWN;
U(propvarSrc).parray = sa;
hr = PropVariantCopy(&propvarDst, &propvarSrc);
ok(hr == S_OK, "PropVariantCopy(...VT_ARRAY|VT_UNKNOWN...) failed: 0x%08x.\n", hr);
ok(unk_obj.ref == 5, "got wrong refcount: %d.\n", unk_obj.ref);
hr = PropVariantClear(&propvarDst);
ok(hr == S_OK, "PropVariantClear(...VT_ARRAY|VT_UNKNOWN...) failed: 0x%08x.\n", hr);
ok(unk_obj.ref == 3, "got wrong refcount: %d.\n", unk_obj.ref);
hr = PropVariantClear(&propvarSrc);
ok(hr == S_OK, "PropVariantClear(...VT_ARRAY|VT_UNKNOWN...) failed: 0x%08x.\n", hr);
ok(unk_obj.ref == 1, "got wrong refcount: %d.\n", unk_obj.ref);
memset(&propvarSrc, 0, sizeof(propvarSrc));
}
struct _PMemoryAllocator_vtable {