Author: silverblade
Date: Thu Mar 15 00:31:31 2007
New Revision: 26103
URL:
http://svn.reactos.org/svn/reactos?rev=26103&view=rev
Log:
Yet more files I've been meaning to commit...
(and again they're mostly incomplete)
Added:
trunk/reactos/drivers/multimedia/sb16_ks/
trunk/reactos/drivers/multimedia/sb16_ks/adapter.cpp
trunk/reactos/drivers/multimedia/sb16_ks/main.cpp
trunk/reactos/drivers/multimedia/sb16_ks/sb16.h
trunk/reactos/drivers/multimedia/sb16_ks/sb16.rbuild
trunk/reactos/drivers/multimedia/sb16_ks/sb16_ks.def
trunk/reactos/drivers/multimedia/sb16_ks/stdunk.cpp
trunk/reactos/drivers/multimedia/sb16_nt4/
trunk/reactos/drivers/multimedia/sb16_nt4/control.c
trunk/reactos/drivers/multimedia/sb16_nt4/interrupt.c
trunk/reactos/drivers/multimedia/sb16_nt4/main.c
trunk/reactos/drivers/multimedia/sb16_nt4/sb16_nt4.def
trunk/reactos/drivers/multimedia/sb16_nt4/sb16_nt4.rbuild
trunk/reactos/drivers/multimedia/sb16_nt4/sndblst.h
trunk/reactos/drivers/multimedia/stdunk/
trunk/reactos/drivers/multimedia/stdunk/stdunk.c
trunk/reactos/drivers/multimedia/stdunk/stdunk.cpp
Added: trunk/reactos/drivers/multimedia/sb16_ks/adapter.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_ks…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_ks/adapter.cpp (added)
+++ trunk/reactos/drivers/multimedia/sb16_ks/adapter.cpp Thu Mar 15 00:31:31 2007
@@ -1,0 +1,137 @@
+#include "sb16.h"
+
+class CAdapterSB16 :
+ public IAdapterSB16,
+ public IAdapterPowerManagement,
+ public CUnknown
+{
+ public :
+ DECLARE_STD_UNKNOWN();
+ DEFINE_STD_CONSTRUCTOR(CAdapterSB16);
+ ~CAdapterSB16();
+
+ STDMETHODIMP_(NTSTATUS) Init(
+ IN PRESOURCELIST ResourceList,
+ IN PDEVICE_OBJECT DeviceObject);
+
+ STDMETHODIMP_(PINTERRUPTSYNC) GetInterruptSync(void);
+
+ STDMETHODIMP_(void) SetWaveMiniport(
+ IN PWAVEMINIPORTSB16 Miniport);
+
+ STDMETHODIMP_(BYTE) Read(void);
+
+ STDMETHODIMP_(BOOLEAN) Write(
+ IN BYTE Value);
+
+ STDMETHODIMP_(NTSTATUS) Reset(void);
+
+ STDMETHODIMP_(void) SetMixerValue(
+ IN BYTE Index,
+ IN BYTE Value);
+
+ STDMETHODIMP_(BYTE) GetMixerValue(
+ IN BYTE Index);
+
+ STDMETHODIMP_(void) ResetMixer(void);
+
+ //IMP_IAdapterPowerManagement;
+};
+
+
+NTSTATUS
+NewAdapter(
+ OUT PUNKNOWN* Unknown,
+ IN REFCLSID,
+ IN PUNKNOWN UnknownOuter OPTIONAL,
+ IN POOL_TYPE PoolType)
+{
+ STD_CREATE_BODY_( CAdapterSB16, Unknown, UnknownOuter, PoolType, PADAPTERSB16 );
+}
+
+
+NTSTATUS CAdapterSB16::Init(
+ IN PRESOURCELIST ResourceList,
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ return STATUS_UNSUCCESSFUL;
+}
+
+CAdapterSB16::~CAdapterSB16()
+{
+}
+/*
+STDMETHODIMP
+CAdapterSB16::NonDelegatingQueryInterface(
+ REFIID Interface,
+ PVOID* Object)
+{
+ return STATUS_UNSUCCESSFUL;
+}
+*/
+STDMETHODIMP_(PINTERRUPTSYNC)
+CAdapterSB16::GetInterruptSync()
+{
+ return NULL;
+}
+
+STDMETHODIMP_(BYTE)
+CAdapterSB16::Read()
+{
+ return 0x00;
+}
+
+STDMETHODIMP_(BOOLEAN)
+CAdapterSB16::Write(
+ IN BYTE Value)
+{
+ return FALSE;
+}
+
+STDMETHODIMP_(NTSTATUS)
+CAdapterSB16::Reset()
+{
+ return STATUS_UNSUCCESSFUL;
+}
+
+STDMETHODIMP_(void)
+CAdapterSB16::SetMixerValue(
+ IN BYTE Index,
+ IN BYTE Value)
+{
+}
+
+STDMETHODIMP_(BYTE)
+CAdapterSB16::GetMixerValue(
+ IN BYTE Index)
+{
+ return 0x00;
+}
+
+STDMETHODIMP_(void)
+CAdapterSB16::ResetMixer()
+{
+}
+
+
+/*
+STDMETHODIMP_(void)
+CAdapterSB16::PowerChangeState(
+ IN POWER_STATE NewState)
+{
+}
+
+STDMETHODIMP_(NTSTATUS)
+CAdapterSB16::QueryPowerChangeState(
+ IN POWER_STATE NewStateQuery)
+{
+ return STATUS_UNSUCCESSFUL;
+}
+
+STDMETHODIMP_(NTSTATUS)
+CAdapterSB16::QueryDeviceCapabilities(
+ IN PDEVICE_CAPABILITIES)
+{
+ return STATUS_UNSUCCESSFUL;
+}
+*/
Added: trunk/reactos/drivers/multimedia/sb16_ks/main.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_ks…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_ks/main.cpp (added)
+++ trunk/reactos/drivers/multimedia/sb16_ks/main.cpp Thu Mar 15 00:31:31 2007
@@ -1,0 +1,356 @@
+/*
+ ReactOS Operating System
+ Sound Blaster KS Driver
+
+ AUTHORS:
+ Andrew Greenwood
+
+ NOTES:
+ WaveTable is not supported.
+*/
+
+#include <sb16.h>
+
+/* How many miniports do we support? */
+#define MAX_MINIPORTS 1
+
+
+typedef struct
+{
+ PRESOURCELIST Wave;
+ PRESOURCELIST WaveTable;
+ PRESOURCELIST FmSynth;
+ PRESOURCELIST Uart;
+ PRESOURCELIST Adapter;
+} Resources;
+
+
+DWORD
+DetectPlatform(
+ PPORTTOPOLOGY Port)
+{
+ /* ASSERT(Port); */
+
+ PPORTCLSVERSION portcls_version;
+ PDRMPORT drm_port;
+ PPORTEVENTS port_events;
+ DWORD version;
+
+/*
+ TODO: This stuff needs IID impls
+
+ Port->QueryInterface( IID_IPortClsVersion, (PVOID*) &portcls_version);
+ Port->QueryInterface( IID_IDrmPort, (PVOID*) &drm_port);
+ Port->QueryInterface( IID_IPortEvents, (PVOID*) &port_events);
+*/
+
+ if ( portcls_version )
+ {
+ version = portcls_version->GetVersion();
+ portcls_version->Release();
+ }
+
+ /* If we don't support portcls' GetVersion, we can try other methods */
+ else if ( drm_port )
+ {
+ version = kVersionWinME;
+ // ASSERT(IoIsWdmVersionAvailable(0x01, 0x05));
+ }
+
+ /* If portcls GetVersion and DRMPort not supported, it'll be Win98 */
+ else if ( port_events )
+ {
+ version = kVersionWin98SE;
+ }
+
+ /* IPortEvents was added in Win 98 SE so if not supported, it's not 98 SE */
+ else
+ {
+ version = kVersionWin98;
+ }
+
+ return version;
+}
+
+
+NTSTATUS
+DetectFeatures(
+ IN PRESOURCELIST ResourceList,
+ OUT PBOOLEAN HasUart,
+ OUT PBOOLEAN HasFmSynth,
+ OUT PBOOLEAN HasWaveTable)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ BOOLEAN DetectedWaveTable = FALSE;
+ BOOLEAN DetectedUart = FALSE;
+ BOOLEAN DetectedFmSynth = FALSE;
+
+ ULONG IoCount = ResourceList->NumberOfPorts();
+ ULONG IrqCount = ResourceList->NumberOfInterrupts();
+ ULONG DmaCount = ResourceList->NumberOfDmas();
+
+ switch ( IoCount )
+ {
+ case 1 : /* No FM / UART */
+ {
+ if ( ( ResourceList->FindTranslatedPort(0)->u.Port.Length < 16 ) ||
+ ( IrqCount < 1 ) ||
+ ( DmaCount < 1 ) )
+ {
+ status = STATUS_DEVICE_CONFIGURATION_ERROR;
+ }
+
+ break;
+
+ case 2 :
+ {
+ if ( ( ResourceList->FindTranslatedPort(0)->u.Port.Length < 16 ) ||
+ ( IrqCount < 1 ) ||
+ ( DmaCount < 1 ) )
+ {
+ status = STATUS_DEVICE_CONFIGURATION_ERROR;
+ }
+
+ else
+ {
+ /* The length of the port indicates the function provided */
+
+ switch ( ResourceList->FindTranslatedPort(1)->u.Port.Length )
+ {
+ case 2 :
+ {
+ DetectedUart = TRUE;
+ break;
+ }
+ case 4:
+ {
+ DetectedFmSynth = TRUE;
+ break;
+ }
+ default :
+ {
+ status = STATUS_DEVICE_CONFIGURATION_ERROR;
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 3 :
+ {
+ if ( ( ResourceList->FindTranslatedPort(0)->u.Port.Length < 16 ) ||
+ ( ResourceList->FindTranslatedPort(1)->u.Port.Length != 2 ) ||
+ ( ResourceList->FindTranslatedPort(2)->u.Port.Length != 4 ) ||
+ ( IrqCount < 1 ) ||
+ ( DmaCount < 1 ) )
+ {
+ status = STATUS_DEVICE_CONFIGURATION_ERROR;
+ }
+ else
+ {
+ DetectedUart = TRUE;
+ DetectedFmSynth = TRUE;
+ }
+
+ break;
+ }
+
+ default :
+ {
+ status = STATUS_DEVICE_CONFIGURATION_ERROR;
+ break;
+ }
+ }
+
+ if ( HasUart )
+ *HasUart = DetectedUart;
+ if ( HasFmSynth )
+ *HasFmSynth = DetectedFmSynth;
+ if ( HasWaveTable )
+ *HasWaveTable = DetectedWaveTable;
+
+ return status;
+}
+
+
+NTSTATUS
+AssignResources(
+ IN PRESOURCELIST ResourceList,
+ OUT Resources* Resources)
+{
+ NTSTATUS status;
+ BOOLEAN HasUart, HasFmSynth, HasWaveTable;
+
+ Resources->Adapter = NULL;
+ Resources->Wave = NULL;
+ Resources->Uart = NULL;
+ Resources->FmSynth = NULL;
+ Resources->WaveTable = NULL;
+
+ status = DetectFeatures(ResourceList, &HasUart, &HasFmSynth,
&HasWaveTable);
+
+ if ( ! NT_SUCCESS(status) )
+ {
+ return status;
+ }
+
+ /* Wave I/O resources */
+
+ status = PcNewResourceSublist(Resources->Wave,
+ NULL,
+ PagedPool,
+ ResourceList,
+ ResourceList->NumberOfDmas() +
+ ResourceList->NumberOfInterrupts + 1);
+
+ if ( NT_SUCCESS(status) )
+ {
+ ULONG i;
+
+ /* Base port address */
+ status = (*Resources->Wave)->AddPortFromParent(ResourceList, 0);
+
+ /* DMA channels */
+ if ( NT_SUCCESS(status) )
+ {
+ for ( i = 0; i < ResourceList->NumberOfDmas(); i ++ )
+ {
+ status = (*Resources->Wave)->AddDmaFromParent(ResourceList, i);
+
+ if ( ! NT_SUCCESS(status) )
+ break;
+ }
+ }
+
+ /* IRQs */
+ if ( NT_SUCCESS(status) )
+ {
+ for ( i = 0; i < ResourceList->NumberOfInterrupts(); i ++ )
+ {
+ status = (*Resources->Wave)->AddInterruptFromParent(ResourceList,
i);
+
+ if ( ! NT_SUCCESS(status) )
+ break;
+ }
+ }
+ }
+
+ /* UART resources */
+
+ if ( NT_SUCCESS(status) && HasUart )
+ {
+ /* TODO */
+ }
+
+ /* FM Synth resources */
+
+ if ( NT_SUCCESS(status) && HasFmSynth )
+ {
+ /* TODO */
+ }
+
+ /* Adapter resources */
+
+ if ( NT_SUCCESS(status) )
+ {
+ status = PcNewResourceSublist(Resources->Adapter,
+ NULL,
+ PagedPool,
+ ResourceList,
+ 3);
+
+ if ( NT_SUCCESS(status) )
+ {
+ status = (*Resources->Adapter)->AddInterruptFromParent(ResourceList,
0);
+ }
+
+ if ( NT_SUCCESS(status) )
+ {
+ status = (*Resources->Adapter)->AddPortFromParent(ResourceList, 0);
+ }
+
+ if ( NT_SUCCESS(status) && HasUart )
+ {
+ /* TODO */
+ }
+ }
+
+ /* Cleanup - TODO: Make this cleanup UART, FM etc. */
+
+ if ( ! NT_SUCCESS(status) )
+ {
+ if ( *Resources->Wave )
+ {
+ (*Resources->Wave)->Release();
+ *Resources->Wave = NULL;
+ }
+
+ if ( *Resources->Adapter )
+ {
+ (*Resources->Adapter)->Release();
+ *Resources->Adapter = NULL;
+ }
+ }
+
+ return status;
+}
+
+
+NTSTATUS
+StartDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PRESOURCELIST ResourceList)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ Resources DeviceResources;
+
+ PUNKNOWN UnknownTopology = NULL;
+ PUNKNOWN UnknownWave = NULL;
+ PUNKNOWN UnknownWaveTable = NUL;
+ PUNKNOWN UnknownFmSynth = NULL;
+
+ PADAPTERCOMMON AdapterCommon = NULL;
+ PUNKNOWN UnknownCommon = NULL;
+
+ status = AssignResources(ResourceList, &DeviceResources);
+
+ if ( NT_SUCCESS(status) )
+ {
+ }
+
+ return status;
+}
+
+extern "C"
+NSTATUS
+AddDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+ return PcAddAdapterDevice(DriverObject,
+ PhysicalDeviceObject,
+ StartDevice,
+ MAX_MINIPORTS,
+ 0);
+}
+
+extern "C"
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPathName)
+{
+ NTSTATUS status;
+
+ status = PcInitializeAdapterDriver(DriverObject,
+ RegistryPathName,
+ AddDevice);
+
+ /* TODO: Add our own IRP handlers here */
+
+ return status;
+}
Added: trunk/reactos/drivers/multimedia/sb16_ks/sb16.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_ks…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_ks/sb16.h (added)
+++ trunk/reactos/drivers/multimedia/sb16_ks/sb16.h Thu Mar 15 00:31:31 2007
@@ -1,0 +1,141 @@
+/*
+ ReactOS Operating System
+ Sound Blaster KS Driver
+
+ AUTHORS:
+ Andrew Greenwood
+
+ NOTES:
+ Ah, the Sound Blaster 16. I remember it well...
+*/
+
+#include <portcls.h>
+#include <stdunk.h>
+
+#ifndef SB16_H
+#define SB16_H
+
+#define MAX_DMA_BUFFER_SIZE 65536
+
+enum DspRegister
+{
+ DspRegCMSD0 = 0x00,
+ DspRegCMSR0 = 0x01,
+ DspRegCMSD1 = 0x02,
+ DspRegCMSR1 = 0x03,
+ DspRegMixerReg = 0x04,
+ DspRegMixerData = 0x05,
+ DspRegReset = 0x06,
+ DspRegFMD0 = 0x08,
+ DspRegFMR0 = 0x09,
+ DspRegRead = 0x0a,
+ DspRegWrite = 0x0c,
+ DspRegDataAvailable = 0x0e,
+
+ DspRegAck8 = 0x0e,
+ DspRegAck16 = 0x0f
+};
+
+enum DspCommand
+{
+ DspWriteWaveProgrammedIo = 0x10,
+ DspWriteWave = 0x14,
+ DspWriteWaveAuto = 0x1c,
+ DspReadWave = 0x24,
+ DspReadWaveAuto = 0x2C,
+ DspWriteHighSpeedWave = 0x90,
+ DspReadHighSpeedWave = 0x98,
+ DspSetSampleRate = 0x40,
+ DspSetBlockSize = 0x48,
+ DspEnableOutput = 0xd1,
+ DspDisableOutput = 0xd3,
+ DspOutputStatus = 0xd8,
+ DspPauseDma = 0xd0,
+ DspContinueDma = 0xd4,
+ DspHaltAutoDma = 0xda,
+ DspInverter = 0xe0,
+ DspGetVersion = 0xe1,
+ DspGenerateInterrupt = 0xf2,
+
+ /* SB16 only */
+ DspSetDacRate = 0x41,
+ DspSetAdcRate = 0x42,
+ DspStartDac16 = 0xb6,
+ DspStartAdc16 = 0xbe,
+ DspStartDac8 = 0xc6,
+ DspStartAdc8 = 0xc3,
+ DspPauseDma16 = 0xd5,
+ DspContinueDma16 = 0xd6,
+ DspHaltAutoDma16 = 0xd9
+};
+
+enum DspMixerRegister
+{
+ DspMixMasterVolumeLeft = 0x00,
+ DspMixMasterVolumeRight = 0x01,
+ DspMixVoiceVolumeLeft = 0x02,
+ DspMixVoiceVolumeRight = 0x03,
+ /* ... */
+ DspMixIrqConfig = 0x80,
+ DspMixDmaConfig = 0x81
+};
+
+
+#define MPU401_OUTPUT_READY 0x40
+#define MPU401_INPUT_READY 0x80
+
+#define MPU401_RESET 0xff
+#define MPU401_UART_MODE 0x3f
+
+DEFINE_GUID(IID_IWaveMiniportSB16,
+ 0xbe23b2d7, 0xa760, 0x43ab, 0xb7, 0x6e, 0xbc, 0x3e, 0x93, 0xe6, 0xff, 0x54);
+
+DECLARE_INTERFACE_(IWaveMiniportSB16, IUnknown)
+{
+ DEFINE_ABSTRACT_UNKNOWN()
+
+ STDMETHOD_(void, RestoreSampleRate)( THIS ) PURE;
+ STDMETHOD_(void, ServiceWaveISR)( THIS ) PURE;
+};
+
+typedef IWaveMiniportSB16 *PWAVEMINIPORTSB16;
+
+
+DEFINE_GUID(IID_IAdapterSB16,
+ 0xfba9052c, 0x0544, 0x4bc4, 0x97, 0x3f, 0x70, 0xb7, 0x06, 0x46, 0x81, 0xe5);
+
+DECLARE_INTERFACE_(IAdapterSB16, IUnknown)
+{
+ DEFINE_ABSTRACT_UNKNOWN()
+
+ STDMETHOD_(NTSTATUS, Init)( THIS_
+ IN PRESOURCELIST ResourceList,
+ IN PDEVICE_OBJECT DeviceObject) PURE;
+
+ STDMETHOD_(PINTERRUPTSYNC, GetInterruptSync)( THIS ) PURE;
+
+ STDMETHOD_(void, SetWaveMiniport)( THIS_
+ IN PWAVEMINIPORTSB16 Miniport) PURE;
+
+ STDMETHOD_(BYTE, Read)( THIS ) PURE;
+
+ STDMETHOD_(BOOLEAN, Write)( THIS_
+ IN BYTE Value) PURE;
+
+ STDMETHOD_(NTSTATUS, Reset)( THIS ) PURE;
+
+ STDMETHOD_(void, SetMixerValue)( THIS_
+ IN BYTE Index,
+ IN BYTE Value) PURE;
+
+ STDMETHOD_(BYTE, GetMixerValue)( THIS_
+ IN BYTE Index) PURE;
+
+ STDMETHOD_(void, ResetMixer)( THIS ) PURE;
+
+ /* TODO - Save/load settings */
+};
+
+typedef IAdapterSB16 *PADAPTERSB16;
+
+#endif
Added: trunk/reactos/drivers/multimedia/sb16_ks/sb16.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_ks…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_ks/sb16.rbuild (added)
+++ trunk/reactos/drivers/multimedia/sb16_ks/sb16.rbuild Thu Mar 15 00:31:31 2007
@@ -1,0 +1,11 @@
+<module name="sb16_ks" type="exportdriver"
installbase="system32/drivers" installname="sb16_ks.sys"
allowwarnings="true">
+ <include base="sb16_ks">.</include>
+ <include base="sb16_ks">..</include>
+ <importlibrary definition="sb16_ks.def" />
+ <library>ntoskrnl</library>
+ <library>portcls</library>
+ <define name="__USE_W32API" />
+ <file>stdunk.cpp</file>
+ <file>adapter.cpp</file>
+ <file>main.cpp</file>
+</module>
Added: trunk/reactos/drivers/multimedia/sb16_ks/sb16_ks.def
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_ks…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_ks/sb16_ks.def (added)
+++ trunk/reactos/drivers/multimedia/sb16_ks/sb16_ks.def Thu Mar 15 00:31:31 2007
@@ -1,0 +1,6 @@
+;
+; Exports definition file for sb16_ks.sys
+;
+EXPORTS
+DriverEntry@8
+
Added: trunk/reactos/drivers/multimedia/sb16_ks/stdunk.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_ks…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_ks/stdunk.cpp (added)
+++ trunk/reactos/drivers/multimedia/sb16_ks/stdunk.cpp Thu Mar 15 00:31:31 2007
@@ -1,0 +1,68 @@
+/*
+ ReactOS Kernel-Mode COM
+ IUnknown implementations
+
+ LICENSE
+ Please see COPYING in the top-level directory for license information.
+
+ AUTHORS
+ Andrew Greenwood
+*/
+
+#include <stdunk.h>
+
+CUnknown::CUnknown(PUNKNOWN outer_unknown)
+{
+ m_ref_count = 0;
+
+ if ( outer_unknown )
+ m_outer_unknown = outer_unknown;
+ else
+ m_outer_unknown = PUNKNOWN(dynamic_cast<PNONDELEGATINGUNKNOWN>(this));
+}
+
+CUnknown::~CUnknown()
+{
+}
+
+STDMETHODIMP_(ULONG)
+CUnknown::NonDelegatingAddRef()
+{
+ InterlockedIncrement(&m_ref_count);
+ return m_ref_count;
+}
+
+STDMETHODIMP_(ULONG)
+CUnknown::NonDelegatingRelease()
+{
+ if ( InterlockedDecrement(&m_ref_count) == 0 )
+ {
+ m_ref_count ++;
+ delete this;
+ return 0;
+ }
+
+ return m_ref_count;
+}
+
+STDMETHODIMP_(NTSTATUS)
+CUnknown::NonDelegatingQueryInterface(
+ IN REFIID iid,
+ PVOID* ppVoid)
+{
+ /* FIXME */
+ #if 0
+ if ( IsEqualGUID(iid, IID_IUnknown) ) /* TODO: Aligned? */
+ *ppVoid = PVOID(PUNKNOWN(this));
+ else
+ *ppVoid = NULL;
+ #endif
+
+ if ( *ppVoid )
+ {
+ PUNKNOWN(*ppVoid)->AddRef();
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_INVALID_PARAMETER;
+}
Added: trunk/reactos/drivers/multimedia/sb16_nt4/control.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_nt…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_nt4/control.c (added)
+++ trunk/reactos/drivers/multimedia/sb16_nt4/control.c Thu Mar 15 00:31:31 2007
@@ -1,0 +1,222 @@
+#include <sndblst.h>
+
+/*
+ TODO: MmMapIoSpace()
+*/
+
+/*
+ This checks the read or write status port of the device.
+*/
+
+BOOLEAN
+WaitForReady(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ UCHAR Port)
+{
+ ULONG timeout = SB_TIMEOUT;
+ BOOL ready = FALSE;
+
+ while ( ( ! ready ) && ( timeout > 0 ) )
+ {
+ if ( SbRead(SBDevice, Port) & 0x80 )
+ return TRUE;
+
+ timeout --;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+SbWriteData(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ UCHAR Data)
+{
+ if ( ! WaitToWrite(SBDevice) )
+ return FALSE;
+
+ DPRINT("Writing 0x%x to Sound Blaster card (data)\n", Data);
+ SbWrite(SBDevice, SB_WRITE_DATA_PORT, Data);
+
+ return TRUE;
+}
+
+BOOLEAN
+SbReadData(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ PUCHAR Data)
+{
+ if ( ! WaitToWrite(SBDevice) )
+ return FALSE;
+
+ *Data = SbRead(SBDevice, SB_READ_DATA_PORT);
+ DPRINT("Read 0x%x from Sound Blaster card (data)\n", *Data);
+
+ return TRUE;
+}
+
+BOOLEAN
+ResetSoundBlaster(
+ PSOUND_BLASTER_PARAMETERS SBDevice)
+{
+ BOOLEAN acked = FALSE;
+ ULONG timeout;
+
+ SbWriteReset(SBDevice, 0x01);
+ for (timeout = 0; timeout < 30000; timeout ++ );
+ SbWriteReset(SBDevice, 0x00);
+
+ DPRINT("Waiting for SB to acknowledge our reset request\n");
+
+ if ( ! WaitToRead(SBDevice) )
+ {
+ DPRINT("Didn't get an ACK :(\n");
+ return FALSE;
+ }
+
+ timeout = 0;
+
+ while ( ( ! acked ) && ( timeout < SB_TIMEOUT ) )
+ {
+ acked = ( SbReadDataWithoutWait(SBDevice) == SB_DSP_READY );
+ timeout ++;
+ }
+
+ if ( ! acked )
+ {
+ DPRINT("Didn't get an ACK :(\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+ULONG
+GetSoundBlasterModel(
+ PSOUND_BLASTER_PARAMETERS SBDevice)
+{
+ UCHAR MajorVer, MinorVer;
+
+ DPRINT("Querying DSP version\n");
+
+ if ( ! SbWriteData(SBDevice, SbGetDspVersion) )
+ return NotDetected;
+
+ if ( ! WaitToRead(SBDevice) )
+ return NotDetected;
+
+ if ( SbReadData(SBDevice, &MajorVer) )
+ {
+ if ( SbReadData(SBDevice, &MinorVer) )
+ {
+ DPRINT("Version %d.%d\n", MajorVer, MinorVer);
+
+ SBDevice->dsp_version = (MajorVer * 256) + MinorVer;
+
+ if ( SBDevice->dsp_version < 0x0200 )
+ return SoundBlaster;
+ else if ( ( SBDevice->dsp_version & 0xFF00 ) == 0x0200 )
+ return SoundBlaster2;
+ else if ( ( SBDevice->dsp_version & 0xFF00 ) == 0x0300 )
+ return SoundBlasterPro;
+ else if ( SBDevice->dsp_version >= 0x0400 )
+ return SoundBlaster16;
+
+ return NotDetected;
+ }
+ }
+
+ return NotDetected;
+}
+
+
+BOOLEAN
+IsSampleRateCompatible(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ ULONG SampleRate)
+{
+ /* TODO */
+ return TRUE;
+}
+
+BOOLEAN
+SetOutputSampleRate(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ ULONG SampleRate)
+{
+ /* Only works for DSP v4.xx */
+ DPRINT("Setting sample rate\n");
+
+ SbWriteData(SBDevice, SbSetOutputRate);
+ SbWriteData(SBDevice, SampleRate / 256);
+ SbWriteData(SBDevice, SampleRate % 256);
+
+ return TRUE;
+}
+
+BOOLEAN
+EnableSpeaker(
+ PSOUND_BLASTER_PARAMETERS SBDevice)
+{
+ DPRINT("Enabling speaker\n");
+
+ return SbWriteData(SBDevice, SbEnableSpeaker);
+}
+
+BOOLEAN
+DisableSpeaker(
+ PSOUND_BLASTER_PARAMETERS SBDevice)
+{
+ DPRINT("Disabling speaker\n");
+
+ return SbWriteData(SBDevice, SbDisableSpeaker);
+}
+
+BOOLEAN
+StartSoundOutput(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ ULONG BitDepth,
+ ULONG Channels,
+ ULONG BlockSize)
+{
+ DPRINT("Initializing output with %d channels at %d bits/sample\n",
Channels, BitDepth);
+
+ UCHAR command = 0xc6, mode = 0x00;
+
+ if ( ( Channels < 1 ) || ( Channels > 2 ) )
+ return FALSE;
+
+ if ( ( BitDepth != 8 ) && ( BitDepth != 16 ) )
+ return FALSE;
+
+ switch ( BitDepth )
+ {
+ case 8 : command = 0xc6; break;
+ case 16 : command = 0xb6; break;
+ };
+
+ switch ( Channels )
+ {
+ case 1 : mode = 0x00; break;
+ case 2 : mode = 0x20; break;
+ }
+#if 0
+ first_byte = (BitDepth == 16) ? 0xb6 : 0xc6;
+ second_byte = (Channels == 1) ? 0x20 : 0x00;
+#endif
+
+ if ( SBDevice->dsp_version < 0x0400 )
+ {
+ /* TODO: Additional programming required */
+ }
+
+ /* Send freq */
+ SbWriteData(SBDevice, command);
+ SbWriteData(SBDevice, mode);
+ SbWriteData(SBDevice, BlockSize % 256);
+ SbWriteData(SBDevice, BlockSize / 256);
+
+ DPRINT("Finished programming the DSP\n");
+
+ return TRUE;
+}
Added: trunk/reactos/drivers/multimedia/sb16_nt4/interrupt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_nt…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_nt4/interrupt.c (added)
+++ trunk/reactos/drivers/multimedia/sb16_nt4/interrupt.c Thu Mar 15 00:31:31 2007
@@ -1,0 +1,61 @@
+/*
+*/
+
+#include <sndblst.h>
+
+BOOLEAN
+CheckIrq(
+ PDEVICE_OBJECT DeviceObject)
+{
+/* PSOUND_BLASTER_PARAMETERS parameters = DeviceObject->DriverExtension;*/
+
+ /* TODO */
+
+ return TRUE;
+}
+
+BOOLEAN
+ServiceSoundBlasterInterrupt(
+ IN PKINTERRUPT Interrupt,
+ IN PVOID Context)
+{
+ DPRINT("* Processing ISR *\n");
+ return FALSE;
+}
+
+NTSTATUS
+EnableIrq(
+ PDEVICE_OBJECT DeviceObject)
+{
+ PSOUND_BLASTER_PARAMETERS parameters = DeviceObject->DeviceExtension;
+ ULONG vector;
+ KIRQL irq_level;
+ KAFFINITY affinity;
+ NTSTATUS status = STATUS_SUCCESS;
+
+ vector = HalGetInterruptVector(Isa,
+ 0,
+ parameters->irq,
+ parameters->irq,
+ &irq_level,
+ &affinity);
+
+ DPRINT("Vector is 0x%x\n", vector);
+
+ status = IoConnectInterrupt(parameters->interrupt,
+ ServiceSoundBlasterInterrupt,
+ DeviceObject,
+ (PKSPIN_LOCK) NULL,
+ vector,
+ irq_level,
+ irq_level,
+ Latched, /* Latched / LevelSensitive */
+ FALSE, /* shareable */
+ affinity,
+ FALSE);
+
+ if ( status == STATUS_INVALID_PARAMETER )
+ status = STATUS_DEVICE_CONFIGURATION_ERROR;
+
+ return status;
+}
Added: trunk/reactos/drivers/multimedia/sb16_nt4/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_nt…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_nt4/main.c (added)
+++ trunk/reactos/drivers/multimedia/sb16_nt4/main.c Thu Mar 15 00:31:31 2007
@@ -1,0 +1,489 @@
+/*
+ ReactOS
+ Sound Blaster driver
+
+ Programmers:
+ Andrew Greenwood
+
+ Notes:
+ Compatible with NT4
+*/
+
+#include <sndblst.h>
+
+
+/*
+ IRP DISPATCH ROUTINES
+*/
+
+NTSTATUS STDCALL
+CreateSoundBlaster(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
+
+ DPRINT("CreateSoundBlaster() called - extension 0x%x\n", sb_device);
+
+ EnableSpeaker(sb_device);
+ /*SetOutputSampleRate(sb_device, 22*/
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+CloseSoundBlaster(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
+
+ DPRINT("CloseSoundBlaster() called\n");
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+CleanupSoundBlaster(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
+
+ DPRINT("CleanupSoundBlaster() called\n");
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+ControlSoundBlaster(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PIO_STACK_LOCATION stack;
+ PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
+
+ DPRINT("ControlSoundBlaster() called\n");
+
+ stack = IoGetCurrentIrpStackLocation(Irp);
+
+ switch ( stack->Parameters.DeviceIoControl.IoControlCode)
+ {
+ /* TODO */
+ };
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+WriteSoundBlaster(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PSOUND_BLASTER_PARAMETERS sb_device = DeviceObject->DeviceExtension;
+
+ DPRINT("WriteSoundBlaster() called\n");
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+VOID STDCALL
+UnloadSoundBlaster(
+ PDRIVER_OBJECT DriverObject)
+{
+ DPRINT("Sound Blaster driver unload\n");
+}
+
+NTSTATUS STDCALL
+OpenSubkey(
+ PUNICODE_STRING RegistryPath,
+ PWSTR Subkey,
+ ACCESS_MASK DesiredAccess,
+ OUT HANDLE* DevicesKeyHandle)
+{
+ NTSTATUS status;
+ OBJECT_ATTRIBUTES attribs;
+ UNICODE_STRING subkey_name;
+ HANDLE key_handle;
+
+ /* TODO: Check for NULL ptr in DevicesKeyHandle */
+
+ InitializeObjectAttributes(&attribs,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ (PSECURITY_DESCRIPTOR) NULL);
+
+ status = ZwOpenKey(&key_handle, KEY_READ, &attribs);
+
+ if ( ! NT_SUCCESS(status) )
+ {
+ DPRINT("Couldn't open subkey %wZ\n", Subkey);
+ return status;
+ }
+
+ RtlInitUnicodeString(&subkey_name, Subkey);
+
+ InitializeObjectAttributes(&attribs,
+ &subkey_name,
+ OBJ_CASE_INSENSITIVE,
+ key_handle,
+ (PSECURITY_DESCRIPTOR) NULL);
+
+ status = ZwOpenKey(*DevicesKeyHandle, DesiredAccess, &attribs);
+ ZwClose(key_handle);
+
+ return status;
+}
+
+
+PWSTR STDCALL
+AllocateRegistryPathInfo(
+ PUNICODE_STRING BasePath,
+ PUNICODE_STRING ParametersPath,
+ PKEY_BASIC_INFORMATION KeyInfo)
+{
+ PWSTR name;
+ PWSTR pos;
+
+ DPRINT("Allocating memory for path info\n");
+ name = ExAllocatePool(PagedPool,
+ BasePath->Length + sizeof(WCHAR) +
+ ParametersPath->Length + sizeof(WCHAR) +
+ KeyInfo->NameLength + sizeof(UNICODE_NULL));
+
+ if ( ! name )
+ return NULL;
+
+ DPRINT("Copying info\n");
+ pos = name;
+
+ RtlCopyMemory((PVOID)Pos, (PVOID)BasePath->Buffer, BasePath->Length);
+ pos += BasePath->Length / sizeof(WCHAR);
+ pos[0] = '\\';
+ pos ++;
+
+ RtlCopyMemory((PVOID)Pos, (PVOID)ParametersPath->Buffer,
ParametersPath->Length);
+ pos += ParametersPath->Length / sizeof(WCHAR);
+ pos[0] = '\\';
+ pos ++;
+
+ RtlCopyMemory((PVOID)Pos, (PVOID)ParametersPath->Buffer,
ParametersPath->Length);
+ pos += KeyInfo->NameLength / sizeof(WCHAR);
+ pos[0] = UNICODE_NULL;
+
+ DPRINT("All OK\n");
+ return name;
+}
+
+#define FreeRegistryPathInfo(ptr) \
+ ExFreePool(ptr)
+
+
+#define TAG_REG_INFO (ULONG)'IgeR'
+#define TAG_REG_NAME (ULONG)'NgeR'
+
+NTSTATUS STDCALL
+EnumerateSubkey(
+ PUNICODE_STRING RegistryPath,
+ PWSTR Subkey,
+ PREGISTRY_CALLBACK_ROUTINE Callback,
+ PDRIVER_OBJECT DriverObject)
+{
+ NTSTATUS status;
+ UNICODE_STRING subkey_name;
+ HANDLE devices_key_handle;
+
+ ULONG key_index = 0;
+ ULONG result_length;
+
+ status = OpenSubkey(RegistryPath, Subkey, KEY_ENUMERATE_SUB_KEYS,
&devices_key_handle);
+
+ if ( ! NT_SUCCESS(status) )
+ return status;
+
+ while ( TRUE )
+ {
+ KEY_BASIC_INFORMATION test_info;
+ PKEY_BASIC_INFORMATION info;
+ ULONG size;
+ PWSTR name;
+
+ status = ZwEnumerateKey(devices_key_handle,
+ key_index,
+ KeyBasicInformation,
+ &test_info,
+ sizeof(test_info),
+ &result_length);
+
+ if ( status == STATUS_NO_MORE_ENTRIES )
+ break;
+
+ size = result_length + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
+
+ info = (PKEY_BASIC_INFORMATION) ExAllocatePoolWithTag(PagedPool, size,
TAG_REG_INFO);
+
+ if ( ! info )
+ {
+ DPRINT("Out of memory\n");
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ status = ZwEnumerateKey(devices_key_handle,
+ key_index,
+ KeyBasicInformation,
+ info,
+ size,
+ &result_length);
+
+ if ( ! NT_SUCCESS(status) )
+ {
+ DPRINT("Unable to enumerate keys\n");
+ ExFreePoolWithTag(info, TAG_REG_INFO);
+ status = STATUS_INTERNAL_ERROR;
+ break;
+ }
+
+ /* Is this ok? */
+ RtlInitUnicodeString(&subkey_name, Subkey);
+
+ name = AllocateRegistryPathInfo(RegistryPath, &subkey_name, info);
+
+ if ( ! name )
+ {
+ DPRINT("Out of memory\n");
+ ExFreePoolWithTag(info, TAG_REG_INFO);
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+
+ ExFreePoolWithTag(info, TAG_REG_INFO);
+
+ /* Call the callback */
+ status = Callback(DriverObject, name);
+
+ FreeRegistryPathInfo(name);
+
+ if ( ! NT_SUCCESS(status) )
+ {
+ DPRINT("Callback FAILED\n");
+ break;
+ }
+
+ key_index ++;
+ }
+
+ ZwClose(devices_key_handle);
+
+ DPRINT("Found %d subkey entries\n", key_index);
+
+ if ( ( key_index == 0 ) && ( status == STATUS_NO_MORE_ENTRIES ) )
+ return STATUS_DEVICE_CONFIGURATION_ERROR;
+
+ if ( status == STATUS_NO_MORE_ENTRIES )
+ status = STATUS_SUCCESS;
+
+ return status;
+}
+
+#define EnumerateDeviceKeys(path, callback, driver_obj) \
+ EnumerateSubkey(path, L"Devices", callback, driver_obj)
+
+
+NTSTATUS
+CreateDeviceName(
+ PCWSTR PrePrefix,
+ PCWSTR Prefix,
+ UCHAR Index,
+ PUNICODE_STRING DeviceName)
+{
+ UNICODE_STRING number;
+ WCHAR number_buffer[5];
+ UNICODE_STRING unicode_pre_prefix;
+ UNICODE_STRING unicode_prefix;
+ ULONG size;
+
+ RtlInitUnicodeString(&unicode_pre_prefix, PrePrefix);
+ RtlInitUnicodeString(&unicode_prefix, Prefix);
+
+ size = unicode_pre_prefix.Length +
+ unicode_prefix.Length +
+ sizeof(number_buffer) +
+ sizeof(UNICODE_NULL);
+
+ DeviceName->Buffer = ExAllocatePool(PagedPool, size);
+ DeviceName->MaximumLength = (USHORT) size;
+
+ if ( ! DeviceName->Buffer )
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlCopyUnicodeString(DeviceName, &unicode_pre_prefix);
+ RtlAppendUnicodeStringToString(DeviceName, &unicode_prefix);
+
+ if ( Index != 255 )
+ {
+ number.Buffer = number_buffer;
+ number.MaximumLength = sizeof(number_buffer);
+
+ RtlIntegerToUnicodeString((ULONG) Index, 10, &number);
+ RtlAppendUnicodeStringToString(DeviceName, &number);
+ }
+
+ DeviceName->Buffer[DeviceName->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+InitializeSoundBlaster(
+ PDRIVER_OBJECT DriverObject,
+ PWSTR RegistryPath)
+{
+ NTSTATUS status;
+ PDEVICE_OBJECT device_object;
+ PSOUND_BLASTER_PARAMETERS parameters = NULL;
+ UNICODE_STRING device_name;
+ UNICODE_STRING dos_device_name;
+
+ UCHAR device_index = 0;
+
+ DPRINT("Initializing a Sound Blaster device\n");
+
+ /* Change these later */
+ status = CreateDeviceName(L"",
+ L"\\Device\\WaveOut",
+ device_index,
+ &device_name);
+
+ if ( ! NT_SUCCESS(status) )
+ return status;
+
+ status = CreateDeviceName(L"\\DosDevices\\",
+ L"\\Device\\WaveOut" +
wcslen(L"\\Device\\"),
+ device_index,
+ &dos_device_name);
+
+ if ( ! NT_SUCCESS(status) )
+ {
+ /* TODO */
+ return status;
+ }
+
+ DPRINT("Device: %wZ\n", device_name);
+ DPRINT("Symlink: %wZ\n", dos_device_name);
+
+ /*
+ Create the device and DOS symlink
+ */
+
+ status = IoCreateDevice(DriverObject,
+ sizeof(SOUND_BLASTER_PARAMETERS),
+ &device_name,
+ FILE_DEVICE_SOUND,
+ 0,
+ FALSE,
+ &device_object);
+
+ if ( ! NT_SUCCESS(status) )
+ return status;
+
+ DPRINT("Created a device extension at 0x%x\n",
device_object->DeviceExtension);
+ parameters = device_object->DeviceExtension;
+
+ status = IoCreateSymbolicLink(&dos_device_name, &device_name);
+
+ ExFreePool(dos_device_name.Buffer);
+ ExFreePool(device_name.Buffer);
+
+ if ( ! NT_SUCCESS(status) )
+ {
+ IoDeleteDevice(device_object);
+ device_object = NULL;
+ return status;
+ }
+
+ /* IoRegisterShutdownNotification( */
+
+ /*
+ Settings
+ */
+
+ device_object->AlignmentRequirement = FILE_BYTE_ALIGNMENT;
+
+ parameters->driver = DriverObject;
+ parameters->registry_path = RegistryPath;
+ parameters->port = DEFAULT_PORT;
+ parameters->irq = DEFAULT_IRQ;
+ parameters->dma = DEFAULT_DMA;
+ parameters->buffer_size = DEFAULT_BUFFER_SIZE;
+
+ /* TODO: Load the settings from the registry */
+
+ DPRINT("Port %x IRQ %d DMA %d\n", parameters->port, parameters->irq,
parameters->dma);
+
+ DPRINT("Resetting the sound card\n");
+
+ if ( ! ResetSoundBlaster(parameters) )
+ {
+ /* TODO */
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ DPRINT("What kind of SB card is this?\n");
+ GetSoundBlasterModel(parameters);
+ */
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS STDCALL
+DriverEntry(
+ PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath)
+{
+ NTSTATUS status;
+
+ DPRINT("Sound Blaster driver 0.1 by Silver Blade\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] = WriteSoundBlaster;
+ DriverObject->DriverUnload = UnloadSoundBlaster;
+
+ DPRINT("Beginning device key enumeration\n");
+
+ status = EnumerateDeviceKeys(RegistryPath, *InitializeSoundBlaster, DriverObject);
+
+ return status;
+}
Added: trunk/reactos/drivers/multimedia/sb16_nt4/sb16_nt4.def
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_nt…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_nt4/sb16_nt4.def (added)
+++ trunk/reactos/drivers/multimedia/sb16_nt4/sb16_nt4.def Thu Mar 15 00:31:31 2007
@@ -1,0 +1,6 @@
+;
+; Exports definition file for sb16_ks.sys
+;
+EXPORTS
+DriverEntry@8
+
Added: trunk/reactos/drivers/multimedia/sb16_nt4/sb16_nt4.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_nt…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_nt4/sb16_nt4.rbuild (added)
+++ trunk/reactos/drivers/multimedia/sb16_nt4/sb16_nt4.rbuild Thu Mar 15 00:31:31 2007
@@ -1,0 +1,11 @@
+<module name="sb16_nt4" type="exportdriver"
installbase="system32/drivers" installname="sndblst.sys"
allowwarnings="true">
+ <include base="sb16_nt4">.</include>
+ <include base="sb16_nt4">..</include>
+ <importlibrary definition="sb16_nt4.def" />
+ <library>ntoskrnl</library>
+ <library>hal</library>
+ <define name="__USE_W32API" />
+ <file>main.c</file>
+ <file>control.c</file>
+ <file>interrupt.c</file>
+</module>
Added: trunk/reactos/drivers/multimedia/sb16_nt4/sndblst.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/sb16_nt…
==============================================================================
--- trunk/reactos/drivers/multimedia/sb16_nt4/sndblst.h (added)
+++ trunk/reactos/drivers/multimedia/sb16_nt4/sndblst.h Thu Mar 15 00:31:31 2007
@@ -1,0 +1,155 @@
+#ifndef SNDBLST_H
+#define SNDBLST_H
+
+#include <debug.h>
+#include <ntddk.h>
+
+#define SB_WAVE_IN_DEVICE_NAME L"\\Device\\SBWaveIn"
+#define SB_WAVE_OUT_DEVICE_NAME L"\\Device\\SBWaveOut"
+/* TODO: MIDI */
+#define SB_AUX_DEVICE_NAME L"\\Device\\SBAux"
+#define SB_MIXER_DEVICE_NAME L"\\Device\\SBMixer"
+
+#define DEFAULT_PORT 0x220
+#define DEFAULT_IRQ 5
+#define DEFAULT_DMA 1
+#define DEFAULT_BUFFER_SIZE 65535
+
+#define SB_TIMEOUT 1000000
+
+#define SB_DSP_READY 0xaa
+
+enum
+{
+ NotDetected,
+ SoundBlaster,
+ SoundBlasterPro,
+ SoundBlaster2,
+ SoundBlasterPro2,
+ SoundBlasterProMCV,
+ SoundBlaster16
+};
+
+enum
+{
+ SB_RESET_PORT = 0x06,
+ SB_READ_DATA_PORT = 0x0a,
+ SB_WRITE_DATA_PORT = 0x0c,
+ SB_WRITE_STATUS_PORT = 0x0c,
+ SB_READ_STATUS_PORT = 0x0e
+};
+
+enum
+{
+ SbAutoInitDmaOutput = 0x1c,
+ SbAutoInitDmaInput = 0x2c,
+ SbSetOutputRate = 0x41, /* DSP v4.xx */
+ SbSetInputRate = 0x42, /* DSP v4.xx */
+ SbSetBlockSize = 0x48, /* DSP v2.00 + */
+ SbPauseDac = 0x80,
+ SbPauseDmaOutput = 0xd0,
+ SbEnableSpeaker = 0xd1,
+ SbDisableSpeaker = 0xd3,
+ SbGetSpeakerStatus = 0xd8, /* DSP v2.00 + */
+ SbGetDspVersion = 0xe1
+};
+
+typedef struct _SOUND_BLASTER_PARAMETERS
+{
+ PDRIVER_OBJECT driver;
+ PWSTR registry_path;
+ PKINTERRUPT interrupt;
+ ULONG port;
+ ULONG irq;
+ ULONG dma;
+ ULONG buffer_size;
+ USHORT dsp_version;
+} SOUND_BLASTER_PARAMETERS, *PSOUND_BLASTER_PARAMETERS;
+
+
+typedef STDCALL NTSTATUS REGISTRY_CALLBACK_ROUTINE(PDRIVER_OBJECT DriverObject, PWSTR
RegistryPath);
+typedef REGISTRY_CALLBACK_ROUTINE *PREGISTRY_CALLBACK_ROUTINE;
+
+
+/*
+ Port I/O
+*/
+
+#define SbWrite(sbdevice, subport, data) \
+ WRITE_PORT_UCHAR((PUCHAR) sbdevice->port + subport, data)
+
+#define SbRead(sbdevice, subport) \
+ READ_PORT_UCHAR((PUCHAR) sbdevice->port + subport)
+
+#define SbWriteReset(sbdevice, data) \
+ SbWrite(sbdevice, SB_RESET_PORT, data)
+
+#define SbWriteDataWithoutWait(sbdevice, data) \
+ SbWrite(sbdevice, SB_WRITE_DATA_PORT, data)
+
+#define SbReadDataWithoutWait(sbdevice) \
+ SbRead(sbdevice, SB_READ_DATA_PORT)
+
+
+#define SbGetWriteStatus(sbdevice) \
+ SbRead(sbdevice, SB_WRITE_STATUS_PORT)
+
+#define SbGetReadStatus(sbdevice) \
+ SbRead(sbdevice, SB_READ_STATUS_PORT)
+
+
+
+BOOLEAN
+WaitForReady(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ UCHAR Port);
+
+#define WaitToWrite(sbdevice) \
+ WaitForReady(sbdevice, SB_WRITE_STATUS_PORT)
+
+#define WaitToRead(sbdevice) \
+ WaitForReady(sbdevice, SB_READ_STATUS_PORT)
+
+BOOLEAN
+ResetSoundBlaster(
+ PSOUND_BLASTER_PARAMETERS SBDevice);
+
+ULONG
+GetSoundBlasterModel(
+ PSOUND_BLASTER_PARAMETERS SBDevice);
+
+BOOLEAN
+IsSampleRateCompatible(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ ULONG SampleRate);
+
+BOOLEAN
+SetOutputSampleRate(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ ULONG SampleRate);
+
+BOOLEAN
+EnableSpeaker(
+ PSOUND_BLASTER_PARAMETERS SBDevice);
+
+BOOLEAN
+DisableSpeaker(
+ PSOUND_BLASTER_PARAMETERS SBDevice);
+
+BOOLEAN
+StartSoundOutput(
+ PSOUND_BLASTER_PARAMETERS SBDevice,
+ ULONG BitDepth,
+ ULONG Channels,
+ ULONG BlockSize);
+
+
+/*
+ interrupt.c
+*/
+
+NTSTATUS
+EnableIrq(
+ PDEVICE_OBJECT DeviceObject);
+
+#endif
Added: trunk/reactos/drivers/multimedia/stdunk/stdunk.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/stdunk/…
==============================================================================
--- trunk/reactos/drivers/multimedia/stdunk/stdunk.c (added)
+++ trunk/reactos/drivers/multimedia/stdunk/stdunk.c Thu Mar 15 00:31:31 2007
@@ -1,0 +1,62 @@
+/*
+ "Unknown" implementation, in C
+ by Andrew Greenwood
+
+ Not quite sure how this is used, but the C++ variant is intended for
+ implementing a NonDelegatingUnknown object
+*/
+
+#include <stdunk.h>
+
+STDMETHODCALLTYPE
+NTSTATUS
+Unknown_QueryInterface(
+ IUnknown* this,
+ IN REFIID refiid,
+ OUT PVOID* output)
+{
+ /* TODO */
+ return STATUS_SUCCESS;
+}
+
+STDMETHODCALLTYPE
+ULONG
+Unknown_AddRef(
+ IUnknown* unknown_this)
+{
+ struct CUnknown* this = CONTAINING_RECORD(unknown_this, struct CUnknown, IUnknown);
+
+ InterlockedIncrement(&this->m_ref_count);
+ return this->m_ref_count;
+}
+
+STDMETHODCALLTYPE
+ULONG
+Unknown_Release(
+ IUnknown* unknown_this)
+{
+ struct CUnknown* this = CONTAINING_RECORD(unknown_this, struct CUnknown, IUnknown);
+
+ InterlockedDecrement(&this->m_ref_count);
+
+ if ( this->m_ref_count == 0 )
+ {
+ ExFreePool(this);
+ return 0;
+ }
+
+ return this->m_ref_count;
+}
+
+
+/*
+ The vtable for Unknown
+*/
+
+const IUnknownVtbl UnknownVtbl =
+{
+ Unknown_QueryInterface,
+ Unknown_AddRef,
+ Unknown_Release
+};
+
Added: trunk/reactos/drivers/multimedia/stdunk/stdunk.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/stdunk/…
==============================================================================
--- trunk/reactos/drivers/multimedia/stdunk/stdunk.cpp (added)
+++ trunk/reactos/drivers/multimedia/stdunk/stdunk.cpp Thu Mar 15 00:31:31 2007
@@ -1,0 +1,98 @@
+/*
+ TODO:
+ Need to call ASSERT on m_ref_count to ensure it is valid.
+*/
+
+#define PUT_GUIDS_HERE
+
+//#include <portcls.h>
+#include <punknown.h>
+#include <stdunk.h>
+
+#include <ntddk.h>
+
+
+/*
+ HACK ALERT
+ This is a little bit of a hack, but ReactOS doesn't seem to have this
+ defined. TODO: Make the aligned test truly aligned.
+*/
+
+#define IsEqualGUID(a, b) \
+ RtlEqualMemory(&a, &b, sizeof(GUID))
+
+#define IsEqualGUIDAligned(a, b) \
+ IsEqualGUID(a, b)
+
+/*
+ Shut the linker up - can also pass -defsym ___cxa_pure_virtual=0
+*/
+extern "C" void __cxa_pure_virtual(void) {}
+
+/*
+ IUnknown
+*/
+
+CUnknown::CUnknown(PUNKNOWN outer_unknown)
+{
+ m_ref_count = 0;
+
+ if ( outer_unknown )
+ {
+ m_outer_unknown = outer_unknown;
+ }
+ else
+ {
+ m_outer_unknown = PUNKNOWN(dynamic_cast<PNONDELEGATINGUNKNOWN>(this));
+ }
+}
+
+CUnknown::~CUnknown()
+{
+}
+
+/*
+ INonDelegatingUnknown
+*/
+
+STDMETHODIMP_(ULONG)
+CUnknown::NonDelegatingAddRef(void)
+{
+ InterlockedIncrement(&m_ref_count);
+ return m_ref_count;
+}
+
+STDMETHODIMP_(ULONG)
+CUnknown::NonDelegatingRelease(void)
+{
+ if ( InterlockedDecrement(&m_ref_count) == 0 )
+ {
+ delete this;
+ return 0;
+ }
+
+ return m_ref_count;
+}
+
+STDMETHODIMP_(NTSTATUS)
+CUnknown::NonDelegatingQueryInterface(
+ IN REFIID iid,
+ IN PVOID* ppvoid)
+{
+ //if ( RtlEqualMemory(&iid, &IID_IUnknown, sizeof(GUID)) )
+ {
+ *ppvoid = (PVOID)((PUNKNOWN) this);
+ }
+ // else
+ {
+ *ppvoid = NULL;
+ }
+
+ if ( *ppvoid )
+ {
+ ((PUNKNOWN)(*ppvoid))->AddRef();
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_INVALID_PARAMETER;
+}