[WDMAUD.DRV]

- Implement copying mixer capabilities
[WDMAUD_KERNEL]
- Partly implement retrieving mixer capabilties
- Implement retrieving mixer name

svn path=/trunk/; revision=43138
This commit is contained in:
Johannes Anderwald 2009-09-24 19:24:22 +00:00
parent c17e7adfbd
commit 0cb3d8ff11
5 changed files with 172 additions and 9 deletions

View file

@ -125,6 +125,19 @@ GetWdmDeviceCapabilities(
/* This is pretty much a big hack right now */
switch ( DeviceType )
{
case MIXER_DEVICE_TYPE:
{
LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities;
CopyWideString(MixerCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
MixerCaps->cDestinations = DeviceInfo.u.MixCaps.cDestinations;
MixerCaps->fdwSupport = DeviceInfo.u.MixCaps.fdwSupport;
MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion;
MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid;
MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid;
break;
}
case WAVE_OUT_DEVICE_TYPE :
{
LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;

View file

@ -706,6 +706,13 @@ WdmAudCapabilities(
DPRINT("WdmAudCapabilities entered\n");
if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
Status = WdmAudMixerCapabilities(DeviceObject, DeviceInfo, ClientInfo);
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
if (!NT_SUCCESS(Status))
{

View file

@ -34,6 +34,7 @@ typedef struct
union
{
MIXERCAPSW MixCaps;
MIXERCONTROLDETAILS MixDetails;
MIXERLINECONTROLSW MixControls;
MIXERLINEW MixLine;

View file

@ -36,14 +36,11 @@ GetSysAudioDeviceCount(
}
NTSTATUS
OpenSysAudioDeviceByIndex(
GetSysAudioDevicePnpName(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG DeviceIndex,
IN PHANDLE DeviceHandle,
IN PFILE_OBJECT * FileObject)
OUT LPWSTR * Device)
{
LPWSTR Device;
HANDLE hDevice;
ULONG BytesReturned;
KSP_PIN Pin;
NTSTATUS Status;
@ -59,7 +56,6 @@ OpenSysAudioDeviceByIndex(
Pin.Property.Flags = KSPROPERTY_TYPE_GET;
Pin.PinId = DeviceIndex;
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* query sysaudio for the device path */
@ -70,20 +66,38 @@ OpenSysAudioDeviceByIndex(
return STATUS_UNSUCCESSFUL;
/* allocate buffer for the device */
Device = ExAllocatePool(NonPagedPool, BytesReturned);
*Device = ExAllocatePool(NonPagedPool, BytesReturned);
if (!Device)
return STATUS_INSUFFICIENT_RESOURCES;
/* query sysaudio again for the device path */
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), (PVOID)Device, BytesReturned, &BytesReturned);
Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), (PVOID)*Device, BytesReturned, &BytesReturned);
if (!NT_SUCCESS(Status))
{
/* failed */
ExFreePool(Device);
ExFreePool(*Device);
return Status;
}
return Status;
}
NTSTATUS
OpenSysAudioDeviceByIndex(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG DeviceIndex,
IN PHANDLE DeviceHandle,
IN PFILE_OBJECT * FileObject)
{
LPWSTR Device = NULL;
NTSTATUS Status;
HANDLE hDevice;
Status = GetSysAudioDevicePnpName(DeviceObject, DeviceIndex, &Device);
if (!NT_SUCCESS(Status))
return Status;
/* now open the device */
Status = WdmAudOpenSysAudioDevice(Device, &hDevice);
@ -228,6 +242,122 @@ GetNumOfMixerDevices(
return Count;
}
ULONG
IsOutputMixer(
IN PDEVICE_OBJECT DeviceObject,
IN ULONG DeviceIndex)
{
ULONG DeviceCount, Index, Count;
NTSTATUS Status;
HANDLE hDevice;
PFILE_OBJECT FileObject;
PKSMULTIPLE_ITEM MultipleItem;
/* get number of devices */
DeviceCount = GetSysAudioDeviceCount(DeviceObject);
if (!DeviceCount)
return 0;
Index = 0;
Count = 0;
do
{
/* open the virtual audio device */
Status = OpenSysAudioDeviceByIndex(DeviceObject, Index, &hDevice, &FileObject);
if (NT_SUCCESS(Status))
{
/* retrieve all available node types */
Status = GetFilterNodeTypes(FileObject, &MultipleItem);
if (NT_SUCCESS(Status))
{
if (CountNodeType(MultipleItem, (LPGUID)&KSNODETYPE_DAC))
{
/* increment (output) mixer count */
if (DeviceIndex == Count)
{
ExFreePool(MultipleItem);
ObDereferenceObject(FileObject);
ZwClose(hDevice);
return TRUE;
}
Count++;
}
if (CountNodeType(MultipleItem, (LPGUID)&KSNODETYPE_ADC))
{
/* increment (input) mixer count */
if (DeviceIndex == Count)
{
ExFreePool(MultipleItem);
ObDereferenceObject(FileObject);
ZwClose(hDevice);
return FALSE;
}
Count++;
}
ExFreePool(MultipleItem);
}
ObDereferenceObject(FileObject);
ZwClose(hDevice);
}
Index++;
}while(Index < DeviceCount);
ASSERT(0);
return FALSE;
}
NTSTATUS
WdmAudMixerCapabilities(
IN PDEVICE_OBJECT DeviceObject,
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo)
{
NTSTATUS Status;
LPWSTR Device;
WCHAR Buffer[100];
Status = GetSysAudioDevicePnpName(DeviceObject, DeviceInfo->DeviceIndex,&Device);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get device name %x\n", Status);
return Status;
}
DeviceInfo->u.MixCaps.cDestinations = 1; //FIXME
Status = FindProductName(Device, sizeof(Buffer) / sizeof(WCHAR), Buffer);
/* check for success */
if (!NT_SUCCESS(Status))
{
DeviceInfo->u.MixCaps.szPname[0] = L'\0';
}
else
{
if (IsOutputMixer(DeviceObject, DeviceInfo->DeviceIndex))
{
wcscat(Buffer, L" output");
}
else
{
wcscat(Buffer, L" Input");
}
RtlMoveMemory(DeviceInfo->u.MixCaps.szPname, Buffer, min(MAXPNAMELEN, wcslen(Buffer)+1) * sizeof(WCHAR));
DeviceInfo->u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
}
return Status;
}
NTSTATUS
WdmAudControlOpenMixer(
IN PDEVICE_OBJECT DeviceObject,

View file

@ -108,4 +108,16 @@ WdmAudOpenSysAudioDevice(
IN LPWSTR DeviceName,
OUT PHANDLE Handle);
NTSTATUS
FindProductName(
IN LPWSTR PnpName,
IN ULONG ProductNameSize,
OUT LPWSTR ProductName);
NTSTATUS
WdmAudMixerCapabilities(
IN PDEVICE_OBJECT DeviceObject,
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo);
#endif