Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensndblst.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
1.7.6.1
|