From: Johannes Anderwald Date: Wed, 23 Dec 2009 03:05:11 +0000 (+0000) Subject: [WDMAUD.DRV] X-Git-Tag: backups/aicom-network-stable@46924~194 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=4b9731d0db1a4868c0759c8f43cde24f4be7ae8a [WDMAUD.DRV] - Move the routines which interact wdmaud.sys to legacy.c - Implement opening / closing of audio pins as well as writing / reading audio bytes from / to it - By defining USE_MMIXER_LIB, wdmaud.drv bypasses wdmaud+sysaudio and directly writes/reads the audio bytes to portcls. svn path=/trunk/; revision=44721 --- diff --git a/reactos/dll/win32/wdmaud.drv/legacy.c b/reactos/dll/win32/wdmaud.drv/legacy.c new file mode 100644 index 00000000000..68486dd9215 --- /dev/null +++ b/reactos/dll/win32/wdmaud.drv/legacy.c @@ -0,0 +1,823 @@ +/* + * PROJECT: ReactOS Sound System + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/win32/wdmaud.drv/wdmaud.c + * + * PURPOSE: WDM Audio Driver (User-mode part) + * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org) + Johannes Anderwald + * + * NOTES: Looking for wodMessage & co? You won't find them here. Try + * the MME Buddy library, which is where these routines are + * actually implemented. + * + */ + +#include "wdmaud.h" + +#define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud" +extern HANDLE KernelHandle; +DWORD OpenCount = 0; + +DWORD +WINAPI +MixerEventThreadRoutine( + LPVOID Parameter) +{ + HANDLE WaitObjects[2]; + DWORD dwResult; + MMRESULT Result; + WDMAUD_DEVICE_INFO DeviceInfo; + PSOUND_DEVICE_INSTANCE Instance = (PSOUND_DEVICE_INSTANCE)Parameter; + + /* setup wait objects */ + WaitObjects[0] = Instance->hNotifyEvent; + WaitObjects[1] = Instance->hStopEvent; + + /* zero device info */ + ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); + + DeviceInfo.hDevice = Instance->Handle; + DeviceInfo.DeviceType = MIXER_DEVICE_TYPE; + + do + { + dwResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE); + + if (dwResult == WAIT_OBJECT_0 + 1) + { + /* stop event was signalled */ + break; + } + + do + { + Result = SyncOverlappedDeviceIoControl(KernelHandle, + IOCTL_GET_MIXER_EVENT, + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + NULL); + + if (Result == MMSYSERR_NOERROR) + { + DriverCallback(Instance->WinMM.ClientCallback, + HIWORD(Instance->WinMM.Flags), + Instance->WinMM.Handle, + DeviceInfo.u.MixerEvent.NotificationType, + Instance->WinMM.ClientCallbackInstanceData, + (DWORD_PTR)DeviceInfo.u.MixerEvent.Value, + 0); + } + }while(Result == MMSYSERR_NOERROR); + }while(TRUE); + + /* done */ + return 0; +} + +VOID +WdmAudCleanupLegacy() +{ + if ( KernelHandle != INVALID_HANDLE_VALUE ) + { + CloseHandle(KernelHandle); + KernelHandle = INVALID_HANDLE_VALUE; + } +} + +MMRESULT +WdmAudGetNumWdmDevsByLegacy( + IN MMDEVICE_TYPE DeviceType, + OUT DWORD* DeviceCount) +{ + MMRESULT Result; + WDMAUD_DEVICE_INFO DeviceInfo; + + VALIDATE_MMSYS_PARAMETER( KernelHandle != 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(KernelHandle, + 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; +} + +MMRESULT +WdmAudGetCapabilitiesByLegacy( + IN PSOUND_DEVICE SoundDevice, + IN DWORD DeviceId, + OUT PVOID Capabilities, + IN DWORD CapabilitiesSize) +{ + 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); + + 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 +WdmAudOpenSoundDeviceByLegacy() +{ + /* 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; + + ++ OpenCount; + + return MMSYSERR_NOERROR; +} + +MMRESULT +WdmAudCloseSoundDeviceByLegacy( + 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); + } + + 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 +WdmAudSetMixerDeviceFormatByLegacy( + 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; + + 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 +WdmAudSetWaveDeviceFormatByLegacy( + 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); + + 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 +WriteFileEx_Committer2( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + IN PVOID OffsetPtr, + IN DWORD Length, + IN PSOUND_OVERLAPPED Overlap, + IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine) +{ + HANDLE Handle; + MMRESULT Result; + WDMAUD_DEVICE_INFO DeviceInfo; + PSOUND_DEVICE SoundDevice; + MMDEVICE_TYPE DeviceType; + BOOL Ret; + + VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance ); + VALIDATE_MMSYS_PARAMETER( OffsetPtr ); + VALIDATE_MMSYS_PARAMETER( Overlap ); + VALIDATE_MMSYS_PARAMETER( CompletionRoutine ); + + GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); + + + Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); + + if ( ! MMSUCCESS(Result) ) + { + return TranslateInternalMmResult(Result); + } + + Result = GetSoundDeviceType(SoundDevice, &DeviceType); + SND_ASSERT( Result == MMSYSERR_NOERROR ); + + SND_ASSERT(Handle); + + ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); + + DeviceInfo.Header.FrameExtent = Length; + if (DeviceType == WAVE_OUT_DEVICE_TYPE) + { + DeviceInfo.Header.DataUsed = Length; + } + DeviceInfo.Header.Data = OffsetPtr; + DeviceInfo.Header.Size = sizeof(WDMAUD_DEVICE_INFO); + DeviceInfo.Header.PresentationTime.Numerator = 1; + DeviceInfo.Header.PresentationTime.Denominator = 1; + DeviceInfo.hDevice = Handle; + DeviceInfo.DeviceType = DeviceType; + + Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + + if (DeviceType == WAVE_OUT_DEVICE_TYPE) + { + Ret = WriteFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine); + if (Ret) + WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); + } + else if (DeviceType == WAVE_IN_DEVICE_TYPE) + { + Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine); + //if (Ret) + // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); + } + + return MMSYSERR_NOERROR; +} + + +MMRESULT +WdmAudSetWaveStateByLegacy( + 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 +WdmAudGetDeviceInterfaceStringByLegacy( + 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 +WdmAudGetWavePositionByLegacy( + 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 +WdmAudResetStreamByLegacy( + 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 +WdmAudQueryMixerInfoByLegacy( + 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; + + 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; +} diff --git a/reactos/dll/win32/wdmaud.drv/mixer.c b/reactos/dll/win32/wdmaud.drv/mixer.c index 687af373039..ec41ef2d832 100644 --- a/reactos/dll/win32/wdmaud.drv/mixer.c +++ b/reactos/dll/win32/wdmaud.drv/mixer.c @@ -556,3 +556,4 @@ WriteFileEx_Remixer( return MMSYSERR_NOERROR; } + diff --git a/reactos/dll/win32/wdmaud.drv/mmixer.c b/reactos/dll/win32/wdmaud.drv/mmixer.c index 1c8c0465cf3..bdf5875d193 100644 --- a/reactos/dll/win32/wdmaud.drv/mmixer.c +++ b/reactos/dll/win32/wdmaud.drv/mmixer.c @@ -321,11 +321,10 @@ WdmAudInitUserModeMixer() return TRUE; } -ULONG -WdmAudGetMixerCount() +VOID +WdmAudCleanupMMixer() { - /* return number of mixers available */ - return MMixerGetCount(&MixerContext); + /* TODO */ } MMRESULT @@ -339,31 +338,10 @@ WdmAudGetMixerCapabilties( return MMSYSERR_BADDEVICEID; } -MMRESULT -WdmAudCloseMixer( - IN HMIXER Handle, - IN HANDLE hNotifyEvent) -{ - /* FIXME */ - return MMSYSERR_NOERROR; -} - -MMRESULT -WdmAudOpenMixer( - IN PHANDLE hMixer, - IN ULONG DeviceId, - IN HANDLE hNotifyEvent) -{ - if (MMixerOpen(&MixerContext, DeviceId, hNotifyEvent, NULL /* FIXME */, hMixer) == MM_STATUS_SUCCESS) - return MMSYSERR_NOERROR; - - return MMSYSERR_BADDEVICEID; -} - MMRESULT WdmAudGetLineInfo( IN HANDLE hMixer, - IN LPMIXERLINE MixLine, + IN LPMIXERLINEW MixLine, IN ULONG Flags) { if (MMixerGetLineInfo(&MixerContext, hMixer, Flags, MixLine) == MM_STATUS_SUCCESS) @@ -409,18 +387,6 @@ WdmAudGetControlDetails( return MMSYSERR_ERROR; } -ULONG -WdmAudGetWaveOutCount() -{ - return MMixerGetWaveOutCount(&MixerContext); -} - -ULONG -WdmAudGetWaveInCount() -{ - return MMixerGetWaveInCount(&MixerContext); -} - MMRESULT WdmAudGetWaveOutCapabilities( IN ULONG DeviceId, @@ -445,17 +411,297 @@ WdmAudGetWaveInCapabilities( } MMRESULT -WdmAudOpenWave( - OUT PHANDLE hPin, - IN DWORD DeviceId, - IN PWAVEFORMATEX WaveFormat, - IN DWORD bWaveIn) +WdmAudSetWdmWaveDeviceFormatByMMixer( + IN PSOUND_DEVICE_INSTANCE Instance, + IN DWORD DeviceId, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize) { - if (MMixerOpenWave(&MixerContext, DeviceId, bWaveIn, WaveFormat, hPin) == MM_STATUS_SUCCESS) + MMDEVICE_TYPE DeviceType; + PSOUND_DEVICE SoundDevice; + MMRESULT Result; + BOOL bWaveIn; + + Result = GetSoundDeviceFromInstance(Instance, &SoundDevice); + + if ( ! MMSUCCESS(Result) ) { - //fixme - // start stream if waveout + return TranslateInternalMmResult(Result); + } + + Result = GetSoundDeviceType(SoundDevice, &DeviceType); + SND_ASSERT( Result == MMSYSERR_NOERROR ); + + bWaveIn = (DeviceType == WAVE_IN_DEVICE_TYPE ? TRUE : FALSE); + + if (MMixerOpenWave(&MixerContext, DeviceId, bWaveIn, WaveFormat, &Instance->Handle) == MM_STATUS_SUCCESS) + { + if (DeviceType == WAVE_OUT_DEVICE_TYPE) + { + MMixerSetWaveStatus(&MixerContext, Instance->Handle, KSSTATE_ACQUIRE); + MMixerSetWaveStatus(&MixerContext, Instance->Handle, KSSTATE_PAUSE); + MMixerSetWaveStatus(&MixerContext, Instance->Handle, KSSTATE_RUN); + } return MMSYSERR_NOERROR; } return MMSYSERR_ERROR; } + + +MMRESULT +WdmAudGetCapabilitiesByMMixer( + IN PSOUND_DEVICE SoundDevice, + IN DWORD DeviceId, + OUT PVOID Capabilities, + IN DWORD CapabilitiesSize) +{ + MMDEVICE_TYPE DeviceType; + MMRESULT Result; + + Result = GetSoundDeviceType(SoundDevice, &DeviceType); + SND_ASSERT( Result == MMSYSERR_NOERROR ); + + if (DeviceType == MIXER_DEVICE_TYPE) + { + return WdmAudGetMixerCapabilties(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); + } + else + { + // not supported + return MMSYSERR_ERROR; + } +} + +MMRESULT +WdmAudOpenSoundDeviceByMMixer( + IN struct _SOUND_DEVICE* SoundDevice, + OUT PVOID* Handle) +{ + /* no-op */ + return MMSYSERR_NOERROR; +} + +MMRESULT +WdmAudCloseSoundDeviceByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN PVOID Handle) +{ + MMDEVICE_TYPE DeviceType; + PSOUND_DEVICE SoundDevice; + MMRESULT Result; + + Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); + + if ( ! MMSUCCESS(Result) ) + { + return TranslateInternalMmResult(Result); + } + + Result = GetSoundDeviceType(SoundDevice, &DeviceType); + SND_ASSERT( Result == MMSYSERR_NOERROR ); + + if (DeviceType == MIXER_DEVICE_TYPE) + { + /* no op */ + return MMSYSERR_NOERROR; + } + else if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) + { + /* make sure the pin is stopped */ + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_PAUSE); + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE); + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_STOP); + + CloseHandle(Handle); + return MMSYSERR_NOERROR; + } + + /* midi is not supported */ + return MMSYSERR_ERROR; +} + +MMRESULT +WdmAudGetNumDevsByMMixer( + IN MMDEVICE_TYPE DeviceType, + OUT DWORD* DeviceCount) +{ + switch(DeviceType) + { + case MIXER_DEVICE_TYPE: + *DeviceCount = MMixerGetCount(&MixerContext); + break; + case WAVE_OUT_DEVICE_TYPE: + *DeviceCount = MMixerGetWaveOutCount(&MixerContext); + break; + case WAVE_IN_DEVICE_TYPE: + *DeviceCount = MMixerGetWaveInCount(&MixerContext); + break; + default: + *DeviceCount = 0; + } + return MMSYSERR_NOERROR; +} + +MMRESULT +WdmAudQueryMixerInfoByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN UINT uMsg, + IN LPVOID Parameter, + IN DWORD Flags) +{ + LPMIXERLINEW MixLine; + LPMIXERLINECONTROLSW MixControls; + LPMIXERCONTROLDETAILS MixDetails; + + MixLine = (LPMIXERLINEW)Parameter; + MixControls = (LPMIXERLINECONTROLSW)Parameter; + MixDetails = (LPMIXERCONTROLDETAILS)Parameter; + + /* FIXME param checks */ + + 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; + } +} + +MMRESULT +WdmAudGetDeviceInterfaceStringByMMixer( + IN MMDEVICE_TYPE DeviceType, + IN DWORD DeviceId, + IN LPWSTR Interface, + IN DWORD InterfaceLength, + OUT DWORD * InterfaceSize) +{ + /* FIXME */ + return MMSYSERR_NOTSUPPORTED; +} + +MMRESULT +WdmAudSetMixerDeviceFormatByMMixer( + IN PSOUND_DEVICE_INSTANCE Instance, + IN DWORD DeviceId, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize) +{ + Instance->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if ( ! Instance->hNotifyEvent ) + return MMSYSERR_NOMEM; + + if (MMixerOpen(&MixerContext, DeviceId, Instance->hNotifyEvent, NULL /* FIXME */, &Instance->Handle) == MM_STATUS_SUCCESS) + return MMSYSERR_NOERROR; + + return MMSYSERR_BADDEVICEID; +} + +MMRESULT +WdmAudSetWdmWaveStateByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN BOOL bStart) +{ + if (bStart) + { + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE); + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_PAUSE); + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_RUN); + } + else + { + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_PAUSE); + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE); + MMixerSetWaveStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_STOP); + } + + return MMSYSERR_NOERROR; +} + +MMRESULT +WdmAudResetStreamByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN MMDEVICE_TYPE DeviceType, + IN BOOLEAN bStartReset) +{ + /* FIXME */ + return MMSYSERR_NOTSUPPORTED; +} + +MMRESULT +WdmAudGetWdmPositionByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN MMTIME* Time) +{ + /* FIXME */ + return MMSYSERR_NOTSUPPORTED; +} + +MMRESULT +WdmAudCommitWaveBufferByMMixer( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + IN PVOID OffsetPtr, + IN DWORD Length, + IN PSOUND_OVERLAPPED Overlap, + IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine) +{ + KSSTREAM_HEADER Packet; + PSOUND_DEVICE SoundDevice; + MMDEVICE_TYPE DeviceType; + MMRESULT Result; + + Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); + + if ( ! MMSUCCESS(Result) ) + { + return TranslateInternalMmResult(Result); + } + + Result = GetSoundDeviceType(SoundDevice, &DeviceType); + SND_ASSERT( Result == MMSYSERR_NOERROR ); + + /* setup stream packet */ + ZeroMemory(&Packet, sizeof(KSSTREAM_HEADER)); + Packet.Size = sizeof(KSSTREAM_HEADER); + Packet.PresentationTime.Numerator = 1; + Packet.PresentationTime.Denominator = 1; + Packet.Data = OffsetPtr; + Packet.FrameExtent = Length; + + if (DeviceType == WAVE_OUT_DEVICE_TYPE) + { + Packet.DataUsed = Length; + } + + Result = SyncOverlappedDeviceIoControl(SoundDeviceInstance->Handle, + IOCTL_KS_WRITE_STREAM, + NULL, + 0, + &Packet, + sizeof(KSSTREAM_HEADER), + &Length); + + /* FIXXXXXME + * don't call completion routine directly + */ + CompletionRoutine(ERROR_SUCCESS, Length, (LPOVERLAPPED)Overlap); + + return MMSYSERR_NOERROR; +} diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index 99c78ac188b..15f6983f715 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -14,307 +14,7 @@ #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( @@ -327,605 +27,8 @@ QueryWdmWaveDeviceFormatSupport( } -DWORD -WINAPI -MixerEventThreadRoutine( - LPVOID Parameter) -{ - HANDLE WaitObjects[2]; - DWORD dwResult; - MMRESULT Result; - WDMAUD_DEVICE_INFO DeviceInfo; - PSOUND_DEVICE_INSTANCE Instance = (PSOUND_DEVICE_INSTANCE)Parameter; - - /* setup wait objects */ - WaitObjects[0] = Instance->hNotifyEvent; - WaitObjects[1] = Instance->hStopEvent; - - /* zero device info */ - ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); - - DeviceInfo.hDevice = Instance->Handle; - DeviceInfo.DeviceType = MIXER_DEVICE_TYPE; - - do - { - dwResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE); - - if (dwResult == WAIT_OBJECT_0 + 1) - { - /* stop event was signalled */ - break; - } - - do - { - Result = SyncOverlappedDeviceIoControl(KernelHandle, - IOCTL_GET_MIXER_EVENT, - (LPVOID) &DeviceInfo, - sizeof(WDMAUD_DEVICE_INFO), - (LPVOID) &DeviceInfo, - sizeof(WDMAUD_DEVICE_INFO), - NULL); - - if (Result == MMSYSERR_NOERROR) - { - DriverCallback(Instance->WinMM.ClientCallback, - HIWORD(Instance->WinMM.Flags), - Instance->WinMM.Handle, - DeviceInfo.u.MixerEvent.NotificationType, - Instance->WinMM.ClientCallbackInstanceData, - (DWORD_PTR)DeviceInfo.u.MixerEvent.Value, - 0); - } - }while(Result == MMSYSERR_NOERROR); - }while(TRUE); - - /* done */ - return 0; -} - - -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 -WriteFileEx_Committer2( - IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, - IN PVOID OffsetPtr, - IN DWORD Length, - IN PSOUND_OVERLAPPED Overlap, - IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine) -{ - HANDLE Handle; - MMRESULT Result; - WDMAUD_DEVICE_INFO DeviceInfo; - PSOUND_DEVICE SoundDevice; - MMDEVICE_TYPE DeviceType; - BOOL Ret; - - VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance ); - VALIDATE_MMSYS_PARAMETER( OffsetPtr ); - VALIDATE_MMSYS_PARAMETER( Overlap ); - VALIDATE_MMSYS_PARAMETER( CompletionRoutine ); - - GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); - - - Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); - - if ( ! MMSUCCESS(Result) ) - { - return TranslateInternalMmResult(Result); - } - - Result = GetSoundDeviceType(SoundDevice, &DeviceType); - SND_ASSERT( Result == MMSYSERR_NOERROR ); - - SND_ASSERT(Handle); - - ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); - - DeviceInfo.Header.FrameExtent = Length; - if (DeviceType == WAVE_OUT_DEVICE_TYPE) - { - DeviceInfo.Header.DataUsed = Length; - } - DeviceInfo.Header.Data = OffsetPtr; - DeviceInfo.Header.Size = sizeof(WDMAUD_DEVICE_INFO); - DeviceInfo.Header.PresentationTime.Numerator = 1; - DeviceInfo.Header.PresentationTime.Denominator = 1; - DeviceInfo.hDevice = Handle; - DeviceInfo.DeviceType = DeviceType; - - Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); - - if (DeviceType == WAVE_OUT_DEVICE_TYPE) - { - Ret = WriteFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine); - if (Ret) - WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); - } - else if (DeviceType == WAVE_IN_DEVICE_TYPE) - { - Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine); - //if (Ret) - // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); - } - - 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; @@ -934,10 +37,13 @@ PopulateWdmDeviceList( MMFUNCTION_TABLE FuncTable; DWORD i; - VALIDATE_MMSYS_PARAMETER( Handle != INVALID_HANDLE_VALUE ); VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) ); - Result = GetNumWdmDevs(Handle, DeviceType, &DeviceCount); +#ifdef USE_MMIXER_LIB + Result = WdmAudGetNumDevsByMMixer(DeviceType, &DeviceCount); +#else + Result = WdmAudGetNumWdmDevsByLegacy(DeviceType, &DeviceCount); +#endif if ( ! MMSUCCESS(Result) ) { @@ -960,33 +66,52 @@ PopulateWdmDeviceList( /* Set up our function table */ ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE)); - FuncTable.GetCapabilities = GetWdmDeviceCapabilities; +#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.QueryWaveFormatSupport = QueryWdmWaveDeviceFormatSupport; if (DeviceType == MIXER_DEVICE_TYPE) { - FuncTable.SetWaveFormat = SetWdmMixerDeviceFormat; - FuncTable.QueryMixerInfo = QueryMixerInfo; - } - else - { - FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat; +#ifdef USE_MMIXER_LIB + FuncTable.SetWaveFormat = WdmAudSetMixerDeviceFormatByMMixer; + FuncTable.QueryMixerInfo = WdmAudQueryMixerInfoByMMixer; +#else + FuncTable.SetWaveFormat = WdmAudSetMixerDeviceFormatByLegacy; + FuncTable.QueryMixerInfo = WdmAudQueryMixerInfoByLegacy; +#endif } if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) { - FuncTable.SetState = SetWdmWaveState; - FuncTable.ResetStream = ResetStream; - } +#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 - FuncTable.Open = OpenWdmSoundDevice; - FuncTable.Close = CloseWdmSoundDevice; - FuncTable.GetDeviceInterfaceString = GetDeviceInterfaceString; -#ifndef USERMODE_MIXER - FuncTable.CommitWaveBuffer = WriteFileEx_Committer2; +#ifdef USE_MMIXER_LIB + FuncTable.CommitWaveBuffer = WdmAudCommitWaveBufferByMMixer; +#elif defined (USERMODE_MIXER) + FuncTable.CommitWaveBuffer = WriteFileEx_Remixer; #else - FuncTable.CommitWaveBuffer = WriteFileEx_Remixer; + FuncTable.CommitWaveBuffer = WriteFileEx_Committer2; #endif - FuncTable.GetPos = GetWdmPosition; + } SetSoundDeviceFunctionTable(SoundDevice, &FuncTable); } @@ -994,8 +119,6 @@ PopulateWdmDeviceList( return MMSYSERR_NOERROR; } - - LONG APIENTRY DriverProc( @@ -1011,7 +134,10 @@ DriverProc( { case DRV_LOAD : { +#ifndef USE_MMIXER_LIB HANDLE Handle; +#endif + SND_TRACE(L"DRV_LOAD\n"); Result = InitEntrypointMutexes(); @@ -1019,9 +145,14 @@ DriverProc( if ( ! MMSUCCESS(Result) ) return 0L; - OpenWdmSoundDevice(NULL, &Handle); - - if ( Handle == INVALID_HANDLE_VALUE ) +#ifdef USE_MMIXER_LIB + if (!WdmAudInitUserModeMixer()) + { + SND_ERR(L"Failed to initialize mmixer lib\n"); + return 0; + } +#else + if (WdmAudOpenSoundDeviceByLegacy() != MMSYSERR_NOERROR) { SND_ERR(L"Failed to open %s\n", KERNEL_DEVICE_NAME); CleanupEntrypointMutexes(); @@ -1030,15 +161,16 @@ DriverProc( return 0L; } +#endif /* Populate the device lists */ SND_TRACE(L"Populating device lists\n"); - 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); + 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); SND_TRACE(L"Initialisation complete\n"); @@ -1049,11 +181,11 @@ DriverProc( { SND_TRACE(L"DRV_FREE\n"); - if ( KernelHandle != INVALID_HANDLE_VALUE ) - { - CloseHandle(KernelHandle); - KernelHandle = INVALID_HANDLE_VALUE; - } +#ifdef USE_MMIXER_LIB + WdmAudCleanupMMixer(); +#else + WdmAudCleanupLegacy(); +#endif /* TODO: Clean up the path names! */ UnlistAllSoundDevices(); @@ -1107,9 +239,6 @@ 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 : diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.h b/reactos/dll/win32/wdmaud.drv/wdmaud.h index 38d92e81395..dd7b37b8e64 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.h +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.h @@ -27,43 +27,39 @@ ULONG WdmAudGetMixerCount(); MMRESULT -WdmAudGetMixerCapabilties( - IN ULONG DeviceId, - LPMIXERCAPSW Capabilities); +WdmAudGetNumDevsByMMixer( + IN MMDEVICE_TYPE DeviceType, + OUT DWORD* DeviceCount); MMRESULT -WdmAudGetWaveOutCapabilities( - IN ULONG DeviceId, - LPWAVEOUTCAPSW Capabilities); +WriteFileEx_Remixer( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + IN PVOID OffsetPtr, + IN DWORD Length, + IN PSOUND_OVERLAPPED Overlap, + IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine); MMRESULT -WdmAudGetWaveInCapabilities( - IN ULONG DeviceId, - LPWAVEINCAPSW Capabilities); +WdmAudGetCapabilitiesByMMixer( + IN PSOUND_DEVICE SoundDevice, + IN DWORD DeviceId, + OUT PVOID Capabilities, + IN DWORD CapabilitiesSize); MMRESULT -WdmAudCloseMixer( - IN HMIXER Handle, - IN HANDLE hNotifyEvent); +WdmAudOpenSoundDeviceByMMixer( + IN struct _SOUND_DEVICE* SoundDevice, + OUT PVOID* Handle); MMRESULT -WdmAudOpenMixer( - IN PHANDLE hMixer, - IN ULONG DeviceId, - IN HANDLE hNotifyEvent); - -MMRESULT -WdmAudOpenWave( - OUT PHANDLE hPin, - IN DWORD DeviceId, - IN PWAVEFORMATEX WaveFormat, - IN DWORD bWaveIn); - +WdmAudCloseSoundDeviceByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN PVOID Handle); MMRESULT WdmAudGetLineInfo( IN HANDLE hMixer, - IN LPMIXERLINE MixLine, + IN LPMIXERLINEW MixLine, IN ULONG Flags); MMRESULT @@ -84,4 +80,143 @@ WdmAudGetControlDetails( IN LPMIXERCONTROLDETAILS MixDetails, IN ULONG Flags); +MMRESULT +WdmAudSetWdmWaveDeviceFormatByMMixer( + IN PSOUND_DEVICE_INSTANCE Instance, + IN DWORD DeviceId, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize); + +MMRESULT +WdmAudGetDeviceInterfaceStringByMMixer( + IN MMDEVICE_TYPE DeviceType, + IN DWORD DeviceId, + IN LPWSTR Interface, + IN DWORD InterfaceLength, + OUT DWORD * InterfaceSize); + +MMRESULT +WdmAudSetMixerDeviceFormatByMMixer( + IN PSOUND_DEVICE_INSTANCE Instance, + IN DWORD DeviceId, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize); + +MMRESULT +WdmAudQueryMixerInfoByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN UINT uMsg, + IN LPVOID Parameter, + IN DWORD Flags); + +MMRESULT +WdmAudSetWdmWaveStateByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN BOOL bStart); + +MMRESULT +WdmAudResetStreamByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN MMDEVICE_TYPE DeviceType, + IN BOOLEAN bStartReset); + +MMRESULT +WdmAudGetWdmPositionByMMixer( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN MMTIME* Time); + +MMRESULT +WdmAudCommitWaveBufferByMMixer( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + IN PVOID OffsetPtr, + IN DWORD Length, + IN PSOUND_OVERLAPPED Overlap, + IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine); + +VOID +WdmAudCleanupMMixer(); + +/* legacy.c */ + +VOID +WdmAudCleanupLegacy(); + +MMRESULT +WdmAudGetCapabilitiesByLegacy( + IN PSOUND_DEVICE SoundDevice, + IN DWORD DeviceId, + OUT PVOID Capabilities, + IN DWORD CapabilitiesSize); + +MMRESULT +WdmAudOpenSoundDeviceByLegacy(); + +MMRESULT +WdmAudCloseSoundDeviceByLegacy( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN PVOID Handle); + +MMRESULT +WdmAudGetDeviceInterfaceStringByLegacy( + IN MMDEVICE_TYPE DeviceType, + IN DWORD DeviceId, + IN LPWSTR Interface, + IN DWORD InterfaceLength, + OUT DWORD * InterfaceSize); + +MMRESULT +WdmAudSetMixerDeviceFormatByLegacy( + IN PSOUND_DEVICE_INSTANCE Instance, + IN DWORD DeviceId, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize); + +MMRESULT +WdmAudQueryMixerInfoByLegacy( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN UINT uMsg, + IN LPVOID Parameter, + IN DWORD Flags); + +MMRESULT +WdmAudSetWaveDeviceFormatByLegacy( + IN PSOUND_DEVICE_INSTANCE Instance, + IN DWORD DeviceId, + IN PWAVEFORMATEX WaveFormat, + IN DWORD WaveFormatSize); + +MMRESULT +WdmAudSetWaveStateByLegacy( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN BOOL bStart); + +MMRESULT +WdmAudResetStreamByLegacy( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN MMDEVICE_TYPE DeviceType, + IN BOOLEAN bStartReset); + +MMRESULT +WdmAudGetWavePositionByLegacy( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN MMTIME* Time); + +MMRESULT +WriteFileEx_Committer2( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + IN PVOID OffsetPtr, + IN DWORD Length, + IN PSOUND_OVERLAPPED Overlap, + IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine); + +MMRESULT +WdmAudGetNumWdmDevsByLegacy( + IN MMDEVICE_TYPE DeviceType, + OUT DWORD* DeviceCount); + +DWORD +WINAPI +MixerEventThreadRoutine( + LPVOID Parameter); + #endif diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.rbuild b/reactos/dll/win32/wdmaud.drv/wdmaud.rbuild index 360eb614e7b..69b1f5729ed 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.rbuild +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.rbuild @@ -5,8 +5,8 @@ . . . - 1 - + + mmebuddy ntdll user32 @@ -20,5 +20,6 @@ wdmaud.c mixer.c mmixer.c + legacy.c wdmaud.rc