ReactOS  0.4.14-dev-342-gdc047f9
main.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/main.c
5  * PURPOSE: System Audio graph builder
6  * PROGRAMMER: Andrew Greenwood
7  * Johannes Anderwald
8  * HISTORY:
9  * 8 Jul 07 Started basic implementation
10  */
11 
12 #include "sysaudio.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
18 const GUID KSCATEGORY_AUDIO_DEVICE = {0xFBF6F530L, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
19 const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE = {0xD6C5066EL, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
20 const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE = {0xD6C50671L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
21 const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE = {0xD6C50674L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
22 
23 PVOID
27 {
29  if (!Item)
30  return Item;
31 
33  return Item;
34 }
35 
36 VOID
38  IN PVOID Item)
39 {
40  ExFreePool(Item);
41 }
42 
43 
44 VOID
45 NTAPI
47 {
48  DPRINT("SysAudio_Unload called\n");
49 }
50 
52 NTAPI
55  IN PIRP Irp)
56 {
57  PKSAUDIO_DEVICE_ENTRY DeviceEntry;
58  PSYSAUDIODEVEXT DeviceExtension;
60 
61  DPRINT("SysAudio_Shutdown called\n");
62 
63  DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
64 
65  while(!IsListEmpty(&DeviceExtension->KsAudioDeviceList))
66  {
67  Entry = RemoveHeadList(&DeviceExtension->KsAudioDeviceList);
69 
70  DPRINT("Freeing item %wZ\n", &DeviceEntry->DeviceName);
71 
72  /* dereference audio device file object */
73  ObDereferenceObject(DeviceEntry->FileObject);
74 
75  /* close audio device handle */
76  ZwClose(DeviceEntry->Handle);
77 
78  /* free device string */
79  RtlFreeUnicodeString(&DeviceEntry->DeviceName);
80 
81  /* free audio device entry */
82  FreeItem(DeviceEntry);
83  }
84 
85  Irp->IoStatus.Information = 0;
86  Irp->IoStatus.Status = STATUS_SUCCESS;
88  return STATUS_SUCCESS;
89 }
90 
91 
93 NTAPI
96  IN PIRP Irp)
97 {
98  PIO_STACK_LOCATION IrpStack;
99  UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
100  SYSAUDIODEVEXT *DeviceExtension;
101 
102  /* Get current irp stack */
103  IrpStack = IoGetCurrentIrpStackLocation(Irp);
104 
105  /* Fetch the device extension */
106  DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
107  ASSERT(DeviceExtension);
108 
109  if (IrpStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
110  {
111  /* Unregister the echo cancel hook */
112  if (DeviceExtension->EchoCancelNotificationEntry)
114 
115  /* Unregister the ks audio hook */
116  if (DeviceExtension->KsAudioNotificationEntry)
118 
119  /* Destroy our symbolic link */
120  IoDeleteSymbolicLink(&SymlinkName);
121  }
122  else if (IrpStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
123  {
124  /* Sysaudio can not be disabled */
125  Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
126  }
127 
128  /* Perform default pnp actions */
130 }
131 
132 NTSTATUS
133 NTAPI
137 {
139  UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio");
140  UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
142  SYSAUDIODEVEXT *DeviceExtension;
143 
144  DPRINT("SysAudio_AddDevice called\n");
145 
146  /* Create the device */
148  sizeof(SYSAUDIODEVEXT),
149  &DeviceName,
151  0,
152  FALSE,
153  &DeviceObject);
154 
155  /* Check for success */
156  if (!NT_SUCCESS(Status))
157  {
158  DPRINT("Failed to create \\Device\\sysaudio !\n");
159  return Status;
160  }
161 
162  /* Register device interfaces */
164  if (!NT_SUCCESS(Status))
165  {
166  /* Failed to register
167  * Create a hack interface
168  */
169  Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
170  if (!NT_SUCCESS(Status))
171  {
173  DPRINT1("Failed to create sysaudio symlink!\n");
174  return Status;
175  }
176  }
177  /* Acquire device extension */
178  DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
179  /* Initialize device extension */
180  RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
181 
182  /* Initialize the mutex */
183  KeInitializeSpinLock(&DeviceExtension->Lock);
184 
185  /* Initialize the ks audio device list */
186  InitializeListHead(&DeviceExtension->KsAudioDeviceList);
187 
188  /* Allocate kernel streaming device header */
189  Status = SysAudioAllocateDeviceHeader(DeviceExtension);
190  if (!NT_SUCCESS(Status))
191  {
192  DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
193  goto cleanup;
194  }
195 
196  /* Register device notification hooks */
198  DeviceObject);
199  if (!NT_SUCCESS(Status))
200  {
201  DPRINT1("Failed to register device notifications\n");
202  goto cleanup;
203  }
204 
205  /* Load kmixer */
206  Status = SysAudioOpenKMixer(DeviceExtension);
207  if (!NT_SUCCESS(Status))
208  {
209  DPRINT1("SysAudioOpenKMixer failed with %x\n", Status);
210  goto cleanup;
211  }
212 
213  /* set io flags */
215  /* clear initializing flag */
217 
218  /* atttach to device stack */
221 
222  /* register shutdown notification */
224 
225 
226  /* Done */
227  return STATUS_SUCCESS;
228 
229 cleanup:
230 
231  if (DeviceExtension->KsAudioNotificationEntry)
233 
234  if (DeviceExtension->EchoCancelNotificationEntry)
236 
237  IoDeleteSymbolicLink(&SymlinkName);
239  return Status;
240 }
241 
242 NTSTATUS
243 NTAPI
247 {
248  DPRINT("System audio graph builder (sysaudio) started\n");
249 
250  /* Let ks handle these */
255 
256  /* Let ks handle these */
259 
260  /* Use provided ks unload function */
262 
263  /* Sysaudio needs to do work on pnp, so handle it */
267 
268  /* done */
269  return STATUS_SUCCESS;
270 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE
Definition: main.c:20
KSDDKAPI NTSTATUS NTAPI KsDefaultDispatchPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: api.c:166
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
Definition: pnpnotify.c:371
#define DO_POWER_PAGABLE
KSDDKAPI NTSTATUS NTAPI KsDefaultDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: api.c:110
#define IN
Definition: typedefs.h:38
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MN_REMOVE_DEVICE
struct _Entry Entry
Definition: kefuncs.h:640
NTSTATUS SysAudioOpenKMixer(IN SYSAUDIODEVEXT *DeviceExtension)
Definition: dispatcher.c:132
#define IRP_MJ_SHUTDOWN
KSDDKAPI VOID NTAPI KsSetDevicePnpAndBaseObject(IN KSDEVICE_HEADER Header, IN PDEVICE_OBJECT PnpDeviceObject, IN PDEVICE_OBJECT BaseDevice)
Definition: api.c:257
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS SysAudioRegisterDeviceInterfaces(IN PDEVICE_OBJECT DeviceObject)
Definition: deviface.c:214
const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE
Definition: main.c:21
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: main.c:24
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY KsAudioDeviceList
Definition: sysaudio.h:30
KSDDKAPI VOID NTAPI KsNullDriverUnload(IN PDRIVER_OBJECT DriverObject)
Definition: irp.c:1145
KSPIN_LOCK Lock
Definition: sysaudio.h:33
struct KSAUDIO_DEVICE_ENTRY * PKSAUDIO_DEVICE_ENTRY
NTSTATUS NTAPI SysAudio_Shutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: main.c:53
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
KSDEVICE_HEADER KsDeviceHeader
Definition: sysaudio.h:25
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
WCHAR DeviceName[]
Definition: adapter.cpp:21
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
NTSTATUS SysAudioAllocateDeviceHeader(IN SYSAUDIODEVEXT *DeviceExtension)
Definition: dispatcher.c:104
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
KSDDKAPI NTSTATUS NTAPI KsSetMajorFunctionHandler(IN PDRIVER_OBJECT DriverObject, IN ULONG MajorFunction)
Definition: irp.c:2017
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2174
NTSTATUS NTAPI SysAudio_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: main.c:134
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PFILE_OBJECT FileObject
Definition: sysaudio.h:18
VOID FreeItem(IN PVOID Item)
Definition: main.c:37
Definition: sysaudio.h:12
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID EchoCancelNotificationEntry
Definition: sysaudio.h:32
INT POOL_TYPE
Definition: typedefs.h:76
PVOID KsAudioNotificationEntry
Definition: sysaudio.h:31
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:969
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
const GUID KSCATEGORY_AUDIO_DEVICE
Definition: main.c:18
VOID NTAPI SysAudio_Unload(IN PDRIVER_OBJECT DriverObject)
Definition: main.c:46
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT * NextDeviceObject
Definition: ndis.h:4640
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE
Definition: main.c:19
static const WCHAR L[]
Definition: oid.c:1250
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
Definition: typedefs.h:117
#define IRP_MJ_SYSTEM_CONTROL
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
ULONG_PTR SIZE_T
Definition: typedefs.h:78
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
KSDDKAPI NTSTATUS NTAPI KsDefaultForwardIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: api.c:227
NTSTATUS NTAPI SysAudio_Pnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: main.c:94
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: main.c:690
#define FILE_DEVICE_KS
Definition: winioctl.h:152
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
NTSTATUS SysAudioRegisterNotifications(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject)
Definition: deviface.c:172
struct SYSAUDIODEVEXT * PSYSAUDIODEVEXT
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:998
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
char * cleanup(char *str)
Definition: wpickclick.c:99
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
return STATUS_SUCCESS
Definition: btrfs.c:2938
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T _In_ POOL_TYPE PoolType
Definition: fltkernel.h:1444
const GUID KSCATEGORY_SYSAUDIO
Definition: main.c:17
base of all file and directory entries
Definition: entries.h:82
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
UNICODE_STRING DeviceName
Definition: sysaudio.h:15
HANDLE Handle
Definition: sysaudio.h:17
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14