static HRESULT WINAPI MediaDet_get_Filename(IMediaDet* iface, BSTR *pVal) { MediaDetImpl *This = impl_from_IMediaDet(iface); IFileSourceFilter *file; LPOLESTR name; HRESULT hr; TRACE("(%p)\n", This); if (!pVal) return E_POINTER; *pVal = NULL; /* MSDN says it should return E_FAIL if no file is open, but tests show otherwise. */ if (!This->source) return S_OK; hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter, (void **) &file); if (FAILED(hr)) return hr; hr = IFileSourceFilter_GetCurFile(file, &name, NULL); IFileSourceFilter_Release(file); if (FAILED(hr)) return hr; *pVal = SysAllocString(name); CoTaskMemFree(name); if (!*pVal) return E_OUTOFMEMORY; return S_OK; }
static HRESULT GetSplitter(MediaDetImpl *This) { IFileSourceFilter *file; LPOLESTR name; AM_MEDIA_TYPE mt; GUID type[2]; IFilterMapper2 *map; IEnumMoniker *filters; IMoniker *mon; VARIANT var; GUID clsid; IBaseFilter *splitter; IEnumPins *pins; IPin *source_pin, *splitter_pin; HRESULT hr; hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (void **) &map); if (FAILED(hr)) return hr; hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter, (void **) &file); if (FAILED(hr)) { IFilterMapper2_Release(map); return hr; } hr = IFileSourceFilter_GetCurFile(file, &name, &mt); IFileSourceFilter_Release(file); CoTaskMemFree(name); if (FAILED(hr)) { IFilterMapper2_Release(map); return hr; } type[0] = mt.majortype; type[1] = mt.subtype; CoTaskMemFree(mt.pbFormat); hr = IFilterMapper2_EnumMatchingFilters(map, &filters, 0, TRUE, MERIT_UNLIKELY, FALSE, 1, type, NULL, NULL, FALSE, TRUE, 0, NULL, NULL, NULL); IFilterMapper2_Release(map); if (FAILED(hr)) return hr; hr = E_NOINTERFACE; while (IEnumMoniker_Next(filters, 1, &mon, NULL) == S_OK) { hr = GetFilterInfo(mon, &clsid, &var); IMoniker_Release(mon); if (FAILED(hr)) continue; hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void **) &splitter); if (FAILED(hr)) { VariantClear(&var); continue; } hr = IGraphBuilder_AddFilter(This->graph, splitter, V_UNION(&var, bstrVal)); VariantClear(&var); This->splitter = splitter; if (FAILED(hr)) goto retry; hr = IBaseFilter_EnumPins(This->source, &pins); if (FAILED(hr)) goto retry; IEnumPins_Next(pins, 1, &source_pin, NULL); IEnumPins_Release(pins); hr = IBaseFilter_EnumPins(splitter, &pins); if (FAILED(hr)) { IPin_Release(source_pin); goto retry; } IEnumPins_Next(pins, 1, &splitter_pin, NULL); IEnumPins_Release(pins); hr = IPin_Connect(source_pin, splitter_pin, NULL); IPin_Release(source_pin); IPin_Release(splitter_pin); if (SUCCEEDED(hr)) break; retry: IBaseFilter_Release(splitter); This->splitter = NULL; } IEnumMoniker_Release(filters); if (FAILED(hr)) return hr; return S_OK; }
static void test_filesourcefilter(void) { static const WCHAR prefix[] = {'w','i','n',0}; static const struct { const char *label; const char *data; DWORD size; const GUID *subtype; } tests[] = { { "AVI", "\x52\x49\x46\x46xxxx\x41\x56\x49\x20", 12, &MEDIASUBTYPE_Avi, }, { "MPEG1 System", "\x00\x00\x01\xBA\x21\x00\x01\x00\x01\x80\x00\x01\x00\x00\x01\xBB", 16, &MEDIASUBTYPE_MPEG1System, }, { "MPEG1 Video", "\x00\x00\x01\xB3", 4, &MEDIASUBTYPE_MPEG1Video, }, { "MPEG1 Audio", "\xFF\xE0", 2, &MEDIASUBTYPE_MPEG1Audio, }, { "MPEG2 Program", "\x00\x00\x01\xBA\x40", 5, &MEDIASUBTYPE_MPEG2_PROGRAM, }, { "WAVE", "\x52\x49\x46\x46xxxx\x57\x41\x56\x45", 12, &MEDIASUBTYPE_WAVE, }, { "unknown format", "Hello World", 11, NULL, /* FIXME: should be &MEDIASUBTYPE_NULL */ }, }; WCHAR path[MAX_PATH], temp[MAX_PATH]; IFileSourceFilter *filesource; DWORD ret, written; IBaseFilter *base; AM_MEDIA_TYPE mt; OLECHAR *olepath; BOOL success; HANDLE file; HRESULT hr; int i; ret = GetTempPathW(MAX_PATH, temp); ok(ret, "GetTempPathW failed with error %u\n", GetLastError()); ret = GetTempFileNameW(temp, prefix, 0, path); ok(ret, "GetTempFileNameW failed with error %u\n", GetLastError()); for (i = 0; i < ARRAY_SIZE(tests); i++) { trace("Running test for %s\n", tests[i].label); file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); ok(file != INVALID_HANDLE_VALUE, "CreateFileW failed with error %u\n", GetLastError()); success = WriteFile(file, tests[i].data, tests[i].size, &written, NULL); ok(success, "WriteFile failed with error %u\n", GetLastError()); ok(written == tests[i].size, "could not write test data\n"); CloseHandle(file); hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void **)&base); ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr); hr = IBaseFilter_QueryInterface(base, &IID_IFileSourceFilter, (void **)&filesource); ok(hr == S_OK, "IBaseFilter_QueryInterface failed with %08x\n", hr); olepath = (void *)0xdeadbeef; hr = IFileSourceFilter_GetCurFile(filesource, &olepath, NULL); ok(hr == S_OK, "expected S_OK, got %08x\n", hr); ok(olepath == NULL, "expected NULL, got %p\n", olepath); hr = IFileSourceFilter_Load(filesource, NULL, NULL); ok(hr == E_POINTER, "expected E_POINTER, got %08x\n", hr); hr = IFileSourceFilter_Load(filesource, path, NULL); ok(hr == S_OK, "IFileSourceFilter_Load failed with %08x\n", hr); hr = IFileSourceFilter_GetCurFile(filesource, NULL, &mt); ok(hr == E_POINTER, "expected E_POINTER, got %08x\n", hr); olepath = NULL; hr = IFileSourceFilter_GetCurFile(filesource, &olepath, NULL); ok(hr == S_OK, "expected S_OK, got %08x\n", hr); CoTaskMemFree(olepath); olepath = NULL; memset(&mt, 0x11, sizeof(mt)); hr = IFileSourceFilter_GetCurFile(filesource, &olepath, &mt); ok(hr == S_OK, "expected S_OK, got %08x\n", hr); ok(!lstrcmpW(olepath, path), "expected %s, got %s\n", wine_dbgstr_w(path), wine_dbgstr_w(olepath)); if (tests[i].subtype) { ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Stream), "expected MEDIATYPE_Stream, got %s\n", wine_dbgstr_guid(&mt.majortype)); ok(IsEqualGUID(&mt.subtype, tests[i].subtype), "expected %s, got %s\n", wine_dbgstr_guid(tests[i].subtype), wine_dbgstr_guid(&mt.subtype)); } CoTaskMemFree(olepath); IFileSourceFilter_Release(filesource); IBaseFilter_Release(base); success = DeleteFileW(path); ok(success, "DeleteFileW failed with error %u\n", GetLastError()); } }