mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 05:15:41 +00:00
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:
parent
36bf174662
commit
60a7be44dc
6 changed files with 405 additions and 3 deletions
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
375
reactos/drivers/multimedia/audio/sndblst_sys/sndblst.c
Normal file
375
reactos/drivers/multimedia/audio/sndblst_sys/sndblst.c
Normal 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");
|
||||
}
|
|
@ -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>
|
7
reactos/drivers/multimedia/audio/sndblst_sys/sndblst.rc
Normal file
7
reactos/drivers/multimedia/audio/sndblst_sys/sndblst.rc
Normal 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>
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue