ReactOS 0.4.16-dev-319-g6cf4263
pin.c
Go to the documentation of this file.
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#define NDEBUG
12#include <debug.h>
13
18 PIRP Irp)
19{
24 PIO_STACK_LOCATION IoStack;
25
26 DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject, Irp);
27
28 /* Get current stack location */
30
31 /* The dispatch context is stored in the FsContext member */
32 Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
33
34 /* Sanity check */
36
37 /* acquire real pin file object */
39 if (!NT_SUCCESS(Status))
40 {
41 Irp->IoStatus.Information = 0;
42 Irp->IoStatus.Status = Status;
43 /* Complete the irp */
45 return Status;
46 }
47
48 /* Re-dispatch the request to the real target pin */
50 IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
51 IoStack->Parameters.DeviceIoControl.InputBufferLength,
52 Irp->UserBuffer,
53 IoStack->Parameters.DeviceIoControl.OutputBufferLength,
55 /* release file object */
57
58 /* Save status and information */
59 Irp->IoStatus.Information = BytesReturned;
60 Irp->IoStatus.Status = Status;
61 /* Complete the irp */
63 /* Done */
64 return Status;
65}
66
67
68
73 PIRP Irp)
74{
76 PIO_STACK_LOCATION IoStack;
79
80 /* Get current stack location */
82
83 /* The dispatch context is stored in the FsContext member */
84 Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
85
86 /* Sanity check */
88
89 if (Context->hMixerPin)
90 {
91 // FIXME
92 // call kmixer to convert stream
94 }
95
96 /* acquire real pin file object */
98 if (!NT_SUCCESS(Status))
99 {
100 DPRINT1("failed\n");
101 Irp->IoStatus.Information = 0;
102 Irp->IoStatus.Status = Status;
103 /* Complete the irp */
105 return Status;
106 }
107
108 /* skip current irp location */
110
111 /* get next stack location */
113 /* store file object of next device object */
114 IoStack->FileObject = FileObject;
116 //ASSERT(Irp->AssociatedIrp.SystemBuffer);
117
118 /* now call the driver */
120
121 /* dereference file object */
123
124 return Status;
125
126}
127
129NTAPI
132 PIRP Irp)
133{
135 PIO_STACK_LOCATION IoStack;
136
137 //DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject, Irp);
138
139 /* Get current stack location */
141
142 /* The dispatch context is stored in the FsContext member */
143 Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
144
145 if (Context->Handle)
146 {
147 ZwClose(Context->Handle);
148 }
149
150 if (Context->hMixerPin)
151 {
152 ZwClose(Context->hMixerPin);
153 }
154
156
157 Irp->IoStatus.Status = STATUS_SUCCESS;
158 Irp->IoStatus.Information = 0;
160 return STATUS_SUCCESS;
161}
162
163static KSDISPATCH_TABLE PinTable =
164{
174 KsDispatchFastWriteFailure,
175};
176
180 IN PKSDATAFORMAT InputFormat,
182{
183 KSP_PIN PinRequest;
186
187 /* re-using pin */
191
192 /* set the input format */
193 PinRequest.PinId = 0;
194 DPRINT("InputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", InputFormat, InputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX));
196 (PVOID)&PinRequest,
197 sizeof(KSP_PIN),
198 (PVOID)InputFormat,
199 InputFormat->FormatSize,
201 if (!NT_SUCCESS(Status))
202 return Status;
203
204 /* set the the output format */
205 PinRequest.PinId = 1;
206 DPRINT("OutputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", OutputFormat, OutputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX));
208 (PVOID)&PinRequest,
209 sizeof(KSP_PIN),
211 OutputFormat->FormatSize,
213 return Status;
214}
215
216
219 IN HANDLE KMixerHandle,
220 IN KSPIN_CONNECT *PinConnect,
221 IN PKSDATAFORMAT InputFormat,
223 OUT PHANDLE MixerPinHandle)
224{
226 HANDLE PinHandle;
228
229 Status = KsCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
230
231 if (!NT_SUCCESS(Status))
232 {
233 DPRINT1("Failed to create Mixer Pin with %x\n", Status);
234 return STATUS_UNSUCCESSFUL;
235 }
236
240
241 if (!NT_SUCCESS(Status))
242 {
243 DPRINT1("Failed to get file object with %x\n", Status);
244 return STATUS_UNSUCCESSFUL;
245 }
246
248 if (!NT_SUCCESS(Status))
249 {
251 ZwClose(PinHandle);
252 return Status;
253 }
254
256
257 *MixerPinHandle = PinHandle;
258 return Status;
259}
260
261
263NTAPI
265 IN PKSAUDIO_DEVICE_ENTRY DeviceEntry,
268 IN PSYSAUDIODEVEXT DeviceExtension)
269{
271 HANDLE RealPinHandle;
272 PKSDATAFORMAT_WAVEFORMATEX InputFormat;
274 PKSPIN_CONNECT MixerPinConnect = NULL;
275 KSPIN_CINSTANCES PinInstances;
276
277 DPRINT("InstantiatePins entered\n");
278
279 /* query instance count */
280 Status = GetPinInstanceCount(DeviceEntry, &PinInstances, Connect);
281 if (!NT_SUCCESS(Status))
282 {
283 /* failed to query instance count */
284 return Status;
285 }
286
287 /* can be the pin be instantiated */
288 if (PinInstances.PossibleCount == 0)
289 {
290 /* caller wanted to open an instance-less pin */
291 return STATUS_UNSUCCESSFUL;
292 }
293
294 /* has the maximum instance count been exceeded */
295 if (PinInstances.CurrentCount == PinInstances.PossibleCount)
296 {
297 /* FIXME pin already exists
298 * and kmixer infrastructure is not implemented
299 */
300 return STATUS_UNSUCCESSFUL;
301 }
302
303 /* Fetch input format */
304 InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1);
305
306 /* Let's try to create the audio irp pin */
307 Status = KsCreatePin(DeviceEntry->Handle, Connect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
308
309 if (!NT_SUCCESS(Status))
310 {
311 /* FIXME disable kmixer
312 */
313 return STATUS_UNSUCCESSFUL;
314 }
315#if 0
316 if (!NT_SUCCESS(Status))
317 {
318 /* the audio irp pin didnt accept the input format
319 * let's compute a compatible format
320 */
321 MixerPinConnect = AllocateItem(NonPagedPool, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX));
322 if (!MixerPinConnect)
323 {
324 /* not enough memory */
326 }
327
328 /* Zero pin connect */
329 RtlZeroMemory(MixerPinConnect, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX));
330
331 /* Copy initial connect details */
332 RtlMoveMemory(MixerPinConnect, Connect, sizeof(KSPIN_CONNECT));
333
334
335 OutputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(MixerPinConnect + 1);
336
337 Status = ComputeCompatibleFormat(DeviceEntry, Connect->PinId, InputFormat, OutputFormat);
338 if (!NT_SUCCESS(Status))
339 {
340 DPRINT1("ComputeCompatibleFormat failed with %x\n", Status);
341 FreeItem(MixerPinConnect);
342 return Status;
343 }
344
345 /* Retry with Mixer format */
346 Status = KsCreatePin(DeviceEntry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
347 if (!NT_SUCCESS(Status))
348 {
349 /* This should not fail */
350 DPRINT1("KsCreatePin failed with %x\n", Status);
351 DPRINT1(" InputFormat: SampleRate %u Bits %u Channels %u\n", InputFormat->WaveFormatEx.nSamplesPerSec, InputFormat->WaveFormatEx.wBitsPerSample, InputFormat->WaveFormatEx.nChannels);
352 DPRINT1("OutputFormat: SampleRate %u Bits %u Channels %u\n", OutputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.nChannels);
353
354 FreeItem(MixerPinConnect);
355 return Status;
356 }
357 }
358#endif
359
360 //DeviceEntry->Pins[Connect->PinId].References = 0;
361
362 /* initialize dispatch context */
363 DispatchContext->Handle = RealPinHandle;
364 DispatchContext->PinId = Connect->PinId;
365 DispatchContext->AudioEntry = DeviceEntry;
366
367
368 DPRINT("RealPinHandle %p\n", RealPinHandle);
369
370 /* Do we need to transform the audio stream */
371 if (OutputFormat != NULL)
372 {
373 /* Now create the mixer pin */
374 Status = CreateMixerPinAndSetFormat(DeviceExtension->KMixerHandle,
375 MixerPinConnect,
376 (PKSDATAFORMAT)InputFormat,
378 &DispatchContext->hMixerPin);
379
380 /* check for success */
381 if (!NT_SUCCESS(Status))
382 {
383 DPRINT1("Failed to create Mixer Pin with %x\n", Status);
384 FreeItem(MixerPinConnect);
385 }
386 }
387 /* done */
388 return Status;
389}
390
393 IN PIRP Irp,
395{
396 PIO_STACK_LOCATION IoStack;
397 ULONG ObjectLength, ParametersLength;
399
400 /* get current irp stack */
402
403 /* get object class length */
404 ObjectLength = (wcslen(KSSTRING_Pin) + 1) * sizeof(WCHAR);
405
406 /* check for minium length requirement */
407 if (ObjectLength + sizeof(KSPIN_CONNECT) > IoStack->FileObject->FileName.MaximumLength)
408 return STATUS_UNSUCCESSFUL;
409
410 /* extract parameters length */
411 ParametersLength = IoStack->FileObject->FileName.MaximumLength - ObjectLength;
412
413 /* allocate buffer */
414 Buffer = AllocateItem(NonPagedPool, ParametersLength);
415 if (!Buffer)
417
418 /* copy parameters */
419 RtlMoveMemory(Buffer, &IoStack->FileObject->FileName.Buffer[ObjectLength / sizeof(WCHAR)], ParametersLength);
420
421 /* store result */
423
424 return STATUS_SUCCESS;
425}
426
427
428
430NTAPI
433 IN PIRP Irp)
434{
436 PIO_STACK_LOCATION IoStack;
437 PKSAUDIO_DEVICE_ENTRY DeviceEntry;
440
441 DPRINT("DispatchCreateSysAudioPin entered\n");
442
443 /* get current stack location */
445
446 /* sanity checks */
447 ASSERT(IoStack->FileObject);
448 ASSERT(IoStack->FileObject->RelatedFileObject);
449 ASSERT(IoStack->FileObject->RelatedFileObject->FsContext);
450
451 /* get current attached virtual device */
452 DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)IoStack->FileObject->RelatedFileObject->FsContext;
453
454 /* check for success */
456 {
457 /* failed */
458 Irp->IoStatus.Status = Status;
460 return Status;
461 }
462
463 /* get connect details */
465
466 /* check for success */
467 if (!NT_SUCCESS(Status))
468 {
469 /* failed to obtain connect details */
470 Irp->IoStatus.Status = Status;
472 return Status;
473 }
474
475
476 /* allocate dispatch context */
478 if (!DispatchContext)
479 {
480 /* failed */
481 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
484 }
485
486 /* zero dispatch context */
488
489 /* allocate object header */
491 if (!NT_SUCCESS(Status))
492 {
493 /* failed */
495 Irp->IoStatus.Status = Status;
497 return Status;
498 }
499
500 /* now instantiate the pins */
501 Status = InstantiatePins(DeviceEntry, Connect, DispatchContext, (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension);
502 if (!NT_SUCCESS(Status))
503 {
504 /* failed */
505 KsFreeObjectHeader(DispatchContext->ObjectHeader);
507 }
508 else
509 {
510 /* store dispatch context */
511 IoStack->FileObject->FsContext = (PVOID)DispatchContext;
512 }
513
514
515 /* FIXME create items for clocks / allocators */
516 Irp->IoStatus.Status = Status;
518 return Status;
519}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
enum OutputFormat_ OutputFormat
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define GENERIC_READ
Definition: compat.h:135
KSDDKAPI VOID NTAPI KsFreeObjectHeader(IN PVOID Header)
Definition: api.c:720
KSDDKAPI NTSTATUS NTAPI KsSynchronousIoControlDevice(IN PFILE_OBJECT FileObject, IN KPROCESSOR_MODE RequestorMode, IN ULONG IoControl, IN PVOID InBuffer, IN ULONG InSize, OUT PVOID OutBuffer, IN ULONG OutSize, OUT PULONG BytesReturned)
Definition: api.c:1099
KSDDKAPI NTSTATUS NTAPI KsAllocateObjectHeader(OUT KSOBJECT_HEADER *Header, IN ULONG ItemsCount, IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL, IN PIRP Irp, IN KSDISPATCH_TABLE *Table)
Definition: api.c:610
KSDDKAPI NTSTATUS NTAPI KsDispatchInvalidDeviceRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1189
KSDDKAPI BOOLEAN NTAPI KsDispatchFastReadFailure(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: irp.c:1271
KSDDKAPI BOOLEAN NTAPI KsDispatchFastIoDeviceControlFailure(IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: irp.c:1251
const GUID KSPROPSETID_Connection
Definition: pin.c:113
NTSTATUS NTAPI Pin_fnDeviceIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pin.c:423
static KSDISPATCH_TABLE PinTable
Definition: pin.c:684
NTSTATUS NTAPI Pin_fnClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pin.c:513
NTSTATUS NTAPI Pin_fnWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: pin.c:485
NTSTATUS ComputeCompatibleFormat(IN PKSAUDIO_DEVICE_ENTRY Entry, IN ULONG PinId, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat)
Definition: control.c:135
NTSTATUS GetPinInstanceCount(PKSAUDIO_DEVICE_ENTRY Entry, PKSPIN_CINSTANCES PinInstances, PKSPIN_CONNECT PinConnect)
Definition: control.c:269
NTSTATUS CreateMixerPinAndSetFormat(IN HANDLE KMixerHandle, IN KSPIN_CONNECT *PinConnect, IN PKSDATAFORMAT InputFormat, IN PKSDATAFORMAT OutputFormat, OUT PHANDLE MixerPinHandle)
Definition: pin.c:218
NTSTATUS NTAPI InstantiatePins(IN PKSAUDIO_DEVICE_ENTRY DeviceEntry, IN PKSPIN_CONNECT Connect, IN PDISPATCH_CONTEXT DispatchContext, IN PSYSAUDIODEVEXT DeviceExtension)
Definition: pin.c:264
NTSTATUS SetMixerInputOutputFormat(IN PFILE_OBJECT FileObject, IN PKSDATAFORMAT InputFormat, IN PKSDATAFORMAT OutputFormat)
Definition: pin.c:178
NTSTATUS NTAPI DispatchCreateSysAudioPin(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pin.c:431
NTSTATUS GetConnectRequest(IN PIRP Irp, OUT PKSPIN_CONNECT *Result)
Definition: pin.c:392
#define KSPROPERTY_TYPE_SET
Definition: dmksctrl.h:43
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
@ KSPROPERTY_CONNECTION_DATAFORMAT
Definition: ks.h:351
#define IOCTL_KS_PROPERTY
Definition: ks.h:127
struct KSPIN_CONNECT * PKSPIN_CONNECT
#define KSSTRING_Pin
Definition: ks.h:48
_In_ PKSPIN_CONNECT Connect
Definition: ks.h:4536
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
struct KSDATAFORMAT_WAVEFORMATEX * PKSDATAFORMAT_WAVEFORMATEX
KSDDKAPI DWORD NTAPI KsCreatePin(HANDLE FilterHandle, PKSPIN_CONNECT Connect, ACCESS_MASK DesiredAccess, PHANDLE ConnectionHandle)
Definition: ksuser.c:192
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define GENERIC_WRITE
Definition: nt_native.h:90
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
struct DISPATCH_CONTEXT * PDISPATCH_CONTEXT
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
Definition: sysaudio.h:13
WAVEFORMATEX WaveFormatEx
Definition: ksmedia.h:632
ULONG Id
Definition: dmksctrl.h:77
ULONG Flags
Definition: dmksctrl.h:78
GUID Set
Definition: dmksctrl.h:76
ULONG CurrentCount
Definition: ks.h:652
ULONG PossibleCount
Definition: ks.h:651
ULONG PinId
Definition: ks.h:2603
Definition: ks.h:642
KSPROPERTY Property
Definition: ks.h:643
ULONG PinId
Definition: ks.h:644
WORD wBitsPerSample
Definition: audioclient.idl:45
DWORD nSamplesPerSec
Definition: audioclient.idl:42
struct _IO_STACK_LOCATION::@1580::@1581 DeviceIoControl
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1580 Parameters
struct KSAUDIO_DEVICE_ENTRY * PKSAUDIO_DEVICE_ENTRY
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ UCHAR _In_ UCHAR _In_ ULONG _In_ WDFCONTEXT _Inout_ PIRP _In_ WDFCONTEXT DispatchContext
Definition: wdfdevice.h:1708
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
__wchar_t WCHAR
Definition: xmlstorage.h:180