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.
This commit is contained in:
parent
916854c5a8
commit
e583f8806e
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
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;
|
||||
if (!hr)
|
||||
return CreateFilterInstanceAndLoadFile(&clsid, pszFileName, filter);
|
||||
|
||||
if (!ext)
|
||||
{
|
||||
CloseHandle(extkey);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
lRet = RegOpenKeyExW(extkey, ext, 0, KEY_READ, &pathkey);
|
||||
hr = HRESULT_FROM_WIN32(lRet);
|
||||
CloseHandle(extkey);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
lRet = RegQueryValueExW(pathkey, filtersource, NULL, NULL, (LPBYTE)clsid_key, &size);
|
||||
hr = HRESULT_FROM_WIN32(lRet);
|
||||
CloseHandle(pathkey);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
CLSIDFromString(clsid_key, &clsid);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
/* 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))
|
||||
*filter = NULL;
|
||||
return hr;
|
||||
return hr;
|
||||
|
||||
hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID *)&pSource);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IBaseFilter_Release(*filter);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IFileSourceFilter_Load(pSource, pszFileName, NULL);
|
||||
IFileSourceFilter_Release(pSource);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IBaseFilter_Release(*filter);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IBaseFilter_FindPin(*filter, wszOutputPinName, &pOutputPin);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IBaseFilter_Release(*filter);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = IPin_QueryInterface(pOutputPin, &IID_IAsyncReader, (LPVOID *)&pReader);
|
||||
IPin_Release(pOutputPin);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
IBaseFilter_Release(*filter);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* Try again find a match */
|
||||
hr = GetClassMediaFile(pReader, pszFileName, NULL, NULL, &clsid);
|
||||
IAsyncReader_Release(pReader);
|
||||
|
||||
if (!hr)
|
||||
{
|
||||
/* Release the AsyncReader filter and create the matching one */
|
||||
IBaseFilter_Release(*filter);
|
||||
return CreateFilterInstanceAndLoadFile(&clsid, pszFileName, filter);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
|
Loading…
Reference in New Issue