[PATCH 03/11] mfplat: Implement IMFAttributes::{SetItem,GetItem}.

Nikolay Sivov nsivov at codeweavers.com
Thu Mar 14 03:03:08 CDT 2019


From: Jactry Zeng <jzeng at codeweavers.com>

Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/main.c            | 85 ++++++++++++++++++++++++++++++++---
 dlls/mfplat/tests/Makefile.in |  2 +-
 dlls/mfplat/tests/mfplat.c    | 85 ++++++++++++++++++++++++++++++++++-
 3 files changed, 165 insertions(+), 7 deletions(-)

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 9d8a3ae2fe..8ab7c979a8 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -642,11 +642,41 @@ static ULONG WINAPI mfattributes_Release(IMFAttributes *iface)
     return refcount;
 }
 
+static struct attribute *attributes_find_item(struct attributes *attributes, REFGUID key, size_t *index)
+{
+    size_t i;
+
+    for (i = 0; i < attributes->count; ++i)
+    {
+        if (IsEqualGUID(key, &attributes->attributes[i].key))
+        {
+            if (index)
+                *index = i;
+            return &attributes->attributes[i];
+        }
+    }
+
+    return NULL;
+}
+
 static HRESULT WINAPI mfattributes_GetItem(IMFAttributes *iface, REFGUID key, PROPVARIANT *value)
 {
-    FIXME("%p, %s, %p.\n", iface, debugstr_attr(key), value);
+    struct attributes *attributes = impl_from_IMFAttributes(iface);
+    struct attribute *attribute;
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
+
+    EnterCriticalSection(&attributes->cs);
+
+    if ((attribute = attributes_find_item(attributes, key, NULL)))
+        hr = PropVariantCopy(value, &attribute->value);
+    else
+        hr = MF_E_ATTRIBUTENOTFOUND;
+
+    LeaveCriticalSection(&attributes->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI mfattributes_GetItemType(IMFAttributes *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
@@ -753,11 +783,56 @@ static HRESULT WINAPI mfattributes_GetUnknown(IMFAttributes *iface, REFGUID key,
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI mfattributes_SetItem(IMFAttributes *iface, REFGUID key, REFPROPVARIANT Value)
+static HRESULT attributes_set_item(struct attributes *attributes, REFGUID key, REFPROPVARIANT value)
 {
-    FIXME("%p, %s, %p.\n", iface, debugstr_attr(key), Value);
+    struct attribute *attribute;
 
-    return E_NOTIMPL;
+    EnterCriticalSection(&attributes->cs);
+
+    attribute = attributes_find_item(attributes, key, NULL);
+    if (!attribute)
+    {
+        if (!mf_array_reserve((void **)&attributes->attributes, &attributes->capacity, attributes->count + 1,
+                sizeof(*attributes->attributes)))
+        {
+            LeaveCriticalSection(&attributes->cs);
+            return E_OUTOFMEMORY;
+        }
+        attributes->attributes[attributes->count].key = *key;
+        attribute = &attributes->attributes[attributes->count++];
+    }
+    else
+        PropVariantClear(&attribute->value);
+
+    PropVariantCopy(&attribute->value, value);
+
+    LeaveCriticalSection(&attributes->cs);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI mfattributes_SetItem(IMFAttributes *iface, REFGUID key, REFPROPVARIANT value)
+{
+    struct attributes *attributes = impl_from_IMFAttributes(iface);
+    PROPVARIANT empty;
+
+    TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value);
+
+    switch (value->vt)
+    {
+        case MF_ATTRIBUTE_UINT32:
+        case MF_ATTRIBUTE_UINT64:
+        case MF_ATTRIBUTE_DOUBLE:
+        case MF_ATTRIBUTE_GUID:
+        case MF_ATTRIBUTE_STRING:
+        case MF_ATTRIBUTE_BLOB:
+        case MF_ATTRIBUTE_IUNKNOWN:
+            return attributes_set_item(attributes, key, value);
+        default:
+            PropVariantInit(&empty);
+            attributes_set_item(attributes, key, &empty);
+            return MF_E_INVALIDTYPE;
+    }
 }
 
 static HRESULT WINAPI mfattributes_DeleteItem(IMFAttributes *iface, REFGUID key)
diff --git a/dlls/mfplat/tests/Makefile.in b/dlls/mfplat/tests/Makefile.in
index 15b8e17842..150ca6f954 100644
--- a/dlls/mfplat/tests/Makefile.in
+++ b/dlls/mfplat/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = mfplat.dll
-IMPORTS   = ole32 mfplat mfuuid
+IMPORTS   = ole32 mfplat mfuuid propsys
 
 C_SRCS = \
 	mfplat.c
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index aa8029c98d..8550160b8e 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -35,6 +35,7 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
 DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
 DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
+DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23);
 
 #undef INITGUID
 #include <guiddef.h>
@@ -42,6 +43,7 @@ DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,
 #include "mfidl.h"
 #include "mferror.h"
 #include "mfreadwrite.h"
+#include "propvarutil.h"
 
 #include "wine/test.h"
 
@@ -498,9 +500,10 @@ static void test_MFCreateMediaEvent(void)
 
 static void test_MFCreateAttributes(void)
 {
+    PROPVARIANT propvar, ret_propvar;
     IMFAttributes *attributes;
-    HRESULT hr;
     UINT32 count;
+    HRESULT hr;
 
     hr = MFCreateAttributes( &attributes, 3 );
     ok(hr == S_OK, "got 0x%08x\n", hr);
@@ -518,6 +521,86 @@ static void test_MFCreateAttributes(void)
     todo_wine ok(count == 1, "got %d\n", count);
 
     IMFAttributes_Release(attributes);
+
+    hr = MFCreateAttributes(&attributes, 0);
+    ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
+
+    PropVariantInit(&propvar);
+    propvar.vt = MF_ATTRIBUTE_UINT32;
+    U(propvar).ulVal = 123;
+    hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
+    ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
+    PropVariantInit(&ret_propvar);
+    ret_propvar.vt = MF_ATTRIBUTE_UINT32;
+    U(ret_propvar).ulVal = 0xdeadbeef;
+    hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
+    ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
+    ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
+    PropVariantClear(&ret_propvar);
+
+    PropVariantInit(&ret_propvar);
+    ret_propvar.vt = MF_ATTRIBUTE_STRING;
+    U(ret_propvar).pwszVal = NULL;
+    hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
+    ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
+    ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
+    PropVariantClear(&ret_propvar);
+
+    PropVariantClear(&propvar);
+
+    PropVariantInit(&propvar);
+    propvar.vt = MF_ATTRIBUTE_UINT64;
+    U(propvar).uhVal.QuadPart = 65536;
+    hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
+    ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
+    PropVariantInit(&ret_propvar);
+    ret_propvar.vt = MF_ATTRIBUTE_UINT32;
+    U(ret_propvar).ulVal = 0xdeadbeef;
+    hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
+    ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
+    ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
+    PropVariantClear(&ret_propvar);
+    PropVariantClear(&propvar);
+
+    PropVariantInit(&propvar);
+    propvar.vt = VT_I4;
+    U(propvar).lVal = 123;
+    hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
+    ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#x.\n", hr);
+    PropVariantInit(&ret_propvar);
+    ret_propvar.vt = MF_ATTRIBUTE_UINT32;
+    U(ret_propvar).lVal = 0xdeadbeef;
+    hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
+    ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
+    PropVariantClear(&propvar);
+    ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
+    PropVariantClear(&ret_propvar);
+
+    PropVariantInit(&propvar);
+    propvar.vt = MF_ATTRIBUTE_UINT32;
+    U(propvar).ulVal = 123;
+    hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
+    ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
+
+    hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
+    todo_wine ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
+
+    hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
+    ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
+    ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
+    PropVariantClear(&ret_propvar);
+    PropVariantClear(&propvar);
+
+    propvar.vt = MF_ATTRIBUTE_UINT64;
+    U(propvar).uhVal.QuadPart = 65536;
+
+    hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
+    ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
+    ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
+    PropVariantClear(&ret_propvar);
+    PropVariantClear(&propvar);
+
+    IMFAttributes_Release(attributes);
 }
 
 static void test_MFCreateMFByteStreamOnStream(void)
-- 
2.20.1




More information about the wine-devel mailing list