Hackfix wdmaud.drv for now (Johannes Anderwald)

svn path=/trunk/; revision=44931
This commit is contained in:
Sylvain Petreolle 2010-01-04 18:07:27 +00:00
parent ba52cb038d
commit 09bf249e9d
2 changed files with 818 additions and 64 deletions

View file

@ -17,7 +17,7 @@
#define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
extern HANDLE KernelHandle;
DWORD OpenCount = 0;
extern DWORD OpenCount;
DWORD
WINAPI
@ -561,6 +561,7 @@ WriteFileEx_Committer2(
}
MMRESULT
WdmAudSetWaveStateByLegacy(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,

View file

@ -14,7 +14,307 @@
#include "wdmaud.h"
#define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
PWSTR UnknownWaveIn = L"Wave Input";
PWSTR UnknownWaveOut = L"Wave Output";
PWSTR UnknownMidiIn = L"Midi Input";
PWSTR UnknownMidiOut = L"Midi Output";
HANDLE KernelHandle = INVALID_HANDLE_VALUE;
DWORD OpenCount = 0;
MMRESULT
WriteFileEx_Remixer(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN PVOID OffsetPtr,
IN DWORD Length,
IN PSOUND_OVERLAPPED Overlap,
IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine);
MMRESULT
GetNumWdmDevs(
IN HANDLE Handle,
IN MMDEVICE_TYPE DeviceType,
OUT DWORD* DeviceCount)
{
#ifdef USE_MMIXER_LIB
switch(DeviceType)
{
case MIXER_DEVICE_TYPE:
*DeviceCount = WdmAudGetMixerCount();
break;
case WAVE_OUT_DEVICE_TYPE:
*DeviceCount = WdmAudGetWaveOutCount();
break;
case WAVE_IN_DEVICE_TYPE:
*DeviceCount = WdmAudGetWaveInCount();
break;
default:
*DeviceCount = 0;
}
return MMSYSERR_NOERROR;
#else
MMRESULT Result;
WDMAUD_DEVICE_INFO DeviceInfo;
VALIDATE_MMSYS_PARAMETER( Handle != INVALID_HANDLE_VALUE );
VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
VALIDATE_MMSYS_PARAMETER( DeviceCount );
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
Result = SyncOverlappedDeviceIoControl(Handle,
IOCTL_GETNUMDEVS_TYPE,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( ! MMSUCCESS( Result ) )
{
SND_ERR(L"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
*DeviceCount = 0;
return TranslateInternalMmResult(Result);
}
*DeviceCount = DeviceInfo.DeviceCount;
return MMSYSERR_NOERROR;
#endif
}
MMRESULT
GetWdmDeviceCapabilities(
IN PSOUND_DEVICE SoundDevice,
IN DWORD DeviceId,
OUT PVOID Capabilities,
IN DWORD CapabilitiesSize)
{
/* NOTE - At this time, WDMAUD does not support this properly */
MMRESULT Result;
MMDEVICE_TYPE DeviceType;
WDMAUD_DEVICE_INFO DeviceInfo;
SND_ASSERT( SoundDevice );
SND_ASSERT( Capabilities );
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
SND_ASSERT( Result == MMSYSERR_NOERROR );
if ( ! MMSUCCESS(Result) )
return Result;
SND_TRACE(L"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType, DeviceId);
#ifdef USE_MMIXER_LIB
if (DeviceType == MIXER_DEVICE_TYPE)
{
return WdmAudGetMixerCapabilities(DeviceId, (LPMIXERCAPSW)Capabilities);
}
else if (DeviceType == WAVE_OUT_DEVICE_TYPE)
{
return WdmAudGetWaveOutCapabilities(DeviceId, (LPWAVEOUTCAPSW)Capabilities);
}
else if (DeviceType == WAVE_IN_DEVICE_TYPE)
{
return WdmAudGetWaveInCapabilities(DeviceId, (LPWAVEINCAPSW)Capabilities);
}
#endif
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
DeviceInfo.DeviceIndex = DeviceId;
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_GETCAPABILITIES,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
/* This is pretty much a big hack right now */
switch ( DeviceType )
{
case MIXER_DEVICE_TYPE:
{
LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities;
DeviceInfo.u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
CopyWideString(MixerCaps->szPname, DeviceInfo.u.MixCaps.szPname);
MixerCaps->cDestinations = DeviceInfo.u.MixCaps.cDestinations;
MixerCaps->fdwSupport = DeviceInfo.u.MixCaps.fdwSupport;
MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion;
MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid;
MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid;
break;
}
case WAVE_OUT_DEVICE_TYPE :
{
LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;
DeviceInfo.u.WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
WaveOutCaps->vDriverVersion = 0x0001;
CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
WaveOutCaps->dwSupport = DeviceInfo.u.WaveOutCaps.dwSupport;
break;
}
case WAVE_IN_DEVICE_TYPE :
{
LPWAVEINCAPSW WaveInCaps = (LPWAVEINCAPSW) Capabilities;
DeviceInfo.u.WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0';
WaveInCaps->wMid = DeviceInfo.u.WaveInCaps.wMid;
WaveInCaps->wPid = DeviceInfo.u.WaveInCaps.wPid;
WaveInCaps->vDriverVersion = 0x0001;
CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveInCaps.szPname);
WaveInCaps->dwFormats = DeviceInfo.u.WaveInCaps.dwFormats;
WaveInCaps->wChannels = DeviceInfo.u.WaveInCaps.wChannels;
WaveInCaps->wReserved1 = 0;
break;
}
}
return MMSYSERR_NOERROR;
}
MMRESULT
OpenWdmSoundDevice(
IN struct _SOUND_DEVICE* SoundDevice, /* NOT USED */
OUT PVOID* Handle)
{
/* Only open this if it's not already open */
if ( KernelHandle == INVALID_HANDLE_VALUE )
{
SND_TRACE(L"Opening wdmaud device\n");
KernelHandle = CreateFileW(KERNEL_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
}
if ( KernelHandle == INVALID_HANDLE_VALUE )
return MMSYSERR_ERROR;
SND_ASSERT( Handle );
*Handle = KernelHandle;
++ OpenCount;
return MMSYSERR_NOERROR;
}
MMRESULT
CloseWdmSoundDevice(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN PVOID Handle)
{
WDMAUD_DEVICE_INFO DeviceInfo;
MMRESULT Result;
MMDEVICE_TYPE DeviceType;
PSOUND_DEVICE SoundDevice;
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
if ( OpenCount == 0 )
{
return MMSYSERR_NOERROR;
}
SND_ASSERT( KernelHandle != INVALID_HANDLE_VALUE );
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
SND_ASSERT( Result == MMSYSERR_NOERROR );
if (SoundDeviceInstance->Handle != (PVOID)KernelHandle)
{
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
DeviceInfo.hDevice = SoundDeviceInstance->Handle;
/* First stop the stream */
if (DeviceType != MIXER_DEVICE_TYPE)
{
DeviceInfo.u.State = KSSTATE_STOP;
SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_SETDEVICE_STATE,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
}
#ifdef USE_MMIXER_LIB
if (DeviceType == MIXER_DEVICE_TYPE)
{
return WdmAudCloseMixer(SoundDeviceInstance->Handle, SoundDeviceInstance->hNotifyEvent);
}
#endif
SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_CLOSE_WDMAUD,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
}
if (DeviceType == MIXER_DEVICE_TYPE)
{
SetEvent(SoundDeviceInstance->hStopEvent);
CloseHandle(SoundDeviceInstance->hStopEvent);
CloseHandle(SoundDeviceInstance->hNotifyEvent);
}
--OpenCount;
if ( OpenCount < 1 )
{
CloseHandle(KernelHandle);
KernelHandle = INVALID_HANDLE_VALUE;
}
return MMSYSERR_NOERROR;
}
MMRESULT
QueryWdmWaveDeviceFormatSupport(
@ -27,8 +327,483 @@ QueryWdmWaveDeviceFormatSupport(
}
MMRESULT
SetWdmMixerDeviceFormat(
IN PSOUND_DEVICE_INSTANCE Instance,
IN DWORD DeviceId,
IN PWAVEFORMATEX WaveFormat,
IN DWORD WaveFormatSize)
{
MMRESULT Result;
WDMAUD_DEVICE_INFO DeviceInfo;
HANDLE hThread;
Instance->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if ( ! Instance->hNotifyEvent )
return MMSYSERR_NOMEM;
#ifdef USE_MMIXER_LIB
return WdmAudOpenMixer(&Instance->Handle, DeviceId, Instance->hNotifyEvent);
#endif
if (Instance->Handle != KernelHandle)
{
/* device is already open */
return MMSYSERR_NOERROR;
}
Instance->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
if ( ! Instance->hStopEvent )
return MMSYSERR_NOMEM;
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
DeviceInfo.DeviceIndex = DeviceId;
DeviceInfo.u.hNotifyEvent = Instance->hNotifyEvent;
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_OPEN_WDMAUD,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( ! MMSUCCESS(Result) )
{
CloseHandle(Instance->hNotifyEvent);
CloseHandle(Instance->hStopEvent);
return TranslateInternalMmResult(Result);
}
hThread = CreateThread(NULL, 0, MixerEventThreadRoutine, (LPVOID)Instance, 0, NULL);
if ( hThread )
{
CloseHandle(hThread);
}
/* Store sound device handle instance handle */
Instance->Handle = (PVOID)DeviceInfo.hDevice;
return MMSYSERR_NOERROR;
}
MMRESULT
SetWdmWaveDeviceFormat(
IN PSOUND_DEVICE_INSTANCE Instance,
IN DWORD DeviceId,
IN PWAVEFORMATEX WaveFormat,
IN DWORD WaveFormatSize)
{
MMRESULT Result;
PSOUND_DEVICE SoundDevice;
PVOID Identifier;
WDMAUD_DEVICE_INFO DeviceInfo;
MMDEVICE_TYPE DeviceType;
Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
if (Instance->Handle != KernelHandle)
{
/* device is already open */
return MMSYSERR_NOERROR;
}
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
#ifdef USE_MMIXER_LIB
return WdmAudOpenWavePin(Instance, DeviceId, WaveFormat, DeviceType);
#endif
SND_ASSERT( Result == MMSYSERR_NOERROR );
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
DeviceInfo.DeviceIndex = DeviceId;
DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize;
DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
#ifdef USERMODE_MIXER
DeviceInfo.u.WaveFormatEx.nChannels = 2;
DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100;
DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400;
DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
#else
DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels;
DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
DeviceInfo.u.WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
#endif
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_OPEN_WDMAUD,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
/* Store format */
Instance->WaveFormatEx.cbSize = WaveFormat->cbSize;
Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
Instance->WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
/* Store sound device handle instance handle */
Instance->Handle = (PVOID)DeviceInfo.hDevice;
/* Now determine framing requirements */
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_GETFRAMESIZE,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( MMSUCCESS(Result) )
{
if (DeviceInfo.u.FrameSize)
{
Instance->FrameSize = DeviceInfo.u.FrameSize * 2;
Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize;
SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount);
}
}
else
{
// use a default of 100 buffers
Instance->BufferCount = 100;
}
if (DeviceType == WAVE_OUT_DEVICE_TYPE)
{
/* Now start the stream */
DeviceInfo.u.State = KSSTATE_RUN;
SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_SETDEVICE_STATE,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
}
return MMSYSERR_NOERROR;
}
MMRESULT
SetWdmWaveState(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN BOOL bStart)
{
MMRESULT Result;
PSOUND_DEVICE SoundDevice;
WDMAUD_DEVICE_INFO DeviceInfo;
MMDEVICE_TYPE DeviceType;
HANDLE Handle;
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
SND_ASSERT( Result == MMSYSERR_NOERROR );
Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
SND_ASSERT( Result == MMSYSERR_NOERROR );
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.hDevice = Handle;
DeviceInfo.DeviceType = DeviceType;
if (bStart)
DeviceInfo.u.State = KSSTATE_RUN;
else
DeviceInfo.u.State = KSSTATE_PAUSE;
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_SETDEVICE_STATE,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
return Result;
}
MMRESULT
GetDeviceInterfaceString(
IN MMDEVICE_TYPE DeviceType,
IN DWORD DeviceId,
IN LPWSTR Interface,
IN DWORD InterfaceLength,
OUT DWORD * InterfaceSize)
{
WDMAUD_DEVICE_INFO DeviceInfo;
MMRESULT Result;
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.DeviceType = DeviceType;
DeviceInfo.DeviceIndex = DeviceId;
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_QUERYDEVICEINTERFACESTRING,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
if (!Interface)
{
SND_ASSERT(InterfaceSize);
*InterfaceSize = DeviceInfo.u.Interface.DeviceInterfaceStringSize;
return MMSYSERR_NOERROR;
}
if (InterfaceLength < DeviceInfo.u.Interface.DeviceInterfaceStringSize)
{
/* buffer is too small */
return MMSYSERR_MOREDATA;
}
DeviceInfo.u.Interface.DeviceInterfaceStringSize = InterfaceLength;
DeviceInfo.u.Interface.DeviceInterfaceString = Interface;
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_QUERYDEVICEINTERFACESTRING,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( MMSUCCESS(Result) && InterfaceLength > 2)
{
Interface[1] = L'\\';
Interface[InterfaceLength-1] = L'\0';
}
return Result;
}
MMRESULT
GetWdmPosition(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN MMTIME* Time)
{
MMRESULT Result;
PSOUND_DEVICE SoundDevice;
WDMAUD_DEVICE_INFO DeviceInfo;
MMDEVICE_TYPE DeviceType;
HANDLE Handle;
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
Result = GetSoundDeviceType(SoundDevice, &DeviceType);
SND_ASSERT( Result == MMSYSERR_NOERROR );
Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
SND_ASSERT( Result == MMSYSERR_NOERROR );
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.hDevice = Handle;
DeviceInfo.DeviceType = DeviceType;
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_OPEN_WDMAUD,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( ! MMSUCCESS(Result) )
{
return TranslateInternalMmResult(Result);
}
Time->wType = TIME_BYTES;
Time->u.cb = (DWORD)DeviceInfo.u.Position;
return MMSYSERR_NOERROR;
}
MMRESULT
ResetStream(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN MMDEVICE_TYPE DeviceType,
IN BOOLEAN bStartReset)
{
MMRESULT Result;
HANDLE Handle;
WDMAUD_DEVICE_INFO DeviceInfo;
Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
SND_ASSERT( Result == MMSYSERR_NOERROR );
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.hDevice = Handle;
DeviceInfo.DeviceType = DeviceType;
DeviceInfo.u.ResetStream = (bStartReset ? KSRESET_BEGIN : KSRESET_END);
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IOCTL_RESET_STREAM,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
return Result;
}
MMRESULT
QueryMixerInfo(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN UINT uMsg,
IN LPVOID Parameter,
IN DWORD Flags)
{
MMRESULT Result;
WDMAUD_DEVICE_INFO DeviceInfo;
HANDLE Handle;
DWORD IoControlCode;
LPMIXERLINEW MixLine;
LPMIXERLINECONTROLSW MixControls;
LPMIXERCONTROLDETAILS MixDetails;
SND_TRACE(L"uMsg %x Flags %x\n", uMsg, Flags);
Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
SND_ASSERT( Result == MMSYSERR_NOERROR );
ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
DeviceInfo.hDevice = Handle;
DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
DeviceInfo.Flags = Flags;
MixLine = (LPMIXERLINEW)Parameter;
MixControls = (LPMIXERLINECONTROLSW)Parameter;
MixDetails = (LPMIXERCONTROLDETAILS)Parameter;
#ifdef USE_MMIXER_LIB
switch(uMsg)
{
case MXDM_GETLINEINFO:
return WdmAudGetLineInfo(SoundDeviceInstance->Handle, MixLine, Flags);
case MXDM_GETLINECONTROLS:
return WdmAudGetLineControls(SoundDeviceInstance->Handle, MixControls, Flags);
case MXDM_SETCONTROLDETAILS:
return WdmAudSetControlDetails(SoundDeviceInstance->Handle, MixDetails, Flags);
break;
case MXDM_GETCONTROLDETAILS:
return WdmAudGetControlDetails(SoundDeviceInstance->Handle, MixDetails, Flags);
break;
default:
SND_ASSERT(0);
return MMSYSERR_NOTSUPPORTED;
}
#endif
switch(uMsg)
{
case MXDM_GETLINEINFO:
RtlCopyMemory(&DeviceInfo.u.MixLine, MixLine, sizeof(MIXERLINEW));
IoControlCode = IOCTL_GETLINEINFO;
break;
case MXDM_GETLINECONTROLS:
RtlCopyMemory(&DeviceInfo.u.MixControls, MixControls, sizeof(MIXERLINECONTROLSW));
IoControlCode = IOCTL_GETLINECONTROLS;
break;
case MXDM_SETCONTROLDETAILS:
RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
IoControlCode = IOCTL_SETCONTROLDETAILS;
break;
case MXDM_GETCONTROLDETAILS:
RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
IoControlCode = IOCTL_GETCONTROLDETAILS;
break;
default:
SND_ASSERT(0);
return MMSYSERR_NOTSUPPORTED;
}
Result = SyncOverlappedDeviceIoControl(KernelHandle,
IoControlCode,
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
(LPVOID) &DeviceInfo,
sizeof(WDMAUD_DEVICE_INFO),
NULL);
if ( ! MMSUCCESS(Result) )
{
return Result;
}
switch(uMsg)
{
case MXDM_GETLINEINFO:
{
RtlCopyMemory(MixLine, &DeviceInfo.u.MixLine, sizeof(MIXERLINEW));
break;
}
}
return Result;
}
MMRESULT
PopulateWdmDeviceList(
HANDLE Handle,
MMDEVICE_TYPE DeviceType)
{
MMRESULT Result;
@ -37,13 +812,10 @@ PopulateWdmDeviceList(
MMFUNCTION_TABLE FuncTable;
DWORD i;
VALIDATE_MMSYS_PARAMETER( Handle != INVALID_HANDLE_VALUE );
VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
#ifdef USE_MMIXER_LIB
Result = WdmAudGetNumDevsByMMixer(DeviceType, &DeviceCount);
#else
Result = WdmAudGetNumWdmDevsByLegacy(DeviceType, &DeviceCount);
#endif
Result = GetNumWdmDevs(Handle, DeviceType, &DeviceCount);
if ( ! MMSUCCESS(Result) )
{
@ -66,59 +838,42 @@ PopulateWdmDeviceList(
/* Set up our function table */
ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE));
#ifdef USE_MMIXER_LIB
FuncTable.GetCapabilities = WdmAudGetCapabilitiesByMMixer;
FuncTable.Open = WdmAudOpenSoundDeviceByMMixer;
FuncTable.Close = WdmAudCloseSoundDeviceByMMixer;
FuncTable.GetDeviceInterfaceString = WdmAudGetDeviceInterfaceStringByMMixer;
#else
FuncTable.GetCapabilities = WdmAudGetCapabilitiesByLegacy;
FuncTable.Open = WdmAudOpenSoundDeviceByLegacy;
FuncTable.Close = WdmAudCloseSoundDeviceByLegacy;
FuncTable.GetDeviceInterfaceString = WdmAudGetDeviceInterfaceStringByLegacy;
#endif
FuncTable.GetCapabilities = GetWdmDeviceCapabilities;
FuncTable.QueryWaveFormatSupport = QueryWdmWaveDeviceFormatSupport;
if (DeviceType == MIXER_DEVICE_TYPE)
{
#ifdef USE_MMIXER_LIB
FuncTable.SetWaveFormat = WdmAudSetMixerDeviceFormatByMMixer;
FuncTable.QueryMixerInfo = WdmAudQueryMixerInfoByMMixer;
#else
FuncTable.SetWaveFormat = WdmAudSetMixerDeviceFormatByLegacy;
FuncTable.QueryMixerInfo = WdmAudQueryMixerInfoByLegacy;
#endif
FuncTable.SetWaveFormat = SetWdmMixerDeviceFormat;
FuncTable.QueryMixerInfo = QueryMixerInfo;
}
else
{
FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
}
if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
{
#ifdef USE_MMIXER_LIB
FuncTable.SetWaveFormat = WdmAudSetWdmWaveDeviceFormatByMMixer;
FuncTable.SetState = WdmAudSetWdmWaveStateByMMixer;
FuncTable.ResetStream = WdmAudResetStreamByMMixer;
FuncTable.GetPos = WdmAudGetWdmPositionByMMixer;
#else
FuncTable.SetWaveFormat = WdmAudSetWaveDeviceFormatByLegacy;
FuncTable.SetState = WdmAudSetWaveStateByLegacy;
FuncTable.ResetStream = WdmAudResetStreamByLegacy;
FuncTable.GetPos = WdmAudGetWavePositionByLegacy;
#endif
#ifdef USE_MMIXER_LIB
FuncTable.CommitWaveBuffer = WdmAudCommitWaveBufferByMMixer;
#elif defined (USERMODE_MIXER)
FuncTable.CommitWaveBuffer = WriteFileEx_Remixer;
#else
FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
#endif
FuncTable.SetState = SetWdmWaveState;
FuncTable.ResetStream = ResetStream;
}
FuncTable.Open = OpenWdmSoundDevice;
FuncTable.Close = CloseWdmSoundDevice;
FuncTable.GetDeviceInterfaceString = GetDeviceInterfaceString;
#ifndef USERMODE_MIXER
FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
#else
FuncTable.CommitWaveBuffer = WriteFileEx_Remixer;
#endif
FuncTable.GetPos = GetWdmPosition;
SetSoundDeviceFunctionTable(SoundDevice, &FuncTable);
}
return MMSYSERR_NOERROR;
}
LONG
APIENTRY
DriverProc(
@ -134,6 +889,7 @@ DriverProc(
{
case DRV_LOAD :
{
HANDLE Handle;
SND_TRACE(L"DRV_LOAD\n");
Result = InitEntrypointMutexes();
@ -141,14 +897,9 @@ DriverProc(
if ( ! MMSUCCESS(Result) )
return 0L;
#ifdef USE_MMIXER_LIB
if (!WdmAudInitUserModeMixer())
{
SND_ERR(L"Failed to initialize mmixer lib\n");
return 0;
}
#else
if (WdmAudOpenSoundDeviceByLegacy() != MMSYSERR_NOERROR)
OpenWdmSoundDevice(NULL, &Handle);
if ( Handle == INVALID_HANDLE_VALUE )
{
SND_ERR(L"Failed to open \\\\.\\wdmaud\n");
CleanupEntrypointMutexes();
@ -157,16 +908,15 @@ DriverProc(
return 0L;
}
#endif
/* Populate the device lists */
SND_TRACE(L"Populating device lists\n");
PopulateWdmDeviceList(WAVE_OUT_DEVICE_TYPE);
PopulateWdmDeviceList(WAVE_IN_DEVICE_TYPE);
PopulateWdmDeviceList(MIDI_OUT_DEVICE_TYPE);
PopulateWdmDeviceList(MIDI_IN_DEVICE_TYPE);
PopulateWdmDeviceList(AUX_DEVICE_TYPE);
PopulateWdmDeviceList(MIXER_DEVICE_TYPE);
PopulateWdmDeviceList(KernelHandle, WAVE_OUT_DEVICE_TYPE);
PopulateWdmDeviceList(KernelHandle, WAVE_IN_DEVICE_TYPE);
PopulateWdmDeviceList(KernelHandle, MIDI_OUT_DEVICE_TYPE);
PopulateWdmDeviceList(KernelHandle, MIDI_IN_DEVICE_TYPE);
PopulateWdmDeviceList(KernelHandle, AUX_DEVICE_TYPE);
PopulateWdmDeviceList(KernelHandle, MIXER_DEVICE_TYPE);
SND_TRACE(L"Initialisation complete\n");
@ -177,11 +927,11 @@ DriverProc(
{
SND_TRACE(L"DRV_FREE\n");
#ifdef USE_MMIXER_LIB
WdmAudCleanupMMixer();
#else
WdmAudCleanupLegacy();
#endif
if ( KernelHandle != INVALID_HANDLE_VALUE )
{
CloseHandle(KernelHandle);
KernelHandle = INVALID_HANDLE_VALUE;
}
/* TODO: Clean up the path names! */
UnlistAllSoundDevices();
@ -235,6 +985,9 @@ BOOL WINAPI DllMain(
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH :
#ifdef USE_MMIXER_LIB
WdmAudInitUserModeMixer();
#endif
SND_TRACE(L"WDMAUD.DRV - Process attached\n");
break;
case DLL_PROCESS_DETACH :