From 47b50e1e0b4ece2eb2ed5aa193819f8fd21200b0 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 26 Oct 2009 23:10:05 +0000 Subject: [PATCH] [WDMAUD.DRV][WDMAUD_KERNEL][MMEBUDDY] - Implement support for DRV_QUERYDEVICEINTERFACESIZE, DRV_QUERYDEVICEINTERFACE - Required for DSound support svn path=/trunk/; revision=43788 --- reactos/dll/win32/wdmaud.drv/wdmaud.c | 59 ++++++++++ .../drivers/wdm/audio/legacy/wdmaud/control.c | 106 ++++++++++++++++++ .../wdm/audio/legacy/wdmaud/interface.h | 23 ++++ .../drivers/wdm/audio/legacy/wdmaud/mixer.c | 1 + .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 15 ++- reactos/include/reactos/libs/sound/mmebuddy.h | 18 +++ reactos/lib/drivers/sound/mmebuddy/mmewrap.c | 33 ++++++ .../drivers/sound/mmebuddy/wave/wodMessage.c | 12 ++ 8 files changed, 266 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index 27c38a5dac8..3378be68c0f 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -554,6 +554,64 @@ SetWdmWaveState( 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); + return Result; +} + MMRESULT GetWdmPosition( IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, @@ -734,6 +792,7 @@ PopulateWdmDeviceList( FuncTable.Open = OpenWdmSoundDevice; FuncTable.Close = CloseWdmSoundDevice; + FuncTable.GetDeviceInterfaceString = GetDeviceInterfaceString; #ifndef USERMODE_MIXER FuncTable.CommitWaveBuffer = WriteFileEx_Committer2; #else diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 73b4b7056a8..2bac8107ae2 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -203,6 +203,110 @@ WdmAudFrameSize( } +NTSTATUS +NTAPI +WdmAudGetDeviceInterface( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo) +{ + PWDMAUD_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + LPWSTR Device; + LPWAVE_INFO WaveInfo; + ULONG Size, Length; + + /* get device extension */ + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* get device interface string input length */ + Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize; + + if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE) + { + /* get wave info */ + Status = GetWaveInfoByIndexAndType(DeviceObject, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &WaveInfo); + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* invalid device id */ + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); + } + + Status = GetSysAudioDevicePnpName(DeviceObject, WaveInfo->FilterId, &Device); + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* invalid device id */ + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); + } + + /* calculate length */ + Length = (wcslen(Device)+1) * sizeof(WCHAR); + + if (!Size) + { + /* store device interface size */ + DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length; + } + else if (Size < Length) + { + /* buffer too small */ + DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length; + return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO)); + } + else + { + //FIXME SEH + RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length); + } + + ExFreePool(Device); + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); + } + else if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE) + { + if (DeviceInfo->DeviceIndex >= DeviceExtension->MixerInfoCount) + { + /* invalid device id */ + return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO)); + } + + Status = GetSysAudioDevicePnpName(DeviceObject, DeviceExtension->MixerInfo[DeviceInfo->DeviceIndex].DeviceIndex, &Device); + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* invalid device id */ + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); + } + + /* calculate length */ + Length = (wcslen(Device)+1) * sizeof(WCHAR); + + if (!Size) + { + /* store device interface size */ + DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length; + } + else if (Size < Length) + { + /* buffer too small */ + DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length; + return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO)); + } + else + { + //FIXME SEH + RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length); + } + + ExFreePool(Device); + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); + } + + return SetIrpIoStatus(Irp, STATUS_INVALID_DEVICE_REQUEST, sizeof(WDMAUD_DEVICE_INFO)); +} NTSTATUS NTAPI @@ -266,6 +370,8 @@ WdmAudDeviceControl( return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_GETCONTROLDETAILS: return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo); + case IOCTL_QUERYDEVICEINTERFACESTRING: + return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo); case IOCTL_GETPOS: case IOCTL_GETDEVID: case IOCTL_GETVOLUME: diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h index fa7e416613c..44eef61c028 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h @@ -44,6 +44,11 @@ typedef struct AUXCAPSW AuxCaps; WAVEINCAPSW WaveInCaps; ULONGLONG Position; + struct + { + LPWSTR DeviceInterfaceString; + ULONG DeviceInterfaceStringSize; + }Interface; KSSTATE State; ULONG Volume; ULONG FrameSize; @@ -313,4 +318,22 @@ typedef struct METHOD_BUFFERED, \ FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) + +/// IOCTL_QUERYDEVICEINTERFACESTRING +/// +/// Description: This IOCTL queries the mixer / playback / recording device for its device interface string +/// +/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, +/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure +/// Note: The DeviceType, DeviceIndex must be set +/// Result: The size is returned in Interface.DeviceInterfaceStringSize and if a buffer is supplied in Interface.DeviceInterfaceString +/// the device interface string is stored +/// ReturnCode: STATUS_SUCCESS indicates success + +#define IOCTL_QUERYDEVICEINTERFACESTRING \ + CTL_CODE(FILE_DEVICE_SOUND, \ + 15, \ + METHOD_BUFFERED, \ + FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) + #endif diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c index db59c0b25a9..4229290a6d0 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -1536,6 +1536,7 @@ InitializeMixer( MixerInfo->MixCaps.vDriverVersion = 1; //FIXME MixerInfo->MixCaps.fdwSupport = 0; MixerInfo->MixCaps.cDestinations = 1; + MixerInfo->DeviceIndex = DeviceIndex; /* get target pnp name */ Status = GetSysAudioDevicePnpName(DeviceObject, DeviceIndex, &Device); diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 16f85991c1a..598d3747a4b 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -67,7 +67,7 @@ typedef struct typedef struct { MIXERCAPSW MixCaps; - + ULONG DeviceIndex; LIST_ENTRY LineList; ULONG ControlId; }MIXER_INFO, *LPMIXER_INFO; @@ -277,4 +277,17 @@ InsertPinHandle( IN ULONG FreeIndex); +NTSTATUS +GetWaveInfoByIndexAndType( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG DeviceIndex, + IN SOUND_DEVICE_TYPE DeviceType, + OUT LPWAVE_INFO *OutWaveInfo); + +NTSTATUS +GetSysAudioDevicePnpName( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG DeviceIndex, + OUT LPWSTR * Device); + #endif diff --git a/reactos/include/reactos/libs/sound/mmebuddy.h b/reactos/include/reactos/libs/sound/mmebuddy.h index b8158005abe..b145c16b4d8 100644 --- a/reactos/include/reactos/libs/sound/mmebuddy.h +++ b/reactos/include/reactos/libs/sound/mmebuddy.h @@ -242,6 +242,14 @@ typedef MMRESULT(*MMSETSTATE_FUNC)( IN BOOL bStart); +typedef MMRESULT(*MMQUERYDEVICEINTERFACESTRING_FUNC)( + IN MMDEVICE_TYPE DeviceType, + IN DWORD DeviceId, + IN LPWSTR Interface, + IN DWORD InterfaceLength, + OUT DWORD * InterfaceSize); + + typedef struct _MMFUNCTION_TABLE { union @@ -265,6 +273,7 @@ typedef struct _MMFUNCTION_TABLE MMGETPOS_FUNC GetPos; MMSETSTATE_FUNC SetState; + MMQUERYDEVICEINTERFACESTRING_FUNC GetDeviceInterfaceString; // Redundant //MMWAVEHEADER_FUNC PrepareWaveHeader; @@ -414,6 +423,15 @@ MmeGetPosition( IN MMTIME* Time, IN DWORD Size); +MMRESULT +MmeGetDeviceInterfaceString( + IN MMDEVICE_TYPE DeviceType, + IN DWORD DeviceId, + IN LPWSTR Interface, + IN DWORD InterfaceLength, + OUT DWORD * InterfaceSize); + + MMRESULT MmeSetState( IN DWORD PrivateHandle, diff --git a/reactos/lib/drivers/sound/mmebuddy/mmewrap.c b/reactos/lib/drivers/sound/mmebuddy/mmewrap.c index f63e55a5ee2..63f3e6f5c5a 100644 --- a/reactos/lib/drivers/sound/mmebuddy/mmewrap.c +++ b/reactos/lib/drivers/sound/mmebuddy/mmewrap.c @@ -247,6 +247,39 @@ MmeResetWavePlayback( return StopStreaming(SoundDeviceInstance); } +MMRESULT +MmeGetDeviceInterfaceString( + IN MMDEVICE_TYPE DeviceType, + IN DWORD DeviceId, + IN LPWSTR Interface, + IN DWORD InterfaceLength, + OUT DWORD * InterfaceSize) +{ + MMRESULT Result; + PSOUND_DEVICE SoundDevice; + PMMFUNCTION_TABLE FunctionTable; + + Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice); + if ( ! MMSUCCESS(Result) ) + return TranslateInternalMmResult(Result); + + Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); + if ( ! MMSUCCESS(Result) ) + return TranslateInternalMmResult(Result); + + if ( FunctionTable->GetDeviceInterfaceString == NULL ) + { + /* querying device interface string / size not supported */ + return MMSYSERR_NOTSUPPORTED; + } + + /* Call the driver */ + Result = FunctionTable->GetDeviceInterfaceString(DeviceType, DeviceId, Interface, InterfaceLength, InterfaceSize); + + return Result; +} + + MMRESULT MmeGetPosition( IN MMDEVICE_TYPE DeviceType, diff --git a/reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c b/reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c index 108941ee764..de579f32200 100644 --- a/reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c @@ -117,6 +117,18 @@ wodMessage( Result = MmeGetPosition(WAVE_OUT_DEVICE_TYPE, DeviceId, PrivateHandle, (MMTIME*)Parameter1, Parameter2); break; } + + case DRV_QUERYDEVICEINTERFACESIZE : + { + Result = MmeGetDeviceInterfaceString(WAVE_OUT_DEVICE_TYPE, DeviceId, NULL, 0, (DWORD*)Parameter1); //FIXME DWORD_PTR + break; + } + + case DRV_QUERYDEVICEINTERFACE : + { + Result = MmeGetDeviceInterfaceString(WAVE_OUT_DEVICE_TYPE, DeviceId, (LPWSTR)Parameter1, Parameter2, NULL); //FIXME DWORD_PTR + break; + } } SND_TRACE(L"wodMessage returning MMRESULT %d\n", Result);