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}};
20 const GUID IID_IPersist
= {0x0000010c, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
23 const GUID IID_IBDA_DeviceControl
= {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
24 const GUID IID_IKsAggregateControl
= {0x7F40EAC0, 0x3947, 0x11D2, {0x87, 0x4E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
25 const GUID IID_IKsClockPropertySet
= {0x5C5CBD84, 0xE755, 0x11D0, {0xAC, 0x18, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
26 const GUID IID_IKsTopology
= {0x28F54683, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
27 const GUID IID_IKsClock
= {0x877E4351, 0x6FEA, 0x11D0, {0xB8, 0x63, 0x00, 0xAA, 0x00, 0xA2, 0x16, 0xA1}};
29 Needs IKsClock, IKsNotifyEvent
32 class CKsProxy
: public IBaseFilter
,
34 public IPersistPropertyBag
,
36 public IPersistStream
,
37 public IAMDeviceRemoval
,
38 public ISpecifyPropertyPages
,
39 public IReferenceClock
,
41 public IKsPropertySet
,
43 public IKsClockPropertySet
,
44 public IAMFilterMiscFlags
,
47 public IKsAggregateControl
51 typedef std::vector
<IUnknown
*>ProxyPluginVector
;
52 typedef std::vector
<IPin
*> PinVector
;
54 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
56 STDMETHODIMP_(ULONG
) AddRef()
58 InterlockedIncrement(&m_Ref
);
61 STDMETHODIMP_(ULONG
) Release()
63 InterlockedDecrement(&m_Ref
);
72 // IBaseFilter methods
73 HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
74 HRESULT STDMETHODCALLTYPE
Stop( void);
75 HRESULT STDMETHODCALLTYPE
Pause( void);
76 HRESULT STDMETHODCALLTYPE
Run(REFERENCE_TIME tStart
);
77 HRESULT STDMETHODCALLTYPE
GetState(DWORD dwMilliSecsTimeout
, FILTER_STATE
*State
);
78 HRESULT STDMETHODCALLTYPE
SetSyncSource(IReferenceClock
*pClock
);
79 HRESULT STDMETHODCALLTYPE
GetSyncSource(IReferenceClock
**pClock
);
80 HRESULT STDMETHODCALLTYPE
EnumPins(IEnumPins
**ppEnum
);
81 HRESULT STDMETHODCALLTYPE
FindPin(LPCWSTR Id
, IPin
**ppPin
);
82 HRESULT STDMETHODCALLTYPE
QueryFilterInfo(FILTER_INFO
*pInfo
);
83 HRESULT STDMETHODCALLTYPE
JoinFilterGraph(IFilterGraph
*pGraph
, LPCWSTR pName
);
84 HRESULT STDMETHODCALLTYPE
QueryVendorInfo(LPWSTR
*pVendorInfo
);
87 HRESULT STDMETHODCALLTYPE
GetTime(REFERENCE_TIME
*pTime
);
88 HRESULT STDMETHODCALLTYPE
AdviseTime(REFERENCE_TIME baseTime
, REFERENCE_TIME streamTime
, HEVENT hEvent
, DWORD_PTR
*pdwAdviseCookie
);
89 HRESULT STDMETHODCALLTYPE
AdvisePeriodic(REFERENCE_TIME startTime
, REFERENCE_TIME periodTime
, HSEMAPHORE hSemaphore
, DWORD_PTR
*pdwAdviseCookie
);
90 HRESULT STDMETHODCALLTYPE
Unadvise(DWORD_PTR dwAdviseCookie
);
93 HRESULT STDMETHODCALLTYPE
GetCapabilities(DWORD
*pCapabilities
);
94 HRESULT STDMETHODCALLTYPE
CheckCapabilities(DWORD
*pCapabilities
);
95 HRESULT STDMETHODCALLTYPE
IsFormatSupported(const GUID
*pFormat
);
96 HRESULT STDMETHODCALLTYPE
QueryPreferredFormat(GUID
*pFormat
);
97 HRESULT STDMETHODCALLTYPE
GetTimeFormat(GUID
*pFormat
);
98 HRESULT STDMETHODCALLTYPE
IsUsingTimeFormat(const GUID
*pFormat
);
99 HRESULT STDMETHODCALLTYPE
SetTimeFormat(const GUID
*pFormat
);
100 HRESULT STDMETHODCALLTYPE
GetDuration(LONGLONG
*pDuration
);
101 HRESULT STDMETHODCALLTYPE
GetStopPosition(LONGLONG
*pStop
);
102 HRESULT STDMETHODCALLTYPE
GetCurrentPosition(LONGLONG
*pCurrent
);
103 HRESULT STDMETHODCALLTYPE
ConvertTimeFormat(LONGLONG
*pTarget
, const GUID
*pTargetFormat
, LONGLONG Source
, const GUID
*pSourceFormat
);
104 HRESULT STDMETHODCALLTYPE
SetPositions(LONGLONG
*pCurrent
, DWORD dwCurrentFlags
, LONGLONG
*pStop
, DWORD dwStopFlags
);
105 HRESULT STDMETHODCALLTYPE
GetPositions(LONGLONG
*pCurrent
, LONGLONG
*pStop
);
106 HRESULT STDMETHODCALLTYPE
GetAvailable(LONGLONG
*pEarliest
, LONGLONG
*pLatest
);
107 HRESULT STDMETHODCALLTYPE
SetRate(double dRate
);
108 HRESULT STDMETHODCALLTYPE
GetRate(double *pdRate
);
109 HRESULT STDMETHODCALLTYPE
GetPreroll(LONGLONG
*pllPreroll
);
112 HRESULT STDMETHODCALLTYPE
Set(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
);
113 HRESULT STDMETHODCALLTYPE
Get(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
, DWORD
*pcbReturned
);
114 HRESULT STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet
, DWORD dwPropID
, DWORD
*pTypeSupport
);
117 ULONG STDMETHODCALLTYPE
GetMiscFlags( void);
120 HRESULT STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
, ULONG DataLength
, ULONG
* BytesReturned
);
121 HRESULT STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
, ULONG DataLength
, ULONG
* BytesReturned
);
122 HRESULT STDMETHODCALLTYPE
KsEvent(PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
, ULONG DataLength
, ULONG
* BytesReturned
);
125 HRESULT STDMETHODCALLTYPE
CreateNodeInstance(ULONG NodeId
, ULONG Flags
, ACCESS_MASK DesiredAccess
, IUnknown
* UnkOuter
, REFGUID InterfaceId
, LPVOID
* Interface
);
127 //IKsAggregateControl
128 HRESULT STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass
);
129 HRESULT STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass
);
131 //IKsClockPropertySet
132 HRESULT STDMETHODCALLTYPE
KsGetTime(LONGLONG
* Time
);
133 HRESULT STDMETHODCALLTYPE
KsSetTime(LONGLONG Time
);
134 HRESULT STDMETHODCALLTYPE
KsGetPhysicalTime(LONGLONG
* Time
);
135 HRESULT STDMETHODCALLTYPE
KsSetPhysicalTime(LONGLONG Time
);
136 HRESULT STDMETHODCALLTYPE
KsGetCorrelatedTime(KSCORRELATED_TIME
* CorrelatedTime
);
137 HRESULT STDMETHODCALLTYPE
KsSetCorrelatedTime(KSCORRELATED_TIME
* CorrelatedTime
);
138 HRESULT STDMETHODCALLTYPE
KsGetCorrelatedPhysicalTime(KSCORRELATED_TIME
* CorrelatedTime
);
139 HRESULT STDMETHODCALLTYPE
KsSetCorrelatedPhysicalTime(KSCORRELATED_TIME
* CorrelatedTime
);
140 HRESULT STDMETHODCALLTYPE
KsGetResolution(KSRESOLUTION
* Resolution
);
141 HRESULT STDMETHODCALLTYPE
KsGetState(KSSTATE
* State
);
144 //IAMovieSetup methods
145 HRESULT STDMETHODCALLTYPE
Register( void);
146 HRESULT STDMETHODCALLTYPE
Unregister( void);
148 // IPersistPropertyBag methods
149 HRESULT STDMETHODCALLTYPE
InitNew( void);
150 HRESULT STDMETHODCALLTYPE
Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
);
151 HRESULT STDMETHODCALLTYPE
Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
);
154 HANDLE STDMETHODCALLTYPE
KsGetObjectHandle();
157 HANDLE STDMETHODCALLTYPE
KsGetClockHandle();
160 HRESULT STDMETHODCALLTYPE
DeviceInfo(CLSID
*pclsidInterfaceClass
, LPWSTR
*pwszSymbolicLink
);
161 HRESULT STDMETHODCALLTYPE
Reassociate(void);
162 HRESULT STDMETHODCALLTYPE
Disassociate( void);
165 HRESULT STDMETHODCALLTYPE
IsDirty( void);
166 HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
167 HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
168 HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
170 // ISpecifyPropertyPages
171 HRESULT STDMETHODCALLTYPE
GetPages(CAUUID
*pPages
);
178 CloseHandle(m_hDevice
);
181 HRESULT STDMETHODCALLTYPE
GetSupportedSets(LPGUID
* pOutGuid
, PULONG NumGuids
);
182 HRESULT STDMETHODCALLTYPE
LoadProxyPlugins(LPGUID pGuids
, ULONG NumGuids
);
183 HRESULT STDMETHODCALLTYPE
GetNumberOfPins(PULONG NumPins
);
184 HRESULT STDMETHODCALLTYPE
GetPinInstanceCount(ULONG PinId
, PKSPIN_CINSTANCES Instances
);
185 HRESULT STDMETHODCALLTYPE
GetPinDataflow(ULONG PinId
, KSPIN_DATAFLOW
* DataFlow
);
186 HRESULT STDMETHODCALLTYPE
GetPinName(ULONG PinId
, KSPIN_DATAFLOW DataFlow
, ULONG PinCount
, LPWSTR
* OutPinName
);
187 HRESULT STDMETHODCALLTYPE
GetPinCommunication(ULONG PinId
, KSPIN_COMMUNICATION
* Communication
);
188 HRESULT STDMETHODCALLTYPE
CreatePins();
189 HRESULT STDMETHODCALLTYPE
GetMediaSeekingFormats(PKSMULTIPLE_ITEM
*FormatList
);
190 HRESULT STDMETHODCALLTYPE
CreateClockInstance();
191 HRESULT STDMETHODCALLTYPE
PerformClockProperty(ULONG PropertyId
, ULONG PropertyFlags
, PVOID OutputBuffer
, ULONG OutputBufferSize
);
192 HRESULT STDMETHODCALLTYPE
SetPinState(KSSTATE State
);
197 IFilterGraph
*m_pGraph
;
198 IReferenceClock
* m_ReferenceClock
;
199 FILTER_STATE m_FilterState
;
201 ProxyPluginVector m_Plugins
;
204 CLSID m_DeviceInterfaceGUID
;
206 CRITICAL_SECTION m_Lock
;
209 CKsProxy::CKsProxy() : m_Ref(0),
211 m_ReferenceClock((IReferenceClock
*)this),
212 m_FilterState(State_Stopped
),
219 InitializeCriticalSection(&m_Lock
);
225 CKsProxy::QueryInterface(
231 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
232 IsEqualGUID(refiid
, IID_IBaseFilter
))
234 *Output
= PVOID(this);
235 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
238 else if (IsEqualGUID(refiid
, IID_IPersistPropertyBag
))
240 *Output
= (IPersistPropertyBag
*)(this);
241 reinterpret_cast<IPersistPropertyBag
*>(*Output
)->AddRef();
244 else if (IsEqualGUID(refiid
, IID_IAMDeviceRemoval
))
246 *Output
= (IAMDeviceRemoval
*)(this);
247 reinterpret_cast<IAMDeviceRemoval
*>(*Output
)->AddRef();
250 else if (IsEqualGUID(refiid
, IID_IPersistStream
))
252 *Output
= (IPersistStream
*)(this);
253 reinterpret_cast<IPersistStream
*>(*Output
)->AddRef();
256 else if (IsEqualGUID(refiid
, IID_IPersist
))
258 *Output
= (IPersistStream
*)(this);
259 reinterpret_cast<IPersist
*>(*Output
)->AddRef();
262 else if (IsEqualGUID(refiid
, IID_IKsObject
))
264 *Output
= (IKsObject
*)(this);
265 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
268 else if (IsEqualGUID(refiid
, IID_IKsClock
))
270 *Output
= (IKsClock
*)(this);
271 reinterpret_cast<IKsClock
*>(*Output
)->AddRef();
274 else if (IsEqualGUID(refiid
, IID_IReferenceClock
))
278 HRESULT hr
= CreateClockInstance();
283 *Output
= (IReferenceClock
*)(this);
284 reinterpret_cast<IReferenceClock
*>(*Output
)->AddRef();
287 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
289 *Output
= (IMediaSeeking
*)(this);
290 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
293 else if (IsEqualGUID(refiid
, IID_IAMFilterMiscFlags
))
295 *Output
= (IAMFilterMiscFlags
*)(this);
296 reinterpret_cast<IAMFilterMiscFlags
*>(*Output
)->AddRef();
299 else if (IsEqualGUID(refiid
, IID_IKsControl
))
301 *Output
= (IKsControl
*)(this);
302 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
305 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
307 *Output
= (IKsPropertySet
*)(this);
308 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
311 else if (IsEqualGUID(refiid
, IID_IKsTopology
))
313 *Output
= (IKsTopology
*)(this);
314 reinterpret_cast<IKsTopology
*>(*Output
)->AddRef();
317 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
319 *Output
= (IKsAggregateControl
*)(this);
320 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
323 else if (IsEqualGUID(refiid
, IID_IKsClockPropertySet
))
327 HRESULT hr
= CreateClockInstance();
332 *Output
= (IKsClockPropertySet
*)(this);
333 reinterpret_cast<IKsClockPropertySet
*>(*Output
)->AddRef();
336 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
338 *Output
= (ISpecifyPropertyPages
*)(this);
339 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
343 for(ULONG Index
= 0; Index
< m_Plugins
.size(); Index
++)
347 HRESULT hr
= m_Plugins
[Index
]->QueryInterface(refiid
, Output
);
353 StringFromCLSID(refiid
, &lpstr
);
354 swprintf(Buffer
, L
"CKsProxy::QueryInterface plugin %lu supports interface %s\n", Index
, lpstr
);
355 OutputDebugStringW(Buffer
);
356 CoTaskMemFree(lpstr
);
363 WCHAR Buffer
[MAX_PATH
];
365 StringFromCLSID(refiid
, &lpstr
);
366 swprintf(Buffer
, L
"CKsProxy::QueryInterface: NoInterface for %s !!!\n", lpstr
);
367 OutputDebugStringW(Buffer
);
368 CoTaskMemFree(lpstr
);
371 return E_NOINTERFACE
;
374 //-------------------------------------------------------------------
375 // ISpecifyPropertyPages
380 CKsProxy::GetPages(CAUUID
*pPages
)
383 OutputDebugStringW(L
"CKsProxy::GetPages NotImplemented\n");
390 pPages
->pElems
= NULL
;
395 //-------------------------------------------------------------------
396 // IKsClockPropertySet interface
401 CKsProxy::CreateClockInstance()
404 HANDLE hPin
= INVALID_HANDLE_VALUE
;
406 PIN_DIRECTION PinDir
;
408 KSCLOCK_CREATE ClockCreate
;
410 // find output pin and handle
411 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
414 IPin
* pin
= m_Pins
[Index
];
419 hr
= pin
->QueryDirection(&PinDir
);
423 // query IKsObject interface
424 hr
= pin
->QueryInterface(IID_IKsObject
, (void**)&pObject
);
430 hPin
= pObject
->KsGetObjectHandle();
435 if (hPin
!= INVALID_HANDLE_VALUE
)
439 if (hPin
== INVALID_HANDLE_VALUE
)
441 // clock can only be instantiated on a pin handle
447 // release clock handle
448 CloseHandle(m_hClock
);
451 //setup clock create request
452 ClockCreate
.CreateFlags
= 0;
454 // setup clock create request
455 hr
= KsCreateClock(hPin
, &ClockCreate
, &m_hClock
); // FIXME KsCreateClock returns NTSTATUS
458 // failed to create clock
459 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
467 CKsProxy::PerformClockProperty(
471 ULONG OutputBufferSize
)
480 hr
= CreateClockInstance();
486 Property
.Set
= KSPROPSETID_Clock
;
487 Property
.Id
= PropertyId
;
488 Property
.Flags
= PropertyFlags
;
490 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)OutputBuffer
, OutputBufferSize
, &BytesReturned
);
501 OutputDebugStringW(L
"CKsProxy::KsGetTime\n");
504 return PerformClockProperty(KSPROPERTY_CLOCK_TIME
, KSPROPERTY_TYPE_GET
, (PVOID
)Time
, sizeof(LONGLONG
));
513 OutputDebugStringW(L
"CKsProxy::KsSetTime\n");
516 return PerformClockProperty(KSPROPERTY_CLOCK_TIME
, KSPROPERTY_TYPE_SET
, (PVOID
)&Time
, sizeof(LONGLONG
));
521 CKsProxy::KsGetPhysicalTime(
525 OutputDebugStringW(L
"CKsProxy::KsGetPhysicalTime\n");
528 return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)Time
, sizeof(LONGLONG
));
533 CKsProxy::KsSetPhysicalTime(
537 OutputDebugStringW(L
"CKsProxy::KsSetPhysicalTime\n");
540 return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)&Time
, sizeof(LONGLONG
));
545 CKsProxy::KsGetCorrelatedTime(
546 KSCORRELATED_TIME
* CorrelatedTime
)
549 OutputDebugStringW(L
"CKsProxy::KsGetCorrelatedTime\n");
552 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
557 CKsProxy::KsSetCorrelatedTime(
558 KSCORRELATED_TIME
* CorrelatedTime
)
561 OutputDebugStringW(L
"CKsProxy::KsSetCorrelatedTime\n");
563 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
568 CKsProxy::KsGetCorrelatedPhysicalTime(
569 KSCORRELATED_TIME
* CorrelatedTime
)
572 OutputDebugStringW(L
"CKsProxy::KsGetCorrelatedPhysicalTime\n");
574 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
579 CKsProxy::KsSetCorrelatedPhysicalTime(
580 KSCORRELATED_TIME
* CorrelatedTime
)
583 OutputDebugStringW(L
"CKsProxy::KsSetCorrelatedPhysicalTime\n");
586 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
591 CKsProxy::KsGetResolution(
592 KSRESOLUTION
* Resolution
)
595 OutputDebugStringW(L
"CKsProxy::KsGetResolution\n");
597 return PerformClockProperty(KSPROPERTY_CLOCK_RESOLUTION
, KSPROPERTY_TYPE_GET
, (PVOID
)Resolution
, sizeof(KSRESOLUTION
));
602 CKsProxy::KsGetState(
606 OutputDebugStringW(L
"CKsProxy::KsGetState\n");
608 return PerformClockProperty(KSPROPERTY_CLOCK_STATE
, KSPROPERTY_TYPE_GET
, (PVOID
)State
, sizeof(KSSTATE
));
611 //-------------------------------------------------------------------
612 // IReferenceClock interface
617 REFERENCE_TIME
*pTime
)
624 OutputDebugStringW(L
"CKsProxy::GetTime\n");
637 hr
= CreateClockInstance();
643 Property
.Set
= KSPROPSETID_Clock
;
644 Property
.Id
= KSPROPERTY_CLOCK_TIME
;
645 Property
.Flags
= KSPROPERTY_TYPE_GET
;
648 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pTime
, sizeof(REFERENCE_TIME
), &BytesReturned
);
659 CKsProxy::AdviseTime(
660 REFERENCE_TIME baseTime
,
661 REFERENCE_TIME streamTime
,
663 DWORD_PTR
*pdwAdviseCookie
)
668 PKSEVENT_TIME_MARK Event
;
671 OutputDebugStringW(L
"CKsProxy::AdviseTime\n");
678 if (!pdwAdviseCookie
)
684 hr
= CreateClockInstance();
689 // allocate event entry
690 Event
= (PKSEVENT_TIME_MARK
)CoTaskMemAlloc(sizeof(KSEVENT_TIME_MARK
));
694 Property
.Set
= KSEVENTSETID_Clock
;
695 Property
.Id
= KSEVENT_CLOCK_POSITION_MARK
;
696 Property
.Flags
= KSEVENT_TYPE_ENABLE
;
698 Event
->EventData
.NotificationType
= KSEVENTF_EVENT_HANDLE
;
699 Event
->EventData
.EventHandle
.Event
= (HANDLE
)hEvent
;
700 Event
->EventData
.Alignment
.Alignment
[0] = 0;
701 Event
->EventData
.Alignment
.Alignment
[1] = 0;
702 Event
->MarkTime
= baseTime
+ streamTime
;
705 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSEVENT
), (PVOID
)Event
, sizeof(KSEVENT_TIME_MARK
), &BytesReturned
);
708 // store event handle
709 *pdwAdviseCookie
= (DWORD_PTR
)Event
;
713 // failed to enable event
714 CoTaskMemFree(Event
);
727 CKsProxy::AdvisePeriodic(
728 REFERENCE_TIME startTime
,
729 REFERENCE_TIME periodTime
,
730 HSEMAPHORE hSemaphore
,
731 DWORD_PTR
*pdwAdviseCookie
)
736 PKSEVENT_TIME_INTERVAL Event
;
739 OutputDebugStringW(L
"CKsProxy::AdvisePeriodic\n");
746 if (!pdwAdviseCookie
)
752 hr
= CreateClockInstance();
757 // allocate event entry
758 Event
= (PKSEVENT_TIME_INTERVAL
)CoTaskMemAlloc(sizeof(KSEVENT_TIME_INTERVAL
));
762 Property
.Set
= KSEVENTSETID_Clock
;
763 Property
.Id
= KSEVENT_CLOCK_INTERVAL_MARK
;
764 Property
.Flags
= KSEVENT_TYPE_ENABLE
;
766 Event
->EventData
.NotificationType
= KSEVENTF_SEMAPHORE_HANDLE
;
767 Event
->EventData
.SemaphoreHandle
.Semaphore
= (HANDLE
)hSemaphore
;
768 Event
->EventData
.SemaphoreHandle
.Reserved
= 0;
769 Event
->EventData
.SemaphoreHandle
.Adjustment
= 1;
770 Event
->TimeBase
= startTime
;
771 Event
->Interval
= periodTime
;
774 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSEVENT
), (PVOID
)Event
, sizeof(KSEVENT_TIME_INTERVAL
), &BytesReturned
);
777 // store event handle
778 *pdwAdviseCookie
= (DWORD_PTR
)Event
;
782 // failed to enable event
783 CoTaskMemFree(Event
);
797 DWORD_PTR dwAdviseCookie
)
803 OutputDebugStringW(L
"CKsProxy::Unadvise\n");
808 //lets disable the event
809 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)dwAdviseCookie
, sizeof(KSEVENTDATA
), 0, 0, &BytesReturned
);
812 // lets free event data
813 CoTaskMemFree((LPVOID
)dwAdviseCookie
);
818 // no clock available
825 //-------------------------------------------------------------------
826 // IMediaSeeking interface
830 CKsProxy::GetCapabilities(
831 DWORD
*pCapabilities
)
834 ULONG BytesReturned
, Index
;
838 Property
.Set
= KSPROPSETID_MediaSeeking
;
839 Property
.Id
= KSPROPERTY_MEDIASEEKING_CAPABILITIES
;
840 Property
.Flags
= KSPROPERTY_TYPE_GET
;
843 OutputDebugStringW(L
"CKsProxy::GetCapabilities\n");
851 *pCapabilities
= (KS_SEEKING_CanSeekAbsolute
| KS_SEEKING_CanSeekForwards
| KS_SEEKING_CanSeekBackwards
| KS_SEEKING_CanGetCurrentPos
|
852 KS_SEEKING_CanGetStopPos
| KS_SEEKING_CanGetDuration
| KS_SEEKING_CanPlayBackwards
);
854 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pCapabilities
, sizeof(KS_SEEKING_CAPABILITIES
), &BytesReturned
);
855 // check if plugins support it
856 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
859 IUnknown
* Plugin
= m_Plugins
[Index
];
864 // query for IMediaSeeking interface
865 IMediaSeeking
*pSeek
= NULL
;
866 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
875 hr
= pSeek
->GetCapabilities(&TempCaps
);
878 // and with supported flags
879 *pCapabilities
= (*pCapabilities
& TempCaps
);
881 // release IMediaSeeking interface
889 CKsProxy::CheckCapabilities(
890 DWORD
*pCapabilities
)
896 OutputDebugStringW(L
"CKsProxy::CheckCapabilities\n");
905 hr
= GetCapabilities(&Capabilities
);
908 if ((Capabilities
| *pCapabilities
) == Capabilities
)
914 Capabilities
= (Capabilities
& *pCapabilities
);
918 *pCapabilities
= Capabilities
;
921 // no capabilities are present
930 CKsProxy::GetMediaSeekingFormats(
931 PKSMULTIPLE_ITEM
*FormatList
)
937 Property
.Set
= KSPROPSETID_MediaSeeking
;
938 Property
.Id
= KSPROPERTY_MEDIASEEKING_FORMATS
;
939 Property
.Flags
= KSPROPERTY_TYPE_GET
;
941 // query for format size list
942 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &BytesReturned
);
944 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
946 // allocate format list
947 *FormatList
= (PKSMULTIPLE_ITEM
)CoTaskMemAlloc(BytesReturned
);
951 return E_OUTOFMEMORY
;
955 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)*FormatList
, BytesReturned
, &BytesReturned
);
958 // failed to query format list
959 CoTaskMemFree(FormatList
);
967 CKsProxy::IsFormatSupported(
970 PKSMULTIPLE_ITEM FormatList
;
973 HRESULT hr
= S_FALSE
;
978 StringFromCLSID(*pFormat
, &pstr
);
979 swprintf(Buffer
, L
"CKsProxy::IsFormatSupported %s\n",pstr
);
980 OutputDebugStringW(Buffer
);
987 hr
= GetMediaSeekingFormats(&FormatList
);
991 swprintf(Buffer
, L
"CKsProxy::IsFormatSupported NumFormat %lu\n",FormatList
->Count
);
992 OutputDebugStringW(Buffer
);
995 //iterate through format list
996 pGuid
= (LPGUID
)(FormatList
+ 1);
997 for(Index
= 0; Index
< FormatList
->Count
; Index
++)
999 if (IsEqualGUID(*pGuid
, *pFormat
))
1001 CoTaskMemFree(FormatList
);
1007 CoTaskMemFree(FormatList
);
1010 // check if all plugins support it
1011 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1014 IUnknown
* Plugin
= m_Plugins
[Index
];
1019 // query for IMediaSeeking interface
1020 IMediaSeeking
*pSeek
= NULL
;
1021 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1024 // plugin does not support interface
1026 #ifdef KSPROXY_TRACE
1027 OutputDebugStringW(L
"CKsProxy::IsFormatSupported plugin does not support IMediaSeeking interface\n");
1032 // query if it is supported
1033 hr
= pSeek
->IsFormatSupported(pFormat
);
1034 // release interface
1037 if (FAILED(hr
) || hr
== S_FALSE
)
1046 CKsProxy::QueryPreferredFormat(
1049 PKSMULTIPLE_ITEM FormatList
;
1053 #ifdef KSPROXY_TRACE
1054 OutputDebugStringW(L
"CKsProxy::QueryPreferredFormat\n");
1060 hr
= GetMediaSeekingFormats(&FormatList
);
1063 if (FormatList
->Count
)
1065 CopyMemory(pFormat
, (FormatList
+ 1), sizeof(GUID
));
1066 CoTaskMemFree(FormatList
);
1069 CoTaskMemFree(FormatList
);
1071 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1073 // check if plugins support it
1074 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1077 IUnknown
* Plugin
= m_Plugins
[Index
];
1082 // query for IMediaSeeking interface
1083 IMediaSeeking
*pSeek
= NULL
;
1084 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1087 // get preferred time format
1088 hr
= pSeek
->QueryPreferredFormat(pFormat
);
1089 // release IMediaSeeking interface
1104 CKsProxy::GetTimeFormat(
1107 KSPROPERTY Property
;
1108 ULONG BytesReturned
, Index
;
1111 Property
.Set
= KSPROPSETID_MediaSeeking
;
1112 Property
.Id
= KSPROPERTY_MEDIASEEKING_TIMEFORMAT
;
1113 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1115 #ifdef KSPROXY_TRACE
1116 OutputDebugStringW(L
"CKsProxy::GetTimeFormat\n");
1119 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pFormat
, sizeof(GUID
), &BytesReturned
);
1120 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1122 // check if plugins support it
1123 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1127 IUnknown
* Plugin
= m_Plugins
[Index
];
1132 // query for IMediaSeeking interface
1133 IMediaSeeking
*pSeek
= NULL
;
1134 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1138 hr
= pSeek
->GetTimeFormat(pFormat
);
1139 // release IMediaSeeking interface
1152 CKsProxy::IsUsingTimeFormat(
1153 const GUID
*pFormat
)
1157 #ifdef KSPROXY_TRACE
1158 OutputDebugStringW(L
"CKsProxy::IsUsingTimeFormat\n");
1161 if (FAILED(QueryPreferredFormat(&Format
)))
1164 if (IsEqualGUID(Format
, *pFormat
))
1172 CKsProxy::SetTimeFormat(
1173 const GUID
*pFormat
)
1175 KSPROPERTY Property
;
1176 ULONG BytesReturned
, Index
;
1179 Property
.Set
= KSPROPSETID_MediaSeeking
;
1180 Property
.Id
= KSPROPERTY_MEDIASEEKING_TIMEFORMAT
;
1181 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1183 #ifdef KSPROXY_TRACE
1184 OutputDebugStringW(L
"CKsProxy::SetTimeFormat\n");
1187 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pFormat
, sizeof(GUID
), &BytesReturned
);
1188 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1190 // check if plugins support it
1191 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1195 IUnknown
* Plugin
= m_Plugins
[Index
];
1200 // query for IMediaSeeking interface
1201 IMediaSeeking
*pSeek
= NULL
;
1202 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1209 hr
= pSeek
->SetTimeFormat(pFormat
);
1210 // release IMediaSeeking interface
1222 CKsProxy::GetDuration(
1223 LONGLONG
*pDuration
)
1225 KSPROPERTY Property
;
1226 ULONG BytesReturned
, Index
;
1229 Property
.Set
= KSPROPSETID_MediaSeeking
;
1230 Property
.Id
= KSPROPERTY_MEDIASEEKING_DURATION
;
1231 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1233 #ifdef KSPROXY_TRACE
1234 OutputDebugStringW(L
"CKsProxy::GetDuration\n");
1237 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pDuration
, sizeof(LONGLONG
), &BytesReturned
);
1238 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1240 // check if plugins support it
1241 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1245 IUnknown
* Plugin
= m_Plugins
[Index
];
1250 // query for IMediaSeeking interface
1251 IMediaSeeking
*pSeek
= NULL
;
1252 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1256 hr
= pSeek
->GetStopPosition(pDuration
);
1257 // release IMediaSeeking interface
1260 if (hr
!= S_FALSE
) // plugin implements it
1270 CKsProxy::GetStopPosition(
1273 KSPROPERTY Property
;
1274 ULONG BytesReturned
, Index
;
1277 Property
.Set
= KSPROPSETID_MediaSeeking
;
1278 Property
.Id
= KSPROPERTY_MEDIASEEKING_STOPPOSITION
;
1279 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1281 #ifdef KSPROXY_TRACE
1282 OutputDebugStringW(L
"CKsProxy::GetStopPosition\n");
1285 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pStop
, sizeof(LONGLONG
), &BytesReturned
);
1286 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1288 // check if plugins support it
1289 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1293 IUnknown
* Plugin
= m_Plugins
[Index
];
1298 // query for IMediaSeeking interface
1299 IMediaSeeking
*pSeek
= NULL
;
1300 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1303 // get stop position
1304 hr
= pSeek
->GetStopPosition(pStop
);
1305 // release IMediaSeeking interface
1308 if (hr
!= S_FALSE
) // plugin implements it
1318 CKsProxy::GetCurrentPosition(
1321 KSPROPERTY Property
;
1322 ULONG BytesReturned
, Index
;
1325 Property
.Set
= KSPROPSETID_MediaSeeking
;
1326 Property
.Id
= KSPROPERTY_MEDIASEEKING_POSITION
;
1327 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1329 #ifdef KSPROXY_TRACE
1330 OutputDebugStringW(L
"CKsProxy::GetCurrentPosition\n");
1333 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pCurrent
, sizeof(LONGLONG
), &BytesReturned
);
1334 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1336 // check if plugins support it
1337 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1341 IUnknown
* Plugin
= m_Plugins
[Index
];
1346 // query for IMediaSeeking interface
1347 IMediaSeeking
*pSeek
= NULL
;
1348 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1351 // get current position
1352 hr
= pSeek
->GetCurrentPosition(pCurrent
);
1353 // release IMediaSeeking interface
1356 if (hr
!= S_FALSE
) // plugin implements it
1366 CKsProxy::ConvertTimeFormat(
1368 const GUID
*pTargetFormat
,
1370 const GUID
*pSourceFormat
)
1372 KSP_TIMEFORMAT Property
;
1373 ULONG BytesReturned
, Index
;
1374 GUID SourceFormat
, TargetFormat
;
1377 Property
.Property
.Set
= KSPROPSETID_MediaSeeking
;
1378 Property
.Property
.Id
= KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT
;
1379 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
1381 #ifdef KSPROXY_TRACE
1382 OutputDebugStringW(L
"CKsProxy::ConvertTimeFormat\n");
1387 // get current format
1388 hr
= GetTimeFormat(&TargetFormat
);
1392 pTargetFormat
= &TargetFormat
;
1397 // get current format
1398 hr
= GetTimeFormat(&SourceFormat
);
1402 pSourceFormat
= &SourceFormat
;
1405 Property
.SourceFormat
= *pSourceFormat
;
1406 Property
.TargetFormat
= *pTargetFormat
;
1407 Property
.Time
= Source
;
1410 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_TIMEFORMAT
), (PVOID
)pTarget
, sizeof(LONGLONG
), &BytesReturned
);
1411 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1416 // check if plugins support it
1417 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1420 IUnknown
* Plugin
= m_Plugins
[Index
];
1425 // query for IMediaSeeking interface
1426 IMediaSeeking
*pSeek
= NULL
;
1427 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1430 // convert time format
1431 hr
= pSeek
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
1432 // release IMediaSeeking interface
1435 if (hr
!= S_FALSE
) // plugin implements it
1446 CKsProxy::SetPositions(
1448 DWORD dwCurrentFlags
,
1452 KSPROPERTY Property
;
1453 KSPROPERTY_POSITIONS Positions
;
1454 ULONG BytesReturned
, Index
;
1457 Property
.Set
= KSPROPSETID_MediaSeeking
;
1458 Property
.Id
= KSPROPERTY_MEDIASEEKING_POSITIONS
;
1459 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1461 Positions
.Current
= *pCurrent
;
1462 Positions
.CurrentFlags
= (KS_SEEKING_FLAGS
)dwCurrentFlags
;
1463 Positions
.Stop
= *pStop
;
1464 Positions
.StopFlags
= (KS_SEEKING_FLAGS
)dwStopFlags
;
1466 #ifdef KSPROXY_TRACE
1467 OutputDebugStringW(L
"CKsProxy::SetPositions\n");
1470 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Positions
, sizeof(KSPROPERTY_POSITIONS
), &BytesReturned
);
1473 if (dwCurrentFlags
& AM_SEEKING_ReturnTime
)
1475 // retrieve current position
1476 hr
= GetCurrentPosition(pCurrent
);
1481 if (dwStopFlags
& AM_SEEKING_ReturnTime
)
1483 // retrieve current position
1484 hr
= GetStopPosition(pStop
);
1489 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1493 // check if plugins support it
1494 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1497 IUnknown
* Plugin
= m_Plugins
[Index
];
1502 // query for IMediaSeeking interface
1503 IMediaSeeking
*pSeek
= NULL
;
1504 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1508 hr
= pSeek
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
1509 // release IMediaSeeking interface
1523 CKsProxy::GetPositions(
1529 #ifdef KSPROXY_TRACE
1530 OutputDebugStringW(L
"CKsProxy::GetPositions\n");
1533 hr
= GetCurrentPosition(pCurrent
);
1535 hr
= GetStopPosition(pStop
);
1542 CKsProxy::GetAvailable(
1543 LONGLONG
*pEarliest
,
1546 KSPROPERTY Property
;
1547 KSPROPERTY_MEDIAAVAILABLE Media
;
1548 ULONG BytesReturned
, Index
;
1551 Property
.Set
= KSPROPSETID_MediaSeeking
;
1552 Property
.Id
= KSPROPERTY_MEDIASEEKING_AVAILABLE
;
1553 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1555 #ifdef KSPROXY_TRACE
1556 OutputDebugStringW(L
"CKsProxy::GetAvailable\n");
1559 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Media
, sizeof(KSPROPERTY_MEDIAAVAILABLE
), &BytesReturned
);
1560 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1562 // check if plugins support it
1563 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1567 IUnknown
* Plugin
= m_Plugins
[Index
];
1572 // query for IMediaSeeking interface
1573 IMediaSeeking
*pSeek
= NULL
;
1574 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1578 hr
= pSeek
->GetAvailable(pEarliest
, pLatest
);
1579 // release IMediaSeeking interface
1582 if (hr
!= S_FALSE
) // plugin implements it
1587 else if (SUCCEEDED(hr
))
1589 *pEarliest
= Media
.Earliest
;
1590 *pLatest
= Media
.Latest
;
1601 #ifdef KSPROXY_TRACE
1602 OutputDebugStringW(L
"CKsProxy::SetRate\n");
1612 #ifdef KSPROXY_TRACE
1613 OutputDebugStringW(L
"CKsProxy::GetRate\n");
1620 CKsProxy::GetPreroll(
1621 LONGLONG
*pllPreroll
)
1623 KSPROPERTY Property
;
1624 ULONG BytesReturned
, Index
;
1627 Property
.Set
= KSPROPSETID_MediaSeeking
;
1628 Property
.Id
= KSPROPERTY_MEDIASEEKING_PREROLL
;
1629 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1631 #ifdef KSPROXY_TRACE
1632 OutputDebugStringW(L
"CKsProxy::GetPreroll\n");
1635 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pllPreroll
, sizeof(LONGLONG
), &BytesReturned
);
1636 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1638 // check if all plugins support it
1639 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1642 IUnknown
* Plugin
= m_Plugins
[Index
];
1647 // query for IMediaSeeking interface
1648 IMediaSeeking
*pSeek
= NULL
;
1649 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1653 hr
= pSeek
->GetPreroll(pllPreroll
);
1654 // release IMediaSeeking interface
1657 if (hr
!= S_FALSE
) // plugin implements it
1666 //-------------------------------------------------------------------
1667 // IAMFilterMiscFlags interface
1672 CKsProxy::GetMiscFlags()
1677 PIN_DIRECTION PinDirection
;
1678 KSPIN_COMMUNICATION Communication
;
1681 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
1684 IPin
* pin
= m_Pins
[Index
];
1686 hr
= pin
->QueryDirection(&PinDirection
);
1689 if (PinDirection
== PINDIR_INPUT
)
1691 if (SUCCEEDED(GetPinCommunication(Index
, //FIXME verify PinId
1694 if (Communication
!= KSPIN_COMMUNICATION_NONE
&& Communication
!= KSPIN_COMMUNICATION_BRIDGE
)
1696 Flags
|= AM_FILTER_MISC_FLAGS_IS_SOURCE
;
1703 #ifdef KSPROXY_TRACE
1705 swprintf(Buffer
, L
"CKsProxy::GetMiscFlags stub Flags %x\n", Flags
);
1706 OutputDebugStringW(Buffer
);
1712 //-------------------------------------------------------------------
1717 CKsProxy::KsProperty(
1718 PKSPROPERTY Property
,
1719 ULONG PropertyLength
,
1720 LPVOID PropertyData
,
1722 ULONG
* BytesReturned
)
1724 #ifdef KSPROXY_TRACE
1725 OutputDebugStringW(L
"CKsProxy::KsProperty\n");
1728 assert(m_hDevice
!= 0);
1729 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1739 ULONG
* BytesReturned
)
1741 #ifdef KSPROXY_TRACE
1742 OutputDebugStringW(L
"CKsProxy::KsMethod\n");
1745 assert(m_hDevice
!= 0);
1746 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1756 ULONG
* BytesReturned
)
1758 #ifdef KSPROXY_TRACE
1759 OutputDebugStringW(L
"CKsProxy::KsEvent\n");
1762 assert(m_hDevice
!= 0);
1764 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1766 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1770 //-------------------------------------------------------------------
1776 REFGUID guidPropSet
,
1778 LPVOID pInstanceData
,
1779 DWORD cbInstanceData
,
1783 ULONG BytesReturned
;
1785 #ifdef KSPROXY_TRACE
1786 OutputDebugStringW(L
"CKsProxy::Set\n");
1791 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1793 return E_OUTOFMEMORY
;
1795 Property
->Set
= guidPropSet
;
1796 Property
->Id
= dwPropID
;
1797 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1799 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1801 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1802 CoTaskMemFree(Property
);
1807 KSPROPERTY Property
;
1809 Property
.Set
= guidPropSet
;
1810 Property
.Id
= dwPropID
;
1811 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1813 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1821 REFGUID guidPropSet
,
1823 LPVOID pInstanceData
,
1824 DWORD cbInstanceData
,
1829 ULONG BytesReturned
;
1831 #ifdef KSPROXY_TRACE
1832 OutputDebugStringW(L
"CKsProxy::Get\n");
1837 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1839 return E_OUTOFMEMORY
;
1841 Property
->Set
= guidPropSet
;
1842 Property
->Id
= dwPropID
;
1843 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1845 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1847 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1848 CoTaskMemFree(Property
);
1853 KSPROPERTY Property
;
1855 Property
.Set
= guidPropSet
;
1856 Property
.Id
= dwPropID
;
1857 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1859 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1866 CKsProxy::QuerySupported(
1867 REFGUID guidPropSet
,
1869 DWORD
*pTypeSupport
)
1871 KSPROPERTY Property
;
1872 ULONG BytesReturned
;
1874 #ifdef KSPROXY_TRACE
1875 OutputDebugStringW(L
"CKsProxy::QuerySupported\n");
1878 Property
.Set
= guidPropSet
;
1879 Property
.Id
= dwPropID
;
1880 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1882 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1886 //-------------------------------------------------------------------
1887 // IKsTopology interface
1891 CKsProxy::CreateNodeInstance(
1894 ACCESS_MASK DesiredAccess
,
1896 REFGUID InterfaceId
,
1901 #ifdef KSPROXY_TRACE
1902 OutputDebugStringW(L
"CKsProxy::CreateNodeInstance\n");
1907 if (IsEqualIID(IID_IUnknown
, InterfaceId
) || !UnkOuter
)
1909 hr
= CKsNode_Constructor(UnkOuter
, m_hDevice
, NodeId
, DesiredAccess
, InterfaceId
, Interface
);
1913 // interface not supported
1920 //-------------------------------------------------------------------
1921 // IKsAggregateControl interface
1925 CKsProxy::KsAddAggregate(
1926 IN REFGUID AggregateClass
)
1928 #ifdef KSPROXY_TRACE
1929 OutputDebugStringW(L
"CKsProxy::KsAddAggregate NotImplemented\n");
1936 CKsProxy::KsRemoveAggregate(
1937 REFGUID AggregateClass
)
1939 #ifdef KSPROXY_TRACE
1940 OutputDebugStringW(L
"CKsProxy::KsRemoveAggregate NotImplemented\n");
1947 //-------------------------------------------------------------------
1948 // IPersistStream interface
1955 #ifdef KSPROXY_TRACE
1956 OutputDebugStringW(L
"CKsProxy::IsDirty Notimplemented\n");
1969 AM_MEDIA_TYPE MediaType
;
1970 ULONG BytesReturned
;
1974 LPOLESTR pMajor
, pSub
, pFormat
;
1976 #ifdef KSPROXY_TRACE
1977 OutputDebugStringW(L
"CKsProxy::Load\n");
1981 ULONG Version
= ReadInt(pStm
, hr
);
1986 hr
= pStm
->Read(&Length
, sizeof(ULONG
), &BytesReturned
);
1987 swprintf(Buffer
, L
"Length hr %x hr length %lu\n", hr
, Length
);
1988 OutputDebugStringW(Buffer
);
1992 hr
= pStm
->Read(&PinId
, sizeof(ULONG
), &BytesReturned
);
1993 swprintf(Buffer
, L
"Read: hr %08x PinId %lx BytesReturned %lu\n", hr
, PinId
, BytesReturned
);
1994 OutputDebugStringW(Buffer
);
1996 if (FAILED(hr
) || !BytesReturned
)
1999 Length
-= BytesReturned
;
2001 hr
= pStm
->Read(&MediaType
, sizeof(AM_MEDIA_TYPE
), &BytesReturned
);
2002 if (FAILED(hr
) || BytesReturned
!= sizeof(AM_MEDIA_TYPE
))
2004 swprintf(Buffer
, L
"Read failed with %lx\n", hr
);
2005 OutputDebugStringW(Buffer
);
2010 StringFromIID(MediaType
.majortype
, &pMajor
);
2011 StringFromIID(MediaType
.subtype
, &pSub
);
2012 StringFromIID(MediaType
.formattype
, &pFormat
);
2014 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
);
2015 OutputDebugStringW(Buffer
);
2017 Length
-= BytesReturned
;
2020 if (MediaType
.cbFormat
)
2022 MediaType
.pbFormat
= (BYTE
*)CoTaskMemAlloc(MediaType
.cbFormat
);
2023 if (!MediaType
.pbFormat
)
2024 return E_OUTOFMEMORY
;
2026 hr
= pStm
->Read(&MediaType
.pbFormat
, sizeof(MediaType
.cbFormat
), &BytesReturned
);
2029 swprintf(Buffer
, L
"ReadFormat failed with %lx\n", hr
);
2030 OutputDebugStringW(Buffer
);
2033 Length
-= BytesReturned
;
2048 #ifdef KSPROXY_TRACE
2049 OutputDebugStringW(L
"CKsProxy::Save Notimplemented\n");
2057 CKsProxy::GetSizeMax(
2058 ULARGE_INTEGER
*pcbSize
)
2060 #ifdef KSPROXY_TRACE
2061 OutputDebugStringW(L
"CKsProxy::GetSizeMax Notimplemented\n");
2068 //-------------------------------------------------------------------
2069 // IAMDeviceRemoval interface
2074 CKsProxy::DeviceInfo(CLSID
*pclsidInterfaceClass
, LPWSTR
*pwszSymbolicLink
)
2076 #ifdef KSPROXY_TRACE
2077 OutputDebugStringW(L
"CKsProxy::DeviceInfo\n");
2082 // object not initialized
2083 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_FILE_NOT_FOUND
);
2086 // copy device interface guid
2087 CopyMemory(pclsidInterfaceClass
, &m_DeviceInterfaceGUID
, sizeof(GUID
));
2089 if (pwszSymbolicLink
)
2091 *pwszSymbolicLink
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_DevicePath
)+1) * sizeof(WCHAR
));
2092 if (!*pwszSymbolicLink
)
2093 return E_OUTOFMEMORY
;
2095 wcscpy(*pwszSymbolicLink
, m_DevicePath
);
2101 CKsProxy::Reassociate(void)
2103 #ifdef KSPROXY_TRACE
2104 OutputDebugStringW(L
"CKsProxy::Reassociate\n");
2107 if (!m_DevicePath
|| m_hDevice
)
2109 // file path not available
2110 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_FILE_NOT_FOUND
);
2113 m_hDevice
= CreateFileW(m_DevicePath
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2116 // failed to open device
2117 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2126 CKsProxy::Disassociate(void)
2128 #ifdef KSPROXY_TRACE
2129 OutputDebugStringW(L
"CKsProxy::Disassociate\n");
2135 CloseHandle(m_hDevice
);
2140 //-------------------------------------------------------------------
2141 // IKsClock interface
2146 CKsProxy::KsGetClockHandle()
2148 #ifdef KSPROXY_TRACE
2149 OutputDebugStringW(L
"CKsProxy::KsGetClockHandle\n");
2156 //-------------------------------------------------------------------
2157 // IKsObject interface
2162 CKsProxy::KsGetObjectHandle()
2164 #ifdef KSPROXY_TRACE
2165 OutputDebugStringW(L
"CKsProxy::KsGetObjectHandle\n");
2171 //-------------------------------------------------------------------
2172 // IPersistPropertyBag interface
2176 CKsProxy::InitNew( void)
2178 #ifdef KSPROXY_TRACE
2179 OutputDebugStringW(L
"CKsProxy::InitNew\n");
2187 CKsProxy::GetSupportedSets(
2191 KSPROPERTY Property
;
2193 ULONG NumProperty
= 0;
2194 ULONG NumMethods
= 0;
2195 ULONG NumEvents
= 0;
2197 ULONG BytesReturned
;
2200 Property
.Set
= GUID_NULL
;
2202 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
2204 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumProperty
);
2205 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumMethods
);
2206 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumEvents
);
2208 Length
= NumProperty
+ NumMethods
+ NumEvents
;
2210 // allocate guid buffer
2211 pGuid
= (LPGUID
)CoTaskMemAlloc(Length
);
2215 return E_OUTOFMEMORY
;
2218 NumProperty
/= sizeof(GUID
);
2219 NumMethods
/= sizeof(GUID
);
2220 NumEvents
/= sizeof(GUID
);
2222 // get all properties
2223 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pGuid
, Length
, &BytesReturned
);
2226 CoTaskMemFree(pGuid
);
2229 Length
-= BytesReturned
;
2234 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
], Length
, &BytesReturned
);
2237 CoTaskMemFree(pGuid
);
2240 Length
-= BytesReturned
;
2246 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
+NumMethods
], Length
, &BytesReturned
);
2249 CoTaskMemFree(pGuid
);
2252 Length
-= BytesReturned
;
2255 #ifdef KSPROXY_TRACE
2257 swprintf(Buffer
, L
"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty
, NumMethods
, NumEvents
);
2258 OutputDebugStringW(Buffer
);
2262 *NumGuids
= NumProperty
+NumEvents
+NumMethods
;
2268 CKsProxy::LoadProxyPlugins(
2276 IUnknown
* pUnknown
;
2278 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
2280 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
2284 // enumerate all sets
2285 for(Index
= 0; Index
< NumGuids
; Index
++)
2287 // convert to string
2288 hr
= StringFromCLSID(pGuids
[Index
], &pStr
);
2292 // now try open class key
2293 if (RegOpenKeyExW(hKey
, pStr
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
2295 // no plugin for that set exists
2296 CoTaskMemFree(pStr
);
2301 hr
= CoCreateInstance(pGuids
[Index
], (IBaseFilter
*)this, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void**)&pUnknown
);
2305 m_Plugins
.push_back(pUnknown
);
2308 RegCloseKey(hSubKey
);
2311 // close media interfaces key
2318 CKsProxy::GetNumberOfPins(
2321 KSPROPERTY Property
;
2322 ULONG BytesReturned
;
2325 Property
.Set
= KSPROPSETID_Pin
;
2326 Property
.Id
= KSPROPERTY_PIN_CTYPES
;
2327 Property
.Flags
= KSPROPERTY_TYPE_GET
;
2329 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)NumPins
, sizeof(ULONG
), &BytesReturned
);
2334 CKsProxy::GetPinInstanceCount(
2336 PKSPIN_CINSTANCES Instances
)
2339 ULONG BytesReturned
;
2342 Property
.Property
.Set
= KSPROPSETID_Pin
;
2343 Property
.Property
.Id
= KSPROPERTY_PIN_CINSTANCES
;
2344 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2345 Property
.PinId
= PinId
;
2346 Property
.Reserved
= 0;
2348 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)Instances
, sizeof(KSPIN_CINSTANCES
), &BytesReturned
);
2353 CKsProxy::GetPinCommunication(
2355 KSPIN_COMMUNICATION
* Communication
)
2358 ULONG BytesReturned
;
2361 Property
.Property
.Set
= KSPROPSETID_Pin
;
2362 Property
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
2363 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2364 Property
.PinId
= PinId
;
2365 Property
.Reserved
= 0;
2367 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)Communication
, sizeof(KSPIN_COMMUNICATION
), &BytesReturned
);
2372 CKsProxy::GetPinDataflow(
2374 KSPIN_DATAFLOW
* DataFlow
)
2377 ULONG BytesReturned
;
2380 Property
.Property
.Set
= KSPROPSETID_Pin
;
2381 Property
.Property
.Id
= KSPROPERTY_PIN_DATAFLOW
;
2382 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2383 Property
.PinId
= PinId
;
2384 Property
.Reserved
= 0;
2386 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)DataFlow
, sizeof(KSPIN_DATAFLOW
), &BytesReturned
);
2391 CKsProxy::GetPinName(
2393 KSPIN_DATAFLOW DataFlow
,
2395 LPWSTR
* OutPinName
)
2399 ULONG BytesReturned
;
2404 Property
.Property
.Set
= KSPROPSETID_Pin
;
2405 Property
.Property
.Id
= KSPROPERTY_PIN_NAME
;
2406 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2407 Property
.PinId
= PinId
;
2408 Property
.Reserved
= 0;
2410 // #1 try get it from pin directly
2411 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
2413 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
2415 // allocate pin name
2416 PinName
= (LPWSTR
)CoTaskMemAlloc(BytesReturned
);
2418 return E_OUTOFMEMORY
;
2420 // retry with allocated buffer
2421 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), PinName
, BytesReturned
, &BytesReturned
);
2424 *OutPinName
= PinName
;
2429 CoTaskMemFree(PinName
);
2433 // TODO: retrieve pin name from topology node
2436 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2438 swprintf(Buffer
, L
"Input%lu", PinCount
);
2442 swprintf(Buffer
, L
"Output%lu", PinCount
);
2445 // allocate pin name
2446 PinName
= (LPWSTR
)CoTaskMemAlloc((wcslen(Buffer
)+1) * sizeof(WCHAR
));
2448 return E_OUTOFMEMORY
;
2451 wcscpy(PinName
, Buffer
);
2454 *OutPinName
= PinName
;
2461 CKsProxy::CreatePins()
2463 ULONG NumPins
, Index
;
2464 KSPIN_CINSTANCES Instances
;
2465 KSPIN_DATAFLOW DataFlow
;
2466 KSPIN_COMMUNICATION Communication
;
2471 ULONG OutputPin
= 0;
2473 // get number of pins
2474 hr
= GetNumberOfPins(&NumPins
);
2478 for(Index
= 0; Index
< NumPins
; Index
++)
2480 // query current instance count
2481 hr
= GetPinInstanceCount(Index
, &Instances
);
2485 // query pin communication;
2486 hr
= GetPinCommunication(Index
, &Communication
);
2490 if (Instances
.CurrentCount
== Instances
.PossibleCount
)
2492 // already maximum reached for this pin
2496 // get direction of pin
2497 hr
= GetPinDataflow(Index
, &DataFlow
);
2501 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2502 hr
= GetPinName(Index
, DataFlow
, InputPin
, &PinName
);
2504 hr
= GetPinName(Index
, DataFlow
, OutputPin
, &PinName
);
2509 // construct the pins
2510 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2512 hr
= CInputPin_Constructor((IBaseFilter
*)this, PinName
, m_hDevice
, Index
, Communication
, IID_IPin
, (void**)&pPin
);
2515 CoTaskMemFree(PinName
);
2522 hr
= COutputPin_Constructor((IBaseFilter
*)this, PinName
, Index
, Communication
, IID_IPin
, (void**)&pPin
);
2525 CoTaskMemFree(PinName
);
2532 m_Pins
.push_back(pPin
);
2534 #ifdef KSPROXY_TRACE
2536 swprintf(Buffer
, L
"Index %lu DataFlow %lu Name %s\n", Index
, DataFlow
, PinName
);
2537 OutputDebugStringW(Buffer
);
2547 CKsProxy::Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
)
2554 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
2556 #ifdef KSPROXY_TRACE
2558 OutputDebugStringW(L
"CKsProxy::Load\n");
2562 varName
.vt
= VT_BSTR
;
2563 hr
= pPropBag
->Read(L
"DevicePath", &varName
, pErrorLog
);
2567 #ifdef KSPROXY_TRACE
2568 swprintf(Buffer
, L
"CKsProxy::Load Read %lx\n", hr
);
2569 OutputDebugStringW(Buffer
);
2571 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2574 #ifdef KSPROXY_TRACE
2575 OutputDebugStringW(L
"DevicePath: ");
2576 OutputDebugStringW(varName
.bstrVal
);
2577 OutputDebugStringW(L
"\n");
2580 // create device list
2581 hList
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
2582 if (hList
== INVALID_HANDLE_VALUE
)
2584 // failed to create device list
2585 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2588 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
2589 if (!SetupDiOpenDeviceInterfaceW(hList
, (PCWSTR
)varName
.bstrVal
, 0, &DeviceInterfaceData
))
2591 // failed to open device interface
2592 SetupDiDestroyDeviceInfoList(hList
);
2595 // FIXME handle device interface links(aliases)
2596 CopyMemory(&m_DeviceInterfaceGUID
, &DeviceInterfaceData
.InterfaceClassGuid
, sizeof(GUID
));
2598 // close device info list
2599 SetupDiDestroyDeviceInfoList(hList
);
2602 m_hDevice
= CreateFileW(varName
.bstrVal
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2604 if (m_hDevice
== INVALID_HANDLE_VALUE
)
2606 // failed to open device
2607 #ifdef KSPROXY_TRACE
2608 swprintf(Buffer
, L
"CKsProxy:: failed to open device with %lx\n", GetLastError());
2609 OutputDebugStringW(Buffer
);
2611 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2614 // store device path
2615 m_DevicePath
= varName
.bstrVal
;
2617 // get all supported sets
2618 hr
= GetSupportedSets(&pGuid
, &NumGuids
);
2621 CloseHandle(m_hDevice
);
2626 // load all proxy plugins
2627 hr
= LoadProxyPlugins(pGuid
, NumGuids
);
2630 CloseHandle(m_hDevice
);
2636 CoTaskMemFree(pGuid
);
2638 // now create the input / output pins
2646 CKsProxy::Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
)
2648 #ifdef KSPROXY_TRACE
2649 OutputDebugStringW(L
"CKsProxy::Save\n");
2654 //-------------------------------------------------------------------
2655 // IBaseFilter interface
2660 CKsProxy::GetClassID(
2663 #ifdef KSPROXY_TRACE
2664 OutputDebugStringW(L
"CKsProxy::GetClassID\n");
2666 CopyMemory(pClassID
, &CLSID_Proxy
, sizeof(GUID
));
2677 #ifdef KSPROXY_TRACE
2678 OutputDebugStringW(L
"CKsProxy::Stop\n");
2681 EnterCriticalSection(&m_Lock
);
2683 hr
= SetPinState(KSSTATE_STOP
);
2685 m_FilterState
= State_Stopped
;
2687 LeaveCriticalSection(&m_Lock
);
2698 #ifdef KSPROXY_TRACE
2699 OutputDebugStringW(L
"CKsProxy::Pause\n");
2702 EnterCriticalSection(&m_Lock
);
2704 if (m_FilterState
== State_Running
)
2706 hr
= SetPinState(KSSTATE_STOP
);
2710 if (m_FilterState
== State_Stopped
)
2712 hr
= SetPinState(KSSTATE_PAUSE
);
2717 m_FilterState
= State_Paused
;
2719 LeaveCriticalSection(&m_Lock
);
2727 REFERENCE_TIME tStart
)
2731 #ifdef KSPROXY_TRACE
2732 OutputDebugStringW(L
"CKsProxy::Run\n");
2735 EnterCriticalSection(&m_Lock
);
2737 if (m_FilterState
== State_Stopped
)
2739 LeaveCriticalSection(&m_Lock
);
2740 // setting filter state to pause
2745 EnterCriticalSection(&m_Lock
);
2746 assert(m_FilterState
== State_Paused
);
2749 hr
= SetPinState(KSSTATE_RUN
);
2753 m_FilterState
= State_Running
;
2756 LeaveCriticalSection(&m_Lock
);
2762 CKsProxy::SetPinState(
2768 ULONG BytesReturned
;
2769 KSPROPERTY Property
;
2772 Property
.Set
= KSPROPSETID_Connection
;
2773 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
2774 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2776 // set all pins to running state
2777 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
2779 IPin
* Pin
= m_Pins
[Index
];
2783 //check if the pin is connected
2785 hr
= Pin
->ConnectedTo(&TempPin
);
2788 // skip unconnected pins
2792 // release connected pin
2795 // query for the pin info
2796 hr
= Pin
->QueryPinInfo(&PinInfo
);
2800 if (PinInfo
.pFilter
)
2801 PinInfo
.pFilter
->Release();
2803 if (PinInfo
.dir
== PINDIR_OUTPUT
)
2805 hr
= COutputPin_SetState(Pin
, State
);
2811 //query IKsObject interface
2812 hr
= Pin
->QueryInterface(IID_IKsObject
, (void**)&pObject
);
2815 HANDLE hPin
= pObject
->KsGetObjectHandle();
2818 assert(hPin
&& hPin
!= INVALID_HANDLE_VALUE
);
2821 hr
= KsSynchronousDeviceControl(hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
2823 #ifdef KSPROXY_TRACE
2825 swprintf(Buffer
, L
"CKsProxy::SetPinState Index %u State %u hr %lx\n", Index
, State
, hr
);
2826 OutputDebugStringW(Buffer
);
2838 DWORD dwMilliSecsTimeout
,
2839 FILTER_STATE
*State
)
2844 *State
= m_FilterState
;
2850 CKsProxy::SetSyncSource(
2851 IReferenceClock
*pClock
)
2855 HANDLE hClock
, hPin
;
2858 IKsObject
* pObject
;
2859 KSPROPERTY Property
;
2860 ULONG BytesReturned
;
2861 PIN_DIRECTION PinDir
;
2863 #ifdef KSPROXY_TRACE
2864 OutputDebugStringW(L
"CKsProxy::SetSyncSource\n");
2872 hr
= pClock
->QueryInterface(IID_IKsClock
, (void**)&pKsClock
);
2875 hr
= m_ReferenceClock
->QueryInterface(IID_IKsClock
, (void**)&pKsClock
);
2881 hClock
= pKsClock
->KsGetClockHandle();
2883 // release IKsClock interface
2884 pKsClock
->Release();
2894 // distribute clock to all pins
2895 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
2898 pin
= m_Pins
[Index
];
2902 // get IKsObject interface
2903 hr
= pin
->QueryInterface(IID_IKsObject
, (void **)&pObject
);
2907 hPin
= pObject
->KsGetObjectHandle();
2908 if (hPin
!= INVALID_HANDLE_VALUE
&& hPin
)
2911 Property
.Set
= KSPROPSETID_Stream
;
2912 Property
.Id
= KSPROPERTY_STREAM_MASTERCLOCK
;
2913 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2916 hr
= KsSynchronousDeviceControl(hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&m_hClock
, sizeof(HANDLE
), &BytesReturned
);
2920 if (hr
!= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
) &&
2921 hr
!= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
))
2923 // failed to set master clock
2926 swprintf(Buffer
, L
"CKsProxy::SetSyncSource KSPROPERTY_STREAM_MASTERCLOCK failed with %lx\n", hr
);
2927 OutputDebugStringW(Buffer
);
2932 // release IKsObject
2936 // now get the direction
2937 hr
= pin
->QueryDirection(&PinDir
);
2940 if (PinDir
== PINDIR_OUTPUT
)
2943 //CBaseStreamControl::SetSyncSource(pClock)
2953 if (m_ReferenceClock
)
2955 m_ReferenceClock
->Release();
2958 m_ReferenceClock
= pClock
;
2959 #ifdef KSPROXY_TRACE
2960 OutputDebugStringW(L
"CKsProxy::SetSyncSource done\n");
2967 CKsProxy::GetSyncSource(
2968 IReferenceClock
**pClock
)
2970 #ifdef KSPROXY_TRACE
2971 OutputDebugStringW(L
"CKsProxy::GetSyncSource\n");
2977 if (m_ReferenceClock
)
2978 m_ReferenceClock
->AddRef();
2980 *pClock
= m_ReferenceClock
;
2989 #ifdef KSPROXY_TRACE
2990 OutputDebugStringW(L
"CKsProxy::EnumPins\n");
2993 return CEnumPins_fnConstructor(m_Pins
, IID_IEnumPins
, (void**)ppEnum
);
2999 LPCWSTR Id
, IPin
**ppPin
)
3003 #ifdef KSPROXY_TRACE
3004 OutputDebugStringW(L
"CKsProxy::FindPin\n");
3011 int ret
= swscanf(Id
, L
"%u", &PinId
);
3013 if (!ret
|| ret
== EOF
)
3016 return VFW_E_NOT_FOUND
;
3019 if (PinId
>= m_Pins
.size() || m_Pins
[PinId
] == NULL
)
3022 return VFW_E_NOT_FOUND
;
3026 *ppPin
= m_Pins
[PinId
];
3027 m_Pins
[PinId
]->AddRef();
3035 CKsProxy::QueryFilterInfo(
3041 #ifdef KSPROXY_TRACE
3042 OutputDebugStringW(L
"CKsProxy::QueryFilterInfo\n");
3045 pInfo
->achName
[0] = L
'\0';
3046 pInfo
->pGraph
= m_pGraph
;
3056 CKsProxy::JoinFilterGraph(
3057 IFilterGraph
*pGraph
,
3060 #ifdef KSPROXY_TRACE
3062 swprintf(Buffer
, L
"CKsProxy::JoinFilterGraph pName %s pGraph %p m_Ref %u\n", pName
, pGraph
, m_Ref
);
3063 OutputDebugStringW(Buffer
);
3068 // joining filter graph
3083 CKsProxy::QueryVendorInfo(
3084 LPWSTR
*pVendorInfo
)
3086 #ifdef KSPROXY_TRACE
3087 OutputDebugStringW(L
"CKsProxy::QueryVendorInfo\n");
3089 return StringFromCLSID(CLSID_Proxy
, pVendorInfo
);
3092 //-------------------------------------------------------------------
3093 // IAMovieSetup interface
3098 CKsProxy::Register()
3100 #ifdef KSPROXY_TRACE
3101 OutputDebugStringW(L
"CKsProxy::Register : NotImplemented\n");
3109 CKsProxy::Unregister()
3111 #ifdef KSPROXY_TRACE
3112 OutputDebugStringW(L
"CKsProxy::Unregister : NotImplemented\n");
3119 CKsProxy_Constructor(
3120 IUnknown
* pUnkOuter
,
3124 #ifdef KSPROXY_TRACE
3127 StringFromCLSID(riid
, &pstr
);
3128 swprintf(Buffer
, L
"CKsProxy_Constructor pUnkOuter %p riid %s\n", pUnkOuter
, pstr
);
3129 OutputDebugStringW(Buffer
);
3132 CKsProxy
* handler
= new CKsProxy();
3135 return E_OUTOFMEMORY
;
3137 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
3141 return E_NOINTERFACE
;