2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/port_wavert.c
5 * PURPOSE: WaveRT Port Driver
6 * PROGRAMMER: Johannes Anderwald
13 IPortWaveRTVtbl
*lpVtbl
;
14 IPortEventsVtbl
*lpVbtlPortEvents
;
15 IUnregisterSubdeviceVtbl
*lpVtblUnregisterSubdevice
;
16 IUnregisterPhysicalConnectionVtbl
*lpVtblPhysicalConnection
;
17 IPortEventsVtbl
*lpVtblPortEvents
;
18 ISubdeviceVtbl
*lpVtblSubDevice
;
23 PDEVICE_OBJECT pDeviceObject
;
24 PMINIPORTWAVERT pMiniport
;
25 PRESOURCELIST pResourceList
;
27 PPOWERNOTIFY pPowerNotify
;
28 PPCFILTER_DESCRIPTOR pDescriptor
;
29 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor
;
30 IPortFilterWaveRT
* Filter
;
33 static GUID InterfaceGuids
[3] =
37 0x65E8773EL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
40 /// KSCATEGORY_CAPTURE
41 0x65E8773DL
, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
45 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
49 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterWaveRTTopologySet
, TopologyPropertyHandler
);
50 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterWaveRTPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
52 KSPROPERTY_SET WaveRTPropertySet
[] =
55 &KSPROPSETID_Topology
,
56 sizeof(PortFilterWaveRTTopologySet
) / sizeof(KSPROPERTY_ITEM
),
57 (const KSPROPERTY_ITEM
*)&PortFilterWaveRTTopologySet
,
63 sizeof(PortFilterWaveRTPinSet
) / sizeof(KSPROPERTY_ITEM
),
64 (const KSPROPERTY_ITEM
*)&PortFilterWaveRTPinSet
,
70 //KSEVENTSETID_LoopedStreaming, Type = KSEVENT_LOOPEDSTREAMING_POSITION
71 //KSEVENTSETID_Connection, Type = KSEVENT_CONNECTION_ENDOFSTREAM,
76 static const KSIDENTIFIER Identifiers
[] =
79 &KSINTERFACESETID_Standard
,
84 &KSINTERFACESETID_Standard
,
91 //---------------------------------------------------------------
98 IPortEvents_fnQueryInterface(
103 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblPortEvents
);
105 DPRINT("IPortEvents_fnQueryInterface entered\n");
107 if (IsEqualGUIDAligned(refiid
, &IID_IPortEvents
) ||
108 IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
110 *Output
= &This
->lpVbtlPortEvents
;
111 InterlockedIncrement(&This
->ref
);
112 return STATUS_SUCCESS
;
114 return STATUS_UNSUCCESSFUL
;
120 IPortEvents_fnAddRef(
123 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblPortEvents
);
124 DPRINT("IPortEvents_fnQueryInterface entered\n");
125 return InterlockedIncrement(&This
->ref
);
131 IPortEvents_fnRelease(
134 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblPortEvents
);
136 DPRINT("IPortEvents_fnRelease entered\n");
137 InterlockedDecrement(&This
->ref
);
141 FreeItem(This
, TAG_PORTCLASS
);
144 /* Return new reference count */
151 IPortEvents_fnAddEventToEventList(
153 IN PKSEVENT_ENTRY EventEntry
)
162 IPortEvents_fnGenerateEventList(
164 IN GUID
* Set OPTIONAL
,
174 static IPortEventsVtbl vt_IPortEvents
=
176 IPortEvents_fnQueryInterface
,
177 IPortEvents_fnAddRef
,
178 IPortEvents_fnRelease
,
179 IPortEvents_fnAddEventToEventList
,
180 IPortEvents_fnGenerateEventList
183 //---------------------------------------------------------------
184 // IUnknown interface functions
189 IPortWaveRT_fnQueryInterface(
194 UNICODE_STRING GuidString
;
195 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)iface
;
197 if (IsEqualGUIDAligned(refiid
, &IID_IPortWaveRT
) ||
198 IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
200 *Output
= &This
->lpVtbl
;
201 InterlockedIncrement(&This
->ref
);
202 return STATUS_SUCCESS
;
204 else if (IsEqualGUIDAligned(refiid
, &IID_IPortEvents
))
206 *Output
= &This
->lpVtblPortEvents
;
207 InterlockedIncrement(&This
->ref
);
208 return STATUS_SUCCESS
;
210 else if (IsEqualGUIDAligned(refiid
, &IID_ISubdevice
))
212 *Output
= &This
->lpVtblSubDevice
;
213 InterlockedIncrement(&This
->ref
);
214 return STATUS_SUCCESS
;
216 else if (IsEqualGUIDAligned(refiid
, &IID_IPortClsVersion
))
218 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
220 else if (IsEqualGUIDAligned(refiid
, &IID_IDrmPort
) ||
221 IsEqualGUIDAligned(refiid
, &IID_IDrmPort2
))
223 return NewIDrmPort((PDRMPORT2
*)Output
);
225 else if (IsEqualGUIDAligned(refiid
, &IID_IUnregisterSubdevice
))
227 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
229 else if (IsEqualGUIDAligned(refiid
, &IID_IUnregisterPhysicalConnection
))
231 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
234 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
236 DPRINT1("IPortWaveRT_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
237 RtlFreeUnicodeString(&GuidString
);
240 return STATUS_UNSUCCESSFUL
;
245 IPortWaveRT_fnAddRef(
248 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)iface
;
250 return InterlockedIncrement(&This
->ref
);
255 IPortWaveRT_fnRelease(
258 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)iface
;
260 InterlockedDecrement(&This
->ref
);
264 if (This
->bInitialized
)
266 This
->pMiniport
->lpVtbl
->Release(This
->pMiniport
);
269 This
->pPinCount
->lpVtbl
->Release(This
->pPinCount
);
271 if (This
->pPowerNotify
)
272 This
->pPowerNotify
->lpVtbl
->Release(This
->pPowerNotify
);
274 FreeItem(This
, TAG_PORTCLASS
);
277 /* Return new reference count */
282 //---------------------------------------------------------------
283 // IPort interface functions
288 IPortWaveRT_fnGetDeviceProperty(
289 IN IPortWaveRT
* iface
,
290 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
291 IN ULONG BufferLength
,
292 OUT PVOID PropertyBuffer
,
293 OUT PULONG ReturnLength
)
295 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)iface
;
296 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
298 if (!This
->bInitialized
)
300 DPRINT("IPortWaveRT_fnNewRegistryKey called w/o initiazed\n");
301 return STATUS_UNSUCCESSFUL
;
304 return IoGetDeviceProperty(This
->pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
310 IN IPortWaveRT
* iface
,
311 IN PDEVICE_OBJECT DeviceObject
,
313 IN PUNKNOWN UnknownMiniport
,
314 IN PUNKNOWN UnknownAdapter OPTIONAL
,
315 IN PRESOURCELIST ResourceList
)
317 IMiniportWaveRT
* Miniport
;
320 PPOWERNOTIFY PowerNotify
;
321 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)iface
;
323 DPRINT("IPortWaveRT_Init entered %p\n", This
);
324 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
326 if (This
->bInitialized
)
328 DPRINT("IPortWaveRT_Init called again\n");
329 return STATUS_SUCCESS
;
332 Status
= UnknownMiniport
->lpVtbl
->QueryInterface(UnknownMiniport
, &IID_IMiniportWaveRT
, (PVOID
*)&Miniport
);
333 if (!NT_SUCCESS(Status
))
335 DPRINT("IPortWaveRT_Init called with invalid IMiniport adapter\n");
336 return STATUS_INVALID_PARAMETER
;
339 /* Initialize port object */
340 This
->pMiniport
= Miniport
;
341 This
->pDeviceObject
= DeviceObject
;
342 This
->bInitialized
= TRUE
;
343 This
->pResourceList
= ResourceList
;
345 /* increment reference on miniport adapter */
346 Miniport
->lpVtbl
->AddRef(Miniport
);
348 Status
= Miniport
->lpVtbl
->Init(Miniport
, UnknownAdapter
, ResourceList
, iface
);
349 if (!NT_SUCCESS(Status
))
351 DPRINT("IMiniportWaveRT_Init failed with %x\n", Status
);
352 Miniport
->lpVtbl
->Release(Miniport
);
353 This
->bInitialized
= FALSE
;
358 /* get the miniport device descriptor */
359 Status
= Miniport
->lpVtbl
->GetDescription(Miniport
, &This
->pDescriptor
);
360 if (!NT_SUCCESS(Status
))
362 DPRINT1("failed to get description\n");
363 Miniport
->lpVtbl
->Release(Miniport
);
364 This
->bInitialized
= FALSE
;
368 /* create the subdevice descriptor */
369 Status
= PcCreateSubdeviceDescriptor(&This
->SubDeviceDescriptor
,
384 if (!NT_SUCCESS(Status
))
386 DPRINT1("PcCreateSubdeviceDescriptor failed with %x\n", Status
);
387 Miniport
->lpVtbl
->Release(Miniport
);
388 This
->bInitialized
= FALSE
;
392 /* check if it supports IPinCount interface */
393 Status
= UnknownMiniport
->lpVtbl
->QueryInterface(UnknownMiniport
, &IID_IPinCount
, (PVOID
*)&PinCount
);
394 if (NT_SUCCESS(Status
))
396 /* store IPinCount interface */
397 This
->pPinCount
= PinCount
;
400 /* does the Miniport adapter support IPowerNotify interface*/
401 Status
= UnknownMiniport
->lpVtbl
->QueryInterface(UnknownMiniport
, &IID_IPowerNotify
, (PVOID
*)&PowerNotify
);
402 if (NT_SUCCESS(Status
))
404 /* store reference */
405 This
->pPowerNotify
= PowerNotify
;
408 /* increment reference on resource list */
409 ResourceList
->lpVtbl
->AddRef(ResourceList
);
412 DPRINT("IPortWaveRT successfully initialized\n");
413 return STATUS_SUCCESS
;
419 IPortWaveRT_fnNewRegistryKey(
420 IN IPortWaveRT
* iface
,
421 OUT PREGISTRYKEY
*OutRegistryKey
,
422 IN PUNKNOWN OuterUnknown OPTIONAL
,
423 IN ULONG RegistryKeyType
,
424 IN ACCESS_MASK DesiredAccess
,
425 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
426 IN ULONG CreateOptions OPTIONAL
,
427 OUT PULONG Disposition OPTIONAL
)
429 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)iface
;
431 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
433 if (!This
->bInitialized
)
435 DPRINT("IPortWaveRT_fnNewRegistryKey called w/o initialized\n");
436 return STATUS_UNSUCCESSFUL
;
438 return PcNewRegistryKey(OutRegistryKey
, OuterUnknown
, RegistryKeyType
, DesiredAccess
, This
->pDeviceObject
, NULL
/*FIXME*/, ObjectAttributes
, CreateOptions
, Disposition
);
441 static IPortWaveRTVtbl vt_IPortWaveRTVtbl
=
443 IPortWaveRT_fnQueryInterface
,
444 IPortWaveRT_fnAddRef
,
445 IPortWaveRT_fnRelease
,
447 IPortWaveRT_fnGetDeviceProperty
,
448 IPortWaveRT_fnNewRegistryKey
451 //---------------------------------------------------------------
452 // ISubdevice interface
458 ISubDevice_fnQueryInterface(
459 IN ISubdevice
*iface
,
460 IN REFIID InterfaceId
,
463 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblSubDevice
);
465 return IPortWaveRT_fnQueryInterface((IPortWaveRT
*)This
, InterfaceId
, Interface
);
472 IN ISubdevice
*iface
)
474 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblSubDevice
);
476 return IPortWaveRT_fnAddRef((IPortWaveRT
*)This
);
482 ISubDevice_fnRelease(
483 IN ISubdevice
*iface
)
485 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblSubDevice
);
487 return IPortWaveRT_fnRelease((IPortWaveRT
*)This
);
493 ISubDevice_fnNewIrpTarget(
494 IN ISubdevice
*iface
,
495 OUT
struct IIrpTarget
**OutTarget
,
498 IN POOL_TYPE PoolType
,
499 IN PDEVICE_OBJECT DeviceObject
,
501 IN KSOBJECT_CREATE
*CreateObject
)
504 IPortFilterWaveRT
* Filter
;
505 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblSubDevice
);
507 DPRINT("ISubDevice_NewIrpTarget this %p\n", This
);
511 *OutTarget
= (IIrpTarget
*)This
->Filter
;
512 return STATUS_SUCCESS
;
516 Status
= NewPortFilterWaveRT(&Filter
);
517 if (!NT_SUCCESS(Status
))
522 Status
= Filter
->lpVtbl
->Init(Filter
, (IPortWaveRT
*)This
);
523 if (!NT_SUCCESS(Status
))
525 Filter
->lpVtbl
->Release(Filter
);
529 *OutTarget
= (IIrpTarget
*)Filter
;
530 This
->Filter
= Filter
;
537 ISubDevice_fnReleaseChildren(
538 IN ISubdevice
*iface
)
540 //IPortWaveRTImpl * This = (IPortWaveRTImpl*)CONTAINING_RECORD(iface, IPortWaveRTImpl, lpVtblSubDevice);
543 return STATUS_UNSUCCESSFUL
;
549 ISubDevice_fnGetDescriptor(
550 IN ISubdevice
*iface
,
551 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
553 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblSubDevice
);
555 ASSERT(This
->SubDeviceDescriptor
!= NULL
);
557 *Descriptor
= This
->SubDeviceDescriptor
;
559 DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", This
, This
->SubDeviceDescriptor
);
560 return STATUS_SUCCESS
;
566 ISubDevice_fnDataRangeIntersection(
567 IN ISubdevice
*iface
,
569 IN PKSDATARANGE DataRange
,
570 IN PKSDATARANGE MatchingDataRange
,
571 IN ULONG OutputBufferLength
,
572 OUT PVOID ResultantFormat OPTIONAL
,
573 OUT PULONG ResultantFormatLength
)
575 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblSubDevice
);
577 DPRINT("ISubDevice_DataRangeIntersection this %p\n", This
);
581 return This
->pMiniport
->lpVtbl
->DataRangeIntersection (This
->pMiniport
, PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
584 return STATUS_UNSUCCESSFUL
;
590 ISubDevice_fnPowerChangeNotify(
591 IN ISubdevice
*iface
,
592 IN POWER_STATE PowerState
)
594 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblSubDevice
);
596 if (This
->pPowerNotify
)
598 This
->pPowerNotify
->lpVtbl
->PowerChangeNotify(This
->pPowerNotify
, PowerState
);
601 return STATUS_SUCCESS
;
607 ISubDevice_fnPinCount(
608 IN ISubdevice
*iface
,
610 IN OUT PULONG FilterNecessary
,
611 IN OUT PULONG FilterCurrent
,
612 IN OUT PULONG FilterPossible
,
613 IN OUT PULONG GlobalCurrent
,
614 IN OUT PULONG GlobalPossible
)
616 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)CONTAINING_RECORD(iface
, IPortWaveRTImpl
, lpVtblSubDevice
);
620 This
->pPinCount
->lpVtbl
->PinCount(This
->pPinCount
, PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
621 return STATUS_SUCCESS
;
625 * scan filter descriptor
627 return STATUS_UNSUCCESSFUL
;
630 static ISubdeviceVtbl vt_ISubdeviceVtbl
=
632 ISubDevice_fnQueryInterface
,
634 ISubDevice_fnRelease
,
635 ISubDevice_fnNewIrpTarget
,
636 ISubDevice_fnReleaseChildren
,
637 ISubDevice_fnGetDescriptor
,
638 ISubDevice_fnDataRangeIntersection
,
639 ISubDevice_fnPowerChangeNotify
,
640 ISubDevice_fnPinCount
644 ///--------------------------------------------------------------
647 IN IPortWaveRT
* iface
)
649 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)iface
;
650 return This
->pMiniport
;
654 GetDeviceObjectFromPortWaveRT(
657 IPortWaveRTImpl
* This
= (IPortWaveRTImpl
*)iface
;
658 return This
->pDeviceObject
;
661 //---------------------------------------------------------------
662 // IPortWaveRT constructor
669 IPortWaveRTImpl
* This
;
671 This
= AllocateItem(NonPagedPool
, sizeof(IPortWaveRTImpl
), TAG_PORTCLASS
);
673 return STATUS_INSUFFICIENT_RESOURCES
;
675 This
->lpVtbl
= &vt_IPortWaveRTVtbl
;
676 This
->lpVtblSubDevice
= &vt_ISubdeviceVtbl
;
677 This
->lpVtblPortEvents
= &vt_IPortEvents
;
679 *OutPort
= (PPORT
)(&This
->lpVtbl
);
681 DPRINT("NewPortWaveRT %p\n", *OutPort
);
683 return STATUS_SUCCESS
;