From 0cb3d8ff11deb22581a1f827687dc8ff6d1a74da Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Thu, 24 Sep 2009 19:24:22 +0000 Subject: [PATCH 1/1] [WDMAUD.DRV] - Implement copying mixer capabilities [WDMAUD_KERNEL] - Partly implement retrieving mixer capabilties - Implement retrieving mixer name svn path=/trunk/; revision=43138 --- reactos/dll/win32/wdmaud.drv/wdmaud.c | 13 ++ .../drivers/wdm/audio/legacy/wdmaud/control.c | 7 + .../wdm/audio/legacy/wdmaud/interface.h | 1 + .../drivers/wdm/audio/legacy/wdmaud/mixer.c | 148 ++++++++++++++++-- .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 12 ++ 5 files changed, 172 insertions(+), 9 deletions(-) diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index a4a0f7458d2..9b06369f477 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -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; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 1324462d03b..3b34803a15c 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -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)) { diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h index 0b31c7f1a5d..9721ddd0974 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h @@ -34,6 +34,7 @@ typedef struct union { + MIXERCAPSW MixCaps; MIXERCONTROLDETAILS MixDetails; MIXERLINECONTROLSW MixControls; MIXERLINEW MixLine; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c index 483de834659..4e10888b62d 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -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, diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index ae0b78220c1..9af9edd8b4f 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -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 -- 2.17.1