2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp
5 * PURPOSE: WaveCyclic Port Driver
6 * PROGRAMMER: Johannes Anderwald
11 GUID IID_IDmaChannelSlave
;
13 class CPortWaveCyclic
: public IPortWaveCyclic
,
18 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
20 STDMETHODIMP_(ULONG
) AddRef()
22 InterlockedIncrement(&m_Ref
);
25 STDMETHODIMP_(ULONG
) Release()
27 InterlockedDecrement(&m_Ref
);
38 CPortWaveCyclic(IUnknown
*OuterUnknown
){}
39 virtual ~CPortWaveCyclic(){}
42 PDEVICE_OBJECT m_pDeviceObject
;
43 PMINIPORTWAVECYCLIC m_pMiniport
;
44 PPINCOUNT m_pPinCount
;
45 PPOWERNOTIFY m_pPowerNotify
;
46 PPCFILTER_DESCRIPTOR m_pDescriptor
;
47 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor
;
48 IPortFilterWaveCyclic
* m_Filter
;
52 friend PMINIPORTWAVECYCLIC
GetWaveCyclicMiniport(IN IPortWaveCyclic
* iface
);
53 friend PDEVICE_OBJECT
GetDeviceObject(PPORTWAVECYCLIC iface
);
56 GUID KSPROPERTY_SETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
58 static GUID InterfaceGuids
[4] =
62 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
66 0x65E8773EL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
69 /// KSCATEGORY_CAPTURE
70 0x65E8773DL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
73 ///KSCATEGORY_AUDIO_DEVICE
74 0xFBF6F530L
, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}
79 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWaveCyclicTopologySet
, TopologyPropertyHandler
);
80 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWaveCyclicPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
82 KSPROPERTY_SET WaveCyclicPropertySet
[] =
85 &KSPROPSETID_Topology
,
86 sizeof(PortFilterWaveCyclicTopologySet
) / sizeof(KSPROPERTY_ITEM
),
87 (const KSPROPERTY_ITEM
*)&PortFilterWaveCyclicTopologySet
,
93 sizeof(PortFilterWaveCyclicPinSet
) / sizeof(KSPROPERTY_ITEM
),
94 (const KSPROPERTY_ITEM
*)&PortFilterWaveCyclicPinSet
,
100 //KSEVENTSETID_LoopedStreaming, Type = KSEVENT_LOOPEDSTREAMING_POSITION
101 //KSEVENTSETID_Connection, Type = KSEVENT_CONNECTION_ENDOFSTREAM,
104 //---------------------------------------------------------------
110 CPortWaveCyclic::AddEventToEventList(
111 IN PKSEVENT_ENTRY EventEntry
)
119 CPortWaveCyclic::GenerateEventList(
120 IN GUID
* Set OPTIONAL
,
130 //---------------------------------------------------------------
131 // IUnknown interface functions
136 CPortWaveCyclic::QueryInterface(
140 UNICODE_STRING GuidString
;
142 if (IsEqualGUIDAligned(refiid
, IID_IPortWaveCyclic
) ||
143 IsEqualGUIDAligned(refiid
, IID_IPort
) ||
144 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
146 *Output
= PVOID(PPORTWAVECYCLIC(this));
147 PUNKNOWN(*Output
)->AddRef();
148 return STATUS_SUCCESS
;
150 else if (IsEqualGUIDAligned(refiid
, IID_IPortEvents
))
152 *Output
= PVOID(PPORTEVENTS(this));
153 PUNKNOWN(*Output
)->AddRef();
154 return STATUS_SUCCESS
;
156 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
158 *Output
= PVOID(PSUBDEVICE(this));
159 PUNKNOWN(*Output
)->AddRef();
160 return STATUS_SUCCESS
;
162 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
164 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
166 else if (IsEqualGUIDAligned(refiid
, IID_IDrmPort
) ||
167 IsEqualGUIDAligned(refiid
, IID_IDrmPort2
))
169 return NewIDrmPort((PDRMPORT2
*)Output
);
171 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
173 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
175 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
177 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
180 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
182 DPRINT("IPortWaveCyclic_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
183 RtlFreeUnicodeString(&GuidString
);
186 return STATUS_UNSUCCESSFUL
;
189 //---------------------------------------------------------------
190 // IPort interface functions
195 CPortWaveCyclic::GetDeviceProperty(
196 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
197 IN ULONG BufferLength
,
198 OUT PVOID PropertyBuffer
,
199 OUT PULONG ReturnLength
)
201 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
203 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
208 CPortWaveCyclic::Init(
209 IN PDEVICE_OBJECT DeviceObject
,
211 IN PUNKNOWN UnknownMiniport
,
212 IN PUNKNOWN UnknownAdapter OPTIONAL
,
213 IN PRESOURCELIST ResourceList
)
215 IMiniportWaveCyclic
* Miniport
;
218 PPOWERNOTIFY PowerNotify
;
220 DPRINT("IPortWaveCyclic_Init entered %p\n", this);
221 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
223 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportWaveCyclic
, (PVOID
*)&Miniport
);
224 if (!NT_SUCCESS(Status
))
226 DPRINT("IPortWaveCyclic_Init called with invalid IMiniport adapter\n");
227 return STATUS_INVALID_PARAMETER
;
230 // Initialize port object
231 m_pMiniport
= Miniport
;
232 m_pDeviceObject
= DeviceObject
;
234 // initialize miniport
235 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this);
236 if (!NT_SUCCESS(Status
))
238 DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status
);
244 // get the miniport device descriptor
245 Status
= Miniport
->GetDescription(&m_pDescriptor
);
246 if (!NT_SUCCESS(Status
))
248 DPRINT("failed to get description\n");
253 // create the subdevice descriptor
254 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
260 WaveCyclicPropertySet
,
269 if (!NT_SUCCESS(Status
))
271 DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
276 // store for node property requests
277 m_SubDeviceDescriptor
->UnknownMiniport
= UnknownMiniport
;
279 // check if it supports IPinCount interface
280 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
281 if (NT_SUCCESS(Status
))
283 // store IPinCount interface
284 m_pPinCount
= PinCount
;
287 // does the Miniport adapter support IPowerNotify interface*/
288 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
289 if (NT_SUCCESS(Status
))
292 m_pPowerNotify
= PowerNotify
;
295 DPRINT("IPortWaveCyclic successfully initialized\n");
296 return STATUS_SUCCESS
;
302 CPortWaveCyclic::NewRegistryKey(
303 OUT PREGISTRYKEY
*OutRegistryKey
,
304 IN PUNKNOWN OuterUnknown OPTIONAL
,
305 IN ULONG RegistryKeyType
,
306 IN ACCESS_MASK DesiredAccess
,
307 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
308 IN ULONG CreateOptions OPTIONAL
,
309 OUT PULONG Disposition OPTIONAL
)
311 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
313 return PcNewRegistryKey(OutRegistryKey
, OuterUnknown
, RegistryKeyType
, DesiredAccess
, m_pDeviceObject
, (ISubdevice
*)this, ObjectAttributes
, CreateOptions
, Disposition
);
317 //---------------------------------------------------------------
318 // IPortWaveCyclic interface functions
323 CPortWaveCyclic::NewMasterDmaChannel(
324 OUT PDMACHANNEL
* DmaChannel
,
325 IN PUNKNOWN OuterUnknown
,
326 IN PRESOURCELIST ResourceList OPTIONAL
,
327 IN ULONG MaximumLength
,
328 IN BOOLEAN Dma32BitAddresses
,
329 IN BOOLEAN Dma64BitAddresses
,
330 IN DMA_WIDTH DmaWidth
,
331 IN DMA_SPEED DmaSpeed
)
334 DEVICE_DESCRIPTION DeviceDescription
;
336 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
338 Status
= PcDmaMasterDescription(ResourceList
, (Dma32BitAddresses
| Dma64BitAddresses
), Dma32BitAddresses
, 0, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, 0, &DeviceDescription
);
339 if (NT_SUCCESS(Status
))
341 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, NonPagedPool
, &DeviceDescription
, m_pDeviceObject
);
349 CPortWaveCyclic::NewSlaveDmaChannel(
350 OUT PDMACHANNELSLAVE
* OutDmaChannel
,
351 IN PUNKNOWN OuterUnknown
,
352 IN PRESOURCELIST ResourceList OPTIONAL
,
354 IN ULONG MaximumLength
,
355 IN BOOLEAN DemandMode
,
356 IN DMA_SPEED DmaSpeed
)
358 DEVICE_DESCRIPTION DeviceDescription
;
359 PDMACHANNEL DmaChannel
;
362 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
365 // Check for F-Type DMA Support
368 Status
= PcDmaSlaveDescription(ResourceList
, DmaIndex
, DemandMode
, TRUE
, DmaSpeed
, MaximumLength
, 0, &DeviceDescription
);
369 if (NT_SUCCESS(Status
))
371 Status
= PcNewDmaChannel(&DmaChannel
, OuterUnknown
, NonPagedPool
, &DeviceDescription
, m_pDeviceObject
);
372 if (NT_SUCCESS(Status
))
374 Status
= DmaChannel
->QueryInterface(IID_IDmaChannelSlave
, (PVOID
*)OutDmaChannel
);
375 DmaChannel
->Release();
384 CPortWaveCyclic::Notify(
385 IN PSERVICEGROUP ServiceGroup
)
387 ServiceGroup
->RequestService ();
390 //---------------------------------------------------------------
391 // ISubdevice interface
396 CPortWaveCyclic::NewIrpTarget(
397 OUT
struct IIrpTarget
**OutTarget
,
400 IN POOL_TYPE PoolType
,
401 IN PDEVICE_OBJECT DeviceObject
,
403 IN KSOBJECT_CREATE
*CreateObject
)
406 IPortFilterWaveCyclic
* Filter
;
408 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
410 // is there already an instance of the filter
413 // it is, let's return the result
414 *OutTarget
= (IIrpTarget
*)m_Filter
;
416 // increment reference
418 return STATUS_SUCCESS
;
421 // create new instance of filter
422 Status
= NewPortFilterWaveCyclic(&Filter
);
423 if (!NT_SUCCESS(Status
))
429 // initialize the filter
430 Status
= Filter
->Init((IPortWaveCyclic
*)this);
431 if (!NT_SUCCESS(Status
))
440 *OutTarget
= (IIrpTarget
*)Filter
;
441 // store for later re-use
450 CPortWaveCyclic::ReleaseChildren()
452 DPRINT("ISubDevice_fnReleaseChildren\n");
454 // release the filter
459 // release pincount interface
460 m_pPinCount
->Release();
465 // release power notify interface
466 m_pPowerNotify
->Release();
469 // now release the miniport
470 m_pMiniport
->Release();
472 return STATUS_SUCCESS
;
478 CPortWaveCyclic::GetDescriptor(
479 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
481 PC_ASSERT(m_SubDeviceDescriptor
!= NULL
);
483 *Descriptor
= m_SubDeviceDescriptor
;
485 DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", this, m_SubDeviceDescriptor
);
486 return STATUS_SUCCESS
;
492 CPortWaveCyclic::DataRangeIntersection(
494 IN PKSDATARANGE DataRange
,
495 IN PKSDATARANGE MatchingDataRange
,
496 IN ULONG OutputBufferLength
,
497 OUT PVOID ResultantFormat OPTIONAL
,
498 OUT PULONG ResultantFormatLength
)
500 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
504 return m_pMiniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
507 return STATUS_UNSUCCESSFUL
;
513 CPortWaveCyclic::PowerChangeNotify(
514 IN POWER_STATE PowerState
)
518 m_pPowerNotify
->PowerChangeNotify(PowerState
);
521 return STATUS_SUCCESS
;
526 CPortWaveCyclic::PinCount(
528 IN OUT PULONG FilterNecessary
,
529 IN OUT PULONG FilterCurrent
,
530 IN OUT PULONG FilterPossible
,
531 IN OUT PULONG GlobalCurrent
,
532 IN OUT PULONG GlobalPossible
)
536 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
537 return STATUS_SUCCESS
;
541 // scan filter descriptor
543 return STATUS_UNSUCCESSFUL
;
547 ///--------------------------------------------------------------
549 GetWaveCyclicMiniport(
550 IN IPortWaveCyclic
* iface
)
552 CPortWaveCyclic
* This
= (CPortWaveCyclic
*)iface
;
553 return This
->m_pMiniport
;
558 PPORTWAVECYCLIC iface
)
560 CPortWaveCyclic
* This
= (CPortWaveCyclic
*)iface
;
561 return This
->m_pDeviceObject
;
564 //---------------------------------------------------------------
565 // IPortWaveCyclic constructor
573 CPortWaveCyclic
* Port
;
575 Port
= new(NonPagedPool
, TAG_PORTCLASS
)CPortWaveCyclic(NULL
);
577 return STATUS_INSUFFICIENT_RESOURCES
;
579 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
581 if (!NT_SUCCESS(Status
))
586 DPRINT("NewPortWaveCyclic %p Status %u\n", Port
, Status
);