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 (johannes.anderwald@reactos.org)
11 const GUID IID_IPersistPropertyBag
= {0x37D84F60, 0x42CB, 0x11CE, {0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51}};
12 const GUID IID_ISpecifyPropertyPages
= {0xB196B28B, 0xBAB4, 0x101A, {0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}};
13 const GUID IID_IPersistStream
= {0x00000109, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
14 const GUID IID_IPersist
= {0x0000010c, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
15 const GUID IID_IBDA_DeviceControl
= {0xFD0A5AF3, 0xB41D, 0x11d2, {0x9C, 0x95, 0x00, 0xC0, 0x4F, 0x79, 0x71, 0xE0}};
16 const GUID IID_IKsAggregateControl
= {0x7F40EAC0, 0x3947, 0x11D2, {0x87, 0x4E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
17 const GUID IID_IKsClockPropertySet
= {0x5C5CBD84, 0xE755, 0x11D0, {0xAC, 0x18, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
18 const GUID IID_IKsTopology
= {0x28F54683, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
19 const GUID IID_IKsClock
= {0x877E4351, 0x6FEA, 0x11D0, {0xB8, 0x63, 0x00, 0xAA, 0x00, 0xA2, 0x16, 0xA1}};
21 Needs IKsClock, IKsNotifyEvent
24 class CKsProxy
: public IBaseFilter
,
26 public IPersistPropertyBag
,
28 public IPersistStream
,
29 public IAMDeviceRemoval
,
30 public ISpecifyPropertyPages
,
31 public IReferenceClock
,
33 public IKsPropertySet
,
35 public IKsClockPropertySet
,
36 public IAMFilterMiscFlags
,
39 public IKsAggregateControl
43 typedef std::vector
<IUnknown
*>ProxyPluginVector
;
44 typedef std::vector
<IPin
*> PinVector
;
46 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
48 STDMETHODIMP_(ULONG
) AddRef()
50 InterlockedIncrement(&m_Ref
);
53 STDMETHODIMP_(ULONG
) Release()
55 InterlockedDecrement(&m_Ref
);
64 // IBaseFilter methods
65 HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
66 HRESULT STDMETHODCALLTYPE
Stop( void);
67 HRESULT STDMETHODCALLTYPE
Pause( void);
68 HRESULT STDMETHODCALLTYPE
Run(REFERENCE_TIME tStart
);
69 HRESULT STDMETHODCALLTYPE
GetState(DWORD dwMilliSecsTimeout
, FILTER_STATE
*State
);
70 HRESULT STDMETHODCALLTYPE
SetSyncSource(IReferenceClock
*pClock
);
71 HRESULT STDMETHODCALLTYPE
GetSyncSource(IReferenceClock
**pClock
);
72 HRESULT STDMETHODCALLTYPE
EnumPins(IEnumPins
**ppEnum
);
73 HRESULT STDMETHODCALLTYPE
FindPin(LPCWSTR Id
, IPin
**ppPin
);
74 HRESULT STDMETHODCALLTYPE
QueryFilterInfo(FILTER_INFO
*pInfo
);
75 HRESULT STDMETHODCALLTYPE
JoinFilterGraph(IFilterGraph
*pGraph
, LPCWSTR pName
);
76 HRESULT STDMETHODCALLTYPE
QueryVendorInfo(LPWSTR
*pVendorInfo
);
79 HRESULT STDMETHODCALLTYPE
GetTime(REFERENCE_TIME
*pTime
);
80 HRESULT STDMETHODCALLTYPE
AdviseTime(REFERENCE_TIME baseTime
, REFERENCE_TIME streamTime
, HEVENT hEvent
, DWORD_PTR
*pdwAdviseCookie
);
81 HRESULT STDMETHODCALLTYPE
AdvisePeriodic(REFERENCE_TIME startTime
, REFERENCE_TIME periodTime
, HSEMAPHORE hSemaphore
, DWORD_PTR
*pdwAdviseCookie
);
82 HRESULT STDMETHODCALLTYPE
Unadvise(DWORD_PTR dwAdviseCookie
);
85 HRESULT STDMETHODCALLTYPE
GetCapabilities(DWORD
*pCapabilities
);
86 HRESULT STDMETHODCALLTYPE
CheckCapabilities(DWORD
*pCapabilities
);
87 HRESULT STDMETHODCALLTYPE
IsFormatSupported(const GUID
*pFormat
);
88 HRESULT STDMETHODCALLTYPE
QueryPreferredFormat(GUID
*pFormat
);
89 HRESULT STDMETHODCALLTYPE
GetTimeFormat(GUID
*pFormat
);
90 HRESULT STDMETHODCALLTYPE
IsUsingTimeFormat(const GUID
*pFormat
);
91 HRESULT STDMETHODCALLTYPE
SetTimeFormat(const GUID
*pFormat
);
92 HRESULT STDMETHODCALLTYPE
GetDuration(LONGLONG
*pDuration
);
93 HRESULT STDMETHODCALLTYPE
GetStopPosition(LONGLONG
*pStop
);
94 HRESULT STDMETHODCALLTYPE
GetCurrentPosition(LONGLONG
*pCurrent
);
95 HRESULT STDMETHODCALLTYPE
ConvertTimeFormat(LONGLONG
*pTarget
, const GUID
*pTargetFormat
, LONGLONG Source
, const GUID
*pSourceFormat
);
96 HRESULT STDMETHODCALLTYPE
SetPositions(LONGLONG
*pCurrent
, DWORD dwCurrentFlags
, LONGLONG
*pStop
, DWORD dwStopFlags
);
97 HRESULT STDMETHODCALLTYPE
GetPositions(LONGLONG
*pCurrent
, LONGLONG
*pStop
);
98 HRESULT STDMETHODCALLTYPE
GetAvailable(LONGLONG
*pEarliest
, LONGLONG
*pLatest
);
99 HRESULT STDMETHODCALLTYPE
SetRate(double dRate
);
100 HRESULT STDMETHODCALLTYPE
GetRate(double *pdRate
);
101 HRESULT STDMETHODCALLTYPE
GetPreroll(LONGLONG
*pllPreroll
);
104 HRESULT STDMETHODCALLTYPE
Set(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
);
105 HRESULT STDMETHODCALLTYPE
Get(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
, DWORD
*pcbReturned
);
106 HRESULT STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet
, DWORD dwPropID
, DWORD
*pTypeSupport
);
109 ULONG STDMETHODCALLTYPE
GetMiscFlags( void);
112 HRESULT STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
, ULONG DataLength
, ULONG
* BytesReturned
);
113 HRESULT STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
, ULONG DataLength
, ULONG
* BytesReturned
);
114 HRESULT STDMETHODCALLTYPE
KsEvent(PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
, ULONG DataLength
, ULONG
* BytesReturned
);
117 HRESULT STDMETHODCALLTYPE
CreateNodeInstance(ULONG NodeId
, ULONG Flags
, ACCESS_MASK DesiredAccess
, IUnknown
* UnkOuter
, REFGUID InterfaceId
, LPVOID
* Interface
);
119 //IKsAggregateControl
120 HRESULT STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass
);
121 HRESULT STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass
);
123 //IKsClockPropertySet
124 HRESULT STDMETHODCALLTYPE
KsGetTime(LONGLONG
* Time
);
125 HRESULT STDMETHODCALLTYPE
KsSetTime(LONGLONG Time
);
126 HRESULT STDMETHODCALLTYPE
KsGetPhysicalTime(LONGLONG
* Time
);
127 HRESULT STDMETHODCALLTYPE
KsSetPhysicalTime(LONGLONG Time
);
128 HRESULT STDMETHODCALLTYPE
KsGetCorrelatedTime(KSCORRELATED_TIME
* CorrelatedTime
);
129 HRESULT STDMETHODCALLTYPE
KsSetCorrelatedTime(KSCORRELATED_TIME
* CorrelatedTime
);
130 HRESULT STDMETHODCALLTYPE
KsGetCorrelatedPhysicalTime(KSCORRELATED_TIME
* CorrelatedTime
);
131 HRESULT STDMETHODCALLTYPE
KsSetCorrelatedPhysicalTime(KSCORRELATED_TIME
* CorrelatedTime
);
132 HRESULT STDMETHODCALLTYPE
KsGetResolution(KSRESOLUTION
* Resolution
);
133 HRESULT STDMETHODCALLTYPE
KsGetState(KSSTATE
* State
);
136 //IAMovieSetup methods
137 HRESULT STDMETHODCALLTYPE
Register( void);
138 HRESULT STDMETHODCALLTYPE
Unregister( void);
140 // IPersistPropertyBag methods
141 HRESULT STDMETHODCALLTYPE
InitNew( void);
142 HRESULT STDMETHODCALLTYPE
Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
);
143 HRESULT STDMETHODCALLTYPE
Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
);
146 HANDLE STDMETHODCALLTYPE
KsGetObjectHandle();
149 HANDLE STDMETHODCALLTYPE
KsGetClockHandle();
152 HRESULT STDMETHODCALLTYPE
DeviceInfo(CLSID
*pclsidInterfaceClass
, LPWSTR
*pwszSymbolicLink
);
153 HRESULT STDMETHODCALLTYPE
Reassociate(void);
154 HRESULT STDMETHODCALLTYPE
Disassociate( void);
157 HRESULT STDMETHODCALLTYPE
IsDirty( void);
158 HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
159 HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
160 HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
162 // ISpecifyPropertyPages
163 HRESULT STDMETHODCALLTYPE
GetPages(CAUUID
*pPages
);
170 CloseHandle(m_hDevice
);
173 HRESULT STDMETHODCALLTYPE
GetSupportedSets(LPGUID
* pOutGuid
, PULONG NumGuids
);
174 HRESULT STDMETHODCALLTYPE
LoadProxyPlugins(LPGUID pGuids
, ULONG NumGuids
);
175 HRESULT STDMETHODCALLTYPE
GetNumberOfPins(PULONG NumPins
);
176 HRESULT STDMETHODCALLTYPE
GetPinInstanceCount(ULONG PinId
, PKSPIN_CINSTANCES Instances
);
177 HRESULT STDMETHODCALLTYPE
GetPinDataflow(ULONG PinId
, KSPIN_DATAFLOW
* DataFlow
);
178 HRESULT STDMETHODCALLTYPE
GetPinName(ULONG PinId
, KSPIN_DATAFLOW DataFlow
, ULONG PinCount
, LPWSTR
* OutPinName
);
179 HRESULT STDMETHODCALLTYPE
GetPinCommunication(ULONG PinId
, KSPIN_COMMUNICATION
* Communication
);
180 HRESULT STDMETHODCALLTYPE
CreatePins();
181 HRESULT STDMETHODCALLTYPE
GetMediaSeekingFormats(PKSMULTIPLE_ITEM
*FormatList
);
182 HRESULT STDMETHODCALLTYPE
CreateClockInstance();
183 HRESULT STDMETHODCALLTYPE
PerformClockProperty(ULONG PropertyId
, ULONG PropertyFlags
, PVOID OutputBuffer
, ULONG OutputBufferSize
);
184 HRESULT STDMETHODCALLTYPE
SetPinState(KSSTATE State
);
189 IFilterGraph
*m_pGraph
;
190 IReferenceClock
* m_ReferenceClock
;
191 FILTER_STATE m_FilterState
;
193 ProxyPluginVector m_Plugins
;
196 CLSID m_DeviceInterfaceGUID
;
198 CRITICAL_SECTION m_Lock
;
201 CKsProxy::CKsProxy() : m_Ref(0),
203 m_FilterState(State_Stopped
),
210 m_ReferenceClock
= this;
211 InitializeCriticalSection(&m_Lock
);
217 CKsProxy::QueryInterface(
223 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
224 IsEqualGUID(refiid
, IID_IBaseFilter
))
226 *Output
= PVOID(this);
227 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
230 else if (IsEqualGUID(refiid
, IID_IPersistPropertyBag
))
232 *Output
= (IPersistPropertyBag
*)(this);
233 reinterpret_cast<IPersistPropertyBag
*>(*Output
)->AddRef();
236 else if (IsEqualGUID(refiid
, IID_IAMDeviceRemoval
))
238 *Output
= (IAMDeviceRemoval
*)(this);
239 reinterpret_cast<IAMDeviceRemoval
*>(*Output
)->AddRef();
242 else if (IsEqualGUID(refiid
, IID_IPersistStream
))
244 *Output
= (IPersistStream
*)(this);
245 reinterpret_cast<IPersistStream
*>(*Output
)->AddRef();
248 else if (IsEqualGUID(refiid
, IID_IPersist
))
250 *Output
= (IPersistStream
*)(this);
251 reinterpret_cast<IPersist
*>(*Output
)->AddRef();
254 else if (IsEqualGUID(refiid
, IID_IKsObject
))
256 *Output
= (IKsObject
*)(this);
257 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
260 else if (IsEqualGUID(refiid
, IID_IKsClock
))
262 *Output
= (IKsClock
*)(this);
263 reinterpret_cast<IKsClock
*>(*Output
)->AddRef();
266 else if (IsEqualGUID(refiid
, IID_IReferenceClock
))
270 HRESULT hr
= CreateClockInstance();
275 *Output
= (IReferenceClock
*)(this);
276 reinterpret_cast<IReferenceClock
*>(*Output
)->AddRef();
279 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
281 *Output
= (IMediaSeeking
*)(this);
282 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
285 else if (IsEqualGUID(refiid
, IID_IAMFilterMiscFlags
))
287 *Output
= (IAMFilterMiscFlags
*)(this);
288 reinterpret_cast<IAMFilterMiscFlags
*>(*Output
)->AddRef();
291 else if (IsEqualGUID(refiid
, IID_IKsControl
))
293 *Output
= (IKsControl
*)(this);
294 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
297 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
299 *Output
= (IKsPropertySet
*)(this);
300 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
303 else if (IsEqualGUID(refiid
, IID_IKsTopology
))
305 *Output
= (IKsTopology
*)(this);
306 reinterpret_cast<IKsTopology
*>(*Output
)->AddRef();
309 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
311 *Output
= (IKsAggregateControl
*)(this);
312 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
315 else if (IsEqualGUID(refiid
, IID_IKsClockPropertySet
))
319 HRESULT hr
= CreateClockInstance();
324 *Output
= (IKsClockPropertySet
*)(this);
325 reinterpret_cast<IKsClockPropertySet
*>(*Output
)->AddRef();
328 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
330 *Output
= (ISpecifyPropertyPages
*)(this);
331 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
335 for(ULONG Index
= 0; Index
< m_Plugins
.size(); Index
++)
339 HRESULT hr
= m_Plugins
[Index
]->QueryInterface(refiid
, Output
);
345 StringFromCLSID(refiid
, &lpstr
);
346 swprintf(Buffer
, L
"CKsProxy::QueryInterface plugin %lu supports interface %s\n", Index
, lpstr
);
347 OutputDebugStringW(Buffer
);
348 CoTaskMemFree(lpstr
);
355 WCHAR Buffer
[MAX_PATH
];
357 StringFromCLSID(refiid
, &lpstr
);
358 swprintf(Buffer
, L
"CKsProxy::QueryInterface: NoInterface for %s !!!\n", lpstr
);
359 OutputDebugStringW(Buffer
);
360 CoTaskMemFree(lpstr
);
363 return E_NOINTERFACE
;
366 //-------------------------------------------------------------------
367 // ISpecifyPropertyPages
372 CKsProxy::GetPages(CAUUID
*pPages
)
375 OutputDebugStringW(L
"CKsProxy::GetPages NotImplemented\n");
382 pPages
->pElems
= NULL
;
387 //-------------------------------------------------------------------
388 // IKsClockPropertySet interface
393 CKsProxy::CreateClockInstance()
396 HANDLE hPin
= INVALID_HANDLE_VALUE
;
398 PIN_DIRECTION PinDir
;
400 KSCLOCK_CREATE ClockCreate
;
402 // find output pin and handle
403 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
406 IPin
* pin
= m_Pins
[Index
];
411 hr
= pin
->QueryDirection(&PinDir
);
415 // query IKsObject interface
416 hr
= pin
->QueryInterface(IID_IKsObject
, (void**)&pObject
);
422 hPin
= pObject
->KsGetObjectHandle();
427 if (hPin
!= INVALID_HANDLE_VALUE
)
431 if (hPin
== INVALID_HANDLE_VALUE
)
433 // clock can only be instantiated on a pin handle
439 // release clock handle
440 CloseHandle(m_hClock
);
443 //setup clock create request
444 ClockCreate
.CreateFlags
= 0;
446 // setup clock create request
447 hr
= KsCreateClock(hPin
, &ClockCreate
, &m_hClock
); // FIXME KsCreateClock returns NTSTATUS
450 // failed to create clock
451 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
459 CKsProxy::PerformClockProperty(
463 ULONG OutputBufferSize
)
472 hr
= CreateClockInstance();
478 Property
.Set
= KSPROPSETID_Clock
;
479 Property
.Id
= PropertyId
;
480 Property
.Flags
= PropertyFlags
;
482 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)OutputBuffer
, OutputBufferSize
, &BytesReturned
);
493 OutputDebugStringW(L
"CKsProxy::KsGetTime\n");
496 return PerformClockProperty(KSPROPERTY_CLOCK_TIME
, KSPROPERTY_TYPE_GET
, (PVOID
)Time
, sizeof(LONGLONG
));
505 OutputDebugStringW(L
"CKsProxy::KsSetTime\n");
508 return PerformClockProperty(KSPROPERTY_CLOCK_TIME
, KSPROPERTY_TYPE_SET
, (PVOID
)&Time
, sizeof(LONGLONG
));
513 CKsProxy::KsGetPhysicalTime(
517 OutputDebugStringW(L
"CKsProxy::KsGetPhysicalTime\n");
520 return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)Time
, sizeof(LONGLONG
));
525 CKsProxy::KsSetPhysicalTime(
529 OutputDebugStringW(L
"CKsProxy::KsSetPhysicalTime\n");
532 return PerformClockProperty(KSPROPERTY_CLOCK_PHYSICALTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)&Time
, sizeof(LONGLONG
));
537 CKsProxy::KsGetCorrelatedTime(
538 KSCORRELATED_TIME
* CorrelatedTime
)
541 OutputDebugStringW(L
"CKsProxy::KsGetCorrelatedTime\n");
544 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
549 CKsProxy::KsSetCorrelatedTime(
550 KSCORRELATED_TIME
* CorrelatedTime
)
553 OutputDebugStringW(L
"CKsProxy::KsSetCorrelatedTime\n");
555 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
560 CKsProxy::KsGetCorrelatedPhysicalTime(
561 KSCORRELATED_TIME
* CorrelatedTime
)
564 OutputDebugStringW(L
"CKsProxy::KsGetCorrelatedPhysicalTime\n");
566 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME
, KSPROPERTY_TYPE_GET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
571 CKsProxy::KsSetCorrelatedPhysicalTime(
572 KSCORRELATED_TIME
* CorrelatedTime
)
575 OutputDebugStringW(L
"CKsProxy::KsSetCorrelatedPhysicalTime\n");
578 return PerformClockProperty(KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME
, KSPROPERTY_TYPE_SET
, (PVOID
)CorrelatedTime
, sizeof(KSCORRELATED_TIME
));
583 CKsProxy::KsGetResolution(
584 KSRESOLUTION
* Resolution
)
587 OutputDebugStringW(L
"CKsProxy::KsGetResolution\n");
589 return PerformClockProperty(KSPROPERTY_CLOCK_RESOLUTION
, KSPROPERTY_TYPE_GET
, (PVOID
)Resolution
, sizeof(KSRESOLUTION
));
594 CKsProxy::KsGetState(
598 OutputDebugStringW(L
"CKsProxy::KsGetState\n");
600 return PerformClockProperty(KSPROPERTY_CLOCK_STATE
, KSPROPERTY_TYPE_GET
, (PVOID
)State
, sizeof(KSSTATE
));
603 //-------------------------------------------------------------------
604 // IReferenceClock interface
609 REFERENCE_TIME
*pTime
)
616 OutputDebugStringW(L
"CKsProxy::GetTime\n");
629 hr
= CreateClockInstance();
635 Property
.Set
= KSPROPSETID_Clock
;
636 Property
.Id
= KSPROPERTY_CLOCK_TIME
;
637 Property
.Flags
= KSPROPERTY_TYPE_GET
;
640 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pTime
, sizeof(REFERENCE_TIME
), &BytesReturned
);
651 CKsProxy::AdviseTime(
652 REFERENCE_TIME baseTime
,
653 REFERENCE_TIME streamTime
,
655 DWORD_PTR
*pdwAdviseCookie
)
660 PKSEVENT_TIME_MARK Event
;
663 OutputDebugStringW(L
"CKsProxy::AdviseTime\n");
670 if (!pdwAdviseCookie
)
676 hr
= CreateClockInstance();
681 // allocate event entry
682 Event
= (PKSEVENT_TIME_MARK
)CoTaskMemAlloc(sizeof(KSEVENT_TIME_MARK
));
686 Property
.Set
= KSEVENTSETID_Clock
;
687 Property
.Id
= KSEVENT_CLOCK_POSITION_MARK
;
688 Property
.Flags
= KSEVENT_TYPE_ENABLE
;
690 Event
->EventData
.NotificationType
= KSEVENTF_EVENT_HANDLE
;
691 Event
->EventData
.EventHandle
.Event
= (HANDLE
)hEvent
;
692 Event
->EventData
.Alignment
.Alignment
[0] = 0;
693 Event
->EventData
.Alignment
.Alignment
[1] = 0;
694 Event
->MarkTime
= baseTime
+ streamTime
;
697 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSEVENT
), (PVOID
)Event
, sizeof(KSEVENT_TIME_MARK
), &BytesReturned
);
700 // store event handle
701 *pdwAdviseCookie
= (DWORD_PTR
)Event
;
705 // failed to enable event
706 CoTaskMemFree(Event
);
719 CKsProxy::AdvisePeriodic(
720 REFERENCE_TIME startTime
,
721 REFERENCE_TIME periodTime
,
722 HSEMAPHORE hSemaphore
,
723 DWORD_PTR
*pdwAdviseCookie
)
728 PKSEVENT_TIME_INTERVAL Event
;
731 OutputDebugStringW(L
"CKsProxy::AdvisePeriodic\n");
738 if (!pdwAdviseCookie
)
744 hr
= CreateClockInstance();
749 // allocate event entry
750 Event
= (PKSEVENT_TIME_INTERVAL
)CoTaskMemAlloc(sizeof(KSEVENT_TIME_INTERVAL
));
754 Property
.Set
= KSEVENTSETID_Clock
;
755 Property
.Id
= KSEVENT_CLOCK_INTERVAL_MARK
;
756 Property
.Flags
= KSEVENT_TYPE_ENABLE
;
758 Event
->EventData
.NotificationType
= KSEVENTF_SEMAPHORE_HANDLE
;
759 Event
->EventData
.SemaphoreHandle
.Semaphore
= (HANDLE
)hSemaphore
;
760 Event
->EventData
.SemaphoreHandle
.Reserved
= 0;
761 Event
->EventData
.SemaphoreHandle
.Adjustment
= 1;
762 Event
->TimeBase
= startTime
;
763 Event
->Interval
= periodTime
;
766 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSEVENT
), (PVOID
)Event
, sizeof(KSEVENT_TIME_INTERVAL
), &BytesReturned
);
769 // store event handle
770 *pdwAdviseCookie
= (DWORD_PTR
)Event
;
774 // failed to enable event
775 CoTaskMemFree(Event
);
789 DWORD_PTR dwAdviseCookie
)
795 OutputDebugStringW(L
"CKsProxy::Unadvise\n");
800 //lets disable the event
801 hr
= KsSynchronousDeviceControl(m_hClock
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)dwAdviseCookie
, sizeof(KSEVENTDATA
), 0, 0, &BytesReturned
);
804 // lets free event data
805 CoTaskMemFree((LPVOID
)dwAdviseCookie
);
810 // no clock available
817 //-------------------------------------------------------------------
818 // IMediaSeeking interface
822 CKsProxy::GetCapabilities(
823 DWORD
*pCapabilities
)
826 ULONG BytesReturned
, Index
;
830 Property
.Set
= KSPROPSETID_MediaSeeking
;
831 Property
.Id
= KSPROPERTY_MEDIASEEKING_CAPABILITIES
;
832 Property
.Flags
= KSPROPERTY_TYPE_GET
;
835 OutputDebugStringW(L
"CKsProxy::GetCapabilities\n");
843 *pCapabilities
= (KS_SEEKING_CanSeekAbsolute
| KS_SEEKING_CanSeekForwards
| KS_SEEKING_CanSeekBackwards
| KS_SEEKING_CanGetCurrentPos
|
844 KS_SEEKING_CanGetStopPos
| KS_SEEKING_CanGetDuration
| KS_SEEKING_CanPlayBackwards
);
846 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pCapabilities
, sizeof(KS_SEEKING_CAPABILITIES
), &BytesReturned
);
847 // check if plugins support it
848 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
851 IUnknown
* Plugin
= m_Plugins
[Index
];
856 // query for IMediaSeeking interface
857 IMediaSeeking
*pSeek
= NULL
;
858 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
867 hr
= pSeek
->GetCapabilities(&TempCaps
);
870 // and with supported flags
871 *pCapabilities
= (*pCapabilities
& TempCaps
);
873 // release IMediaSeeking interface
881 CKsProxy::CheckCapabilities(
882 DWORD
*pCapabilities
)
888 OutputDebugStringW(L
"CKsProxy::CheckCapabilities\n");
897 hr
= GetCapabilities(&Capabilities
);
900 if ((Capabilities
| *pCapabilities
) == Capabilities
)
906 Capabilities
= (Capabilities
& *pCapabilities
);
910 *pCapabilities
= Capabilities
;
913 // no capabilities are present
922 CKsProxy::GetMediaSeekingFormats(
923 PKSMULTIPLE_ITEM
*FormatList
)
929 Property
.Set
= KSPROPSETID_MediaSeeking
;
930 Property
.Id
= KSPROPERTY_MEDIASEEKING_FORMATS
;
931 Property
.Flags
= KSPROPERTY_TYPE_GET
;
933 // query for format size list
934 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &BytesReturned
);
936 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
938 // allocate format list
939 *FormatList
= (PKSMULTIPLE_ITEM
)CoTaskMemAlloc(BytesReturned
);
943 return E_OUTOFMEMORY
;
947 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)*FormatList
, BytesReturned
, &BytesReturned
);
950 // failed to query format list
951 CoTaskMemFree(FormatList
);
959 CKsProxy::IsFormatSupported(
962 PKSMULTIPLE_ITEM FormatList
;
965 HRESULT hr
= S_FALSE
;
970 StringFromCLSID(*pFormat
, &pstr
);
971 swprintf(Buffer
, L
"CKsProxy::IsFormatSupported %s\n",pstr
);
972 OutputDebugStringW(Buffer
);
979 hr
= GetMediaSeekingFormats(&FormatList
);
983 swprintf(Buffer
, L
"CKsProxy::IsFormatSupported NumFormat %lu\n",FormatList
->Count
);
984 OutputDebugStringW(Buffer
);
987 //iterate through format list
988 pGuid
= (LPGUID
)(FormatList
+ 1);
989 for(Index
= 0; Index
< FormatList
->Count
; Index
++)
991 if (IsEqualGUID(*pGuid
, *pFormat
))
993 CoTaskMemFree(FormatList
);
999 CoTaskMemFree(FormatList
);
1002 // check if all plugins support it
1003 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1006 IUnknown
* Plugin
= m_Plugins
[Index
];
1011 // query for IMediaSeeking interface
1012 IMediaSeeking
*pSeek
= NULL
;
1013 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1016 // plugin does not support interface
1018 #ifdef KSPROXY_TRACE
1019 OutputDebugStringW(L
"CKsProxy::IsFormatSupported plugin does not support IMediaSeeking interface\n");
1024 // query if it is supported
1025 hr
= pSeek
->IsFormatSupported(pFormat
);
1026 // release interface
1029 if (FAILED(hr
) || hr
== S_FALSE
)
1038 CKsProxy::QueryPreferredFormat(
1041 PKSMULTIPLE_ITEM FormatList
;
1045 #ifdef KSPROXY_TRACE
1046 OutputDebugStringW(L
"CKsProxy::QueryPreferredFormat\n");
1052 hr
= GetMediaSeekingFormats(&FormatList
);
1055 if (FormatList
->Count
)
1057 CopyMemory(pFormat
, (FormatList
+ 1), sizeof(GUID
));
1058 CoTaskMemFree(FormatList
);
1061 CoTaskMemFree(FormatList
);
1063 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1065 // check if plugins support it
1066 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1069 IUnknown
* Plugin
= m_Plugins
[Index
];
1074 // query for IMediaSeeking interface
1075 IMediaSeeking
*pSeek
= NULL
;
1076 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1079 // get preferred time format
1080 hr
= pSeek
->QueryPreferredFormat(pFormat
);
1081 // release IMediaSeeking interface
1096 CKsProxy::GetTimeFormat(
1099 KSPROPERTY Property
;
1100 ULONG BytesReturned
, Index
;
1103 Property
.Set
= KSPROPSETID_MediaSeeking
;
1104 Property
.Id
= KSPROPERTY_MEDIASEEKING_TIMEFORMAT
;
1105 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1107 #ifdef KSPROXY_TRACE
1108 OutputDebugStringW(L
"CKsProxy::GetTimeFormat\n");
1111 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pFormat
, sizeof(GUID
), &BytesReturned
);
1112 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1114 // check if plugins support it
1115 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1119 IUnknown
* Plugin
= m_Plugins
[Index
];
1124 // query for IMediaSeeking interface
1125 IMediaSeeking
*pSeek
= NULL
;
1126 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1130 hr
= pSeek
->GetTimeFormat(pFormat
);
1131 // release IMediaSeeking interface
1144 CKsProxy::IsUsingTimeFormat(
1145 const GUID
*pFormat
)
1149 #ifdef KSPROXY_TRACE
1150 OutputDebugStringW(L
"CKsProxy::IsUsingTimeFormat\n");
1153 if (FAILED(QueryPreferredFormat(&Format
)))
1156 if (IsEqualGUID(Format
, *pFormat
))
1164 CKsProxy::SetTimeFormat(
1165 const GUID
*pFormat
)
1167 KSPROPERTY Property
;
1168 ULONG BytesReturned
, Index
;
1171 Property
.Set
= KSPROPSETID_MediaSeeking
;
1172 Property
.Id
= KSPROPERTY_MEDIASEEKING_TIMEFORMAT
;
1173 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1175 #ifdef KSPROXY_TRACE
1176 OutputDebugStringW(L
"CKsProxy::SetTimeFormat\n");
1179 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pFormat
, sizeof(GUID
), &BytesReturned
);
1180 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1182 // check if plugins support it
1183 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1187 IUnknown
* Plugin
= m_Plugins
[Index
];
1192 // query for IMediaSeeking interface
1193 IMediaSeeking
*pSeek
= NULL
;
1194 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1201 hr
= pSeek
->SetTimeFormat(pFormat
);
1202 // release IMediaSeeking interface
1214 CKsProxy::GetDuration(
1215 LONGLONG
*pDuration
)
1217 KSPROPERTY Property
;
1218 ULONG BytesReturned
, Index
;
1221 Property
.Set
= KSPROPSETID_MediaSeeking
;
1222 Property
.Id
= KSPROPERTY_MEDIASEEKING_DURATION
;
1223 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1225 #ifdef KSPROXY_TRACE
1226 OutputDebugStringW(L
"CKsProxy::GetDuration\n");
1229 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pDuration
, sizeof(LONGLONG
), &BytesReturned
);
1230 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1232 // check if plugins support it
1233 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1237 IUnknown
* Plugin
= m_Plugins
[Index
];
1242 // query for IMediaSeeking interface
1243 IMediaSeeking
*pSeek
= NULL
;
1244 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1248 hr
= pSeek
->GetStopPosition(pDuration
);
1249 // release IMediaSeeking interface
1252 if (hr
!= S_FALSE
) // plugin implements it
1262 CKsProxy::GetStopPosition(
1265 KSPROPERTY Property
;
1266 ULONG BytesReturned
, Index
;
1269 Property
.Set
= KSPROPSETID_MediaSeeking
;
1270 Property
.Id
= KSPROPERTY_MEDIASEEKING_STOPPOSITION
;
1271 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1273 #ifdef KSPROXY_TRACE
1274 OutputDebugStringW(L
"CKsProxy::GetStopPosition\n");
1277 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pStop
, sizeof(LONGLONG
), &BytesReturned
);
1278 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1280 // check if plugins support it
1281 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1285 IUnknown
* Plugin
= m_Plugins
[Index
];
1290 // query for IMediaSeeking interface
1291 IMediaSeeking
*pSeek
= NULL
;
1292 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1295 // get stop position
1296 hr
= pSeek
->GetStopPosition(pStop
);
1297 // release IMediaSeeking interface
1300 if (hr
!= S_FALSE
) // plugin implements it
1310 CKsProxy::GetCurrentPosition(
1313 KSPROPERTY Property
;
1314 ULONG BytesReturned
, Index
;
1317 Property
.Set
= KSPROPSETID_MediaSeeking
;
1318 Property
.Id
= KSPROPERTY_MEDIASEEKING_POSITION
;
1319 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1321 #ifdef KSPROXY_TRACE
1322 OutputDebugStringW(L
"CKsProxy::GetCurrentPosition\n");
1325 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pCurrent
, sizeof(LONGLONG
), &BytesReturned
);
1326 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1328 // check if plugins support it
1329 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1333 IUnknown
* Plugin
= m_Plugins
[Index
];
1338 // query for IMediaSeeking interface
1339 IMediaSeeking
*pSeek
= NULL
;
1340 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1343 // get current position
1344 hr
= pSeek
->GetCurrentPosition(pCurrent
);
1345 // release IMediaSeeking interface
1348 if (hr
!= S_FALSE
) // plugin implements it
1358 CKsProxy::ConvertTimeFormat(
1360 const GUID
*pTargetFormat
,
1362 const GUID
*pSourceFormat
)
1364 KSP_TIMEFORMAT Property
;
1365 ULONG BytesReturned
, Index
;
1366 GUID SourceFormat
, TargetFormat
;
1369 Property
.Property
.Set
= KSPROPSETID_MediaSeeking
;
1370 Property
.Property
.Id
= KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT
;
1371 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
1373 #ifdef KSPROXY_TRACE
1374 OutputDebugStringW(L
"CKsProxy::ConvertTimeFormat\n");
1379 // get current format
1380 hr
= GetTimeFormat(&TargetFormat
);
1384 pTargetFormat
= &TargetFormat
;
1389 // get current format
1390 hr
= GetTimeFormat(&SourceFormat
);
1394 pSourceFormat
= &SourceFormat
;
1397 Property
.SourceFormat
= *pSourceFormat
;
1398 Property
.TargetFormat
= *pTargetFormat
;
1399 Property
.Time
= Source
;
1402 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_TIMEFORMAT
), (PVOID
)pTarget
, sizeof(LONGLONG
), &BytesReturned
);
1403 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1408 // check if plugins support it
1409 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1412 IUnknown
* Plugin
= m_Plugins
[Index
];
1417 // query for IMediaSeeking interface
1418 IMediaSeeking
*pSeek
= NULL
;
1419 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1422 // convert time format
1423 hr
= pSeek
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
1424 // release IMediaSeeking interface
1427 if (hr
!= S_FALSE
) // plugin implements it
1438 CKsProxy::SetPositions(
1440 DWORD dwCurrentFlags
,
1444 KSPROPERTY Property
;
1445 KSPROPERTY_POSITIONS Positions
;
1446 ULONG BytesReturned
, Index
;
1449 Property
.Set
= KSPROPSETID_MediaSeeking
;
1450 Property
.Id
= KSPROPERTY_MEDIASEEKING_POSITIONS
;
1451 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1453 Positions
.Current
= *pCurrent
;
1454 Positions
.CurrentFlags
= (KS_SEEKING_FLAGS
)dwCurrentFlags
;
1455 Positions
.Stop
= *pStop
;
1456 Positions
.StopFlags
= (KS_SEEKING_FLAGS
)dwStopFlags
;
1458 #ifdef KSPROXY_TRACE
1459 OutputDebugStringW(L
"CKsProxy::SetPositions\n");
1462 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Positions
, sizeof(KSPROPERTY_POSITIONS
), &BytesReturned
);
1465 if (dwCurrentFlags
& AM_SEEKING_ReturnTime
)
1467 // retrieve current position
1468 hr
= GetCurrentPosition(pCurrent
);
1473 if (dwStopFlags
& AM_SEEKING_ReturnTime
)
1475 // retrieve current position
1476 hr
= GetStopPosition(pStop
);
1481 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1485 // check if plugins support it
1486 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1489 IUnknown
* Plugin
= m_Plugins
[Index
];
1494 // query for IMediaSeeking interface
1495 IMediaSeeking
*pSeek
= NULL
;
1496 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1500 hr
= pSeek
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
1501 // release IMediaSeeking interface
1515 CKsProxy::GetPositions(
1521 #ifdef KSPROXY_TRACE
1522 OutputDebugStringW(L
"CKsProxy::GetPositions\n");
1525 hr
= GetCurrentPosition(pCurrent
);
1527 hr
= GetStopPosition(pStop
);
1534 CKsProxy::GetAvailable(
1535 LONGLONG
*pEarliest
,
1538 KSPROPERTY Property
;
1539 KSPROPERTY_MEDIAAVAILABLE Media
;
1540 ULONG BytesReturned
, Index
;
1543 Property
.Set
= KSPROPSETID_MediaSeeking
;
1544 Property
.Id
= KSPROPERTY_MEDIASEEKING_AVAILABLE
;
1545 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1547 #ifdef KSPROXY_TRACE
1548 OutputDebugStringW(L
"CKsProxy::GetAvailable\n");
1551 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Media
, sizeof(KSPROPERTY_MEDIAAVAILABLE
), &BytesReturned
);
1552 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1554 // check if plugins support it
1555 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1559 IUnknown
* Plugin
= m_Plugins
[Index
];
1564 // query for IMediaSeeking interface
1565 IMediaSeeking
*pSeek
= NULL
;
1566 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1570 hr
= pSeek
->GetAvailable(pEarliest
, pLatest
);
1571 // release IMediaSeeking interface
1574 if (hr
!= S_FALSE
) // plugin implements it
1579 else if (SUCCEEDED(hr
))
1581 *pEarliest
= Media
.Earliest
;
1582 *pLatest
= Media
.Latest
;
1593 #ifdef KSPROXY_TRACE
1594 OutputDebugStringW(L
"CKsProxy::SetRate\n");
1604 #ifdef KSPROXY_TRACE
1605 OutputDebugStringW(L
"CKsProxy::GetRate\n");
1612 CKsProxy::GetPreroll(
1613 LONGLONG
*pllPreroll
)
1615 KSPROPERTY Property
;
1616 ULONG BytesReturned
, Index
;
1619 Property
.Set
= KSPROPSETID_MediaSeeking
;
1620 Property
.Id
= KSPROPERTY_MEDIASEEKING_PREROLL
;
1621 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1623 #ifdef KSPROXY_TRACE
1624 OutputDebugStringW(L
"CKsProxy::GetPreroll\n");
1627 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pllPreroll
, sizeof(LONGLONG
), &BytesReturned
);
1628 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
) || hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
))
1630 // check if all plugins support it
1631 for(Index
= 0; Index
< m_Plugins
.size(); Index
++)
1634 IUnknown
* Plugin
= m_Plugins
[Index
];
1639 // query for IMediaSeeking interface
1640 IMediaSeeking
*pSeek
= NULL
;
1641 hr
= Plugin
->QueryInterface(IID_IMediaSeeking
, (void**)&pSeek
);
1645 hr
= pSeek
->GetPreroll(pllPreroll
);
1646 // release IMediaSeeking interface
1649 if (hr
!= S_FALSE
) // plugin implements it
1658 //-------------------------------------------------------------------
1659 // IAMFilterMiscFlags interface
1664 CKsProxy::GetMiscFlags()
1669 PIN_DIRECTION PinDirection
;
1670 KSPIN_COMMUNICATION Communication
;
1673 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
1676 IPin
* pin
= m_Pins
[Index
];
1678 hr
= pin
->QueryDirection(&PinDirection
);
1681 if (PinDirection
== PINDIR_INPUT
)
1683 if (SUCCEEDED(GetPinCommunication(Index
, //FIXME verify PinId
1686 if (Communication
!= KSPIN_COMMUNICATION_NONE
&& Communication
!= KSPIN_COMMUNICATION_BRIDGE
)
1688 Flags
|= AM_FILTER_MISC_FLAGS_IS_SOURCE
;
1695 #ifdef KSPROXY_TRACE
1697 swprintf(Buffer
, L
"CKsProxy::GetMiscFlags stub Flags %x\n", Flags
);
1698 OutputDebugStringW(Buffer
);
1704 //-------------------------------------------------------------------
1709 CKsProxy::KsProperty(
1710 PKSPROPERTY Property
,
1711 ULONG PropertyLength
,
1712 LPVOID PropertyData
,
1714 ULONG
* BytesReturned
)
1716 #ifdef KSPROXY_TRACE
1717 OutputDebugStringW(L
"CKsProxy::KsProperty\n");
1720 assert(m_hDevice
!= 0);
1721 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1731 ULONG
* BytesReturned
)
1733 #ifdef KSPROXY_TRACE
1734 OutputDebugStringW(L
"CKsProxy::KsMethod\n");
1737 assert(m_hDevice
!= 0);
1738 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1748 ULONG
* BytesReturned
)
1750 #ifdef KSPROXY_TRACE
1751 OutputDebugStringW(L
"CKsProxy::KsEvent\n");
1754 assert(m_hDevice
!= 0);
1756 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1758 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1762 //-------------------------------------------------------------------
1768 REFGUID guidPropSet
,
1770 LPVOID pInstanceData
,
1771 DWORD cbInstanceData
,
1775 ULONG BytesReturned
;
1777 #ifdef KSPROXY_TRACE
1778 OutputDebugStringW(L
"CKsProxy::Set\n");
1783 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1785 return E_OUTOFMEMORY
;
1787 Property
->Set
= guidPropSet
;
1788 Property
->Id
= dwPropID
;
1789 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1791 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1793 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1794 CoTaskMemFree(Property
);
1799 KSPROPERTY Property
;
1801 Property
.Set
= guidPropSet
;
1802 Property
.Id
= dwPropID
;
1803 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1805 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1813 REFGUID guidPropSet
,
1815 LPVOID pInstanceData
,
1816 DWORD cbInstanceData
,
1821 ULONG BytesReturned
;
1823 #ifdef KSPROXY_TRACE
1824 OutputDebugStringW(L
"CKsProxy::Get\n");
1829 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1831 return E_OUTOFMEMORY
;
1833 Property
->Set
= guidPropSet
;
1834 Property
->Id
= dwPropID
;
1835 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1837 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1839 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1840 CoTaskMemFree(Property
);
1845 KSPROPERTY Property
;
1847 Property
.Set
= guidPropSet
;
1848 Property
.Id
= dwPropID
;
1849 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1851 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1858 CKsProxy::QuerySupported(
1859 REFGUID guidPropSet
,
1861 DWORD
*pTypeSupport
)
1863 KSPROPERTY Property
;
1864 ULONG BytesReturned
;
1866 #ifdef KSPROXY_TRACE
1867 OutputDebugStringW(L
"CKsProxy::QuerySupported\n");
1870 Property
.Set
= guidPropSet
;
1871 Property
.Id
= dwPropID
;
1872 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1874 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1878 //-------------------------------------------------------------------
1879 // IKsTopology interface
1883 CKsProxy::CreateNodeInstance(
1886 ACCESS_MASK DesiredAccess
,
1888 REFGUID InterfaceId
,
1893 #ifdef KSPROXY_TRACE
1894 OutputDebugStringW(L
"CKsProxy::CreateNodeInstance\n");
1899 if (IsEqualIID(IID_IUnknown
, InterfaceId
) || !UnkOuter
)
1901 hr
= CKsNode_Constructor(UnkOuter
, m_hDevice
, NodeId
, DesiredAccess
, InterfaceId
, Interface
);
1905 // interface not supported
1912 //-------------------------------------------------------------------
1913 // IKsAggregateControl interface
1917 CKsProxy::KsAddAggregate(
1918 IN REFGUID AggregateClass
)
1920 #ifdef KSPROXY_TRACE
1921 OutputDebugStringW(L
"CKsProxy::KsAddAggregate NotImplemented\n");
1928 CKsProxy::KsRemoveAggregate(
1929 REFGUID AggregateClass
)
1931 #ifdef KSPROXY_TRACE
1932 OutputDebugStringW(L
"CKsProxy::KsRemoveAggregate NotImplemented\n");
1939 //-------------------------------------------------------------------
1940 // IPersistStream interface
1947 #ifdef KSPROXY_TRACE
1948 OutputDebugStringW(L
"CKsProxy::IsDirty Notimplemented\n");
1960 AM_MEDIA_TYPE MediaType
;
1961 ULONG BytesReturned
;
1965 LPOLESTR pMajor
, pSub
, pFormat
;
1967 #ifdef KSPROXY_TRACE
1968 OutputDebugStringW(L
"CKsProxy::Load\n");
1972 ULONG Version
= ReadInt(pStm
, hr
);
1977 hr
= pStm
->Read(&Length
, sizeof(ULONG
), &BytesReturned
);
1978 swprintf(Buffer
, L
"Length hr %x hr length %lu\n", hr
, Length
);
1979 OutputDebugStringW(Buffer
);
1983 hr
= pStm
->Read(&PinId
, sizeof(ULONG
), &BytesReturned
);
1984 swprintf(Buffer
, L
"Read: hr %08x PinId %lx BytesReturned %lu\n", hr
, PinId
, BytesReturned
);
1985 OutputDebugStringW(Buffer
);
1987 if (FAILED(hr
) || !BytesReturned
)
1990 Length
-= BytesReturned
;
1992 hr
= pStm
->Read(&MediaType
, sizeof(AM_MEDIA_TYPE
), &BytesReturned
);
1993 if (FAILED(hr
) || BytesReturned
!= sizeof(AM_MEDIA_TYPE
))
1995 swprintf(Buffer
, L
"Read failed with %lx\n", hr
);
1996 OutputDebugStringW(Buffer
);
2001 StringFromIID(MediaType
.majortype
, &pMajor
);
2002 StringFromIID(MediaType
.subtype
, &pSub
);
2003 StringFromIID(MediaType
.formattype
, &pFormat
);
2005 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
);
2006 OutputDebugStringW(Buffer
);
2008 Length
-= BytesReturned
;
2011 if (MediaType
.cbFormat
)
2013 MediaType
.pbFormat
= (BYTE
*)CoTaskMemAlloc(MediaType
.cbFormat
);
2014 if (!MediaType
.pbFormat
)
2015 return E_OUTOFMEMORY
;
2017 hr
= pStm
->Read(&MediaType
.pbFormat
, sizeof(MediaType
.cbFormat
), &BytesReturned
);
2020 swprintf(Buffer
, L
"ReadFormat failed with %lx\n", hr
);
2021 OutputDebugStringW(Buffer
);
2024 Length
-= BytesReturned
;
2038 #ifdef KSPROXY_TRACE
2039 OutputDebugStringW(L
"CKsProxy::Save Notimplemented\n");
2047 CKsProxy::GetSizeMax(
2048 ULARGE_INTEGER
*pcbSize
)
2050 #ifdef KSPROXY_TRACE
2051 OutputDebugStringW(L
"CKsProxy::GetSizeMax Notimplemented\n");
2057 //-------------------------------------------------------------------
2058 // IAMDeviceRemoval interface
2063 CKsProxy::DeviceInfo(CLSID
*pclsidInterfaceClass
, LPWSTR
*pwszSymbolicLink
)
2065 #ifdef KSPROXY_TRACE
2066 OutputDebugStringW(L
"CKsProxy::DeviceInfo\n");
2071 // object not initialized
2072 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_FILE_NOT_FOUND
);
2075 // copy device interface guid
2076 CopyMemory(pclsidInterfaceClass
, &m_DeviceInterfaceGUID
, sizeof(GUID
));
2078 if (pwszSymbolicLink
)
2080 *pwszSymbolicLink
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_DevicePath
)+1) * sizeof(WCHAR
));
2081 if (!*pwszSymbolicLink
)
2082 return E_OUTOFMEMORY
;
2084 wcscpy(*pwszSymbolicLink
, m_DevicePath
);
2090 CKsProxy::Reassociate(void)
2092 #ifdef KSPROXY_TRACE
2093 OutputDebugStringW(L
"CKsProxy::Reassociate\n");
2096 if (!m_DevicePath
|| m_hDevice
)
2098 // file path not available
2099 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_FILE_NOT_FOUND
);
2102 m_hDevice
= CreateFileW(m_DevicePath
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2105 // failed to open device
2106 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2115 CKsProxy::Disassociate(void)
2117 #ifdef KSPROXY_TRACE
2118 OutputDebugStringW(L
"CKsProxy::Disassociate\n");
2124 CloseHandle(m_hDevice
);
2129 //-------------------------------------------------------------------
2130 // IKsClock interface
2135 CKsProxy::KsGetClockHandle()
2137 #ifdef KSPROXY_TRACE
2138 OutputDebugStringW(L
"CKsProxy::KsGetClockHandle\n");
2145 //-------------------------------------------------------------------
2146 // IKsObject interface
2151 CKsProxy::KsGetObjectHandle()
2153 #ifdef KSPROXY_TRACE
2154 OutputDebugStringW(L
"CKsProxy::KsGetObjectHandle\n");
2160 //-------------------------------------------------------------------
2161 // IPersistPropertyBag interface
2165 CKsProxy::InitNew( void)
2167 #ifdef KSPROXY_TRACE
2168 OutputDebugStringW(L
"CKsProxy::InitNew\n");
2176 CKsProxy::GetSupportedSets(
2180 KSPROPERTY Property
;
2182 ULONG NumProperty
= 0;
2183 ULONG NumMethods
= 0;
2184 ULONG NumEvents
= 0;
2186 ULONG BytesReturned
;
2189 Property
.Set
= GUID_NULL
;
2191 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
2193 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumProperty
);
2194 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumMethods
);
2195 KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumEvents
);
2197 Length
= NumProperty
+ NumMethods
+ NumEvents
;
2199 // allocate guid buffer
2200 pGuid
= (LPGUID
)CoTaskMemAlloc(Length
);
2204 return E_OUTOFMEMORY
;
2207 NumProperty
/= sizeof(GUID
);
2208 NumMethods
/= sizeof(GUID
);
2209 NumEvents
/= sizeof(GUID
);
2211 // get all properties
2212 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pGuid
, Length
, &BytesReturned
);
2215 CoTaskMemFree(pGuid
);
2218 Length
-= BytesReturned
;
2223 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
], Length
, &BytesReturned
);
2226 CoTaskMemFree(pGuid
);
2229 Length
-= BytesReturned
;
2235 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
+NumMethods
], Length
, &BytesReturned
);
2238 CoTaskMemFree(pGuid
);
2241 Length
-= BytesReturned
;
2244 #ifdef KSPROXY_TRACE
2246 swprintf(Buffer
, L
"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty
, NumMethods
, NumEvents
);
2247 OutputDebugStringW(Buffer
);
2251 *NumGuids
= NumProperty
+NumEvents
+NumMethods
;
2257 CKsProxy::LoadProxyPlugins(
2265 IUnknown
* pUnknown
;
2267 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
2269 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
2273 // enumerate all sets
2274 for(Index
= 0; Index
< NumGuids
; Index
++)
2276 // convert to string
2277 hr
= StringFromCLSID(pGuids
[Index
], &pStr
);
2281 // now try open class key
2282 if (RegOpenKeyExW(hKey
, pStr
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
2284 // no plugin for that set exists
2285 CoTaskMemFree(pStr
);
2290 hr
= CoCreateInstance(pGuids
[Index
], (IBaseFilter
*)this, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void**)&pUnknown
);
2294 m_Plugins
.push_back(pUnknown
);
2297 RegCloseKey(hSubKey
);
2300 // close media interfaces key
2307 CKsProxy::GetNumberOfPins(
2310 KSPROPERTY Property
;
2311 ULONG BytesReturned
;
2314 Property
.Set
= KSPROPSETID_Pin
;
2315 Property
.Id
= KSPROPERTY_PIN_CTYPES
;
2316 Property
.Flags
= KSPROPERTY_TYPE_GET
;
2318 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)NumPins
, sizeof(ULONG
), &BytesReturned
);
2323 CKsProxy::GetPinInstanceCount(
2325 PKSPIN_CINSTANCES Instances
)
2328 ULONG BytesReturned
;
2331 Property
.Property
.Set
= KSPROPSETID_Pin
;
2332 Property
.Property
.Id
= KSPROPERTY_PIN_CINSTANCES
;
2333 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2334 Property
.PinId
= PinId
;
2335 Property
.Reserved
= 0;
2337 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)Instances
, sizeof(KSPIN_CINSTANCES
), &BytesReturned
);
2342 CKsProxy::GetPinCommunication(
2344 KSPIN_COMMUNICATION
* Communication
)
2347 ULONG BytesReturned
;
2350 Property
.Property
.Set
= KSPROPSETID_Pin
;
2351 Property
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
2352 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2353 Property
.PinId
= PinId
;
2354 Property
.Reserved
= 0;
2356 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)Communication
, sizeof(KSPIN_COMMUNICATION
), &BytesReturned
);
2361 CKsProxy::GetPinDataflow(
2363 KSPIN_DATAFLOW
* DataFlow
)
2366 ULONG BytesReturned
;
2369 Property
.Property
.Set
= KSPROPSETID_Pin
;
2370 Property
.Property
.Id
= KSPROPERTY_PIN_DATAFLOW
;
2371 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2372 Property
.PinId
= PinId
;
2373 Property
.Reserved
= 0;
2375 return KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)DataFlow
, sizeof(KSPIN_DATAFLOW
), &BytesReturned
);
2380 CKsProxy::GetPinName(
2382 KSPIN_DATAFLOW DataFlow
,
2384 LPWSTR
* OutPinName
)
2388 ULONG BytesReturned
;
2393 Property
.Property
.Set
= KSPROPSETID_Pin
;
2394 Property
.Property
.Id
= KSPROPERTY_PIN_NAME
;
2395 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
2396 Property
.PinId
= PinId
;
2397 Property
.Reserved
= 0;
2399 // #1 try get it from pin directly
2400 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
2402 if (hr
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
2404 // allocate pin name
2405 PinName
= (LPWSTR
)CoTaskMemAlloc(BytesReturned
);
2407 return E_OUTOFMEMORY
;
2409 // retry with allocated buffer
2410 hr
= KsSynchronousDeviceControl(m_hDevice
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), PinName
, BytesReturned
, &BytesReturned
);
2413 *OutPinName
= PinName
;
2418 CoTaskMemFree(PinName
);
2422 // TODO: retrieve pin name from topology node
2425 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2427 swprintf(Buffer
, L
"Input%lu", PinCount
);
2431 swprintf(Buffer
, L
"Output%lu", PinCount
);
2434 // allocate pin name
2435 PinName
= (LPWSTR
)CoTaskMemAlloc((wcslen(Buffer
)+1) * sizeof(WCHAR
));
2437 return E_OUTOFMEMORY
;
2440 wcscpy(PinName
, Buffer
);
2443 *OutPinName
= PinName
;
2450 CKsProxy::CreatePins()
2452 ULONG NumPins
, Index
;
2453 KSPIN_CINSTANCES Instances
;
2454 KSPIN_DATAFLOW DataFlow
;
2455 KSPIN_COMMUNICATION Communication
;
2460 ULONG OutputPin
= 0;
2462 // get number of pins
2463 hr
= GetNumberOfPins(&NumPins
);
2467 for(Index
= 0; Index
< NumPins
; Index
++)
2469 // query current instance count
2470 hr
= GetPinInstanceCount(Index
, &Instances
);
2473 #ifdef KSPROXY_TRACE
2475 swprintf(Buffer
, L
"CKsProxy::CreatePins GetPinInstanceCount failed with %lx\n", hr
);
2476 OutputDebugStringW(Buffer
);
2482 // query pin communication;
2483 hr
= GetPinCommunication(Index
, &Communication
);
2486 #ifdef KSPROXY_TRACE
2488 swprintf(Buffer
, L
"CKsProxy::CreatePins GetPinCommunication failed with %lx\n", hr
);
2489 OutputDebugStringW(Buffer
);
2494 if (Instances
.CurrentCount
== Instances
.PossibleCount
)
2496 // already maximum reached for this pin
2497 #ifdef KSPROXY_TRACE
2499 swprintf(Buffer
, L
"CKsProxy::CreatePins Instances.CurrentCount == Instances.PossibleCount\n");
2500 OutputDebugStringW(Buffer
);
2505 // get direction of pin
2506 hr
= GetPinDataflow(Index
, &DataFlow
);
2509 #ifdef KSPROXY_TRACE
2511 swprintf(Buffer
, L
"CKsProxy::CreatePins GetPinDataflow failed with %lx\n", hr
);
2512 OutputDebugStringW(Buffer
);
2517 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2518 hr
= GetPinName(Index
, DataFlow
, InputPin
, &PinName
);
2520 hr
= GetPinName(Index
, DataFlow
, OutputPin
, &PinName
);
2524 #ifdef KSPROXY_TRACE
2526 swprintf(Buffer
, L
"CKsProxy::CreatePins GetPinName failed with %lx\n", hr
);
2527 OutputDebugStringW(Buffer
);
2532 // construct the pins
2533 if (DataFlow
== KSPIN_DATAFLOW_IN
)
2535 hr
= CInputPin_Constructor((IBaseFilter
*)this, PinName
, m_hDevice
, Index
, Communication
, IID_IPin
, (void**)&pPin
);
2538 #ifdef KSPROXY_TRACE
2540 swprintf(Buffer
, L
"CKsProxy::CreatePins CInputPin_Constructor failed with %lx\n", hr
);
2541 OutputDebugStringW(Buffer
);
2543 CoTaskMemFree(PinName
);
2550 hr
= COutputPin_Constructor((IBaseFilter
*)this, PinName
, Index
, Communication
, IID_IPin
, (void**)&pPin
);
2553 #ifdef KSPROXY_TRACE
2555 swprintf(Buffer
, L
"CKsProxy::CreatePins COutputPin_Constructor failed with %lx\n", hr
);
2556 OutputDebugStringW(Buffer
);
2558 CoTaskMemFree(PinName
);
2565 m_Pins
.push_back(pPin
);
2567 #ifdef KSPROXY_TRACE
2569 swprintf(Buffer
, L
"Index %lu DataFlow %lu Name %s\n", Index
, DataFlow
, PinName
);
2570 OutputDebugStringW(Buffer
);
2580 CKsProxy::Load(IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
)
2587 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
2589 #ifdef KSPROXY_TRACE
2591 OutputDebugStringW(L
"CKsProxy::Load\n");
2595 varName
.vt
= VT_BSTR
;
2596 hr
= pPropBag
->Read(L
"DevicePath", &varName
, pErrorLog
);
2600 #ifdef KSPROXY_TRACE
2601 swprintf(Buffer
, L
"CKsProxy::Load Read %lx\n", hr
);
2602 OutputDebugStringW(Buffer
);
2604 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2607 #ifdef KSPROXY_TRACE
2608 OutputDebugStringW(L
"DevicePath: ");
2609 OutputDebugStringW(varName
.bstrVal
);
2610 OutputDebugStringW(L
"\n");
2613 // create device list
2614 hList
= SetupDiCreateDeviceInfoListExW(NULL
, NULL
, NULL
, NULL
);
2615 if (hList
== INVALID_HANDLE_VALUE
)
2617 // failed to create device list
2618 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2621 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
2622 if (!SetupDiOpenDeviceInterfaceW(hList
, (PCWSTR
)varName
.bstrVal
, 0, &DeviceInterfaceData
))
2624 // failed to open device interface
2625 SetupDiDestroyDeviceInfoList(hList
);
2628 // FIXME handle device interface links(aliases)
2629 CopyMemory(&m_DeviceInterfaceGUID
, &DeviceInterfaceData
.InterfaceClassGuid
, sizeof(GUID
));
2631 // close device info list
2632 SetupDiDestroyDeviceInfoList(hList
);
2635 m_hDevice
= CreateFileW(varName
.bstrVal
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
2637 if (m_hDevice
== INVALID_HANDLE_VALUE
)
2639 // failed to open device
2640 #ifdef KSPROXY_TRACE
2641 swprintf(Buffer
, L
"CKsProxy:: failed to open device with %lx\n", GetLastError());
2642 OutputDebugStringW(Buffer
);
2644 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
2647 // store device path
2648 m_DevicePath
= varName
.bstrVal
;
2650 // get all supported sets
2651 hr
= GetSupportedSets(&pGuid
, &NumGuids
);
2654 CloseHandle(m_hDevice
);
2659 // load all proxy plugins
2660 hr
= LoadProxyPlugins(pGuid
, NumGuids
);
2664 CloseHandle(m_hDevice
);
2668 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed!\n");
2672 CoTaskMemFree(pGuid
);
2674 // now create the input / output pins
2677 #ifdef KSPROXY_TRACE
2678 swprintf(Buffer
, L
"CKsProxy::Load CreatePins %lx\n", hr
);
2679 OutputDebugStringW(Buffer
);
2690 CKsProxy::Save(IPropertyBag
*pPropBag
, BOOL fClearDirty
, BOOL fSaveAllProperties
)
2692 #ifdef KSPROXY_TRACE
2693 OutputDebugStringW(L
"CKsProxy::Save\n");
2698 //-------------------------------------------------------------------
2699 // IBaseFilter interface
2704 CKsProxy::GetClassID(
2707 #ifdef KSPROXY_TRACE
2708 OutputDebugStringW(L
"CKsProxy::GetClassID\n");
2710 CopyMemory(pClassID
, &CLSID_Proxy
, sizeof(GUID
));
2721 #ifdef KSPROXY_TRACE
2722 OutputDebugStringW(L
"CKsProxy::Stop\n");
2725 EnterCriticalSection(&m_Lock
);
2727 hr
= SetPinState(KSSTATE_STOP
);
2729 m_FilterState
= State_Stopped
;
2731 LeaveCriticalSection(&m_Lock
);
2742 #ifdef KSPROXY_TRACE
2743 OutputDebugStringW(L
"CKsProxy::Pause\n");
2746 EnterCriticalSection(&m_Lock
);
2748 if (m_FilterState
== State_Running
)
2750 hr
= SetPinState(KSSTATE_STOP
);
2754 if (m_FilterState
== State_Stopped
)
2756 hr
= SetPinState(KSSTATE_PAUSE
);
2761 m_FilterState
= State_Paused
;
2763 LeaveCriticalSection(&m_Lock
);
2771 REFERENCE_TIME tStart
)
2775 #ifdef KSPROXY_TRACE
2776 OutputDebugStringW(L
"CKsProxy::Run\n");
2779 EnterCriticalSection(&m_Lock
);
2781 if (m_FilterState
== State_Stopped
)
2783 LeaveCriticalSection(&m_Lock
);
2784 // setting filter state to pause
2789 EnterCriticalSection(&m_Lock
);
2790 assert(m_FilterState
== State_Paused
);
2793 hr
= SetPinState(KSSTATE_RUN
);
2797 m_FilterState
= State_Running
;
2800 LeaveCriticalSection(&m_Lock
);
2806 CKsProxy::SetPinState(
2812 ULONG BytesReturned
;
2813 KSPROPERTY Property
;
2816 Property
.Set
= KSPROPSETID_Connection
;
2817 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
2818 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2820 // set all pins to running state
2821 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
2823 IPin
* Pin
= m_Pins
[Index
];
2827 //check if the pin is connected
2829 hr
= Pin
->ConnectedTo(&TempPin
);
2832 // skip unconnected pins
2836 // release connected pin
2839 // query for the pin info
2840 hr
= Pin
->QueryPinInfo(&PinInfo
);
2844 if (PinInfo
.pFilter
)
2845 PinInfo
.pFilter
->Release();
2847 if (PinInfo
.dir
== PINDIR_OUTPUT
)
2849 hr
= COutputPin_SetState(Pin
, State
);
2855 //query IKsObject interface
2856 hr
= Pin
->QueryInterface(IID_IKsObject
, (void**)&pObject
);
2859 HANDLE hPin
= pObject
->KsGetObjectHandle();
2862 assert(hPin
&& hPin
!= INVALID_HANDLE_VALUE
);
2865 hr
= KsSynchronousDeviceControl(hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
2867 #ifdef KSPROXY_TRACE
2869 swprintf(Buffer
, L
"CKsProxy::SetPinState Index %u State %u hr %lx\n", Index
, State
, hr
);
2870 OutputDebugStringW(Buffer
);
2882 DWORD dwMilliSecsTimeout
,
2883 FILTER_STATE
*State
)
2888 *State
= m_FilterState
;
2894 CKsProxy::SetSyncSource(
2895 IReferenceClock
*pClock
)
2899 HANDLE hClock
, hPin
;
2902 IKsObject
* pObject
;
2903 KSPROPERTY Property
;
2904 ULONG BytesReturned
;
2905 PIN_DIRECTION PinDir
;
2907 #ifdef KSPROXY_TRACE
2908 OutputDebugStringW(L
"CKsProxy::SetSyncSource\n");
2916 hr
= pClock
->QueryInterface(IID_IKsClock
, (void**)&pKsClock
);
2919 hr
= m_ReferenceClock
->QueryInterface(IID_IKsClock
, (void**)&pKsClock
);
2925 hClock
= pKsClock
->KsGetClockHandle();
2927 // release IKsClock interface
2928 pKsClock
->Release();
2938 // distribute clock to all pins
2939 for(Index
= 0; Index
< m_Pins
.size(); Index
++)
2942 pin
= m_Pins
[Index
];
2946 // get IKsObject interface
2947 hr
= pin
->QueryInterface(IID_IKsObject
, (void **)&pObject
);
2951 hPin
= pObject
->KsGetObjectHandle();
2952 if (hPin
!= INVALID_HANDLE_VALUE
&& hPin
)
2955 Property
.Set
= KSPROPSETID_Stream
;
2956 Property
.Id
= KSPROPERTY_STREAM_MASTERCLOCK
;
2957 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2960 hr
= KsSynchronousDeviceControl(hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&m_hClock
, sizeof(HANDLE
), &BytesReturned
);
2964 if (hr
!= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_SET_NOT_FOUND
) &&
2965 hr
!= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NOT_FOUND
))
2967 // failed to set master clock
2970 swprintf(Buffer
, L
"CKsProxy::SetSyncSource KSPROPERTY_STREAM_MASTERCLOCK failed with %lx\n", hr
);
2971 OutputDebugStringW(Buffer
);
2976 // release IKsObject
2980 // now get the direction
2981 hr
= pin
->QueryDirection(&PinDir
);
2984 if (PinDir
== PINDIR_OUTPUT
)
2987 //CBaseStreamControl::SetSyncSource(pClock)
2997 if (m_ReferenceClock
)
2999 m_ReferenceClock
->Release();
3002 m_ReferenceClock
= pClock
;
3003 #ifdef KSPROXY_TRACE
3004 OutputDebugStringW(L
"CKsProxy::SetSyncSource done\n");
3011 CKsProxy::GetSyncSource(
3012 IReferenceClock
**pClock
)
3014 #ifdef KSPROXY_TRACE
3015 OutputDebugStringW(L
"CKsProxy::GetSyncSource\n");
3021 if (m_ReferenceClock
)
3022 m_ReferenceClock
->AddRef();
3024 *pClock
= m_ReferenceClock
;
3033 return CEnumPins_fnConstructor(m_Pins
, IID_IEnumPins
, (void**)ppEnum
);
3039 LPCWSTR Id
, IPin
**ppPin
)
3043 #ifdef KSPROXY_TRACE
3044 OutputDebugStringW(L
"CKsProxy::FindPin\n");
3051 int ret
= swscanf(Id
, L
"%u", &PinId
);
3053 if (!ret
|| ret
== EOF
)
3056 return VFW_E_NOT_FOUND
;
3059 if (PinId
>= m_Pins
.size() || m_Pins
[PinId
] == NULL
)
3062 return VFW_E_NOT_FOUND
;
3066 *ppPin
= m_Pins
[PinId
];
3067 m_Pins
[PinId
]->AddRef();
3075 CKsProxy::QueryFilterInfo(
3081 #ifdef KSPROXY_TRACE
3082 OutputDebugStringW(L
"CKsProxy::QueryFilterInfo\n");
3085 pInfo
->achName
[0] = L
'\0';
3086 pInfo
->pGraph
= m_pGraph
;
3096 CKsProxy::JoinFilterGraph(
3097 IFilterGraph
*pGraph
,
3100 #ifdef KSPROXY_TRACE
3102 swprintf(Buffer
, L
"CKsProxy::JoinFilterGraph pName %s pGraph %p m_Ref %u\n", pName
, pGraph
, m_Ref
);
3103 OutputDebugStringW(Buffer
);
3108 // joining filter graph
3123 CKsProxy::QueryVendorInfo(
3124 LPWSTR
*pVendorInfo
)
3126 #ifdef KSPROXY_TRACE
3127 OutputDebugStringW(L
"CKsProxy::QueryVendorInfo\n");
3129 return StringFromCLSID(CLSID_Proxy
, pVendorInfo
);
3132 //-------------------------------------------------------------------
3133 // IAMovieSetup interface
3138 CKsProxy::Register()
3140 #ifdef KSPROXY_TRACE
3141 OutputDebugStringW(L
"CKsProxy::Register : NotImplemented\n");
3149 CKsProxy::Unregister()
3151 #ifdef KSPROXY_TRACE
3152 OutputDebugStringW(L
"CKsProxy::Unregister : NotImplemented\n");
3159 CKsProxy_Constructor(
3160 IUnknown
* pUnkOuter
,
3164 #ifdef KSPROXY_TRACE
3167 StringFromCLSID(riid
, &pstr
);
3168 swprintf(Buffer
, L
"CKsProxy_Constructor pUnkOuter %p riid %s\n", pUnkOuter
, pstr
);
3169 OutputDebugStringW(Buffer
);
3172 CKsProxy
* handler
= new CKsProxy();
3175 return E_OUTOFMEMORY
;
3177 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
3181 return E_NOINTERFACE
;