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,
FuncTable.Open = OpenWdmSoundDevice;
FuncTable.Close = CloseWdmSoundDevice;
+ FuncTable.GetDeviceInterfaceString = GetDeviceInterfaceString;
#ifndef USERMODE_MIXER
FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
#else
}
+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
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:
AUXCAPSW AuxCaps;
WAVEINCAPSW WaveInCaps;
ULONGLONG Position;
+ struct
+ {
+ LPWSTR DeviceInterfaceString;
+ ULONG DeviceInterfaceStringSize;
+ }Interface;
KSSTATE State;
ULONG Volume;
ULONG FrameSize;
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
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);
typedef struct
{
MIXERCAPSW MixCaps;
-
+ ULONG DeviceIndex;
LIST_ENTRY LineList;
ULONG ControlId;
}MIXER_INFO, *LPMIXER_INFO;
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
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
MMGETPOS_FUNC GetPos;
MMSETSTATE_FUNC SetState;
+ MMQUERYDEVICEINTERFACESTRING_FUNC GetDeviceInterfaceString;
// Redundant
//MMWAVEHEADER_FUNC PrepareWaveHeader;
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,
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,
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);