[WDMAUD.DRV][WDMAUD_KERNEL][MMEBUDDY]

- Implement support for DRV_QUERYDEVICEINTERFACESIZE, DRV_QUERYDEVICEINTERFACE
- Required for DSound support

svn path=/trunk/; revision=43788
This commit is contained in:
Johannes Anderwald 2009-10-26 23:10:05 +00:00
parent 48c283f6e6
commit 47b50e1e0b
8 changed files with 266 additions and 1 deletions

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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,

View file

@ -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,

View file

@ -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);