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 SetNt4WaveDeviceFormat( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN DWORD DeviceId, IN LPWAVEFORMATEX Format, IN DWORD FormatSize) { MMRESULT Result; HANDLE Handle; VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) ); VALIDATE_MMSYS_PARAMETER( Format ); VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) ); Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); SND_TRACE(L"Setting wave device format on handle %x\n", Handle); Result = SyncOverlappedDeviceIoControl(Handle, IOCTL_WAVE_SET_FORMAT, (LPVOID) Format, FormatSize, NULL, 0, NULL); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); return MMSYSERR_NOERROR; }
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 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 DestroySoundDeviceInstance( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance) { MMRESULT Result; PMMFUNCTION_TABLE FunctionTable; PSOUND_DEVICE SoundDevice; PVOID Handle; SND_TRACE(L"Destroying a sound device instance\n"); VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) ); Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); /* Get the "close" routine from the function table, and validate it */ Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); SND_ASSERT( FunctionTable->Close ); if ( FunctionTable->Close == NULL ) { /* This indicates bad practice, really! If you can open, why not close?! */ return MMSYSERR_NOTSUPPORTED; } /* Stop the streaming thread */ if ( SoundDeviceInstance->Thread ) { Result = DestroySoundThread(SoundDeviceInstance->Thread); SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */ if ( ! MMSUCCESS(Result ) ) { return TranslateInternalMmResult(Result); } } /* Blank this out here */ SoundDeviceInstance->Thread = NULL; /* Try and close the device */ Result = FunctionTable->Close(SoundDeviceInstance, Handle); SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */ if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); /* Drop it from the list */ Result = UnlistSoundDeviceInstance(SoundDeviceInstance); SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */ if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); FreeSoundDeviceInstance(SoundDeviceInstance); return MMSYSERR_NOERROR; }
MMRESULT WdmAudQueryMixerInfoByLegacy( IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, IN DWORD DeviceId, 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.DeviceIndex = DeviceId; 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; }
MMRESULT WdmAudCommitWaveBufferByLegacy( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID OffsetPtr, IN DWORD Length, IN PSOUND_OVERLAPPED Overlap, IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine) { HANDLE Handle; MMRESULT Result; PWDMAUD_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); SND_ASSERT(Handle); Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); if ( ! MMSUCCESS(Result) ) { return TranslateInternalMmResult(Result); } Result = GetSoundDeviceType(SoundDevice, &DeviceType); SND_ASSERT( Result == MMSYSERR_NOERROR ); DeviceInfo = (PWDMAUD_DEVICE_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WDMAUD_DEVICE_INFO)); if (!DeviceInfo) { // no memory return MMSYSERR_NOMEM; } 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; // create completion event Overlap->Standard.hEvent = Handle = CreateEventW(NULL, FALSE, FALSE, NULL); if (Overlap->Standard.hEvent == NULL) { // no memory HeapFree(GetProcessHeap(), 0, DeviceInfo); return MMSYSERR_NOMEM; } Overlap->OriginalCompletionRoutine = CompletionRoutine; Overlap->CompletionContext = (PVOID)DeviceInfo; if (DeviceType == WAVE_OUT_DEVICE_TYPE) { Ret = WriteFileEx(KernelHandle, DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, LegacyCompletionRoutine); if (Ret) WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); } else if (DeviceType == WAVE_IN_DEVICE_TYPE) { Ret = ReadFileEx(KernelHandle, DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, LegacyCompletionRoutine); if (Ret) WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); } // close event handle CloseHandle(Handle); return MMSYSERR_NOERROR; }