Module: wine Branch: master Commit: 0e93b08f6e81799f943159e529c3fa1e767d0d02 URL: http://source.winehq.org/git/wine.git/?a=commit;h=0e93b08f6e81799f943159e529...
Author: Michael Müller michael@fds-team.de Date: Mon May 8 22:50:50 2017 +0000
mfplat: Implement MFTEnum.
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mfplat/Makefile.in | 2 +- dlls/mfplat/main.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 2 +- include/mfapi.h | 3 + 4 files changed, 188 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/Makefile.in b/dlls/mfplat/Makefile.in index 8af0525..1a3ac3a 100644 --- a/dlls/mfplat/Makefile.in +++ b/dlls/mfplat/Makefile.in @@ -1,5 +1,5 @@ MODULE = mfplat.dll -IMPORTS = advapi32 +IMPORTS = advapi32 ole32
C_SRCS = \ main.c diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index b54dc9d..c1c7003 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -18,6 +18,7 @@ */
#include <stdarg.h> +#include <string.h>
#define COBJMACROS
@@ -49,6 +50,17 @@ static const WCHAR szGUIDFmt[] = 'x','%','0','2','x','%','0','2','x','%','0','2','x',0 };
+static const BYTE guid_conv_table[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */ + 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */ + 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */ +}; + static WCHAR* GUIDToString(WCHAR *str, REFGUID guid) { sprintfW(str, szGUIDFmt, guid->Data1, guid->Data2, @@ -59,6 +71,60 @@ static WCHAR* GUIDToString(WCHAR *str, REFGUID guid) return str; }
+static inline BOOL is_valid_hex(WCHAR c) +{ + if (!(((c >= '0') && (c <= '9')) || + ((c >= 'a') && (c <= 'f')) || + ((c >= 'A') && (c <= 'F')))) + return FALSE; + return TRUE; +} + +static BOOL GUIDFromString(LPCWSTR s, GUID *id) +{ + int i; + + /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */ + + id->Data1 = 0; + for (i = 0; i < 8; i++) + { + if (!is_valid_hex(s[i])) return FALSE; + id->Data1 = (id->Data1 << 4) | guid_conv_table[s[i]]; + } + if (s[8]!='-') return FALSE; + + id->Data2 = 0; + for (i = 9; i < 13; i++) + { + if (!is_valid_hex(s[i])) return FALSE; + id->Data2 = (id->Data2 << 4) | guid_conv_table[s[i]]; + } + if (s[13]!='-') return FALSE; + + id->Data3 = 0; + for (i = 14; i < 18; i++) + { + if (!is_valid_hex(s[i])) return FALSE; + id->Data3 = (id->Data3 << 4) | guid_conv_table[s[i]]; + } + if (s[18]!='-') return FALSE; + + for (i = 19; i < 36; i+=2) + { + if (i == 23) + { + if (s[i]!='-') return FALSE; + i++; + } + if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return FALSE; + id->Data4[(i-19)/2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i+1]]; + } + + if (!s[37]) return TRUE; + return FALSE; +} + BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) @@ -163,6 +229,123 @@ HRESULT WINAPI MFTRegister(CLSID clsid, GUID category, LPWSTR name, UINT32 flags return hr; }
+static BOOL match_type(const WCHAR *clsid_str, const WCHAR *type_str, MFT_REGISTER_TYPE_INFO *type) +{ + HKEY htransform, hfilter; + DWORD reg_type, size; + LONG ret = FALSE; + MFT_REGISTER_TYPE_INFO *info = NULL; + int i; + + if (RegOpenKeyW(HKEY_CLASSES_ROOT, transform_keyW, &htransform)) + return FALSE; + + if (RegOpenKeyW(htransform, clsid_str, &hfilter)) + { + RegCloseKey(htransform); + return FALSE; + } + + if (RegQueryValueExW(hfilter, type_str, NULL, ®_type, NULL, &size) != ERROR_SUCCESS) + goto out; + + if (reg_type != REG_BINARY) + goto out; + + if (!size || size % (sizeof(MFT_REGISTER_TYPE_INFO)) != 0) + goto out; + + info = HeapAlloc(GetProcessHeap(), 0, size); + if (!info) + goto out; + + if (RegQueryValueExW(hfilter, type_str, NULL, ®_type, (LPBYTE)info, &size) != ERROR_SUCCESS) + goto out; + + for (i = 0; i < size / sizeof(MFT_REGISTER_TYPE_INFO) + 1; i++) + { + if (IsEqualGUID(&info[i].guidMajorType, &type->guidMajorType) && + IsEqualGUID(&info[i].guidSubtype, &type->guidSubtype)) + { + ret = TRUE; + break; + } + } + +out: + HeapFree(GetProcessHeap(), 0, info); + RegCloseKey(hfilter); + RegCloseKey(htransform); + return ret; +} + +/*********************************************************************** + * MFTEnum (mfplat.@) + */ +HRESULT WINAPI MFTEnum(GUID category, UINT32 flags, MFT_REGISTER_TYPE_INFO *input_type, + MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, + CLSID **pclsids, UINT32 *pcount) +{ + WCHAR buffer[64], clsid_str[MAX_PATH] = {0}; + HKEY hcategory, hlist; + DWORD index = 0; + DWORD size = MAX_PATH; + CLSID *clsids = NULL; + UINT32 count = 0; + LONG ret; + + TRACE("(%s, %x, %p, %p, %p, %p, %p)\n", debugstr_guid(&category), flags, input_type, + output_type, attributes, pclsids, pcount); + + if (!pclsids || !pcount) + return E_INVALIDARG; + + if (RegOpenKeyW(HKEY_CLASSES_ROOT, categories_keyW, &hcategory)) + return E_FAIL; + + GUIDToString(buffer, &category); + + ret = RegOpenKeyW(hcategory, buffer, &hlist); + RegCloseKey(hcategory); + if (ret) return E_FAIL; + + while (RegEnumKeyExW(hlist, index, clsid_str, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + GUID clsid; + void *tmp; + + if (!GUIDFromString(clsid_str, &clsid)) + goto next; + + if (output_type && !match_type(clsid_str, outputtypesW, output_type)) + goto next; + + if (input_type && !match_type(clsid_str, inputtypesW, input_type)) + goto next; + + tmp = CoTaskMemRealloc(clsids, (count + 1) * sizeof(GUID)); + if (!tmp) + { + CoTaskMemFree(clsids); + RegCloseKey(hlist); + return E_OUTOFMEMORY; + } + + clsids = tmp; + clsids[count++] = clsid; + + next: + size = MAX_PATH; + index++; + } + + *pclsids = clsids; + *pcount = count; + + RegCloseKey(hlist); + return S_OK; +} + /*********************************************************************** * MFTUnregister (mfplat.@) */ diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index dc6f402..d96eb51 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -134,7 +134,7 @@ @ stdcall MFShutdown() @ stdcall MFStartup(long long) @ stub MFStreamDescriptorProtectMediaType -@ stub MFTEnum +@ stdcall MFTEnum(int128 long ptr ptr ptr ptr ptr) @ stub MFTEnumEx @ stub MFTGetInfo @ stdcall MFTRegister(int128 int128 wstr long long ptr long ptr ptr) diff --git a/include/mfapi.h b/include/mfapi.h index a37d655..35641dd 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -32,6 +32,9 @@ typedef unsigned __int64 MFWORKITEM_KEY; HRESULT WINAPI MFCancelWorkItem(MFWORKITEM_KEY key); HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size); HRESULT WINAPI MFGetTimerPeriodicity(DWORD *periodicity); +HRESULT WINAPI MFTEnum(GUID category, UINT32 flags, MFT_REGISTER_TYPE_INFO *input_type, + MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, + CLSID **pclsids, UINT32 *pcount); HRESULT WINAPI MFLockPlatform(void); HRESULT WINAPI MFTRegister(CLSID clsid, GUID category, LPWSTR name, UINT32 flags, UINT32 cinput, MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,