1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/legacy/stream/filter.c
5 * PURPOSE: filter instance handling
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9
10 #include "stream.h"
11
12
13 NTSTATUS
14 NTAPI
StreamClassCreatePin(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)15 StreamClassCreatePin(
16 IN PDEVICE_OBJECT DeviceObject,
17 IN PIRP Irp)
18 {
19 UNIMPLEMENTED;
20
21 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
22 Irp->IoStatus.Information = 0;
23 IoCompleteRequest(Irp, IO_NO_INCREMENT);
24 return STATUS_NOT_IMPLEMENTED;
25 }
26
27
28 NTSTATUS
29 NTAPI
FilterDispatch_fnDeviceIoControl(PDEVICE_OBJECT DeviceObject,PIRP Irp)30 FilterDispatch_fnDeviceIoControl(
31 PDEVICE_OBJECT DeviceObject,
32 PIRP Irp)
33 {
34 DPRINT1("FilterDispatch Called\n");
35
36 Irp->IoStatus.Status = STATUS_SUCCESS;
37 Irp->IoStatus.Information = 0;
38 IoCompleteRequest(Irp, IO_NO_INCREMENT);
39 return STATUS_SUCCESS;
40 }
41
42
43 NTSTATUS
44 NTAPI
FilterDispatch_fnClose(PDEVICE_OBJECT DeviceObject,PIRP Irp)45 FilterDispatch_fnClose(
46 PDEVICE_OBJECT DeviceObject,
47 PIRP Irp)
48 {
49 NTSTATUS Status = STATUS_SUCCESS;
50 PSTREAM_DEVICE_EXTENSION DeviceExtension;
51 HW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
52
53 /* Get device extension */
54 DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
55
56 if (!DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize)
57 {
58 /* driver supports only one instance */
59 if (DeviceExtension->InstanceCount)
60 {
61 /* there is already one instance open */
62 return STATUS_UNSUCCESSFUL;
63 }
64 }
65 else
66 {
67 /* driver supports more than one filter instance */
68 RtlZeroMemory(&RequestBlock, sizeof(HW_STREAM_REQUEST_BLOCK_EXT));
69
70 /* set up request block */
71 RequestBlock.Block.Command = SRB_CLOSE_DEVICE_INSTANCE;
72 RequestBlock.Block.HwDeviceExtension = DeviceExtension->DeviceExtension;
73 RequestBlock.Block.Irp = Irp;
74 KeInitializeEvent(&RequestBlock.Event, SynchronizationEvent, FALSE);
75
76 /*FIXME SYNCHRONIZATION */
77
78 /* Send the request */
79 DeviceExtension->DriverExtension->Data.HwReceivePacket((PHW_STREAM_REQUEST_BLOCK)&RequestBlock);
80 if (RequestBlock.Block.Status == STATUS_PENDING)
81 {
82 /* Wait for the request */
83 KeWaitForSingleObject(&RequestBlock.Event, Executive, KernelMode, FALSE, NULL);
84 }
85 }
86
87 /* Increment total instance count */
88 InterlockedDecrement(&DeviceExtension->InstanceCount);
89
90 Irp->IoStatus.Status = Status;
91 Irp->IoStatus.Information = 0;
92 IoCompleteRequest(Irp, IO_NO_INCREMENT);
93 return Status;
94 }
95
96 static KSDISPATCH_TABLE DispatchTable =
97 {
98 FilterDispatch_fnDeviceIoControl,
99 KsDispatchInvalidDeviceRequest,
100 KsDispatchInvalidDeviceRequest,
101 KsDispatchInvalidDeviceRequest,
102 FilterDispatch_fnClose,
103 NULL,
104 NULL,
105 NULL,
106 NULL,
107 NULL
108 };
109
110 VOID
RegisterDeviceInterfaces(IN PSTREAM_DEVICE_EXTENSION DeviceExtension)111 RegisterDeviceInterfaces(
112 IN PSTREAM_DEVICE_EXTENSION DeviceExtension)
113 {
114 ULONG Index;
115 PHW_STREAM_INFORMATION StreamInformation;
116 UNICODE_STRING SymbolicLink;
117 NTSTATUS Status;
118
119 /* Sanity check */
120 ASSERT(DeviceExtension->StreamDescriptor);
121 ASSERT(DeviceExtension->StreamDescriptorSize);
122
123 /* Loop all stream descriptors and register device interfaces */
124 StreamInformation = (PHW_STREAM_INFORMATION)&DeviceExtension->StreamDescriptor->StreamInfo;
125
126 for(Index = 0; DeviceExtension->StreamDescriptor->StreamHeader.NumberOfStreams; Index++)
127 {
128 if (StreamInformation->Category)
129 {
130 /* Register device interface */
131 Status = IoRegisterDeviceInterface(DeviceExtension->PhysicalDeviceObject,
132 StreamInformation->Category,
133 NULL, /* see CORE-4218 and r42457 */
134 &SymbolicLink);
135
136 if (NT_SUCCESS(Status))
137 {
138 /* Activate device interface */
139 IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
140 /* Release Symbolic Link */
141 RtlFreeUnicodeString(&SymbolicLink);
142 }
143 }
144 StreamInformation = (PHW_STREAM_INFORMATION) (ULONG_PTR)StreamInformation + DeviceExtension->StreamDescriptor->StreamHeader.SizeOfHwStreamInformation;
145 }
146
147 }
148
149 NTSTATUS
InitializeFilterWithKs(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)150 InitializeFilterWithKs(
151 IN PDEVICE_OBJECT DeviceObject,
152 IN PIRP Irp)
153 {
154 NTSTATUS Status;
155 PSTREAM_DEVICE_EXTENSION DeviceExtension;
156 KSOBJECT_HEADER ObjectHeader;
157 PKSOBJECT_CREATE_ITEM CreateItem;
158 PIO_STACK_LOCATION IoStack;
159 HW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
160 PVOID HwInstanceExtension = NULL;
161
162 /* Get device extension */
163 DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
164
165 if (!DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize)
166 {
167 /* driver supports only one instance */
168 if (DeviceExtension->InstanceCount)
169 {
170 /* there is already one instance open */
171 return STATUS_UNSUCCESSFUL;
172 }
173 }
174 else
175 {
176 /* driver supports more than one filter instance */
177 RtlZeroMemory(&RequestBlock, sizeof(HW_STREAM_REQUEST_BLOCK_EXT));
178
179 /* allocate instance extension */
180 HwInstanceExtension = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize);
181 if (!HwInstanceExtension)
182 {
183 /* Not enough memory */
184 return STATUS_INSUFFICIENT_RESOURCES;
185 }
186
187 /* Zero instance extension */
188 RtlZeroMemory(HwInstanceExtension, DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize);
189
190 /* set up request block */
191 RequestBlock.Block.Command = SRB_OPEN_DEVICE_INSTANCE;
192 RequestBlock.Block.HwDeviceExtension = DeviceExtension->DeviceExtension;
193 RequestBlock.Block.Irp = Irp;
194 RequestBlock.Block.HwInstanceExtension = HwInstanceExtension;
195 KeInitializeEvent(&RequestBlock.Event, SynchronizationEvent, FALSE);
196
197 /*FIXME SYNCHRONIZATION */
198
199 /* Send the request */
200 DeviceExtension->DriverExtension->Data.HwReceivePacket((PHW_STREAM_REQUEST_BLOCK)&RequestBlock);
201 if (RequestBlock.Block.Status == STATUS_PENDING)
202 {
203 /* Wait for the request */
204 KeWaitForSingleObject(&RequestBlock.Event, Executive, KernelMode, FALSE, NULL);
205 }
206 /* Check for success */
207 if (!NT_SUCCESS(RequestBlock.Block.Status))
208 {
209 /* Resource is not available */
210 ExFreePool(HwInstanceExtension);
211 return RequestBlock.Block.Status;
212 }
213 }
214
215 /* Allocate create item */
216 CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
217 if (!CreateItem)
218 {
219 /* not enough memory */
220 return STATUS_INSUFFICIENT_RESOURCES;
221 }
222
223 /* Zero create item */
224 RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
225 /* Initialize createitem */
226 RtlInitUnicodeString(&CreateItem->ObjectClass, KSSTRING_Pin);
227 CreateItem->Create = StreamClassCreatePin;
228
229 /* Get current irp stack location */
230 IoStack = IoGetCurrentIrpStackLocation(Irp);
231 /* Create Ks streaming object header */
232 Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
233 if (!NT_SUCCESS(Status))
234 {
235 /* Failed to create header */
236 ExFreePool(CreateItem);
237 if (HwInstanceExtension)
238 {
239 /* free instance buffer */
240 ExFreePool(HwInstanceExtension);
241 }
242 return Status;
243 }
244
245 /* Store instance buffer in file object context */
246 IoStack->FileObject->FsContext2 = HwInstanceExtension;
247
248 /* Increment total instance count */
249 InterlockedIncrement(&DeviceExtension->InstanceCount);
250
251 /* Register device stream interfaces */
252 RegisterDeviceInterfaces(DeviceExtension);
253
254 /* Return result */
255 return Status;
256
257 }
258
259 NTSTATUS
260 NTAPI
StreamClassCreateFilter(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)261 StreamClassCreateFilter(
262 IN PDEVICE_OBJECT DeviceObject,
263 IN PIRP Irp)
264 {
265 NTSTATUS Status;
266 DPRINT1("StreamClassCreateFilter Called\n");
267
268 /* Init filter */
269 Status = InitializeFilterWithKs(DeviceObject, Irp);
270
271 Irp->IoStatus.Status = Status;
272 Irp->IoStatus.Information = 0;
273 IoCompleteRequest(Irp, IO_NO_INCREMENT);
274 return Status;
275 }
276
277
278
279