From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/windowscodecs/metadatahandler.c | 30 +++++++ dlls/windowscodecs/tests/metadata.c | 121 ++++++++++++--------------- 2 files changed, 82 insertions(+), 69 deletions(-)
diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index 18ef6419eb4..a7c5612b447 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -230,8 +230,38 @@ static HRESULT WINAPI MetadataHandler_GetValueByIndex(IWICMetadataWriter *iface, static MetadataItem *metadatahandler_get_item(MetadataHandler *handler, const PROPVARIANT *schema, const PROPVARIANT *id) { + PROPVARIANT index; + GUID format; + HRESULT hr; UINT i;
+ PropVariantInit(&index); + if (id->vt == VT_CLSID && SUCCEEDED(PropVariantChangeType(&index, schema, 0, VT_UI4))) + { + for (i = 0; i < handler->item_count; i++) + { + PROPVARIANT *value = &handler->items[i].value; + IWICMetadataReader *reader; + + if (value->vt != VT_UNKNOWN) continue; + + if (SUCCEEDED(IUnknown_QueryInterface(value->punkVal, &IID_IWICMetadataReader, (void **)&reader))) + { + hr = IWICMetadataReader_GetMetadataFormat(reader, &format); + IWICMetadataReader_Release(reader); + + if (SUCCEEDED(hr)) + { + if (IsEqualGUID(&format, id->puuid)) + { + if (!index.ulVal) return &handler->items[i]; + --index.ulVal; + } + } + } + } + } + for (i = 0; i < handler->item_count; i++) { if (schema && handler->items[i].schema.vt != VT_EMPTY) diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index a1dd95c732b..fe4dc41255e 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -4280,8 +4280,8 @@ static void test_metadata_App1(void) IWICEnumMetadataItem *enumerator; IStream *app1_stream, *stream2; IWICComponentFactory *factory; + PROPVARIANT schema, id, value; IWICMetadataWriter *writer; - PROPVARIANT id, value; UINT length, count; WCHAR path[64]; ULONG fetched; @@ -4400,6 +4400,19 @@ static void test_metadata_App1(void) ok(value.vt == VT_UI4, "Unexpected value type: %u.\n", value.vt); ok(value.ulVal == 333, "Unexpected value %lu.\n", value.ulVal);
+ /* Nested handlers are accessible by format GUIDs. */ + PropVariantInit(&schema); + PropVariantInit(&id); + PropVariantInit(&value); + InitPropVariantFromCLSID(&GUID_MetadataFormatExif, &id); + hr = IWICMetadataReader_GetValue(ifd_reader, &schema, &id, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataReader, (void **)&exif_reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + PropVariantClear(&value); + PropVariantClear(&id); + PropVariantInit(&id); PropVariantInit(&value); hr = IWICMetadataReader_GetValueByIndex(ifd_reader, 2, NULL, &id, &value); @@ -4507,103 +4520,73 @@ static void test_metadata_App1(void)
PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(query_reader, L"/app1/ifd", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); - hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&query_reader2); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - hr = IWICMetadataQueryReader_GetLocation(query_reader2, ARRAY_SIZE(path), path, &length); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(!lstrcmpW(path, L"/app1/ifd"), "Unexpected path %s.\n", wine_dbgstr_w(path)); - IWICMetadataQueryReader_Release(query_reader2); - PropVariantClear(&value); - } + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&query_reader2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataQueryReader_GetLocation(query_reader2, ARRAY_SIZE(path), path, &length); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpW(path, L"/app1/ifd"), "Unexpected path %s.\n", wine_dbgstr_w(path)); + IWICMetadataQueryReader_Release(query_reader2); + PropVariantClear(&value);
PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(query_reader, L"/app1/ifd/gps", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); - hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&query_reader2); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - hr = IWICMetadataQueryReader_GetLocation(query_reader2, ARRAY_SIZE(path), path, &length); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(!lstrcmpW(path, L"/app1/ifd/gps"), "Unexpected path %s.\n", wine_dbgstr_w(path)); - IWICMetadataQueryReader_Release(query_reader2); - PropVariantClear(&value); - } + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&query_reader2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataQueryReader_GetLocation(query_reader2, ARRAY_SIZE(path), path, &length); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpW(path, L"/app1/ifd/gps"), "Unexpected path %s.\n", wine_dbgstr_w(path)); + IWICMetadataQueryReader_Release(query_reader2); + PropVariantClear(&value);
PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(query_reader, L"/app1/ifd/exif", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); - hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&query_reader2); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - hr = IWICMetadataQueryReader_GetLocation(query_reader2, ARRAY_SIZE(path), path, &length); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(!lstrcmpW(path, L"/app1/ifd/exif"), "Unexpected path %s.\n", wine_dbgstr_w(path)); - IWICMetadataQueryReader_Release(query_reader2); - PropVariantClear(&value); - } + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + hr = IUnknown_QueryInterface(value.punkVal, &IID_IWICMetadataQueryReader, (void **)&query_reader2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IWICMetadataQueryReader_GetLocation(query_reader2, ARRAY_SIZE(path), path, &length); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpW(path, L"/app1/ifd/exif"), "Unexpected path %s.\n", wine_dbgstr_w(path)); + IWICMetadataQueryReader_Release(query_reader2); + PropVariantClear(&value);
PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(query_reader, L"/app1/ifd/exif/{ushort=512}", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_UI2, "Unexpected value type: %u.\n", value.vt); - ok(value.ulVal == 444, "Unexpected value %lu.\n", value.ulVal); - } + ok(value.vt == VT_UI2, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 444, "Unexpected value %lu.\n", value.ulVal);
PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(query_reader, L"/app1/ifd/gps/{ushort=768}", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_UI2, "Unexpected value type: %u.\n", value.vt); - ok(value.ulVal == 555, "Unexpected value %lu.\n", value.ulVal); - } + ok(value.vt == VT_UI2, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 555, "Unexpected value %lu.\n", value.ulVal);
PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(query_reader, L"/app1/ifd/{ushort=256}", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_UI4, "Unexpected value type: %u.\n", value.vt); - ok(value.ulVal == 222, "Unexpected value %lu.\n", value.ulVal); - } + ok(value.vt == VT_UI4, "Unexpected value type: %u.\n", value.vt); + ok(value.ulVal == 222, "Unexpected value %lu.\n", value.ulVal);
PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(query_reader, L"/app1/ifd/{ushort=34665}", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); - check_interface(value.punkVal, &IID_IWICMetadataQueryReader, TRUE); - PropVariantClear(&value); - } + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + todo_wine + check_interface(value.punkVal, &IID_IWICMetadataQueryReader, TRUE); + PropVariantClear(&value);
PropVariantInit(&value); hr = IWICMetadataQueryReader_GetMetadataByName(query_reader, L"/app1/ifd/{ushort=34853}", &value); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); - check_interface(value.punkVal, &IID_IWICMetadataQueryReader, TRUE); - PropVariantClear(&value); - } + ok(value.vt == VT_UNKNOWN, "Unexpected value type: %u.\n", value.vt); + todo_wine + check_interface(value.punkVal, &IID_IWICMetadataQueryReader, TRUE); + PropVariantClear(&value);
IWICMetadataQueryReader_Release(query_reader);