Sync trunk r40500
[reactos.git] / reactos / drivers / wdm / audio / sysaudio / pin.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/sysaudio/deviface.c
5 * PURPOSE: System Audio graph builder
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "sysaudio.h"
10
11 NTSTATUS
12 NTAPI
13 Pin_fnDeviceIoControl(
14 PDEVICE_OBJECT DeviceObject,
15 PIRP Irp)
16 {
17 PDISPATCH_CONTEXT Context;
18 NTSTATUS Status;
19 ULONG BytesReturned;
20 PIO_STACK_LOCATION IoStack;
21
22 DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
23
24 /* Get current stack location */
25 IoStack = IoGetCurrentIrpStackLocation(Irp);
26
27 /* The dispatch context is stored in the FsContext2 member */
28 Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
29
30 /* Sanity check */
31 ASSERT(Context);
32 ASSERT(Context->FileObject != NULL);
33
34 /* Re-dispatch the request to the real target pin */
35 Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
36 IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
37 IoStack->Parameters.DeviceIoControl.InputBufferLength,
38 Irp->UserBuffer,
39 IoStack->Parameters.DeviceIoControl.OutputBufferLength,
40 &BytesReturned);
41
42 /* Save status and information */
43 Irp->IoStatus.Information = BytesReturned;
44 Irp->IoStatus.Status = Status;
45 /* Complete the irp */
46 IoCompleteRequest(Irp, IO_NO_INCREMENT);
47 /* Done */
48 return Status;
49 }
50
51 NTSTATUS
52 NTAPI
53 Pin_fnRead(
54 PDEVICE_OBJECT DeviceObject,
55 PIRP Irp)
56 {
57 PDISPATCH_CONTEXT Context;
58 PIO_STACK_LOCATION IoStack;
59 ULONG BytesReturned;
60 NTSTATUS Status;
61
62 /* Get current stack location */
63 IoStack = IoGetCurrentIrpStackLocation(Irp);
64
65 /* The dispatch context is stored in the FsContext2 member */
66 Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
67
68 /* Sanity check */
69 ASSERT(Context);
70 ASSERT(Context->FileObject != NULL);
71
72 /* Re-dispatch the request to the real target pin */
73 Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_READ_STREAM,
74 MmGetMdlVirtualAddress(Irp->MdlAddress),
75 IoStack->Parameters.Read.Length,
76 NULL,
77 0,
78 &BytesReturned);
79
80 if (Context->hMixerPin && Context->MixerFileObject)
81 {
82 // FIXME
83 // call kmixer to convert stream
84 UNIMPLEMENTED
85 }
86
87 /* Save status and information */
88 Irp->IoStatus.Status = Status;
89 Irp->IoStatus.Information = 0;
90 /* Complete the irp */
91 IoCompleteRequest(Irp, IO_NO_INCREMENT);
92 /* Done */
93 return Status;
94 }
95
96 NTSTATUS
97 NTAPI
98 Pin_fnWrite(
99 PDEVICE_OBJECT DeviceObject,
100 PIRP Irp)
101 {
102 PDISPATCH_CONTEXT Context;
103 PIO_STACK_LOCATION IoStack;
104 ULONG BytesReturned;
105 NTSTATUS Status;
106
107 /* Get current stack location */
108 IoStack = IoGetCurrentIrpStackLocation(Irp);
109
110 /* The dispatch context is stored in the FsContext2 member */
111 Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
112
113 /* Sanity check */
114 ASSERT(Context);
115 ASSERT(Context->FileObject != NULL);
116
117 if (Context->hMixerPin && Context->MixerFileObject)
118 {
119 // FIXME
120 // call kmixer to convert stream
121 UNIMPLEMENTED
122 }
123
124
125 /* Re-dispatch the request to the real target pin */
126 Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
127 MmGetMdlVirtualAddress(Irp->MdlAddress),
128 IoStack->Parameters.Read.Length,
129 NULL,
130 0,
131 &BytesReturned);
132
133 /* Save status and information */
134 Irp->IoStatus.Status = Status;
135 Irp->IoStatus.Information = 0;
136 /* Complete the irp */
137 IoCompleteRequest(Irp, IO_NO_INCREMENT);
138 /* Done */
139 return Status;
140 }
141
142 NTSTATUS
143 NTAPI
144 Pin_fnFlush(
145 PDEVICE_OBJECT DeviceObject,
146 PIRP Irp)
147 {
148 PDISPATCH_CONTEXT Context;
149 PIO_STACK_LOCATION IoStack;
150 PDEVICE_OBJECT PinDeviceObject;
151 PIRP PinIrp;
152 IO_STATUS_BLOCK IoStatus;
153 KEVENT Event;
154 NTSTATUS Status = STATUS_UNSUCCESSFUL;
155
156 /* Get current stack location */
157 IoStack = IoGetCurrentIrpStackLocation(Irp);
158
159 /* The dispatch context is stored in the FsContext2 member */
160 Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
161
162 /* Sanity check */
163 ASSERT(Context);
164 ASSERT(Context->FileObject != NULL);
165
166 /* Get Pin's device object */
167 PinDeviceObject = IoGetRelatedDeviceObject(Context->FileObject);
168
169 /* Initialize notification event */
170 KeInitializeEvent(&Event, NotificationEvent, FALSE);
171
172 /* build target irp */
173 PinIrp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS, PinDeviceObject, NULL, 0, NULL, &Event, &IoStatus);
174 if (PinIrp)
175 {
176
177 /* Get the next stack location */
178 IoStack = IoGetNextIrpStackLocation(PinIrp);
179 /* The file object must be present in the irp as it contains the KSOBJECT_HEADER */
180 IoStack->FileObject = Context->FileObject;
181
182 /* call the driver */
183 Status = IoCallDriver(PinDeviceObject, PinIrp);
184 /* Has request already completed ? */
185 if (Status == STATUS_PENDING)
186 {
187 /* Wait untill the request has completed */
188 KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, NULL);
189 /* Update status */
190 Status = IoStatus.Status;
191 }
192 }
193
194 /* store status */
195 Irp->IoStatus.Status = Status;
196 Irp->IoStatus.Information = 0;
197 /* Complete the irp */
198 IoCompleteRequest(Irp, IO_NO_INCREMENT);
199 /* Done */
200 return Status;
201 }
202
203 NTSTATUS
204 NTAPI
205 Pin_fnClose(
206 PDEVICE_OBJECT DeviceObject,
207 PIRP Irp)
208 {
209 DPRINT1("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
210
211 Irp->IoStatus.Status = STATUS_SUCCESS;
212 Irp->IoStatus.Information = 0;
213 IoCompleteRequest(Irp, IO_NO_INCREMENT);
214 return STATUS_SUCCESS;
215 }
216
217 NTSTATUS
218 NTAPI
219 Pin_fnQuerySecurity(
220 PDEVICE_OBJECT DeviceObject,
221 PIRP Irp)
222 {
223 DPRINT1("Pin_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject);
224
225 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
226 Irp->IoStatus.Information = 0;
227 IoCompleteRequest(Irp, IO_NO_INCREMENT);
228 return STATUS_UNSUCCESSFUL;
229 }
230
231 NTSTATUS
232 NTAPI
233 Pin_fnSetSecurity(
234 PDEVICE_OBJECT DeviceObject,
235 PIRP Irp)
236 {
237
238 DPRINT1("Pin_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject);
239
240 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
241 Irp->IoStatus.Information = 0;
242 IoCompleteRequest(Irp, IO_NO_INCREMENT);
243 return STATUS_UNSUCCESSFUL;
244 }
245
246 BOOLEAN
247 NTAPI
248 Pin_fnFastDeviceIoControl(
249 PFILE_OBJECT FileObject,
250 BOOLEAN Wait,
251 PVOID InputBuffer,
252 ULONG InputBufferLength,
253 PVOID OutputBuffer,
254 ULONG OutputBufferLength,
255 ULONG IoControlCode,
256 PIO_STATUS_BLOCK IoStatus,
257 PDEVICE_OBJECT DeviceObject)
258 {
259 DPRINT1("Pin_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
260
261
262 return FALSE;
263 }
264
265
266 BOOLEAN
267 NTAPI
268 Pin_fnFastRead(
269 PFILE_OBJECT FileObject,
270 PLARGE_INTEGER FileOffset,
271 ULONG Length,
272 BOOLEAN Wait,
273 ULONG LockKey,
274 PVOID Buffer,
275 PIO_STATUS_BLOCK IoStatus,
276 PDEVICE_OBJECT DeviceObject)
277 {
278 DPRINT1("Pin_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject);
279
280 return FALSE;
281
282 }
283
284 BOOLEAN
285 NTAPI
286 Pin_fnFastWrite(
287 PFILE_OBJECT FileObject,
288 PLARGE_INTEGER FileOffset,
289 ULONG Length,
290 BOOLEAN Wait,
291 ULONG LockKey,
292 PVOID Buffer,
293 PIO_STATUS_BLOCK IoStatus,
294 PDEVICE_OBJECT DeviceObject)
295 {
296 PDISPATCH_CONTEXT Context;
297 NTSTATUS Status;
298
299 //DPRINT1("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
300
301 Context = (PDISPATCH_CONTEXT)FileObject->FsContext2;
302
303 if (Context->hMixerPin && Context->MixerFileObject)
304 {
305 Status = KsStreamIo(Context->MixerFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode);
306 if (!NT_SUCCESS(Status))
307 {
308 DPRINT1("Mixing stream failed with %lx\n", Status);
309 return FALSE;
310 }
311 }
312
313 Status = KsStreamIo(Context->FileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode);
314 if (Status == STATUS_SUCCESS)
315 return TRUE;
316 else
317 return FALSE;
318 }
319
320 static KSDISPATCH_TABLE PinTable =
321 {
322 Pin_fnDeviceIoControl,
323 Pin_fnRead,
324 Pin_fnWrite,
325 Pin_fnFlush,
326 Pin_fnClose,
327 Pin_fnQuerySecurity,
328 Pin_fnSetSecurity,
329 Pin_fnFastDeviceIoControl,
330 Pin_fnFastRead,
331 Pin_fnFastWrite,
332 };
333
334 NTSTATUS
335 CreateDispatcher(
336 IN PIRP Irp)
337 {
338 NTSTATUS Status;
339 KSOBJECT_HEADER ObjectHeader;
340
341 /* allocate object header */
342 Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable);
343 return Status;
344 }