Alessandro Pignotti : quartz: Check byte patterns in GetFileSourceFilter.
Alexandre Julliard
julliard at winehq.org
Wed Feb 27 14:41:58 CST 2013
Module: wine
Branch: master
Commit: e583f8806eea8928d845dff1953f706d2c3ea207
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e583f8806eea8928d845dff1953f706d2c3ea207
Author: Alessandro Pignotti <a.pignotti at sssup.it>
Date: Thu Feb 21 16:57:50 2013 +0100
quartz: Check byte patterns in GetFileSourceFilter.
The idea is to create a temporary AsyncReader and use it to match a
better filter. If no match is found the temporary filter is returned.
---
dlls/quartz/filesource.c | 15 ++++-
dlls/quartz/filtergraph.c | 133 +++++++++++++++++++++++++++------------------
2 files changed, 92 insertions(+), 56 deletions(-)
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index 5bde1e5..95e146d 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -295,7 +295,8 @@ HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, GUID *
if (process_extensions(hkeyMajor, pszFileName, majorType, minorType, sourceFilter) == S_OK)
bFound = TRUE;
}
- else
+ /* We need a reader interface to check bytes */
+ else if (pReader)
{
DWORD indexMinor;
@@ -305,7 +306,7 @@ HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, GUID *
WCHAR wszMinorKeyName[CHARS_IN_GUID];
DWORD dwMinorKeyNameLen = sizeof(wszMinorKeyName) / sizeof(wszMinorKeyName[0]);
WCHAR wszSourceFilterKeyName[CHARS_IN_GUID];
- DWORD dwSourceFilterKeyNameLen = sizeof(wszSourceFilterKeyName) / sizeof(wszSourceFilterKeyName[0]);
+ DWORD dwSourceFilterKeyNameLen = sizeof(wszSourceFilterKeyName);
DWORD maxValueLen;
DWORD indexValue;
@@ -370,7 +371,15 @@ HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, GUID *
hr = E_FAIL;
}
else if (bFound)
- TRACE("Found file's class: major = %s, subtype = %s\n", qzdebugstr_guid(majorType), qzdebugstr_guid(minorType));
+ {
+ TRACE("Found file's class:\n");
+ if(majorType)
+ TRACE("\tmajor = %s\n", qzdebugstr_guid(majorType));
+ if(minorType)
+ TRACE("\tsubtype = %s\n", qzdebugstr_guid(minorType));
+ if(sourceFilter)
+ TRACE("\tsource filter = %s\n", qzdebugstr_guid(sourceFilter));
+ }
return hr;
}
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 4140d23..985e568 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -1556,61 +1556,97 @@ static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface, LPCWSTR lpcw
return hr;
}
+static HRESULT CreateFilterInstanceAndLoadFile(GUID* clsid, LPCOLESTR pszFileName, IBaseFilter **filter)
+{
+ IFileSourceFilter *source = NULL;
+ HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)filter);
+ TRACE("CLSID: %s\n", debugstr_guid(clsid));
+ if (FAILED(hr))
+ return hr;
+
+ hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID*)&source);
+ if (FAILED(hr))
+ {
+ IBaseFilter_Release(*filter);
+ return hr;
+ }
+
+ /* Load the file in the file source filter */
+ hr = IFileSourceFilter_Load(source, pszFileName, NULL);
+ IFileSourceFilter_Release(source);
+ if (FAILED(hr)) {
+ WARN("Load (%x)\n", hr);
+ IBaseFilter_Release(*filter);
+ return hr;
+ }
+
+ return hr;
+}
+
/* Some filters implement their own asynchronous reader (Theoretically they all should, try to load it first */
static HRESULT GetFileSourceFilter(LPCOLESTR pszFileName, IBaseFilter **filter)
{
- static const WCHAR wszReg[] = {'M','e','d','i','a',' ','T','y','p','e','\\','E','x','t','e','n','s','i','o','n','s',0};
- HRESULT hr = S_OK;
- HKEY extkey;
- LONG lRet;
+ HRESULT hr;
+ GUID clsid;
+ IAsyncReader * pReader = NULL;
+ IFileSourceFilter* pSource = NULL;
+ IPin * pOutputPin = NULL;
+ static const WCHAR wszOutputPinName[] = { 'O','u','t','p','u','t',0 };
- lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszReg, 0, KEY_READ, &extkey);
- hr = HRESULT_FROM_WIN32(lRet);
+ /* Try to find a match without reading the file first */
+ hr = GetClassMediaFile(NULL, pszFileName, NULL, NULL, &clsid);
- if (SUCCEEDED(hr))
+ if (!hr)
+ return CreateFilterInstanceAndLoadFile(&clsid, pszFileName, filter);
+
+ /* Now create a AyncReader instance, to check for signature bytes in the file */
+ hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)filter);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID *)&pSource);
+ if (FAILED(hr))
{
- static const WCHAR filtersource[] = {'S','o','u','r','c','e',' ','F','i','l','t','e','r',0};
- WCHAR *ext = PathFindExtensionW(pszFileName);
- WCHAR clsid_key[39];
- GUID clsid;
- DWORD size = sizeof(clsid_key);
- HKEY pathkey;
+ IBaseFilter_Release(*filter);
+ return hr;
+ }
- if (!ext)
- {
- CloseHandle(extkey);
- return E_FAIL;
- }
+ hr = IFileSourceFilter_Load(pSource, pszFileName, NULL);
+ IFileSourceFilter_Release(pSource);
+ if (FAILED(hr))
+ {
+ IBaseFilter_Release(*filter);
+ return hr;
+ }
- lRet = RegOpenKeyExW(extkey, ext, 0, KEY_READ, &pathkey);
- hr = HRESULT_FROM_WIN32(lRet);
- CloseHandle(extkey);
- if (FAILED(hr))
- return hr;
+ hr = IBaseFilter_FindPin(*filter, wszOutputPinName, &pOutputPin);
+ if (FAILED(hr))
+ {
+ IBaseFilter_Release(*filter);
+ return hr;
+ }
- lRet = RegQueryValueExW(pathkey, filtersource, NULL, NULL, (LPBYTE)clsid_key, &size);
- hr = HRESULT_FROM_WIN32(lRet);
- CloseHandle(pathkey);
- if (FAILED(hr))
- return hr;
+ hr = IPin_QueryInterface(pOutputPin, &IID_IAsyncReader, (LPVOID *)&pReader);
+ IPin_Release(pOutputPin);
+ if (FAILED(hr))
+ {
+ IBaseFilter_Release(*filter);
+ return hr;
+ }
- CLSIDFromString(clsid_key, &clsid);
+ /* Try again find a match */
+ hr = GetClassMediaFile(pReader, pszFileName, NULL, NULL, &clsid);
+ IAsyncReader_Release(pReader);
- TRACE("CLSID: %s\n", debugstr_guid(&clsid));
- hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)filter);
- if (SUCCEEDED(hr))
- {
- IFileSourceFilter *source = NULL;
- hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID*)&source);
- if (SUCCEEDED(hr))
- IFileSourceFilter_Release(source);
- else
- IBaseFilter_Release(*filter);
- }
+ if (!hr)
+ {
+ /* Release the AsyncReader filter and create the matching one */
+ IBaseFilter_Release(*filter);
+ return CreateFilterInstanceAndLoadFile(&clsid, pszFileName, filter);
}
- if (FAILED(hr))
- *filter = NULL;
- return hr;
+
+ /* Return the AsyncReader filter */
+ return S_OK;
}
static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface, LPCWSTR lpcwstrFileName,
@@ -1627,9 +1663,6 @@ static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface, LPCWSTR
/* Try from file name first, then fall back to default asynchronous reader */
hr = GetFileSourceFilter(lpcwstrFileName, &preader);
-
- if (FAILED(hr))
- hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&preader);
if (FAILED(hr)) {
WARN("Unable to create file source filter (%x)\n", hr);
return hr;
@@ -1648,13 +1681,7 @@ static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface, LPCWSTR
goto error;
}
- /* Load the file in the file source filter */
- hr = IFileSourceFilter_Load(pfile, lpcwstrFileName, NULL);
- if (FAILED(hr)) {
- WARN("Load (%x)\n", hr);
- goto error;
- }
-
+ /* The file has been already loaded */
IFileSourceFilter_GetCurFile(pfile, &filename, &mt);
if (FAILED(hr)) {
WARN("GetCurFile (%x)\n", hr);
More information about the wine-cvs
mailing list