X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdll%2Fwin32%2Fwdmaud.drv%2Fwdmaud.c;h=2db6c0e48c9d341ebea6a74e4da431406b811891;hp=2cf107bd6c41334420cb93248cc2a68da4e60690;hb=09bf249e9deb9055ff0fe63ab02e227d7ef088b7;hpb=ba52cb038d84e6a9fd9adda97ba85f1fb7120dbd diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index 2cf107bd6c4..2db6c0e48c9 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -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,52 +838,33 @@ 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 + FuncTable.SetState = SetWdmWaveState; + FuncTable.ResetStream = ResetStream; + } -#ifdef USE_MMIXER_LIB - FuncTable.CommitWaveBuffer = WdmAudCommitWaveBufferByMMixer; -#elif defined (USERMODE_MIXER) - FuncTable.CommitWaveBuffer = WriteFileEx_Remixer; + FuncTable.Open = OpenWdmSoundDevice; + FuncTable.Close = CloseWdmSoundDevice; + FuncTable.GetDeviceInterfaceString = GetDeviceInterfaceString; +#ifndef USERMODE_MIXER + FuncTable.CommitWaveBuffer = WriteFileEx_Committer2; #else - FuncTable.CommitWaveBuffer = WriteFileEx_Committer2; + FuncTable.CommitWaveBuffer = WriteFileEx_Remixer; #endif - } + FuncTable.GetPos = GetWdmPosition; SetSoundDeviceFunctionTable(SoundDevice, &FuncTable); } @@ -119,6 +872,8 @@ PopulateWdmDeviceList( 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 :