ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

main.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.