From: Piotr Caban piotr@codeweavers.com
--- dlls/ole32/stg_prop.c | 23 +++++++++++++++++++++-- dlls/ole32/tests/propvariant.c | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/dlls/ole32/stg_prop.c b/dlls/ole32/stg_prop.c index c4145cf864f..fedba892c70 100644 --- a/dlls/ole32/stg_prop.c +++ b/dlls/ole32/stg_prop.c @@ -1612,7 +1612,22 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const struct read
for (i = 0; i < count; ++i) { - if (FAILED(hr = propertystorage_read_scalar(&elem, buffer, &offset, codepage, pma))) + if (prop->vt == (VT_VECTOR | VT_VARIANT)) + { + DWORD vt; + + offset = ALIGNED_LENGTH(offset, sizeof(DWORD) - 1); + hr = buffer_read_dword(buffer, offset, &vt); + if (SUCCEEDED(hr)) + { + offset += sizeof(DWORD); + elem.vt = vt; + } + } + + if (SUCCEEDED(hr)) + hr = propertystorage_read_scalar(&elem, buffer, &offset, codepage, pma); + if (FAILED(hr)) { for (; i > 0; --i) { @@ -1633,7 +1648,11 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const struct read call_IMemoryAllocator_Free(pma, prop->cac.pElems); return hr; } - memcpy(prop->cac.pElems + elemsize * i, &elem.lVal, elemsize); + + if (prop->vt == (VT_VECTOR | VT_VARIANT)) + memcpy(prop->cac.pElems + elemsize * i, &elem, elemsize); + else + memcpy(prop->cac.pElems + elemsize * i, &elem.lVal, elemsize); } } else if (prop->vt & VT_ARRAY) diff --git a/dlls/ole32/tests/propvariant.c b/dlls/ole32/tests/propvariant.c index 875a213c197..891d2a7d141 100644 --- a/dlls/ole32/tests/propvariant.c +++ b/dlls/ole32/tests/propvariant.c @@ -544,6 +544,15 @@ static const char serialized_i1_vec[] = { 1, 2, 3, 0 };
+static const char serialized_variant_vec[] = { + VT_VARIANT, VT_VECTOR >> 8, 0, 0, + 2, 0, 0, 0, + VT_I1, 0, 0, 0, + 1, 0, 0, 0, + VT_I4, 0, 0, 0, + 2, 0, 0, 0 +}; + static void test_propertytovariant(void) { HANDLE hole32; @@ -626,6 +635,18 @@ static void test_propertytovariant(void) ok(!wcscmp(propvar.calpwstr.pElems[2], L"def"), "pElems[2] = %s\n", debugstr_w(propvar.calpwstr.pElems[2])); PropVariantClear(&propvar); + + ret = pStgConvertPropertyToVariant((SERIALIZEDPROPERTYVALUE*)serialized_variant_vec, + CP_WINUNICODE, &propvar, &allocator); + + ok(!ret, "StgConvertPropertyToVariant returned %i\n", ret); + ok(propvar.vt == (VT_VECTOR | VT_VARIANT), "unexpected vt %x\n", propvar.vt); + ok(propvar.capropvar.cElems == 2, "unexpected cElems %lu\n", propvar.calpwstr.cElems); + ok(propvar.capropvar.pElems[0].vt == VT_I1, "pElems[0].vt = %d\n", propvar.capropvar.pElems[0].vt); + ok(propvar.capropvar.pElems[0].cVal == 1, "pElems[0].cVal = %d\n", propvar.capropvar.pElems[0].cVal); + ok(propvar.capropvar.pElems[1].vt == VT_I4, "pElems[1].vt = %d\n", propvar.capropvar.pElems[1].vt); + ok(propvar.capropvar.pElems[1].lVal == 2, "pElems[1].lVal = %ld\n", propvar.capropvar.pElems[1].lVal); + PropVariantClear(&propvar); }
static void test_varianttoproperty(void)