diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 30bb808f6a8..2ef40779213 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -872,24 +872,84 @@ static HRESULT WINAPI mfattributes_GetAllocatedString(IMFAttributes *iface, REFG static HRESULT WINAPI mfattributes_GetBlobSize(IMFAttributes *iface, REFGUID key, UINT32 *size) { - FIXME("%p, %s, %p.\n", iface, debugstr_attr(key), size); + struct attributes *attributes = impl_from_IMFAttributes(iface); + struct attribute *attribute; + HRESULT hr = S_OK; - return E_NOTIMPL; + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size); + + EnterCriticalSection(&attributes->cs); + + attribute = attributes_find_item(attributes, key, NULL); + if (attribute) + { + if (attribute->value.vt == MF_ATTRIBUTE_BLOB) + *size = attribute->value.u.caub.cElems; + else + hr = MF_E_INVALIDTYPE; + } + else + hr = MF_E_ATTRIBUTENOTFOUND; + + LeaveCriticalSection(&attributes->cs); + + return hr; } static HRESULT WINAPI mfattributes_GetBlob(IMFAttributes *iface, REFGUID key, UINT8 *buf, UINT32 bufsize, UINT32 *blobsize) { - FIXME("%p, %s, %p, %d, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize); + struct attributes *attributes = impl_from_IMFAttributes(iface); + struct attribute *attribute; + HRESULT hr; - return E_NOTIMPL; + TRACE("%p, %s, %p, %d, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize); + + EnterCriticalSection(&attributes->cs); + + attribute = attributes_find_item(attributes, key, NULL); + if (attribute) + { + if (attribute->value.vt == MF_ATTRIBUTE_BLOB) + { + UINT32 size = attribute->value.u.caub.cElems; + + if (bufsize >= size) + hr = PropVariantToBuffer(&attribute->value, buf, size); + else + hr = E_NOT_SUFFICIENT_BUFFER; + + if (blobsize) + *blobsize = size; + } + else + hr = MF_E_INVALIDTYPE; + } + else + hr = MF_E_ATTRIBUTENOTFOUND; + + LeaveCriticalSection(&attributes->cs); + + return hr; } static HRESULT WINAPI mfattributes_GetAllocatedBlob(IMFAttributes *iface, REFGUID key, UINT8 **buf, UINT32 *size) { - FIXME("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size); + struct attributes *attributes = impl_from_IMFAttributes(iface); + PROPVARIANT attrval; + HRESULT hr; - return E_NOTIMPL; + TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size); + + attrval.vt = VT_VECTOR | VT_UI1; + hr = attributes_get_item(attributes, key, &attrval); + if (SUCCEEDED(hr)) + { + *buf = attrval.u.caub.pElems; + *size = attrval.u.caub.cElems; + } + + return hr; } static HRESULT WINAPI mfattributes_GetUnknown(IMFAttributes *iface, REFGUID key, REFIID riid, void **ppv) @@ -1070,9 +1130,15 @@ static HRESULT WINAPI mfattributes_SetString(IMFAttributes *iface, REFGUID key, static HRESULT WINAPI mfattributes_SetBlob(IMFAttributes *iface, REFGUID key, const UINT8 *buf, UINT32 size) { - FIXME("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size); + struct attributes *attributes = impl_from_IMFAttributes(iface); + PROPVARIANT attrval; - return E_NOTIMPL; + TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size); + + attrval.vt = VT_VECTOR | VT_UI1; + attrval.u.caub.cElems = size; + attrval.u.caub.pElems = (UINT8 *)buf; + return attributes_set_item(attributes, key, &attrval); } static HRESULT WINAPI mfattributes_SetUnknown(IMFAttributes *iface, REFGUID key, IUnknown *unknown) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 73367b67ad8..edf3c6e694d 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -501,9 +501,11 @@ static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line) static void test_MFCreateAttributes(void) { static const WCHAR stringW[] = {'W','i','n','e',0}; + static const UINT8 blob[] = {0,1,2,3,4,5}; IMFAttributes *attributes, *attributes1; + UINT8 blob_value[256], *blob_buf = NULL; + UINT32 value, string_length, size; PROPVARIANT propvar, ret_propvar; - UINT32 value, string_length; double double_value; IUnknown *unk_value; WCHAR bufferW[256]; @@ -724,6 +726,40 @@ static void test_MFCreateAttributes(void) ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr); CHECK_ATTR_COUNT(attributes, 0); + /* Blob */ + hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob)); + ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr); + CHECK_ATTR_COUNT(attributes, 1); + hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size); + ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr); + ok(size == sizeof(blob), "Unexpected blob size %u.\n", size); + + hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr); + + size = 0; + hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size); + ok(hr == S_OK, "Failed to get blob, hr %#x.\n", hr); + ok(size == sizeof(blob), "Unexpected blob size %u.\n", size); + ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n"); + + hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr); + + memset(blob_value, 0, sizeof(blob_value)); + size = 0; + hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size); + ok(hr == S_OK, "Failed to get allocated blob, hr %#x.\n", hr); + ok(size == sizeof(blob), "Unexpected blob size %u.\n", size); + ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n"); + CoTaskMemFree(blob_buf); + + hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr); + + hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL); + ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr); + IMFAttributes_Release(attributes); IMFAttributes_Release(attributes1); }