1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Kernel Streaming
4  * FILE:            drivers/wdm/audio/sysaudio/dispatcher.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 
14 NTSTATUS
15 NTAPI
16 Dispatch_fnDeviceIoControl(
17     PDEVICE_OBJECT DeviceObject,
18     PIRP Irp)
19 {
20     PIO_STACK_LOCATION IoStack;
21 
22     IoStack = IoGetCurrentIrpStackLocation(Irp);
23     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
24     {
25        return SysAudioHandleProperty(DeviceObject, Irp);
26     }
27 
28     /* unsupported request */
29     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
30     Irp->IoStatus.Information = 0;
31     IoCompleteRequest(Irp, IO_NO_INCREMENT);
32     return STATUS_UNSUCCESSFUL;
33 }
34 
35 NTSTATUS
36 NTAPI
37 Dispatch_fnClose(
38     PDEVICE_OBJECT DeviceObject,
39     PIRP Irp)
40 {
41     DPRINT("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
42 
43     Irp->IoStatus.Status = STATUS_SUCCESS;
44     Irp->IoStatus.Information = 0;
45     IoCompleteRequest(Irp, IO_NO_INCREMENT);
46     return STATUS_SUCCESS;
47 }
48 
49 static KSDISPATCH_TABLE DispatchTable =
50 {
51     Dispatch_fnDeviceIoControl,
52     KsDispatchInvalidDeviceRequest,
53     KsDispatchInvalidDeviceRequest,
54     KsDispatchInvalidDeviceRequest,
55     Dispatch_fnClose,
56     KsDispatchInvalidDeviceRequest,
57     KsDispatchInvalidDeviceRequest,
58     KsDispatchFastIoDeviceControlFailure,
59     KsDispatchFastReadFailure,
60     KsDispatchFastWriteFailure,
61 };
62 
63 NTSTATUS
64 NTAPI
65 DispatchCreateSysAudio(
66     IN  PDEVICE_OBJECT DeviceObject,
67     IN  PIRP Irp)
68 {
69     NTSTATUS Status;
70     KSOBJECT_HEADER ObjectHeader;
71     PKSOBJECT_CREATE_ITEM CreateItem;
72 
73     DPRINT("DispatchCreateSysAudio entered\n");
74 
75     /* allocate create item */
76     CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
77     if (!CreateItem)
78     {
79         Irp->IoStatus.Information = 0;
80         Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
81         IoCompleteRequest(Irp, IO_NO_INCREMENT);
82         return STATUS_INSUFFICIENT_RESOURCES;
83     }
84 
85     /* zero create struct */
86     RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
87 
88     /* setup create context */
89     CreateItem->Create = DispatchCreateSysAudioPin;
90     RtlInitUnicodeString(&CreateItem->ObjectClass, KSSTRING_Pin);
91 
92     /* allocate object header */
93     Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
94 
95     DPRINT("KsAllocateObjectHeader result %x\n", Status);
96     /* complete the irp */
97     Irp->IoStatus.Information = 0;
98     Irp->IoStatus.Status = Status;
99     IoCompleteRequest(Irp, IO_NO_INCREMENT);
100     return Status;
101 }
102 
103 NTSTATUS
104 SysAudioAllocateDeviceHeader(
105     IN SYSAUDIODEVEXT *DeviceExtension)
106 {
107     NTSTATUS Status;
108     PKSOBJECT_CREATE_ITEM CreateItem;
109 
110     /* allocate create item */
111     CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
112     if (!CreateItem)
113         return STATUS_INSUFFICIENT_RESOURCES;
114 
115     /* initialize create item struct */
116     RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
117     CreateItem->Create = DispatchCreateSysAudio;
118 
119     /* FIXME Sysaudio doesnt need a named create item because it installs itself
120      * via the device interface
121      */
122     RtlInitUnicodeString(&CreateItem->ObjectClass, L"GLOBAL");
123     CreateItem->Flags = KSCREATE_ITEM_WILDCARD;
124 
125     Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
126                                     1,
127                                     CreateItem);
128     return Status;
129 }
130 
131 NTSTATUS
132 SysAudioOpenKMixer(
133     IN SYSAUDIODEVEXT *DeviceExtension)
134 {
135     NTSTATUS Status;
136     UNICODE_STRING DeviceInstanceName = RTL_CONSTANT_STRING(L"\\Device\\kmixer\\GLOBAL");
137     UNICODE_STRING DevicePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\kmixer");
138 
139     Status = ZwLoadDriver(&DevicePath);
140 
141     if (NT_SUCCESS(Status))
142     {
143         Status = OpenDevice(&DeviceInstanceName, &DeviceExtension->KMixerHandle, &DeviceExtension->KMixerFileObject);
144         if (!NT_SUCCESS(Status))
145         {
146             DeviceExtension->KMixerHandle = NULL;
147             DeviceExtension->KMixerFileObject = NULL;
148         }
149     }
150 
151     DPRINT("Status %lx KMixerHandle %p KMixerFileObject %p\n", Status, DeviceExtension->KMixerHandle, DeviceExtension->KMixerFileObject);
152     return STATUS_SUCCESS;
153 }
154