Started new implementation of Sound Blaster driver (kernel mode), which

at present just looks at the settings in the registry (actual sound
blaster code to go in a dedicated library elsewhere for later reuse in
portcls.) Also updated wdmaud.drv - it can only identify how many devices
have been reported by janderwald's code at present.


svn path=/trunk/; revision=39797
This commit is contained in:
Andrew Greenwood 2009-02-27 22:50:58 +00:00
parent 36bf174662
commit 60a7be44dc
6 changed files with 405 additions and 3 deletions

View file

@ -22,7 +22,7 @@
#include <ksmedia.h>
#include "interface.h"
#define KERNEL_DEVICE_NAME L"\\\\Device\\wdmaud"
#define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
PWSTR UnknownWaveIn = L"Wave Input";
PWSTR UnknownWaveOut = L"Wave Output";
@ -57,8 +57,9 @@ GetNumWdmDevs(
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( ! Result )
if ( ! MMSUCCESS( Result ) )
{
SND_ERR(L"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
*DeviceCount = 0;
return TranslateInternalMmResult(Result);
}
@ -128,6 +129,7 @@ OpenWdmSoundDevice(
/* Only open this if it's not already open */
if ( KernelHandle == INVALID_HANDLE_VALUE )
{
SND_TRACE(L"Opening wdmaud device\n");
KernelHandle = CreateFile(KERNEL_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
@ -153,7 +155,11 @@ CloseWdmSoundDevice(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, /* NOT USED */
IN PVOID Handle)
{
SND_ASSERT( OpenCount > 0 );
if ( OpenCount == 0 )
{
return MMSYSERR_NOERROR;
}
SND_ASSERT( KernelHandle != INVALID_HANDLE_VALUE );
-- OpenCount;

View file

@ -1,6 +1,9 @@
<?xml version="1.0"?>
<!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
<group xmlns:xi="http://www.w3.org/2001/XInclude">
<directory name="sndblst_sys">
<xi:include href="sndblst_sys/sndblst.rbuild" />
</directory>
<!--directory name="mpu401_nt4">
<xi:include href="mpu401_nt4/mpu401.rbuild" />
</directory>

View file

@ -0,0 +1,375 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Sound System
* FILE: drivers/multimedia/audio/sndblst/sndblst.c
* PURPOSE: Sound Blaster / Pro / 16 driver
* PROGRAMMER: Andrew Greenwood (silverblade@reactos.org)
*
* UPDATE HISTORY: Feb 25, 2009: New rewrite started
*
*/
/* DEFINES AND INCLUDES ******************************************************/
#include <ntddk.h>
#include <windef.h>
#include <mmsystem.h>
#include <debug.h>
#define CompleteIrpAndReturn(irp, status) \
irp->IoStatus.Status = status; \
irp->IoStatus.Information = 0; \
IoCompleteRequest(Irp, IO_NO_INCREMENT); \
return status;
/* FORWARD DECLARATIONS *****************************************************/
static VOID NTAPI
UnloadSoundBlaster(PDRIVER_OBJECT DriverObject);
/* DEVICE "DISCOVERY" *******************************************************/
/* Nb: These need to go in the helper lib */
typedef NTSTATUS (*SOUNDDEVICEENUMERATIONCALLBACK)(
IN PUNICODE_STRING DeviceRegistryPath);
NTSTATUS
EnumerateSoundDevices(
IN PUNICODE_STRING RegistryPath,
IN PWSTR RegistrySubKey,
IN SOUNDDEVICEENUMERATIONCALLBACK Callback)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES RegAttributes;
HKEY MainKeyHandle, ChildKeyHandle;
UNICODE_STRING UnicodeSubkeyName, DeviceKeyName;
KEY_BASIC_INFORMATION KeyInfo, *FinalKeyInfo;
ULONG i = 0, NeededDataLength = 0, FinalDataLength = 0, NameLength = 0;
/* Turn the subkey name into a Unicode string */
RtlInitUnicodeString(&UnicodeSubkeyName, RegistrySubKey);
/* Open the registry key for the service */
InitializeObjectAttributes(&RegAttributes,
RegistryPath,
OBJ_CASE_INSENSITIVE,
NULL,
(PSECURITY_DESCRIPTOR) NULL);
Status = ZwOpenKey(&MainKeyHandle, KEY_READ, &RegAttributes);
if ( ! NT_SUCCESS(Status) )
{
DPRINT("Failed to open registry key\n");
return Status;
}
/* Open the subkey usually named "Parameters" */
InitializeObjectAttributes(&RegAttributes,
&UnicodeSubkeyName,
OBJ_CASE_INSENSITIVE,
MainKeyHandle,
(PSECURITY_DESCRIPTOR) NULL);
Status = ZwOpenKey(&ChildKeyHandle, KEY_ENUMERATE_SUB_KEYS, &RegAttributes);
/* We're done with the main key now */
ZwClose(MainKeyHandle);
if ( ! NT_SUCCESS(Status) )
{
DPRINT("Failed to open registry subkeys for enumeration\n");
return Status;
}
/* Enumerate through the device keys */
while ( ( Status = ZwEnumerateKey(ChildKeyHandle,
i,
KeyBasicInformation,
&KeyInfo,
sizeof(KEY_BASIC_INFORMATION),
&NeededDataLength) ) != STATUS_NO_MORE_ENTRIES )
{
PWSTR EnumeratedKeyName, StartOfEnumeratedKeyName;
DPRINT("Found subkey %d\n", i);
FinalDataLength = NeededDataLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
DPRINT("Allocating %d bytes\n", FinalDataLength);
FinalKeyInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, FinalDataLength);
if ( ! FinalKeyInfo )
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
/* This time we get the real info */
Status = ZwEnumerateKey(ChildKeyHandle,
i,
KeyBasicInformation,
FinalKeyInfo,
FinalDataLength,
&NeededDataLength);
if ( ! NT_SUCCESS(Status) )
{
DPRINT("FAILED to enumerate key!\n");
}
else
{
NameLength = RegistryPath->Length + sizeof(WCHAR) +
UnicodeSubkeyName.Length + sizeof(WCHAR) +
FinalKeyInfo->NameLength + sizeof(UNICODE_NULL);
DPRINT("Allocating memory for name (%d bytes)\n", NameLength);
EnumeratedKeyName = (PWSTR) ExAllocatePool(PagedPool, NameLength);
if ( ! EnumeratedKeyName )
{
ExFreePool((PVOID)FinalKeyInfo);
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
StartOfEnumeratedKeyName = EnumeratedKeyName;
/* Start building the registry path using the service key */
RtlCopyMemory(EnumeratedKeyName,
RegistryPath->Buffer,
RegistryPath->Length);
EnumeratedKeyName += RegistryPath->Length / sizeof(WCHAR);
EnumeratedKeyName[0] = '\\';
++ EnumeratedKeyName;
/* Append the parameters subkey */
RtlCopyMemory(EnumeratedKeyName,
RegistrySubKey,
UnicodeSubkeyName.Length);
EnumeratedKeyName += UnicodeSubkeyName.Length / sizeof(WCHAR);
EnumeratedKeyName[0] = '\\';
++ EnumeratedKeyName;
/* And finally append the enumerated key name */
RtlCopyMemory(EnumeratedKeyName,
FinalKeyInfo->Name,
FinalKeyInfo->NameLength);
EnumeratedKeyName += FinalKeyInfo->NameLength / sizeof(WCHAR);
EnumeratedKeyName[0] = UNICODE_NULL;
/* Reset pointer */
EnumeratedKeyName = StartOfEnumeratedKeyName;
/* Convert into a Unicode string for the callback */
RtlInitUnicodeString(&DeviceKeyName, EnumeratedKeyName);
Callback(&DeviceKeyName);
/* No longer need the key name */
ExFreePool((PVOID)EnumeratedKeyName);
EnumeratedKeyName = NULL;
}
/* No longer need the key info */
ExFreePool((PVOID)FinalKeyInfo);
FinalKeyInfo = NULL;
++ i;
}
/* We're done with enumeration so close this */
ZwClose(ChildKeyHandle);
/* This isn't an error */
if ( Status == STATUS_NO_MORE_ENTRIES )
{
Status = STATUS_SUCCESS;
}
/* No devices configured? */
if ( i == 0 && Status == STATUS_NO_MORE_ENTRIES )
{
Status = STATUS_DEVICE_CONFIGURATION_ERROR;
}
return Status;
}
NTSTATUS
PublishWaveOutDevice(
IN DWORD HardwareDeviceIndex,
IN PWSTR BaseDeviceName,
IN DWORD DeviceIndex,
IN LPWAVEOUTCAPS Capabilities)
{
return STATUS_SUCCESS;
}
typedef struct _SOUND_BLASTER_DEVICE
{
DWORD BasePort;
DWORD MidiUartBasePort;
DWORD Irq;
DWORD DmaChannel_8;
DWORD DmaChannel_16;
DWORD DspVersion;
DWORD ActualDmaBufferSize;
DWORD DmaBufferSize;
} SOUND_BLASTER_DEVICE;
NTSTATUS
AllocateSoundBlasterStructure(OUT SOUND_BLASTER_DEVICE* SoundBlasterDevice)
{
return STATUS_NOT_IMPLEMENTED;
}
/* callback */
/*
Configuration options within the registry:
REG_DWORD Actual Dma Buffer Size 0x00004000
REG_DWORD Configuration Error 0xffffffff
REG_DWORD Dma Buffer Size 0x00004000
REG_DWORD DmaChannel 0x00000001
REG_DWORD DmaChannel16 0x00000005
REG_DWORD DSP Version 0x00000405
REG_DWORD Interrupt 0x00000005
REG_DWORD Load Type 0x00000000
REG_BINARY Mixer Settings ??
REG_DWORD MPU401 Port 0xffffffff
REG_DWORD Port 0x00000220
*/
NTSTATUS
ConfigureSoundBlasterDevice(IN PUNICODE_STRING DeviceRegistryPath)
{
OBJECT_ATTRIBUTES RegAttributes;
NTSTATUS Status = STATUS_SUCCESS;
HKEY ConfigKeyHandle;
DPRINT("Configuring Sound Blaster (config at %S)\n", DeviceRegistryPath->Buffer);
if ( ! DeviceRegistryPath )
{
return STATUS_INVALID_PARAMETER;
}
/* Open the registry key */
InitializeObjectAttributes(&RegAttributes,
DeviceRegistryPath,
OBJ_CASE_INSENSITIVE,
NULL,
(PSECURITY_DESCRIPTOR) NULL);
Status = ZwOpenKey(&ConfigKeyHandle, KEY_READ, &RegAttributes);
if ( ! NT_SUCCESS(Status) )
{
DPRINT("Failed to open config registry key\n");
return Status;
}
/* Read configuration */
DPRINT("Reading configuration\n");
//Status = ZwQueryValueKey(ConfigKeyHandle,
return Status;
}
/* IRP DISPATCHERS **********************************************************/
static NTSTATUS NTAPI
CreateSoundBlaster(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT("Sound Blaster driver received IRP_MJ_CREATE\n");
CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
}
static NTSTATUS NTAPI
CloseSoundBlaster(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT("Sound Blaster driver received IRP_MJ_CLOSE\n");
CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
}
static NTSTATUS NTAPI
CleanupSoundBlaster(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT("Sound Blaster driver received IRP_MJ_CLEANUP\n");
CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
}
static NTSTATUS NTAPI
ControlSoundBlaster(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT("Sound Blaster driver received IRP_MJ_CONTROL\n");
CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
}
static NTSTATUS NTAPI
WriteToSoundBlaster(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT("Sound Blaster driver received IRP_MJ_WRITE\n");
CompleteIrpAndReturn(Irp, STATUS_SUCCESS);
}
/* DRIVER ENTRYPOINT ********************************************************/
NTSTATUS NTAPI
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("Sound Blaster driver by silverblade\n");
DriverObject->Flags = 0;
DriverObject->MajorFunction[IRP_MJ_CREATE] = CreateSoundBlaster;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = CloseSoundBlaster;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = CleanupSoundBlaster;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlSoundBlaster;
DriverObject->MajorFunction[IRP_MJ_WRITE] = WriteToSoundBlaster;
DriverObject->DriverUnload = UnloadSoundBlaster;
EnumerateSoundDevices(RegistryPath, L"Parameters", ConfigureSoundBlasterDevice);
return Status;
}
static VOID NTAPI
UnloadSoundBlaster(IN PDRIVER_OBJECT DriverObject)
{
DPRINT("Sound Blaster driver is being unloaded\n");
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
<module name="sndblst_sys" type="kernelmodedriver">
<include base="sndblst_sys">.</include>
<library>ntoskrnl</library>
<library>hal</library>
<file>sndblst.c</file>
<file>sndblst.rc</file>
</module>

View file

@ -0,0 +1,7 @@
/* $Id: sndblst.rc 39744 2009-02-25 09:10:46Z silverblade $ */
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "SoundBlaster Driver\0"
#define REACTOS_STR_INTERNAL_NAME "sndblst\0"
#define REACTOS_STR_ORIGINAL_FILENAME "sndblst.sys\0"
#include <reactos/version.rc>

View file

@ -127,6 +127,8 @@ SyncOverlappedDeviceIoControl(
if ( ! IoResult )
return Win32ErrorToMmResult(GetLastError());
SND_TRACE(L"Transferred %d bytes in Sync overlapped I/O\n", Transferred);
if ( BytesTransferred )
*BytesTransferred = Transferred;