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)
9 * UPDATE HISTORY: Feb 25, 2009: New rewrite started
13 /* DEFINES AND INCLUDES ******************************************************/
20 #define CompleteIrpAndReturn(irp, status) \
21 irp->IoStatus.Status = status; \
22 irp->IoStatus.Information = 0; \
23 IoCompleteRequest(Irp, IO_NO_INCREMENT); \
27 /* FORWARD DECLARATIONS *****************************************************/
30 UnloadSoundBlaster(PDRIVER_OBJECT DriverObject
);
33 /* DEVICE "DISCOVERY" *******************************************************/
34 /* Nb: These need to go in the helper lib */
36 typedef NTSTATUS (*SOUNDDEVICEENUMERATIONCALLBACK
)(
37 IN PUNICODE_STRING DeviceRegistryPath
);
40 EnumerateSoundDevices(
41 IN PUNICODE_STRING RegistryPath
,
42 IN PWSTR RegistrySubKey
,
43 IN SOUNDDEVICEENUMERATIONCALLBACK Callback
)
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;
52 /* Turn the subkey name into a Unicode string */
53 RtlInitUnicodeString(&UnicodeSubkeyName
, RegistrySubKey
);
55 /* Open the registry key for the service */
56 InitializeObjectAttributes(&RegAttributes
,
60 (PSECURITY_DESCRIPTOR
) NULL
);
62 Status
= ZwOpenKey(&MainKeyHandle
, KEY_READ
, &RegAttributes
);
64 if ( ! NT_SUCCESS(Status
) )
66 DPRINT("Failed to open registry key\n");
70 /* Open the subkey usually named "Parameters" */
71 InitializeObjectAttributes(&RegAttributes
,
75 (PSECURITY_DESCRIPTOR
) NULL
);
77 Status
= ZwOpenKey(&ChildKeyHandle
, KEY_ENUMERATE_SUB_KEYS
, &RegAttributes
);
79 /* We're done with the main key now */
80 ZwClose(MainKeyHandle
);
82 if ( ! NT_SUCCESS(Status
) )
84 DPRINT("Failed to open registry subkeys for enumeration\n");
88 /* Enumerate through the device keys */
89 while ( ( Status
= ZwEnumerateKey(ChildKeyHandle
,
93 sizeof(KEY_BASIC_INFORMATION
),
94 &NeededDataLength
) ) != STATUS_NO_MORE_ENTRIES
)
96 PWSTR EnumeratedKeyName
, StartOfEnumeratedKeyName
;
98 DPRINT("Found subkey %d\n", i
);
100 FinalDataLength
= NeededDataLength
+ FIELD_OFFSET(KEY_BASIC_INFORMATION
, Name
[0]);
101 DPRINT("Allocating %d bytes\n", FinalDataLength
);
103 FinalKeyInfo
= (PKEY_BASIC_INFORMATION
) ExAllocatePool(PagedPool
, FinalDataLength
);
105 if ( ! FinalKeyInfo
)
107 Status
= STATUS_INSUFFICIENT_RESOURCES
;
111 /* This time we get the real info */
112 Status
= ZwEnumerateKey(ChildKeyHandle
,
119 if ( ! NT_SUCCESS(Status
) )
121 DPRINT("FAILED to enumerate key!\n");
125 NameLength
= RegistryPath
->Length
+ sizeof(WCHAR
) +
126 UnicodeSubkeyName
.Length
+ sizeof(WCHAR
) +
127 FinalKeyInfo
->NameLength
+ sizeof(UNICODE_NULL
);
129 DPRINT("Allocating memory for name (%d bytes)\n", NameLength
);
131 EnumeratedKeyName
= (PWSTR
) ExAllocatePool(PagedPool
, NameLength
);
133 if ( ! EnumeratedKeyName
)
135 ExFreePool((PVOID
)FinalKeyInfo
);
136 Status
= STATUS_INSUFFICIENT_RESOURCES
;
140 StartOfEnumeratedKeyName
= EnumeratedKeyName
;
142 /* Start building the registry path using the service key */
143 RtlCopyMemory(EnumeratedKeyName
,
144 RegistryPath
->Buffer
,
145 RegistryPath
->Length
);
147 EnumeratedKeyName
+= RegistryPath
->Length
/ sizeof(WCHAR
);
148 EnumeratedKeyName
[0] = '\\';
149 ++ EnumeratedKeyName
;
151 /* Append the parameters subkey */
152 RtlCopyMemory(EnumeratedKeyName
,
154 UnicodeSubkeyName
.Length
);
156 EnumeratedKeyName
+= UnicodeSubkeyName
.Length
/ sizeof(WCHAR
);
157 EnumeratedKeyName
[0] = '\\';
158 ++ EnumeratedKeyName
;
160 /* And finally append the enumerated key name */
161 RtlCopyMemory(EnumeratedKeyName
,
163 FinalKeyInfo
->NameLength
);
165 EnumeratedKeyName
+= FinalKeyInfo
->NameLength
/ sizeof(WCHAR
);
166 EnumeratedKeyName
[0] = UNICODE_NULL
;
169 EnumeratedKeyName
= StartOfEnumeratedKeyName
;
171 /* Convert into a Unicode string for the callback */
172 RtlInitUnicodeString(&DeviceKeyName
, EnumeratedKeyName
);
174 Callback(&DeviceKeyName
);
176 /* No longer need the key name */
177 ExFreePool((PVOID
)EnumeratedKeyName
);
178 EnumeratedKeyName
= NULL
;
181 /* No longer need the key info */
182 ExFreePool((PVOID
)FinalKeyInfo
);
188 /* We're done with enumeration so close this */
189 ZwClose(ChildKeyHandle
);
191 /* This isn't an error */
192 if ( Status
== STATUS_NO_MORE_ENTRIES
)
194 Status
= STATUS_SUCCESS
;
197 /* No devices configured? */
198 if ( i
== 0 && Status
== STATUS_NO_MORE_ENTRIES
)
200 Status
= STATUS_DEVICE_CONFIGURATION_ERROR
;
207 PublishWaveOutDevice(
208 IN DWORD HardwareDeviceIndex
,
209 IN PWSTR BaseDeviceName
,
210 IN DWORD DeviceIndex
,
211 IN LPWAVEOUTCAPS Capabilities
)
213 return STATUS_SUCCESS
;
217 typedef struct _SOUND_BLASTER_DEVICE
220 DWORD MidiUartBasePort
;
229 DWORD ActualDmaBufferSize
;
231 } SOUND_BLASTER_DEVICE
;
235 AllocateSoundBlasterStructure(OUT SOUND_BLASTER_DEVICE
* SoundBlasterDevice
)
237 return STATUS_NOT_IMPLEMENTED
;
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
257 ConfigureSoundBlasterDevice(IN PUNICODE_STRING DeviceRegistryPath
)
259 OBJECT_ATTRIBUTES RegAttributes
;
260 NTSTATUS Status
= STATUS_SUCCESS
;
261 HKEY ConfigKeyHandle
;
263 DPRINT("Configuring Sound Blaster (config at %S)\n", DeviceRegistryPath
->Buffer
);
265 if ( ! DeviceRegistryPath
)
267 return STATUS_INVALID_PARAMETER
;
270 /* Open the registry key */
271 InitializeObjectAttributes(&RegAttributes
,
273 OBJ_CASE_INSENSITIVE
,
275 (PSECURITY_DESCRIPTOR
) NULL
);
277 Status
= ZwOpenKey(&ConfigKeyHandle
, KEY_READ
, &RegAttributes
);
279 if ( ! NT_SUCCESS(Status
) )
281 DPRINT("Failed to open config registry key\n");
285 /* Read configuration */
286 DPRINT("Reading configuration\n");
288 //Status = ZwQueryValueKey(ConfigKeyHandle,
294 /* IRP DISPATCHERS **********************************************************/
296 static NTSTATUS NTAPI
298 IN PDEVICE_OBJECT DeviceObject
,
301 DPRINT("Sound Blaster driver received IRP_MJ_CREATE\n");
303 CompleteIrpAndReturn(Irp
, STATUS_SUCCESS
);
306 static NTSTATUS NTAPI
308 IN PDEVICE_OBJECT DeviceObject
,
311 DPRINT("Sound Blaster driver received IRP_MJ_CLOSE\n");
313 CompleteIrpAndReturn(Irp
, STATUS_SUCCESS
);
316 static NTSTATUS NTAPI
318 IN PDEVICE_OBJECT DeviceObject
,
321 DPRINT("Sound Blaster driver received IRP_MJ_CLEANUP\n");
323 CompleteIrpAndReturn(Irp
, STATUS_SUCCESS
);
326 static NTSTATUS NTAPI
328 IN PDEVICE_OBJECT DeviceObject
,
331 DPRINT("Sound Blaster driver received IRP_MJ_CONTROL\n");
333 CompleteIrpAndReturn(Irp
, STATUS_SUCCESS
);
336 static NTSTATUS NTAPI
338 IN PDEVICE_OBJECT DeviceObject
,
341 DPRINT("Sound Blaster driver received IRP_MJ_WRITE\n");
343 CompleteIrpAndReturn(Irp
, STATUS_SUCCESS
);
347 /* DRIVER ENTRYPOINT ********************************************************/
351 IN PDRIVER_OBJECT DriverObject
,
352 IN PUNICODE_STRING RegistryPath
)
354 NTSTATUS Status
= STATUS_SUCCESS
;
356 DPRINT("Sound Blaster driver by silverblade\n");
358 DriverObject
->Flags
= 0;
359 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = CreateSoundBlaster
;
360 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = CloseSoundBlaster
;
361 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = CleanupSoundBlaster
;
362 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ControlSoundBlaster
;
363 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = WriteToSoundBlaster
;
364 DriverObject
->DriverUnload
= UnloadSoundBlaster
;
366 EnumerateSoundDevices(RegistryPath
, L
"Parameters", ConfigureSoundBlasterDevice
);
372 UnloadSoundBlaster(IN PDRIVER_OBJECT DriverObject
)
374 DPRINT("Sound Blaster driver is being unloaded\n");