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
);
28 DPRINT1("Release %u\n", m_Ref
);
39 CPortWaveCyclic(IUnknown
*OuterUnknown
){}
40 virtual ~CPortWaveCyclic(){}
44 PDEVICE_OBJECT m_pDeviceObject
;
45 PMINIPORTWAVECYCLIC m_pMiniport
;
46 PRESOURCELIST m_pResourceList
;
47 PPINCOUNT m_pPinCount
;
48 PPOWERNOTIFY m_pPowerNotify
;
49 PPCFILTER_DESCRIPTOR m_pDescriptor
;
50 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor
;
51 IPortFilterWaveCyclic
* m_Filter
;
55 friend PMINIPORTWAVECYCLIC
GetWaveCyclicMiniport(IN IPortWaveCyclic
* iface
);
56 friend PDEVICE_OBJECT
GetDeviceObject(PPORTWAVECYCLIC iface
);
59 GUID KSPROPERTY_SETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
61 static GUID InterfaceGuids
[4] =
65 0x65E8773EL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
68 /// KSCATEGORY_CAPTURE
69 0x65E8773DL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
73 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
76 ///KSCATEGORY_AUDIO_DEVICE
77 0xFBF6F530L
, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}
82 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWaveCyclicTopologySet
, TopologyPropertyHandler
);
83 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWaveCyclicPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
85 KSPROPERTY_SET WaveCyclicPropertySet
[] =
88 &KSPROPSETID_Topology
,
89 sizeof(PortFilterWaveCyclicTopologySet
) / sizeof(KSPROPERTY_ITEM
),
90 (const KSPROPERTY_ITEM
*)&PortFilterWaveCyclicTopologySet
,
96 sizeof(PortFilterWaveCyclicPinSet
) / sizeof(KSPROPERTY_ITEM
),
97 (const KSPROPERTY_ITEM
*)&PortFilterWaveCyclicPinSet
,
103 //KSEVENTSETID_LoopedStreaming, Type = KSEVENT_LOOPEDSTREAMING_POSITION
104 //KSEVENTSETID_Connection, Type = KSEVENT_CONNECTION_ENDOFSTREAM,
107 //---------------------------------------------------------------
113 CPortWaveCyclic::AddEventToEventList(
114 IN PKSEVENT_ENTRY EventEntry
)
122 CPortWaveCyclic::GenerateEventList(
123 IN GUID
* Set OPTIONAL
,
133 //---------------------------------------------------------------
134 // IUnknown interface functions
139 CPortWaveCyclic::QueryInterface(
143 UNICODE_STRING GuidString
;
145 if (IsEqualGUIDAligned(refiid
, IID_IPortWaveCyclic
) ||
146 IsEqualGUIDAligned(refiid
, IID_IPort
) ||
147 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
149 *Output
= PVOID(PPORTWAVECYCLIC(this));
150 PUNKNOWN(*Output
)->AddRef();
151 return STATUS_SUCCESS
;
153 else if (IsEqualGUIDAligned(refiid
, IID_IPortEvents
))
155 *Output
= PVOID(PPORTEVENTS(this));
156 PUNKNOWN(*Output
)->AddRef();
157 return STATUS_SUCCESS
;
159 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
161 *Output
= PVOID(PSUBDEVICE(this));
162 PUNKNOWN(*Output
)->AddRef();
163 return STATUS_SUCCESS
;
165 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
167 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
169 else if (IsEqualGUIDAligned(refiid
, IID_IDrmPort
) ||
170 IsEqualGUIDAligned(refiid
, IID_IDrmPort2
))
172 return NewIDrmPort((PDRMPORT2
*)Output
);
174 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
176 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
178 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
180 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
183 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
185 DPRINT1("IPortWaveCyclic_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
186 RtlFreeUnicodeString(&GuidString
);
189 return STATUS_UNSUCCESSFUL
;
192 //---------------------------------------------------------------
193 // IPort interface functions
198 CPortWaveCyclic::GetDeviceProperty(
199 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
200 IN ULONG BufferLength
,
201 OUT PVOID PropertyBuffer
,
202 OUT PULONG ReturnLength
)
204 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
208 DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initiazed\n");
209 return STATUS_UNSUCCESSFUL
;
212 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
217 CPortWaveCyclic::Init(
218 IN PDEVICE_OBJECT DeviceObject
,
220 IN PUNKNOWN UnknownMiniport
,
221 IN PUNKNOWN UnknownAdapter OPTIONAL
,
222 IN PRESOURCELIST ResourceList
)
224 IMiniportWaveCyclic
* Miniport
;
227 PPOWERNOTIFY PowerNotify
;
229 DPRINT("IPortWaveCyclic_Init entered %p\n", this);
230 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
234 DPRINT("IPortWaveCyclic_Init called again\n");
235 return STATUS_SUCCESS
;
238 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportWaveCyclic
, (PVOID
*)&Miniport
);
239 if (!NT_SUCCESS(Status
))
241 DPRINT("IPortWaveCyclic_Init called with invalid IMiniport adapter\n");
242 return STATUS_INVALID_PARAMETER
;
245 // Initialize port object
246 m_pMiniport
= Miniport
;
247 m_pDeviceObject
= DeviceObject
;
248 m_bInitialized
= TRUE
;
249 m_pResourceList
= ResourceList
;
254 // increment reference on resource list
255 ResourceList
->AddRef();
258 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this);
259 if (!NT_SUCCESS(Status
))
261 DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status
);
263 m_bInitialized
= FALSE
;
268 // get the miniport device descriptor
269 Status
= Miniport
->GetDescription(&m_pDescriptor
);
270 if (!NT_SUCCESS(Status
))
272 DPRINT1("failed to get description\n");
274 m_bInitialized
= FALSE
;
278 // create the subdevice descriptor
279 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
285 WaveCyclicPropertySet
,
294 if (!NT_SUCCESS(Status
))
296 DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
298 m_bInitialized
= FALSE
;
302 // check if it supports IPinCount interface
303 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
304 if (NT_SUCCESS(Status
))
306 // store IPinCount interface
307 m_pPinCount
= PinCount
;
310 // does the Miniport adapter support IPowerNotify interface*/
311 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
312 if (NT_SUCCESS(Status
))
315 m_pPowerNotify
= PowerNotify
;
318 DPRINT("IPortWaveCyclic successfully initialized\n");
319 return STATUS_SUCCESS
;
325 CPortWaveCyclic::NewRegistryKey(
326 OUT PREGISTRYKEY
*OutRegistryKey
,
327 IN PUNKNOWN OuterUnknown OPTIONAL
,
328 IN ULONG RegistryKeyType
,
329 IN ACCESS_MASK DesiredAccess
,
330 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
331 IN ULONG CreateOptions OPTIONAL
,
332 OUT PULONG Disposition OPTIONAL
)
334 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
338 DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n");
339 return STATUS_UNSUCCESSFUL
;
341 return PcNewRegistryKey(OutRegistryKey
, OuterUnknown
, RegistryKeyType
, DesiredAccess
, m_pDeviceObject
, NULL
/*FIXME*/, ObjectAttributes
, CreateOptions
, Disposition
);
345 //---------------------------------------------------------------
346 // IPortWaveCyclic interface functions
351 CPortWaveCyclic::NewMasterDmaChannel(
352 OUT PDMACHANNEL
* DmaChannel
,
353 IN PUNKNOWN OuterUnknown
,
354 IN PRESOURCELIST ResourceList OPTIONAL
,
355 IN ULONG MaximumLength
,
356 IN BOOL Dma32BitAddresses
,
357 IN BOOL Dma64BitAddresses
,
358 IN DMA_WIDTH DmaWidth
,
359 IN DMA_SPEED DmaSpeed
)
362 DEVICE_DESCRIPTION DeviceDescription
;
364 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
368 DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n");
369 return STATUS_UNSUCCESSFUL
;
372 Status
= PcDmaMasterDescription(ResourceList
, (Dma32BitAddresses
| Dma64BitAddresses
), Dma32BitAddresses
, 0, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, 0, &DeviceDescription
);
373 if (NT_SUCCESS(Status
))
375 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, NonPagedPool
, &DeviceDescription
, m_pDeviceObject
);
383 CPortWaveCyclic::NewSlaveDmaChannel(
384 OUT PDMACHANNELSLAVE
* OutDmaChannel
,
385 IN PUNKNOWN OuterUnknown
,
386 IN PRESOURCELIST ResourceList OPTIONAL
,
388 IN ULONG MaximumLength
,
390 IN DMA_SPEED DmaSpeed
)
392 DEVICE_DESCRIPTION DeviceDescription
;
393 PDMACHANNEL DmaChannel
;
396 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
400 DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n");
401 return STATUS_UNSUCCESSFUL
;
405 // Check for F-Type DMA Support
408 Status
= PcDmaSlaveDescription(ResourceList
, DmaIndex
, DemandMode
, TRUE
, DmaSpeed
, MaximumLength
, 0, &DeviceDescription
);
409 if (NT_SUCCESS(Status
))
411 Status
= PcNewDmaChannel(&DmaChannel
, OuterUnknown
, NonPagedPool
, &DeviceDescription
, m_pDeviceObject
);
412 if (NT_SUCCESS(Status
))
414 Status
= DmaChannel
->QueryInterface(IID_IDmaChannelSlave
, (PVOID
*)OutDmaChannel
);
415 DmaChannel
->Release();
424 CPortWaveCyclic::Notify(
425 IN PSERVICEGROUP ServiceGroup
)
427 ServiceGroup
->RequestService ();
430 //---------------------------------------------------------------
431 // ISubdevice interface
436 CPortWaveCyclic::NewIrpTarget(
437 OUT
struct IIrpTarget
**OutTarget
,
440 IN POOL_TYPE PoolType
,
441 IN PDEVICE_OBJECT DeviceObject
,
443 IN KSOBJECT_CREATE
*CreateObject
)
446 IPortFilterWaveCyclic
* Filter
;
448 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
450 // is there already an instance of the filter
453 // it is, let's return the result
454 *OutTarget
= (IIrpTarget
*)m_Filter
;
456 // increment reference
458 return STATUS_SUCCESS
;
461 // create new instance of filter
462 Status
= NewPortFilterWaveCyclic(&Filter
);
463 if (!NT_SUCCESS(Status
))
469 // initialize the filter
470 Status
= Filter
->Init((IPortWaveCyclic
*)this);
471 if (!NT_SUCCESS(Status
))
480 *OutTarget
= (IIrpTarget
*)Filter
;
481 // store for later re-use
490 CPortWaveCyclic::ReleaseChildren()
492 DPRINT("ISubDevice_fnReleaseChildren\n");
494 // release the filter
499 // release pincount interface
500 m_pPinCount
->Release();
505 // release power notify interface
506 m_pPowerNotify
->Release();
509 // now release the miniport
510 m_pMiniport
->Release();
512 return STATUS_SUCCESS
;
518 CPortWaveCyclic::GetDescriptor(
519 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
521 PC_ASSERT(m_SubDeviceDescriptor
!= NULL
);
523 *Descriptor
= m_SubDeviceDescriptor
;
525 DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", this, m_SubDeviceDescriptor
);
526 return STATUS_SUCCESS
;
532 CPortWaveCyclic::DataRangeIntersection(
534 IN PKSDATARANGE DataRange
,
535 IN PKSDATARANGE MatchingDataRange
,
536 IN ULONG OutputBufferLength
,
537 OUT PVOID ResultantFormat OPTIONAL
,
538 OUT PULONG ResultantFormatLength
)
540 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
544 return m_pMiniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
547 return STATUS_UNSUCCESSFUL
;
553 CPortWaveCyclic::PowerChangeNotify(
554 IN POWER_STATE PowerState
)
558 m_pPowerNotify
->PowerChangeNotify(PowerState
);
561 return STATUS_SUCCESS
;
566 CPortWaveCyclic::PinCount(
568 IN OUT PULONG FilterNecessary
,
569 IN OUT PULONG FilterCurrent
,
570 IN OUT PULONG FilterPossible
,
571 IN OUT PULONG GlobalCurrent
,
572 IN OUT PULONG GlobalPossible
)
576 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
577 return STATUS_SUCCESS
;
581 // scan filter descriptor
583 return STATUS_UNSUCCESSFUL
;
587 ///--------------------------------------------------------------
589 GetWaveCyclicMiniport(
590 IN IPortWaveCyclic
* iface
)
592 CPortWaveCyclic
* This
= (CPortWaveCyclic
*)iface
;
593 return This
->m_pMiniport
;
598 PPORTWAVECYCLIC iface
)
600 CPortWaveCyclic
* This
= (CPortWaveCyclic
*)iface
;
601 return This
->m_pDeviceObject
;
604 //---------------------------------------------------------------
605 // IPortWaveCyclic constructor
613 CPortWaveCyclic
* Port
;
615 Port
= new(NonPagedPool
, TAG_PORTCLASS
)CPortWaveCyclic(NULL
);
617 return STATUS_INSUFFICIENT_RESOURCES
;
619 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
621 if (!NT_SUCCESS(Status
))
626 DPRINT("NewPortWaveCyclic %p Status %u\n", Port
, Status
);