2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/port_topology.cpp
5 * PURPOSE: Topology Port driver
6 * PROGRAMMER: Johannes Anderwald
11 class CPortTopology
: public IPortTopology
,
16 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
18 STDMETHODIMP_(ULONG
) AddRef()
20 InterlockedIncrement(&m_Ref
);
23 STDMETHODIMP_(ULONG
) Release()
25 InterlockedDecrement(&m_Ref
);
37 CPortTopology(IUnknown
*OuterUnknown
){}
38 virtual ~CPortTopology(){}
43 PMINIPORTTOPOLOGY m_pMiniport
;
44 PDEVICE_OBJECT m_pDeviceObject
;
45 PPINCOUNT m_pPinCount
;
46 PPOWERNOTIFY m_pPowerNotify
;
48 PPCFILTER_DESCRIPTOR m_pDescriptor
;
49 PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor
;
50 IPortFilterTopology
* m_Filter
;
54 friend PMINIPORTTOPOLOGY
GetTopologyMiniport(PPORTTOPOLOGY Port
);
58 static GUID InterfaceGuids
[2] =
62 0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
65 /// KS_CATEGORY_TOPOLOGY
66 0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00}
70 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterTopologyTopologySet
, TopologyPropertyHandler
);
71 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterTopologyPinSet
, PinPropertyHandler
, PinPropertyHandler
, PinPropertyHandler
);
73 KSPROPERTY_SET TopologyPropertySet
[] =
76 &KSPROPSETID_Topology
,
77 sizeof(PortFilterTopologyTopologySet
) / sizeof(KSPROPERTY_ITEM
),
78 (const KSPROPERTY_ITEM
*)&PortFilterTopologyTopologySet
,
84 sizeof(PortFilterTopologyPinSet
) / sizeof(KSPROPERTY_ITEM
),
85 (const KSPROPERTY_ITEM
*)&PortFilterTopologyPinSet
,
91 //---------------------------------------------------------------
98 CPortTopology::AddEventToEventList(
99 IN PKSEVENT_ENTRY EventEntry
)
106 CPortTopology::GenerateEventList(
107 IN GUID
* Set OPTIONAL
,
118 //---------------------------------------------------------------
119 // IUnknown interface functions
124 CPortTopology::QueryInterface(
128 UNICODE_STRING GuidString
;
130 DPRINT("IPortTopology_fnQueryInterface\n");
132 if (IsEqualGUIDAligned(refiid
, IID_IPortTopology
) ||
133 IsEqualGUIDAligned(refiid
, IID_IPort
) ||
134 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
136 *Output
= PVOID(PUNKNOWN((IPortTopology
*)this));
137 PUNKNOWN(*Output
)->AddRef();
138 return STATUS_SUCCESS
;
140 else if (IsEqualGUIDAligned(refiid
, IID_ISubdevice
))
142 *Output
= PVOID(PSUBDEVICE(this));
143 PUNKNOWN(*Output
)->AddRef();
144 return STATUS_SUCCESS
;
146 else if (IsEqualGUIDAligned(refiid
, IID_IPortEvents
))
148 *Output
= PVOID(PPORTEVENTS(this));
149 PUNKNOWN(*Output
)->AddRef();
150 return STATUS_SUCCESS
;
152 else if (IsEqualGUIDAligned(refiid
, IID_IPortClsVersion
))
154 return NewPortClsVersion((PPORTCLSVERSION
*)Output
);
156 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterSubdevice
))
158 return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE
*)Output
);
160 else if (IsEqualGUIDAligned(refiid
, IID_IUnregisterPhysicalConnection
))
162 return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION
*)Output
);
165 if (RtlStringFromGUID(refiid
, &GuidString
) == STATUS_SUCCESS
)
167 DPRINT("IPortTopology_fnQueryInterface no interface!!! iface %S\n", GuidString
.Buffer
);
168 RtlFreeUnicodeString(&GuidString
);
170 return STATUS_UNSUCCESSFUL
;
173 //---------------------------------------------------------------
174 // IPort interface functions
179 CPortTopology::GetDeviceProperty(
180 IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty
,
181 IN ULONG BufferLength
,
182 OUT PVOID PropertyBuffer
,
183 OUT PULONG ReturnLength
)
185 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
189 DPRINT("IPortTopology_fnNewRegistryKey called w/o initiazed\n");
190 return STATUS_UNSUCCESSFUL
;
193 return IoGetDeviceProperty(m_pDeviceObject
, DeviceRegistryProperty
, BufferLength
, PropertyBuffer
, ReturnLength
);
199 IN PDEVICE_OBJECT DeviceObject
,
201 IN PUNKNOWN UnknownMiniport
,
202 IN PUNKNOWN UnknownAdapter OPTIONAL
,
203 IN PRESOURCELIST ResourceList
)
205 IMiniportTopology
* Miniport
;
208 DPRINT("IPortTopology_fnInit entered This %p DeviceObject %p Irp %p UnknownMiniport %p UnknownAdapter %p ResourceList %p\n",
209 this, DeviceObject
, Irp
, UnknownMiniport
, UnknownAdapter
, ResourceList
);
211 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
215 DPRINT("IPortTopology_Init called again\n");
216 return STATUS_SUCCESS
;
219 Status
= UnknownMiniport
->QueryInterface(IID_IMiniportTopology
, (PVOID
*)&Miniport
);
220 if (!NT_SUCCESS(Status
))
222 DPRINT("IPortTopology_Init called with invalid IMiniport adapter\n");
223 return STATUS_INVALID_PARAMETER
;
226 // Initialize port object
227 m_pMiniport
= Miniport
;
228 m_pDeviceObject
= DeviceObject
;
229 m_bInitialized
= TRUE
;
231 // now initialize the miniport driver
232 Status
= Miniport
->Init(UnknownAdapter
, ResourceList
, this);
233 if (!NT_SUCCESS(Status
))
235 DPRINT("IPortTopology_Init failed with %x\n", Status
);
236 m_bInitialized
= FALSE
;
241 // get the miniport device descriptor
242 Status
= Miniport
->GetDescription(&m_pDescriptor
);
243 if (!NT_SUCCESS(Status
))
245 DPRINT("failed to get description\n");
247 m_bInitialized
= FALSE
;
251 // create the subdevice descriptor
252 Status
= PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor
,
268 DPRINT("IPortTopology_fnInit success\n");
269 if (NT_SUCCESS(Status
))
271 // store for node property requests
272 m_SubDeviceDescriptor
->UnknownMiniport
= UnknownMiniport
;
275 return STATUS_SUCCESS
;
281 CPortTopology::NewRegistryKey(
282 OUT PREGISTRYKEY
*OutRegistryKey
,
283 IN PUNKNOWN OuterUnknown OPTIONAL
,
284 IN ULONG RegistryKeyType
,
285 IN ACCESS_MASK DesiredAccess
,
286 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
287 IN ULONG CreateOptions OPTIONAL
,
288 OUT PULONG Disposition OPTIONAL
)
290 PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL
);
294 DPRINT("IPortTopology_fnNewRegistryKey called w/o initialized\n");
295 return STATUS_UNSUCCESSFUL
;
297 return PcNewRegistryKey(OutRegistryKey
,
308 //---------------------------------------------------------------
309 // ISubdevice interface
314 CPortTopology::NewIrpTarget(
315 OUT
struct IIrpTarget
**OutTarget
,
318 IN POOL_TYPE PoolType
,
319 IN PDEVICE_OBJECT DeviceObject
,
321 IN KSOBJECT_CREATE
*CreateObject
)
324 IPortFilterTopology
* Filter
;
326 // is there already an instance of the filter
329 // it is, let's return the result
330 *OutTarget
= (IIrpTarget
*)m_Filter
;
332 // increment reference
334 return STATUS_SUCCESS
;
337 // create new instance of filter
338 Status
= NewPortFilterTopology(&Filter
);
339 if (!NT_SUCCESS(Status
))
345 // initialize the filter
346 Status
= Filter
->Init((IPortTopology
*)this);
347 if (!NT_SUCCESS(Status
))
356 *OutTarget
= (IIrpTarget
*)Filter
;
357 // store for later re-use
365 CPortTopology::ReleaseChildren()
367 DPRINT("ISubDevice_fnReleaseChildren\n");
369 // release the filter
372 // release the miniport
373 DPRINT("Refs %u\n", m_pMiniport
->Release());
375 return STATUS_SUCCESS
;
380 CPortTopology::GetDescriptor(
381 IN SUBDEVICE_DESCRIPTOR
** Descriptor
)
383 DPRINT("ISubDevice_GetDescriptor this %p Descp %p\n", this, m_SubDeviceDescriptor
);
384 *Descriptor
= m_SubDeviceDescriptor
;
385 return STATUS_SUCCESS
;
390 CPortTopology::DataRangeIntersection(
392 IN PKSDATARANGE DataRange
,
393 IN PKSDATARANGE MatchingDataRange
,
394 IN ULONG OutputBufferLength
,
395 OUT PVOID ResultantFormat OPTIONAL
,
396 OUT PULONG ResultantFormatLength
)
398 DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
402 return m_pMiniport
->DataRangeIntersection (PinId
, DataRange
, MatchingDataRange
, OutputBufferLength
, ResultantFormat
, ResultantFormatLength
);
405 return STATUS_UNSUCCESSFUL
;
410 CPortTopology::PowerChangeNotify(
411 IN POWER_STATE PowerState
)
415 m_pPowerNotify
->PowerChangeNotify(PowerState
);
418 return STATUS_SUCCESS
;
423 CPortTopology::PinCount(
425 IN OUT PULONG FilterNecessary
,
426 IN OUT PULONG FilterCurrent
,
427 IN OUT PULONG FilterPossible
,
428 IN OUT PULONG GlobalCurrent
,
429 IN OUT PULONG GlobalPossible
)
433 m_pPinCount
->PinCount(PinId
, FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
);
434 return STATUS_SUCCESS
;
438 // scan filter descriptor
440 return STATUS_UNSUCCESSFUL
;
447 IN PDEVICE_OBJECT DeviceObject
,
453 PKSOBJECT_CREATE_ITEM CreateItem
;
455 // access the create item
456 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
458 PC_ASSERT(CreateItem
);
460 DPRINT("PcCreatePinDispatch called DeviceObject %p %S Name\n", DeviceObject
, CreateItem
->ObjectClass
.Buffer
);
462 Filter
= (IIrpTarget
*)CreateItem
->Context
;
465 PC_ASSERT(Filter
!= NULL
);
466 PC_ASSERT_IRQL(PASSIVE_LEVEL
);
470 Status
= KsReferenceSoftwareBusObject(DeviceExt
->KsDeviceHeader
);
471 if (!NT_SUCCESS(Status
) && Status
!= STATUS_NOT_IMPLEMENTED
)
473 DPRINT("PcCreatePinDispatch failed to reference device header\n");
475 FreeItem(Entry
, TAG_PORTCLASS
);
480 Status
= Filter
->NewIrpTarget(&Pin
,
488 DPRINT("PcCreatePinDispatch Status %x\n", Status
);
490 if (NT_SUCCESS(Status
))
492 // create the dispatch object
493 // FIXME need create item for clock
494 Status
= NewDispatchObject(Irp
, Pin
, 0, NULL
);
495 DPRINT("Pin %p\n", Pin
);
498 DPRINT("CreatePinWorkerRoutine completing irp %p\n", Irp
);
499 // save status in irp
500 Irp
->IoStatus
.Status
= Status
;
501 Irp
->IoStatus
.Information
= 0;
502 // complete the request
503 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
509 PcCreateItemDispatch(
510 IN PDEVICE_OBJECT DeviceObject
,
514 ISubdevice
* SubDevice
;
516 PKSOBJECT_CREATE_ITEM CreateItem
, PinCreateItem
;
518 // access the create item
519 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
521 DPRINT("PcCreateItemDispatch called DeviceObject %p %S Name\n", DeviceObject
, CreateItem
->ObjectClass
.Buffer
);
524 SubDevice
= (ISubdevice
*)CreateItem
->Context
;
527 PC_ASSERT(SubDevice
!= NULL
);
531 Status
= KsReferenceSoftwareBusObject(DeviceExt
->KsDeviceHeader
);
532 if (!NT_SUCCESS(Status
) && Status
!= STATUS_NOT_IMPLEMENTED
)
534 DPRINT("PcCreateItemDispatch failed to reference device header\n");
536 FreeItem(Entry
, TAG_PORTCLASS
);
542 Status
= SubDevice
->NewIrpTarget(&Filter
,
549 if (!NT_SUCCESS(Status
))
551 DPRINT("Failed to get filter object\n");
552 Irp
->IoStatus
.Status
= Status
;
553 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
557 // allocate pin create item
558 PinCreateItem
= (PKSOBJECT_CREATE_ITEM
)AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
), TAG_PORTCLASS
);
562 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
563 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
564 return STATUS_INSUFFICIENT_RESOURCES
;
567 // initialize pin create item
568 PinCreateItem
->Context
= (PVOID
)Filter
;
569 PinCreateItem
->Create
= PcCreatePinDispatch
;
570 RtlInitUnicodeString(&PinCreateItem
->ObjectClass
, KSSTRING_Pin
);
571 // FIXME copy security descriptor
573 // now allocate a dispatch object
574 Status
= NewDispatchObject(Irp
, Filter
, 1, PinCreateItem
);
577 Irp
->IoStatus
.Status
= Status
;
578 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
580 return STATUS_SUCCESS
;
588 CPortTopology
* This
;
591 This
= new(NonPagedPool
, TAG_PORTCLASS
) CPortTopology(NULL
);
593 return STATUS_INSUFFICIENT_RESOURCES
;
595 Status
= This
->QueryInterface(IID_IPort
, (PVOID
*)OutPort
);
597 if (!NT_SUCCESS(Status
))
602 DPRINT("NewPortTopology %p Status %x\n", *OutPort
, Status
);
611 CPortTopology
* This
= (CPortTopology
*)Port
;
612 return This
->m_pMiniport
;