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
,
19 KSPIN_CINSTANCES
* Instances
;
20 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
22 if (Pin
->PinId
>= Descriptor
->Factory
.PinDescriptorCount
)
24 IoStatus
->Information
= 0;
25 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
26 return STATUS_INVALID_PARAMETER
;
29 Instances
= (KSPIN_CINSTANCES
*)Data
;
32 Instances
->PossibleCount
= Descriptor
->Factory
.Instances
[Pin
->PinId
].MaxGlobalInstanceCount
;
34 Instances
->PossibleCount
= Descriptor
->Factory
.Instances
[Pin
->PinId
].MaxFilterInstanceCount
;
36 Instances
->CurrentCount
= Descriptor
->Factory
.Instances
[Pin
->PinId
].CurrentPinInstanceCount
;
38 IoStatus
->Information
= sizeof(KSPIN_CINSTANCES
);
39 IoStatus
->Status
= STATUS_SUCCESS
;
40 return STATUS_SUCCESS
;
44 HandleNecessaryPropertyInstances(
45 IN PIO_STATUS_BLOCK IoStatus
,
46 IN PKSIDENTIFIER Request
,
48 IN PSUBDEVICE_DESCRIPTOR Descriptor
)
51 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
53 if (Pin
->PinId
>= Descriptor
->Factory
.PinDescriptorCount
)
55 IoStatus
->Information
= 0;
56 IoStatus
->Status
= STATUS_INVALID_PARAMETER
;
57 return STATUS_INVALID_PARAMETER
;
60 Result
= (PULONG
)Data
;
61 *Result
= Descriptor
->Factory
.Instances
[Pin
->PinId
].MinFilterInstanceCount
;
63 IoStatus
->Information
= sizeof(ULONG
);
64 IoStatus
->Status
= STATUS_SUCCESS
;
65 return STATUS_SUCCESS
;
69 HandleDataIntersection(
70 IN PIO_STATUS_BLOCK IoStatus
,
71 IN PKSIDENTIFIER Request
,
74 IN PSUBDEVICE_DESCRIPTOR Descriptor
,
75 IN ISubdevice
*SubDevice
)
77 KSP_PIN
* Pin
= (KSP_PIN
*)Request
;
78 PKSMULTIPLE_ITEM MultipleItem
;
79 PKSDATARANGE DataRange
;
80 NTSTATUS Status
= STATUS_NO_MATCH
;
84 MultipleItem
= (PKSMULTIPLE_ITEM
)(Pin
+ 1);
85 DataRange
= (PKSDATARANGE
)(MultipleItem
+ 1);
87 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
89 // Call miniport's properitary handler
90 PC_ASSERT(Descriptor
->Factory
.KsPinDescriptor
[Pin
->PinId
].DataRangesCount
);
91 PC_ASSERT(Descriptor
->Factory
.KsPinDescriptor
[Pin
->PinId
].DataRanges
[0]);
92 Status
= SubDevice
->DataRangeIntersection(Pin
->PinId
, DataRange
, (PKSDATARANGE
)Descriptor
->Factory
.KsPinDescriptor
[Pin
->PinId
].DataRanges
[0],
93 DataLength
, Data
, &Length
);
95 if (Status
== STATUS_SUCCESS
)
97 IoStatus
->Information
= Length
;
100 DataRange
= (PKSDATARANGE
) UlongToPtr(PtrToUlong(DataRange
) + DataRange
->FormatSize
);
103 IoStatus
->Status
= Status
;
108 HandlePhysicalConnection(
109 IN PIO_STATUS_BLOCK IoStatus
,
110 IN PKSIDENTIFIER Request
,
111 IN ULONG RequestLength
,
114 IN PSUBDEVICE_DESCRIPTOR Descriptor
)
118 PKSPIN_PHYSICALCONNECTION Connection
;
119 PPHYSICAL_CONNECTION_ENTRY ConEntry
;
122 Pin
= (PKSP_PIN
)Request
;
124 if (RequestLength
< sizeof(KSP_PIN
))
126 // input buffer must be at least sizeof KSP_PIN
127 DPRINT("input length too small\n");
128 return STATUS_INVALID_PARAMETER
;
131 if (IsListEmpty(&Descriptor
->PhysicalConnectionList
))
133 DPRINT("no connection\n");
134 return STATUS_NOT_FOUND
;
138 Entry
= Descriptor
->PhysicalConnectionList
.Flink
;
142 ConEntry
= (PPHYSICAL_CONNECTION_ENTRY
)CONTAINING_RECORD(Entry
, PHYSICAL_CONNECTION_ENTRY
, Entry
);
144 if (ConEntry
->FromPin
== Pin
->PinId
)
146 Connection
= (PKSPIN_PHYSICALCONNECTION
)Data
;
147 DPRINT("FoundEntry %S Size %u\n", ConEntry
->Connection
.SymbolicLinkName
, ConEntry
->Connection
.Size
);
148 IoStatus
->Information
= ConEntry
->Connection
.Size
;
152 IoStatus
->Information
= ConEntry
->Connection
.Size
;
153 return STATUS_MORE_ENTRIES
;
156 if (DataLength
< ConEntry
->Connection
.Size
)
158 return STATUS_BUFFER_TOO_SMALL
;
161 RtlMoveMemory(Data
, &ConEntry
->Connection
, ConEntry
->Connection
.Size
);
162 return STATUS_SUCCESS
;
166 Entry
= Entry
->Flink
;
167 }while(Entry
!= &Descriptor
->PhysicalConnectionList
);
169 IoStatus
->Information
= 0;
170 return STATUS_NOT_FOUND
;
177 IN PKSIDENTIFIER Request
,
180 PIO_STACK_LOCATION IoStack
;
181 //PKSOBJECT_CREATE_ITEM CreateItem;
182 PSUBDEVICE_DESCRIPTOR Descriptor
;
183 IIrpTarget
* IrpTarget
;
185 ISubdevice
*SubDevice
;
186 PDISPATCH_CONTEXT DispatchContext
;
188 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
190 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
191 PC_ASSERT(Descriptor
);
193 // get current irp stack
194 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
196 // get dispatch context
197 DispatchContext
= (PDISPATCH_CONTEXT
)IoStack
->FileObject
->FsContext
;
200 IrpTarget
= DispatchContext
->Target
;
201 PC_ASSERT(IrpTarget
);
204 Status
= IrpTarget
->QueryInterface(IID_IPort
, (PVOID
*)&Port
);
205 if (!NT_SUCCESS(Status
))
207 DPRINT("Failed to obtain IPort interface from filter\n");
208 Irp
->IoStatus
.Information
= 0;
209 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
210 return STATUS_UNSUCCESSFUL
;
213 // Get private ISubdevice interface
214 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&SubDevice
);
215 if (!NT_SUCCESS(Status
))
217 DPRINT("Failed to obtain ISubdevice interface from port driver\n");
222 // get current stack location
223 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
227 case KSPROPERTY_PIN_CTYPES
:
228 case KSPROPERTY_PIN_DATAFLOW
:
229 case KSPROPERTY_PIN_DATARANGES
:
230 case KSPROPERTY_PIN_INTERFACES
:
231 case KSPROPERTY_PIN_MEDIUMS
:
232 case KSPROPERTY_PIN_COMMUNICATION
:
233 case KSPROPERTY_PIN_CATEGORY
:
234 case KSPROPERTY_PIN_NAME
:
235 case KSPROPERTY_PIN_PROPOSEDATAFORMAT
:
236 Status
= KsPinPropertyHandler(Irp
, Request
, Data
, Descriptor
->Factory
.PinDescriptorCount
, Descriptor
->Factory
.KsPinDescriptor
);
238 case KSPROPERTY_PIN_GLOBALCINSTANCES
:
239 Status
= HandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, Descriptor
, TRUE
);
241 case KSPROPERTY_PIN_CINSTANCES
:
242 Status
= HandlePropertyInstances(&Irp
->IoStatus
, Request
, Data
, Descriptor
, FALSE
);
244 case KSPROPERTY_PIN_NECESSARYINSTANCES
:
245 Status
= HandleNecessaryPropertyInstances(&Irp
->IoStatus
, Request
, Data
, Descriptor
);
248 case KSPROPERTY_PIN_DATAINTERSECTION
:
249 Status
= HandleDataIntersection(&Irp
->IoStatus
, Request
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, Descriptor
, SubDevice
);
251 case KSPROPERTY_PIN_PHYSICALCONNECTION
:
252 Status
= HandlePhysicalConnection(&Irp
->IoStatus
, Request
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
, Data
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, Descriptor
);
254 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES
:
256 Status
= STATUS_NOT_IMPLEMENTED
;
260 Status
= STATUS_UNSUCCESSFUL
;
266 // Release subdevice reference
267 SubDevice
->Release();
274 TopologyPropertyHandler(
276 IN PKSIDENTIFIER Request
,
279 PSUBDEVICE_DESCRIPTOR Descriptor
;
281 Descriptor
= (PSUBDEVICE_DESCRIPTOR
)KSPROPERTY_ITEM_IRP_STORAGE(Irp
);
283 return KsTopologyPropertyHandler(Irp
, Request
, Data
, Descriptor
->Topology
);