ReactOS 0.4.15-dev-8138-g1e75ea8
sndblst.c
Go to the documentation of this file.
1/*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS Sound System
5 * FILE: drivers/multimedia/audio/sndblst/sndblst.c
6 * PURPOSE: Sound Blaster / Pro / 16 driver
7 * PROGRAMMER: Andrew Greenwood (silverblade@reactos.org)
8 *
9 * UPDATE HISTORY: Feb 25, 2009: New rewrite started
10 *
11 */
12
13/* DEFINES AND INCLUDES ******************************************************/
14
15#include <ntddk.h>
16#include <windef.h>
17#include <mmsystem.h>
18#include <debug.h>
19
20#define CompleteIrpAndReturn(irp, status) \
21 irp->IoStatus.Status = status; \
22 irp->IoStatus.Information = 0; \
23 IoCompleteRequest(Irp, IO_NO_INCREMENT); \
24 return status;
25
26
27/* FORWARD DECLARATIONS *****************************************************/
28
29static VOID NTAPI
31
32
33/* DEVICE "DISCOVERY" *******************************************************/
34/* Nb: These need to go in the helper lib */
35
37 IN PUNICODE_STRING DeviceRegistryPath);
38
42 IN PWSTR RegistrySubKey,
44{
46 OBJECT_ATTRIBUTES RegAttributes;
47 HKEY MainKeyHandle, ChildKeyHandle;
48 UNICODE_STRING UnicodeSubkeyName, DeviceKeyName;
49 KEY_BASIC_INFORMATION KeyInfo, *FinalKeyInfo;
50 ULONG i = 0, NeededDataLength = 0, FinalDataLength = 0, NameLength = 0;
51
52 /* Turn the subkey name into a Unicode string */
53 RtlInitUnicodeString(&UnicodeSubkeyName, RegistrySubKey);
54
55 /* Open the registry key for the service */
56 InitializeObjectAttributes(&RegAttributes,
59 NULL,
61
62 Status = ZwOpenKey(&MainKeyHandle, KEY_READ, &RegAttributes);
63
64 if ( ! NT_SUCCESS(Status) )
65 {
66 DPRINT("Failed to open registry key\n");
67 return Status;
68 }
69
70 /* Open the subkey usually named "Parameters" */
71 InitializeObjectAttributes(&RegAttributes,
72 &UnicodeSubkeyName,
74 MainKeyHandle,
76
77 Status = ZwOpenKey(&ChildKeyHandle, KEY_ENUMERATE_SUB_KEYS, &RegAttributes);
78
79 /* We're done with the main key now */
80 ZwClose(MainKeyHandle);
81
82 if ( ! NT_SUCCESS(Status) )
83 {
84 DPRINT("Failed to open registry subkeys for enumeration\n");
85 return Status;
86 }
87
88 /* Enumerate through the device keys */
89 while ( ( Status = ZwEnumerateKey(ChildKeyHandle,
90 i,
92 &KeyInfo,
94 &NeededDataLength) ) != STATUS_NO_MORE_ENTRIES )
95 {
96 PWSTR EnumeratedKeyName, StartOfEnumeratedKeyName;
97
98 DPRINT("Found subkey %d\n", i);
99
100 FinalDataLength = NeededDataLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
101 DPRINT("Allocating %d bytes\n", FinalDataLength);
102
103 FinalKeyInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, FinalDataLength);
104
105 if ( ! FinalKeyInfo )
106 {
108 break;
109 }
110
111 /* This time we get the real info */
112 Status = ZwEnumerateKey(ChildKeyHandle,
113 i,
115 FinalKeyInfo,
116 FinalDataLength,
117 &NeededDataLength);
118
119 if ( ! NT_SUCCESS(Status) )
120 {
121 DPRINT("FAILED to enumerate key!\n");
122 }
123 else
124 {
125 NameLength = RegistryPath->Length + sizeof(WCHAR) +
126 UnicodeSubkeyName.Length + sizeof(WCHAR) +
127 FinalKeyInfo->NameLength + sizeof(UNICODE_NULL);
128
129 DPRINT("Allocating memory for name (%d bytes)\n", NameLength);
130
131 EnumeratedKeyName = (PWSTR) ExAllocatePool(PagedPool, NameLength);
132
133 if ( ! EnumeratedKeyName )
134 {
135 ExFreePool((PVOID)FinalKeyInfo);
137 break;
138 }
139
140 StartOfEnumeratedKeyName = EnumeratedKeyName;
141
142 /* Start building the registry path using the service key */
143 RtlCopyMemory(EnumeratedKeyName,
144 RegistryPath->Buffer,
145 RegistryPath->Length);
146
147 EnumeratedKeyName += RegistryPath->Length / sizeof(WCHAR);
148 EnumeratedKeyName[0] = '\\';
149 ++ EnumeratedKeyName;
150
151 /* Append the parameters subkey */
152 RtlCopyMemory(EnumeratedKeyName,
153 RegistrySubKey,
154 UnicodeSubkeyName.Length);
155
156 EnumeratedKeyName += UnicodeSubkeyName.Length / sizeof(WCHAR);
157 EnumeratedKeyName[0] = '\\';
158 ++ EnumeratedKeyName;
159
160 /* And finally append the enumerated key name */
161 RtlCopyMemory(EnumeratedKeyName,
162 FinalKeyInfo->Name,
163 FinalKeyInfo->NameLength);
164
165 EnumeratedKeyName += FinalKeyInfo->NameLength / sizeof(WCHAR);
166 EnumeratedKeyName[0] = UNICODE_NULL;
167
168 /* Reset pointer */
169 EnumeratedKeyName = StartOfEnumeratedKeyName;
170
171 /* Convert into a Unicode string for the callback */
172 RtlInitUnicodeString(&DeviceKeyName, EnumeratedKeyName);
173
174 Callback(&DeviceKeyName);
175
176 /* No longer need the key name */
177 ExFreePool((PVOID)EnumeratedKeyName);
178 EnumeratedKeyName = NULL;
179 }
180
181 /* No longer need the key info */
182 ExFreePool((PVOID)FinalKeyInfo);
183 FinalKeyInfo = NULL;
184
185 ++ i;
186 }
187
188 /* We're done with enumeration so close this */
189 ZwClose(ChildKeyHandle);
190
191 /* This isn't an error */
193 {
195 }
196
197 /* No devices configured? */
198 if ( i == 0 && Status == STATUS_NO_MORE_ENTRIES )
199 {
201 }
202
203 return Status;
204}
205
208 IN DWORD HardwareDeviceIndex,
209 IN PWSTR BaseDeviceName,
210 IN DWORD DeviceIndex,
212{
213 return STATUS_SUCCESS;
214}
215
216
218{
221
223
226
228
232
233
236{
238}
239
240/* callback */
241/*
242 Configuration options within the registry:
243 REG_DWORD Actual Dma Buffer Size 0x00004000
244 REG_DWORD Configuration Error 0xffffffff
245 REG_DWORD Dma Buffer Size 0x00004000
246 REG_DWORD DmaChannel 0x00000001
247 REG_DWORD DmaChannel16 0x00000005
248 REG_DWORD DSP Version 0x00000405
249 REG_DWORD Interrupt 0x00000005
250 REG_DWORD Load Type 0x00000000
251 REG_BINARY Mixer Settings ??
252 REG_DWORD MPU401 Port 0xffffffff
253 REG_DWORD Port 0x00000220
254*/
255
258{
259 OBJECT_ATTRIBUTES RegAttributes;
261 HKEY ConfigKeyHandle;
262
263 DPRINT("Configuring Sound Blaster (config at %S)\n", DeviceRegistryPath->Buffer);
264
265 if ( ! DeviceRegistryPath )
266 {
268 }
269
270 /* Open the registry key */
271 InitializeObjectAttributes(&RegAttributes,
272 DeviceRegistryPath,
274 NULL,
276
277 Status = ZwOpenKey(&ConfigKeyHandle, KEY_READ, &RegAttributes);
278
279 if ( ! NT_SUCCESS(Status) )
280 {
281 DPRINT("Failed to open config registry key\n");
282 return Status;
283 }
284
285 /* Read configuration */
286 DPRINT("Reading configuration\n");
287
288 //Status = ZwQueryValueKey(ConfigKeyHandle,
289
290 return Status;
291}
292
293
294/* IRP DISPATCHERS **********************************************************/
295
296static NTSTATUS NTAPI
299 IN PIRP Irp)
300{
301 DPRINT("Sound Blaster driver received IRP_MJ_CREATE\n");
302
304}
305
306static NTSTATUS NTAPI
309 IN PIRP Irp)
310{
311 DPRINT("Sound Blaster driver received IRP_MJ_CLOSE\n");
312
314}
315
316static NTSTATUS NTAPI
319 IN PIRP Irp)
320{
321 DPRINT("Sound Blaster driver received IRP_MJ_CLEANUP\n");
322
324}
325
326static NTSTATUS NTAPI
329 IN PIRP Irp)
330{
331 DPRINT("Sound Blaster driver received IRP_MJ_CONTROL\n");
332
334}
335
336static NTSTATUS NTAPI
339 IN PIRP Irp)
340{
341 DPRINT("Sound Blaster driver received IRP_MJ_WRITE\n");
342
344}
345
346
347/* DRIVER ENTRYPOINT ********************************************************/
348
353{
355
356 DPRINT("Sound Blaster driver by silverblade\n");
357
358 DriverObject->Flags = 0;
364 DriverObject->DriverUnload = UnloadSoundBlaster;
365
367
368 return Status;
369}
370
371static VOID NTAPI
373{
374 DPRINT("Sound Blaster driver is being unloaded\n");
375}
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NTSTATUS
Definition: precomp.h:21
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
NTSTATUS EnumerateSoundDevices(IN PUNICODE_STRING RegistryPath, IN PWSTR RegistrySubKey, IN SOUNDDEVICEENUMERATIONCALLBACK Callback)
Definition: sndblst.c:40
static VOID NTAPI UnloadSoundBlaster(PDRIVER_OBJECT DriverObject)
Definition: main.c:117
static NTSTATUS NTAPI WriteToSoundBlaster(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: sndblst.c:337
#define CompleteIrpAndReturn(irp, status)
Definition: sndblst.c:20
NTSTATUS(* SOUNDDEVICEENUMERATIONCALLBACK)(IN PUNICODE_STRING DeviceRegistryPath)
Definition: sndblst.c:36
NTSTATUS PublishWaveOutDevice(IN DWORD HardwareDeviceIndex, IN PWSTR BaseDeviceName, IN DWORD DeviceIndex, IN LPWAVEOUTCAPS Capabilities)
Definition: sndblst.c:207
static NTSTATUS NTAPI ControlSoundBlaster(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: sndblst.c:327
struct _SOUND_BLASTER_DEVICE SOUND_BLASTER_DEVICE
NTSTATUS AllocateSoundBlasterStructure(OUT SOUND_BLASTER_DEVICE *SoundBlasterDevice)
Definition: sndblst.c:235
static NTSTATUS NTAPI CreateSoundBlaster(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: sndblst.c:297
NTSTATUS ConfigureSoundBlasterDevice(IN PUNICODE_STRING DeviceRegistryPath)
Definition: sndblst.c:257
static NTSTATUS NTAPI CleanupSoundBlaster(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: sndblst.c:317
static NTSTATUS NTAPI CloseSoundBlaster(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: sndblst.c:307
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyBasicInformation
Definition: nt_native.h:1131
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
struct _KEY_BASIC_INFORMATION * PKEY_BASIC_INFORMATION
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define UNICODE_NULL
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:619
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
DWORD ActualDmaBufferSize
Definition: sndblst.c:229
uint16_t * PWSTR
Definition: typedefs.h:56
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
#define IRP_MJ_CLEANUP
__wchar_t WCHAR
Definition: xmlstorage.h:180