22 PDEVICE_OBJECT DeviceObject
,
25 PSOUND_BLASTER_PARAMETERS sb_device
= DeviceObject
->DeviceExtension
;
27 DPRINT("CreateSoundBlaster() called - extension 0x%x\n", sb_device
);
29 EnableSpeaker(sb_device
);
30 /*SetOutputSampleRate(sb_device, 22*/
32 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
33 Irp
->IoStatus
.Information
= 0;
35 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
37 return STATUS_SUCCESS
;
42 PDEVICE_OBJECT DeviceObject
,
45 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
47 DPRINT("CloseSoundBlaster() called\n");
49 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
50 Irp
->IoStatus
.Information
= 0;
52 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
54 return STATUS_SUCCESS
;
59 PDEVICE_OBJECT DeviceObject
,
62 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
64 DPRINT("CleanupSoundBlaster() called\n");
66 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
67 Irp
->IoStatus
.Information
= 0;
69 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
71 return STATUS_SUCCESS
;
76 PDEVICE_OBJECT DeviceObject
,
79 PIO_STACK_LOCATION stack
;
80 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
82 DPRINT("ControlSoundBlaster() called\n");
84 stack
= IoGetCurrentIrpStackLocation(Irp
);
86 switch ( stack
->Parameters
.DeviceIoControl
.IoControlCode
)
91 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
92 Irp
->IoStatus
.Information
= 0;
94 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
96 return STATUS_SUCCESS
;
101 PDEVICE_OBJECT DeviceObject
,
104 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
106 DPRINT("WriteSoundBlaster() called\n");
108 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
109 Irp
->IoStatus
.Information
= 0;
111 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
113 return STATUS_SUCCESS
;
118 PDRIVER_OBJECT DriverObject
)
120 DPRINT("Sound Blaster driver unload\n");
125 PUNICODE_STRING RegistryPath
,
127 ACCESS_MASK DesiredAccess
,
128 OUT HANDLE
* DevicesKeyHandle
)
131 OBJECT_ATTRIBUTES attribs
;
132 UNICODE_STRING subkey_name
;
135 /* TODO: Check for NULL ptr in DevicesKeyHandle */
137 InitializeObjectAttributes(&attribs
,
139 OBJ_CASE_INSENSITIVE
,
141 (PSECURITY_DESCRIPTOR
) NULL
);
143 status
= ZwOpenKey(&key_handle
, KEY_READ
, &attribs
);
145 if ( ! NT_SUCCESS(status
) )
147 DPRINT("Couldn't open subkey %wZ\n", Subkey
);
151 RtlInitUnicodeString(&subkey_name
, Subkey
);
153 InitializeObjectAttributes(&attribs
,
155 OBJ_CASE_INSENSITIVE
,
157 (PSECURITY_DESCRIPTOR
) NULL
);
159 status
= ZwOpenKey(*DevicesKeyHandle
, DesiredAccess
, &attribs
);
167 AllocateRegistryPathInfo(
168 PUNICODE_STRING BasePath
,
169 PUNICODE_STRING ParametersPath
,
170 PKEY_BASIC_INFORMATION KeyInfo
)
175 DPRINT("Allocating memory for path info\n");
176 name
= ExAllocatePool(PagedPool
,
177 BasePath
->Length
+ sizeof(WCHAR
) +
178 ParametersPath
->Length
+ sizeof(WCHAR
) +
179 KeyInfo
->NameLength
+ sizeof(UNICODE_NULL
));
184 DPRINT("Copying info\n");
187 RtlCopyMemory((PVOID
)Pos
, (PVOID
)BasePath
->Buffer
, BasePath
->Length
);
188 pos
+= BasePath
->Length
/ sizeof(WCHAR
);
192 RtlCopyMemory((PVOID
)Pos
, (PVOID
)ParametersPath
->Buffer
, ParametersPath
->Length
);
193 pos
+= ParametersPath
->Length
/ sizeof(WCHAR
);
197 RtlCopyMemory((PVOID
)Pos
, (PVOID
)ParametersPath
->Buffer
, ParametersPath
->Length
);
198 pos
+= KeyInfo
->NameLength
/ sizeof(WCHAR
);
199 pos
[0] = UNICODE_NULL
;
205 #define FreeRegistryPathInfo(ptr) \
209 #define TAG_REG_INFO 'RegI'
210 #define TAG_REG_NAME 'RegN'
214 PUNICODE_STRING RegistryPath
,
216 PREGISTRY_CALLBACK_ROUTINE Callback
,
217 PDRIVER_OBJECT DriverObject
)
220 UNICODE_STRING subkey_name
;
221 HANDLE devices_key_handle
;
226 status
= OpenSubkey(RegistryPath
, Subkey
, KEY_ENUMERATE_SUB_KEYS
, &devices_key_handle
);
228 if ( ! NT_SUCCESS(status
) )
233 KEY_BASIC_INFORMATION test_info
;
234 PKEY_BASIC_INFORMATION info
;
238 status
= ZwEnumerateKey(devices_key_handle
,
245 if ( status
== STATUS_NO_MORE_ENTRIES
)
248 size
= result_length
+ FIELD_OFFSET(KEY_BASIC_INFORMATION
, Name
[0]);
250 info
= (PKEY_BASIC_INFORMATION
) ExAllocatePoolWithTag(PagedPool
, size
, TAG_REG_INFO
);
254 DPRINT("Out of memory\n");
255 status
= STATUS_INSUFFICIENT_RESOURCES
;
259 status
= ZwEnumerateKey(devices_key_handle
,
266 if ( ! NT_SUCCESS(status
) )
268 DPRINT("Unable to enumerate keys\n");
269 ExFreePoolWithTag(info
, TAG_REG_INFO
);
270 status
= STATUS_INTERNAL_ERROR
;
275 RtlInitUnicodeString(&subkey_name
, Subkey
);
277 name
= AllocateRegistryPathInfo(RegistryPath
, &subkey_name
, info
);
281 DPRINT("Out of memory\n");
282 ExFreePoolWithTag(info
, TAG_REG_INFO
);
283 status
= STATUS_INSUFFICIENT_RESOURCES
;
287 ExFreePoolWithTag(info
, TAG_REG_INFO
);
289 /* Call the callback */
290 status
= Callback(DriverObject
, name
);
292 FreeRegistryPathInfo(name
);
294 if ( ! NT_SUCCESS(status
) )
296 DPRINT("Callback FAILED\n");
303 ZwClose(devices_key_handle
);
305 DPRINT("Found %d subkey entries\n", key_index
);
307 if ( ( key_index
== 0 ) && ( status
== STATUS_NO_MORE_ENTRIES
) )
308 return STATUS_DEVICE_CONFIGURATION_ERROR
;
310 if ( status
== STATUS_NO_MORE_ENTRIES
)
311 status
= STATUS_SUCCESS
;
316 #define EnumerateDeviceKeys(path, callback, driver_obj) \
317 EnumerateSubkey(path, L"Devices", callback, driver_obj)
325 PUNICODE_STRING DeviceName
)
327 UNICODE_STRING number
;
328 WCHAR number_buffer
[5];
329 UNICODE_STRING unicode_pre_prefix
;
330 UNICODE_STRING unicode_prefix
;
333 RtlInitUnicodeString(&unicode_pre_prefix
, PrePrefix
);
334 RtlInitUnicodeString(&unicode_prefix
, Prefix
);
336 size
= unicode_pre_prefix
.Length
+
337 unicode_prefix
.Length
+
338 sizeof(number_buffer
) +
339 sizeof(UNICODE_NULL
);
341 DeviceName
->Buffer
= ExAllocatePool(PagedPool
, size
);
342 DeviceName
->MaximumLength
= (USHORT
) size
;
344 if ( ! DeviceName
->Buffer
)
345 return STATUS_INSUFFICIENT_RESOURCES
;
347 RtlCopyUnicodeString(DeviceName
, &unicode_pre_prefix
);
348 RtlAppendUnicodeStringToString(DeviceName
, &unicode_prefix
);
352 number
.Buffer
= number_buffer
;
353 number
.MaximumLength
= sizeof(number_buffer
);
355 RtlIntegerToUnicodeString((ULONG
) Index
, 10, &number
);
356 RtlAppendUnicodeStringToString(DeviceName
, &number
);
359 DeviceName
->Buffer
[DeviceName
->Length
/ sizeof(UNICODE_NULL
)] = UNICODE_NULL
;
361 return STATUS_SUCCESS
;
365 InitializeSoundBlaster(
366 PDRIVER_OBJECT DriverObject
,
370 PDEVICE_OBJECT device_object
;
371 PSOUND_BLASTER_PARAMETERS parameters
= NULL
;
372 UNICODE_STRING device_name
;
373 UNICODE_STRING dos_device_name
;
375 UCHAR device_index
= 0;
377 DPRINT("Initializing a Sound Blaster device\n");
379 /* Change these later */
380 status
= CreateDeviceName(L
"",
381 L
"\\Device\\WaveOut",
385 if ( ! NT_SUCCESS(status
) )
388 status
= CreateDeviceName(L
"\\DosDevices\\",
389 L
"\\Device\\WaveOut" + wcslen(L
"\\Device\\"),
393 if ( ! NT_SUCCESS(status
) )
399 DPRINT("Device: %wZ\n", device_name
);
400 DPRINT("Symlink: %wZ\n", dos_device_name
);
403 Create the device and DOS symlink
406 status
= IoCreateDevice(DriverObject
,
407 sizeof(SOUND_BLASTER_PARAMETERS
),
414 if ( ! NT_SUCCESS(status
) )
417 DPRINT("Created a device extension at 0x%x\n", device_object
->DeviceExtension
);
418 parameters
= device_object
->DeviceExtension
;
420 status
= IoCreateSymbolicLink(&dos_device_name
, &device_name
);
422 ExFreePool(dos_device_name
.Buffer
);
423 ExFreePool(device_name
.Buffer
);
425 if ( ! NT_SUCCESS(status
) )
427 IoDeleteDevice(device_object
);
428 device_object
= NULL
;
432 /* IoRegisterShutdownNotification( */
438 device_object
->AlignmentRequirement
= FILE_BYTE_ALIGNMENT
;
440 parameters
->driver
= DriverObject
;
441 parameters
->registry_path
= RegistryPath
;
442 parameters
->port
= DEFAULT_PORT
;
443 parameters
->irq
= DEFAULT_IRQ
;
444 parameters
->dma
= DEFAULT_DMA
;
445 parameters
->buffer_size
= DEFAULT_BUFFER_SIZE
;
447 /* TODO: Load the settings from the registry */
449 DPRINT("Port %x IRQ %d DMA %d\n", parameters
->port
, parameters
->irq
, parameters
->dma
);
451 DPRINT("Resetting the sound card\n");
453 if ( ! ResetSoundBlaster(parameters
) )
456 return STATUS_UNSUCCESSFUL
;
460 DPRINT("What kind of SB card is this?\n");
461 GetSoundBlasterModel(parameters);
464 return STATUS_SUCCESS
;
470 PDRIVER_OBJECT DriverObject
,
471 PUNICODE_STRING RegistryPath
)
475 DPRINT("Sound Blaster driver 0.1 by Silver Blade\n");
477 DriverObject
->Flags
= 0;
478 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = CreateSoundBlaster
;
479 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = CloseSoundBlaster
;
480 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = CleanupSoundBlaster
;
481 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = ControlSoundBlaster
;
482 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = WriteSoundBlaster
;
483 DriverObject
->DriverUnload
= UnloadSoundBlaster
;
485 DPRINT("Beginning device key enumeration\n");
487 status
= EnumerateDeviceKeys(RegistryPath
, *InitializeSoundBlaster
, DriverObject
);