2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/propertyhandler.cpp
5 * PURPOSE: Pin property handler
6 * PROGRAMMER: Johannes Anderwald
12 HandlePropertyInstances(
13 IN PIO_STATUS_BLOCK IoStatus
,
14 IN PKSIDENTIFIER Request
,
16 IN PSUBDEVICE_DESCRIPTOR Descriptor
,
18 IN ISubdevice
*SubDevice
)
20 KSPIN_CINSTANCES
* Instances
;
21 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
22 ULONG FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
;
25 if (Pin
->PinId
>= Descriptor
->Factory
.PinDescriptorCount
)
27 IoStatus
->Information
= 0;
28 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
29 return STATUS_INVALID_PARAMETER
;
32 Instances
= (KSPIN_CINSTANCES
*)Data
;
34 // check if the miniport supports the IPinCount interface
35 Status
= SubDevice
->PinCount(Pin
->PinId
, &FilterNecessary
, &FilterCurrent
, &FilterPossible
, &GlobalCurrent
, &GlobalPossible
);
37 if (NT_SUCCESS(Status
))
41 Instances
->PossibleCount
= GlobalPossible
;
42 Instances
->CurrentCount
= GlobalCurrent
;
46 Instances
->PossibleCount
= FilterPossible
;
47 Instances
->CurrentCount
= FilterCurrent
;
53 Instances
->PossibleCount
= Descriptor
->Factory
.Instances
[Pin
->PinId
].MaxGlobalInstanceCount
;
55 Instances
->PossibleCount
= Descriptor
->Factory
.Instances
[Pin
->PinId
].MaxFilterInstanceCount
;
57 Instances
->CurrentCount
= Descriptor
->Factory
.Instances
[Pin
->PinId
].CurrentPinInstanceCount
;
60 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
61 IoStatus
->Status
= STATUS_SUCCESS
;
62 return STATUS_SUCCESS
;
66 HandleNecessaryPropertyInstances(
67 IN PIO_STATUS_BLOCK IoStatus
,
68 IN PKSIDENTIFIER Request
,
70 IN PSUBDEVICE_DESCRIPTOR Descriptor
,
71 IN ISubdevice
*SubDevice
)
74 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
75 ULONG FilterNecessary
, FilterCurrent
, FilterPossible
, GlobalCurrent
, GlobalPossible
;
78 if (Pin
->PinId
>= Descriptor
->Factory
.PinDescriptorCount
)
80 IoStatus
->Information
= 0;
81 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
82 return STATUS_INVALID_PARAMETER
;
85 Result
= (PULONG
)Data
;
88 // check if the miniport supports the IPinCount interface
89 Status
= SubDevice
->PinCount(Pin
->PinId
, &FilterNecessary
, &FilterCurrent
, &FilterPossible
, &GlobalCurrent
, &GlobalPossible
);
91 if (NT_SUCCESS(Status
))
93 *Result
= FilterNecessary
;
97 *Result
= Descriptor
->Factory
.Instances
[Pin
->PinId
].MinFilterInstanceCount
;
100 IoStatus
->Information
= sizeof(ULONG
);
101 IoStatus
->Status
= STATUS_SUCCESS
;
102 return STATUS_SUCCESS
;
106 HandleDataIntersection(
107 IN PIO_STATUS_BLOCK IoStatus
,
108 IN PKSIDENTIFIER Request
,
111 IN PSUBDEVICE_DESCRIPTOR Descriptor
,
112 IN ISubdevice
*SubDevice
)
114 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
115 PKSMULTIPLE_ITEM MultipleItem
;
116 PKSDATARANGE DataRange
;
117 NTSTATUS Status
= STATUS_NO_MATCH
;
121 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
122 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
124 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
126 // Call miniport's properitary handler
127 PC_ASSERT(Descriptor
->Factory
.KsPinDescriptor
[Pin
->PinId
].DataRangesCount
);
128 PC_ASSERT(Descriptor
->Factory
.KsPinDescriptor
[Pin
->PinId
].DataRanges
[0]);
129 Status
= SubDevice
->DataRangeIntersection(Pin
->PinId
, DataRange
, (PKSDATARANGE
)Descriptor
->Factory
.KsPinDescriptor
[Pin
->PinId
].DataRanges
[0],
130 DataLength
, Data
, &Length
);
132 if (Status
== STATUS_SUCCESS
)
134 IoStatus
->Information
= Length
;
137 DataRange
= (PKSDATARANGE
) UlongToPtr(PtrToUlong(DataRange
) + DataRange
->FormatSize
);
140 IoStatus
->Status
= Status
;
145 HandlePhysicalConnection(
146 IN PIO_STATUS_BLOCK IoStatus
,
147 IN PKSIDENTIFIER Request
,
148 IN ULONG RequestLength
,
151 IN PSUBDEVICE_DESCRIPTOR Descriptor
)
155 PKSPIN_PHYSICALCONNECTION Connection
;
156 PPHYSICAL_CONNECTION_ENTRY ConEntry
;
159 Pin
= (PKSP_PIN
)Request
;
161 if (RequestLength
< sizeof(KSP_PIN
))
163 // input buffer must be at least sizeof KSP_PIN
164 DPRINT("input length too small\n");
165 return STATUS_INVALID_PARAMETER
;
168 if (IsListEmpty(&Descriptor
->PhysicalConnectionList
))
170 DPRINT("no connection\n");
171 return STATUS_NOT_FOUND
;
175 Entry
= Descriptor
->PhysicalConnectionList
.Flink
;
179 ConEntry
= (PPHYSICAL_CONNECTION_ENTRY
)CONTAINING_RECORD(Entry
, PHYSICAL_CONNECTION_ENTRY
, Entry
);
181 if (ConEntry
->FromPin
== Pin
->PinId
)
183 Connection
= (PKSPIN_PHYSICALCONNECTION
)Data
;
184 DPRINT("FoundEntry %S Size %u\n", ConEntry
->Connection
.SymbolicLinkName
, ConEntry
->Connection
.Size
);
185 IoStatus
->Information
= ConEntry
->Connection
.Size
;
189 IoStatus
->Information
= ConEntry
->Connection
.Size
;
190 return STATUS_MORE_ENTRIES
;
193 if (DataLength
< ConEntry
->Connection
.Size
)
195 return STATUS_BUFFER_TOO_SMALL
;
198 RtlMoveMemory(Data
, &ConEntry
->Connection
, ConEntry
->Connection
.Size
);
199 return STATUS_SUCCESS
;
203 Entry
= Entry
->Flink
;
204 }while(Entry
!= &Descriptor
->PhysicalConnectionList
);
206 IoStatus
->Information
= 0;
207 return STATUS_NOT_FOUND
;
214 IN PKSIDENTIFIER Request
,
217 PIO_STACK_LOCATION IoStack
;
218 //PKSOBJECT_CREATE_ITEM CreateItem;
219 PSUBDEVICE_DESCRIPTOR Descriptor
;
220 IIrpTarget
* IrpTarget
;
222 ISubdevice
*SubDevice
;
223 PDISPATCH_CONTEXT DispatchContext
;
225 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
227 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
228 PC_ASSERT(Descriptor
);
230 // get current irp stack
231 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
233 // get dispatch context
234 DispatchContext
= (PDISPATCH_CONTEXT
)IoStack
->FileObject
->FsContext
;
237 IrpTarget
= DispatchContext
->Target
;
238 PC_ASSERT(IrpTarget
);
241 Status
= IrpTarget
->QueryInterface(IID_IPort
, (PVOID
*)&Port
);
242 if (!NT_SUCCESS(Status
))
244 DPRINT("Failed to obtain IPort interface from filter\n");
245 Irp
->IoStatus
.Information
= 0;
246 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
247 return STATUS_UNSUCCESSFUL
;
250 // Get private ISubdevice interface
251 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&SubDevice
);
252 if (!NT_SUCCESS(Status
))
254 DPRINT("Failed to obtain ISubdevice interface from port driver\n");
259 // get current stack location
260 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
264 case KSPROPERTY_PIN_CTYPES
:
265 case KSPROPERTY_PIN_DATAFLOW
:
266 case KSPROPERTY_PIN_DATARANGES
:
267 case KSPROPERTY_PIN_INTERFACES
:
268 case KSPROPERTY_PIN_MEDIUMS
:
269 case KSPROPERTY_PIN_COMMUNICATION
:
270 case KSPROPERTY_PIN_CATEGORY
:
271 case KSPROPERTY_PIN_NAME
:
272 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
273 Status
= KsPinPropertyHandler(Irp
, Request
, Data
, Descriptor
->Factory
.PinDescriptorCount
, Descriptor
->Factory
.KsPinDescriptor
);
275 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
276 Status
= HandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, Descriptor
, TRUE
, SubDevice
);
278 case KSPROPERTY_PIN_CINSTANCES
:
279 Status
= HandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, Descriptor
, FALSE
, SubDevice
);
281 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
282 Status
= HandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, Descriptor
, SubDevice
);
285 case KSPROPERTY_PIN_DATAINTERSECTION
:
286 Status
= HandleDataIntersection(&Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, Descriptor
, SubDevice
);
288 case KSPROPERTY_PIN_PHYSICALCONNECTION
:
289 Status
= HandlePhysicalConnection(&Irp
->IoStatus
, Request
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, Descriptor
);
291 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
293 Status
= STATUS_NOT_IMPLEMENTED
;
297 Status
= STATUS_UNSUCCESSFUL
;
303 // Release subdevice reference
304 SubDevice
->Release();
311 TopologyPropertyHandler(
313 IN PKSIDENTIFIER Request
,
316 PSUBDEVICE_DESCRIPTOR Descriptor
;
318 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
320 return KsTopologyPropertyHandler(Irp
, Request
, Data
, Descriptor
->Topology
);