diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index 9b06369f477..9a188bb150f 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -281,24 +281,7 @@ SetWdmMixerDeviceFormat( 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) { @@ -307,11 +290,8 @@ SetWdmMixerDeviceFormat( } - Result = GetSoundDeviceType(SoundDevice, &DeviceType); - SND_ASSERT( Result == MMSYSERR_NOERROR ); - ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); - DeviceInfo.DeviceType = DeviceType; + DeviceInfo.DeviceType = MIXER_DEVICE_TYPE; DeviceInfo.DeviceIndex = DeviceId; Result = SyncOverlappedDeviceIoControl(KernelHandle, @@ -539,6 +519,82 @@ GetWdmPosition( return MMSYSERR_NOERROR; } +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; + + 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); + } + + Result = SyncOverlappedDeviceIoControl(KernelHandle, + IoControlCode, + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + NULL); + + if ( ! MMSUCCESS(Result) ) + { + return TranslateInternalMmResult(Result); + } + + switch(uMsg) + { + case MXDM_GETLINEINFO: + { + RtlCopyMemory(MixLine, &DeviceInfo.u.MixLine, sizeof(MIXERLINEW)); + break; + } + } + + return Result; +} + MMRESULT PopulateWdmDeviceList( @@ -582,6 +638,7 @@ PopulateWdmDeviceList( if (DeviceType == MIXER_DEVICE_TYPE) { FuncTable.SetWaveFormat = SetWdmMixerDeviceFormat; + FuncTable.QueryMixerInfo = QueryMixerInfo; } else { diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 3b34803a15c..ada2f2d188f 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -943,6 +943,15 @@ WdmAudDeviceControl( return WdmAudIoctlClose(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_GETFRAMESIZE: return WdmAudFrameSize(DeviceObject, Irp, DeviceInfo, ClientInfo); + case IOCTL_GETLINEINFO: + return WdmAudGetLineInfo(DeviceObject, Irp, DeviceInfo, ClientInfo); + case IOCTL_GETLINECONTROLS: + return WdmAudGetLineControls(DeviceObject, Irp, DeviceInfo, ClientInfo); + case IOCTL_SETCONTROLDETAILS: + return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo); + case IOCTL_GETCONTROLDETAILS: + return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo); + 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 9721ddd0974..fa7e416613c 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h @@ -31,6 +31,7 @@ typedef struct HANDLE hDevice; ULONG DeviceCount; + ULONG Flags; union { @@ -242,5 +243,74 @@ typedef struct METHOD_BUFFERED, \ FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) +/// IOCTL_GETLINEINFO +/// +/// Description: This IOCTL retrieves information on a mixerline +/// +/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, +/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure +/// Note: The hDevice member must be set +/// Result: The result is returned in MixLine +/// ReturnCode: STATUS_SUCCESS indicates success +/// Prequsites: opened device + +#define IOCTL_GETLINEINFO \ + CTL_CODE(FILE_DEVICE_SOUND, \ + 11, \ + METHOD_BUFFERED, \ + FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) + + +/// IOCTL_GETLINECONTROLS +/// +/// Description: This IOCTL retrieves controls of a mixerline +/// +/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, +/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure +/// Note: The hDevice member must be set +/// Result: The result is returned in MixControls +/// ReturnCode: STATUS_SUCCESS indicates success +/// Prequsites: opened device + +#define IOCTL_GETLINECONTROLS \ + CTL_CODE(FILE_DEVICE_SOUND, \ + 12, \ + METHOD_BUFFERED, \ + FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) + + +/// IOCTL_SETCONTROLDETAILS +/// +/// Description: This IOCTL sets details of a control of a mixerline +/// +/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, +/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure +/// Note: The hDevice member must be set +/// ReturnCode: STATUS_SUCCESS indicates success +/// Prequsites: opened device + +#define IOCTL_SETCONTROLDETAILS \ + CTL_CODE(FILE_DEVICE_SOUND, \ + 13, \ + METHOD_BUFFERED, \ + FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) + + +/// IOCTL_GETCONTROLDETAILS +/// +/// Description: This IOCTL gets details of a control of a mixerline +/// +/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, +/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure +/// Note: The hDevice member must be set +/// Result: The result is returned in MixDetails +/// ReturnCode: STATUS_SUCCESS indicates success +/// Prequsites: opened device + +#define IOCTL_GETCONTROLDETAILS \ + CTL_CODE(FILE_DEVICE_SOUND, \ + 14, \ + 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 4e10888b62d..5d5953ff2fb 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -190,6 +190,29 @@ CountNodeType( return Count; } +ULONG +GetNodeTypeIndex( + PKSMULTIPLE_ITEM MultipleItem, + LPGUID NodeType) +{ + ULONG Index; + LPGUID Guid; + + Guid = (LPGUID)(MultipleItem+1); + + /* iterate through node type array */ + for(Index = 0; Index < MultipleItem->Count; Index++) + { + if (IsEqualGUIDAligned(NodeType, Guid)) + { + /* found matching guid */ + return Index; + } + Guid++; + } + return (ULONG)-1; +} + ULONG GetNumOfMixerDevices( IN PDEVICE_OBJECT DeviceObject) @@ -314,6 +337,7 @@ IsOutputMixer( + NTSTATUS WdmAudMixerCapabilities( IN PDEVICE_OBJECT DeviceObject, @@ -410,3 +434,59 @@ WdmAudControlOpenMixer( return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); } +NTSTATUS +NTAPI +WdmAudGetLineInfo( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + UNIMPLEMENTED; + //DbgBreakPoint(); + return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0); + +} + +NTSTATUS +NTAPI +WdmAudGetLineControls( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + UNIMPLEMENTED; + //DbgBreakPoint(); + return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0); + +} + +NTSTATUS +NTAPI +WdmAudSetControlDetails( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + UNIMPLEMENTED; + //DbgBreakPoint(); + return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0); + +} + +NTSTATUS +NTAPI +WdmAudGetControlDetails( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + UNIMPLEMENTED; + //DbgBreakPoint(); + return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0); + +} + diff --git a/reactos/include/reactos/libs/sound/mmebuddy.h b/reactos/include/reactos/libs/sound/mmebuddy.h index ae68c161d06..f8b2d8d57ae 100644 --- a/reactos/include/reactos/libs/sound/mmebuddy.h +++ b/reactos/include/reactos/libs/sound/mmebuddy.h @@ -197,6 +197,11 @@ typedef MMRESULT (*WAVE_COMMIT_FUNC)( IN PSOUND_OVERLAPPED Overlap, IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine); +typedef MMRESULT (*MMMIXERQUERY_FUNC) ( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN UINT uMsg, + IN LPVOID Parameter, + IN DWORD Flags); typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC)( @@ -248,6 +253,8 @@ typedef struct _MMFUNCTION_TABLE MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport; MMWAVESETFORMAT_FUNC SetWaveFormat; + MMMIXERQUERY_FUNC QueryMixerInfo; + WAVE_COMMIT_FUNC CommitWaveBuffer; MMGETPOS_FUNC GetPos; diff --git a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c index 2050dd4c1a2..7e25ac9e678 100644 --- a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c @@ -18,6 +18,39 @@ #undef NDEBUG #include +MMRESULT +MmeGetLineInfo( + IN DWORD Message, + IN DWORD PrivateHandle, + IN DWORD Parameter1, + IN DWORD Parameter2) +{ + MMRESULT Result; + PSOUND_DEVICE_INSTANCE SoundDeviceInstance; + PSOUND_DEVICE SoundDevice; + PMMFUNCTION_TABLE FunctionTable; + + SND_TRACE(L"Getting mixer info %u\n", Message); + + 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, Message, (LPVOID)Parameter1, Parameter2); + + return Result; +} + MMRESULT MmeCloseMixerDevice( @@ -172,21 +205,41 @@ mxdMessage( case MXDM_GETCONTROLDETAILS : { + Result = MmeGetLineInfo(Message, + PrivateHandle, + Parameter1, + Parameter2); + break; } case MXDM_SETCONTROLDETAILS : { + Result = MmeGetLineInfo(Message, + PrivateHandle, + Parameter1, + Parameter2); + break; } case MXDM_GETLINECONTROLS : { + Result = MmeGetLineInfo(Message, + PrivateHandle, + Parameter1, + Parameter2); + break; } case MXDM_GETLINEINFO : { + Result = MmeGetLineInfo(Message, + PrivateHandle, + Parameter1, + Parameter2); + break; } }