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

sndblst.c
Go to the documentation of this file.
00001 /*
00002  *
00003  * COPYRIGHT:           See COPYING in the top level directory
00004  * PROJECT:             ReactOS Sound System
00005  * FILE:                drivers/multimedia/audio/sndblst/sndblst.c
00006  * PURPOSE:             Sound Blaster / Pro / 16 driver
00007  * PROGRAMMER:          Andrew Greenwood (silverblade@reactos.org)
00008  *
00009  * UPDATE HISTORY:      Feb 25, 2009: New rewrite started
00010  *
00011  */
00012 
00013 /* DEFINES AND INCLUDES ******************************************************/
00014 
00015 #include <ntddk.h>
00016 #include <windef.h>
00017 #include <mmsystem.h>
00018 #include <debug.h>
00019 
00020 #define CompleteIrpAndReturn(irp, status) \
00021     irp->IoStatus.Status = status; \
00022     irp->IoStatus.Information = 0; \
00023     IoCompleteRequest(Irp, IO_NO_INCREMENT); \
00024     return status;
00025 
00026 
00027 /* FORWARD DECLARATIONS *****************************************************/
00028 
00029 static VOID NTAPI
00030 UnloadSoundBlaster(PDRIVER_OBJECT DriverObject);
00031 
00032 
00033 /* DEVICE "DISCOVERY" *******************************************************/
00034 /* Nb: These need to go in the helper lib */
00035 
00036 typedef NTSTATUS (*SOUNDDEVICEENUMERATIONCALLBACK)(
00037     IN  PUNICODE_STRING DeviceRegistryPath);
00038 
00039 NTSTATUS
00040 EnumerateSoundDevices(
00041     IN  PUNICODE_STRING RegistryPath,
00042     IN  PWSTR RegistrySubKey,
00043     IN  SOUNDDEVICEENUMERATIONCALLBACK Callback)
00044 {
00045     NTSTATUS Status;
00046     OBJECT_ATTRIBUTES RegAttributes;
00047     HKEY MainKeyHandle, ChildKeyHandle;
00048     UNICODE_STRING UnicodeSubkeyName, DeviceKeyName;
00049     KEY_BASIC_INFORMATION KeyInfo, *FinalKeyInfo;
00050     ULONG i = 0, NeededDataLength = 0, FinalDataLength = 0, NameLength = 0;
00051 
00052     /* Turn the subkey name into a Unicode string */
00053     RtlInitUnicodeString(&UnicodeSubkeyName, RegistrySubKey);
00054 
00055     /* Open the registry key for the service */
00056     InitializeObjectAttributes(&RegAttributes,
00057                                RegistryPath,
00058                                OBJ_CASE_INSENSITIVE,
00059                                NULL,
00060                                (PSECURITY_DESCRIPTOR) NULL);
00061 
00062     Status = ZwOpenKey(&MainKeyHandle, KEY_READ, &RegAttributes);
00063 
00064     if ( ! NT_SUCCESS(Status) )
00065     {
00066         DPRINT("Failed to open registry key\n");
00067         return Status;
00068     }
00069 
00070     /* Open the subkey usually named "Parameters" */
00071     InitializeObjectAttributes(&RegAttributes,
00072                                &UnicodeSubkeyName,
00073                                OBJ_CASE_INSENSITIVE,
00074                                MainKeyHandle,
00075                                (PSECURITY_DESCRIPTOR) NULL);
00076 
00077     Status = ZwOpenKey(&ChildKeyHandle, KEY_ENUMERATE_SUB_KEYS, &RegAttributes);
00078 
00079     /* We're done with the main key now */
00080     ZwClose(MainKeyHandle);
00081 
00082     if ( ! NT_SUCCESS(Status) )
00083     {
00084         DPRINT("Failed to open registry subkeys for enumeration\n");
00085         return Status;
00086     }
00087 
00088     /* Enumerate through the device keys */
00089     while ( ( Status = ZwEnumerateKey(ChildKeyHandle,
00090                                       i,
00091                                       KeyBasicInformation,
00092                                       &KeyInfo,
00093                                       sizeof(KEY_BASIC_INFORMATION),
00094                                       &NeededDataLength) ) != STATUS_NO_MORE_ENTRIES )
00095     {
00096         PWSTR EnumeratedKeyName, StartOfEnumeratedKeyName;
00097 
00098         DPRINT("Found subkey %d\n", i);
00099 
00100         FinalDataLength = NeededDataLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
00101         DPRINT("Allocating %d bytes\n", FinalDataLength);
00102 
00103         FinalKeyInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, FinalDataLength);
00104 
00105         if ( ! FinalKeyInfo )
00106         {
00107             Status = STATUS_INSUFFICIENT_RESOURCES;
00108             break;
00109         }
00110 
00111         /* This time we get the real info */
00112         Status = ZwEnumerateKey(ChildKeyHandle,
00113                                 i,
00114                                 KeyBasicInformation,
00115                                 FinalKeyInfo,
00116                                 FinalDataLength,
00117                                 &NeededDataLength);
00118 
00119         if ( ! NT_SUCCESS(Status) )
00120         {
00121             DPRINT("FAILED to enumerate key!\n");
00122         }
00123         else
00124         {
00125             NameLength = RegistryPath->Length + sizeof(WCHAR) +
00126                          UnicodeSubkeyName.Length + sizeof(WCHAR) +
00127                          FinalKeyInfo->NameLength + sizeof(UNICODE_NULL);
00128 
00129             DPRINT("Allocating memory for name (%d bytes)\n", NameLength);
00130 
00131             EnumeratedKeyName = (PWSTR) ExAllocatePool(PagedPool, NameLength);
00132 
00133             if ( ! EnumeratedKeyName )
00134             {
00135                 ExFreePool((PVOID)FinalKeyInfo);
00136                 Status = STATUS_INSUFFICIENT_RESOURCES;
00137                 break;
00138             }
00139 
00140             StartOfEnumeratedKeyName = EnumeratedKeyName;
00141 
00142             /* Start building the registry path using the service key */
00143             RtlCopyMemory(EnumeratedKeyName,
00144                           RegistryPath->Buffer,
00145                           RegistryPath->Length);
00146 
00147             EnumeratedKeyName += RegistryPath->Length / sizeof(WCHAR);
00148             EnumeratedKeyName[0] = '\\';
00149             ++ EnumeratedKeyName;
00150 
00151             /* Append the parameters subkey */
00152             RtlCopyMemory(EnumeratedKeyName,
00153                           RegistrySubKey,
00154                           UnicodeSubkeyName.Length);
00155 
00156             EnumeratedKeyName += UnicodeSubkeyName.Length / sizeof(WCHAR);
00157             EnumeratedKeyName[0] = '\\';
00158             ++ EnumeratedKeyName;
00159 
00160             /* And finally append the enumerated key name */
00161             RtlCopyMemory(EnumeratedKeyName,
00162                           FinalKeyInfo->Name,
00163                           FinalKeyInfo->NameLength);
00164 
00165             EnumeratedKeyName += FinalKeyInfo->NameLength / sizeof(WCHAR);
00166             EnumeratedKeyName[0] = UNICODE_NULL;
00167 
00168             /* Reset pointer */
00169             EnumeratedKeyName = StartOfEnumeratedKeyName;
00170 
00171             /* Convert into a Unicode string for the callback */
00172             RtlInitUnicodeString(&DeviceKeyName, EnumeratedKeyName);
00173 
00174             Callback(&DeviceKeyName);
00175 
00176             /* No longer need the key name */
00177             ExFreePool((PVOID)EnumeratedKeyName);
00178             EnumeratedKeyName = NULL;
00179         }
00180 
00181         /* No longer need the key info */
00182         ExFreePool((PVOID)FinalKeyInfo);
00183         FinalKeyInfo = NULL;
00184 
00185         ++ i;
00186     }
00187 
00188     /* We're done with enumeration so close this */
00189     ZwClose(ChildKeyHandle);
00190 
00191     /* This isn't an error */
00192     if ( Status == STATUS_NO_MORE_ENTRIES )
00193     {
00194         Status = STATUS_SUCCESS;
00195     }
00196 
00197     /* No devices configured? */
00198     if ( i == 0 && Status == STATUS_NO_MORE_ENTRIES )
00199     {
00200         Status = STATUS_DEVICE_CONFIGURATION_ERROR;
00201     }
00202 
00203     return Status;
00204 }
00205 
00206 NTSTATUS
00207 PublishWaveOutDevice(
00208     IN  DWORD HardwareDeviceIndex,
00209     IN  PWSTR BaseDeviceName,
00210     IN  DWORD DeviceIndex,
00211     IN  LPWAVEOUTCAPS Capabilities)
00212 {
00213     return STATUS_SUCCESS;
00214 }
00215 
00216 
00217 typedef struct _SOUND_BLASTER_DEVICE
00218 {
00219     DWORD   BasePort;
00220     DWORD   MidiUartBasePort;
00221 
00222     DWORD   Irq;
00223 
00224     DWORD   DmaChannel_8;
00225     DWORD   DmaChannel_16;
00226 
00227     DWORD   DspVersion;
00228 
00229     DWORD   ActualDmaBufferSize;
00230     DWORD   DmaBufferSize;
00231 } SOUND_BLASTER_DEVICE;
00232 
00233 
00234 NTSTATUS
00235 AllocateSoundBlasterStructure(OUT SOUND_BLASTER_DEVICE* SoundBlasterDevice)
00236 {
00237     return STATUS_NOT_IMPLEMENTED;
00238 }
00239 
00240 /* callback */
00241 /*
00242     Configuration options within the registry:
00243     REG_DWORD   Actual Dma Buffer Size      0x00004000
00244     REG_DWORD   Configuration Error         0xffffffff
00245     REG_DWORD   Dma Buffer Size             0x00004000
00246     REG_DWORD   DmaChannel                  0x00000001
00247     REG_DWORD   DmaChannel16                0x00000005
00248     REG_DWORD   DSP Version                 0x00000405
00249     REG_DWORD   Interrupt                   0x00000005
00250     REG_DWORD   Load Type                   0x00000000
00251     REG_BINARY  Mixer Settings              ??
00252     REG_DWORD   MPU401 Port                 0xffffffff
00253     REG_DWORD   Port                        0x00000220
00254 */
00255 
00256 NTSTATUS
00257 ConfigureSoundBlasterDevice(IN PUNICODE_STRING DeviceRegistryPath)
00258 {
00259     OBJECT_ATTRIBUTES RegAttributes;
00260     NTSTATUS Status = STATUS_SUCCESS;
00261     HKEY ConfigKeyHandle;
00262 
00263     DPRINT("Configuring Sound Blaster (config at %S)\n", DeviceRegistryPath->Buffer);
00264 
00265     if ( ! DeviceRegistryPath )
00266     {
00267         return STATUS_INVALID_PARAMETER;
00268     }
00269 
00270     /* Open the registry key */
00271     InitializeObjectAttributes(&RegAttributes,
00272                                DeviceRegistryPath,
00273                                OBJ_CASE_INSENSITIVE,
00274                                NULL,
00275                                (PSECURITY_DESCRIPTOR) NULL);
00276 
00277     Status = ZwOpenKey(&ConfigKeyHandle, KEY_READ, &RegAttributes);
00278 
00279     if ( ! NT_SUCCESS(Status) )
00280     {
00281         DPRINT("Failed to open config registry key\n");
00282         return Status;
00283     }
00284 
00285     /* Read configuration */
00286     DPRINT("Reading configuration\n");
00287 
00288     //Status = ZwQueryValueKey(ConfigKeyHandle,
00289 
00290     return Status;
00291 }
00292 
00293 
00294 /* IRP DISPATCHERS **********************************************************/
00295 
00296 static NTSTATUS NTAPI
00297 CreateSoundBlaster(
00298     IN  PDEVICE_OBJECT DeviceObject,
00299     IN  PIRP Irp)
00300 {
00301     DPRINT("Sound Blaster driver received IRP_MJ_CREATE\n");
00302 
00303     CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
00304 }
00305 
00306 static NTSTATUS NTAPI
00307 CloseSoundBlaster(
00308     IN  PDEVICE_OBJECT DeviceObject,
00309     IN  PIRP Irp)
00310 {
00311     DPRINT("Sound Blaster driver received IRP_MJ_CLOSE\n");
00312 
00313     CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
00314 }
00315 
00316 static NTSTATUS NTAPI
00317 CleanupSoundBlaster(
00318     IN  PDEVICE_OBJECT DeviceObject,
00319     IN  PIRP Irp)
00320 {
00321     DPRINT("Sound Blaster driver received IRP_MJ_CLEANUP\n");
00322 
00323     CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
00324 }
00325 
00326 static NTSTATUS NTAPI
00327 ControlSoundBlaster(
00328     IN  PDEVICE_OBJECT DeviceObject,
00329     IN  PIRP Irp)
00330 {
00331     DPRINT("Sound Blaster driver received IRP_MJ_CONTROL\n");
00332 
00333     CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
00334 }
00335 
00336 static NTSTATUS NTAPI
00337 WriteToSoundBlaster(
00338     IN  PDEVICE_OBJECT DeviceObject,
00339     IN  PIRP Irp)
00340 {
00341     DPRINT("Sound Blaster driver received IRP_MJ_WRITE\n");
00342 
00343     CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
00344 }
00345 
00346 
00347 /* DRIVER ENTRYPOINT ********************************************************/
00348 
00349 NTSTATUS NTAPI
00350 DriverEntry(
00351     IN  PDRIVER_OBJECT DriverObject,
00352     IN  PUNICODE_STRING RegistryPath)
00353 {
00354     NTSTATUS Status = STATUS_SUCCESS;
00355 
00356     DPRINT("Sound Blaster driver by silverblade\n");
00357 
00358     DriverObject->Flags = 0;
00359     DriverObject->MajorFunction[IRP_MJ_CREATE] = CreateSoundBlaster;
00360     DriverObject->MajorFunction[IRP_MJ_CLOSE] = CloseSoundBlaster;
00361     DriverObject->MajorFunction[IRP_MJ_CLEANUP] = CleanupSoundBlaster;
00362     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlSoundBlaster;
00363     DriverObject->MajorFunction[IRP_MJ_WRITE] = WriteToSoundBlaster;
00364     DriverObject->DriverUnload = UnloadSoundBlaster;
00365 
00366     EnumerateSoundDevices(RegistryPath, L"Parameters", ConfigureSoundBlasterDevice);
00367 
00368     return Status;
00369 }
00370 
00371 static VOID NTAPI
00372 UnloadSoundBlaster(IN PDRIVER_OBJECT DriverObject)
00373 {
00374     DPRINT("Sound Blaster driver is being unloaded\n");
00375 }

Generated on Sun May 27 2012 04:26:33 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.