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 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
68 0x65E8773EL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
71 /// KSCATEGORY_CAPTURE
72 0x65E8773DL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 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 DPRINT("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 DPRINT("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 DPRINT("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
297 m_bInitialized
= FALSE
;
301 // store for node property requests
302 m_SubDeviceDescriptor
->UnknownMiniport
= UnknownMiniport
;
304 // check if it supports IPinCount interface
305 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
306 if (NT_SUCCESS(Status
))
308 // store IPinCount interface
309 m_pPinCount
= PinCount
;
312 // does the Miniport adapter support IPowerNotify interface*/
313 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
314 if (NT_SUCCESS(Status
))
317 m_pPowerNotify
= PowerNotify
;
320 DPRINT("IPortWaveCyclic successfully initialized\n");
321 return STATUS_SUCCESS
;
327 CPortWaveCyclic::NewRegistryKey(
328 OUT PREGISTRYKEY
*OutRegistryKey
,
329 IN PUNKNOWN OuterUnknown OPTIONAL
,
330 IN ULONG RegistryKeyType
,
331 IN ACCESS_MASK DesiredAccess
,
332 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
333 IN ULONG CreateOptions OPTIONAL
,
334 OUT PULONG Disposition OPTIONAL
)
336 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
340 DPRINT("IPortWaveCyclic_fnNewRegistryKey called w/o initialized\n");
341 return STATUS_UNSUCCESSFUL
;
343 return PcNewRegistryKey(OutRegistryKey
, OuterUnknown
, RegistryKeyType
, DesiredAccess
, m_pDeviceObject
, NULL
/*FIXME*/, ObjectAttributes
, CreateOptions
, Disposition
);
347 //---------------------------------------------------------------
348 // IPortWaveCyclic interface functions
353 CPortWaveCyclic::NewMasterDmaChannel(
354 OUT PDMACHANNEL
* DmaChannel
,
355 IN PUNKNOWN OuterUnknown
,
356 IN PRESOURCELIST ResourceList OPTIONAL
,
357 IN ULONG MaximumLength
,
358 IN BOOLEAN Dma32BitAddresses
,
359 IN BOOLEAN Dma64BitAddresses
,
360 IN DMA_WIDTH DmaWidth
,
361 IN DMA_SPEED DmaSpeed
)
364 DEVICE_DESCRIPTION DeviceDescription
;
366 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
370 DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n");
371 return STATUS_UNSUCCESSFUL
;
374 Status
= PcDmaMasterDescription(ResourceList
, (Dma32BitAddresses
| Dma64BitAddresses
), Dma32BitAddresses
, 0, Dma64BitAddresses
, DmaWidth
, DmaSpeed
, MaximumLength
, 0, &DeviceDescription
);
375 if (NT_SUCCESS(Status
))
377 return PcNewDmaChannel(DmaChannel
, OuterUnknown
, NonPagedPool
, &DeviceDescription
, m_pDeviceObject
);
385 CPortWaveCyclic::NewSlaveDmaChannel(
386 OUT PDMACHANNELSLAVE
* OutDmaChannel
,
387 IN PUNKNOWN OuterUnknown
,
388 IN PRESOURCELIST ResourceList OPTIONAL
,
390 IN ULONG MaximumLength
,
391 IN BOOLEAN DemandMode
,
392 IN DMA_SPEED DmaSpeed
)
394 DEVICE_DESCRIPTION DeviceDescription
;
395 PDMACHANNEL DmaChannel
;
398 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
402 DPRINT("IPortWaveCyclic_fnNewSlaveDmaChannel called w/o initialized\n");
403 return STATUS_UNSUCCESSFUL
;
407 // Check for F-Type DMA Support
410 Status
= PcDmaSlaveDescription(ResourceList
, DmaIndex
, DemandMode
, TRUE
, DmaSpeed
, MaximumLength
, 0, &DeviceDescription
);
411 if (NT_SUCCESS(Status
))
413 Status
= PcNewDmaChannel(&DmaChannel
, OuterUnknown
, NonPagedPool
, &DeviceDescription
, m_pDeviceObject
);
414 if (NT_SUCCESS(Status
))
416 Status
= DmaChannel
->QueryInterface(IID_IDmaChannelSlave
, (PVOID
*)OutDmaChannel
);
417 DmaChannel
->Release();
426 CPortWaveCyclic::Notify(
427 IN PSERVICEGROUP ServiceGroup
)
429 ServiceGroup
->RequestService ();
432 //---------------------------------------------------------------
433 // ISubdevice interface
438 CPortWaveCyclic::NewIrpTarget(
439 OUT
struct IIrpTarget
**OutTarget
,
442 IN POOL_TYPE PoolType
,
443 IN PDEVICE_OBJECT DeviceObject
,
445 IN KSOBJECT_CREATE
*CreateObject
)
448 IPortFilterWaveCyclic
* Filter
;
450 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
452 // is there already an instance of the filter
455 // it is, let's return the result
456 *OutTarget
= (IIrpTarget
*)m_Filter
;
458 // increment reference
460 return STATUS_SUCCESS
;
463 // create new instance of filter
464 Status
= NewPortFilterWaveCyclic(&Filter
);
465 if (!NT_SUCCESS(Status
))
471 // initialize the filter
472 Status
= Filter
->Init((IPortWaveCyclic
*)this);
473 if (!NT_SUCCESS(Status
))
482 *OutTarget
= (IIrpTarget
*)Filter
;
483 // store for later re-use
492 CPortWaveCyclic::ReleaseChildren()
494 DPRINT("ISubDevice_fnReleaseChildren\n");
496 // release the filter
501 // release pincount interface
502 m_pPinCount
->Release();
507 // release power notify interface
508 m_pPowerNotify
->Release();
511 // now release the miniport
512 m_pMiniport
->Release();
514 return STATUS_SUCCESS
;
520 CPortWaveCyclic::GetDescriptor(
521 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
523 PC_ASSERT(m_SubDeviceDescriptor
!= NULL
);
525 *Descriptor
= m_SubDeviceDescriptor
;
527 DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", this, m_SubDeviceDescriptor
);
528 return STATUS_SUCCESS
;
534 CPortWaveCyclic::DataRangeIntersection(
536 IN PKSDATARANGE DataRange
,
537 IN PKSDATARANGE MatchingDataRange
,
538 IN ULONG OutputBufferLength
,
539 OUT PVOID ResultantFormat OPTIONAL
,
540 OUT PULONG ResultantFormatLength
)
542 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
546 return m_pMiniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
549 return STATUS_UNSUCCESSFUL
;
555 CPortWaveCyclic::PowerChangeNotify(
556 IN POWER_STATE PowerState
)
560 m_pPowerNotify
->PowerChangeNotify(PowerState
);
563 return STATUS_SUCCESS
;
568 CPortWaveCyclic::PinCount(
570 IN OUT PULONG FilterNecessary
,
571 IN OUT PULONG FilterCurrent
,
572 IN OUT PULONG FilterPossible
,
573 IN OUT PULONG GlobalCurrent
,
574 IN OUT PULONG GlobalPossible
)
578 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
579 return STATUS_SUCCESS
;
583 // scan filter descriptor
585 return STATUS_UNSUCCESSFUL
;
589 ///--------------------------------------------------------------
591 GetWaveCyclicMiniport(
592 IN IPortWaveCyclic
* iface
)
594 CPortWaveCyclic
* This
= (CPortWaveCyclic
*)iface
;
595 return This
->m_pMiniport
;
600 PPORTWAVECYCLIC iface
)
602 CPortWaveCyclic
* This
= (CPortWaveCyclic
*)iface
;
603 return This
->m_pDeviceObject
;
606 //---------------------------------------------------------------
607 // IPortWaveCyclic constructor
615 CPortWaveCyclic
* Port
;
617 Port
= new(NonPagedPool
, TAG_PORTCLASS
)CPortWaveCyclic(NULL
);
619 return STATUS_INSUFFICIENT_RESOURCES
;
621 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
623 if (!NT_SUCCESS(Status
))
628 DPRINT("NewPortWaveCyclic %p Status %u\n", Port
, Status
);