2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/proxy.cpp
5 * PURPOSE: IKsProxy interface
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
12 const GUID IID_IPersistPropertyBag
= {0x37D84F60, 0x42CB, 0x11CE, {0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51}};
13 const GUID GUID_NULL
= {0x00000000L
, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
14 const GUID IID_ISpecifyPropertyPages
= {0xB196B28B, 0xBAB4, 0x101A, {0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}};
15 const GUID IID_IPersistStream
= {0x00000109, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
16 const GUID KSPROPSETID_MediaSeeking
= {0xEE904F0CL
, 0xD09B, 0x11D0, {0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
17 const GUID KSPROPSETID_Clock
= {0xDF12A4C0L
, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
18 const GUID KSEVENTSETID_Clock
= {0x364D8E20L
, 0x62C7, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
19 const GUID KSPROPSETID_Stream
= {0x65aaba60L
, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
22 const GUID IID_IBDA_DeviceControl
= {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
23 const GUID IID_IKsAggregateControl
= {0x7F40EAC0, 0x3947, 0x11D2, {0x87, 0x4E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
24 const GUID IID_IKsClockPropertySet
= {0x5C5CBD84, 0xE755, 0x11D0, {0xAC, 0x18, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
25 const GUID IID_IKsTopology
= {0x28F54683, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
26 const GUID IID_IKsClock
= {0x877E4351, 0x6FEA, 0x11D0, {0xB8, 0x63, 0x00, 0xAA, 0x00, 0xA2, 0x16, 0xA1}};
28 Needs IKsClock, IKsNotifyEvent
31 class CKsProxy
: public IBaseFilter
,
33 public IPersistPropertyBag
,
35 public IPersistStream
,
36 public IAMDeviceRemoval
,
37 public ISpecifyPropertyPages
,
38 public IReferenceClock
,
40 public IKsPropertySet
,
42 public IKsClockPropertySet
,
43 public IAMFilterMiscFlags
,
46 public IKsAggregateControl
50 typedef std::vector
<IUnknown
*>ProxyPluginVector
;
51 typedef std::vector
<IPin
*> PinVector
;
53 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
55 STDMETHODIMP_(ULONG
) AddRef()
57 InterlockedIncrement(&m_Ref
);
60 STDMETHODIMP_(ULONG
) Release()
62 InterlockedDecrement(&m_Ref
);
71 // IBaseFilter methods
72 HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
73 HRESULT STDMETHODCALLTYPE
Stop( void);
74 HRESULT STDMETHODCALLTYPE
Pause( void);
75 HRESULT STDMETHODCALLTYPE
Run(REFERENCE_TIME tStart
);
76 HRESULT STDMETHODCALLTYPE
GetState(DWORD dwMilliSecsTimeout
, FILTER_STATE
*State
);
77 HRESULT STDMETHODCALLTYPE
SetSyncSource(IReferenceClock
*pClock
);
78 HRESULT STDMETHODCALLTYPE
GetSyncSource(IReferenceClock
**pClock
);
79 HRESULT STDMETHODCALLTYPE
EnumPins(IEnumPins
**ppEnum
);
80 HRESULT STDMETHODCALLTYPE
FindPin(LPCWSTR Id
, IPin
**ppPin
);
81 HRESULT STDMETHODCALLTYPE
QueryFilterInfo(FILTER_INFO
*pInfo
);
82 HRESULT STDMETHODCALLTYPE
JoinFilterGraph(IFilterGraph
*pGraph
, LPCWSTR pName
);
83 HRESULT STDMETHODCALLTYPE
QueryVendorInfo(LPWSTR
*pVendorInfo
);
86 HRESULT STDMETHODCALLTYPE
GetTime(REFERENCE_TIME
*pTime
);
87 HRESULT STDMETHODCALLTYPE
AdviseTime(REFERENCE_TIME baseTime
, REFERENCE_TIME streamTime
, HEVENT hEvent
, DWORD_PTR
*pdwAdviseCookie
);
88 HRESULT STDMETHODCALLTYPE
AdvisePeriodic(REFERENCE_TIME startTime
, REFERENCE_TIME periodTime
, HSEMAPHORE hSemaphore
, DWORD_PTR
*pdwAdviseCookie
);
89 HRESULT STDMETHODCALLTYPE
Unadvise(DWORD_PTR dwAdviseCookie
);
92 HRESULT STDMETHODCALLTYPE
GetCapabilities(DWORD
*pCapabilities
);
93 HRESULT STDMETHODCALLTYPE
CheckCapabilities(DWORD
*pCapabilities
);
94 HRESULT STDMETHODCALLTYPE
IsFormatSupported(const GUID
*pFormat
);
95 HRESULT STDMETHODCALLTYPE
QueryPreferredFormat(GUID
*pFormat
);
96 HRESULT STDMETHODCALLTYPE
GetTimeFormat(GUID
*pFormat
);
97 HRESULT STDMETHODCALLTYPE
IsUsingTimeFormat(const GUID
*pFormat
);
98 HRESULT STDMETHODCALLTYPE
SetTimeFormat(const GUID
*pFormat
);
99 HRESULT STDMETHODCALLTYPE
GetDuration(LONGLONG
*pDuration
);
100 HRESULT STDMETHODCALLTYPE
GetStopPosition(LONGLONG
*pStop
);
101 HRESULT STDMETHODCALLTYPE
GetCurrentPosition(LONGLONG
*pCurrent
);
102 HRESULT STDMETHODCALLTYPE
ConvertTimeFormat(LONGLONG
*pTarget
, const GUID
*pTargetFormat
, LONGLONG Source
, const GUID
*pSourceFormat
);
103 HRESULT STDMETHODCALLTYPE
SetPositions(LONGLONG
*pCurrent
, DWORD dwCurrentFlags
, LONGLONG
*pStop
, DWORD dwStopFlags
);
104 HRESULT STDMETHODCALLTYPE
GetPositions(LONGLONG
*pCurrent
, LONGLONG
*pStop
);
105 HRESULT STDMETHODCALLTYPE
GetAvailable(LONGLONG
*pEarliest
, LONGLONG
*pLatest
);
106 HRESULT STDMETHODCALLTYPE
SetRate(double dRate
);
107 HRESULT STDMETHODCALLTYPE
GetRate(double *pdRate
);
108 HRESULT STDMETHODCALLTYPE
GetPreroll(LONGLONG
*pllPreroll
);
111 HRESULT STDMETHODCALLTYPE
Set(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
);
112 HRESULT STDMETHODCALLTYPE
Get(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
, DWORD
*pcbReturned
);
113 HRESULT STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet
, DWORD dwPropID
, DWORD
*pTypeSupport
);
116 ULONG STDMETHODCALLTYPE
GetMiscFlags( void);
119 HRESULT STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
, ULONG DataLength
, ULONG
* BytesReturned
);
120 HRESULT STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
, ULONG DataLength
, ULONG
* BytesReturned
);
121 HRESULT STDMETHODCALLTYPE
KsEvent(PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
, ULONG DataLength
, ULONG
* BytesReturned
);
124 HRESULT STDMETHODCALLTYPE
CreateNodeInstance(ULONG NodeId
, ULONG Flags
, ACCESS_MASK DesiredAccess
, IUnknown
* UnkOuter
, REFGUID InterfaceId
, LPVOID
* Interface
);
126 //IKsAggregateControl
127 HRESULT STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass
);
128 HRESULT STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass
);
130 //IKsClockPropertySet
131 HRESULT STDMETHODCALLTYPE
KsGetTime(LONGLONG
* Time
);
132 HRESULT STDMETHODCALLTYPE
KsSetTime(LONGLONG Time
);
133 HRESULT STDMETHODCALLTYPE
KsGetPhysicalTime(LONGLONG
* Time
);
134 HRESULT STDMETHODCALLTYPE
KsSetPhysicalTime(LONGLONG Time
);
135 HRESULT STDMETHODCALLTYPE
KsGetCorrelatedTime(KSCORRELATED_TIME
* CorrelatedTime
);
136 HRESULT STDMETHODCALLTYPE
KsSetCorrelatedTime(KSCORRELATED_TIME
* CorrelatedTime
);
137 HRESULT STDMETHODCALLTYPE
KsGetCorrelatedPhysicalTime(KSCORRELATED_TIME
* CorrelatedTime
);
138 HRESULT STDMETHODCALLTYPE
KsSetCorrelatedPhysicalTime(KSCORRELATED_TIME
* CorrelatedTime
);
139 HRESULT STDMETHODCALLTYPE
KsGetResolution(KSRESOLUTION
* Resolution
);
140 HRESULT STDMETHODCALLTYPE
KsGetState(KSSTATE
* State
);
143 //IAMovieSetup methods
144 HRESULT STDMETHODCALLTYPE
Register( void);
145 HRESULT STDMETHODCALLTYPE
Unregister( void);
147 // IPersistPropertyBag methods
148 HRESULT STDMETHODCALLTYPE
InitNew( void);
149 HRESULT STDMETHODCALLTYPE
Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
);
150 HRESULT STDMETHODCALLTYPE
Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
);
153 HANDLE STDMETHODCALLTYPE
KsGetObjectHandle();
156 HANDLE STDMETHODCALLTYPE
KsGetClockHandle();
159 HRESULT STDMETHODCALLTYPE
DeviceInfo(CLSID
*pclsidInterfaceClass
, LPWSTR
*pwszSymbolicLink
);
160 HRESULT STDMETHODCALLTYPE
Reassociate(void);
161 HRESULT STDMETHODCALLTYPE
Disassociate( void);
164 HRESULT STDMETHODCALLTYPE
IsDirty( void);
165 HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
166 HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
167 HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
169 // ISpecifyPropertyPages
170 HRESULT STDMETHODCALLTYPE
GetPages(CAUUID
*pPages
);
173 CKsProxy() : m_Ref(0), m_pGraph(0), m_ReferenceClock(0), m_FilterState(State_Stopped
), m_hDevice(0), m_Plugins(), m_Pins(), m_DevicePath(0), m_hClock(0) {};
177 CloseHandle(m_hDevice
);
180 HRESULT STDMETHODCALLTYPE
GetSupportedSets(LPGUID
* pOutGuid
, PULONG NumGuids
);
181 HRESULT STDMETHODCALLTYPE
LoadProxyPlugins(LPGUID pGuids
, ULONG NumGuids
);
182 HRESULT STDMETHODCALLTYPE
GetNumberOfPins(PULONG NumPins
);
183 HRESULT STDMETHODCALLTYPE
GetPinInstanceCount(ULONG PinId
, PKSPIN_CINSTANCES Instances
);
184 HRESULT STDMETHODCALLTYPE
GetPinDataflow(ULONG PinId
, KSPIN_DATAFLOW
* DataFlow
);
185 HRESULT STDMETHODCALLTYPE
GetPinName(ULONG PinId
, KSPIN_DATAFLOW DataFlow
, ULONG PinCount
, LPWSTR
* OutPinName
);
186 HRESULT STDMETHODCALLTYPE
GetPinCommunication(ULONG PinId
, KSPIN_COMMUNICATION
* Communication
);
187 HRESULT STDMETHODCALLTYPE
CreatePins();
188 HRESULT STDMETHODCALLTYPE
GetMediaSeekingFormats(PKSMULTIPLE_ITEM
*FormatList
);
189 HRESULT STDMETHODCALLTYPE
CreateClockInstance();
190 HRESULT STDMETHODCALLTYPE
PerformClockProperty(ULONG PropertyId
, ULONG PropertyFlags
, PVOID OutputBuffer
, ULONG OutputBufferSize
);
193 IFilterGraph
*m_pGraph
;
194 IReferenceClock
* m_ReferenceClock
;
195 FILTER_STATE m_FilterState
;
197 ProxyPluginVector m_Plugins
;
200 CLSID m_DeviceInterfaceGUID
;
206 CKsProxy::QueryInterface(
212 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
213 IsEqualGUID(refiid
, IID_IBaseFilter
))
215 *Output
= PVOID(this);
216 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
219 else if (IsEqualGUID(refiid
, IID_IPersistPropertyBag
))
221 *Output
= (IPersistPropertyBag
*)(this);
222 reinterpret_cast<IPersistPropertyBag
*>(*Output
)->AddRef();
225 else if (IsEqualGUID(refiid
, IID_IAMDeviceRemoval
))
227 *Output
= (IAMDeviceRemoval
*)(this);
228 reinterpret_cast<IAMDeviceRemoval
*>(*Output
)->AddRef();
231 else if (IsEqualGUID(refiid
, IID_IPersistStream
))
233 *Output
= (IPersistStream
*)(this);
234 reinterpret_cast<IPersistStream
*>(*Output
)->AddRef();
237 else if (IsEqualGUID(refiid
, IID_IKsObject
))
239 *Output
= (IKsObject
*)(this);
240 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
243 else if (IsEqualGUID(refiid
, IID_IKsClock
))
245 *Output
= (IKsClock
*)(this);
246 reinterpret_cast<IKsClock
*>(*Output
)->AddRef();
249 else if (IsEqualGUID(refiid
, IID_IReferenceClock
))
251 *Output
= (IReferenceClock
*)(this);
252 reinterpret_cast<IReferenceClock
*>(*Output
)->AddRef();
255 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
257 *Output
= (IMediaSeeking
*)(this);
258 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
261 else if (IsEqualGUID(refiid
, IID_IAMFilterMiscFlags
))
263 *Output
= (IAMFilterMiscFlags
*)(this);
264 reinterpret_cast<IAMFilterMiscFlags
*>(*Output
)->AddRef();
267 else if (IsEqualGUID(refiid
, IID_IKsControl
))
269 *Output
= (IKsControl
*)(this);
270 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
273 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
275 *Output
= (IKsPropertySet
*)(this);
276 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
279 else if (IsEqualGUID(refiid
, IID_IKsTopology
))
281 *Output
= (IKsTopology
*)(this);
282 reinterpret_cast<IKsTopology
*>(*Output
)->AddRef();
285 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
287 *Output
= (IKsAggregateControl
*)(this);
288 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
291 else if (IsEqualGUID(refiid
, IID_IKsClockPropertySet
))
293 *Output
= (IKsClockPropertySet
*)(this);
294 reinterpret_cast<IKsClockPropertySet
*>(*Output
)->AddRef();
297 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
299 *Output
= (ISpecifyPropertyPages
*)(this);
300 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
304 for(ULONG Index
= 0; Index
< m_Plugins
.size(); Index
++)
308 HRESULT hr
= m_Plugins
[Index
]->QueryInterface(refiid
, Output
);
313 StringFromCLSID(refiid
, &lpstr
);
314 swprintf(Buffer
, L
"CKsProxy::QueryInterface plugin %lu supports interface %s\n", Index
, lpstr
);
315 OutputDebugStringW(Buffer
);
316 CoTaskMemFree(lpstr
);
322 WCHAR Buffer
[MAX_PATH
];
324 StringFromCLSID(refiid
, &lpstr
);
325 swprintf(Buffer
, L
"CKsProxy::QueryInterface: NoInterface for %s !!!\n", lpstr
);
326 OutputDebugStringW(Buffer
);
327 CoTaskMemFree(lpstr
);
330 return E_NOINTERFACE
;
333 //-------------------------------------------------------------------
334 // ISpecifyPropertyPages
339 CKsProxy::GetPages(CAUUID
*pPages
)
341 OutputDebugStringW(L
"CKsProxy::GetPages NotImplemented\n");
347 pPages
->pElems
= NULL
;
352 //-------------------------------------------------------------------
353 // IKsClockPropertySet interface
358 CKsProxy::CreateClockInstance()
361 HANDLE hPin
= INVALID_HANDLE_VALUE
;
363 PIN_DIRECTION PinDir
;
365 KSCLOCK_CREATE ClockCreate
;
367 // find output pin and handle
368 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
371 IPin
* pin
= m_Pins
[Index
];
376 hr
= pin
->QueryDirection(&PinDir
);
380 // query IKsObject interface
381 hr
= pin
->QueryInterface(IID_IKsObject
, (void**)&pObject
);
387 hPin
= pObject
->KsGetObjectHandle();
392 if (hPin
!= INVALID_HANDLE_VALUE
)
396 if (hPin
== INVALID_HANDLE_VALUE
)
398 // clock can only be instantiated on a pin handle
404 // release clock handle
405 CloseHandle(m_hClock
);
408 //setup clock create request
409 ClockCreate
.CreateFlags
= 0;
411 // setup clock create request
412 hr
= KsCreateClock(hPin
, &ClockCreate
, &m_hClock
); // FIXME KsCreateClock returns NTSTATUS
415 // failed to create clock
416 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
424 CKsProxy::PerformClockProperty(
428 ULONG OutputBufferSize
)
437 hr
= CreateClockInstance();
443 Property
.Set
= KSPROPSETID_Clock
;
444 Property
.Id
= PropertyId
;
445 Property
.Flags
= PropertyFlags
;
447 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)OutputBuffer
, OutputBufferSize
, &BytesReturned
);
457 OutputDebugStringW(L
"CKsProxy::KsGetTime\n");
458 return PerformClockProperty(KSPROPERTY_CLOCK_TIME
, KSPROPERTY_TYPE_GET
, (PVOID
)Time
, sizeof(LONGLONG
));
466 OutputDebugStringW(L
"CKsProxy::KsSetTime\n");
467 return PerformClockProperty(KSPROPERTY_CLOCK_TIME
, KSPROPERTY_TYPE_SET
, (PVOID
)&Time
, sizeof(LONGLONG
));
472 CKsProxy::KsGetPhysicalTime(
475 OutputDebugStringW(L
"CKsProxy::KsGetPhysicalTime\n");
476 return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)Time
, sizeof(LONGLONG
));
481 CKsProxy::KsSetPhysicalTime(
484 OutputDebugStringW(L
"CKsProxy::KsSetPhysicalTime NotImplemented\n");
485 return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)&Time
, sizeof(LONGLONG
));
490 CKsProxy::KsGetCorrelatedTime(
491 KSCORRELATED_TIME
* CorrelatedTime
)
493 OutputDebugStringW(L
"CKsProxy::KsGetCorrelatedTime\n");
494 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
499 CKsProxy::KsSetCorrelatedTime(
500 KSCORRELATED_TIME
* CorrelatedTime
)
502 OutputDebugStringW(L
"CKsProxy::KsSetCorrelatedTime\n");
503 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
508 CKsProxy::KsGetCorrelatedPhysicalTime(
509 KSCORRELATED_TIME
* CorrelatedTime
)
511 OutputDebugStringW(L
"CKsProxy::KsGetCorrelatedPhysicalTime\n");
512 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
517 CKsProxy::KsSetCorrelatedPhysicalTime(
518 KSCORRELATED_TIME
* CorrelatedTime
)
520 OutputDebugStringW(L
"CKsProxy::KsSetCorrelatedPhysicalTime\n");
521 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
526 CKsProxy::KsGetResolution(
527 KSRESOLUTION
* Resolution
)
529 OutputDebugStringW(L
"CKsProxy::KsGetResolution\n");
530 return PerformClockProperty(KSPROPERTY_CLOCK_RESOLUTION
, KSPROPERTY_TYPE_GET
, (PVOID
)Resolution
, sizeof(KSRESOLUTION
));
535 CKsProxy::KsGetState(
538 OutputDebugStringW(L
"CKsProxy::KsGetState\n");
539 return PerformClockProperty(KSPROPERTY_CLOCK_STATE
, KSPROPERTY_TYPE_GET
, (PVOID
)State
, sizeof(KSSTATE
));
542 //-------------------------------------------------------------------
543 // IReferenceClock interface
548 REFERENCE_TIME
*pTime
)
554 OutputDebugStringW(L
"CKsProxy::GetTime\n");
566 hr
= CreateClockInstance();
572 Property
.Set
= KSPROPSETID_Clock
;
573 Property
.Id
= KSPROPERTY_CLOCK_TIME
;
574 Property
.Flags
= KSPROPERTY_TYPE_GET
;
577 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pTime
, sizeof(REFERENCE_TIME
), &BytesReturned
);
588 CKsProxy::AdviseTime(
589 REFERENCE_TIME baseTime
,
590 REFERENCE_TIME streamTime
,
592 DWORD_PTR
*pdwAdviseCookie
)
597 PKSEVENT_TIME_MARK Event
;
599 OutputDebugStringW(L
"CKsProxy::AdviseTime\n");
605 if (!pdwAdviseCookie
)
611 hr
= CreateClockInstance();
616 // allocate event entry
617 Event
= (PKSEVENT_TIME_MARK
)CoTaskMemAlloc(sizeof(KSEVENT_TIME_MARK
));
621 Property
.Set
= KSEVENTSETID_Clock
;
622 Property
.Id
= KSEVENT_CLOCK_POSITION_MARK
;
623 Property
.Flags
= KSEVENT_TYPE_ENABLE
;
625 Event
->EventData
.NotificationType
= KSEVENTF_EVENT_HANDLE
;
626 Event
->EventData
.EventHandle
.Event
= (HANDLE
)hEvent
;
627 Event
->EventData
.Alignment
.Alignment
[0] = 0;
628 Event
->EventData
.Alignment
.Alignment
[1] = 0;
629 Event
->MarkTime
= baseTime
+ streamTime
;
632 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSEVENT
), (PVOID
)Event
, sizeof(KSEVENT_TIME_MARK
), &BytesReturned
);
635 // store event handle
636 *pdwAdviseCookie
= (DWORD_PTR
)Event
;
640 // failed to enable event
641 CoTaskMemFree(Event
);
654 CKsProxy::AdvisePeriodic(
655 REFERENCE_TIME startTime
,
656 REFERENCE_TIME periodTime
,
657 HSEMAPHORE hSemaphore
,
658 DWORD_PTR
*pdwAdviseCookie
)
663 PKSEVENT_TIME_INTERVAL Event
;
665 OutputDebugStringW(L
"CKsProxy::AdvisePeriodic\n");
671 if (!pdwAdviseCookie
)
677 hr
= CreateClockInstance();
682 // allocate event entry
683 Event
= (PKSEVENT_TIME_INTERVAL
)CoTaskMemAlloc(sizeof(KSEVENT_TIME_INTERVAL
));
687 Property
.Set
= KSEVENTSETID_Clock
;
688 Property
.Id
= KSEVENT_CLOCK_INTERVAL_MARK
;
689 Property
.Flags
= KSEVENT_TYPE_ENABLE
;
691 Event
->EventData
.NotificationType
= KSEVENTF_SEMAPHORE_HANDLE
;
692 Event
->EventData
.SemaphoreHandle
.Semaphore
= (HANDLE
)hSemaphore
;
693 Event
->EventData
.SemaphoreHandle
.Reserved
= 0;
694 Event
->EventData
.SemaphoreHandle
.Adjustment
= 1;
695 Event
->TimeBase
= startTime
;
696 Event
->Interval
= periodTime
;
699 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSEVENT
), (PVOID
)Event
, sizeof(KSEVENT_TIME_INTERVAL
), &BytesReturned
);
702 // store event handle
703 *pdwAdviseCookie
= (DWORD_PTR
)Event
;
707 // failed to enable event
708 CoTaskMemFree(Event
);
722 DWORD_PTR dwAdviseCookie
)
727 OutputDebugStringW(L
"CKsProxy::Unadvise\n");
731 //lets disable the event
732 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)dwAdviseCookie
, sizeof(KSEVENTDATA
), 0, 0, &BytesReturned
);
735 // lets free event data
736 CoTaskMemFree((LPVOID
)dwAdviseCookie
);
741 // no clock available
748 //-------------------------------------------------------------------
749 // IMediaSeeking interface
753 CKsProxy::GetCapabilities(
754 DWORD
*pCapabilities
)
757 ULONG BytesReturned
, Index
;
761 Property
.Set
= KSPROPSETID_MediaSeeking
;
762 Property
.Id
= KSPROPERTY_MEDIASEEKING_CAPABILITIES
;
763 Property
.Flags
= KSPROPERTY_TYPE_GET
;
765 OutputDebugStringW(L
"CKsProxy::GetCapabilities\n");
771 *pCapabilities
= (KS_SEEKING_CanSeekAbsolute
| KS_SEEKING_CanSeekForwards
| KS_SEEKING_CanSeekBackwards
| KS_SEEKING_CanGetCurrentPos
|
772 KS_SEEKING_CanGetStopPos
| KS_SEEKING_CanGetDuration
| KS_SEEKING_CanPlayBackwards
);
774 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pCapabilities
, sizeof(KS_SEEKING_CAPABILITIES
), &BytesReturned
);
775 // check if plugins support it
776 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
779 IUnknown
* Plugin
= m_Plugins
[Index
];
784 // query for IMediaSeeking interface
785 IMediaSeeking
*pSeek
= NULL
;
786 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
795 hr
= pSeek
->GetCapabilities(&TempCaps
);
798 // and with supported flags
799 *pCapabilities
= (*pCapabilities
& TempCaps
);
801 // release IMediaSeeking interface
809 CKsProxy::CheckCapabilities(
810 DWORD
*pCapabilities
)
815 OutputDebugStringW(L
"CKsProxy::CheckCapabilities\n");
823 hr
= GetCapabilities(&Capabilities
);
826 if ((Capabilities
| *pCapabilities
) == Capabilities
)
832 Capabilities
= (Capabilities
& *pCapabilities
);
836 *pCapabilities
= Capabilities
;
839 // no capabilities are present
848 CKsProxy::GetMediaSeekingFormats(
849 PKSMULTIPLE_ITEM
*FormatList
)
855 Property
.Set
= KSPROPSETID_MediaSeeking
;
856 Property
.Id
= KSPROPERTY_MEDIASEEKING_FORMATS
;
857 Property
.Flags
= KSPROPERTY_TYPE_GET
;
859 // query for format size list
860 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &BytesReturned
);
862 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
864 // allocate format list
865 *FormatList
= (PKSMULTIPLE_ITEM
)CoTaskMemAlloc(BytesReturned
);
869 return E_OUTOFMEMORY
;
873 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)*FormatList
, BytesReturned
, &BytesReturned
);
876 // failed to query format list
877 CoTaskMemFree(FormatList
);
885 CKsProxy::IsFormatSupported(
888 PKSMULTIPLE_ITEM FormatList
;
891 HRESULT hr
= S_FALSE
;
893 OutputDebugStringW(L
"CKsProxy::IsFormatSupported\n");
899 hr
= GetMediaSeekingFormats(&FormatList
);
902 //iterate through format list
903 pGuid
= (LPGUID
)(FormatList
+ 1);
904 for(Index
= 0; Index
< FormatList
->Count
; Index
++)
906 if (IsEqualGUID(*pGuid
, *pFormat
))
908 CoTaskMemFree(FormatList
);
914 CoTaskMemFree(FormatList
);
917 // check if all plugins support it
918 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
921 IUnknown
* Plugin
= m_Plugins
[Index
];
926 // query for IMediaSeeking interface
927 IMediaSeeking
*pSeek
= NULL
;
928 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
931 // plugin does not support interface
933 OutputDebugStringW(L
"CKsProxy::IsFormatSupported plugin does not support IMediaSeeking interface\n");
937 // query if it is supported
938 hr
= pSeek
->IsFormatSupported(pFormat
);
942 if (FAILED(hr
) || hr
== S_FALSE
)
951 CKsProxy::QueryPreferredFormat(
954 PKSMULTIPLE_ITEM FormatList
;
958 OutputDebugStringW(L
"CKsProxy::QueryPreferredFormat\n");
963 hr
= GetMediaSeekingFormats(&FormatList
);
966 if (FormatList
->Count
)
968 CopyMemory(pFormat
, (FormatList
+ 1), sizeof(GUID
));
969 CoTaskMemFree(FormatList
);
972 CoTaskMemFree(FormatList
);
974 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
976 // check if plugins support it
977 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
980 IUnknown
* Plugin
= m_Plugins
[Index
];
985 // query for IMediaSeeking interface
986 IMediaSeeking
*pSeek
= NULL
;
987 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
990 // get preferred time format
991 hr
= pSeek
->QueryPreferredFormat(pFormat
);
992 // release IMediaSeeking interface
1007 CKsProxy::GetTimeFormat(
1010 KSPROPERTY Property
;
1011 ULONG BytesReturned
, Index
;
1014 Property
.Set
= KSPROPSETID_MediaSeeking
;
1015 Property
.Id
= KSPROPERTY_MEDIASEEKING_TIMEFORMAT
;
1016 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1018 OutputDebugStringW(L
"CKsProxy::GetTimeFormat\n");
1020 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pFormat
, sizeof(GUID
), &BytesReturned
);
1021 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1023 // check if plugins support it
1024 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1028 IUnknown
* Plugin
= m_Plugins
[Index
];
1033 // query for IMediaSeeking interface
1034 IMediaSeeking
*pSeek
= NULL
;
1035 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1039 hr
= pSeek
->GetTimeFormat(pFormat
);
1040 // release IMediaSeeking interface
1053 CKsProxy::IsUsingTimeFormat(
1054 const GUID
*pFormat
)
1058 OutputDebugStringW(L
"CKsProxy::IsUsingTimeFormat\n");
1060 if (FAILED(QueryPreferredFormat(&Format
)))
1063 if (IsEqualGUID(Format
, *pFormat
))
1071 CKsProxy::SetTimeFormat(
1072 const GUID
*pFormat
)
1074 KSPROPERTY Property
;
1075 ULONG BytesReturned
, Index
;
1078 Property
.Set
= KSPROPSETID_MediaSeeking
;
1079 Property
.Id
= KSPROPERTY_MEDIASEEKING_TIMEFORMAT
;
1080 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1082 OutputDebugStringW(L
"CKsProxy::SetTimeFormat\n");
1084 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pFormat
, sizeof(GUID
), &BytesReturned
);
1085 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1087 // check if plugins support it
1088 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1092 IUnknown
* Plugin
= m_Plugins
[Index
];
1097 // query for IMediaSeeking interface
1098 IMediaSeeking
*pSeek
= NULL
;
1099 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1106 hr
= pSeek
->SetTimeFormat(pFormat
);
1107 // release IMediaSeeking interface
1119 CKsProxy::GetDuration(
1120 LONGLONG
*pDuration
)
1122 KSPROPERTY Property
;
1123 ULONG BytesReturned
, Index
;
1126 Property
.Set
= KSPROPSETID_MediaSeeking
;
1127 Property
.Id
= KSPROPERTY_MEDIASEEKING_DURATION
;
1128 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1130 OutputDebugStringW(L
"CKsProxy::GetDuration\n");
1132 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pDuration
, sizeof(LONGLONG
), &BytesReturned
);
1133 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1135 // check if plugins support it
1136 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1140 IUnknown
* Plugin
= m_Plugins
[Index
];
1145 // query for IMediaSeeking interface
1146 IMediaSeeking
*pSeek
= NULL
;
1147 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1151 hr
= pSeek
->GetStopPosition(pDuration
);
1152 // release IMediaSeeking interface
1155 if (hr
!= S_FALSE
) // plugin implements it
1165 CKsProxy::GetStopPosition(
1168 KSPROPERTY Property
;
1169 ULONG BytesReturned
, Index
;
1172 Property
.Set
= KSPROPSETID_MediaSeeking
;
1173 Property
.Id
= KSPROPERTY_MEDIASEEKING_STOPPOSITION
;
1174 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1176 OutputDebugStringW(L
"CKsProxy::GetStopPosition\n");
1178 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pStop
, sizeof(LONGLONG
), &BytesReturned
);
1179 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1181 // check if plugins support it
1182 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1186 IUnknown
* Plugin
= m_Plugins
[Index
];
1191 // query for IMediaSeeking interface
1192 IMediaSeeking
*pSeek
= NULL
;
1193 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1196 // get stop position
1197 hr
= pSeek
->GetStopPosition(pStop
);
1198 // release IMediaSeeking interface
1201 if (hr
!= S_FALSE
) // plugin implements it
1211 CKsProxy::GetCurrentPosition(
1214 KSPROPERTY Property
;
1215 ULONG BytesReturned
, Index
;
1218 Property
.Set
= KSPROPSETID_MediaSeeking
;
1219 Property
.Id
= KSPROPERTY_MEDIASEEKING_POSITION
;
1220 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1222 OutputDebugStringW(L
"CKsProxy::GetCurrentPosition\n");
1224 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pCurrent
, sizeof(LONGLONG
), &BytesReturned
);
1225 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1227 // check if plugins support it
1228 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1232 IUnknown
* Plugin
= m_Plugins
[Index
];
1237 // query for IMediaSeeking interface
1238 IMediaSeeking
*pSeek
= NULL
;
1239 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1242 // get current position
1243 hr
= pSeek
->GetCurrentPosition(pCurrent
);
1244 // release IMediaSeeking interface
1247 if (hr
!= S_FALSE
) // plugin implements it
1257 CKsProxy::ConvertTimeFormat(
1259 const GUID
*pTargetFormat
,
1261 const GUID
*pSourceFormat
)
1263 KSP_TIMEFORMAT Property
;
1264 ULONG BytesReturned
, Index
;
1265 GUID SourceFormat
, TargetFormat
;
1268 Property
.Property
.Set
= KSPROPSETID_MediaSeeking
;
1269 Property
.Property
.Id
= KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT
;
1270 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
1272 OutputDebugStringW(L
"CKsProxy::ConvertTimeFormat\n");
1276 // get current format
1277 hr
= GetTimeFormat(&TargetFormat
);
1281 pTargetFormat
= &TargetFormat
;
1286 // get current format
1287 hr
= GetTimeFormat(&SourceFormat
);
1291 pSourceFormat
= &SourceFormat
;
1294 Property
.SourceFormat
= *pSourceFormat
;
1295 Property
.TargetFormat
= *pTargetFormat
;
1296 Property
.Time
= Source
;
1299 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_TIMEFORMAT
), (PVOID
)pTarget
, sizeof(LONGLONG
), &BytesReturned
);
1300 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1305 // check if plugins support it
1306 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1309 IUnknown
* Plugin
= m_Plugins
[Index
];
1314 // query for IMediaSeeking interface
1315 IMediaSeeking
*pSeek
= NULL
;
1316 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1319 // convert time format
1320 hr
= pSeek
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
1321 // release IMediaSeeking interface
1324 if (hr
!= S_FALSE
) // plugin implements it
1335 CKsProxy::SetPositions(
1337 DWORD dwCurrentFlags
,
1341 KSPROPERTY Property
;
1342 KSPROPERTY_POSITIONS Positions
;
1343 ULONG BytesReturned
, Index
;
1346 Property
.Set
= KSPROPSETID_MediaSeeking
;
1347 Property
.Id
= KSPROPERTY_MEDIASEEKING_POSITIONS
;
1348 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1350 Positions
.Current
= *pCurrent
;
1351 Positions
.CurrentFlags
= (KS_SEEKING_FLAGS
)dwCurrentFlags
;
1352 Positions
.Stop
= *pStop
;
1353 Positions
.StopFlags
= (KS_SEEKING_FLAGS
)dwStopFlags
;
1355 OutputDebugStringW(L
"CKsProxy::SetPositions\n");
1357 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Positions
, sizeof(KSPROPERTY_POSITIONS
), &BytesReturned
);
1360 if (dwCurrentFlags
& AM_SEEKING_ReturnTime
)
1362 // retrieve current position
1363 hr
= GetCurrentPosition(pCurrent
);
1368 if (dwStopFlags
& AM_SEEKING_ReturnTime
)
1370 // retrieve current position
1371 hr
= GetStopPosition(pStop
);
1376 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1380 // check if plugins support it
1381 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1384 IUnknown
* Plugin
= m_Plugins
[Index
];
1389 // query for IMediaSeeking interface
1390 IMediaSeeking
*pSeek
= NULL
;
1391 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1395 hr
= pSeek
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
1396 // release IMediaSeeking interface
1410 CKsProxy::GetPositions(
1416 OutputDebugStringW(L
"CKsProxy::GetPositions\n");
1418 hr
= GetCurrentPosition(pCurrent
);
1420 hr
= GetStopPosition(pStop
);
1427 CKsProxy::GetAvailable(
1428 LONGLONG
*pEarliest
,
1431 KSPROPERTY Property
;
1432 KSPROPERTY_MEDIAAVAILABLE Media
;
1433 ULONG BytesReturned
, Index
;
1436 Property
.Set
= KSPROPSETID_MediaSeeking
;
1437 Property
.Id
= KSPROPERTY_MEDIASEEKING_AVAILABLE
;
1438 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1440 OutputDebugStringW(L
"CKsProxy::GetAvailable\n");
1442 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Media
, sizeof(KSPROPERTY_MEDIAAVAILABLE
), &BytesReturned
);
1443 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1445 // check if plugins support it
1446 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1450 IUnknown
* Plugin
= m_Plugins
[Index
];
1455 // query for IMediaSeeking interface
1456 IMediaSeeking
*pSeek
= NULL
;
1457 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1461 hr
= pSeek
->GetAvailable(pEarliest
, pLatest
);
1462 // release IMediaSeeking interface
1465 if (hr
!= S_FALSE
) // plugin implements it
1470 else if (SUCCEEDED(hr
))
1472 *pEarliest
= Media
.Earliest
;
1473 *pLatest
= Media
.Latest
;
1497 CKsProxy::GetPreroll(
1498 LONGLONG
*pllPreroll
)
1500 KSPROPERTY Property
;
1501 ULONG BytesReturned
, Index
;
1504 Property
.Set
= KSPROPSETID_MediaSeeking
;
1505 Property
.Id
= KSPROPERTY_MEDIASEEKING_PREROLL
;
1506 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1508 OutputDebugStringW(L
"CKsProxy::GetPreroll\n");
1510 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pllPreroll
, sizeof(LONGLONG
), &BytesReturned
);
1511 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1513 // check if all plugins support it
1514 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1517 IUnknown
* Plugin
= m_Plugins
[Index
];
1522 // query for IMediaSeeking interface
1523 IMediaSeeking
*pSeek
= NULL
;
1524 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1528 hr
= pSeek
->GetPreroll(pllPreroll
);
1529 // release IMediaSeeking interface
1532 if (hr
!= S_FALSE
) // plugin implements it
1541 //-------------------------------------------------------------------
1542 // IAMFilterMiscFlags interface
1547 CKsProxy::GetMiscFlags()
1552 PIN_DIRECTION PinDirection
;
1553 KSPIN_COMMUNICATION Communication
;
1555 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
1558 IPin
* pin
= m_Pins
[Index
];
1560 hr
= pin
->QueryDirection(&PinDirection
);
1563 if (PinDirection
== PINDIR_INPUT
)
1565 if (SUCCEEDED(GetPinCommunication(Index
, //FIXME verify PinId
1568 if (Communication
== KSPIN_COMMUNICATION_NONE
|| Communication
== KSPIN_COMMUNICATION_BRIDGE
)
1570 Flags
|= AM_FILTER_MISC_FLAGS_IS_SOURCE
;
1577 OutputDebugStringW(L
"CKsProxy::GetMiscFlags stub\n");
1581 //-------------------------------------------------------------------
1586 CKsProxy::KsProperty(
1587 PKSPROPERTY Property
,
1588 ULONG PropertyLength
,
1589 LPVOID PropertyData
,
1591 ULONG
* BytesReturned
)
1593 assert(m_hDevice
!= 0);
1594 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1604 ULONG
* BytesReturned
)
1606 assert(m_hDevice
!= 0);
1607 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1617 ULONG
* BytesReturned
)
1619 assert(m_hDevice
!= 0);
1622 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1624 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1628 //-------------------------------------------------------------------
1634 REFGUID guidPropSet
,
1636 LPVOID pInstanceData
,
1637 DWORD cbInstanceData
,
1641 ULONG BytesReturned
;
1645 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1647 return E_OUTOFMEMORY
;
1649 Property
->Set
= guidPropSet
;
1650 Property
->Id
= dwPropID
;
1651 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1653 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1655 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1656 CoTaskMemFree(Property
);
1661 KSPROPERTY Property
;
1663 Property
.Set
= guidPropSet
;
1664 Property
.Id
= dwPropID
;
1665 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1667 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1675 REFGUID guidPropSet
,
1677 LPVOID pInstanceData
,
1678 DWORD cbInstanceData
,
1683 ULONG BytesReturned
;
1687 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1689 return E_OUTOFMEMORY
;
1691 Property
->Set
= guidPropSet
;
1692 Property
->Id
= dwPropID
;
1693 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1695 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1697 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1698 CoTaskMemFree(Property
);
1703 KSPROPERTY Property
;
1705 Property
.Set
= guidPropSet
;
1706 Property
.Id
= dwPropID
;
1707 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1709 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1716 CKsProxy::QuerySupported(
1717 REFGUID guidPropSet
,
1719 DWORD
*pTypeSupport
)
1721 KSPROPERTY Property
;
1722 ULONG BytesReturned
;
1724 Property
.Set
= guidPropSet
;
1725 Property
.Id
= dwPropID
;
1726 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1728 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1732 //-------------------------------------------------------------------
1733 // IKsTopology interface
1737 CKsProxy::CreateNodeInstance(
1740 ACCESS_MASK DesiredAccess
,
1742 REFGUID InterfaceId
,
1747 OutputDebugStringW(L
"CKsProxy::CreateNodeInstance\n");
1751 if (IsEqualIID(IID_IUnknown
, InterfaceId
) || !UnkOuter
)
1753 hr
= CKsNode_Constructor(UnkOuter
, m_hDevice
, NodeId
, DesiredAccess
, InterfaceId
, Interface
);
1757 // interface not supported
1764 //-------------------------------------------------------------------
1765 // IKsAggregateControl interface
1769 CKsProxy::KsAddAggregate(
1770 IN REFGUID AggregateClass
)
1772 OutputDebugStringW(L
"CKsProxy::KsAddAggregate NotImplemented\n");
1778 CKsProxy::KsRemoveAggregate(
1779 REFGUID AggregateClass
)
1781 OutputDebugStringW(L
"CKsProxy::KsRemoveAggregate NotImplemented\n");
1786 //-------------------------------------------------------------------
1787 // IPersistStream interface
1794 OutputDebugStringW(L
"CKsProxy::IsDirty Notimplemented\n");
1806 AM_MEDIA_TYPE MediaType
;
1807 ULONG BytesReturned
;
1811 LPOLESTR pMajor
, pSub
, pFormat
;
1813 OutputDebugStringW(L
"CKsProxy::Load\n");
1816 ULONG Version
= ReadInt(pStm
, hr
);
1821 hr
= pStm
->Read(&Length
, sizeof(ULONG
), &BytesReturned
);
1822 swprintf(Buffer
, L
"Length hr %x hr length %lu\n", hr
, Length
);
1823 OutputDebugStringW(Buffer
);
1827 hr
= pStm
->Read(&PinId
, sizeof(ULONG
), &BytesReturned
);
1828 swprintf(Buffer
, L
"Read: hr %08x PinId %lx BytesReturned %lu\n", hr
, PinId
, BytesReturned
);
1829 OutputDebugStringW(Buffer
);
1831 if (FAILED(hr
) || !BytesReturned
)
1834 Length
-= BytesReturned
;
1836 hr
= pStm
->Read(&MediaType
, sizeof(AM_MEDIA_TYPE
), &BytesReturned
);
1837 if (FAILED(hr
) || BytesReturned
!= sizeof(AM_MEDIA_TYPE
))
1839 swprintf(Buffer
, L
"Read failed with %lx\n", hr
);
1840 OutputDebugStringW(Buffer
);
1845 StringFromIID(MediaType
.majortype
, &pMajor
);
1846 StringFromIID(MediaType
.subtype
, &pSub
);
1847 StringFromIID(MediaType
.formattype
, &pFormat
);
1849 swprintf(Buffer
, L
"BytesReturned %lu majortype %s subtype %s bFixedSizeSamples %u bTemporalCompression %u lSampleSize %u formattype %s, pUnk %p cbFormat %u pbFormat %p\n", BytesReturned
, pMajor
, pSub
, MediaType
.bFixedSizeSamples
, MediaType
.bTemporalCompression
, MediaType
.lSampleSize
, pFormat
, MediaType
.pUnk
, MediaType
.cbFormat
, MediaType
.pbFormat
);
1850 OutputDebugStringW(Buffer
);
1852 Length
-= BytesReturned
;
1855 if (MediaType
.cbFormat
)
1857 MediaType
.pbFormat
= (BYTE
*)CoTaskMemAlloc(MediaType
.cbFormat
);
1858 if (!MediaType
.pbFormat
)
1859 return E_OUTOFMEMORY
;
1861 hr
= pStm
->Read(&MediaType
.pbFormat
, sizeof(MediaType
.cbFormat
), &BytesReturned
);
1864 swprintf(Buffer
, L
"ReadFormat failed with %lx\n", hr
);
1865 OutputDebugStringW(Buffer
);
1868 Length
-= BytesReturned
;
1883 OutputDebugStringW(L
"CKsProxy::Save Notimplemented\n");
1889 CKsProxy::GetSizeMax(
1890 ULARGE_INTEGER
*pcbSize
)
1892 OutputDebugStringW(L
"CKsProxy::GetSizeMax Notimplemented\n");
1897 //-------------------------------------------------------------------
1898 // IAMDeviceRemoval interface
1903 CKsProxy::DeviceInfo(CLSID
*pclsidInterfaceClass
, LPWSTR
*pwszSymbolicLink
)
1907 // object not initialized
1908 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_FILE_NOT_FOUND
);
1911 // copy device interface guid
1912 CopyMemory(pclsidInterfaceClass
, &m_DeviceInterfaceGUID
, sizeof(GUID
));
1914 if (pwszSymbolicLink
)
1916 *pwszSymbolicLink
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_DevicePath
)+1) * sizeof(WCHAR
));
1917 if (!*pwszSymbolicLink
)
1918 return E_OUTOFMEMORY
;
1920 wcscpy(*pwszSymbolicLink
, m_DevicePath
);
1926 CKsProxy::Reassociate(void)
1928 if (!m_DevicePath
|| m_hDevice
)
1930 // file path not available
1931 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_FILE_NOT_FOUND
);
1934 m_hDevice
= CreateFileW(m_DevicePath
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
1937 // failed to open device
1938 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
1947 CKsProxy::Disassociate(void)
1952 CloseHandle(m_hDevice
);
1957 //-------------------------------------------------------------------
1958 // IKsClock interface
1963 CKsProxy::KsGetClockHandle()
1969 //-------------------------------------------------------------------
1970 // IKsObject interface
1975 CKsProxy::KsGetObjectHandle()
1980 //-------------------------------------------------------------------
1981 // IPersistPropertyBag interface
1985 CKsProxy::InitNew( void)
1992 CKsProxy::GetSupportedSets(
1996 KSPROPERTY Property
;
1998 ULONG NumProperty
= 0;
1999 ULONG NumMethods
= 0;
2000 ULONG NumEvents
= 0;
2002 ULONG BytesReturned
;
2005 Property
.Set
= GUID_NULL
;
2007 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
2009 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumProperty
);
2010 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumMethods
);
2011 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumEvents
);
2013 Length
= NumProperty
+ NumMethods
+ NumEvents
;
2015 // allocate guid buffer
2016 pGuid
= (LPGUID
)CoTaskMemAlloc(Length
);
2020 return E_OUTOFMEMORY
;
2023 NumProperty
/= sizeof(GUID
);
2024 NumMethods
/= sizeof(GUID
);
2025 NumEvents
/= sizeof(GUID
);
2027 // get all properties
2028 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pGuid
, Length
, &BytesReturned
);
2031 CoTaskMemFree(pGuid
);
2034 Length
-= BytesReturned
;
2039 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
], Length
, &BytesReturned
);
2042 CoTaskMemFree(pGuid
);
2045 Length
-= BytesReturned
;
2051 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
+NumMethods
], Length
, &BytesReturned
);
2054 CoTaskMemFree(pGuid
);
2057 Length
-= BytesReturned
;
2060 #ifdef KSPROXY_TRACE
2062 swprintf(Buffer
, L
"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty
, NumMethods
, NumEvents
);
2063 OutputDebugStringW(Buffer
);
2067 *NumGuids
= NumProperty
+NumEvents
+NumMethods
;
2073 CKsProxy::LoadProxyPlugins(
2081 IUnknown
* pUnknown
;
2083 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
2085 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
2089 // enumerate all sets
2090 for(Index
= 0; Index
< NumGuids
; Index
++)
2092 // convert to string
2093 hr
= StringFromCLSID(pGuids
[Index
], &pStr
);
2097 // now try open class key
2098 if (RegOpenKeyExW(hKey
, pStr
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
2100 // no plugin for that set exists
2101 CoTaskMemFree(pStr
);
2106 hr
= CoCreateInstance(pGuids
[Index
], (IBaseFilter
*)this, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void**)&pUnknown
);
2110 m_Plugins
.push_back(pUnknown
);
2113 RegCloseKey(hSubKey
);
2116 // close media interfaces key
2123 CKsProxy::GetNumberOfPins(
2126 KSPROPERTY Property
;
2127 ULONG BytesReturned
;
2130 Property
.Set
= KSPROPSETID_Pin
;
2131 Property
.Id
= KSPROPERTY_PIN_CTYPES
;
2132 Property
.Flags
= KSPROPERTY_TYPE_GET
;
2134 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)NumPins
, sizeof(ULONG
), &BytesReturned
);
2139 CKsProxy::GetPinInstanceCount(
2141 PKSPIN_CINSTANCES Instances
)
2144 ULONG BytesReturned
;
2147 Property
.Property
.Set
= KSPROPSETID_Pin
;
2148 Property
.Property
.Id
= KSPROPERTY_PIN_CINSTANCES
;
2149 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2150 Property
.PinId
= PinId
;
2151 Property
.Reserved
= 0;
2153 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)Instances
, sizeof(KSPIN_CINSTANCES
), &BytesReturned
);
2158 CKsProxy::GetPinCommunication(
2160 KSPIN_COMMUNICATION
* Communication
)
2163 ULONG BytesReturned
;
2166 Property
.Property
.Set
= KSPROPSETID_Pin
;
2167 Property
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
2168 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2169 Property
.PinId
= PinId
;
2170 Property
.Reserved
= 0;
2172 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)Communication
, sizeof(KSPIN_COMMUNICATION
), &BytesReturned
);
2177 CKsProxy::GetPinDataflow(
2179 KSPIN_DATAFLOW
* DataFlow
)
2182 ULONG BytesReturned
;
2185 Property
.Property
.Set
= KSPROPSETID_Pin
;
2186 Property
.Property
.Id
= KSPROPERTY_PIN_DATAFLOW
;
2187 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2188 Property
.PinId
= PinId
;
2189 Property
.Reserved
= 0;
2191 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)DataFlow
, sizeof(KSPIN_DATAFLOW
), &BytesReturned
);
2196 CKsProxy::GetPinName(
2198 KSPIN_DATAFLOW DataFlow
,
2200 LPWSTR
* OutPinName
)
2204 ULONG BytesReturned
;
2209 Property
.Property
.Set
= KSPROPSETID_Pin
;
2210 Property
.Property
.Id
= KSPROPERTY_PIN_NAME
;
2211 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2212 Property
.PinId
= PinId
;
2213 Property
.Reserved
= 0;
2215 // #1 try get it from pin directly
2216 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
2218 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
2220 // allocate pin name
2221 PinName
= (LPWSTR
)CoTaskMemAlloc(BytesReturned
);
2223 return E_OUTOFMEMORY
;
2225 // retry with allocated buffer
2226 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), PinName
, BytesReturned
, &BytesReturned
);
2229 *OutPinName
= PinName
;
2234 CoTaskMemFree(PinName
);
2238 // TODO: retrieve pin name from topology node
2241 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2243 swprintf(Buffer
, L
"Input%lu", PinCount
);
2247 swprintf(Buffer
, L
"Output%lu", PinCount
);
2250 // allocate pin name
2251 PinName
= (LPWSTR
)CoTaskMemAlloc((wcslen(Buffer
)+1) * sizeof(WCHAR
));
2253 return E_OUTOFMEMORY
;
2256 wcscpy(PinName
, Buffer
);
2259 *OutPinName
= PinName
;
2266 CKsProxy::CreatePins()
2268 ULONG NumPins
, Index
;
2269 KSPIN_CINSTANCES Instances
;
2270 KSPIN_DATAFLOW DataFlow
;
2271 KSPIN_COMMUNICATION Communication
;
2277 ULONG OutputPin
= 0;
2279 // get number of pins
2280 hr
= GetNumberOfPins(&NumPins
);
2284 for(Index
= 0; Index
< NumPins
; Index
++)
2286 // query current instance count
2287 hr
= GetPinInstanceCount(Index
, &Instances
);
2291 // query pin communication;
2292 hr
= GetPinCommunication(Index
, &Communication
);
2296 if (Instances
.CurrentCount
== Instances
.PossibleCount
)
2298 // already maximum reached for this pin
2302 // get direction of pin
2303 hr
= GetPinDataflow(Index
, &DataFlow
);
2307 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2308 hr
= GetPinName(Index
, DataFlow
, InputPin
, &PinName
);
2310 hr
= GetPinName(Index
, DataFlow
, OutputPin
, &PinName
);
2315 // construct the pins
2316 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2318 hr
= CInputPin_Constructor((IBaseFilter
*)this, PinName
, m_hDevice
, Index
, Communication
, IID_IPin
, (void**)&pPin
);
2321 CoTaskMemFree(PinName
);
2328 hr
= COutputPin_Constructor((IBaseFilter
*)this, PinName
, Index
, IID_IPin
, (void**)&pPin
);
2331 CoTaskMemFree(PinName
);
2338 m_Pins
.push_back(pPin
);
2340 swprintf(Buffer
, L
"Index %lu DataFlow %lu Name %s\n", Index
, DataFlow
, PinName
);
2341 OutputDebugStringW(Buffer
);
2349 CKsProxy::Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
)
2357 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
2361 varName
.vt
= VT_BSTR
;
2362 hr
= pPropBag
->Read(L
"DevicePath", &varName
, pErrorLog
);
2366 swprintf(Buffer
, L
"CKsProxy::Load Read %lx\n", hr
);
2367 OutputDebugStringW(Buffer
);
2368 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2371 // create device list
2372 hList
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
2373 if (hList
== INVALID_HANDLE_VALUE
)
2375 // failed to create device list
2376 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2379 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
2380 if (!SetupDiOpenDeviceInterfaceW(hList
, (PCWSTR
)varName
.bstrVal
, 0, &DeviceInterfaceData
))
2382 // failed to open device interface
2383 SetupDiDestroyDeviceInfoList(hList
);
2386 // FIXME handle device interface links(aliases)
2387 CopyMemory(&m_DeviceInterfaceGUID
, &DeviceInterfaceData
.InterfaceClassGuid
, sizeof(GUID
));
2389 // close device info list
2390 SetupDiDestroyDeviceInfoList(hList
);
2393 m_hDevice
= CreateFileW(varName
.bstrVal
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2395 if (m_hDevice
== INVALID_HANDLE_VALUE
)
2397 // failed to open device
2398 swprintf(Buffer
, L
"CKsProxy:: failed to open device with %lx\n", GetLastError());
2399 OutputDebugStringW(Buffer
);
2401 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2404 // store device path
2405 m_DevicePath
= varName
.bstrVal
;
2407 // get all supported sets
2408 hr
= GetSupportedSets(&pGuid
, &NumGuids
);
2411 CloseHandle(m_hDevice
);
2416 // load all proxy plugins
2417 hr
= LoadProxyPlugins(pGuid
, NumGuids
);
2420 CloseHandle(m_hDevice
);
2426 CoTaskMemFree(pGuid
);
2428 // now create the input / output pins
2436 CKsProxy::Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
)
2441 //-------------------------------------------------------------------
2442 // IBaseFilter interface
2447 CKsProxy::GetClassID(
2450 OutputDebugStringW(L
"CKsProxy::GetClassID : NotImplemented\n");
2458 OutputDebugStringW(L
"CKsProxy::Stop : NotImplemented\n");
2466 OutputDebugStringW(L
"CKsProxy::Pause : NotImplemented\n");
2473 REFERENCE_TIME tStart
)
2475 OutputDebugStringW(L
"CKsProxy::Run : NotImplemented\n");
2482 DWORD dwMilliSecsTimeout
,
2483 FILTER_STATE
*State
)
2485 *State
= m_FilterState
;
2491 CKsProxy::SetSyncSource(
2492 IReferenceClock
*pClock
)
2496 HANDLE hClock
, hPin
;
2499 IKsObject
* pObject
;
2500 KSPROPERTY Property
;
2501 ULONG BytesReturned
;
2502 PIN_DIRECTION PinDir
;
2504 // Plug In Distributor: IKsClock
2513 hr
= pClock
->QueryInterface(IID_IKsClock
, (void**)&pKsClock
);
2518 hClock
= pKsClock
->KsGetClockHandle();
2519 if (!hClock
|| hClock
== INVALID_HANDLE_VALUE
)
2522 pKsClock
->Release();
2526 // distribute clock to all pins
2527 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
2530 pin
= m_Pins
[Index
];
2534 // get IKsObject interface
2535 hr
= pin
->QueryInterface(IID_IKsObject
, (void **)&pObject
);
2539 hPin
= pObject
->KsGetObjectHandle();
2540 if (hPin
!= INVALID_HANDLE_VALUE
&& hPin
)
2543 Property
.Set
= KSPROPSETID_Stream
;
2544 Property
.Id
= KSPROPERTY_STREAM_MASTERCLOCK
;
2545 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2548 hr
= KsSynchronousDeviceControl(hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)hClock
, sizeof(HANDLE
), &BytesReturned
);
2552 if (hr
!= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
) &&
2553 hr
!= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
))
2555 // failed to set master clock
2556 pKsClock
->Release();
2562 // release IKsObject
2566 // now get the direction
2567 hr
= pin
->QueryDirection(&PinDir
);
2570 if (PinDir
== PINDIR_OUTPUT
)
2573 //CBaseStreamControl::SetSyncSource(pClock)
2583 if (m_ReferenceClock
)
2585 m_ReferenceClock
->Release();
2588 m_ReferenceClock
= pClock
;
2594 CKsProxy::GetSyncSource(
2595 IReferenceClock
**pClock
)
2600 if (m_ReferenceClock
)
2601 m_ReferenceClock
->AddRef();
2603 *pClock
= m_ReferenceClock
;
2612 return CEnumPins_fnConstructor(m_Pins
, IID_IEnumPins
, (void**)ppEnum
);
2618 LPCWSTR Id
, IPin
**ppPin
)
2626 int ret
= swscanf(Id
, L
"%u", &PinId
);
2628 if (!ret
|| ret
== EOF
)
2631 return VFW_E_NOT_FOUND
;
2634 if (PinId
>= m_Pins
.size() || m_Pins
[PinId
] == NULL
)
2637 return VFW_E_NOT_FOUND
;
2641 *ppPin
= m_Pins
[PinId
];
2642 m_Pins
[PinId
]->AddRef();
2650 CKsProxy::QueryFilterInfo(
2656 pInfo
->achName
[0] = L
'\0';
2657 pInfo
->pGraph
= m_pGraph
;
2667 CKsProxy::JoinFilterGraph(
2668 IFilterGraph
*pGraph
,
2673 // joining filter graph
2688 CKsProxy::QueryVendorInfo(
2689 LPWSTR
*pVendorInfo
)
2691 OutputDebugStringW(L
"CKsProxy::QueryVendorInfo : NotImplemented\n");
2695 //-------------------------------------------------------------------
2696 // IAMovieSetup interface
2701 CKsProxy::Register()
2703 OutputDebugStringW(L
"CKsProxy::Register : NotImplemented\n");
2709 CKsProxy::Unregister()
2711 OutputDebugStringW(L
"CKsProxy::Unregister : NotImplemented\n");
2717 CKsProxy_Constructor(
2718 IUnknown
* pUnkOuter
,
2724 StringFromCLSID(riid
, &pstr
);
2725 swprintf(Buffer
, L
"CKsProxy_Constructor pUnkOuter %p riid %s\n", pUnkOuter
, pstr
);
2726 OutputDebugStringW(Buffer
);
2728 CKsProxy
* handler
= new CKsProxy();
2731 return E_OUTOFMEMORY
;
2733 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
2737 return E_NOINTERFACE
;