Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmain.c
Go to the documentation of this file.
00001 /* 00002 ReactOS 00003 Sound Blaster driver 00004 00005 Programmers: 00006 Andrew Greenwood 00007 00008 Notes: 00009 Compatible with NT4 00010 */ 00011 00012 #define NDEBUG 00013 #include <sndblst.h> 00014 00015 00016 /* 00017 IRP DISPATCH ROUTINES 00018 */ 00019 00020 NTSTATUS NTAPI 00021 CreateSoundBlaster( 00022 PDEVICE_OBJECT DeviceObject, 00023 PIRP Irp) 00024 { 00025 PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension; 00026 00027 DPRINT("CreateSoundBlaster() called - extension 0x%x\n", sb_device); 00028 00029 EnableSpeaker(sb_device); 00030 /*SetOutputSampleRate(sb_device, 22*/ 00031 00032 Irp->IoStatus.Status = STATUS_SUCCESS; 00033 Irp->IoStatus.Information = 0; 00034 00035 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00036 00037 return STATUS_SUCCESS; 00038 } 00039 00040 NTSTATUS NTAPI 00041 CloseSoundBlaster( 00042 PDEVICE_OBJECT DeviceObject, 00043 PIRP Irp) 00044 { 00045 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension; 00046 00047 DPRINT("CloseSoundBlaster() called\n"); 00048 00049 Irp->IoStatus.Status = STATUS_SUCCESS; 00050 Irp->IoStatus.Information = 0; 00051 00052 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00053 00054 return STATUS_SUCCESS; 00055 } 00056 00057 NTSTATUS NTAPI 00058 CleanupSoundBlaster( 00059 PDEVICE_OBJECT DeviceObject, 00060 PIRP Irp) 00061 { 00062 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension; 00063 00064 DPRINT("CleanupSoundBlaster() called\n"); 00065 00066 Irp->IoStatus.Status = STATUS_SUCCESS; 00067 Irp->IoStatus.Information = 0; 00068 00069 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00070 00071 return STATUS_SUCCESS; 00072 } 00073 00074 NTSTATUS NTAPI 00075 ControlSoundBlaster( 00076 PDEVICE_OBJECT DeviceObject, 00077 PIRP Irp) 00078 { 00079 PIO_STACK_LOCATION stack; 00080 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension; 00081 00082 DPRINT("ControlSoundBlaster() called\n"); 00083 00084 stack = IoGetCurrentIrpStackLocation(Irp); 00085 00086 switch ( stack->Parameters.DeviceIoControl.IoControlCode) 00087 { 00088 /* TODO */ 00089 }; 00090 00091 Irp->IoStatus.Status = STATUS_SUCCESS; 00092 Irp->IoStatus.Information = 0; 00093 00094 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00095 00096 return STATUS_SUCCESS; 00097 } 00098 00099 NTSTATUS NTAPI 00100 WriteSoundBlaster( 00101 PDEVICE_OBJECT DeviceObject, 00102 PIRP Irp) 00103 { 00104 //PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension; 00105 00106 DPRINT("WriteSoundBlaster() called\n"); 00107 00108 Irp->IoStatus.Status = STATUS_SUCCESS; 00109 Irp->IoStatus.Information = 0; 00110 00111 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00112 00113 return STATUS_SUCCESS; 00114 } 00115 00116 VOID NTAPI 00117 UnloadSoundBlaster( 00118 PDRIVER_OBJECT DriverObject) 00119 { 00120 DPRINT("Sound Blaster driver unload\n"); 00121 } 00122 00123 NTSTATUS NTAPI 00124 OpenSubkey( 00125 PUNICODE_STRING RegistryPath, 00126 PWSTR Subkey, 00127 ACCESS_MASK DesiredAccess, 00128 OUT HANDLE* DevicesKeyHandle) 00129 { 00130 NTSTATUS status; 00131 OBJECT_ATTRIBUTES attribs; 00132 UNICODE_STRING subkey_name; 00133 HANDLE key_handle; 00134 00135 /* TODO: Check for NULL ptr in DevicesKeyHandle */ 00136 00137 InitializeObjectAttributes(&attribs, 00138 RegistryPath, 00139 OBJ_CASE_INSENSITIVE, 00140 NULL, 00141 (PSECURITY_DESCRIPTOR) NULL); 00142 00143 status = ZwOpenKey(&key_handle, KEY_READ, &attribs); 00144 00145 if ( ! NT_SUCCESS(status) ) 00146 { 00147 DPRINT("Couldn't open subkey %wZ\n", Subkey); 00148 return status; 00149 } 00150 00151 RtlInitUnicodeString(&subkey_name, Subkey); 00152 00153 InitializeObjectAttributes(&attribs, 00154 &subkey_name, 00155 OBJ_CASE_INSENSITIVE, 00156 key_handle, 00157 (PSECURITY_DESCRIPTOR) NULL); 00158 00159 status = ZwOpenKey(*DevicesKeyHandle, DesiredAccess, &attribs); 00160 ZwClose(key_handle); 00161 00162 return status; 00163 } 00164 00165 00166 PWSTR NTAPI 00167 AllocateRegistryPathInfo( 00168 PUNICODE_STRING BasePath, 00169 PUNICODE_STRING ParametersPath, 00170 PKEY_BASIC_INFORMATION KeyInfo) 00171 { 00172 PWSTR name; 00173 PWSTR pos; 00174 00175 DPRINT("Allocating memory for path info\n"); 00176 name = ExAllocatePool(PagedPool, 00177 BasePath->Length + sizeof(WCHAR) + 00178 ParametersPath->Length + sizeof(WCHAR) + 00179 KeyInfo->NameLength + sizeof(UNICODE_NULL)); 00180 00181 if ( ! name ) 00182 return NULL; 00183 00184 DPRINT("Copying info\n"); 00185 pos = name; 00186 00187 RtlCopyMemory((PVOID)Pos, (PVOID)BasePath->Buffer, BasePath->Length); 00188 pos += BasePath->Length / sizeof(WCHAR); 00189 pos[0] = '\\'; 00190 pos ++; 00191 00192 RtlCopyMemory((PVOID)Pos, (PVOID)ParametersPath->Buffer, ParametersPath->Length); 00193 pos += ParametersPath->Length / sizeof(WCHAR); 00194 pos[0] = '\\'; 00195 pos ++; 00196 00197 RtlCopyMemory((PVOID)Pos, (PVOID)ParametersPath->Buffer, ParametersPath->Length); 00198 pos += KeyInfo->NameLength / sizeof(WCHAR); 00199 pos[0] = UNICODE_NULL; 00200 00201 DPRINT("All OK\n"); 00202 return name; 00203 } 00204 00205 #define FreeRegistryPathInfo(ptr) \ 00206 ExFreePool(ptr) 00207 00208 00209 #define TAG_REG_INFO 'RegI' 00210 #define TAG_REG_NAME 'RegN' 00211 00212 NTSTATUS NTAPI 00213 EnumerateSubkey( 00214 PUNICODE_STRING RegistryPath, 00215 PWSTR Subkey, 00216 PREGISTRY_CALLBACK_ROUTINE Callback, 00217 PDRIVER_OBJECT DriverObject) 00218 { 00219 NTSTATUS status; 00220 UNICODE_STRING subkey_name; 00221 HANDLE devices_key_handle; 00222 00223 ULONG key_index = 0; 00224 ULONG result_length; 00225 00226 status = OpenSubkey(RegistryPath, Subkey, KEY_ENUMERATE_SUB_KEYS, &devices_key_handle); 00227 00228 if ( ! NT_SUCCESS(status) ) 00229 return status; 00230 00231 while ( TRUE ) 00232 { 00233 KEY_BASIC_INFORMATION test_info; 00234 PKEY_BASIC_INFORMATION info; 00235 ULONG size; 00236 PWSTR name; 00237 00238 status = ZwEnumerateKey(devices_key_handle, 00239 key_index, 00240 KeyBasicInformation, 00241 &test_info, 00242 sizeof(test_info), 00243 &result_length); 00244 00245 if ( status == STATUS_NO_MORE_ENTRIES ) 00246 break; 00247 00248 size = result_length + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]); 00249 00250 info = (PKEY_BASIC_INFORMATION) ExAllocatePoolWithTag(PagedPool, size, TAG_REG_INFO); 00251 00252 if ( ! info ) 00253 { 00254 DPRINT("Out of memory\n"); 00255 status = STATUS_INSUFFICIENT_RESOURCES; 00256 break; 00257 } 00258 00259 status = ZwEnumerateKey(devices_key_handle, 00260 key_index, 00261 KeyBasicInformation, 00262 info, 00263 size, 00264 &result_length); 00265 00266 if ( ! NT_SUCCESS(status) ) 00267 { 00268 DPRINT("Unable to enumerate keys\n"); 00269 ExFreePoolWithTag(info, TAG_REG_INFO); 00270 status = STATUS_INTERNAL_ERROR; 00271 break; 00272 } 00273 00274 /* Is this ok? */ 00275 RtlInitUnicodeString(&subkey_name, Subkey); 00276 00277 name = AllocateRegistryPathInfo(RegistryPath, &subkey_name, info); 00278 00279 if ( ! name ) 00280 { 00281 DPRINT("Out of memory\n"); 00282 ExFreePoolWithTag(info, TAG_REG_INFO); 00283 status = STATUS_INSUFFICIENT_RESOURCES; 00284 break; 00285 } 00286 00287 ExFreePoolWithTag(info, TAG_REG_INFO); 00288 00289 /* Call the callback */ 00290 status = Callback(DriverObject, name); 00291 00292 FreeRegistryPathInfo(name); 00293 00294 if ( ! NT_SUCCESS(status) ) 00295 { 00296 DPRINT("Callback FAILED\n"); 00297 break; 00298 } 00299 00300 key_index ++; 00301 } 00302 00303 ZwClose(devices_key_handle); 00304 00305 DPRINT("Found %d subkey entries\n", key_index); 00306 00307 if ( ( key_index == 0 ) && ( status == STATUS_NO_MORE_ENTRIES ) ) 00308 return STATUS_DEVICE_CONFIGURATION_ERROR; 00309 00310 if ( status == STATUS_NO_MORE_ENTRIES ) 00311 status = STATUS_SUCCESS; 00312 00313 return status; 00314 } 00315 00316 #define EnumerateDeviceKeys(path, callback, driver_obj) \ 00317 EnumerateSubkey(path, L"Devices", callback, driver_obj) 00318 00319 00320 NTSTATUS 00321 CreateDeviceName( 00322 PCWSTR PrePrefix, 00323 PCWSTR Prefix, 00324 UCHAR Index, 00325 PUNICODE_STRING DeviceName) 00326 { 00327 UNICODE_STRING number; 00328 WCHAR number_buffer[5]; 00329 UNICODE_STRING unicode_pre_prefix; 00330 UNICODE_STRING unicode_prefix; 00331 ULONG size; 00332 00333 RtlInitUnicodeString(&unicode_pre_prefix, PrePrefix); 00334 RtlInitUnicodeString(&unicode_prefix, Prefix); 00335 00336 size = unicode_pre_prefix.Length + 00337 unicode_prefix.Length + 00338 sizeof(number_buffer) + 00339 sizeof(UNICODE_NULL); 00340 00341 DeviceName->Buffer = ExAllocatePool(PagedPool, size); 00342 DeviceName->MaximumLength = (USHORT) size; 00343 00344 if ( ! DeviceName->Buffer ) 00345 return STATUS_INSUFFICIENT_RESOURCES; 00346 00347 RtlCopyUnicodeString(DeviceName, &unicode_pre_prefix); 00348 RtlAppendUnicodeStringToString(DeviceName, &unicode_prefix); 00349 00350 if ( Index != 255 ) 00351 { 00352 number.Buffer = number_buffer; 00353 number.MaximumLength = sizeof(number_buffer); 00354 00355 RtlIntegerToUnicodeString((ULONG) Index, 10, &number); 00356 RtlAppendUnicodeStringToString(DeviceName, &number); 00357 } 00358 00359 DeviceName->Buffer[DeviceName->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL; 00360 00361 return STATUS_SUCCESS; 00362 } 00363 00364 NTSTATUS NTAPI 00365 InitializeSoundBlaster( 00366 PDRIVER_OBJECT DriverObject, 00367 PWSTR RegistryPath) 00368 { 00369 NTSTATUS status; 00370 PDEVICE_OBJECT device_object; 00371 PSOUND_BLASTER_PARAMETERS parameters = NULL; 00372 UNICODE_STRING device_name; 00373 UNICODE_STRING dos_device_name; 00374 00375 UCHAR device_index = 0; 00376 00377 DPRINT("Initializing a Sound Blaster device\n"); 00378 00379 /* Change these later */ 00380 status = CreateDeviceName(L"", 00381 L"\\Device\\WaveOut", 00382 device_index, 00383 &device_name); 00384 00385 if ( ! NT_SUCCESS(status) ) 00386 return status; 00387 00388 status = CreateDeviceName(L"\\DosDevices\\", 00389 L"\\Device\\WaveOut" + wcslen(L"\\Device\\"), 00390 device_index, 00391 &dos_device_name); 00392 00393 if ( ! NT_SUCCESS(status) ) 00394 { 00395 /* TODO */ 00396 return status; 00397 } 00398 00399 DPRINT("Device: %wZ\n", device_name); 00400 DPRINT("Symlink: %wZ\n", dos_device_name); 00401 00402 /* 00403 Create the device and DOS symlink 00404 */ 00405 00406 status = IoCreateDevice(DriverObject, 00407 sizeof(SOUND_BLASTER_PARAMETERS), 00408 &device_name, 00409 FILE_DEVICE_SOUND, 00410 0, 00411 FALSE, 00412 &device_object); 00413 00414 if ( ! NT_SUCCESS(status) ) 00415 return status; 00416 00417 DPRINT("Created a device extension at 0x%x\n", device_object->DeviceExtension); 00418 parameters = device_object->DeviceExtension; 00419 00420 status = IoCreateSymbolicLink(&dos_device_name, &device_name); 00421 00422 ExFreePool(dos_device_name.Buffer); 00423 ExFreePool(device_name.Buffer); 00424 00425 if ( ! NT_SUCCESS(status) ) 00426 { 00427 IoDeleteDevice(device_object); 00428 device_object = NULL; 00429 return status; 00430 } 00431 00432 /* IoRegisterShutdownNotification( */ 00433 00434 /* 00435 Settings 00436 */ 00437 00438 device_object->AlignmentRequirement = FILE_BYTE_ALIGNMENT; 00439 00440 parameters->driver = DriverObject; 00441 parameters->registry_path = RegistryPath; 00442 parameters->port = DEFAULT_PORT; 00443 parameters->irq = DEFAULT_IRQ; 00444 parameters->dma = DEFAULT_DMA; 00445 parameters->buffer_size = DEFAULT_BUFFER_SIZE; 00446 00447 /* TODO: Load the settings from the registry */ 00448 00449 DPRINT("Port %x IRQ %d DMA %d\n", parameters->port, parameters->irq, parameters->dma); 00450 00451 DPRINT("Resetting the sound card\n"); 00452 00453 if ( ! ResetSoundBlaster(parameters) ) 00454 { 00455 /* TODO */ 00456 return STATUS_UNSUCCESSFUL; 00457 } 00458 00459 /* 00460 DPRINT("What kind of SB card is this?\n"); 00461 GetSoundBlasterModel(parameters); 00462 */ 00463 00464 return STATUS_SUCCESS; 00465 } 00466 00467 00468 NTSTATUS NTAPI 00469 DriverEntry( 00470 PDRIVER_OBJECT DriverObject, 00471 PUNICODE_STRING RegistryPath) 00472 { 00473 NTSTATUS status; 00474 00475 DPRINT("Sound Blaster driver 0.1 by Silver Blade\n"); 00476 00477 DriverObject->Flags = 0; 00478 DriverObject->MajorFunction[IRP_MJ_CREATE] = CreateSoundBlaster; 00479 DriverObject->MajorFunction[IRP_MJ_CLOSE] = CloseSoundBlaster; 00480 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = CleanupSoundBlaster; 00481 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlSoundBlaster; 00482 DriverObject->MajorFunction[IRP_MJ_WRITE] = WriteSoundBlaster; 00483 DriverObject->DriverUnload = UnloadSoundBlaster; 00484 00485 DPRINT("Beginning device key enumeration\n"); 00486 00487 status = EnumerateDeviceKeys(RegistryPath, *InitializeSoundBlaster, DriverObject); 00488 00489 return status; 00490 } Generated on Fri May 25 2012 04:15:05 for ReactOS by
1.7.6.1
|