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 IID_ISpecifyPropertyPages
= {0xB196B28B, 0xBAB4, 0x101A, {0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}};
14 const GUID IID_IPersistStream
= {0x00000109, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
15 const GUID IID_IPersist
= {0x0000010c, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
17 const GUID IID_IBDA_DeviceControl
= {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
18 const GUID IID_IKsAggregateControl
= {0x7F40EAC0, 0x3947, 0x11D2, {0x87, 0x4E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
19 const GUID IID_IKsClockPropertySet
= {0x5C5CBD84, 0xE755, 0x11D0, {0xAC, 0x18, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
20 const GUID IID_IKsTopology
= {0x28F54683, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
21 const GUID IID_IKsClock
= {0x877E4351, 0x6FEA, 0x11D0, {0xB8, 0x63, 0x00, 0xAA, 0x00, 0xA2, 0x16, 0xA1}};
23 Needs IKsClock, IKsNotifyEvent
26 class CKsProxy
: public IBaseFilter
,
28 public IPersistPropertyBag
,
30 public IPersistStream
,
31 public IAMDeviceRemoval
,
32 public ISpecifyPropertyPages
,
33 public IReferenceClock
,
35 public IKsPropertySet
,
37 public IKsClockPropertySet
,
38 public IAMFilterMiscFlags
,
41 public IKsAggregateControl
45 typedef std::vector
<IUnknown
*>ProxyPluginVector
;
46 typedef std::vector
<IPin
*> PinVector
;
48 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
50 STDMETHODIMP_(ULONG
) AddRef()
52 InterlockedIncrement(&m_Ref
);
55 STDMETHODIMP_(ULONG
) Release()
57 InterlockedDecrement(&m_Ref
);
66 // IBaseFilter methods
67 HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
68 HRESULT STDMETHODCALLTYPE
Stop( void);
69 HRESULT STDMETHODCALLTYPE
Pause( void);
70 HRESULT STDMETHODCALLTYPE
Run(REFERENCE_TIME tStart
);
71 HRESULT STDMETHODCALLTYPE
GetState(DWORD dwMilliSecsTimeout
, FILTER_STATE
*State
);
72 HRESULT STDMETHODCALLTYPE
SetSyncSource(IReferenceClock
*pClock
);
73 HRESULT STDMETHODCALLTYPE
GetSyncSource(IReferenceClock
**pClock
);
74 HRESULT STDMETHODCALLTYPE
EnumPins(IEnumPins
**ppEnum
);
75 HRESULT STDMETHODCALLTYPE
FindPin(LPCWSTR Id
, IPin
**ppPin
);
76 HRESULT STDMETHODCALLTYPE
QueryFilterInfo(FILTER_INFO
*pInfo
);
77 HRESULT STDMETHODCALLTYPE
JoinFilterGraph(IFilterGraph
*pGraph
, LPCWSTR pName
);
78 HRESULT STDMETHODCALLTYPE
QueryVendorInfo(LPWSTR
*pVendorInfo
);
81 HRESULT STDMETHODCALLTYPE
GetTime(REFERENCE_TIME
*pTime
);
82 HRESULT STDMETHODCALLTYPE
AdviseTime(REFERENCE_TIME baseTime
, REFERENCE_TIME streamTime
, HEVENT hEvent
, DWORD_PTR
*pdwAdviseCookie
);
83 HRESULT STDMETHODCALLTYPE
AdvisePeriodic(REFERENCE_TIME startTime
, REFERENCE_TIME periodTime
, HSEMAPHORE hSemaphore
, DWORD_PTR
*pdwAdviseCookie
);
84 HRESULT STDMETHODCALLTYPE
Unadvise(DWORD_PTR dwAdviseCookie
);
87 HRESULT STDMETHODCALLTYPE
GetCapabilities(DWORD
*pCapabilities
);
88 HRESULT STDMETHODCALLTYPE
CheckCapabilities(DWORD
*pCapabilities
);
89 HRESULT STDMETHODCALLTYPE
IsFormatSupported(const GUID
*pFormat
);
90 HRESULT STDMETHODCALLTYPE
QueryPreferredFormat(GUID
*pFormat
);
91 HRESULT STDMETHODCALLTYPE
GetTimeFormat(GUID
*pFormat
);
92 HRESULT STDMETHODCALLTYPE
IsUsingTimeFormat(const GUID
*pFormat
);
93 HRESULT STDMETHODCALLTYPE
SetTimeFormat(const GUID
*pFormat
);
94 HRESULT STDMETHODCALLTYPE
GetDuration(LONGLONG
*pDuration
);
95 HRESULT STDMETHODCALLTYPE
GetStopPosition(LONGLONG
*pStop
);
96 HRESULT STDMETHODCALLTYPE
GetCurrentPosition(LONGLONG
*pCurrent
);
97 HRESULT STDMETHODCALLTYPE
ConvertTimeFormat(LONGLONG
*pTarget
, const GUID
*pTargetFormat
, LONGLONG Source
, const GUID
*pSourceFormat
);
98 HRESULT STDMETHODCALLTYPE
SetPositions(LONGLONG
*pCurrent
, DWORD dwCurrentFlags
, LONGLONG
*pStop
, DWORD dwStopFlags
);
99 HRESULT STDMETHODCALLTYPE
GetPositions(LONGLONG
*pCurrent
, LONGLONG
*pStop
);
100 HRESULT STDMETHODCALLTYPE
GetAvailable(LONGLONG
*pEarliest
, LONGLONG
*pLatest
);
101 HRESULT STDMETHODCALLTYPE
SetRate(double dRate
);
102 HRESULT STDMETHODCALLTYPE
GetRate(double *pdRate
);
103 HRESULT STDMETHODCALLTYPE
GetPreroll(LONGLONG
*pllPreroll
);
106 HRESULT STDMETHODCALLTYPE
Set(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
);
107 HRESULT STDMETHODCALLTYPE
Get(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
, DWORD
*pcbReturned
);
108 HRESULT STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet
, DWORD dwPropID
, DWORD
*pTypeSupport
);
111 ULONG STDMETHODCALLTYPE
GetMiscFlags( void);
114 HRESULT STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
, ULONG DataLength
, ULONG
* BytesReturned
);
115 HRESULT STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
, ULONG DataLength
, ULONG
* BytesReturned
);
116 HRESULT STDMETHODCALLTYPE
KsEvent(PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
, ULONG DataLength
, ULONG
* BytesReturned
);
119 HRESULT STDMETHODCALLTYPE
CreateNodeInstance(ULONG NodeId
, ULONG Flags
, ACCESS_MASK DesiredAccess
, IUnknown
* UnkOuter
, REFGUID InterfaceId
, LPVOID
* Interface
);
121 //IKsAggregateControl
122 HRESULT STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass
);
123 HRESULT STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass
);
125 //IKsClockPropertySet
126 HRESULT STDMETHODCALLTYPE
KsGetTime(LONGLONG
* Time
);
127 HRESULT STDMETHODCALLTYPE
KsSetTime(LONGLONG Time
);
128 HRESULT STDMETHODCALLTYPE
KsGetPhysicalTime(LONGLONG
* Time
);
129 HRESULT STDMETHODCALLTYPE
KsSetPhysicalTime(LONGLONG Time
);
130 HRESULT STDMETHODCALLTYPE
KsGetCorrelatedTime(KSCORRELATED_TIME
* CorrelatedTime
);
131 HRESULT STDMETHODCALLTYPE
KsSetCorrelatedTime(KSCORRELATED_TIME
* CorrelatedTime
);
132 HRESULT STDMETHODCALLTYPE
KsGetCorrelatedPhysicalTime(KSCORRELATED_TIME
* CorrelatedTime
);
133 HRESULT STDMETHODCALLTYPE
KsSetCorrelatedPhysicalTime(KSCORRELATED_TIME
* CorrelatedTime
);
134 HRESULT STDMETHODCALLTYPE
KsGetResolution(KSRESOLUTION
* Resolution
);
135 HRESULT STDMETHODCALLTYPE
KsGetState(KSSTATE
* State
);
138 //IAMovieSetup methods
139 HRESULT STDMETHODCALLTYPE
Register( void);
140 HRESULT STDMETHODCALLTYPE
Unregister( void);
142 // IPersistPropertyBag methods
143 HRESULT STDMETHODCALLTYPE
InitNew( void);
144 HRESULT STDMETHODCALLTYPE
Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
);
145 HRESULT STDMETHODCALLTYPE
Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
);
148 HANDLE STDMETHODCALLTYPE
KsGetObjectHandle();
151 HANDLE STDMETHODCALLTYPE
KsGetClockHandle();
154 HRESULT STDMETHODCALLTYPE
DeviceInfo(CLSID
*pclsidInterfaceClass
, LPWSTR
*pwszSymbolicLink
);
155 HRESULT STDMETHODCALLTYPE
Reassociate(void);
156 HRESULT STDMETHODCALLTYPE
Disassociate( void);
159 HRESULT STDMETHODCALLTYPE
IsDirty( void);
160 HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
161 HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
162 HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
164 // ISpecifyPropertyPages
165 HRESULT STDMETHODCALLTYPE
GetPages(CAUUID
*pPages
);
172 CloseHandle(m_hDevice
);
175 HRESULT STDMETHODCALLTYPE
GetSupportedSets(LPGUID
* pOutGuid
, PULONG NumGuids
);
176 HRESULT STDMETHODCALLTYPE
LoadProxyPlugins(LPGUID pGuids
, ULONG NumGuids
);
177 HRESULT STDMETHODCALLTYPE
GetNumberOfPins(PULONG NumPins
);
178 HRESULT STDMETHODCALLTYPE
GetPinInstanceCount(ULONG PinId
, PKSPIN_CINSTANCES Instances
);
179 HRESULT STDMETHODCALLTYPE
GetPinDataflow(ULONG PinId
, KSPIN_DATAFLOW
* DataFlow
);
180 HRESULT STDMETHODCALLTYPE
GetPinName(ULONG PinId
, KSPIN_DATAFLOW DataFlow
, ULONG PinCount
, LPWSTR
* OutPinName
);
181 HRESULT STDMETHODCALLTYPE
GetPinCommunication(ULONG PinId
, KSPIN_COMMUNICATION
* Communication
);
182 HRESULT STDMETHODCALLTYPE
CreatePins();
183 HRESULT STDMETHODCALLTYPE
GetMediaSeekingFormats(PKSMULTIPLE_ITEM
*FormatList
);
184 HRESULT STDMETHODCALLTYPE
CreateClockInstance();
185 HRESULT STDMETHODCALLTYPE
PerformClockProperty(ULONG PropertyId
, ULONG PropertyFlags
, PVOID OutputBuffer
, ULONG OutputBufferSize
);
186 HRESULT STDMETHODCALLTYPE
SetPinState(KSSTATE State
);
191 IFilterGraph
*m_pGraph
;
192 IReferenceClock
* m_ReferenceClock
;
193 FILTER_STATE m_FilterState
;
195 ProxyPluginVector m_Plugins
;
198 CLSID m_DeviceInterfaceGUID
;
200 CRITICAL_SECTION m_Lock
;
203 CKsProxy::CKsProxy() : m_Ref(0),
205 m_FilterState(State_Stopped
),
212 m_ReferenceClock
= this;
213 InitializeCriticalSection(&m_Lock
);
219 CKsProxy::QueryInterface(
225 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
226 IsEqualGUID(refiid
, IID_IBaseFilter
))
228 *Output
= PVOID(this);
229 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
232 else if (IsEqualGUID(refiid
, IID_IPersistPropertyBag
))
234 *Output
= (IPersistPropertyBag
*)(this);
235 reinterpret_cast<IPersistPropertyBag
*>(*Output
)->AddRef();
238 else if (IsEqualGUID(refiid
, IID_IAMDeviceRemoval
))
240 *Output
= (IAMDeviceRemoval
*)(this);
241 reinterpret_cast<IAMDeviceRemoval
*>(*Output
)->AddRef();
244 else if (IsEqualGUID(refiid
, IID_IPersistStream
))
246 *Output
= (IPersistStream
*)(this);
247 reinterpret_cast<IPersistStream
*>(*Output
)->AddRef();
250 else if (IsEqualGUID(refiid
, IID_IPersist
))
252 *Output
= (IPersistStream
*)(this);
253 reinterpret_cast<IPersist
*>(*Output
)->AddRef();
256 else if (IsEqualGUID(refiid
, IID_IKsObject
))
258 *Output
= (IKsObject
*)(this);
259 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
262 else if (IsEqualGUID(refiid
, IID_IKsClock
))
264 *Output
= (IKsClock
*)(this);
265 reinterpret_cast<IKsClock
*>(*Output
)->AddRef();
268 else if (IsEqualGUID(refiid
, IID_IReferenceClock
))
272 HRESULT hr
= CreateClockInstance();
277 *Output
= (IReferenceClock
*)(this);
278 reinterpret_cast<IReferenceClock
*>(*Output
)->AddRef();
281 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
283 *Output
= (IMediaSeeking
*)(this);
284 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
287 else if (IsEqualGUID(refiid
, IID_IAMFilterMiscFlags
))
289 *Output
= (IAMFilterMiscFlags
*)(this);
290 reinterpret_cast<IAMFilterMiscFlags
*>(*Output
)->AddRef();
293 else if (IsEqualGUID(refiid
, IID_IKsControl
))
295 *Output
= (IKsControl
*)(this);
296 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
299 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
301 *Output
= (IKsPropertySet
*)(this);
302 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
305 else if (IsEqualGUID(refiid
, IID_IKsTopology
))
307 *Output
= (IKsTopology
*)(this);
308 reinterpret_cast<IKsTopology
*>(*Output
)->AddRef();
311 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
313 *Output
= (IKsAggregateControl
*)(this);
314 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
317 else if (IsEqualGUID(refiid
, IID_IKsClockPropertySet
))
321 HRESULT hr
= CreateClockInstance();
326 *Output
= (IKsClockPropertySet
*)(this);
327 reinterpret_cast<IKsClockPropertySet
*>(*Output
)->AddRef();
330 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
332 *Output
= (ISpecifyPropertyPages
*)(this);
333 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
337 for(ULONG Index
= 0; Index
< m_Plugins
.size(); Index
++)
341 HRESULT hr
= m_Plugins
[Index
]->QueryInterface(refiid
, Output
);
347 StringFromCLSID(refiid
, &lpstr
);
348 swprintf(Buffer
, L
"CKsProxy::QueryInterface plugin %lu supports interface %s\n", Index
, lpstr
);
349 OutputDebugStringW(Buffer
);
350 CoTaskMemFree(lpstr
);
357 WCHAR Buffer
[MAX_PATH
];
359 StringFromCLSID(refiid
, &lpstr
);
360 swprintf(Buffer
, L
"CKsProxy::QueryInterface: NoInterface for %s !!!\n", lpstr
);
361 OutputDebugStringW(Buffer
);
362 CoTaskMemFree(lpstr
);
365 return E_NOINTERFACE
;
368 //-------------------------------------------------------------------
369 // ISpecifyPropertyPages
374 CKsProxy::GetPages(CAUUID
*pPages
)
377 OutputDebugStringW(L
"CKsProxy::GetPages NotImplemented\n");
384 pPages
->pElems
= NULL
;
389 //-------------------------------------------------------------------
390 // IKsClockPropertySet interface
395 CKsProxy::CreateClockInstance()
398 HANDLE hPin
= INVALID_HANDLE_VALUE
;
400 PIN_DIRECTION PinDir
;
402 KSCLOCK_CREATE ClockCreate
;
404 // find output pin and handle
405 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
408 IPin
* pin
= m_Pins
[Index
];
413 hr
= pin
->QueryDirection(&PinDir
);
417 // query IKsObject interface
418 hr
= pin
->QueryInterface(IID_IKsObject
, (void**)&pObject
);
424 hPin
= pObject
->KsGetObjectHandle();
429 if (hPin
!= INVALID_HANDLE_VALUE
)
433 if (hPin
== INVALID_HANDLE_VALUE
)
435 // clock can only be instantiated on a pin handle
441 // release clock handle
442 CloseHandle(m_hClock
);
445 //setup clock create request
446 ClockCreate
.CreateFlags
= 0;
448 // setup clock create request
449 hr
= KsCreateClock(hPin
, &ClockCreate
, &m_hClock
); // FIXME KsCreateClock returns NTSTATUS
452 // failed to create clock
453 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
461 CKsProxy::PerformClockProperty(
465 ULONG OutputBufferSize
)
474 hr
= CreateClockInstance();
480 Property
.Set
= KSPROPSETID_Clock
;
481 Property
.Id
= PropertyId
;
482 Property
.Flags
= PropertyFlags
;
484 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)OutputBuffer
, OutputBufferSize
, &BytesReturned
);
495 OutputDebugStringW(L
"CKsProxy::KsGetTime\n");
498 return PerformClockProperty(KSPROPERTY_CLOCK_TIME
, KSPROPERTY_TYPE_GET
, (PVOID
)Time
, sizeof(LONGLONG
));
507 OutputDebugStringW(L
"CKsProxy::KsSetTime\n");
510 return PerformClockProperty(KSPROPERTY_CLOCK_TIME
, KSPROPERTY_TYPE_SET
, (PVOID
)&Time
, sizeof(LONGLONG
));
515 CKsProxy::KsGetPhysicalTime(
519 OutputDebugStringW(L
"CKsProxy::KsGetPhysicalTime\n");
522 return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)Time
, sizeof(LONGLONG
));
527 CKsProxy::KsSetPhysicalTime(
531 OutputDebugStringW(L
"CKsProxy::KsSetPhysicalTime\n");
534 return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)&Time
, sizeof(LONGLONG
));
539 CKsProxy::KsGetCorrelatedTime(
540 KSCORRELATED_TIME
* CorrelatedTime
)
543 OutputDebugStringW(L
"CKsProxy::KsGetCorrelatedTime\n");
546 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
551 CKsProxy::KsSetCorrelatedTime(
552 KSCORRELATED_TIME
* CorrelatedTime
)
555 OutputDebugStringW(L
"CKsProxy::KsSetCorrelatedTime\n");
557 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
562 CKsProxy::KsGetCorrelatedPhysicalTime(
563 KSCORRELATED_TIME
* CorrelatedTime
)
566 OutputDebugStringW(L
"CKsProxy::KsGetCorrelatedPhysicalTime\n");
568 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
573 CKsProxy::KsSetCorrelatedPhysicalTime(
574 KSCORRELATED_TIME
* CorrelatedTime
)
577 OutputDebugStringW(L
"CKsProxy::KsSetCorrelatedPhysicalTime\n");
580 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
585 CKsProxy::KsGetResolution(
586 KSRESOLUTION
* Resolution
)
589 OutputDebugStringW(L
"CKsProxy::KsGetResolution\n");
591 return PerformClockProperty(KSPROPERTY_CLOCK_RESOLUTION
, KSPROPERTY_TYPE_GET
, (PVOID
)Resolution
, sizeof(KSRESOLUTION
));
596 CKsProxy::KsGetState(
600 OutputDebugStringW(L
"CKsProxy::KsGetState\n");
602 return PerformClockProperty(KSPROPERTY_CLOCK_STATE
, KSPROPERTY_TYPE_GET
, (PVOID
)State
, sizeof(KSSTATE
));
605 //-------------------------------------------------------------------
606 // IReferenceClock interface
611 REFERENCE_TIME
*pTime
)
618 OutputDebugStringW(L
"CKsProxy::GetTime\n");
631 hr
= CreateClockInstance();
637 Property
.Set
= KSPROPSETID_Clock
;
638 Property
.Id
= KSPROPERTY_CLOCK_TIME
;
639 Property
.Flags
= KSPROPERTY_TYPE_GET
;
642 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pTime
, sizeof(REFERENCE_TIME
), &BytesReturned
);
653 CKsProxy::AdviseTime(
654 REFERENCE_TIME baseTime
,
655 REFERENCE_TIME streamTime
,
657 DWORD_PTR
*pdwAdviseCookie
)
662 PKSEVENT_TIME_MARK Event
;
665 OutputDebugStringW(L
"CKsProxy::AdviseTime\n");
672 if (!pdwAdviseCookie
)
678 hr
= CreateClockInstance();
683 // allocate event entry
684 Event
= (PKSEVENT_TIME_MARK
)CoTaskMemAlloc(sizeof(KSEVENT_TIME_MARK
));
688 Property
.Set
= KSEVENTSETID_Clock
;
689 Property
.Id
= KSEVENT_CLOCK_POSITION_MARK
;
690 Property
.Flags
= KSEVENT_TYPE_ENABLE
;
692 Event
->EventData
.NotificationType
= KSEVENTF_EVENT_HANDLE
;
693 Event
->EventData
.EventHandle
.Event
= (HANDLE
)hEvent
;
694 Event
->EventData
.Alignment
.Alignment
[0] = 0;
695 Event
->EventData
.Alignment
.Alignment
[1] = 0;
696 Event
->MarkTime
= baseTime
+ streamTime
;
699 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSEVENT
), (PVOID
)Event
, sizeof(KSEVENT_TIME_MARK
), &BytesReturned
);
702 // store event handle
703 *pdwAdviseCookie
= (DWORD_PTR
)Event
;
707 // failed to enable event
708 CoTaskMemFree(Event
);
721 CKsProxy::AdvisePeriodic(
722 REFERENCE_TIME startTime
,
723 REFERENCE_TIME periodTime
,
724 HSEMAPHORE hSemaphore
,
725 DWORD_PTR
*pdwAdviseCookie
)
730 PKSEVENT_TIME_INTERVAL Event
;
733 OutputDebugStringW(L
"CKsProxy::AdvisePeriodic\n");
740 if (!pdwAdviseCookie
)
746 hr
= CreateClockInstance();
751 // allocate event entry
752 Event
= (PKSEVENT_TIME_INTERVAL
)CoTaskMemAlloc(sizeof(KSEVENT_TIME_INTERVAL
));
756 Property
.Set
= KSEVENTSETID_Clock
;
757 Property
.Id
= KSEVENT_CLOCK_INTERVAL_MARK
;
758 Property
.Flags
= KSEVENT_TYPE_ENABLE
;
760 Event
->EventData
.NotificationType
= KSEVENTF_SEMAPHORE_HANDLE
;
761 Event
->EventData
.SemaphoreHandle
.Semaphore
= (HANDLE
)hSemaphore
;
762 Event
->EventData
.SemaphoreHandle
.Reserved
= 0;
763 Event
->EventData
.SemaphoreHandle
.Adjustment
= 1;
764 Event
->TimeBase
= startTime
;
765 Event
->Interval
= periodTime
;
768 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSEVENT
), (PVOID
)Event
, sizeof(KSEVENT_TIME_INTERVAL
), &BytesReturned
);
771 // store event handle
772 *pdwAdviseCookie
= (DWORD_PTR
)Event
;
776 // failed to enable event
777 CoTaskMemFree(Event
);
791 DWORD_PTR dwAdviseCookie
)
797 OutputDebugStringW(L
"CKsProxy::Unadvise\n");
802 //lets disable the event
803 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)dwAdviseCookie
, sizeof(KSEVENTDATA
), 0, 0, &BytesReturned
);
806 // lets free event data
807 CoTaskMemFree((LPVOID
)dwAdviseCookie
);
812 // no clock available
819 //-------------------------------------------------------------------
820 // IMediaSeeking interface
824 CKsProxy::GetCapabilities(
825 DWORD
*pCapabilities
)
828 ULONG BytesReturned
, Index
;
832 Property
.Set
= KSPROPSETID_MediaSeeking
;
833 Property
.Id
= KSPROPERTY_MEDIASEEKING_CAPABILITIES
;
834 Property
.Flags
= KSPROPERTY_TYPE_GET
;
837 OutputDebugStringW(L
"CKsProxy::GetCapabilities\n");
845 *pCapabilities
= (KS_SEEKING_CanSeekAbsolute
| KS_SEEKING_CanSeekForwards
| KS_SEEKING_CanSeekBackwards
| KS_SEEKING_CanGetCurrentPos
|
846 KS_SEEKING_CanGetStopPos
| KS_SEEKING_CanGetDuration
| KS_SEEKING_CanPlayBackwards
);
848 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pCapabilities
, sizeof(KS_SEEKING_CAPABILITIES
), &BytesReturned
);
849 // check if plugins support it
850 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
853 IUnknown
* Plugin
= m_Plugins
[Index
];
858 // query for IMediaSeeking interface
859 IMediaSeeking
*pSeek
= NULL
;
860 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
869 hr
= pSeek
->GetCapabilities(&TempCaps
);
872 // and with supported flags
873 *pCapabilities
= (*pCapabilities
& TempCaps
);
875 // release IMediaSeeking interface
883 CKsProxy::CheckCapabilities(
884 DWORD
*pCapabilities
)
890 OutputDebugStringW(L
"CKsProxy::CheckCapabilities\n");
899 hr
= GetCapabilities(&Capabilities
);
902 if ((Capabilities
| *pCapabilities
) == Capabilities
)
908 Capabilities
= (Capabilities
& *pCapabilities
);
912 *pCapabilities
= Capabilities
;
915 // no capabilities are present
924 CKsProxy::GetMediaSeekingFormats(
925 PKSMULTIPLE_ITEM
*FormatList
)
931 Property
.Set
= KSPROPSETID_MediaSeeking
;
932 Property
.Id
= KSPROPERTY_MEDIASEEKING_FORMATS
;
933 Property
.Flags
= KSPROPERTY_TYPE_GET
;
935 // query for format size list
936 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &BytesReturned
);
938 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
940 // allocate format list
941 *FormatList
= (PKSMULTIPLE_ITEM
)CoTaskMemAlloc(BytesReturned
);
945 return E_OUTOFMEMORY
;
949 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)*FormatList
, BytesReturned
, &BytesReturned
);
952 // failed to query format list
953 CoTaskMemFree(FormatList
);
961 CKsProxy::IsFormatSupported(
964 PKSMULTIPLE_ITEM FormatList
;
967 HRESULT hr
= S_FALSE
;
972 StringFromCLSID(*pFormat
, &pstr
);
973 swprintf(Buffer
, L
"CKsProxy::IsFormatSupported %s\n",pstr
);
974 OutputDebugStringW(Buffer
);
981 hr
= GetMediaSeekingFormats(&FormatList
);
985 swprintf(Buffer
, L
"CKsProxy::IsFormatSupported NumFormat %lu\n",FormatList
->Count
);
986 OutputDebugStringW(Buffer
);
989 //iterate through format list
990 pGuid
= (LPGUID
)(FormatList
+ 1);
991 for(Index
= 0; Index
< FormatList
->Count
; Index
++)
993 if (IsEqualGUID(*pGuid
, *pFormat
))
995 CoTaskMemFree(FormatList
);
1001 CoTaskMemFree(FormatList
);
1004 // check if all plugins support it
1005 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1008 IUnknown
* Plugin
= m_Plugins
[Index
];
1013 // query for IMediaSeeking interface
1014 IMediaSeeking
*pSeek
= NULL
;
1015 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1018 // plugin does not support interface
1020 #ifdef KSPROXY_TRACE
1021 OutputDebugStringW(L
"CKsProxy::IsFormatSupported plugin does not support IMediaSeeking interface\n");
1026 // query if it is supported
1027 hr
= pSeek
->IsFormatSupported(pFormat
);
1028 // release interface
1031 if (FAILED(hr
) || hr
== S_FALSE
)
1040 CKsProxy::QueryPreferredFormat(
1043 PKSMULTIPLE_ITEM FormatList
;
1047 #ifdef KSPROXY_TRACE
1048 OutputDebugStringW(L
"CKsProxy::QueryPreferredFormat\n");
1054 hr
= GetMediaSeekingFormats(&FormatList
);
1057 if (FormatList
->Count
)
1059 CopyMemory(pFormat
, (FormatList
+ 1), sizeof(GUID
));
1060 CoTaskMemFree(FormatList
);
1063 CoTaskMemFree(FormatList
);
1065 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1067 // check if plugins support it
1068 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1071 IUnknown
* Plugin
= m_Plugins
[Index
];
1076 // query for IMediaSeeking interface
1077 IMediaSeeking
*pSeek
= NULL
;
1078 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1081 // get preferred time format
1082 hr
= pSeek
->QueryPreferredFormat(pFormat
);
1083 // release IMediaSeeking interface
1098 CKsProxy::GetTimeFormat(
1101 KSPROPERTY Property
;
1102 ULONG BytesReturned
, Index
;
1105 Property
.Set
= KSPROPSETID_MediaSeeking
;
1106 Property
.Id
= KSPROPERTY_MEDIASEEKING_TIMEFORMAT
;
1107 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1109 #ifdef KSPROXY_TRACE
1110 OutputDebugStringW(L
"CKsProxy::GetTimeFormat\n");
1113 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pFormat
, sizeof(GUID
), &BytesReturned
);
1114 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1116 // check if plugins support it
1117 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1121 IUnknown
* Plugin
= m_Plugins
[Index
];
1126 // query for IMediaSeeking interface
1127 IMediaSeeking
*pSeek
= NULL
;
1128 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1132 hr
= pSeek
->GetTimeFormat(pFormat
);
1133 // release IMediaSeeking interface
1146 CKsProxy::IsUsingTimeFormat(
1147 const GUID
*pFormat
)
1151 #ifdef KSPROXY_TRACE
1152 OutputDebugStringW(L
"CKsProxy::IsUsingTimeFormat\n");
1155 if (FAILED(QueryPreferredFormat(&Format
)))
1158 if (IsEqualGUID(Format
, *pFormat
))
1166 CKsProxy::SetTimeFormat(
1167 const GUID
*pFormat
)
1169 KSPROPERTY Property
;
1170 ULONG BytesReturned
, Index
;
1173 Property
.Set
= KSPROPSETID_MediaSeeking
;
1174 Property
.Id
= KSPROPERTY_MEDIASEEKING_TIMEFORMAT
;
1175 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1177 #ifdef KSPROXY_TRACE
1178 OutputDebugStringW(L
"CKsProxy::SetTimeFormat\n");
1181 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pFormat
, sizeof(GUID
), &BytesReturned
);
1182 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1184 // check if plugins support it
1185 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1189 IUnknown
* Plugin
= m_Plugins
[Index
];
1194 // query for IMediaSeeking interface
1195 IMediaSeeking
*pSeek
= NULL
;
1196 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1203 hr
= pSeek
->SetTimeFormat(pFormat
);
1204 // release IMediaSeeking interface
1216 CKsProxy::GetDuration(
1217 LONGLONG
*pDuration
)
1219 KSPROPERTY Property
;
1220 ULONG BytesReturned
, Index
;
1223 Property
.Set
= KSPROPSETID_MediaSeeking
;
1224 Property
.Id
= KSPROPERTY_MEDIASEEKING_DURATION
;
1225 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1227 #ifdef KSPROXY_TRACE
1228 OutputDebugStringW(L
"CKsProxy::GetDuration\n");
1231 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pDuration
, sizeof(LONGLONG
), &BytesReturned
);
1232 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1234 // check if plugins support it
1235 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1239 IUnknown
* Plugin
= m_Plugins
[Index
];
1244 // query for IMediaSeeking interface
1245 IMediaSeeking
*pSeek
= NULL
;
1246 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1250 hr
= pSeek
->GetStopPosition(pDuration
);
1251 // release IMediaSeeking interface
1254 if (hr
!= S_FALSE
) // plugin implements it
1264 CKsProxy::GetStopPosition(
1267 KSPROPERTY Property
;
1268 ULONG BytesReturned
, Index
;
1271 Property
.Set
= KSPROPSETID_MediaSeeking
;
1272 Property
.Id
= KSPROPERTY_MEDIASEEKING_STOPPOSITION
;
1273 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1275 #ifdef KSPROXY_TRACE
1276 OutputDebugStringW(L
"CKsProxy::GetStopPosition\n");
1279 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pStop
, sizeof(LONGLONG
), &BytesReturned
);
1280 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1282 // check if plugins support it
1283 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1287 IUnknown
* Plugin
= m_Plugins
[Index
];
1292 // query for IMediaSeeking interface
1293 IMediaSeeking
*pSeek
= NULL
;
1294 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1297 // get stop position
1298 hr
= pSeek
->GetStopPosition(pStop
);
1299 // release IMediaSeeking interface
1302 if (hr
!= S_FALSE
) // plugin implements it
1312 CKsProxy::GetCurrentPosition(
1315 KSPROPERTY Property
;
1316 ULONG BytesReturned
, Index
;
1319 Property
.Set
= KSPROPSETID_MediaSeeking
;
1320 Property
.Id
= KSPROPERTY_MEDIASEEKING_POSITION
;
1321 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1323 #ifdef KSPROXY_TRACE
1324 OutputDebugStringW(L
"CKsProxy::GetCurrentPosition\n");
1327 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pCurrent
, sizeof(LONGLONG
), &BytesReturned
);
1328 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1330 // check if plugins support it
1331 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1335 IUnknown
* Plugin
= m_Plugins
[Index
];
1340 // query for IMediaSeeking interface
1341 IMediaSeeking
*pSeek
= NULL
;
1342 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1345 // get current position
1346 hr
= pSeek
->GetCurrentPosition(pCurrent
);
1347 // release IMediaSeeking interface
1350 if (hr
!= S_FALSE
) // plugin implements it
1360 CKsProxy::ConvertTimeFormat(
1362 const GUID
*pTargetFormat
,
1364 const GUID
*pSourceFormat
)
1366 KSP_TIMEFORMAT Property
;
1367 ULONG BytesReturned
, Index
;
1368 GUID SourceFormat
, TargetFormat
;
1371 Property
.Property
.Set
= KSPROPSETID_MediaSeeking
;
1372 Property
.Property
.Id
= KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT
;
1373 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
1375 #ifdef KSPROXY_TRACE
1376 OutputDebugStringW(L
"CKsProxy::ConvertTimeFormat\n");
1381 // get current format
1382 hr
= GetTimeFormat(&TargetFormat
);
1386 pTargetFormat
= &TargetFormat
;
1391 // get current format
1392 hr
= GetTimeFormat(&SourceFormat
);
1396 pSourceFormat
= &SourceFormat
;
1399 Property
.SourceFormat
= *pSourceFormat
;
1400 Property
.TargetFormat
= *pTargetFormat
;
1401 Property
.Time
= Source
;
1404 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_TIMEFORMAT
), (PVOID
)pTarget
, sizeof(LONGLONG
), &BytesReturned
);
1405 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1410 // check if plugins support it
1411 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1414 IUnknown
* Plugin
= m_Plugins
[Index
];
1419 // query for IMediaSeeking interface
1420 IMediaSeeking
*pSeek
= NULL
;
1421 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1424 // convert time format
1425 hr
= pSeek
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
1426 // release IMediaSeeking interface
1429 if (hr
!= S_FALSE
) // plugin implements it
1440 CKsProxy::SetPositions(
1442 DWORD dwCurrentFlags
,
1446 KSPROPERTY Property
;
1447 KSPROPERTY_POSITIONS Positions
;
1448 ULONG BytesReturned
, Index
;
1451 Property
.Set
= KSPROPSETID_MediaSeeking
;
1452 Property
.Id
= KSPROPERTY_MEDIASEEKING_POSITIONS
;
1453 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1455 Positions
.Current
= *pCurrent
;
1456 Positions
.CurrentFlags
= (KS_SEEKING_FLAGS
)dwCurrentFlags
;
1457 Positions
.Stop
= *pStop
;
1458 Positions
.StopFlags
= (KS_SEEKING_FLAGS
)dwStopFlags
;
1460 #ifdef KSPROXY_TRACE
1461 OutputDebugStringW(L
"CKsProxy::SetPositions\n");
1464 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Positions
, sizeof(KSPROPERTY_POSITIONS
), &BytesReturned
);
1467 if (dwCurrentFlags
& AM_SEEKING_ReturnTime
)
1469 // retrieve current position
1470 hr
= GetCurrentPosition(pCurrent
);
1475 if (dwStopFlags
& AM_SEEKING_ReturnTime
)
1477 // retrieve current position
1478 hr
= GetStopPosition(pStop
);
1483 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1487 // check if plugins support it
1488 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1491 IUnknown
* Plugin
= m_Plugins
[Index
];
1496 // query for IMediaSeeking interface
1497 IMediaSeeking
*pSeek
= NULL
;
1498 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1502 hr
= pSeek
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
1503 // release IMediaSeeking interface
1517 CKsProxy::GetPositions(
1523 #ifdef KSPROXY_TRACE
1524 OutputDebugStringW(L
"CKsProxy::GetPositions\n");
1527 hr
= GetCurrentPosition(pCurrent
);
1529 hr
= GetStopPosition(pStop
);
1536 CKsProxy::GetAvailable(
1537 LONGLONG
*pEarliest
,
1540 KSPROPERTY Property
;
1541 KSPROPERTY_MEDIAAVAILABLE Media
;
1542 ULONG BytesReturned
, Index
;
1545 Property
.Set
= KSPROPSETID_MediaSeeking
;
1546 Property
.Id
= KSPROPERTY_MEDIASEEKING_AVAILABLE
;
1547 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1549 #ifdef KSPROXY_TRACE
1550 OutputDebugStringW(L
"CKsProxy::GetAvailable\n");
1553 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Media
, sizeof(KSPROPERTY_MEDIAAVAILABLE
), &BytesReturned
);
1554 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1556 // check if plugins support it
1557 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1561 IUnknown
* Plugin
= m_Plugins
[Index
];
1566 // query for IMediaSeeking interface
1567 IMediaSeeking
*pSeek
= NULL
;
1568 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1572 hr
= pSeek
->GetAvailable(pEarliest
, pLatest
);
1573 // release IMediaSeeking interface
1576 if (hr
!= S_FALSE
) // plugin implements it
1581 else if (SUCCEEDED(hr
))
1583 *pEarliest
= Media
.Earliest
;
1584 *pLatest
= Media
.Latest
;
1595 #ifdef KSPROXY_TRACE
1596 OutputDebugStringW(L
"CKsProxy::SetRate\n");
1606 #ifdef KSPROXY_TRACE
1607 OutputDebugStringW(L
"CKsProxy::GetRate\n");
1614 CKsProxy::GetPreroll(
1615 LONGLONG
*pllPreroll
)
1617 KSPROPERTY Property
;
1618 ULONG BytesReturned
, Index
;
1621 Property
.Set
= KSPROPSETID_MediaSeeking
;
1622 Property
.Id
= KSPROPERTY_MEDIASEEKING_PREROLL
;
1623 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1625 #ifdef KSPROXY_TRACE
1626 OutputDebugStringW(L
"CKsProxy::GetPreroll\n");
1629 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pllPreroll
, sizeof(LONGLONG
), &BytesReturned
);
1630 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1632 // check if all plugins support it
1633 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1636 IUnknown
* Plugin
= m_Plugins
[Index
];
1641 // query for IMediaSeeking interface
1642 IMediaSeeking
*pSeek
= NULL
;
1643 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1647 hr
= pSeek
->GetPreroll(pllPreroll
);
1648 // release IMediaSeeking interface
1651 if (hr
!= S_FALSE
) // plugin implements it
1660 //-------------------------------------------------------------------
1661 // IAMFilterMiscFlags interface
1666 CKsProxy::GetMiscFlags()
1671 PIN_DIRECTION PinDirection
;
1672 KSPIN_COMMUNICATION Communication
;
1675 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
1678 IPin
* pin
= m_Pins
[Index
];
1680 hr
= pin
->QueryDirection(&PinDirection
);
1683 if (PinDirection
== PINDIR_INPUT
)
1685 if (SUCCEEDED(GetPinCommunication(Index
, //FIXME verify PinId
1688 if (Communication
!= KSPIN_COMMUNICATION_NONE
&& Communication
!= KSPIN_COMMUNICATION_BRIDGE
)
1690 Flags
|= AM_FILTER_MISC_FLAGS_IS_SOURCE
;
1697 #ifdef KSPROXY_TRACE
1699 swprintf(Buffer
, L
"CKsProxy::GetMiscFlags stub Flags %x\n", Flags
);
1700 OutputDebugStringW(Buffer
);
1706 //-------------------------------------------------------------------
1711 CKsProxy::KsProperty(
1712 PKSPROPERTY Property
,
1713 ULONG PropertyLength
,
1714 LPVOID PropertyData
,
1716 ULONG
* BytesReturned
)
1718 #ifdef KSPROXY_TRACE
1719 OutputDebugStringW(L
"CKsProxy::KsProperty\n");
1722 assert(m_hDevice
!= 0);
1723 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1733 ULONG
* BytesReturned
)
1735 #ifdef KSPROXY_TRACE
1736 OutputDebugStringW(L
"CKsProxy::KsMethod\n");
1739 assert(m_hDevice
!= 0);
1740 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1750 ULONG
* BytesReturned
)
1752 #ifdef KSPROXY_TRACE
1753 OutputDebugStringW(L
"CKsProxy::KsEvent\n");
1756 assert(m_hDevice
!= 0);
1758 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1760 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1764 //-------------------------------------------------------------------
1770 REFGUID guidPropSet
,
1772 LPVOID pInstanceData
,
1773 DWORD cbInstanceData
,
1777 ULONG BytesReturned
;
1779 #ifdef KSPROXY_TRACE
1780 OutputDebugStringW(L
"CKsProxy::Set\n");
1785 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1787 return E_OUTOFMEMORY
;
1789 Property
->Set
= guidPropSet
;
1790 Property
->Id
= dwPropID
;
1791 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1793 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1795 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1796 CoTaskMemFree(Property
);
1801 KSPROPERTY Property
;
1803 Property
.Set
= guidPropSet
;
1804 Property
.Id
= dwPropID
;
1805 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1807 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1815 REFGUID guidPropSet
,
1817 LPVOID pInstanceData
,
1818 DWORD cbInstanceData
,
1823 ULONG BytesReturned
;
1825 #ifdef KSPROXY_TRACE
1826 OutputDebugStringW(L
"CKsProxy::Get\n");
1831 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1833 return E_OUTOFMEMORY
;
1835 Property
->Set
= guidPropSet
;
1836 Property
->Id
= dwPropID
;
1837 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1839 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1841 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1842 CoTaskMemFree(Property
);
1847 KSPROPERTY Property
;
1849 Property
.Set
= guidPropSet
;
1850 Property
.Id
= dwPropID
;
1851 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1853 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1860 CKsProxy::QuerySupported(
1861 REFGUID guidPropSet
,
1863 DWORD
*pTypeSupport
)
1865 KSPROPERTY Property
;
1866 ULONG BytesReturned
;
1868 #ifdef KSPROXY_TRACE
1869 OutputDebugStringW(L
"CKsProxy::QuerySupported\n");
1872 Property
.Set
= guidPropSet
;
1873 Property
.Id
= dwPropID
;
1874 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1876 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1880 //-------------------------------------------------------------------
1881 // IKsTopology interface
1885 CKsProxy::CreateNodeInstance(
1888 ACCESS_MASK DesiredAccess
,
1890 REFGUID InterfaceId
,
1895 #ifdef KSPROXY_TRACE
1896 OutputDebugStringW(L
"CKsProxy::CreateNodeInstance\n");
1901 if (IsEqualIID(IID_IUnknown
, InterfaceId
) || !UnkOuter
)
1903 hr
= CKsNode_Constructor(UnkOuter
, m_hDevice
, NodeId
, DesiredAccess
, InterfaceId
, Interface
);
1907 // interface not supported
1914 //-------------------------------------------------------------------
1915 // IKsAggregateControl interface
1919 CKsProxy::KsAddAggregate(
1920 IN REFGUID AggregateClass
)
1922 #ifdef KSPROXY_TRACE
1923 OutputDebugStringW(L
"CKsProxy::KsAddAggregate NotImplemented\n");
1930 CKsProxy::KsRemoveAggregate(
1931 REFGUID AggregateClass
)
1933 #ifdef KSPROXY_TRACE
1934 OutputDebugStringW(L
"CKsProxy::KsRemoveAggregate NotImplemented\n");
1941 //-------------------------------------------------------------------
1942 // IPersistStream interface
1949 #ifdef KSPROXY_TRACE
1950 OutputDebugStringW(L
"CKsProxy::IsDirty Notimplemented\n");
1962 AM_MEDIA_TYPE MediaType
;
1963 ULONG BytesReturned
;
1967 LPOLESTR pMajor
, pSub
, pFormat
;
1969 #ifdef KSPROXY_TRACE
1970 OutputDebugStringW(L
"CKsProxy::Load\n");
1974 ULONG Version
= ReadInt(pStm
, hr
);
1979 hr
= pStm
->Read(&Length
, sizeof(ULONG
), &BytesReturned
);
1980 swprintf(Buffer
, L
"Length hr %x hr length %lu\n", hr
, Length
);
1981 OutputDebugStringW(Buffer
);
1985 hr
= pStm
->Read(&PinId
, sizeof(ULONG
), &BytesReturned
);
1986 swprintf(Buffer
, L
"Read: hr %08x PinId %lx BytesReturned %lu\n", hr
, PinId
, BytesReturned
);
1987 OutputDebugStringW(Buffer
);
1989 if (FAILED(hr
) || !BytesReturned
)
1992 Length
-= BytesReturned
;
1994 hr
= pStm
->Read(&MediaType
, sizeof(AM_MEDIA_TYPE
), &BytesReturned
);
1995 if (FAILED(hr
) || BytesReturned
!= sizeof(AM_MEDIA_TYPE
))
1997 swprintf(Buffer
, L
"Read failed with %lx\n", hr
);
1998 OutputDebugStringW(Buffer
);
2003 StringFromIID(MediaType
.majortype
, &pMajor
);
2004 StringFromIID(MediaType
.subtype
, &pSub
);
2005 StringFromIID(MediaType
.formattype
, &pFormat
);
2007 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
);
2008 OutputDebugStringW(Buffer
);
2010 Length
-= BytesReturned
;
2013 if (MediaType
.cbFormat
)
2015 MediaType
.pbFormat
= (BYTE
*)CoTaskMemAlloc(MediaType
.cbFormat
);
2016 if (!MediaType
.pbFormat
)
2017 return E_OUTOFMEMORY
;
2019 hr
= pStm
->Read(&MediaType
.pbFormat
, sizeof(MediaType
.cbFormat
), &BytesReturned
);
2022 swprintf(Buffer
, L
"ReadFormat failed with %lx\n", hr
);
2023 OutputDebugStringW(Buffer
);
2026 Length
-= BytesReturned
;
2040 #ifdef KSPROXY_TRACE
2041 OutputDebugStringW(L
"CKsProxy::Save Notimplemented\n");
2049 CKsProxy::GetSizeMax(
2050 ULARGE_INTEGER
*pcbSize
)
2052 #ifdef KSPROXY_TRACE
2053 OutputDebugStringW(L
"CKsProxy::GetSizeMax Notimplemented\n");
2059 //-------------------------------------------------------------------
2060 // IAMDeviceRemoval interface
2065 CKsProxy::DeviceInfo(CLSID
*pclsidInterfaceClass
, LPWSTR
*pwszSymbolicLink
)
2067 #ifdef KSPROXY_TRACE
2068 OutputDebugStringW(L
"CKsProxy::DeviceInfo\n");
2073 // object not initialized
2074 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_FILE_NOT_FOUND
);
2077 // copy device interface guid
2078 CopyMemory(pclsidInterfaceClass
, &m_DeviceInterfaceGUID
, sizeof(GUID
));
2080 if (pwszSymbolicLink
)
2082 *pwszSymbolicLink
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_DevicePath
)+1) * sizeof(WCHAR
));
2083 if (!*pwszSymbolicLink
)
2084 return E_OUTOFMEMORY
;
2086 wcscpy(*pwszSymbolicLink
, m_DevicePath
);
2092 CKsProxy::Reassociate(void)
2094 #ifdef KSPROXY_TRACE
2095 OutputDebugStringW(L
"CKsProxy::Reassociate\n");
2098 if (!m_DevicePath
|| m_hDevice
)
2100 // file path not available
2101 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_FILE_NOT_FOUND
);
2104 m_hDevice
= CreateFileW(m_DevicePath
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2107 // failed to open device
2108 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2117 CKsProxy::Disassociate(void)
2119 #ifdef KSPROXY_TRACE
2120 OutputDebugStringW(L
"CKsProxy::Disassociate\n");
2126 CloseHandle(m_hDevice
);
2131 //-------------------------------------------------------------------
2132 // IKsClock interface
2137 CKsProxy::KsGetClockHandle()
2139 #ifdef KSPROXY_TRACE
2140 OutputDebugStringW(L
"CKsProxy::KsGetClockHandle\n");
2147 //-------------------------------------------------------------------
2148 // IKsObject interface
2153 CKsProxy::KsGetObjectHandle()
2155 #ifdef KSPROXY_TRACE
2156 OutputDebugStringW(L
"CKsProxy::KsGetObjectHandle\n");
2162 //-------------------------------------------------------------------
2163 // IPersistPropertyBag interface
2167 CKsProxy::InitNew( void)
2169 #ifdef KSPROXY_TRACE
2170 OutputDebugStringW(L
"CKsProxy::InitNew\n");
2178 CKsProxy::GetSupportedSets(
2182 KSPROPERTY Property
;
2184 ULONG NumProperty
= 0;
2185 ULONG NumMethods
= 0;
2186 ULONG NumEvents
= 0;
2188 ULONG BytesReturned
;
2191 Property
.Set
= GUID_NULL
;
2193 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
2195 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumProperty
);
2196 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumMethods
);
2197 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumEvents
);
2199 Length
= NumProperty
+ NumMethods
+ NumEvents
;
2201 // allocate guid buffer
2202 pGuid
= (LPGUID
)CoTaskMemAlloc(Length
);
2206 return E_OUTOFMEMORY
;
2209 NumProperty
/= sizeof(GUID
);
2210 NumMethods
/= sizeof(GUID
);
2211 NumEvents
/= sizeof(GUID
);
2213 // get all properties
2214 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pGuid
, Length
, &BytesReturned
);
2217 CoTaskMemFree(pGuid
);
2220 Length
-= BytesReturned
;
2225 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
], Length
, &BytesReturned
);
2228 CoTaskMemFree(pGuid
);
2231 Length
-= BytesReturned
;
2237 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
+NumMethods
], Length
, &BytesReturned
);
2240 CoTaskMemFree(pGuid
);
2243 Length
-= BytesReturned
;
2246 #ifdef KSPROXY_TRACE
2248 swprintf(Buffer
, L
"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty
, NumMethods
, NumEvents
);
2249 OutputDebugStringW(Buffer
);
2253 *NumGuids
= NumProperty
+NumEvents
+NumMethods
;
2259 CKsProxy::LoadProxyPlugins(
2267 IUnknown
* pUnknown
;
2269 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
2271 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
2275 // enumerate all sets
2276 for(Index
= 0; Index
< NumGuids
; Index
++)
2278 // convert to string
2279 hr
= StringFromCLSID(pGuids
[Index
], &pStr
);
2283 // now try open class key
2284 if (RegOpenKeyExW(hKey
, pStr
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
2286 // no plugin for that set exists
2287 CoTaskMemFree(pStr
);
2292 hr
= CoCreateInstance(pGuids
[Index
], (IBaseFilter
*)this, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void**)&pUnknown
);
2296 m_Plugins
.push_back(pUnknown
);
2299 RegCloseKey(hSubKey
);
2302 // close media interfaces key
2309 CKsProxy::GetNumberOfPins(
2312 KSPROPERTY Property
;
2313 ULONG BytesReturned
;
2316 Property
.Set
= KSPROPSETID_Pin
;
2317 Property
.Id
= KSPROPERTY_PIN_CTYPES
;
2318 Property
.Flags
= KSPROPERTY_TYPE_GET
;
2320 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)NumPins
, sizeof(ULONG
), &BytesReturned
);
2325 CKsProxy::GetPinInstanceCount(
2327 PKSPIN_CINSTANCES Instances
)
2330 ULONG BytesReturned
;
2333 Property
.Property
.Set
= KSPROPSETID_Pin
;
2334 Property
.Property
.Id
= KSPROPERTY_PIN_CINSTANCES
;
2335 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2336 Property
.PinId
= PinId
;
2337 Property
.Reserved
= 0;
2339 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)Instances
, sizeof(KSPIN_CINSTANCES
), &BytesReturned
);
2344 CKsProxy::GetPinCommunication(
2346 KSPIN_COMMUNICATION
* Communication
)
2349 ULONG BytesReturned
;
2352 Property
.Property
.Set
= KSPROPSETID_Pin
;
2353 Property
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
2354 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2355 Property
.PinId
= PinId
;
2356 Property
.Reserved
= 0;
2358 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)Communication
, sizeof(KSPIN_COMMUNICATION
), &BytesReturned
);
2363 CKsProxy::GetPinDataflow(
2365 KSPIN_DATAFLOW
* DataFlow
)
2368 ULONG BytesReturned
;
2371 Property
.Property
.Set
= KSPROPSETID_Pin
;
2372 Property
.Property
.Id
= KSPROPERTY_PIN_DATAFLOW
;
2373 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2374 Property
.PinId
= PinId
;
2375 Property
.Reserved
= 0;
2377 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)DataFlow
, sizeof(KSPIN_DATAFLOW
), &BytesReturned
);
2382 CKsProxy::GetPinName(
2384 KSPIN_DATAFLOW DataFlow
,
2386 LPWSTR
* OutPinName
)
2390 ULONG BytesReturned
;
2395 Property
.Property
.Set
= KSPROPSETID_Pin
;
2396 Property
.Property
.Id
= KSPROPERTY_PIN_NAME
;
2397 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2398 Property
.PinId
= PinId
;
2399 Property
.Reserved
= 0;
2401 // #1 try get it from pin directly
2402 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
2404 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
2406 // allocate pin name
2407 PinName
= (LPWSTR
)CoTaskMemAlloc(BytesReturned
);
2409 return E_OUTOFMEMORY
;
2411 // retry with allocated buffer
2412 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), PinName
, BytesReturned
, &BytesReturned
);
2415 *OutPinName
= PinName
;
2420 CoTaskMemFree(PinName
);
2424 // TODO: retrieve pin name from topology node
2427 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2429 swprintf(Buffer
, L
"Input%lu", PinCount
);
2433 swprintf(Buffer
, L
"Output%lu", PinCount
);
2436 // allocate pin name
2437 PinName
= (LPWSTR
)CoTaskMemAlloc((wcslen(Buffer
)+1) * sizeof(WCHAR
));
2439 return E_OUTOFMEMORY
;
2442 wcscpy(PinName
, Buffer
);
2445 *OutPinName
= PinName
;
2452 CKsProxy::CreatePins()
2454 ULONG NumPins
, Index
;
2455 KSPIN_CINSTANCES Instances
;
2456 KSPIN_DATAFLOW DataFlow
;
2457 KSPIN_COMMUNICATION Communication
;
2462 ULONG OutputPin
= 0;
2464 // get number of pins
2465 hr
= GetNumberOfPins(&NumPins
);
2469 for(Index
= 0; Index
< NumPins
; Index
++)
2471 // query current instance count
2472 hr
= GetPinInstanceCount(Index
, &Instances
);
2475 #ifdef KSPROXY_TRACE
2477 swprintf(Buffer
, L
"CKsProxy::CreatePins GetPinInstanceCount failed with %lx\n", hr
);
2478 OutputDebugStringW(Buffer
);
2484 // query pin communication;
2485 hr
= GetPinCommunication(Index
, &Communication
);
2488 #ifdef KSPROXY_TRACE
2490 swprintf(Buffer
, L
"CKsProxy::CreatePins GetPinCommunication failed with %lx\n", hr
);
2491 OutputDebugStringW(Buffer
);
2496 if (Instances
.CurrentCount
== Instances
.PossibleCount
)
2498 // already maximum reached for this pin
2499 #ifdef KSPROXY_TRACE
2501 swprintf(Buffer
, L
"CKsProxy::CreatePins Instances.CurrentCount == Instances.PossibleCount\n");
2502 OutputDebugStringW(Buffer
);
2507 // get direction of pin
2508 hr
= GetPinDataflow(Index
, &DataFlow
);
2511 #ifdef KSPROXY_TRACE
2513 swprintf(Buffer
, L
"CKsProxy::CreatePins GetPinDataflow failed with %lx\n", hr
);
2514 OutputDebugStringW(Buffer
);
2519 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2520 hr
= GetPinName(Index
, DataFlow
, InputPin
, &PinName
);
2522 hr
= GetPinName(Index
, DataFlow
, OutputPin
, &PinName
);
2526 #ifdef KSPROXY_TRACE
2528 swprintf(Buffer
, L
"CKsProxy::CreatePins GetPinName failed with %lx\n", hr
);
2529 OutputDebugStringW(Buffer
);
2534 // construct the pins
2535 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2537 hr
= CInputPin_Constructor((IBaseFilter
*)this, PinName
, m_hDevice
, Index
, Communication
, IID_IPin
, (void**)&pPin
);
2540 #ifdef KSPROXY_TRACE
2542 swprintf(Buffer
, L
"CKsProxy::CreatePins CInputPin_Constructor failed with %lx\n", hr
);
2543 OutputDebugStringW(Buffer
);
2545 CoTaskMemFree(PinName
);
2552 hr
= COutputPin_Constructor((IBaseFilter
*)this, PinName
, Index
, Communication
, IID_IPin
, (void**)&pPin
);
2555 #ifdef KSPROXY_TRACE
2557 swprintf(Buffer
, L
"CKsProxy::CreatePins COutputPin_Constructor failed with %lx\n", hr
);
2558 OutputDebugStringW(Buffer
);
2560 CoTaskMemFree(PinName
);
2567 m_Pins
.push_back(pPin
);
2569 #ifdef KSPROXY_TRACE
2571 swprintf(Buffer
, L
"Index %lu DataFlow %lu Name %s\n", Index
, DataFlow
, PinName
);
2572 OutputDebugStringW(Buffer
);
2582 CKsProxy::Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
)
2589 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
2591 #ifdef KSPROXY_TRACE
2593 OutputDebugStringW(L
"CKsProxy::Load\n");
2597 varName
.vt
= VT_BSTR
;
2598 hr
= pPropBag
->Read(L
"DevicePath", &varName
, pErrorLog
);
2602 #ifdef KSPROXY_TRACE
2603 swprintf(Buffer
, L
"CKsProxy::Load Read %lx\n", hr
);
2604 OutputDebugStringW(Buffer
);
2606 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2609 #ifdef KSPROXY_TRACE
2610 OutputDebugStringW(L
"DevicePath: ");
2611 OutputDebugStringW(varName
.bstrVal
);
2612 OutputDebugStringW(L
"\n");
2615 // create device list
2616 hList
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
2617 if (hList
== INVALID_HANDLE_VALUE
)
2619 // failed to create device list
2620 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2623 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
2624 if (!SetupDiOpenDeviceInterfaceW(hList
, (PCWSTR
)varName
.bstrVal
, 0, &DeviceInterfaceData
))
2626 // failed to open device interface
2627 SetupDiDestroyDeviceInfoList(hList
);
2630 // FIXME handle device interface links(aliases)
2631 CopyMemory(&m_DeviceInterfaceGUID
, &DeviceInterfaceData
.InterfaceClassGuid
, sizeof(GUID
));
2633 // close device info list
2634 SetupDiDestroyDeviceInfoList(hList
);
2637 m_hDevice
= CreateFileW(varName
.bstrVal
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2639 if (m_hDevice
== INVALID_HANDLE_VALUE
)
2641 // failed to open device
2642 #ifdef KSPROXY_TRACE
2643 swprintf(Buffer
, L
"CKsProxy:: failed to open device with %lx\n", GetLastError());
2644 OutputDebugStringW(Buffer
);
2646 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2649 // store device path
2650 m_DevicePath
= varName
.bstrVal
;
2652 // get all supported sets
2653 hr
= GetSupportedSets(&pGuid
, &NumGuids
);
2656 CloseHandle(m_hDevice
);
2661 // load all proxy plugins
2662 hr
= LoadProxyPlugins(pGuid
, NumGuids
);
2666 CloseHandle(m_hDevice
);
2670 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed!\n");
2674 CoTaskMemFree(pGuid
);
2676 // now create the input / output pins
2679 #ifdef KSPROXY_TRACE
2680 swprintf(Buffer
, L
"CKsProxy::Load CreatePins %lx\n", hr
);
2681 OutputDebugStringW(Buffer
);
2692 CKsProxy::Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
)
2694 #ifdef KSPROXY_TRACE
2695 OutputDebugStringW(L
"CKsProxy::Save\n");
2700 //-------------------------------------------------------------------
2701 // IBaseFilter interface
2706 CKsProxy::GetClassID(
2709 #ifdef KSPROXY_TRACE
2710 OutputDebugStringW(L
"CKsProxy::GetClassID\n");
2712 CopyMemory(pClassID
, &CLSID_Proxy
, sizeof(GUID
));
2723 #ifdef KSPROXY_TRACE
2724 OutputDebugStringW(L
"CKsProxy::Stop\n");
2727 EnterCriticalSection(&m_Lock
);
2729 hr
= SetPinState(KSSTATE_STOP
);
2731 m_FilterState
= State_Stopped
;
2733 LeaveCriticalSection(&m_Lock
);
2744 #ifdef KSPROXY_TRACE
2745 OutputDebugStringW(L
"CKsProxy::Pause\n");
2748 EnterCriticalSection(&m_Lock
);
2750 if (m_FilterState
== State_Running
)
2752 hr
= SetPinState(KSSTATE_STOP
);
2756 if (m_FilterState
== State_Stopped
)
2758 hr
= SetPinState(KSSTATE_PAUSE
);
2763 m_FilterState
= State_Paused
;
2765 LeaveCriticalSection(&m_Lock
);
2773 REFERENCE_TIME tStart
)
2777 #ifdef KSPROXY_TRACE
2778 OutputDebugStringW(L
"CKsProxy::Run\n");
2781 EnterCriticalSection(&m_Lock
);
2783 if (m_FilterState
== State_Stopped
)
2785 LeaveCriticalSection(&m_Lock
);
2786 // setting filter state to pause
2791 EnterCriticalSection(&m_Lock
);
2792 assert(m_FilterState
== State_Paused
);
2795 hr
= SetPinState(KSSTATE_RUN
);
2799 m_FilterState
= State_Running
;
2802 LeaveCriticalSection(&m_Lock
);
2808 CKsProxy::SetPinState(
2814 ULONG BytesReturned
;
2815 KSPROPERTY Property
;
2818 Property
.Set
= KSPROPSETID_Connection
;
2819 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
2820 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2822 // set all pins to running state
2823 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
2825 IPin
* Pin
= m_Pins
[Index
];
2829 //check if the pin is connected
2831 hr
= Pin
->ConnectedTo(&TempPin
);
2834 // skip unconnected pins
2838 // release connected pin
2841 // query for the pin info
2842 hr
= Pin
->QueryPinInfo(&PinInfo
);
2846 if (PinInfo
.pFilter
)
2847 PinInfo
.pFilter
->Release();
2849 if (PinInfo
.dir
== PINDIR_OUTPUT
)
2851 hr
= COutputPin_SetState(Pin
, State
);
2857 //query IKsObject interface
2858 hr
= Pin
->QueryInterface(IID_IKsObject
, (void**)&pObject
);
2861 HANDLE hPin
= pObject
->KsGetObjectHandle();
2864 assert(hPin
&& hPin
!= INVALID_HANDLE_VALUE
);
2867 hr
= KsSynchronousDeviceControl(hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
2869 #ifdef KSPROXY_TRACE
2871 swprintf(Buffer
, L
"CKsProxy::SetPinState Index %u State %u hr %lx\n", Index
, State
, hr
);
2872 OutputDebugStringW(Buffer
);
2884 DWORD dwMilliSecsTimeout
,
2885 FILTER_STATE
*State
)
2890 *State
= m_FilterState
;
2896 CKsProxy::SetSyncSource(
2897 IReferenceClock
*pClock
)
2901 HANDLE hClock
, hPin
;
2904 IKsObject
* pObject
;
2905 KSPROPERTY Property
;
2906 ULONG BytesReturned
;
2907 PIN_DIRECTION PinDir
;
2909 #ifdef KSPROXY_TRACE
2910 OutputDebugStringW(L
"CKsProxy::SetSyncSource\n");
2918 hr
= pClock
->QueryInterface(IID_IKsClock
, (void**)&pKsClock
);
2921 hr
= m_ReferenceClock
->QueryInterface(IID_IKsClock
, (void**)&pKsClock
);
2927 hClock
= pKsClock
->KsGetClockHandle();
2929 // release IKsClock interface
2930 pKsClock
->Release();
2940 // distribute clock to all pins
2941 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
2944 pin
= m_Pins
[Index
];
2948 // get IKsObject interface
2949 hr
= pin
->QueryInterface(IID_IKsObject
, (void **)&pObject
);
2953 hPin
= pObject
->KsGetObjectHandle();
2954 if (hPin
!= INVALID_HANDLE_VALUE
&& hPin
)
2957 Property
.Set
= KSPROPSETID_Stream
;
2958 Property
.Id
= KSPROPERTY_STREAM_MASTERCLOCK
;
2959 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2962 hr
= KsSynchronousDeviceControl(hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&m_hClock
, sizeof(HANDLE
), &BytesReturned
);
2966 if (hr
!= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
) &&
2967 hr
!= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
))
2969 // failed to set master clock
2972 swprintf(Buffer
, L
"CKsProxy::SetSyncSource KSPROPERTY_STREAM_MASTERCLOCK failed with %lx\n", hr
);
2973 OutputDebugStringW(Buffer
);
2978 // release IKsObject
2982 // now get the direction
2983 hr
= pin
->QueryDirection(&PinDir
);
2986 if (PinDir
== PINDIR_OUTPUT
)
2989 //CBaseStreamControl::SetSyncSource(pClock)
2999 if (m_ReferenceClock
)
3001 m_ReferenceClock
->Release();
3004 m_ReferenceClock
= pClock
;
3005 #ifdef KSPROXY_TRACE
3006 OutputDebugStringW(L
"CKsProxy::SetSyncSource done\n");
3013 CKsProxy::GetSyncSource(
3014 IReferenceClock
**pClock
)
3016 #ifdef KSPROXY_TRACE
3017 OutputDebugStringW(L
"CKsProxy::GetSyncSource\n");
3023 if (m_ReferenceClock
)
3024 m_ReferenceClock
->AddRef();
3026 *pClock
= m_ReferenceClock
;
3035 return CEnumPins_fnConstructor(m_Pins
, IID_IEnumPins
, (void**)ppEnum
);
3041 LPCWSTR Id
, IPin
**ppPin
)
3045 #ifdef KSPROXY_TRACE
3046 OutputDebugStringW(L
"CKsProxy::FindPin\n");
3053 int ret
= swscanf(Id
, L
"%u", &PinId
);
3055 if (!ret
|| ret
== EOF
)
3058 return VFW_E_NOT_FOUND
;
3061 if (PinId
>= m_Pins
.size() || m_Pins
[PinId
] == NULL
)
3064 return VFW_E_NOT_FOUND
;
3068 *ppPin
= m_Pins
[PinId
];
3069 m_Pins
[PinId
]->AddRef();
3077 CKsProxy::QueryFilterInfo(
3083 #ifdef KSPROXY_TRACE
3084 OutputDebugStringW(L
"CKsProxy::QueryFilterInfo\n");
3087 pInfo
->achName
[0] = L
'\0';
3088 pInfo
->pGraph
= m_pGraph
;
3098 CKsProxy::JoinFilterGraph(
3099 IFilterGraph
*pGraph
,
3102 #ifdef KSPROXY_TRACE
3104 swprintf(Buffer
, L
"CKsProxy::JoinFilterGraph pName %s pGraph %p m_Ref %u\n", pName
, pGraph
, m_Ref
);
3105 OutputDebugStringW(Buffer
);
3110 // joining filter graph
3125 CKsProxy::QueryVendorInfo(
3126 LPWSTR
*pVendorInfo
)
3128 #ifdef KSPROXY_TRACE
3129 OutputDebugStringW(L
"CKsProxy::QueryVendorInfo\n");
3131 return StringFromCLSID(CLSID_Proxy
, pVendorInfo
);
3134 //-------------------------------------------------------------------
3135 // IAMovieSetup interface
3140 CKsProxy::Register()
3142 #ifdef KSPROXY_TRACE
3143 OutputDebugStringW(L
"CKsProxy::Register : NotImplemented\n");
3151 CKsProxy::Unregister()
3153 #ifdef KSPROXY_TRACE
3154 OutputDebugStringW(L
"CKsProxy::Unregister : NotImplemented\n");
3161 CKsProxy_Constructor(
3162 IUnknown
* pUnkOuter
,
3166 #ifdef KSPROXY_TRACE
3169 StringFromCLSID(riid
, &pstr
);
3170 swprintf(Buffer
, L
"CKsProxy_Constructor pUnkOuter %p riid %s\n", pUnkOuter
, pstr
);
3171 OutputDebugStringW(Buffer
);
3174 CKsProxy
* handler
= new CKsProxy();
3177 return E_OUTOFMEMORY
;
3179 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
3183 return E_NOINTERFACE
;