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
13 Pin_fnDeviceIoControl(
14 PDEVICE_OBJECT DeviceObject
,
17 PDISPATCH_CONTEXT Context
;
20 PFILE_OBJECT FileObject
;
21 PIO_STACK_LOCATION IoStack
;
23 DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject
);
25 /* Get current stack location */
26 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
28 /* The dispatch context is stored in the FsContext2 member */
29 Context
= (PDISPATCH_CONTEXT
)IoStack
->FileObject
->FsContext2
;
34 /* acquire real pin file object */
35 Status
= ObReferenceObjectByHandle(Context
->Handle
, GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
36 if (!NT_SUCCESS(Status
))
38 Irp
->IoStatus
.Information
= 0;
39 Irp
->IoStatus
.Status
= Status
;
40 /* Complete the irp */
41 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
45 /* Re-dispatch the request to the real target pin */
46 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IoStack
->Parameters
.DeviceIoControl
.IoControlCode
,
47 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
,
48 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
,
50 IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
52 /* release file object */
53 ObDereferenceObject(FileObject
);
55 /* Save status and information */
56 Irp
->IoStatus
.Information
= BytesReturned
;
57 Irp
->IoStatus
.Status
= Status
;
58 /* Complete the irp */
59 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
67 PDEVICE_OBJECT DeviceObject
,
70 PDISPATCH_CONTEXT Context
;
71 PIO_STACK_LOCATION IoStack
;
73 PFILE_OBJECT FileObject
;
76 /* Get current stack location */
77 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
79 /* The dispatch context is stored in the FsContext2 member */
80 Context
= (PDISPATCH_CONTEXT
)IoStack
->FileObject
->FsContext2
;
85 /* acquire real pin file object */
86 Status
= ObReferenceObjectByHandle(Context
->Handle
, GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
87 if (!NT_SUCCESS(Status
))
89 Irp
->IoStatus
.Information
= 0;
90 Irp
->IoStatus
.Status
= Status
;
91 /* Complete the irp */
92 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
96 /* Re-dispatch the request to the real target pin */
97 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_READ_STREAM
,
98 MmGetMdlVirtualAddress(Irp
->MdlAddress
),
99 IoStack
->Parameters
.Read
.Length
,
104 /* release file object */
105 ObDereferenceObject(FileObject
);
107 if (Context
->hMixerPin
)
110 // call kmixer to convert stream
114 /* Save status and information */
115 Irp
->IoStatus
.Status
= Status
;
116 Irp
->IoStatus
.Information
= 0;
117 /* Complete the irp */
118 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
126 PDEVICE_OBJECT DeviceObject
,
129 PDISPATCH_CONTEXT Context
;
130 PIO_STACK_LOCATION IoStack
;
131 PFILE_OBJECT FileObject
;
135 /* Get current stack location */
136 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
138 /* The dispatch context is stored in the FsContext2 member */
139 Context
= (PDISPATCH_CONTEXT
)IoStack
->FileObject
->FsContext2
;
144 if (Context
->hMixerPin
)
147 // call kmixer to convert stream
151 /* acquire real pin file object */
152 Status
= ObReferenceObjectByHandle(Context
->Handle
, GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
153 if (!NT_SUCCESS(Status
))
155 Irp
->IoStatus
.Information
= 0;
156 Irp
->IoStatus
.Status
= Status
;
157 /* Complete the irp */
158 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
162 /* call the portcls audio pin */
163 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_WRITE_STREAM
,
164 MmGetMdlVirtualAddress(Irp
->MdlAddress
),
165 IoStack
->Parameters
.Write
.Length
,
171 /* Release file object */
172 ObDereferenceObject(FileObject
);
174 /* Save status and information */
175 Irp
->IoStatus
.Status
= Status
;
176 Irp
->IoStatus
.Information
= BytesReturned
;
177 /* Complete the irp */
178 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
186 PDEVICE_OBJECT DeviceObject
,
189 PDISPATCH_CONTEXT Context
;
190 PIO_STACK_LOCATION IoStack
;
191 PDEVICE_OBJECT PinDeviceObject
;
193 PFILE_OBJECT FileObject
;
194 IO_STATUS_BLOCK IoStatus
;
196 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
198 /* Get current stack location */
199 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
201 /* The dispatch context is stored in the FsContext2 member */
202 Context
= (PDISPATCH_CONTEXT
)IoStack
->FileObject
->FsContext2
;
208 /* acquire real pin file object */
209 Status
= ObReferenceObjectByHandle(Context
->Handle
, GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
210 if (!NT_SUCCESS(Status
))
212 Irp
->IoStatus
.Information
= 0;
213 Irp
->IoStatus
.Status
= Status
;
214 /* Complete the irp */
215 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
219 /* Get Pin's device object */
220 PinDeviceObject
= IoGetRelatedDeviceObject(FileObject
);
222 /* release file object */
223 ObDereferenceObject(FileObject
);
225 /* Initialize notification event */
226 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
228 /* build target irp */
229 PinIrp
= IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS
, PinDeviceObject
, NULL
, 0, NULL
, &Event
, &IoStatus
);
233 /* Get the next stack location */
234 IoStack
= IoGetNextIrpStackLocation(PinIrp
);
235 /* The file object must be present in the irp as it contains the KSOBJECT_HEADER */
236 IoStack
->FileObject
= FileObject
;
238 /* call the driver */
239 Status
= IoCallDriver(PinDeviceObject
, PinIrp
);
240 /* Has request already completed ? */
241 if (Status
== STATUS_PENDING
)
243 /* Wait untill the request has completed */
244 KeWaitForSingleObject(&Event
, UserRequest
, KernelMode
, FALSE
, NULL
);
246 Status
= IoStatus
.Status
;
251 Irp
->IoStatus
.Status
= Status
;
252 Irp
->IoStatus
.Information
= 0;
253 /* Complete the irp */
254 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
262 PDEVICE_OBJECT DeviceObject
,
265 PDISPATCH_CONTEXT Context
;
266 PIO_STACK_LOCATION IoStack
;
268 DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject
);
270 /* Get current stack location */
271 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
273 /* The dispatch context is stored in the FsContext2 member */
274 Context
= (PDISPATCH_CONTEXT
)IoStack
->FileObject
->FsContext2
;
278 ZwClose(Context
->Handle
);
280 ZwClose(Context
->hMixerPin
);
284 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
285 Irp
->IoStatus
.Information
= 0;
286 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
287 return STATUS_SUCCESS
;
293 PDEVICE_OBJECT DeviceObject
,
296 DPRINT("Pin_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject
);
298 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
299 Irp
->IoStatus
.Information
= 0;
300 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
301 return STATUS_UNSUCCESSFUL
;
307 PDEVICE_OBJECT DeviceObject
,
311 DPRINT("Pin_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject
);
313 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
314 Irp
->IoStatus
.Information
= 0;
315 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
316 return STATUS_UNSUCCESSFUL
;
321 Pin_fnFastDeviceIoControl(
322 PFILE_OBJECT FileObject
,
325 ULONG InputBufferLength
,
327 ULONG OutputBufferLength
,
329 PIO_STATUS_BLOCK IoStatus
,
330 PDEVICE_OBJECT DeviceObject
)
332 DPRINT("Pin_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject
);
342 PFILE_OBJECT FileObject
,
343 PLARGE_INTEGER FileOffset
,
348 PIO_STATUS_BLOCK IoStatus
,
349 PDEVICE_OBJECT DeviceObject
)
351 DPRINT("Pin_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject
);
360 PFILE_OBJECT FileObject
,
361 PLARGE_INTEGER FileOffset
,
366 PIO_STATUS_BLOCK IoStatus
,
367 PDEVICE_OBJECT DeviceObject
)
369 PDISPATCH_CONTEXT Context
;
370 PFILE_OBJECT RealFileObject
;
373 DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject
);
375 Context
= (PDISPATCH_CONTEXT
)FileObject
->FsContext2
;
377 if (Context
->hMixerPin
)
379 Status
= ObReferenceObjectByHandle(Context
->hMixerPin
, GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&RealFileObject
, NULL
);
380 if (NT_SUCCESS(Status
))
382 Status
= KsStreamIo(RealFileObject
, NULL
, NULL
, NULL
, NULL
, 0, IoStatus
, Buffer
, Length
, KSSTREAM_WRITE
, KernelMode
);
383 ObDereferenceObject(RealFileObject
);
386 if (!NT_SUCCESS(Status
))
388 DPRINT1("Mixing stream failed with %lx\n", Status
);
393 Status
= ObReferenceObjectByHandle(Context
->Handle
, GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&RealFileObject
, NULL
);
394 if (!NT_SUCCESS(Status
))
397 Status
= KsStreamIo(RealFileObject
, NULL
, NULL
, NULL
, NULL
, 0, IoStatus
, Buffer
, Length
, KSSTREAM_WRITE
, KernelMode
);
399 ObDereferenceObject(RealFileObject
);
401 if (Status
== STATUS_SUCCESS
)
407 static KSDISPATCH_TABLE PinTable
=
409 Pin_fnDeviceIoControl
,
416 Pin_fnFastDeviceIoControl
,
426 KSOBJECT_HEADER ObjectHeader
;
428 /* allocate object header */
429 Status
= KsAllocateObjectHeader(&ObjectHeader
, 0, NULL
, Irp
, &PinTable
);