ReactOS 0.4.15-dev-7942-gd23573b
filesource.c
Go to the documentation of this file.
1/*
2 * File Source Filter
3 *
4 * Copyright 2003 Robert Shearman
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#define NONAMELESSUNION
22#define NONAMELESSSTRUCT
23
24#include "quartz_private.h"
25
26#include "wine/debug.h"
27#include "wine/unicode.h"
28#include "pin.h"
29#include "uuids.h"
30#include "vfwmsgs.h"
31#include "winbase.h"
32#include "winreg.h"
33#include "shlwapi.h"
34#include <assert.h>
35
37
38static const WCHAR wszOutputPinName[] = { 'O','u','t','p','u','t',0 };
39
40typedef struct AsyncReader
41{
45
50
52{
53 return CONTAINING_RECORD(iface, AsyncReader, filter);
54}
55
57{
58 return CONTAINING_RECORD(iface, AsyncReader, filter.IBaseFilter_iface);
59}
60
62{
63 return CONTAINING_RECORD(iface, AsyncReader, IFileSourceFilter_iface);
64}
65
67{
68 return CONTAINING_RECORD(iface, AsyncReader, IAMFilterMiscFlags_iface);
69}
70
71static const IBaseFilterVtbl AsyncReader_Vtbl;
72static const IFileSourceFilterVtbl FileSource_Vtbl;
73static const IAsyncReaderVtbl FileAsyncReader_Vtbl;
74static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl;
75
76static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
77
78static const WCHAR mediatype_name[] = {
79 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 };
80static const WCHAR subtype_name[] = {
81 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 };
82static const WCHAR source_filter_name[] = {
83 'S','o','u','r','c','e',' ','F','i','l','t','e','r',0};
84
85static HRESULT process_extensions(HKEY hkeyExtensions, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType, GUID * sourceFilter)
86{
87 WCHAR *extension;
88 LONG l;
89 HKEY hsub;
90 WCHAR keying[39];
91 DWORD size;
92
93 if (!pszFileName)
94 return E_POINTER;
95
96 /* Get the part of the name that matters */
98 if (*extension != '.')
99 return E_FAIL;
100
101 l = RegOpenKeyExW(hkeyExtensions, extension, 0, KEY_READ, &hsub);
102 if (l)
103 return E_FAIL;
104
105 if (majorType)
106 {
107 size = sizeof(keying);
108 l = RegQueryValueExW(hsub, mediatype_name, NULL, NULL, (LPBYTE)keying, &size);
109 if (!l)
110 CLSIDFromString(keying, majorType);
111 }
112
113 if (minorType)
114 {
115 size = sizeof(keying);
116 if (!l)
117 l = RegQueryValueExW(hsub, subtype_name, NULL, NULL, (LPBYTE)keying, &size);
118 if (!l)
119 CLSIDFromString(keying, minorType);
120 }
121
122 if (sourceFilter)
123 {
124 size = sizeof(keying);
125 if (!l)
127 if (!l)
128 CLSIDFromString(keying, sourceFilter);
129 }
130
131 RegCloseKey(hsub);
132
133 if (!l)
134 return S_OK;
135 return E_FAIL;
136}
137
138static unsigned char byte_from_hex_char(WCHAR wHex)
139{
140 switch (tolowerW(wHex))
141 {
142 case '0':
143 case '1':
144 case '2':
145 case '3':
146 case '4':
147 case '5':
148 case '6':
149 case '7':
150 case '8':
151 case '9':
152 return (wHex - '0') & 0xf;
153 case 'a':
154 case 'b':
155 case 'c':
156 case 'd':
157 case 'e':
158 case 'f':
159 return (wHex - 'a' + 10) & 0xf;
160 default:
161 return 0;
162 }
163}
164
165static HRESULT process_pattern_string(LPCWSTR wszPatternString, IAsyncReader * pReader)
166{
167 ULONG ulOffset;
168 ULONG ulBytes;
169 BYTE * pbMask;
170 BYTE * pbValue;
171 BYTE * pbFile;
172 HRESULT hr = S_OK;
173 ULONG strpos;
174
175 TRACE("\t\tPattern string: %s\n", debugstr_w(wszPatternString));
176
177 /* format: "offset, bytestocompare, mask, value" */
178
179 ulOffset = strtolW(wszPatternString, NULL, 10);
180
181 if (!(wszPatternString = strchrW(wszPatternString, ',')))
182 return E_INVALIDARG;
183
184 wszPatternString++; /* skip ',' */
185
186 ulBytes = strtolW(wszPatternString, NULL, 10);
187
188 pbMask = HeapAlloc(GetProcessHeap(), 0, ulBytes);
189 pbValue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulBytes);
190 pbFile = HeapAlloc(GetProcessHeap(), 0, ulBytes);
191
192 /* default mask is match everything */
193 memset(pbMask, 0xFF, ulBytes);
194
195 if (!(wszPatternString = strchrW(wszPatternString, ',')))
197
198 if (hr == S_OK)
199 {
200 wszPatternString++; /* skip ',' */
201 while (!isxdigitW(*wszPatternString) && (*wszPatternString != ',')) wszPatternString++;
202
203 for (strpos = 0; isxdigitW(*wszPatternString) && (strpos/2 < ulBytes); wszPatternString++, strpos++)
204 {
205 if ((strpos % 2) == 1) /* odd numbered position */
206 pbMask[strpos / 2] |= byte_from_hex_char(*wszPatternString);
207 else
208 pbMask[strpos / 2] = byte_from_hex_char(*wszPatternString) << 4;
209 }
210
211 if (!(wszPatternString = strchrW(wszPatternString, ',')))
213 else
214 wszPatternString++; /* skip ',' */
215 }
216
217 if (hr == S_OK)
218 {
219 for ( ; !isxdigitW(*wszPatternString) && (*wszPatternString != ','); wszPatternString++)
220 ;
221
222 for (strpos = 0; isxdigitW(*wszPatternString) && (strpos/2 < ulBytes); wszPatternString++, strpos++)
223 {
224 if ((strpos % 2) == 1) /* odd numbered position */
225 pbValue[strpos / 2] |= byte_from_hex_char(*wszPatternString);
226 else
227 pbValue[strpos / 2] = byte_from_hex_char(*wszPatternString) << 4;
228 }
229 }
230
231 if (hr == S_OK)
232 hr = IAsyncReader_SyncRead(pReader, ulOffset, ulBytes, pbFile);
233
234 if (hr == S_OK)
235 {
236 ULONG i;
237 for (i = 0; i < ulBytes; i++)
238 if ((pbFile[i] & pbMask[i]) != pbValue[i])
239 {
240 hr = S_FALSE;
241 break;
242 }
243 }
244
245 HeapFree(GetProcessHeap(), 0, pbMask);
246 HeapFree(GetProcessHeap(), 0, pbValue);
247 HeapFree(GetProcessHeap(), 0, pbFile);
248
249 /* if we encountered no errors with this string, and there is a following tuple, then we
250 * have to match that as well to succeed */
251 if ((hr == S_OK) && (wszPatternString = strchrW(wszPatternString, ',')))
252 return process_pattern_string(wszPatternString + 1, pReader);
253 else
254 return hr;
255}
256
257HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType, GUID * sourceFilter)
258{
259 HKEY hkeyMediaType = NULL;
260 LONG lRet;
261 HRESULT hr = S_OK;
262 BOOL bFound = FALSE;
263 static const WCHAR wszMediaType[] = {'M','e','d','i','a',' ','T','y','p','e',0};
264
265 TRACE("(%p, %s, %p, %p)\n", pReader, debugstr_w(pszFileName), majorType, minorType);
266
267 if(majorType)
268 *majorType = GUID_NULL;
269 if(minorType)
270 *minorType = GUID_NULL;
271 if(sourceFilter)
272 *sourceFilter = GUID_NULL;
273
274 lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszMediaType, 0, KEY_READ, &hkeyMediaType);
275 hr = HRESULT_FROM_WIN32(lRet);
276
277 if (SUCCEEDED(hr))
278 {
279 DWORD indexMajor;
280
281 for (indexMajor = 0; !bFound; indexMajor++)
282 {
283 HKEY hkeyMajor;
284 WCHAR wszMajorKeyName[CHARS_IN_GUID];
285 DWORD dwKeyNameLength = sizeof(wszMajorKeyName) / sizeof(wszMajorKeyName[0]);
286 static const WCHAR wszExtensions[] = {'E','x','t','e','n','s','i','o','n','s',0};
287
288 if (RegEnumKeyExW(hkeyMediaType, indexMajor, wszMajorKeyName, &dwKeyNameLength, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
289 break;
290 if (RegOpenKeyExW(hkeyMediaType, wszMajorKeyName, 0, KEY_READ, &hkeyMajor) != ERROR_SUCCESS)
291 break;
292 TRACE("%s\n", debugstr_w(wszMajorKeyName));
293 if (!strcmpW(wszExtensions, wszMajorKeyName))
294 {
295 if (process_extensions(hkeyMajor, pszFileName, majorType, minorType, sourceFilter) == S_OK)
296 bFound = TRUE;
297 }
298 /* We need a reader interface to check bytes */
299 else if (pReader)
300 {
301 DWORD indexMinor;
302
303 for (indexMinor = 0; !bFound; indexMinor++)
304 {
305 HKEY hkeyMinor;
306 WCHAR wszMinorKeyName[CHARS_IN_GUID];
307 DWORD dwMinorKeyNameLen = sizeof(wszMinorKeyName) / sizeof(wszMinorKeyName[0]);
308 WCHAR wszSourceFilterKeyName[CHARS_IN_GUID];
309 DWORD dwSourceFilterKeyNameLen = sizeof(wszSourceFilterKeyName);
310 DWORD maxValueLen;
311 DWORD indexValue;
312
313 if (RegEnumKeyExW(hkeyMajor, indexMinor, wszMinorKeyName, &dwMinorKeyNameLen, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
314 break;
315
316 if (RegOpenKeyExW(hkeyMajor, wszMinorKeyName, 0, KEY_READ, &hkeyMinor) != ERROR_SUCCESS)
317 break;
318
319 TRACE("\t%s\n", debugstr_w(wszMinorKeyName));
320
321 if (RegQueryInfoKeyW(hkeyMinor, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &maxValueLen, NULL, NULL) != ERROR_SUCCESS)
322 break;
323
324 for (indexValue = 0; !bFound; indexValue++)
325 {
326 DWORD dwType;
327 WCHAR wszValueName[14]; /* longest name we should encounter will be "Source Filter" */
328 LPWSTR wszPatternString = HeapAlloc(GetProcessHeap(), 0, maxValueLen);
329 DWORD dwValueNameLen = sizeof(wszValueName) / sizeof(wszValueName[0]); /* remember this is in chars */
330 DWORD dwDataLen = maxValueLen; /* remember this is in bytes */
331
332 if (RegEnumValueW(hkeyMinor, indexValue, wszValueName, &dwValueNameLen, NULL, &dwType, (LPBYTE)wszPatternString, &dwDataLen) != ERROR_SUCCESS)
333 {
334 HeapFree(GetProcessHeap(), 0, wszPatternString);
335 break;
336 }
337
338 if (strcmpW(wszValueName, source_filter_name)==0) {
339 HeapFree(GetProcessHeap(), 0, wszPatternString);
340 continue;
341 }
342
343 /* if it is not the source filter value */
344 if (process_pattern_string(wszPatternString, pReader) == S_OK)
345 {
346 HeapFree(GetProcessHeap(), 0, wszPatternString);
347 if (majorType && FAILED(CLSIDFromString(wszMajorKeyName, majorType)))
348 break;
349 if (minorType && FAILED(CLSIDFromString(wszMinorKeyName, minorType)))
350 break;
351 if (sourceFilter)
352 {
353 /* Look up the source filter key */
354 if (RegQueryValueExW(hkeyMinor, source_filter_name, NULL, NULL, (LPBYTE)wszSourceFilterKeyName, &dwSourceFilterKeyNameLen))
355 break;
356 if (FAILED(CLSIDFromString(wszSourceFilterKeyName, sourceFilter)))
357 break;
358 }
359 bFound = TRUE;
360 } else
361 HeapFree(GetProcessHeap(), 0, wszPatternString);
362 }
363 CloseHandle(hkeyMinor);
364 }
365 }
366 CloseHandle(hkeyMajor);
367 }
368 }
369 CloseHandle(hkeyMediaType);
370
371 if (SUCCEEDED(hr) && !bFound)
372 {
373 ERR("Media class not found\n");
374 hr = E_FAIL;
375 }
376 else if (bFound)
377 {
378 TRACE("Found file's class:\n");
379 if(majorType)
380 TRACE("\tmajor = %s\n", qzdebugstr_guid(majorType));
381 if(minorType)
382 TRACE("\tsubtype = %s\n", qzdebugstr_guid(minorType));
383 if(sourceFilter)
384 TRACE("\tsource filter = %s\n", qzdebugstr_guid(sourceFilter));
385 }
386
387 return hr;
388}
389
391{
393
394 TRACE("%p->(%d)\n", This, pos);
395
396 if (pos >= 1 || !This->pOutputPin)
397 return NULL;
398
399 IPin_AddRef(This->pOutputPin);
400 return This->pOutputPin;
401}
402
404{
406
407 TRACE("%p->()\n", This);
408
409 if (!This->pOutputPin)
410 return 0;
411 else
412 return 1;
413}
414
418};
419
421{
422 AsyncReader *pAsyncRead;
423
424 if( pUnkOuter )
426
427 pAsyncRead = CoTaskMemAlloc(sizeof(AsyncReader));
428
429 if (!pAsyncRead)
430 return E_OUTOFMEMORY;
431
432 BaseFilter_Init(&pAsyncRead->filter, &AsyncReader_Vtbl, &CLSID_AsyncReader, (DWORD_PTR)(__FILE__ ": AsyncReader.csFilter"), &BaseFuncTable);
433
434 pAsyncRead->IFileSourceFilter_iface.lpVtbl = &FileSource_Vtbl;
436 pAsyncRead->pOutputPin = NULL;
437
438 pAsyncRead->pszFileName = NULL;
439 pAsyncRead->pmt = NULL;
440
441 *ppv = pAsyncRead;
442
443 TRACE("-- created at %p\n", pAsyncRead);
444
445 return S_OK;
446}
447
451{
453
454 TRACE("%p->(%s, %p)\n", This, qzdebugstr_guid(riid), ppv);
455
456 *ppv = NULL;
457
459 *ppv = &This->filter.IBaseFilter_iface;
460 else if (IsEqualIID(riid, &IID_IPersist))
461 *ppv = &This->filter.IBaseFilter_iface;
462 else if (IsEqualIID(riid, &IID_IMediaFilter))
463 *ppv = &This->filter.IBaseFilter_iface;
464 else if (IsEqualIID(riid, &IID_IBaseFilter))
465 *ppv = &This->filter.IBaseFilter_iface;
466 else if (IsEqualIID(riid, &IID_IFileSourceFilter))
467 *ppv = &This->IFileSourceFilter_iface;
468 else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
469 *ppv = &This->IAMFilterMiscFlags_iface;
470
471 if (*ppv)
472 {
473 IUnknown_AddRef((IUnknown *)(*ppv));
474 return S_OK;
475 }
476
477 if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IMediaSeeking) &&
478 !IsEqualIID(riid, &IID_IVideoWindow) && !IsEqualIID(riid, &IID_IBasicAudio))
479 FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
480
481 return E_NOINTERFACE;
482}
483
485{
487 ULONG refCount = InterlockedDecrement(&This->filter.refCount);
488
489 TRACE("%p->() Release from %d\n", This, refCount + 1);
490
491 if (!refCount)
492 {
493 if (This->pOutputPin)
494 {
495 IPin *pConnectedTo;
496 if(SUCCEEDED(IPin_ConnectedTo(This->pOutputPin, &pConnectedTo)))
497 {
498 IPin_Disconnect(pConnectedTo);
499 IPin_Release(pConnectedTo);
500 }
501 IPin_Disconnect(This->pOutputPin);
502 IPin_Release(This->pOutputPin);
503 }
504 CoTaskMemFree(This->pszFileName);
505 if (This->pmt)
506 FreeMediaType(This->pmt);
507 BaseFilter_Destroy(&This->filter);
509 return 0;
510 }
511 else
512 return refCount;
513}
514
518{
520
521 TRACE("%p->()\n", This);
522
523 This->filter.state = State_Stopped;
524
525 return S_OK;
526}
527
529{
531
532 TRACE("%p->()\n", This);
533
534 This->filter.state = State_Paused;
535
536 return S_OK;
537}
538
540{
542
543 TRACE("%p->(%s)\n", This, wine_dbgstr_longlong(tStart));
544
545 This->filter.state = State_Running;
546
547 return S_OK;
548}
549
553{
555 TRACE("%p->(%s, %p)\n", This, debugstr_w(Id), ppPin);
556
557 if (!Id || !ppPin)
558 return E_POINTER;
559
561 {
562 *ppPin = NULL;
563 return VFW_E_NOT_FOUND;
564 }
565
566 *ppPin = This->pOutputPin;
567 IPin_AddRef(*ppPin);
568 return S_OK;
569}
570
571static const IBaseFilterVtbl AsyncReader_Vtbl =
572{
588};
589
591{
593
594 return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv);
595}
596
598{
600
601 return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
602}
603
605{
607
608 return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
609}
610
612{
613 HRESULT hr;
615 IAsyncReader * pReader = NULL;
617
618 TRACE("%p->(%s, %p)\n", This, debugstr_w(pszFileName), pmt);
619
620 if (!pszFileName)
621 return E_POINTER;
622
623 /* open file */
624 /* FIXME: check the sharing values that native uses */
626
628 {
630 }
631
632 /* create pin */
633 hr = FileAsyncReader_Construct(hFile, &This->filter.IBaseFilter_iface, &This->filter.csFilter, &This->pOutputPin);
635
636 if (SUCCEEDED(hr))
637 hr = IPin_QueryInterface(This->pOutputPin, &IID_IAsyncReader, (LPVOID *)&pReader);
638
639 /* store file name & media type */
640 if (SUCCEEDED(hr))
641 {
642 CoTaskMemFree(This->pszFileName);
643 if (This->pmt)
644 FreeMediaType(This->pmt);
645
646 This->pszFileName = CoTaskMemAlloc((strlenW(pszFileName) + 1) * sizeof(WCHAR));
647 strcpyW(This->pszFileName, pszFileName);
648
649 This->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
650 if (!pmt)
651 {
652 This->pmt->bFixedSizeSamples = TRUE;
653 This->pmt->bTemporalCompression = FALSE;
654 This->pmt->cbFormat = 0;
655 This->pmt->pbFormat = NULL;
656 This->pmt->pUnk = NULL;
657 This->pmt->lSampleSize = 0;
658 This->pmt->formattype = FORMAT_None;
659 hr = GetClassMediaFile(pReader, pszFileName, &This->pmt->majortype, &This->pmt->subtype, NULL);
660 if (FAILED(hr))
661 {
662 This->pmt->majortype = MEDIATYPE_Stream;
663 This->pmt->subtype = MEDIASUBTYPE_NULL;
664 hr = S_OK;
665 }
666 }
667 else
668 CopyMediaType(This->pmt, pmt);
669 }
670
671 if (pReader)
672 IAsyncReader_Release(pReader);
673
674 if (FAILED(hr))
675 {
676 if (This->pOutputPin)
677 {
678 IPin_Release(This->pOutputPin);
679 This->pOutputPin = NULL;
680 }
681
682 CoTaskMemFree(This->pszFileName);
683 if (This->pmt)
684 FreeMediaType(This->pmt);
685 This->pszFileName = NULL;
686 This->pmt = NULL;
687
689 }
690
691 /* FIXME: check return codes */
692 return hr;
693}
694
696{
698
699 TRACE("%p->(%p, %p)\n", This, ppszFileName, pmt);
700
701 if (!ppszFileName)
702 return E_POINTER;
703
704 /* copy file name & media type if available, otherwise clear the outputs */
705 if (This->pszFileName)
706 {
707 *ppszFileName = CoTaskMemAlloc((strlenW(This->pszFileName) + 1) * sizeof(WCHAR));
708 strcpyW(*ppszFileName, This->pszFileName);
709 }
710 else
711 *ppszFileName = NULL;
712
713 if (pmt)
714 {
715 if (This->pmt)
716 CopyMediaType(pmt, This->pmt);
717 else
718 ZeroMemory(pmt, sizeof(*pmt));
719 }
720
721 return S_OK;
722}
723
724static const IFileSourceFilterVtbl FileSource_Vtbl =
725{
731};
732
733
734/* the dwUserData passed back to user */
735typedef struct DATAREQUEST
736{
737 IMediaSample * pSample; /* sample passed to us by user */
738 DWORD_PTR dwUserData; /* user data passed to us */
739 OVERLAPPED ovl; /* our overlapped structure */
741
742typedef struct FileAsyncReader
743{
746
750 /* Why would you need more? Every sample has its own handle */
754 CRITICAL_SECTION csList; /* critical section to prevent concurrency issues */
756
757 /* Have a handle for every sample, and then one more as flushing handle */
760
761static inline FileAsyncReader *impl_from_IPin(IPin *iface)
762{
763 return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin.IPin_iface);
764}
765
767{
768 return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin);
769}
770
772{
773 return CONTAINING_RECORD(iface, FileAsyncReader, pin);
774}
775
777{
778 return CONTAINING_RECORD(iface, BaseOutputPin, pin);
779}
780
782{
783 return CONTAINING_RECORD(iface, FileAsyncReader, IAsyncReader_iface);
784}
785
787{
788 AM_MEDIA_TYPE *pmt_filter = impl_from_IBaseFilter(pin->pinInfo.pFilter)->pmt;
789
790 FIXME("(%p, %p)\n", pin, pmt);
791
792 if (IsEqualGUID(&pmt->majortype, &pmt_filter->majortype) &&
793 IsEqualGUID(&pmt->subtype, &pmt_filter->subtype) &&
794 IsEqualGUID(&pmt->formattype, &FORMAT_None))
795 return S_OK;
796
797 return S_FALSE;
798}
799
801{
803 if (iPosition < 0)
804 return E_INVALIDARG;
805 if (iPosition > 0)
806 return VFW_S_NO_MORE_ITEMS;
807 CopyMediaType(pmt, impl_from_IBaseFilter(This->pin.pin.pinInfo.pFilter)->pmt);
808 return S_OK;
809}
810
811/* overridden pin functions */
812
814{
816 TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
817
818 *ppv = NULL;
819
821 *ppv = &This->pin.pin.IPin_iface;
822 else if (IsEqualIID(riid, &IID_IAsyncReader))
823 *ppv = &This->IAsyncReader_iface;
824
825 if (*ppv)
826 {
827 IUnknown_AddRef((IUnknown *)*ppv);
828 return S_OK;
829 }
830
831 if (!IsEqualIID(riid, &IID_IMediaSeeking))
832 FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
833
834 return E_NOINTERFACE;
835}
836
838{
840 ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount);
841 int x;
842
843 TRACE("(%p)->() Release from %d\n", This, refCount + 1);
844
845 if (!refCount)
846 {
847 CoTaskMemFree(This->sample_list);
848 if (This->handle_list)
849 {
850 for (x = 0; x <= This->samples; ++x)
851 CloseHandle(This->handle_list[x]);
852 CoTaskMemFree(This->handle_list);
853 }
854 CloseHandle(This->hFile);
855 This->csList.DebugInfo->Spare[0] = 0;
856 DeleteCriticalSection(&This->csList);
858 return 0;
859 }
860 return refCount;
861}
862
863static const IPinVtbl FileAsyncReaderPin_Vtbl =
864{
883};
884
885/* Function called as a helper to IPin_Connect */
886/* specific AM_MEDIA_TYPE - it cannot be NULL */
887/* this differs from standard OutputPin_AttemptConnection only in that it
888 * doesn't need the IMemInputPin interface on the receiving pin */
890{
892 HRESULT hr;
893
894 TRACE("%p->(%p, %p)\n", This, pReceivePin, pmt);
896
897 /* FIXME: call queryacceptproc */
898
899 This->pin.pConnectedTo = pReceivePin;
900 IPin_AddRef(pReceivePin);
901 CopyMediaType(&This->pin.mtCurrent, pmt);
902
903 hr = IPin_ReceiveConnection(pReceivePin, &iface->IPin_iface, pmt);
904
905 if (FAILED(hr))
906 {
907 IPin_Release(This->pin.pConnectedTo);
908 This->pin.pConnectedTo = NULL;
909 FreeMediaType(&This->pin.mtCurrent);
910 }
911
912 TRACE(" -- %x\n", hr);
913 return hr;
914}
915
917{
920
921 if (ppropInputRequest->cbAlign && ppropInputRequest->cbAlign != This->allocProps.cbAlign)
922 FIXME("Requested Buffer cbAlign mismatch %i,%i\n",This->allocProps.cbAlign, ppropInputRequest->cbAlign);
923 if (ppropInputRequest->cbPrefix)
924 FIXME("Requested Buffer cbPrefix mismatch %i,%i\n",This->allocProps.cbPrefix, ppropInputRequest->cbPrefix);
925 if (ppropInputRequest->cbBuffer)
926 FIXME("Requested Buffer cbBuffer mismatch %i,%i\n",This->allocProps.cbBuffer, ppropInputRequest->cbBuffer);
927 if (ppropInputRequest->cBuffers)
928 FIXME("Requested Buffer cBuffers mismatch %i,%i\n",This->allocProps.cBuffers, ppropInputRequest->cBuffers);
929
930 return IMemAllocator_SetProperties(pAlloc, &This->allocProps, &actual);
931}
932
934 {
939 },
943};
944
946{
947 PIN_INFO piOutput;
948 HRESULT hr;
949
950 *ppPin = NULL;
951 piOutput.dir = PINDIR_OUTPUT;
952 piOutput.pFilter = pBaseFilter;
953 strcpyW(piOutput.achName, wszOutputPinName);
955
956 if (SUCCEEDED(hr))
957 {
958 FileAsyncReader *pPinImpl = (FileAsyncReader *)*ppPin;
959 pPinImpl->IAsyncReader_iface.lpVtbl = &FileAsyncReader_Vtbl;
960 pPinImpl->hFile = hFile;
961 pPinImpl->bFlushing = FALSE;
962 pPinImpl->sample_list = NULL;
963 pPinImpl->handle_list = NULL;
964 pPinImpl->queued_number = 0;
966 pPinImpl->csList.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FileAsyncReader.csList");
967 }
968 return hr;
969}
970
971/* IAsyncReader */
972
974{
976
977 return IPin_QueryInterface(&This->pin.pin.IPin_iface, riid, ppv);
978}
979
981{
983
984 return IPin_AddRef(&This->pin.pin.IPin_iface);
985}
986
988{
990
991 return IPin_Release(&This->pin.pin.IPin_iface);
992}
993
994#define DEF_ALIGNMENT 1
995
997{
999
1000 HRESULT hr = S_OK;
1001
1002 TRACE("%p->(%p, %p, %p)\n", This, pPreferred, pProps, ppActual);
1003
1004 if (!pProps->cbAlign || (pProps->cbAlign % DEF_ALIGNMENT) != 0)
1005 pProps->cbAlign = DEF_ALIGNMENT;
1006
1007 if (pPreferred)
1008 {
1009 hr = IMemAllocator_SetProperties(pPreferred, pProps, pProps);
1010 /* FIXME: check we are still aligned */
1011 if (SUCCEEDED(hr))
1012 {
1013 IMemAllocator_AddRef(pPreferred);
1014 *ppActual = pPreferred;
1015 TRACE("FileAsyncReader_RequestAllocator -- %x\n", hr);
1016 goto done;
1017 }
1018 }
1019
1020 pPreferred = NULL;
1021
1022 hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC, &IID_IMemAllocator, (LPVOID *)&pPreferred);
1023
1024 if (SUCCEEDED(hr))
1025 {
1026 hr = IMemAllocator_SetProperties(pPreferred, pProps, pProps);
1027 /* FIXME: check we are still aligned */
1028 if (SUCCEEDED(hr))
1029 {
1030 *ppActual = pPreferred;
1031 TRACE("FileAsyncReader_RequestAllocator -- %x\n", hr);
1032 }
1033 }
1034
1035done:
1036 if (SUCCEEDED(hr))
1037 {
1038 CoTaskMemFree(This->sample_list);
1039 if (This->handle_list)
1040 {
1041 int x;
1042 for (x = 0; x <= This->samples; ++x)
1043 CloseHandle(This->handle_list[x]);
1044 CoTaskMemFree(This->handle_list);
1045 }
1046
1047 This->samples = pProps->cBuffers;
1048 This->oldest_sample = 0;
1049 TRACE("Samples: %u\n", This->samples);
1050 This->sample_list = CoTaskMemAlloc(sizeof(This->sample_list[0]) * pProps->cBuffers);
1051 This->handle_list = CoTaskMemAlloc(sizeof(HANDLE) * pProps->cBuffers * 2);
1052
1053 if (This->sample_list && This->handle_list)
1054 {
1055 int x;
1056 ZeroMemory(This->sample_list, sizeof(This->sample_list[0]) * pProps->cBuffers);
1057 for (x = 0; x < This->samples; ++x)
1058 {
1059 This->sample_list[x].ovl.hEvent = This->handle_list[x] = CreateEventW(NULL, 0, 0, NULL);
1060 if (x + 1 < This->samples)
1061 This->handle_list[This->samples + 1 + x] = This->handle_list[x];
1062 }
1063 This->handle_list[This->samples] = CreateEventW(NULL, 1, 0, NULL);
1064 This->allocProps = *pProps;
1065 }
1066 else
1067 {
1068 hr = E_OUTOFMEMORY;
1069 CoTaskMemFree(This->sample_list);
1070 CoTaskMemFree(This->handle_list);
1071 This->samples = 0;
1072 This->sample_list = NULL;
1073 This->handle_list = NULL;
1074 }
1075 }
1076
1077 if (FAILED(hr))
1078 {
1079 *ppActual = NULL;
1080 if (pPreferred)
1081 IMemAllocator_Release(pPreferred);
1082 }
1083
1084 TRACE("-- %x\n", hr);
1085 return hr;
1086}
1087
1088/* we could improve the Request/WaitForNext mechanism by allowing out of order samples.
1089 * however, this would be quite complicated to do and may be a bit error prone */
1091{
1092 HRESULT hr = S_OK;
1097
1098 TRACE("%p->(%p, %lx)\n", This, pSample, dwUser);
1099
1100 if (!pSample)
1101 return E_POINTER;
1102
1103 /* get start and stop positions in bytes */
1104 if (SUCCEEDED(hr))
1105 hr = IMediaSample_GetTime(pSample, &Start, &Stop);
1106
1107 if (SUCCEEDED(hr))
1108 hr = IMediaSample_GetPointer(pSample, &pBuffer);
1109
1110 EnterCriticalSection(&This->csList);
1111 if (This->bFlushing)
1112 {
1113 LeaveCriticalSection(&This->csList);
1114 return VFW_E_WRONG_STATE;
1115 }
1116
1117 if (SUCCEEDED(hr))
1118 {
1120 DATAREQUEST *pDataRq;
1121 int x;
1122
1123 /* Try to insert above the waiting sample if possible */
1124 for (x = This->oldest_sample; x < This->samples; ++x)
1125 {
1126 if (!This->sample_list[x].pSample)
1127 break;
1128 }
1129
1130 if (x >= This->samples)
1131 for (x = 0; x < This->oldest_sample; ++x)
1132 {
1133 if (!This->sample_list[x].pSample)
1134 break;
1135 }
1136
1137 /* There must be a sample we have found */
1138 assert(x < This->samples);
1139 ++This->queued_number;
1140
1141 pDataRq = This->sample_list + x;
1142
1143 pDataRq->ovl.u.s.Offset = (DWORD) BYTES_FROM_MEDIATIME(Start);
1144 pDataRq->ovl.u.s.OffsetHigh = (DWORD)(BYTES_FROM_MEDIATIME(Start) >> (sizeof(DWORD) * 8));
1145 pDataRq->dwUserData = dwUser;
1146
1147 /* we violate traditional COM rules here by maintaining
1148 * a reference to the sample, but not calling AddRef, but
1149 * that's what MSDN says to do */
1150 pDataRq->pSample = pSample;
1151
1152 /* this is definitely not how it is implemented on Win9x
1153 * as they do not support async reads on files, but it is
1154 * sooo much easier to use this than messing around with threads!
1155 */
1156 if (!ReadFile(This->hFile, pBuffer, dwLength, NULL, &pDataRq->ovl))
1158
1159 /* ERROR_IO_PENDING is not actually an error since this is what we want! */
1161 hr = S_OK;
1162 }
1163
1164 LeaveCriticalSection(&This->csList);
1165
1166 TRACE("-- %x\n", hr);
1167 return hr;
1168}
1169
1171{
1172 HRESULT hr = S_OK;
1174 DWORD buffer = ~0;
1175
1176 TRACE("%p->(%u, %p, %p)\n", This, dwTimeout, ppSample, pdwUser);
1177
1178 *ppSample = NULL;
1179 *pdwUser = 0;
1180
1181 EnterCriticalSection(&This->csList);
1182 if (!This->bFlushing)
1183 {
1184 LONG oldest = This->oldest_sample;
1185
1186 if (!This->queued_number)
1187 {
1188 /* It could be that nothing is queued right now, but that can be fixed */
1189 WARN("Called without samples in queue and not flushing!!\n");
1190 }
1191 LeaveCriticalSection(&This->csList);
1192
1193 /* wait for an object to read, or time out */
1194 buffer = WaitForMultipleObjectsEx(This->samples+1, This->handle_list + oldest, FALSE, dwTimeout, TRUE);
1195
1196 EnterCriticalSection(&This->csList);
1197 if (buffer <= This->samples)
1198 {
1199 /* Re-scale the buffer back to normal */
1200 buffer += oldest;
1201
1202 /* Uh oh, we overshot the flusher handle, renormalize it back to 0..Samples-1 */
1203 if (buffer > This->samples)
1204 buffer -= This->samples + 1;
1205 assert(buffer <= This->samples);
1206 }
1207
1208 if (buffer >= This->samples)
1209 {
1210 if (buffer != This->samples)
1211 {
1212 FIXME("Returned: %u (%08x)\n", buffer, GetLastError());
1213 hr = VFW_E_TIMEOUT;
1214 }
1215 else
1217 buffer = ~0;
1218 }
1219 else
1220 --This->queued_number;
1221 }
1222
1223 if (This->bFlushing && buffer == ~0)
1224 {
1225 for (buffer = 0; buffer < This->samples; ++buffer)
1226 {
1227 if (This->sample_list[buffer].pSample)
1228 {
1229 ResetEvent(This->handle_list[buffer]);
1230 break;
1231 }
1232 }
1233 if (buffer == This->samples)
1234 {
1235 assert(!This->queued_number);
1236 hr = VFW_E_TIMEOUT;
1237 }
1238 else
1239 {
1240 --This->queued_number;
1241 hr = S_OK;
1242 }
1243 }
1244
1245 if (SUCCEEDED(hr))
1246 {
1247 REFERENCE_TIME rtStart, rtStop;
1248 REFERENCE_TIME rtSampleStart, rtSampleStop;
1249 DATAREQUEST *pDataRq = This->sample_list + buffer;
1250 DWORD dwBytes = 0;
1251
1252 /* get any errors */
1253 if (!This->bFlushing && !GetOverlappedResult(This->hFile, &pDataRq->ovl, &dwBytes, FALSE))
1255
1256 /* Return the sample no matter what so it can be destroyed */
1257 *ppSample = pDataRq->pSample;
1258 *pdwUser = pDataRq->dwUserData;
1259
1260 if (This->bFlushing)
1262
1263 if (FAILED(hr))
1264 dwBytes = 0;
1265
1266 /* Set the time on the sample */
1267 IMediaSample_SetActualDataLength(pDataRq->pSample, dwBytes);
1268
1269 rtStart = (DWORD64)pDataRq->ovl.u.s.Offset + ((DWORD64)pDataRq->ovl.u.s.OffsetHigh << 32);
1270 rtStart = MEDIATIME_FROM_BYTES(rtStart);
1271 rtStop = rtStart + MEDIATIME_FROM_BYTES(dwBytes);
1272
1273 IMediaSample_GetTime(pDataRq->pSample, &rtSampleStart, &rtSampleStop);
1274 assert(rtStart == rtSampleStart);
1275 assert(rtStop <= rtSampleStop);
1276
1277 IMediaSample_SetTime(pDataRq->pSample, &rtStart, &rtStop);
1278 assert(rtStart == rtSampleStart);
1279 if (hr == S_OK)
1280 assert(rtStop == rtSampleStop);
1281 else
1282 assert(rtStop == rtStart);
1283
1284 This->sample_list[buffer].pSample = NULL;
1285 assert(This->oldest_sample < This->samples);
1286
1287 if (buffer == This->oldest_sample)
1288 {
1289 LONG x;
1290 for (x = This->oldest_sample + 1; x < This->samples; ++x)
1291 if (This->sample_list[x].pSample)
1292 break;
1293 if (x >= This->samples)
1294 for (x = 0; x < This->oldest_sample; ++x)
1295 if (This->sample_list[x].pSample)
1296 break;
1297 if (This->oldest_sample == x)
1298 /* No samples found, reset to 0 */
1299 x = 0;
1300 This->oldest_sample = x;
1301 }
1302 }
1303 LeaveCriticalSection(&This->csList);
1304
1305 TRACE("-- %x\n", hr);
1306 return hr;
1307}
1308
1309static HRESULT WINAPI FileAsyncReader_SyncRead(IAsyncReader * iface, LONGLONG llPosition, LONG lLength, BYTE * pBuffer);
1310
1312{
1313 BYTE * pBuffer;
1314 REFERENCE_TIME tStart;
1315 REFERENCE_TIME tStop;
1316 HRESULT hr;
1317
1318 TRACE("(%p)\n", pSample);
1319
1320 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
1321
1322 if (SUCCEEDED(hr))
1323 hr = IMediaSample_GetPointer(pSample, &pBuffer);
1324
1325 if (SUCCEEDED(hr))
1327 BYTES_FROM_MEDIATIME(tStart),
1328 (LONG) BYTES_FROM_MEDIATIME(tStop - tStart),
1329 pBuffer);
1330
1331 TRACE("-- %x\n", hr);
1332 return hr;
1333}
1334
1336{
1337 OVERLAPPED ovl;
1338 HRESULT hr = S_OK;
1340
1341 TRACE("%p->(%s, %d, %p)\n", This, wine_dbgstr_longlong(llPosition), lLength, pBuffer);
1342
1343 ZeroMemory(&ovl, sizeof(ovl));
1344
1345 ovl.hEvent = CreateEventW(NULL, 0, 0, NULL);
1346 /* NOTE: llPosition is the actual byte position to start reading from */
1347 ovl.u.s.Offset = (DWORD) llPosition;
1348 ovl.u.s.OffsetHigh = (DWORD) (llPosition >> (sizeof(DWORD) * 8));
1349
1350 if (!ReadFile(This->hFile, pBuffer, lLength, NULL, &ovl))
1352
1354 hr = S_OK;
1355
1356 if (SUCCEEDED(hr))
1357 {
1358 DWORD dwBytesRead;
1359
1360 if (!GetOverlappedResult(This->hFile, &ovl, &dwBytesRead, TRUE))
1362 }
1363
1364 CloseHandle(ovl.hEvent);
1365
1366 TRACE("-- %x\n", hr);
1367 return hr;
1368}
1369
1371{
1372 DWORD dwSizeLow;
1373 DWORD dwSizeHigh;
1375
1376 TRACE("%p->(%p, %p)\n", This, pTotal, pAvailable);
1377
1378 if (((dwSizeLow = GetFileSize(This->hFile, &dwSizeHigh)) == -1) &&
1379 (GetLastError() != NO_ERROR))
1381
1382 *pTotal = (LONGLONG)dwSizeLow | (LONGLONG)dwSizeHigh << (sizeof(DWORD) * 8);
1383
1384 *pAvailable = *pTotal;
1385
1386 return S_OK;
1387}
1388
1390{
1392
1393 TRACE("%p->()\n", This);
1394
1395 EnterCriticalSection(&This->csList);
1396 This->bFlushing = TRUE;
1397 CancelIo(This->hFile);
1398 SetEvent(This->handle_list[This->samples]);
1399 LeaveCriticalSection(&This->csList);
1400
1401 return S_OK;
1402}
1403
1405{
1407 int x;
1408
1409 TRACE("%p->()\n", This);
1410
1411 EnterCriticalSection(&This->csList);
1412 ResetEvent(This->handle_list[This->samples]);
1413 This->bFlushing = FALSE;
1414 for (x = 0; x < This->samples; ++x)
1415 assert(!This->sample_list[x].pSample);
1416
1417 LeaveCriticalSection(&This->csList);
1418
1419 return S_OK;
1420}
1421
1422static const IAsyncReaderVtbl FileAsyncReader_Vtbl =
1423{
1435};
1436
1437
1440 return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv);
1441}
1442
1445 return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
1446}
1447
1450 return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
1451}
1452
1455}
1456
1457static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
1462};
DWORD Id
#define InterlockedDecrement
Definition: armddk.h:52
@ PINDIR_OUTPUT
Definition: axcore.idl:42
@ AM_FILTER_MISC_FLAGS_IS_SOURCE
Definition: axextend.idl:1240
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
r l[0]
Definition: byte_order.h:168
#define CHARS_IN_GUID
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
const GUID IID_IBaseFilter
const GUID IID_IAsyncReader
BOOL WINAPI CancelIo(IN HANDLE hFile)
Definition: deviceio.c:290
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
const char * qzdebugstr_guid(const GUID *id)
Definition: main.c:279
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2830
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define GENERIC_READ
Definition: compat.h:135
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static DWORD DWORD * dwLength
Definition: fusion.c:86
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
#define assert(x)
Definition: debug.h:53
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
static const IAsyncReaderVtbl FileAsyncReader_Vtbl
Definition: filesource.c:73
static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl
Definition: filesource.c:74
static HRESULT process_pattern_string(LPCWSTR wszPatternString, IAsyncReader *pReader)
Definition: filesource.c:165
static const IBaseFilterVtbl AsyncReader_Vtbl
Definition: filesource.c:71
static HRESULT WINAPI AsyncReader_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
Definition: filesource.c:552
static AsyncReader * impl_from_IFileSourceFilter(IFileSourceFilter *iface)
Definition: filesource.c:61
static HRESULT WINAPI FileAsyncReader_Request(IAsyncReader *iface, IMediaSample *pSample, DWORD_PTR dwUser)
Definition: filesource.c:1090
static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin *iface, REFIID riid, LPVOID *ppv)
Definition: filesource.c:813
static const IFileSourceFilterVtbl FileSource_Vtbl
Definition: filesource.c:72
static ULONG WINAPI FileSource_AddRef(IFileSourceFilter *iface)
Definition: filesource.c:597
static HRESULT WINAPI FileSource_GetCurFile(IFileSourceFilter *iface, LPOLESTR *ppszFileName, AM_MEDIA_TYPE *pmt)
Definition: filesource.c:695
static ULONG WINAPI AsyncReader_Release(IBaseFilter *iface)
Definition: filesource.c:484
static const WCHAR subtype_name[]
Definition: filesource.c:80
static const WCHAR source_filter_name[]
Definition: filesource.c:82
static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter *pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin **ppPin)
Definition: filesource.c:945
HRESULT GetClassMediaFile(IAsyncReader *pReader, LPCOLESTR pszFileName, GUID *majorType, GUID *minorType, GUID *sourceFilter)
Definition: filesource.c:257
static AsyncReader * impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
Definition: filesource.c:66
static ULONG WINAPI FileSource_Release(IFileSourceFilter *iface)
Definition: filesource.c:604
static const BaseOutputPinFuncTable output_BaseOutputFuncTable
Definition: filesource.c:933
static HRESULT WINAPI FileAsyncReaderPin_AttemptConnection(BasePin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: filesource.c:889
#define DEF_ALIGNMENT
Definition: filesource.c:994
static AsyncReader * impl_from_BaseFilter(BaseFilter *iface)
Definition: filesource.c:51
static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface)
Definition: filesource.c:1448
static HRESULT WINAPI FileSource_QueryInterface(IFileSourceFilter *iface, REFIID riid, LPVOID *ppv)
Definition: filesource.c:590
static ULONG WINAPI FileAsyncReader_Release(IAsyncReader *iface)
Definition: filesource.c:987
struct AsyncReader AsyncReader
static const IPinVtbl FileAsyncReaderPin_Vtbl
Definition: filesource.c:863
static HRESULT WINAPI FileAsyncReader_QueryInterface(IAsyncReader *iface, REFIID riid, LPVOID *ppv)
Definition: filesource.c:973
static const WCHAR wszOutputPinName[]
Definition: filesource.c:38
static HRESULT WINAPI FileAsyncReader_SyncRead(IAsyncReader *iface, LONGLONG llPosition, LONG lLength, BYTE *pBuffer)
Definition: filesource.c:1335
static HRESULT process_extensions(HKEY hkeyExtensions, LPCOLESTR pszFileName, GUID *majorType, GUID *minorType, GUID *sourceFilter)
Definition: filesource.c:85
static HRESULT WINAPI FileAsyncReader_Length(IAsyncReader *iface, LONGLONG *pTotal, LONGLONG *pAvailable)
Definition: filesource.c:1370
static HRESULT WINAPI FileAsyncReaderPin_DecideBufferSize(BaseOutputPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
Definition: filesource.c:916
static HRESULT WINAPI FileAsyncReader_BeginFlush(IAsyncReader *iface)
Definition: filesource.c:1389
static HRESULT WINAPI FileAsyncReader_WaitForNext(IAsyncReader *iface, DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser)
Definition: filesource.c:1170
HRESULT AsyncReader_create(IUnknown *pUnkOuter, LPVOID *ppv)
Definition: filesource.c:420
static const WCHAR mediatype_name[]
Definition: filesource.c:78
static HRESULT WINAPI AsyncReader_QueryInterface(IBaseFilter *iface, REFIID riid, LPVOID *ppv)
Definition: filesource.c:450
static FileAsyncReader * impl_from_BasePin(BasePin *iface)
Definition: filesource.c:766
static IPin *WINAPI AsyncReader_GetPin(BaseFilter *iface, int pos)
Definition: filesource.c:390
static const BaseFilterFuncTable BaseFuncTable
Definition: filesource.c:415
static unsigned char byte_from_hex_char(WCHAR wHex)
Definition: filesource.c:138
static HRESULT WINAPI FileAsyncReader_EndFlush(IAsyncReader *iface)
Definition: filesource.c:1404
static BaseOutputPin * impl_BaseOutputPin_from_BasePin(BasePin *iface)
Definition: filesource.c:776
static AsyncReader * impl_from_IBaseFilter(IBaseFilter *iface)
Definition: filesource.c:56
static HRESULT WINAPI FileAsyncReaderPin_GetMediaType(BasePin *iface, int iPosition, AM_MEDIA_TYPE *pmt)
Definition: filesource.c:800
static LONG WINAPI AsyncReader_GetPinCount(BaseFilter *iface)
Definition: filesource.c:403
static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv)
Definition: filesource.c:1438
static HRESULT WINAPI AsyncReader_Pause(IBaseFilter *iface)
Definition: filesource.c:528
static HRESULT WINAPI AsyncReader_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
Definition: filesource.c:539
static HRESULT WINAPI FileSource_Load(IFileSourceFilter *iface, LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt)
Definition: filesource.c:611
static HRESULT WINAPI FileAsyncReader_RequestAllocator(IAsyncReader *iface, IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual)
Definition: filesource.c:996
static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface)
Definition: filesource.c:1453
static HRESULT WINAPI FileAsyncReaderPin_CheckMediaType(BasePin *pin, const AM_MEDIA_TYPE *pmt)
Definition: filesource.c:786
static FileAsyncReader * impl_from_BaseOutputPin(BaseOutputPin *iface)
Definition: filesource.c:771
static FileAsyncReader * impl_from_IPin(IPin *iface)
Definition: filesource.c:761
static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface)
Definition: filesource.c:1443
static HRESULT WINAPI FileAsyncReader_SyncReadAligned(IAsyncReader *iface, IMediaSample *pSample)
Definition: filesource.c:1311
static HRESULT WINAPI AsyncReader_Stop(IBaseFilter *iface)
Definition: filesource.c:517
static ULONG WINAPI FileAsyncReaderPin_Release(IPin *iface)
Definition: filesource.c:837
static ULONG WINAPI FileAsyncReader_AddRef(IAsyncReader *iface)
Definition: filesource.c:980
static FileAsyncReader * impl_from_IAsyncReader(IAsyncReader *iface)
Definition: filesource.c:781
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLsizeiptr size
Definition: glext.h:5919
GLsizei samples
Definition: glext.h:7006
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
Definition: axcore.idl:92
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:221
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
_In_opt_ PVOID _Out_ BOOLEAN * Stop
Definition: ldrtypes.h:241
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
static LPOLESTR
Definition: stg_prop.c:27
static void FreeMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: filtergraph.c:692
static HRESULT CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: filtergraph.c:706
_In_ HANDLE hFile
Definition: mswsock.h:90
#define KEY_READ
Definition: nt_native.h:1023
#define DWORD
Definition: nt_native.h:44
long LONG
Definition: pedump.c:60
const GUID IID_IPin
Definition: pincontrol.cpp:15
const GUID IID_IPersist
Definition: proxy.cpp:14
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *pmt)
Definition: enummedia.c:38
#define MEDIATIME_FROM_BYTES(x)
#define BYTES_FROM_MEDIATIME(time)
PVOID pBuffer
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strchrW(s, c)
Definition: unicode.h:34
#define tolowerW(n)
Definition: unicode.h:44
#define strlenW(s)
Definition: unicode.h:28
#define isxdigitW(n)
Definition: unicode.h:51
#define strtolW(s, e, b)
Definition: unicode.h:33
#define strcpyW(d, s)
Definition: unicode.h:29
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
Definition: pin.c:248
HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock)
Definition: filter.c:101
HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin *iface, IPin **apPin, ULONG *cPin)
Definition: pin.c:329
HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin *iface)
Definition: pin.c:545
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin *iface, IPin **ppPin)
Definition: pin.c:222
HRESULT WINAPI BasePinImpl_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
Definition: pin.c:338
HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter *iface, CLSID *pClsid)
Definition: filter.c:77
HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
Definition: filter.c:145
HRESULT WINAPI BasePinImpl_QueryId(IPin *iface, LPWSTR *Id)
Definition: pin.c:296
HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
Definition: pin.c:273
HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin *iface)
Definition: pin.c:527
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter *iface)
Definition: filter.c:54
HRESULT WINAPI BaseFilter_Destroy(BaseFilter *This)
Definition: filter.c:214
HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin *iface)
Definition: pin.c:536
HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(BaseOutputPin *This, IMemInputPin *pPin, IMemAllocator **pAlloc)
Definition: pin.c:683
HRESULT WINAPI BaseOutputPin_Destroy(BaseOutputPin *This)
Definition: pin.c:821
HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
Definition: filter.c:87
HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO *pPinInfo, const BaseOutputPinFuncTable *pBaseOutputFuncsTable, LPCRITICAL_SECTION pCritSec, IPin **ppPin)
Definition: pin.c:791
HRESULT WINAPI BasePinImpl_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
Definition: pin.c:318
HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName)
Definition: filter.c:159
LONG WINAPI BasePinImpl_GetMediaTypeVersion(BasePin *This)
Definition: pin.c:182
HRESULT WINAPI BaseOutputPinImpl_BreakConnect(BaseOutputPin *This)
Definition: pin.c:654
HRESULT WINAPI BaseOutputPinImpl_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:405
HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo)
Definition: filter.c:178
HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
Definition: filter.c:119
HRESULT WINAPI BasePinImpl_Disconnect(IPin *iface)
Definition: pin.c:197
HRESULT WINAPI BasePinImpl_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
Definition: pin.c:285
HRESULT WINAPI BasePinImpl_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:311
HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:490
VOID WINAPI BaseFilterImpl_IncrementPinVersion(BaseFilter *This)
Definition: filter.c:190
HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
Definition: filter.c:135
HRESULT WINAPI BaseFilter_Init(BaseFilter *This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseFilterFuncTable *pBaseFuncsTable)
Definition: filter.c:196
ULONG WINAPI BasePinImpl_AddRef(IPin *iface)
Definition: pin.c:187
IPin * pOutputPin
Definition: filesource.c:46
BaseFilter filter
Definition: filesource.c:42
LPOLESTR pszFileName
Definition: filesource.c:47
IFileSourceFilter IFileSourceFilter_iface
Definition: filesource.c:43
AM_MEDIA_TYPE * pmt
Definition: filesource.c:48
IAMFilterMiscFlags IAMFilterMiscFlags_iface
Definition: filesource.c:44
IPin IPin_iface
Definition: strmbase.h:35
OVERLAPPED ovl
Definition: filesource.c:739
DWORD_PTR dwUserData
Definition: filesource.c:738
IMediaSample * pSample
Definition: filesource.c:737
CRITICAL_SECTION csList
Definition: filesource.c:754
HANDLE * handle_list
Definition: filesource.c:758
BaseOutputPin pin
Definition: filesource.c:744
IAsyncReader IAsyncReader_iface
Definition: filesource.c:745
ALLOCATOR_PROPERTIES allocProps
Definition: filesource.c:747
DATAREQUEST * sample_list
Definition: filesource.c:755
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:887
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:894
DWORD OffsetHigh
Definition: winbase.h:816
DWORD Offset
Definition: winbase.h:815
HANDLE hEvent
Definition: winbase.h:820
Definition: regsvr.c:104
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
DWORD WINAPI WaitForMultipleObjectsEx(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:169
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint64_t DWORD64
Definition: typedefs.h:67
unsigned char * LPBYTE
Definition: typedefs.h:53
int64_t LONGLONG
Definition: typedefs.h:68
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
@ Start
Definition: partlist.h:33
#define MEDIASUBTYPE_NULL
Definition: uuids.h:25
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
#define VFW_E_TIMEOUT
Definition: vfwmsgs.h:85
#define VFW_E_WRONG_STATE
Definition: vfwmsgs.h:78
#define VFW_S_NO_MORE_ITEMS
Definition: vfwmsgs.h:19
#define VFW_E_NOT_FOUND
Definition: vfwmsgs.h:61
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD dwTimeout
Definition: wincrypt.h:6081
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193