ReactOS  0.4.14-dev-552-g2fad488
main.c
Go to the documentation of this file.
1 /*
2  ReactOS
3  Sound Blaster driver
4 
5  Programmers:
6  Andrew Greenwood
7 
8  Notes:
9  Compatible with NT4
10 */
11 
12 #define NDEBUG
13 #include <sndblst.h>
14 
15 
16 /*
17  IRP DISPATCH ROUTINES
18 */
19 
23  PIRP Irp)
24 {
26 
27  DPRINT("CreateSoundBlaster() called - extension 0x%x\n", sb_device);
28 
29  EnableSpeaker(sb_device);
30  /*SetOutputSampleRate(sb_device, 22*/
31 
32  Irp->IoStatus.Status = STATUS_SUCCESS;
33  Irp->IoStatus.Information = 0;
34 
36 
37  return STATUS_SUCCESS;
38 }
39 
43  PIRP Irp)
44 {
45  //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
46 
47  DPRINT("CloseSoundBlaster() called\n");
48 
49  Irp->IoStatus.Status = STATUS_SUCCESS;
50  Irp->IoStatus.Information = 0;
51 
53 
54  return STATUS_SUCCESS;
55 }
56 
60  PIRP Irp)
61 {
62  //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
63 
64  DPRINT("CleanupSoundBlaster() called\n");
65 
66  Irp->IoStatus.Status = STATUS_SUCCESS;
67  Irp->IoStatus.Information = 0;
68 
70 
71  return STATUS_SUCCESS;
72 }
73 
77  PIRP Irp)
78 {
80  //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
81 
82  DPRINT("ControlSoundBlaster() called\n");
83 
85 
86  switch ( stack->Parameters.DeviceIoControl.IoControlCode)
87  {
88  /* TODO */
89  };
90 
91  Irp->IoStatus.Status = STATUS_SUCCESS;
92  Irp->IoStatus.Information = 0;
93 
95 
96  return STATUS_SUCCESS;
97 }
98 
102  PIRP Irp)
103 {
104  //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
105 
106  DPRINT("WriteSoundBlaster() called\n");
107 
108  Irp->IoStatus.Status = STATUS_SUCCESS;
109  Irp->IoStatus.Information = 0;
110 
112 
113  return STATUS_SUCCESS;
114 }
115 
116 VOID NTAPI
119 {
120  DPRINT("Sound Blaster driver unload\n");
121 }
122 
126  PWSTR Subkey,
128  OUT HANDLE* DevicesKeyHandle)
129 {
132  UNICODE_STRING subkey_name;
133  HANDLE key_handle;
134 
135  /* TODO: Check for NULL ptr in DevicesKeyHandle */
136 
138  RegistryPath,
140  NULL,
142 
143  status = ZwOpenKey(&key_handle, KEY_READ, &attribs);
144 
145  if ( ! NT_SUCCESS(status) )
146  {
147  DPRINT("Couldn't open key %wZ\n", RegistryPath);
148  return status;
149  }
150 
151  RtlInitUnicodeString(&subkey_name, Subkey);
152 
154  &subkey_name,
156  key_handle,
158 
159  status = ZwOpenKey(*DevicesKeyHandle, DesiredAccess, &attribs);
160  ZwClose(key_handle);
161 
162  return status;
163 }
164 
165 
166 PWSTR NTAPI
168  PUNICODE_STRING BasePath,
169  PUNICODE_STRING ParametersPath,
170  PKEY_BASIC_INFORMATION KeyInfo)
171 {
172  PWSTR name;
173  PWSTR pos;
174 
175  DPRINT("Allocating memory for path info\n");
177  BasePath->Length + sizeof(WCHAR) +
178  ParametersPath->Length + sizeof(WCHAR) +
179  KeyInfo->NameLength + sizeof(UNICODE_NULL));
180 
181  if ( ! name )
182  return NULL;
183 
184  DPRINT("Copying info\n");
185  pos = name;
186 
187  RtlCopyMemory((PVOID)Pos, (PVOID)BasePath->Buffer, BasePath->Length);
188  pos += BasePath->Length / sizeof(WCHAR);
189  pos[0] = '\\';
190  pos ++;
191 
192  RtlCopyMemory((PVOID)Pos, (PVOID)ParametersPath->Buffer, ParametersPath->Length);
193  pos += ParametersPath->Length / sizeof(WCHAR);
194  pos[0] = '\\';
195  pos ++;
196 
197  RtlCopyMemory((PVOID)Pos, (PVOID)ParametersPath->Buffer, ParametersPath->Length);
198  pos += KeyInfo->NameLength / sizeof(WCHAR);
199  pos[0] = UNICODE_NULL;
200 
201  DPRINT("All OK\n");
202  return name;
203 }
204 
205 #define FreeRegistryPathInfo(ptr) \
206  ExFreePool(ptr)
207 
208 
209 #define TAG_REG_INFO 'RegI'
210 #define TAG_REG_NAME 'RegN'
211 
215  PWSTR Subkey,
218 {
220  UNICODE_STRING subkey_name;
221  HANDLE devices_key_handle;
222 
223  ULONG key_index = 0;
224  ULONG result_length;
225 
226  status = OpenSubkey(RegistryPath, Subkey, KEY_ENUMERATE_SUB_KEYS, &devices_key_handle);
227 
228  if ( ! NT_SUCCESS(status) )
229  return status;
230 
231  while ( TRUE )
232  {
235  ULONG size;
236  PWSTR name;
237 
238  status = ZwEnumerateKey(devices_key_handle,
239  key_index,
241  &test_info,
242  sizeof(test_info),
243  &result_length);
244 
246  break;
247 
248  size = result_length + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
249 
251 
252  if ( ! info )
253  {
254  DPRINT("Out of memory\n");
256  break;
257  }
258 
259  status = ZwEnumerateKey(devices_key_handle,
260  key_index,
262  info,
263  size,
264  &result_length);
265 
266  if ( ! NT_SUCCESS(status) )
267  {
268  DPRINT("Unable to enumerate keys\n");
271  break;
272  }
273 
274  /* Is this ok? */
275  RtlInitUnicodeString(&subkey_name, Subkey);
276 
278 
279  if ( ! name )
280  {
281  DPRINT("Out of memory\n");
284  break;
285  }
286 
288 
289  /* Call the callback */
291 
293 
294  if ( ! NT_SUCCESS(status) )
295  {
296  DPRINT("Callback FAILED\n");
297  break;
298  }
299 
300  key_index ++;
301  }
302 
303  ZwClose(devices_key_handle);
304 
305  DPRINT("Found %d subkey entries\n", key_index);
306 
307  if ( ( key_index == 0 ) && ( status == STATUS_NO_MORE_ENTRIES ) )
309 
312 
313  return status;
314 }
315 
316 #define EnumerateDeviceKeys(path, callback, driver_obj) \
317  EnumerateSubkey(path, L"Devices", callback, driver_obj)
318 
319 
320 NTSTATUS
322  PCWSTR PrePrefix,
323  PCWSTR Prefix,
324  UCHAR Index,
326 {
328  WCHAR number_buffer[5];
329  UNICODE_STRING unicode_pre_prefix;
330  UNICODE_STRING unicode_prefix;
331  ULONG size;
332 
333  RtlInitUnicodeString(&unicode_pre_prefix, PrePrefix);
334  RtlInitUnicodeString(&unicode_prefix, Prefix);
335 
336  size = unicode_pre_prefix.Length +
337  unicode_prefix.Length +
338  sizeof(number_buffer) +
339  sizeof(UNICODE_NULL);
340 
342  DeviceName->MaximumLength = (USHORT) size;
343 
344  if ( ! DeviceName->Buffer )
346 
347  RtlCopyUnicodeString(DeviceName, &unicode_pre_prefix);
348  RtlAppendUnicodeStringToString(DeviceName, &unicode_prefix);
349 
350  if ( Index != 255 )
351  {
352  number.Buffer = number_buffer;
353  number.MaximumLength = sizeof(number_buffer);
354 
357  }
358 
359  DeviceName->Buffer[DeviceName->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
360 
361  return STATUS_SUCCESS;
362 }
363 
368 {
370  PDEVICE_OBJECT device_object;
371  PSOUND_BLASTER_PARAMETERS parameters = NULL;
373  UNICODE_STRING dos_device_name;
374 
375  UCHAR device_index = 0;
376 
377  DPRINT("Initializing a Sound Blaster device\n");
378 
379  /* Change these later */
381  L"\\Device\\WaveOut",
382  device_index,
383  &device_name);
384 
385  if ( ! NT_SUCCESS(status) )
386  return status;
387 
388  status = CreateDeviceName(L"\\DosDevices\\",
389  L"\\Device\\WaveOut" + wcslen(L"\\Device\\"),
390  device_index,
391  &dos_device_name);
392 
393  if ( ! NT_SUCCESS(status) )
394  {
395  /* TODO */
396  return status;
397  }
398 
399  DPRINT("Device: %wZ\n", &device_name);
400  DPRINT("Symlink: %wZ\n", &dos_device_name);
401 
402  /*
403  Create the device and DOS symlink
404  */
405 
407  sizeof(SOUND_BLASTER_PARAMETERS),
408  &device_name,
410  0,
411  FALSE,
412  &device_object);
413 
414  if ( ! NT_SUCCESS(status) )
415  return status;
416 
417  DPRINT("Created a device extension at 0x%x\n", device_object->DeviceExtension);
418  parameters = device_object->DeviceExtension;
419 
420  status = IoCreateSymbolicLink(&dos_device_name, &device_name);
421 
422  ExFreePool(dos_device_name.Buffer);
423  ExFreePool(device_name.Buffer);
424 
425  if ( ! NT_SUCCESS(status) )
426  {
427  IoDeleteDevice(device_object);
428  device_object = NULL;
429  return status;
430  }
431 
432  /* IoRegisterShutdownNotification( */
433 
434  /*
435  Settings
436  */
437 
438  device_object->AlignmentRequirement = FILE_BYTE_ALIGNMENT;
439 
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;
446 
447  /* TODO: Load the settings from the registry */
448 
449  DPRINT("Port %x IRQ %d DMA %d\n", parameters->port, parameters->irq, parameters->dma);
450 
451  DPRINT("Resetting the sound card\n");
452 
453  if ( ! ResetSoundBlaster(parameters) )
454  {
455  /* TODO */
456  return STATUS_UNSUCCESSFUL;
457  }
458 
459  /*
460  DPRINT("What kind of SB card is this?\n");
461  GetSoundBlasterModel(parameters);
462  */
463 
464  return STATUS_SUCCESS;
465 }
466 
467 
472 {
474 
475  DPRINT("Sound Blaster driver 0.1 by Silver Blade\n");
476 
477  DriverObject->Flags = 0;
484 
485  DPRINT("Beginning device key enumeration\n");
486 
488 
489  return status;
490 }
const uint16_t * PCWSTR
Definition: typedefs.h:55
NTSTATUS NTAPI EnumerateSubkey(PUNICODE_STRING RegistryPath, PWSTR Subkey, PREGISTRY_CALLBACK_ROUTINE Callback, PDRIVER_OBJECT DriverObject)
Definition: main.c:213
#define FILE_BYTE_ALIGNMENT
Definition: nt_native.h:786
#define TRUE
Definition: types.h:120
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define DEFAULT_PORT
Definition: mpu401.h:19
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI UnloadSoundBlaster(PDRIVER_OBJECT DriverObject)
Definition: main.c:117
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
_In_ PIRP Irp
Definition: csq.h:116
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
const GLint * attribs
Definition: glext.h:10538
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR device_name[]
Definition: btrfs.c:61
ush Pos
Definition: deflate.h:92
const char * name
Definition: main.c:224
static stack_node_t * stack
Definition: rpn_ieee.c:37
NTSTATUS CreateDeviceName(PCWSTR PrePrefix, PCWSTR Prefix, UCHAR Index, PUNICODE_STRING DeviceName)
Definition: main.c:321
WCHAR DeviceName[]
Definition: adapter.cpp:21
NTSTATUS NTAPI ControlSoundBlaster(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: main.c:75
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
struct _test_info info[]
Definition: SetCursorPos.c:19
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
#define FreeRegistryPathInfo(ptr)
Definition: main.c:205
NTSTATUS NTAPI CloseSoundBlaster(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: main.c:41
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
static size_t double number
Definition: printf.c:69
#define DEFAULT_DMA
Definition: sndblst.h:14
BOOLEAN ResetSoundBlaster(PSOUND_BLASTER_PARAMETERS SBDevice)
Definition: control.c:59
struct _KEY_BASIC_INFORMATION * PKEY_BASIC_INFORMATION
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
Definition: _stack.h:47
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
REGISTRY_CALLBACK_ROUTINE * PREGISTRY_CALLBACK_ROUTINE
Definition: mpu401.h:121
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PWSTR NTAPI AllocateRegistryPathInfo(PUNICODE_STRING BasePath, PUNICODE_STRING ParametersPath, PKEY_BASIC_INFORMATION KeyInfo)
Definition: main.c:167
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSTATUS NTAPI CleanupSoundBlaster(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: main.c:58
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
static const WCHAR L[]
Definition: oid.c:1250
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define FILE_DEVICE_SOUND
Definition: winioctl.h:134
#define DEFAULT_BUFFER_SIZE
Definition: sndblst.h:15
#define EnumerateDeviceKeys(path, callback, driver_obj)
Definition: main.c:316
NTSTATUS NTAPI CreateSoundBlaster(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: main.c:21
PDRIVER_OBJECT driver
Definition: sndblst.h:58
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
BOOLEAN EnableSpeaker(PSOUND_BLASTER_PARAMETERS SBDevice)
Definition: control.c:158
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: main.c:690
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSTATUS NTAPI WriteSoundBlaster(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: main.c:100
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define TAG_REG_INFO
Definition: main.c:209
#define DEFAULT_IRQ
Definition: mpu401.h:20
static void test_info(void)
Definition: eventlog.c:131
NTSTATUS NTAPI OpenSubkey(PUNICODE_STRING RegistryPath, PWSTR Subkey, ACCESS_MASK DesiredAccess, OUT HANDLE *DevicesKeyHandle)
Definition: main.c:124
#define IRP_MJ_CLEANUP
Definition: name.c:38
#define OUT
Definition: typedefs.h:39
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
NTSTATUS NTAPI InitializeSoundBlaster(PDRIVER_OBJECT DriverObject, PWSTR RegistryPath)
Definition: main.c:365
unsigned int ULONG
Definition: retypes.h:1
#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
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:605
return STATUS_SUCCESS
Definition: btrfs.c:2938
LPFNPSPCALLBACK Callback
Definition: desk.c:111
static SERVICE_STATUS status
Definition: service.c:31
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
Definition: ps.c:97