2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/port_dmus.cpp
5 * PURPOSE: DirectMusic Port driver
6 * PROGRAMMER: Johannes Anderwald
17 class CPortDMus
: public IPortDMus
,
21 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
23 STDMETHODIMP_(ULONG
) AddRef()
25 InterlockedIncrement(&m_Ref
);
28 STDMETHODIMP_(ULONG
) Release()
30 InterlockedDecrement(&m_Ref
);
41 CPortDMus(IUnknown
*OuterUnknown
){}
42 virtual ~CPortDMus(){}
47 IMiniportDMus
* m_pMiniport
;
48 IMiniportMidi
* m_pMiniportMidi
;
49 DEVICE_OBJECT
* m_pDeviceObject
;
50 PSERVICEGROUP m_ServiceGroup
;
51 PPINCOUNT m_pPinCount
;
52 PPOWERNOTIFY m_pPowerNotify
;
53 PPORTFILTERDMUS m_Filter
;
55 PPCFILTER_DESCRIPTOR m_pDescriptor
;
56 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor
;
60 friend VOID
GetDMusMiniport(IN IPortDMus
* iface
, IN PMINIPORTDMUS
* Miniport
, IN PMINIPORTMIDI
* MidiMiniport
);
64 static GUID InterfaceGuids
[3] =
68 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
71 /// KS_CATEGORY_RENDER
72 0x65E8773E, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
75 /// KS_CATEGORY_CAPTURE
76 0x65E8773D, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
80 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterDMusTopologySet
, TopologyPropertyHandler
);
81 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterDMusPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
83 KSPROPERTY_SET PortDMusPropertySet
[] =
86 &KSPROPSETID_Topology
,
87 sizeof(PortFilterDMusTopologySet
) / sizeof(KSPROPERTY_ITEM
),
88 (const KSPROPERTY_ITEM
*)&PortFilterDMusTopologySet
,
94 sizeof(PortFilterDMusPinSet
) / sizeof(KSPROPERTY_ITEM
),
95 (const KSPROPERTY_ITEM
*)&PortFilterDMusPinSet
,
102 //---------------------------------------------------------------
103 // IUnknown interface functions
108 CPortDMus::QueryInterface(
112 UNICODE_STRING GuidString
;
114 if (IsEqualGUIDAligned(refiid
, IID_IPortDMus
) ||
115 IsEqualGUIDAligned(refiid
, IID_IPortMidi
) ||
116 IsEqualGUIDAligned(refiid
, IID_IPort
) ||
117 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
119 *Output
= PVOID(PUNKNOWN((IPortDMus
*)this));
120 PUNKNOWN(*Output
)->AddRef();
121 return STATUS_SUCCESS
;
123 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
125 *Output
= PVOID(PSUBDEVICE(this));
126 PUNKNOWN(*Output
)->AddRef();
127 return STATUS_SUCCESS
;
129 else if (IsEqualGUIDAligned(refiid
, IID_IDrmPort
) ||
130 IsEqualGUIDAligned(refiid
, IID_IDrmPort2
))
132 return NewIDrmPort((PDRMPORT2
*)Output
);
134 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
136 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
138 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
140 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
142 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
144 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
147 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
149 DPRINT("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
150 RtlFreeUnicodeString(&GuidString
);
152 return STATUS_UNSUCCESSFUL
;
155 //---------------------------------------------------------------
156 // IPort interface functions
161 CPortDMus::GetDeviceProperty(
162 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
163 IN ULONG BufferLength
,
164 OUT PVOID PropertyBuffer
,
165 OUT PULONG ReturnLength
)
167 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
171 DPRINT("IPortDMus_fnNewRegistryKey called w/o initialized\n");
172 return STATUS_UNSUCCESSFUL
;
175 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
181 IN PDEVICE_OBJECT DeviceObject
,
183 IN PUNKNOWN UnknownMiniport
,
184 IN PUNKNOWN UnknownAdapter OPTIONAL
,
185 IN PRESOURCELIST ResourceList
)
187 IMiniportDMus
* Miniport
= NULL
;
188 IMiniportMidi
* MidiMiniport
= NULL
;
190 PSERVICEGROUP ServiceGroup
= NULL
;
192 PPOWERNOTIFY PowerNotify
;
194 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
198 DPRINT("IPortDMus_Init called again\n");
199 return STATUS_SUCCESS
;
202 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportDMus
, (PVOID
*)&Miniport
);
203 if (!NT_SUCCESS(Status
))
205 // check for legacy interface
206 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportMidi
, (PVOID
*)&MidiMiniport
);
207 if (!NT_SUCCESS(Status
))
209 DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n");
210 return STATUS_INVALID_PARAMETER
;
214 // Initialize port object
215 m_pMiniport
= Miniport
;
216 m_pMiniportMidi
= MidiMiniport
;
217 m_pDeviceObject
= DeviceObject
;
218 m_bInitialized
= TRUE
;
222 // initialize IMiniportDMus
223 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this, &ServiceGroup
);
224 if (!NT_SUCCESS(Status
))
226 DPRINT("IMiniportDMus_Init failed with %x\n", Status
);
227 m_bInitialized
= FALSE
;
231 // get the miniport device descriptor
232 Status
= Miniport
->GetDescription(&m_pDescriptor
);
233 if (!NT_SUCCESS(Status
))
235 DPRINT("failed to get description\n");
237 m_bInitialized
= FALSE
;
241 // increment reference on miniport adapter
247 // initialize IMiniportMidi
248 Status
= MidiMiniport
->Init(UnknownAdapter
, ResourceList
, (IPortMidi
*)this, &ServiceGroup
);
249 if (!NT_SUCCESS(Status
))
251 DPRINT("IMiniportMidi_Init failed with %x\n", Status
);
252 m_bInitialized
= FALSE
;
256 // get the miniport device descriptor
257 Status
= MidiMiniport
->GetDescription(&m_pDescriptor
);
258 if (!NT_SUCCESS(Status
))
260 DPRINT("failed to get description\n");
261 MidiMiniport
->Release();
262 m_bInitialized
= FALSE
;
266 // increment reference on miniport adapter
267 MidiMiniport
->AddRef();
270 // create the subdevice descriptor
271 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
286 if (!NT_SUCCESS(Status
))
288 DPRINT("Failed to create descriptor\n");
293 MidiMiniport
->Release();
295 m_bInitialized
= FALSE
;
299 if (m_ServiceGroup
== NULL
&& ServiceGroup
)
301 // register service group
302 m_ServiceGroup
= ServiceGroup
;
305 // check if it supports IPinCount interface
306 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
307 if (NT_SUCCESS(Status
))
309 // store IPinCount interface
310 m_pPinCount
= PinCount
;
313 // does the Miniport adapter support IPowerNotify interface*/
314 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
315 if (NT_SUCCESS(Status
))
318 m_pPowerNotify
= PowerNotify
;
321 return STATUS_SUCCESS
;
327 CPortDMus::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("IPortDMus_fnNewRegistryKey called w/o initialized\n");
341 return STATUS_UNSUCCESSFUL
;
344 return PcNewRegistryKey(OutRegistryKey
,
358 IN PSERVICEGROUP ServiceGroup OPTIONAL
)
362 ServiceGroup
->RequestService ();
366 PC_ASSERT(m_ServiceGroup
);
368 // notify miniport service group
369 m_ServiceGroup
->RequestService();
371 // notify stream miniport service group
374 m_Filter
->NotifyPins();
380 CPortDMus::RegisterServiceGroup(
381 IN PSERVICEGROUP ServiceGroup
)
383 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
385 m_ServiceGroup
= ServiceGroup
;
387 ServiceGroup
->AddMember(PSERVICESINK(this));
389 //---------------------------------------------------------------
390 // ISubdevice interface
395 CPortDMus::NewIrpTarget(
396 OUT
struct IIrpTarget
**OutTarget
,
399 IN POOL_TYPE PoolType
,
400 IN PDEVICE_OBJECT DeviceObject
,
402 IN KSOBJECT_CREATE
*CreateObject
)
405 PPORTFILTERDMUS Filter
;
407 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
411 *OutTarget
= (IIrpTarget
*)m_Filter
;
412 return STATUS_SUCCESS
;
416 Status
= NewPortFilterDMus(&Filter
);
417 if (!NT_SUCCESS(Status
))
422 Status
= Filter
->Init(PPORTDMUS(this));
423 if (!NT_SUCCESS(Status
))
429 *OutTarget
= (IIrpTarget
*)Filter
;
435 CPortDMus::ReleaseChildren()
438 return STATUS_UNSUCCESSFUL
;
443 CPortDMus::GetDescriptor(
444 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
446 DPRINT("ISubDevice_GetDescriptor this %p\n", this);
447 *Descriptor
= m_SubDeviceDescriptor
;
448 return STATUS_SUCCESS
;
453 CPortDMus::DataRangeIntersection(
455 IN PKSDATARANGE DataRange
,
456 IN PKSDATARANGE MatchingDataRange
,
457 IN ULONG OutputBufferLength
,
458 OUT PVOID ResultantFormat OPTIONAL
,
459 OUT PULONG ResultantFormatLength
)
461 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
465 return m_pMiniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
468 return STATUS_UNSUCCESSFUL
;
473 CPortDMus::PowerChangeNotify(
474 IN POWER_STATE PowerState
)
478 m_pPowerNotify
->PowerChangeNotify(PowerState
);
481 return STATUS_SUCCESS
;
489 IN OUT PULONG FilterNecessary
,
490 IN OUT PULONG FilterCurrent
,
491 IN OUT PULONG FilterPossible
,
492 IN OUT PULONG GlobalCurrent
,
493 IN OUT PULONG GlobalPossible
)
497 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
498 return STATUS_SUCCESS
;
502 // scan filter descriptor
504 return STATUS_UNSUCCESSFUL
;
514 CPortDMus
* Port
= new(NonPagedPool
, TAG_PORTCLASS
) CPortDMus(NULL
);
516 return STATUS_INSUFFICIENT_RESOURCES
;
518 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
520 if (!NT_SUCCESS(Status
))
525 DPRINT("NewPortDMus %p Status %u\n", Port
, Status
);
534 IN IPortDMus
* iface
,
535 IN PMINIPORTDMUS
* Miniport
,
536 IN PMINIPORTMIDI
* MidiMiniport
)
538 CPortDMus
* This
= (CPortDMus
*)iface
;
540 *Miniport
= This
->m_pMiniport
;
541 *MidiMiniport
= This
->m_pMiniportMidi
;