Commit 00544351 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

mfplat: Implement MFTGetInfo().

parent 6dbaba7c
...@@ -631,7 +631,7 @@ static const BYTE guid_conv_table[256] = ...@@ -631,7 +631,7 @@ static const BYTE guid_conv_table[256] =
0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */ 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */
}; };
static WCHAR* GUIDToString(WCHAR *str, REFGUID guid) static WCHAR* guid_to_string(WCHAR *str, REFGUID guid)
{ {
swprintf(str, 39, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", swprintf(str, 39, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1],
...@@ -706,7 +706,7 @@ static HRESULT register_transform(const CLSID *clsid, const WCHAR *name, UINT32 ...@@ -706,7 +706,7 @@ static HRESULT register_transform(const CLSID *clsid, const WCHAR *name, UINT32
WCHAR str[250]; WCHAR str[250];
UINT8 *blob; UINT8 *blob;
GUIDToString(buffer, clsid); guid_to_string(buffer, clsid);
swprintf(str, ARRAY_SIZE(str), L"%s\\%s", transform_keyW, buffer); swprintf(str, ARRAY_SIZE(str), L"%s\\%s", transform_keyW, buffer);
if ((ret = RegCreateKeyW(HKEY_CLASSES_ROOT, str, &hclsid))) if ((ret = RegCreateKeyW(HKEY_CLASSES_ROOT, str, &hclsid)))
...@@ -767,8 +767,8 @@ static HRESULT register_category(CLSID *clsid, GUID *category) ...@@ -767,8 +767,8 @@ static HRESULT register_category(CLSID *clsid, GUID *category)
WCHAR guid1[64], guid2[64]; WCHAR guid1[64], guid2[64];
WCHAR str[350]; WCHAR str[350];
GUIDToString(guid1, category); guid_to_string(guid1, category);
GUIDToString(guid2, clsid); guid_to_string(guid2, clsid);
swprintf(str, ARRAY_SIZE(str), L"%s\\%s\\%s", categories_keyW, guid1, guid2); swprintf(str, ARRAY_SIZE(str), L"%s\\%s\\%s", categories_keyW, guid1, guid2);
...@@ -1030,7 +1030,7 @@ static BOOL mft_is_type_info_match(struct mft_registration *mft, const GUID *cat ...@@ -1030,7 +1030,7 @@ static BOOL mft_is_type_info_match(struct mft_registration *mft, const GUID *cat
return matching; return matching;
} }
static void mft_get_reg_type_info(const WCHAR *clsidW, const WCHAR *typeW, MFT_REGISTER_TYPE_INFO **type, static void mft_get_reg_type_info_internal(const WCHAR *clsidW, const WCHAR *typeW, MFT_REGISTER_TYPE_INFO **type,
UINT32 *count) UINT32 *count)
{ {
HKEY htransform, hfilter; HKEY htransform, hfilter;
...@@ -1109,7 +1109,7 @@ static HRESULT mft_collect_machine_reg(struct list *mfts, const GUID *category, ...@@ -1109,7 +1109,7 @@ static HRESULT mft_collect_machine_reg(struct list *mfts, const GUID *category,
if (RegOpenKeyW(HKEY_CLASSES_ROOT, categories_keyW, &hcategory)) if (RegOpenKeyW(HKEY_CLASSES_ROOT, categories_keyW, &hcategory))
return E_FAIL; return E_FAIL;
GUIDToString(clsidW, category); guid_to_string(clsidW, category);
ret = RegOpenKeyW(hcategory, clsidW, &hlist); ret = RegOpenKeyW(hcategory, clsidW, &hlist);
RegCloseKey(hcategory); RegCloseKey(hcategory);
if (ret) if (ret)
...@@ -1126,10 +1126,10 @@ static HRESULT mft_collect_machine_reg(struct list *mfts, const GUID *category, ...@@ -1126,10 +1126,10 @@ static HRESULT mft_collect_machine_reg(struct list *mfts, const GUID *category,
mft_get_reg_flags(clsidW, L"MFTFlags", &mft.flags); mft_get_reg_flags(clsidW, L"MFTFlags", &mft.flags);
if (output_type) if (output_type)
mft_get_reg_type_info(clsidW, L"OutputTypes", &mft.output_types, &mft.output_types_count); mft_get_reg_type_info_internal(clsidW, L"OutputTypes", &mft.output_types, &mft.output_types_count);
if (input_type) if (input_type)
mft_get_reg_type_info(clsidW, L"InputTypes", &mft.input_types, &mft.input_types_count); mft_get_reg_type_info_internal(clsidW, L"InputTypes", &mft.input_types, &mft.input_types_count);
if (!mft_is_type_info_match(&mft, category, flags, plugin_control, input_type, output_type)) if (!mft_is_type_info_match(&mft, category, flags, plugin_control, input_type, output_type))
{ {
...@@ -1416,7 +1416,7 @@ HRESULT WINAPI MFTUnregister(CLSID clsid) ...@@ -1416,7 +1416,7 @@ HRESULT WINAPI MFTUnregister(CLSID clsid)
TRACE("(%s)\n", debugstr_guid(&clsid)); TRACE("(%s)\n", debugstr_guid(&clsid));
GUIDToString(buffer, &clsid); guid_to_string(buffer, &clsid);
if (!RegOpenKeyW(HKEY_CLASSES_ROOT, transform_keyW, &htransform)) if (!RegOpenKeyW(HKEY_CLASSES_ROOT, transform_keyW, &htransform))
{ {
...@@ -1442,6 +1442,141 @@ HRESULT WINAPI MFTUnregister(CLSID clsid) ...@@ -1442,6 +1442,141 @@ HRESULT WINAPI MFTUnregister(CLSID clsid)
return S_OK; return S_OK;
} }
static HRESULT mft_get_name(HKEY hkey, WCHAR **name)
{
DWORD size;
if (!name)
return S_OK;
*name = NULL;
if (!RegQueryValueExW(hkey, NULL, NULL, NULL, NULL, &size))
{
if (!(*name = CoTaskMemAlloc(size)))
return E_OUTOFMEMORY;
RegQueryValueExW(hkey, NULL, NULL, NULL, (BYTE *)*name, &size);
}
return S_OK;
}
static HRESULT mft_get_reg_type_info(const WCHAR *clsid, const WCHAR *key, MFT_REGISTER_TYPE_INFO **ret_types,
UINT32 *ret_count)
{
MFT_REGISTER_TYPE_INFO *types = NULL;
UINT32 count = 0;
if (!ret_types)
return S_OK;
mft_get_reg_type_info_internal(clsid, key, &types, &count);
if (count)
{
if (!(*ret_types = CoTaskMemAlloc(count * sizeof(**ret_types))))
{
free(types);
return E_OUTOFMEMORY;
}
memcpy(*ret_types, types, count * sizeof(**ret_types));
*ret_count = count;
}
free(types);
return S_OK;
}
static HRESULT mft_get_attributes(HKEY hkey, IMFAttributes **ret)
{
IMFAttributes *attributes;
UINT8 *blob;
DWORD size;
HRESULT hr;
if (!ret)
return S_OK;
if (FAILED(hr = MFCreateAttributes(&attributes, 0)))
return hr;
if (!RegQueryValueExW(hkey, L"Attributes", NULL, NULL, NULL, &size) && size)
{
if (!(blob = malloc(size)))
{
IMFAttributes_Release(attributes);
return E_OUTOFMEMORY;
}
if (!RegQueryValueExW(hkey, L"Attributes", NULL, NULL, blob, &size))
{
if (FAILED(hr = MFInitAttributesFromBlob(attributes, blob, size)))
WARN("Failed to initialize attributes, hr %#x.\n", hr);
}
free(blob);
}
if (SUCCEEDED(hr))
{
*ret = attributes;
IMFAttributes_AddRef(*ret);
}
IMFAttributes_Release(attributes);
return hr;
}
/***********************************************************************
* MFTGetInfo (mfplat.@)
*/
HRESULT WINAPI MFTGetInfo(CLSID clsid, WCHAR **name, MFT_REGISTER_TYPE_INFO **input_types,
UINT32 *input_types_count, MFT_REGISTER_TYPE_INFO **output_types, UINT32 *output_types_count,
IMFAttributes **attributes)
{
HRESULT hr = S_OK;
WCHAR clsidW[64];
HKEY hroot, hmft;
DWORD ret;
TRACE("%s, %p, %p, %p, %p, %p, %p.\n", debugstr_guid(&clsid), name, input_types,
input_types_count, output_types, output_types_count, attributes);
guid_to_string(clsidW, &clsid);
if ((ret = RegOpenKeyW(HKEY_CLASSES_ROOT, transform_keyW, &hroot)))
return HRESULT_FROM_WIN32(ret);
ret = RegOpenKeyW(hroot, clsidW, &hmft);
RegCloseKey(hroot);
if (ret)
return HRESULT_FROM_WIN32(ret);
if (input_types_count)
*input_types_count = 0;
if (output_types_count)
*output_types_count = 0;
hr = mft_get_name(hmft, name);
if (SUCCEEDED(hr))
hr = mft_get_reg_type_info(clsidW, L"InputTypes", input_types, input_types_count);
if (SUCCEEDED(hr))
hr = mft_get_reg_type_info(clsidW, L"OutputTypes", output_types, output_types_count);
if (SUCCEEDED(hr))
hr = mft_get_attributes(hmft, attributes);
RegCloseKey(hmft);
return hr;
}
/*********************************************************************** /***********************************************************************
* MFStartup (mfplat.@) * MFStartup (mfplat.@)
*/ */
......
...@@ -160,7 +160,7 @@ ...@@ -160,7 +160,7 @@
@ stdcall MFTEnum(int128 long ptr ptr ptr ptr ptr) @ stdcall MFTEnum(int128 long ptr ptr ptr ptr ptr)
@ stdcall MFTEnum2(int128 long ptr ptr ptr ptr ptr) @ stdcall MFTEnum2(int128 long ptr ptr ptr ptr ptr)
@ stdcall MFTEnumEx(int128 long ptr ptr ptr ptr) @ stdcall MFTEnumEx(int128 long ptr ptr ptr ptr)
@ stub MFTGetInfo @ stdcall MFTGetInfo(int128 ptr ptr ptr ptr ptr ptr)
@ stdcall MFTRegister(int128 int128 wstr long long ptr long ptr ptr) @ stdcall MFTRegister(int128 int128 wstr long long ptr long ptr ptr)
@ stdcall MFTRegisterLocal(ptr ptr wstr long long ptr long ptr) @ stdcall MFTRegisterLocal(ptr ptr wstr long long ptr long ptr)
@ stdcall MFTRegisterLocalByCLSID(ptr ptr wstr long long ptr long ptr) @ stdcall MFTRegisterLocalByCLSID(ptr ptr wstr long long ptr long ptr)
......
...@@ -396,6 +396,7 @@ static BOOL check_clsid(CLSID *clsids, UINT32 count) ...@@ -396,6 +396,7 @@ static BOOL check_clsid(CLSID *clsids, UINT32 count)
static void test_register(void) static void test_register(void)
{ {
MFT_REGISTER_TYPE_INFO *in_types, *out_types;
WCHAR name[] = L"Wine test"; WCHAR name[] = L"Wine test";
MFT_REGISTER_TYPE_INFO input[] = MFT_REGISTER_TYPE_INFO input[] =
{ {
...@@ -405,17 +406,19 @@ static void test_register(void) ...@@ -405,17 +406,19 @@ static void test_register(void)
{ {
{ DUMMY_CLSID, DUMMY_GUID2 } { DUMMY_CLSID, DUMMY_GUID2 }
}; };
UINT32 count, in_count, out_count;
IMFAttributes *attributes;
WCHAR *mft_name;
CLSID *clsids; CLSID *clsids;
UINT32 count; HRESULT hr, ret;
HRESULT ret;
ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL); ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
if (ret == E_ACCESSDENIED) if (ret == E_ACCESSDENIED)
{ {
win_skip("Not enough permissions to register a filter\n"); win_skip("Not enough permissions to register a transform.\n");
return; return;
} }
ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret); ok(ret == S_OK, "Failed to register dummy transform, hr %#x.\n", ret);
if(0) if(0)
{ {
...@@ -445,6 +448,49 @@ if(0) ...@@ -445,6 +448,49 @@ if(0)
ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL); ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret); ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
} }
hr = MFTGetInfo(DUMMY_CLSID, &mft_name, NULL, NULL, NULL, NULL, NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
CoTaskMemFree(mft_name);
hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
in_count = out_count = 1;
hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, &in_count, NULL, &out_count, NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!in_count, "Unexpected count %u.\n", in_count);
ok(!out_count, "Unexpected count %u.\n", out_count);
hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, &attributes);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!!attributes, "Unexpected attributes.\n");
IMFAttributes_Release(attributes);
hr = MFTGetInfo(DUMMY_CLSID, &mft_name, &in_types, &in_count, &out_types, &out_count, &attributes);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
ok(!!in_types, "Unexpected pointer.\n");
ok(!!out_types, "Unexpected pointer.\n");
ok(in_count == 1, "Unexpected count %u.\n", in_count);
ok(out_count == 1, "Unexpected count %u.\n", out_count);
ok(IsEqualGUID(&in_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
wine_dbgstr_guid(&in_types->guidMajorType));
ok(IsEqualGUID(&in_types->guidSubtype, &DUMMY_GUID1), "Unexpected type guid %s.\n",
wine_dbgstr_guid(&in_types->guidSubtype));
ok(IsEqualGUID(&out_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
wine_dbgstr_guid(&out_types->guidMajorType));
ok(IsEqualGUID(&out_types->guidSubtype, &DUMMY_GUID2), "Unexpected type guid %s.\n",
wine_dbgstr_guid(&out_types->guidSubtype));
ok(!!attributes, "Unexpected attributes.\n");
count = 1;
hr = IMFAttributes_GetCount(attributes, &count);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!count, "Unexpected count %u.\n", count);
CoTaskMemFree(mft_name);
CoTaskMemFree(in_types);
CoTaskMemFree(out_types);
IMFAttributes_Release(attributes);
count = 0; count = 0;
clsids = NULL; clsids = NULL;
...@@ -5213,9 +5259,11 @@ static const IClassFactoryVtbl test_mft_factory_vtbl = ...@@ -5213,9 +5259,11 @@ static const IClassFactoryVtbl test_mft_factory_vtbl =
static void test_MFTRegisterLocal(void) static void test_MFTRegisterLocal(void)
{ {
IClassFactory test_factory = { &test_mft_factory_vtbl }; IClassFactory test_factory = { &test_mft_factory_vtbl };
MFT_REGISTER_TYPE_INFO input_types[1]; MFT_REGISTER_TYPE_INFO input_types[1], *in_types, *out_types;
IMFAttributes *attributes;
IMFActivate **activate; IMFActivate **activate;
UINT32 count, count2; UINT32 count, count2;
WCHAR *name;
HRESULT hr; HRESULT hr;
if (!pMFTRegisterLocal) if (!pMFTRegisterLocal)
...@@ -5255,6 +5303,9 @@ static void test_MFTRegisterLocal(void) ...@@ -5255,6 +5303,9 @@ static void test_MFTRegisterLocal(void)
0, NULL); 0, NULL);
ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr); ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
hr = MFTGetInfo(MFT_CATEGORY_OTHER, &name, &in_types, &count, &out_types, &count2, &attributes);
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#x.\n", hr);
hr = pMFTUnregisterLocal(NULL); hr = pMFTUnregisterLocal(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
......
...@@ -558,6 +558,8 @@ HRESULT WINAPI MFTEnum2(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INF ...@@ -558,6 +558,8 @@ HRESULT WINAPI MFTEnum2(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INF
HRESULT WINAPI MFTEnumEx(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type, HRESULT WINAPI MFTEnumEx(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate,
UINT32 *pcount); UINT32 *pcount);
HRESULT WINAPI MFTGetInfo(CLSID clsid, WCHAR **name, MFT_REGISTER_TYPE_INFO **input_types, UINT32 *input_types_count,
MFT_REGISTER_TYPE_INFO **output_types, UINT32 *output_types_count, IMFAttributes **attributes);
BOOL WINAPI MFIsFormatYUV(DWORD format); BOOL WINAPI MFIsFormatYUV(DWORD format);
HRESULT WINAPI MFInitAttributesFromBlob(IMFAttributes *attributes, const UINT8 *buffer, UINT size); HRESULT WINAPI MFInitAttributesFromBlob(IMFAttributes *attributes, const UINT8 *buffer, UINT size);
HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size); HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment