Sync with trunk head (part 1 or 2)
[reactos.git] / drivers / wdm / audio / backpln / portcls / propertyhandler.cpp
1 /*
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
7 */
8
9 #include "private.hpp"
10
11 NTSTATUS
12 HandlePropertyInstances(
13 IN PIO_STATUS_BLOCK IoStatus,
14 IN PKSIDENTIFIER Request,
15 IN OUT PVOID Data,
16 IN PSUBDEVICE_DESCRIPTOR Descriptor,
17 IN BOOL Global)
18 {
19 KSPIN_CINSTANCES * Instances;
20 KSP_PIN * Pin = (KSP_PIN*)Request;
21
22 if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
23 {
24 IoStatus->Information = 0;
25 IoStatus->Status = STATUS_INVALID_PARAMETER;
26 return STATUS_INVALID_PARAMETER;
27 }
28
29 Instances = (KSPIN_CINSTANCES*)Data;
30
31 if (Global)
32 Instances->PossibleCount = Descriptor->Factory.Instances[Pin->PinId].MaxGlobalInstanceCount;
33 else
34 Instances->PossibleCount = Descriptor->Factory.Instances[Pin->PinId].MaxFilterInstanceCount;
35
36 Instances->CurrentCount = Descriptor->Factory.Instances[Pin->PinId].CurrentPinInstanceCount;
37
38 IoStatus->Information = sizeof(KSPIN_CINSTANCES);
39 IoStatus->Status = STATUS_SUCCESS;
40 return STATUS_SUCCESS;
41 }
42
43 NTSTATUS
44 HandleNecessaryPropertyInstances(
45 IN PIO_STATUS_BLOCK IoStatus,
46 IN PKSIDENTIFIER Request,
47 IN OUT PVOID Data,
48 IN PSUBDEVICE_DESCRIPTOR Descriptor)
49 {
50 PULONG Result;
51 KSP_PIN * Pin = (KSP_PIN*)Request;
52
53 if (Pin->PinId >= Descriptor->Factory.PinDescriptorCount)
54 {
55 IoStatus->Information = 0;
56 IoStatus->Status = STATUS_INVALID_PARAMETER;
57 return STATUS_INVALID_PARAMETER;
58 }
59
60 Result = (PULONG)Data;
61 *Result = Descriptor->Factory.Instances[Pin->PinId].MinFilterInstanceCount;
62
63 IoStatus->Information = sizeof(ULONG);
64 IoStatus->Status = STATUS_SUCCESS;
65 return STATUS_SUCCESS;
66 }
67
68 NTSTATUS
69 HandleDataIntersection(
70 IN PIO_STATUS_BLOCK IoStatus,
71 IN PKSIDENTIFIER Request,
72 IN OUT PVOID Data,
73 IN ULONG DataLength,
74 IN PSUBDEVICE_DESCRIPTOR Descriptor,
75 IN ISubdevice *SubDevice)
76 {
77 KSP_PIN * Pin = (KSP_PIN*)Request;
78 PKSMULTIPLE_ITEM MultipleItem;
79 PKSDATARANGE DataRange;
80 NTSTATUS Status = STATUS_NO_MATCH;
81 ULONG Index, Length;
82
83 // Access parameters
84 MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
85 DataRange = (PKSDATARANGE)(MultipleItem + 1);
86
87 for(Index = 0; Index < MultipleItem->Count; Index++)
88 {
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);
94
95 if (Status == STATUS_SUCCESS)
96 {
97 IoStatus->Information = Length;
98 break;
99 }
100 DataRange = (PKSDATARANGE) UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize);
101 }
102
103 IoStatus->Status = Status;
104 return Status;
105 }
106
107 NTSTATUS
108 HandlePhysicalConnection(
109 IN PIO_STATUS_BLOCK IoStatus,
110 IN PKSIDENTIFIER Request,
111 IN ULONG RequestLength,
112 IN OUT PVOID Data,
113 IN ULONG DataLength,
114 IN PSUBDEVICE_DESCRIPTOR Descriptor)
115 {
116 PKSP_PIN Pin;
117 PLIST_ENTRY Entry;
118 PKSPIN_PHYSICALCONNECTION Connection;
119 PPHYSICAL_CONNECTION_ENTRY ConEntry;
120
121 // get pin
122 Pin = (PKSP_PIN)Request;
123
124 if (RequestLength < sizeof(KSP_PIN))
125 {
126 // input buffer must be at least sizeof KSP_PIN
127 DPRINT("input length too small\n");
128 return STATUS_INVALID_PARAMETER;
129 }
130
131 if (IsListEmpty(&Descriptor->PhysicalConnectionList))
132 {
133 DPRINT("no connection\n");
134 return STATUS_NOT_FOUND;
135 }
136
137 // get first item
138 Entry = Descriptor->PhysicalConnectionList.Flink;
139
140 do
141 {
142 ConEntry = (PPHYSICAL_CONNECTION_ENTRY)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION_ENTRY, Entry);
143
144 if (ConEntry->FromPin == Pin->PinId)
145 {
146 Connection = (PKSPIN_PHYSICALCONNECTION)Data;
147 DPRINT("FoundEntry %S Size %u\n", ConEntry->Connection.SymbolicLinkName, ConEntry->Connection.Size);
148 IoStatus->Information = ConEntry->Connection.Size;
149
150 if (!DataLength)
151 {
152 IoStatus->Information = ConEntry->Connection.Size;
153 return STATUS_MORE_ENTRIES;
154 }
155
156 if (DataLength < ConEntry->Connection.Size)
157 {
158 return STATUS_BUFFER_TOO_SMALL;
159 }
160
161 RtlMoveMemory(Data, &ConEntry->Connection, ConEntry->Connection.Size);
162 return STATUS_SUCCESS;
163 }
164
165 // move to next item
166 Entry = Entry->Flink;
167 }while(Entry != &Descriptor->PhysicalConnectionList);
168
169 IoStatus->Information = 0;
170 return STATUS_NOT_FOUND;
171 }
172
173 NTSTATUS
174 NTAPI
175 PinPropertyHandler(
176 IN PIRP Irp,
177 IN PKSIDENTIFIER Request,
178 IN OUT PVOID Data)
179 {
180 PIO_STACK_LOCATION IoStack;
181 //PKSOBJECT_CREATE_ITEM CreateItem;
182 PSUBDEVICE_DESCRIPTOR Descriptor;
183 IIrpTarget * IrpTarget;
184 IPort *Port;
185 ISubdevice *SubDevice;
186 PDISPATCH_CONTEXT DispatchContext;
187
188 NTSTATUS Status = STATUS_UNSUCCESSFUL;
189
190 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
191 PC_ASSERT(Descriptor);
192
193 // get current irp stack
194 IoStack = IoGetCurrentIrpStackLocation(Irp);
195
196 // get dispatch context
197 DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
198
199 // Get the IrpTarget
200 IrpTarget = DispatchContext->Target;
201 PC_ASSERT(IrpTarget);
202
203 // Get the parent
204 Status = IrpTarget->QueryInterface(IID_IPort, (PVOID*)&Port);
205 if (!NT_SUCCESS(Status))
206 {
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;
211 }
212
213 // Get private ISubdevice interface
214 Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice);
215 if (!NT_SUCCESS(Status))
216 {
217 DPRINT("Failed to obtain ISubdevice interface from port driver\n");
218 DbgBreakPoint();
219 while(TRUE);
220 }
221
222 // get current stack location
223 IoStack = IoGetCurrentIrpStackLocation(Irp);
224
225 switch(Request->Id)
226 {
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);
237 break;
238 case KSPROPERTY_PIN_GLOBALCINSTANCES:
239 Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, TRUE);
240 break;
241 case KSPROPERTY_PIN_CINSTANCES:
242 Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, FALSE);
243 break;
244 case KSPROPERTY_PIN_NECESSARYINSTANCES:
245 Status = HandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, Descriptor);
246 break;
247
248 case KSPROPERTY_PIN_DATAINTERSECTION:
249 Status = HandleDataIntersection(&Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor, SubDevice);
250 break;
251 case KSPROPERTY_PIN_PHYSICALCONNECTION:
252 Status = HandlePhysicalConnection(&Irp->IoStatus, Request, IoStack->Parameters.DeviceIoControl.InputBufferLength, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor);
253 break;
254 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
255 UNIMPLEMENTED
256 Status = STATUS_NOT_IMPLEMENTED;
257 break;
258 default:
259 UNIMPLEMENTED
260 Status = STATUS_UNSUCCESSFUL;
261 }
262
263 // Release reference
264 Port->Release();
265
266 // Release subdevice reference
267 SubDevice->Release();
268
269 return Status;
270 }
271
272 NTSTATUS
273 NTAPI
274 TopologyPropertyHandler(
275 IN PIRP Irp,
276 IN PKSIDENTIFIER Request,
277 IN OUT PVOID Data)
278 {
279 PSUBDEVICE_DESCRIPTOR Descriptor;
280
281 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
282
283 return KsTopologyPropertyHandler(Irp, Request, Data, Descriptor->Topology);
284 }