15 #define TAG(A, B, C, D) (IN ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
23 PDEVICE_OBJECT DeviceObject
,
26 PSOUND_BLASTER_PARAMETERS sb_device
= DeviceObject
->DeviceExtension
;
28 DPRINT("CreateSoundBlaster() called - extension 0x%x\n", sb_device
);
30 EnableSpeaker(sb_device
);
31 /*SetOutputSampleRate(sb_device, 22*/
33 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
34 Irp
->IoStatus
.Information
= 0;
36 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
38 return STATUS_SUCCESS
;
43 PDEVICE_OBJECT DeviceObject
,
46 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
48 DPRINT("CloseSoundBlaster() called\n");
50 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
51 Irp
->IoStatus
.Information
= 0;
53 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
55 return STATUS_SUCCESS
;
60 PDEVICE_OBJECT DeviceObject
,
63 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
65 DPRINT("CleanupSoundBlaster() called\n");
67 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
68 Irp
->IoStatus
.Information
= 0;
70 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
72 return STATUS_SUCCESS
;
77 PDEVICE_OBJECT DeviceObject
,
80 PIO_STACK_LOCATION stack
;
81 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
83 DPRINT("ControlSoundBlaster() called\n");
85 stack
= IoGetCurrentIrpStackLocation(Irp
);
87 switch ( stack
->Parameters
.DeviceIoControl
.IoControlCode
)
92 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
93 Irp
->IoStatus
.Information
= 0;
95 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
97 return STATUS_SUCCESS
;
102 PDEVICE_OBJECT DeviceObject
,
105 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
107 DPRINT("WriteSoundBlaster() called\n");
109 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
110 Irp
->IoStatus
.Information
= 0;
112 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
114 return STATUS_SUCCESS
;
119 PDRIVER_OBJECT DriverObject
)
121 DPRINT("Sound Blaster driver unload\n");
126 PUNICODE_STRING RegistryPath
,
128 ACCESS_MASK DesiredAccess
,
129 OUT HANDLE
* DevicesKeyHandle
)
132 OBJECT_ATTRIBUTES attribs
;
133 UNICODE_STRING subkey_name
;
136 /* TODO: Check for NULL ptr in DevicesKeyHandle */
138 InitializeObjectAttributes(&attribs
,
140 OBJ_CASE_INSENSITIVE
,
142 (PSECURITY_DESCRIPTOR
) NULL
);
144 status
= ZwOpenKey(&key_handle
, KEY_READ
, &attribs
);
146 if ( ! NT_SUCCESS(status
) )
148 DPRINT("Couldn't open subkey %wZ\n", Subkey
);
152 RtlInitUnicodeString(&subkey_name
, Subkey
);
154 InitializeObjectAttributes(&attribs
,
156 OBJ_CASE_INSENSITIVE
,
158 (PSECURITY_DESCRIPTOR
) NULL
);
160 status
= ZwOpenKey(*DevicesKeyHandle
, DesiredAccess
, &attribs
);
168 AllocateRegistryPathInfo(
169 PUNICODE_STRING BasePath
,
170 PUNICODE_STRING ParametersPath
,
171 PKEY_BASIC_INFORMATION KeyInfo
)
176 DPRINT("Allocating memory for path info\n");
177 name
= ExAllocatePool(PagedPool
,
178 BasePath
->Length
+ sizeof(WCHAR
) +
179 ParametersPath
->Length
+ sizeof(WCHAR
) +
180 KeyInfo
->NameLength
+ sizeof(UNICODE_NULL
));
185 DPRINT("Copying info\n");
188 RtlCopyMemory((PVOID
)Pos
, (PVOID
)BasePath
->Buffer
, BasePath
->Length
);
189 pos
+= BasePath
->Length
/ sizeof(WCHAR
);
193 RtlCopyMemory((PVOID
)Pos
, (PVOID
)ParametersPath
->Buffer
, ParametersPath
->Length
);
194 pos
+= ParametersPath
->Length
/ sizeof(WCHAR
);
198 RtlCopyMemory((PVOID
)Pos
, (PVOID
)ParametersPath
->Buffer
, ParametersPath
->Length
);
199 pos
+= KeyInfo
->NameLength
/ sizeof(WCHAR
);
200 pos
[0] = UNICODE_NULL
;
206 #define FreeRegistryPathInfo(ptr) \
210 #define TAG_REG_INFO TAG('I','g','e','R')
211 #define TAG_REG_NAME TAG('N','g','e','R')
215 PUNICODE_STRING RegistryPath
,
217 PREGISTRY_CALLBACK_ROUTINE Callback
,
218 PDRIVER_OBJECT DriverObject
)
221 UNICODE_STRING subkey_name
;
222 HANDLE devices_key_handle
;
227 status
= OpenSubkey(RegistryPath
, Subkey
, KEY_ENUMERATE_SUB_KEYS
, &devices_key_handle
);
229 if ( ! NT_SUCCESS(status
) )
234 KEY_BASIC_INFORMATION test_info
;
235 PKEY_BASIC_INFORMATION info
;
239 status
= ZwEnumerateKey(devices_key_handle
,
246 if ( status
== STATUS_NO_MORE_ENTRIES
)
249 size
= result_length
+ FIELD_OFFSET(KEY_BASIC_INFORMATION
, Name
[0]);
251 info
= (PKEY_BASIC_INFORMATION
) ExAllocatePoolWithTag(PagedPool
, size
, TAG_REG_INFO
);
255 DPRINT("Out of memory\n");
256 status
= STATUS_INSUFFICIENT_RESOURCES
;
260 status
= ZwEnumerateKey(devices_key_handle
,
267 if ( ! NT_SUCCESS(status
) )
269 DPRINT("Unable to enumerate keys\n");
270 ExFreePoolWithTag(info
, TAG_REG_INFO
);
271 status
= STATUS_INTERNAL_ERROR
;
276 RtlInitUnicodeString(&subkey_name
, Subkey
);
278 name
= AllocateRegistryPathInfo(RegistryPath
, &subkey_name
, info
);
282 DPRINT("Out of memory\n");
283 ExFreePoolWithTag(info
, TAG_REG_INFO
);
284 status
= STATUS_INSUFFICIENT_RESOURCES
;
288 ExFreePoolWithTag(info
, TAG_REG_INFO
);
290 /* Call the callback */
291 status
= Callback(DriverObject
, name
);
293 FreeRegistryPathInfo(name
);
295 if ( ! NT_SUCCESS(status
) )
297 DPRINT("Callback FAILED\n");
304 ZwClose(devices_key_handle
);
306 DPRINT("Found %d subkey entries\n", key_index
);
308 if ( ( key_index
== 0 ) && ( status
== STATUS_NO_MORE_ENTRIES
) )
309 return STATUS_DEVICE_CONFIGURATION_ERROR
;
311 if ( status
== STATUS_NO_MORE_ENTRIES
)
312 status
= STATUS_SUCCESS
;
317 #define EnumerateDeviceKeys(path, callback, driver_obj) \
318 EnumerateSubkey(path, L"Devices", callback, driver_obj)
326 PUNICODE_STRING DeviceName
)
328 UNICODE_STRING number
;
329 WCHAR number_buffer
[5];
330 UNICODE_STRING unicode_pre_prefix
;
331 UNICODE_STRING unicode_prefix
;
334 RtlInitUnicodeString(&unicode_pre_prefix
, PrePrefix
);
335 RtlInitUnicodeString(&unicode_prefix
, Prefix
);
337 size
= unicode_pre_prefix
.Length
+
338 unicode_prefix
.Length
+
339 sizeof(number_buffer
) +
340 sizeof(UNICODE_NULL
);
342 DeviceName
->Buffer
= ExAllocatePool(PagedPool
, size
);
343 DeviceName
->MaximumLength
= (USHORT
) size
;
345 if ( ! DeviceName
->Buffer
)
346 return STATUS_INSUFFICIENT_RESOURCES
;
348 RtlCopyUnicodeString(DeviceName
, &unicode_pre_prefix
);
349 RtlAppendUnicodeStringToString(DeviceName
, &unicode_prefix
);
353 number
.Buffer
= number_buffer
;
354 number
.MaximumLength
= sizeof(number_buffer
);
356 RtlIntegerToUnicodeString((ULONG
) Index
, 10, &number
);
357 RtlAppendUnicodeStringToString(DeviceName
, &number
);
360 DeviceName
->Buffer
[DeviceName
->Length
/ sizeof(UNICODE_NULL
)] = UNICODE_NULL
;
362 return STATUS_SUCCESS
;
366 InitializeSoundBlaster(
367 PDRIVER_OBJECT DriverObject
,
371 PDEVICE_OBJECT device_object
;
372 PSOUND_BLASTER_PARAMETERS parameters
= NULL
;
373 UNICODE_STRING device_name
;
374 UNICODE_STRING dos_device_name
;
376 UCHAR device_index
= 0;
378 DPRINT("Initializing a Sound Blaster device\n");
380 /* Change these later */
381 status
= CreateDeviceName(L
"",
382 L
"\\Device\\WaveOut",
386 if ( ! NT_SUCCESS(status
) )
389 status
= CreateDeviceName(L
"\\DosDevices\\",
390 L
"\\Device\\WaveOut" + wcslen(L
"\\Device\\"),
394 if ( ! NT_SUCCESS(status
) )
400 DPRINT("Device: %wZ\n", device_name
);
401 DPRINT("Symlink: %wZ\n", dos_device_name
);
404 Create the device and DOS symlink
407 status
= IoCreateDevice(DriverObject
,
408 sizeof(SOUND_BLASTER_PARAMETERS
),
415 if ( ! NT_SUCCESS(status
) )
418 DPRINT("Created a device extension at 0x%x\n", device_object
->DeviceExtension
);
419 parameters
= device_object
->DeviceExtension
;
421 status
= IoCreateSymbolicLink(&dos_device_name
, &device_name
);
423 ExFreePool(dos_device_name
.Buffer
);
424 ExFreePool(device_name
.Buffer
);
426 if ( ! NT_SUCCESS(status
) )
428 IoDeleteDevice(device_object
);
429 device_object
= NULL
;
433 /* IoRegisterShutdownNotification( */
439 device_object
->AlignmentRequirement
= FILE_BYTE_ALIGNMENT
;
441 parameters
->driver
= DriverObject
;
442 parameters
->registry_path
= RegistryPath
;
443 parameters
->port
= DEFAULT_PORT
;
444 parameters
->irq
= DEFAULT_IRQ
;
445 parameters
->dma
= DEFAULT_DMA
;
446 parameters
->buffer_size
= DEFAULT_BUFFER_SIZE
;
448 /* TODO: Load the settings from the registry */
450 DPRINT("Port %x IRQ %d DMA %d\n", parameters
->port
, parameters
->irq
, parameters
->dma
);
452 DPRINT("Resetting the sound card\n");
454 if ( ! ResetSoundBlaster(parameters
) )
457 return STATUS_UNSUCCESSFUL
;
461 DPRINT("What kind of SB card is this?\n");
462 GetSoundBlasterModel(parameters);
465 return STATUS_SUCCESS
;
471 PDRIVER_OBJECT DriverObject
,
472 PUNICODE_STRING RegistryPath
)
476 DPRINT("Sound Blaster driver 0.1 by Silver Blade\n");
478 DriverObject
->Flags
= 0;
479 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = CreateSoundBlaster
;
480 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = CloseSoundBlaster
;
481 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = CleanupSoundBlaster
;
482 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ControlSoundBlaster
;
483 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = WriteSoundBlaster
;
484 DriverObject
->DriverUnload
= UnloadSoundBlaster
;
486 DPRINT("Beginning device key enumeration\n");
488 status
= EnumerateDeviceKeys(RegistryPath
, *InitializeSoundBlaster
, DriverObject
);