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(){}
43 PDEVICE_OBJECT m_pDeviceObject
;
44 PMINIPORTWAVECYCLIC m_pMiniport
;
45 PRESOURCELIST m_pResourceList
;
46 PPINCOUNT m_pPinCount
;
47 PPOWERNOTIFY m_pPowerNotify
;
48 PPCFILTER_DESCRIPTOR m_pDescriptor
;
49 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor
;
50 IPortFilterWaveCyclic
* m_Filter
;
54 friend PMINIPORTWAVECYCLIC
GetWaveCyclicMiniport(IN IPortWaveCyclic
* iface
);
55 friend PDEVICE_OBJECT
GetDeviceObject(PPORTWAVECYCLIC iface
);
58 GUID KSPROPERTY_SETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
60 static GUID InterfaceGuids
[4] =
64 0x65E8773EL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
67 /// KSCATEGORY_CAPTURE
68 0x65E8773DL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
72 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
75 ///KSCATEGORY_AUDIO_DEVICE
76 0xFBF6F530L
, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}
81 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWaveCyclicTopologySet
, TopologyPropertyHandler
);
82 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWaveCyclicPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
84 KSPROPERTY_SET WaveCyclicPropertySet
[] =
87 &KSPROPSETID_Topology
,
88 sizeof(PortFilterWaveCyclicTopologySet
) / sizeof(KSPROPERTY_ITEM
),
89 (const KSPROPERTY_ITEM
*)&PortFilterWaveCyclicTopologySet
,
95 sizeof(PortFilterWaveCyclicPinSet
) / sizeof(KSPROPERTY_ITEM
),
96 (const KSPROPERTY_ITEM
*)&PortFilterWaveCyclicPinSet
,
102 //KSEVENTSETID_LoopedStreaming, Type = KSEVENT_LOOPEDSTREAMING_POSITION
103 //KSEVENTSETID_Connection, Type = KSEVENT_CONNECTION_ENDOFSTREAM,
106 //---------------------------------------------------------------
112 CPortWaveCyclic::AddEventToEventList(
113 IN PKSEVENT_ENTRY EventEntry
)
121 CPortWaveCyclic::GenerateEventList(
122 IN GUID
* Set OPTIONAL
,
132 //---------------------------------------------------------------
133 // IUnknown interface functions
138 CPortWaveCyclic::QueryInterface(
142 UNICODE_STRING GuidString
;
144 if (IsEqualGUIDAligned(refiid
, IID_IPortWaveCyclic
) ||
145 IsEqualGUIDAligned(refiid
, IID_IPort
) ||
146 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
148 *Output
= PVOID(PPORTWAVECYCLIC(this));
149 PUNKNOWN(*Output
)->AddRef();
150 return STATUS_SUCCESS
;
152 else if (IsEqualGUIDAligned(refiid
, IID_IPortEvents
))
154 *Output
= PVOID(PPORTEVENTS(this));
155 PUNKNOWN(*Output
)->AddRef();
156 return STATUS_SUCCESS
;
158 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
160 *Output
= PVOID(PSUBDEVICE(this));
161 PUNKNOWN(*Output
)->AddRef();
162 return STATUS_SUCCESS
;
164 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
166 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
168 else if (IsEqualGUIDAligned(refiid
, IID_IDrmPort
) ||
169 IsEqualGUIDAligned(refiid
, IID_IDrmPort2
))
171 return NewIDrmPort((PDRMPORT2
*)Output
);
173 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
175 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
177 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
179 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
182 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
184 DPRINT1("IPortWaveCyclic_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
185 RtlFreeUnicodeString(&GuidString
);
188 return STATUS_UNSUCCESSFUL
;
191 //---------------------------------------------------------------
192 // IPort interface functions
197 CPortWaveCyclic::GetDeviceProperty(
198 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
199 IN ULONG BufferLength
,
200 OUT PVOID PropertyBuffer
,
201 OUT PULONG ReturnLength
)
203 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
207 DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initiazed\n");
208 return STATUS_UNSUCCESSFUL
;
211 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
216 CPortWaveCyclic::Init(
217 IN PDEVICE_OBJECT DeviceObject
,
219 IN PUNKNOWN UnknownMiniport
,
220 IN PUNKNOWN UnknownAdapter OPTIONAL
,
221 IN PRESOURCELIST ResourceList
)
223 IMiniportWaveCyclic
* Miniport
;
226 PPOWERNOTIFY PowerNotify
;
228 DPRINT("IPortWaveCyclic_Init entered %p\n", this);
229 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
233 DPRINT("IPortWaveCyclic_Init called again\n");
234 return STATUS_SUCCESS
;
237 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportWaveCyclic
, (PVOID
*)&Miniport
);
238 if (!NT_SUCCESS(Status
))
240 DPRINT("IPortWaveCyclic_Init called with invalid IMiniport adapter\n");
241 return STATUS_INVALID_PARAMETER
;
244 // Initialize port object
245 m_pMiniport
= Miniport
;
246 m_pDeviceObject
= DeviceObject
;
247 m_bInitialized
= TRUE
;
248 m_pResourceList
= ResourceList
;
253 // increment reference on resource list
254 ResourceList
->AddRef();
257 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this);
258 if (!NT_SUCCESS(Status
))
260 DPRINT("IMiniportWaveCyclic_Init failed with %x\n", Status
);
262 m_bInitialized
= FALSE
;
267 // get the miniport device descriptor
268 Status
= Miniport
->GetDescription(&m_pDescriptor
);
269 if (!NT_SUCCESS(Status
))
271 DPRINT1("failed to get description\n");
273 m_bInitialized
= FALSE
;
277 // create the subdevice descriptor
278 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
284 WaveCyclicPropertySet
,
293 if (!NT_SUCCESS(Status
))
295 DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
297 m_bInitialized
= FALSE
;
301 // check if it supports IPinCount interface
302 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
303 if (NT_SUCCESS(Status
))
305 // store IPinCount interface
306 m_pPinCount
= PinCount
;
309 // does the Miniport adapter support IPowerNotify interface*/
310 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
311 if (NT_SUCCESS(Status
))
314 m_pPowerNotify
= PowerNotify
;
317 DPRINT("IPortWaveCyclic successfully initialized\n");
318 return STATUS_SUCCESS
;
324 CPortWaveCyclic::NewRegistryKey(
325 OUT PREGISTRYKEY
*OutRegistryKey
,
326 IN PUNKNOWN OuterUnknown OPTIONAL
,
327 IN ULONG RegistryKeyType
,
328 IN ACCESS_MASK DesiredAccess
,
329 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
330 IN ULONG CreateOptions OPTIONAL
,
331 OUT PULONG Disposition OPTIONAL
)
333 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
337 DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n");
338 return STATUS_UNSUCCESSFUL
;
340 return PcNewRegistryKey(OutRegistryKey
, OuterUnknown
, RegistryKeyType
, DesiredAccess
, m_pDeviceObject
, NULL
/*FIXME*/, ObjectAttributes
, CreateOptions
, Disposition
);
344 //---------------------------------------------------------------
345 // IPortWaveCyclic interface functions
350 CPortWaveCyclic::NewMasterDmaChannel(
351 OUT PDMACHANNEL
* DmaChannel
,
352 IN PUNKNOWN OuterUnknown
,
353 IN PRESOURCELIST ResourceList OPTIONAL
,
354 IN ULONG MaximumLength
,
355 IN BOOL Dma32BitAddresses
,
356 IN BOOL Dma64BitAddresses
,
357 IN DMA_WIDTH DmaWidth
,
358 IN DMA_SPEED DmaSpeed
)
361 DEVICE_DESCRIPTION DeviceDescription
;
363 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
367 DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n");
368 return STATUS_UNSUCCESSFUL
;
371 Status
= PcDmaMasterDescription(ResourceList
, (Dma32BitAddresses
| Dma64BitAddresses
), Dma32BitAddresses
, 0, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, 0, &DeviceDescription
);
372 if (NT_SUCCESS(Status
))
374 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, NonPagedPool
, &DeviceDescription
, m_pDeviceObject
);
382 CPortWaveCyclic::NewSlaveDmaChannel(
383 OUT PDMACHANNELSLAVE
* OutDmaChannel
,
384 IN PUNKNOWN OuterUnknown
,
385 IN PRESOURCELIST ResourceList OPTIONAL
,
387 IN ULONG MaximumLength
,
389 IN DMA_SPEED DmaSpeed
)
391 DEVICE_DESCRIPTION DeviceDescription
;
392 PDMACHANNEL DmaChannel
;
395 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
399 DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n");
400 return STATUS_UNSUCCESSFUL
;
404 // Check for F-Type DMA Support
407 Status
= PcDmaSlaveDescription(ResourceList
, DmaIndex
, DemandMode
, TRUE
, DmaSpeed
, MaximumLength
, 0, &DeviceDescription
);
408 if (NT_SUCCESS(Status
))
410 Status
= PcNewDmaChannel(&DmaChannel
, OuterUnknown
, NonPagedPool
, &DeviceDescription
, m_pDeviceObject
);
411 if (NT_SUCCESS(Status
))
413 Status
= DmaChannel
->QueryInterface(IID_IDmaChannelSlave
, (PVOID
*)OutDmaChannel
);
414 DmaChannel
->Release();
423 CPortWaveCyclic::Notify(
424 IN PSERVICEGROUP ServiceGroup
)
426 ServiceGroup
->RequestService ();
429 //---------------------------------------------------------------
430 // ISubdevice interface
435 CPortWaveCyclic::NewIrpTarget(
436 OUT
struct IIrpTarget
**OutTarget
,
439 IN POOL_TYPE PoolType
,
440 IN PDEVICE_OBJECT DeviceObject
,
442 IN KSOBJECT_CREATE
*CreateObject
)
445 IPortFilterWaveCyclic
* Filter
;
447 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
449 // is there already an instance of the filter
452 // it is, let's return the result
453 *OutTarget
= (IIrpTarget
*)m_Filter
;
455 // increment reference
457 return STATUS_SUCCESS
;
460 // create new instance of filter
461 Status
= NewPortFilterWaveCyclic(&Filter
);
462 if (!NT_SUCCESS(Status
))
468 // initialize the filter
469 Status
= Filter
->Init((IPortWaveCyclic
*)this);
470 if (!NT_SUCCESS(Status
))
479 *OutTarget
= (IIrpTarget
*)Filter
;
480 // store for later re-use
489 CPortWaveCyclic::ReleaseChildren()
491 DPRINT("ISubDevice_fnReleaseChildren\n");
493 // release the filter
498 // release pincount interface
499 m_pPinCount
->Release();
504 // release power notify interface
505 m_pPowerNotify
->Release();
508 // now release the miniport
509 m_pMiniport
->Release();
511 return STATUS_SUCCESS
;
517 CPortWaveCyclic::GetDescriptor(
518 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
520 PC_ASSERT(m_SubDeviceDescriptor
!= NULL
);
522 *Descriptor
= m_SubDeviceDescriptor
;
524 DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", this, m_SubDeviceDescriptor
);
525 return STATUS_SUCCESS
;
531 CPortWaveCyclic::DataRangeIntersection(
533 IN PKSDATARANGE DataRange
,
534 IN PKSDATARANGE MatchingDataRange
,
535 IN ULONG OutputBufferLength
,
536 OUT PVOID ResultantFormat OPTIONAL
,
537 OUT PULONG ResultantFormatLength
)
539 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
543 return m_pMiniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
546 return STATUS_UNSUCCESSFUL
;
552 CPortWaveCyclic::PowerChangeNotify(
553 IN POWER_STATE PowerState
)
557 m_pPowerNotify
->PowerChangeNotify(PowerState
);
560 return STATUS_SUCCESS
;
565 CPortWaveCyclic::PinCount(
567 IN OUT PULONG FilterNecessary
,
568 IN OUT PULONG FilterCurrent
,
569 IN OUT PULONG FilterPossible
,
570 IN OUT PULONG GlobalCurrent
,
571 IN OUT PULONG GlobalPossible
)
575 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
576 return STATUS_SUCCESS
;
580 // scan filter descriptor
582 return STATUS_UNSUCCESSFUL
;
586 ///--------------------------------------------------------------
588 GetWaveCyclicMiniport(
589 IN IPortWaveCyclic
* iface
)
591 CPortWaveCyclic
* This
= (CPortWaveCyclic
*)iface
;
592 return This
->m_pMiniport
;
597 PPORTWAVECYCLIC iface
)
599 CPortWaveCyclic
* This
= (CPortWaveCyclic
*)iface
;
600 return This
->m_pDeviceObject
;
603 //---------------------------------------------------------------
604 // IPortWaveCyclic constructor
612 CPortWaveCyclic
* Port
;
614 Port
= new(NonPagedPool
, TAG_PORTCLASS
)CPortWaveCyclic(NULL
);
616 return STATUS_INSUFFICIENT_RESOURCES
;
618 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
620 if (!NT_SUCCESS(Status
))
625 DPRINT("NewPortWaveCyclic %p Status %u\n", Port
, Status
);