MMRESULT WdmAudCommitWaveBufferByMMixer( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID OffsetPtr, IN DWORD Length, IN PSOUND_OVERLAPPED Overlap, IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine) { PSOUND_DEVICE SoundDevice; MMDEVICE_TYPE DeviceType; MMRESULT Result; LPIO_PACKET Packet; HANDLE hThread; Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); if ( ! MMSUCCESS(Result) ) { return TranslateInternalMmResult(Result); } Result = GetSoundDeviceType(SoundDevice, &DeviceType); SND_ASSERT( Result == MMSYSERR_NOERROR ); Packet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IO_PACKET)); if ( ! Packet ) { /* no memory */ return MMSYSERR_NOMEM; } /* setup stream packet */ Packet->Header.Size = sizeof(KSSTREAM_HEADER); Packet->Header.PresentationTime.Numerator = 1; Packet->Header.PresentationTime.Denominator = 1; Packet->Header.Data = OffsetPtr; Packet->Header.FrameExtent = Length; Packet->hDevice = SoundDeviceInstance->Handle; Packet->Overlap = Overlap; Packet->CompletionRoutine = CompletionRoutine; Packet->IoCtl = (DeviceType == WAVE_OUT_DEVICE_TYPE ? IOCTL_KS_WRITE_STREAM : IOCTL_KS_READ_STREAM); if (DeviceType == WAVE_OUT_DEVICE_TYPE) { Packet->Header.DataUsed = Length; } hThread = CreateThread(NULL, 0, IoStreamingThread, (LPVOID)Packet, 0, NULL); if (hThread == NULL) { /* error */ return MMSYSERR_ERROR; } CloseHandle(hThread); return MMSYSERR_NOERROR; }
MMRESULT WdmAudSetWaveStateByMMixer( IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, IN BOOL bStart) { MMDEVICE_TYPE DeviceType; PSOUND_DEVICE SoundDevice; MMRESULT Result; Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); SND_ASSERT( Result == MMSYSERR_NOERROR ); Result = GetSoundDeviceType(SoundDevice, &DeviceType); SND_ASSERT( Result == MMSYSERR_NOERROR ); if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) { 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); } } else if (DeviceType == MIDI_IN_DEVICE_TYPE || DeviceType == MIDI_OUT_DEVICE_TYPE) { if (bStart) { MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE); MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_PAUSE); MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_RUN); } else { MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_PAUSE); MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_ACQUIRE); MMixerSetMidiStatus(&MixerContext, SoundDeviceInstance->Handle, KSSTATE_STOP); } } return MMSYSERR_NOERROR; }
MMRESULT UnlistSoundDeviceInstance( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance) { MMRESULT Result; PSOUND_DEVICE SoundDevice; PSOUND_DEVICE_INSTANCE CurrentInstance, PreviousInstance; VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) ); SND_TRACE(L"Unlisting sound device instance\n"); Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); SND_ASSERT( MMSUCCESS(Result) ); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); PreviousInstance = NULL; CurrentInstance = SoundDevice->HeadInstance; while ( CurrentInstance ) { if ( CurrentInstance == SoundDeviceInstance ) { if ( ! PreviousInstance ) { /* This is the head node */ SoundDevice->HeadInstance = SoundDevice->HeadInstance->Next; } else { /* There are nodes before this one - cut ours out */ PreviousInstance->Next = CurrentInstance->Next; } if ( ! CurrentInstance->Next ) { /* This is the tail node */ SoundDevice->TailInstance = PreviousInstance; } } PreviousInstance = CurrentInstance; CurrentInstance = CurrentInstance->Next; } return MMSYSERR_NOERROR; }
MMRESULT MmeGetLineInfo( IN UINT DeviceId, IN UINT Message, IN DWORD_PTR PrivateHandle, IN DWORD_PTR Parameter1, IN DWORD_PTR Parameter2) { MMRESULT Result; PSOUND_DEVICE_INSTANCE SoundDeviceInstance; PSOUND_DEVICE SoundDevice; PMMFUNCTION_TABLE FunctionTable; //SND_TRACE(L"Getting mixer info %u\n", Message); if ( PrivateHandle == 0 ) { Result = GetSoundDevice(MIXER_DEVICE_TYPE, DeviceId, &SoundDevice); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); Result = FunctionTable->QueryMixerInfo(NULL, DeviceId, Message, (LPVOID)Parameter1, Parameter2); return Result; } VALIDATE_MMSYS_PARAMETER( PrivateHandle ); SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle; Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); if ( ! FunctionTable->QueryMixerInfo ) return MMSYSERR_NOTSUPPORTED; Result = FunctionTable->QueryMixerInfo(SoundDeviceInstance, DeviceId, Message, (LPVOID)Parameter1, Parameter2); 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 SetWaveDeviceFormat( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN DWORD DeviceId, IN LPWAVEFORMATEX Format, IN DWORD FormatSize) { MMRESULT Result; MMDEVICE_TYPE DeviceType; PMMFUNCTION_TABLE FunctionTable; PSOUND_DEVICE SoundDevice; SND_TRACE(L"Setting wave format\n"); VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) ); Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); Result = GetSoundDeviceType(SoundDevice, &DeviceType); SND_ASSERT( Result == MMSYSERR_NOERROR ); if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) { VALIDATE_MMSYS_PARAMETER( Format ); VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) ); } /* Ensure we have a wave device (TODO: check if this applies to wavein as well) */ VALIDATE_MMSYS_PARAMETER( IS_WAVE_DEVICE_TYPE(DeviceType) || IS_MIDI_DEVICE_TYPE(DeviceType) || IS_MIXER_DEVICE_TYPE(DeviceType)); /* Obtain the function table */ Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); SND_ASSERT( Result == MMSYSERR_NOERROR ); if ( ! MMSUCCESS(Result) ) return TranslateInternalMmResult(Result); if ( ! FunctionTable->SetWaveFormat ) return MMSYSERR_NOTSUPPORTED; return FunctionTable->SetWaveFormat(SoundDeviceInstance, DeviceId, Format, FormatSize); }
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 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 WdmAudSetWaveDeviceFormatByMMixer( IN PSOUND_DEVICE_INSTANCE Instance, IN DWORD DeviceId, IN PWAVEFORMATEX WaveFormat, IN DWORD WaveFormatSize) { MMDEVICE_TYPE DeviceType; PSOUND_DEVICE SoundDevice; MMRESULT Result; BOOL bWaveIn; Result = GetSoundDeviceFromInstance(Instance, &SoundDevice); if ( ! MMSUCCESS(Result) ) { 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, NULL, NULL, &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 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 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; }
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 != NULL) { /* 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 = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels); #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); } if (WaveFormatSize >= sizeof(WAVEFORMAT)) { /* Store format */ 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; } /* store details */ Instance->WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); Instance->WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels); /* 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; } /* Now acquire resources */ DeviceInfo.u.State = KSSTATE_ACQUIRE; SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); /* pause the pin */ DeviceInfo.u.State = KSSTATE_PAUSE; SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); /* start the pin */ 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 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_PAUSE; SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); DeviceInfo.u.State = KSSTATE_ACQUIRE; SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); 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; }