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)
{
}
- 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,
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(
if (DeviceType == MIXER_DEVICE_TYPE)
{
FuncTable.SetWaveFormat = SetWdmMixerDeviceFormat;
+ FuncTable.QueryMixerInfo = QueryMixerInfo;
}
else
{
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:
HANDLE hDevice;
ULONG DeviceCount;
+ ULONG Flags;
union
{
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
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)
+
NTSTATUS
WdmAudMixerCapabilities(
IN PDEVICE_OBJECT DeviceObject,
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);
+
+}
+
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)(
MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport;
MMWAVESETFORMAT_FUNC SetWaveFormat;
+ MMMIXERQUERY_FUNC QueryMixerInfo;
+
WAVE_COMMIT_FUNC CommitWaveBuffer;
MMGETPOS_FUNC GetPos;
#undef NDEBUG
#include <mmebuddy.h>
+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(
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;
}
}