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
11 class CPortDMus
: public IPortDMus
,
15 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
17 STDMETHODIMP_(ULONG
) AddRef()
19 InterlockedIncrement(&m_Ref
);
22 STDMETHODIMP_(ULONG
) Release()
24 InterlockedDecrement(&m_Ref
);
35 CPortDMus(IUnknown
*OuterUnknown
){}
36 virtual ~CPortDMus(){}
41 IMiniportDMus
* m_pMiniport
;
42 IMiniportMidi
* m_pMiniportMidi
;
43 DEVICE_OBJECT
* m_pDeviceObject
;
44 PSERVICEGROUP m_ServiceGroup
;
45 PPINCOUNT m_pPinCount
;
46 PPOWERNOTIFY m_pPowerNotify
;
47 PPORTFILTERDMUS m_Filter
;
49 PPCFILTER_DESCRIPTOR m_pDescriptor
;
50 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor
;
54 friend VOID
GetDMusMiniport(IN IPortDMus
* iface
, IN PMINIPORTDMUS
* Miniport
, IN PMINIPORTMIDI
* MidiMiniport
);
58 static GUID InterfaceGuids
[3] =
62 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
65 /// KS_CATEGORY_RENDER
66 0x65E8773E, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
69 /// KS_CATEGORY_CAPTURE
70 0x65E8773D, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
74 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterDMusTopologySet
, TopologyPropertyHandler
);
75 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterDMusPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
77 KSPROPERTY_SET PortDMusPropertySet
[] =
80 &KSPROPSETID_Topology
,
81 sizeof(PortFilterDMusTopologySet
) / sizeof(KSPROPERTY_ITEM
),
82 (const KSPROPERTY_ITEM
*)&PortFilterDMusTopologySet
,
88 sizeof(PortFilterDMusPinSet
) / sizeof(KSPROPERTY_ITEM
),
89 (const KSPROPERTY_ITEM
*)&PortFilterDMusPinSet
,
96 //---------------------------------------------------------------
97 // IUnknown interface functions
102 CPortDMus::QueryInterface(
106 UNICODE_STRING GuidString
;
108 if (IsEqualGUIDAligned(refiid
, IID_IPortDMus
) ||
109 IsEqualGUIDAligned(refiid
, IID_IPortMidi
) ||
110 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
112 *Output
= PVOID(PUNKNOWN((IPortDMus
*)this));
113 PUNKNOWN(*Output
)->AddRef();
114 return STATUS_SUCCESS
;
116 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
118 *Output
= PVOID(PSUBDEVICE(this));
119 PUNKNOWN(*Output
)->AddRef();
120 return STATUS_SUCCESS
;
122 else if (IsEqualGUIDAligned(refiid
, IID_IDrmPort
) ||
123 IsEqualGUIDAligned(refiid
, IID_IDrmPort2
))
125 return NewIDrmPort((PDRMPORT2
*)Output
);
127 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
129 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
131 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
133 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
135 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
137 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
140 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
142 DPRINT1("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
143 RtlFreeUnicodeString(&GuidString
);
145 return STATUS_UNSUCCESSFUL
;
148 //---------------------------------------------------------------
149 // IPort interface functions
154 CPortDMus::GetDeviceProperty(
155 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
156 IN ULONG BufferLength
,
157 OUT PVOID PropertyBuffer
,
158 OUT PULONG ReturnLength
)
160 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
164 DPRINT("IPortDMus_fnNewRegistryKey called w/o initiazed\n");
165 return STATUS_UNSUCCESSFUL
;
168 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
174 IN PDEVICE_OBJECT DeviceObject
,
176 IN PUNKNOWN UnknownMiniport
,
177 IN PUNKNOWN UnknownAdapter OPTIONAL
,
178 IN PRESOURCELIST ResourceList
)
180 IMiniportDMus
* Miniport
= NULL
;
181 IMiniportMidi
* MidiMiniport
= NULL
;
183 PSERVICEGROUP ServiceGroup
= NULL
;
185 PPOWERNOTIFY PowerNotify
;
187 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
191 DPRINT("IPortDMus_Init called again\n");
192 return STATUS_SUCCESS
;
195 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportDMus
, (PVOID
*)&Miniport
);
196 if (!NT_SUCCESS(Status
))
198 // check for legacy interface
199 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportMidi
, (PVOID
*)&MidiMiniport
);
200 if (!NT_SUCCESS(Status
))
202 DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n");
203 return STATUS_INVALID_PARAMETER
;
207 // Initialize port object
208 m_pMiniport
= Miniport
;
209 m_pMiniportMidi
= MidiMiniport
;
210 m_pDeviceObject
= DeviceObject
;
211 m_bInitialized
= TRUE
;
215 // initialize IMiniportDMus
216 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this, &ServiceGroup
);
217 if (!NT_SUCCESS(Status
))
219 DPRINT("IMiniportDMus_Init failed with %x\n", Status
);
220 m_bInitialized
= FALSE
;
224 // get the miniport device descriptor
225 Status
= Miniport
->GetDescription(&m_pDescriptor
);
226 if (!NT_SUCCESS(Status
))
228 DPRINT1("failed to get description\n");
230 m_bInitialized
= FALSE
;
234 // increment reference on miniport adapter
240 // initialize IMiniportMidi
241 Status
= MidiMiniport
->Init(UnknownAdapter
, ResourceList
, (IPortMidi
*)this, &ServiceGroup
);
242 if (!NT_SUCCESS(Status
))
244 DPRINT("IMiniportMidi_Init failed with %x\n", Status
);
245 m_bInitialized
= FALSE
;
249 // get the miniport device descriptor
250 Status
= MidiMiniport
->GetDescription(&m_pDescriptor
);
251 if (!NT_SUCCESS(Status
))
253 DPRINT1("failed to get description\n");
254 MidiMiniport
->Release();
255 m_bInitialized
= FALSE
;
259 // increment reference on miniport adapter
260 MidiMiniport
->AddRef();
263 // create the subdevice descriptor
264 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
279 if (!NT_SUCCESS(Status
))
281 DPRINT1("Failed to create descriptior\n");
286 MidiMiniport
->Release();
288 m_bInitialized
= FALSE
;
292 if (m_ServiceGroup
== NULL
&& ServiceGroup
)
294 // register service group
295 m_ServiceGroup
= ServiceGroup
;
298 // check if it supports IPinCount interface
299 Status
= UnknownMiniport
->QueryInterface(IID_IPinCount
, (PVOID
*)&PinCount
);
300 if (NT_SUCCESS(Status
))
302 // store IPinCount interface
303 m_pPinCount
= PinCount
;
306 // does the Miniport adapter support IPowerNotify interface*/
307 Status
= UnknownMiniport
->QueryInterface(IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
308 if (NT_SUCCESS(Status
))
311 m_pPowerNotify
= PowerNotify
;
314 return STATUS_SUCCESS
;
320 CPortDMus::NewRegistryKey(
321 OUT PREGISTRYKEY
*OutRegistryKey
,
322 IN PUNKNOWN OuterUnknown OPTIONAL
,
323 IN ULONG RegistryKeyType
,
324 IN ACCESS_MASK DesiredAccess
,
325 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
326 IN ULONG CreateOptions OPTIONAL
,
327 OUT PULONG Disposition OPTIONAL
)
329 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
333 DPRINT("IPortDMus_fnNewRegistryKey called w/o initialized\n");
334 return STATUS_UNSUCCESSFUL
;
337 return PcNewRegistryKey(OutRegistryKey
,
351 IN PSERVICEGROUP ServiceGroup OPTIONAL
)
355 ServiceGroup
->RequestService ();
359 PC_ASSERT(m_ServiceGroup
);
361 // notify miniport service group
362 m_ServiceGroup
->RequestService();
364 // notify stream miniport service group
367 m_Filter
->NotifyPins();
373 CPortDMus::RegisterServiceGroup(
374 IN PSERVICEGROUP ServiceGroup
)
376 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
378 m_ServiceGroup
= ServiceGroup
;
380 ServiceGroup
->AddMember(PSERVICESINK(this));
382 //---------------------------------------------------------------
383 // ISubdevice interface
388 CPortDMus::NewIrpTarget(
389 OUT
struct IIrpTarget
**OutTarget
,
392 IN POOL_TYPE PoolType
,
393 IN PDEVICE_OBJECT DeviceObject
,
395 IN KSOBJECT_CREATE
*CreateObject
)
398 PPORTFILTERDMUS Filter
;
400 DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
404 *OutTarget
= (IIrpTarget
*)m_Filter
;
405 return STATUS_SUCCESS
;
409 Status
= NewPortFilterDMus(&Filter
);
410 if (!NT_SUCCESS(Status
))
415 Status
= Filter
->Init(PPORTDMUS(this));
416 if (!NT_SUCCESS(Status
))
422 *OutTarget
= (IIrpTarget
*)Filter
;
428 CPortDMus::ReleaseChildren()
431 return STATUS_UNSUCCESSFUL
;
436 CPortDMus::GetDescriptor(
437 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
439 DPRINT("ISubDevice_GetDescriptor this %p\n", this);
440 *Descriptor
= m_SubDeviceDescriptor
;
441 return STATUS_SUCCESS
;
446 CPortDMus::DataRangeIntersection(
448 IN PKSDATARANGE DataRange
,
449 IN PKSDATARANGE MatchingDataRange
,
450 IN ULONG OutputBufferLength
,
451 OUT PVOID ResultantFormat OPTIONAL
,
452 OUT PULONG ResultantFormatLength
)
454 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
458 return m_pMiniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
461 return STATUS_UNSUCCESSFUL
;
466 CPortDMus::PowerChangeNotify(
467 IN POWER_STATE PowerState
)
471 m_pPowerNotify
->PowerChangeNotify(PowerState
);
474 return STATUS_SUCCESS
;
482 IN OUT PULONG FilterNecessary
,
483 IN OUT PULONG FilterCurrent
,
484 IN OUT PULONG FilterPossible
,
485 IN OUT PULONG GlobalCurrent
,
486 IN OUT PULONG GlobalPossible
)
490 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
491 return STATUS_SUCCESS
;
495 // scan filter descriptor
497 return STATUS_UNSUCCESSFUL
;
507 CPortDMus
* Port
= new(NonPagedPool
, TAG_PORTCLASS
) CPortDMus(NULL
);
509 return STATUS_INSUFFICIENT_RESOURCES
;
511 Status
= Port
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
513 if (!NT_SUCCESS(Status
))
518 DPRINT("NewPortDMus %p Status %u\n", Port
, Status
);
527 IN IPortDMus
* iface
,
528 IN PMINIPORTDMUS
* Miniport
,
529 IN PMINIPORTMIDI
* MidiMiniport
)
531 CPortDMus
* This
= (CPortDMus
*)iface
;
533 *Miniport
= This
->m_pMiniport
;
534 *MidiMiniport
= This
->m_pMiniportMidi
;