From fd1851d16a21ce5691e34bf963c15d513d0429a1 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 8 Jun 2009 21:37:20 +0000 Subject: [PATCH] - Fix a bug in KsTopologyPropertyHandler - Create a KSTOPOLOGY struct when creating the subdevice descriptor and pass the struct to KsTopologyPropertyHandler - Implement enumerating mixer devices - Change handle array to contain the target device type. Mixer handles are not real handles, they are just pseudo handles - Forward KSPROPSETID_Topology request to portcls (sysaudio) svn path=/trunk/; revision=41352 --- reactos/drivers/ksfilter/ks/topology.c | 4 +- .../wdm/audio/backpln/portcls/interfaces.h | 1 + .../audio/backpln/portcls/pin_wavecyclic.c | 4 +- .../audio/backpln/portcls/propertyhandler.c | 9 +- .../drivers/wdm/audio/backpln/portcls/undoc.c | 31 +++ .../drivers/wdm/audio/legacy/wdmaud/control.c | 29 ++- .../drivers/wdm/audio/legacy/wdmaud/entry.c | 4 +- .../drivers/wdm/audio/legacy/wdmaud/mixer.c | 209 ++++++++++++++++++ .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 25 ++- .../wdm/audio/legacy/wdmaud/wdmaud.rbuild | 1 + reactos/drivers/wdm/audio/sysaudio/control.c | 29 ++- 11 files changed, 324 insertions(+), 22 deletions(-) create mode 100644 reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c diff --git a/reactos/drivers/ksfilter/ks/topology.c b/reactos/drivers/ksfilter/ks/topology.c index 9ab60801728..21404d1b34e 100644 --- a/reactos/drivers/ksfilter/ks/topology.c +++ b/reactos/drivers/ksfilter/ks/topology.c @@ -162,7 +162,7 @@ KsTopologyPropertyHandler( break; case KSPROPERTY_TOPOLOGY_CONNECTIONS: - Size = sizeof(KSMULTIPLE_ITEM) + Topology->TopologyConnectionsCount * sizeof(GUID); + Size = sizeof(KSMULTIPLE_ITEM) + Topology->TopologyConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) { Irp->IoStatus.Information = Size; @@ -174,7 +174,7 @@ KsTopologyPropertyHandler( Item->Size = Size; Item->Count = Topology->TopologyConnectionsCount; - RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyConnections, Topology->TopologyConnectionsCount * sizeof(GUID)); + RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyConnections, Topology->TopologyConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION)); Irp->IoStatus.Information = Size; Status = STATUS_SUCCESS; break; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h index 8ac4647f5d9..77d98c31616 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h @@ -130,6 +130,7 @@ typedef struct KSPROPERTY_SET_LIST FilterPropertySet; PPCFILTER_DESCRIPTOR DeviceDescriptor; + KSTOPOLOGY* Topology; }SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR; #undef INTERFACE diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c index 36d7c60e54d..2cf58e87849 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c @@ -223,7 +223,7 @@ SetStreamWorkerRoutine( /* Set the state */ if (NT_SUCCESS(This->Stream->lpVtbl->SetState(This->Stream, State))) { - /* Set internal state to stop */ + /* Set internal state */ This->State = State; if (This->State == KSSTATE_STOP) @@ -913,7 +913,7 @@ IPortPinWaveCyclic_fnFastWrite( InterlockedIncrement((PLONG)&This->TotalPackets); - DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted); + DPRINT1("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted); Packet = (PCONTEXT_WRITE)Buffer; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c index bd002977388..7a174129bd6 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c @@ -353,10 +353,11 @@ TopologyPropertyHandler( IN PKSIDENTIFIER Request, IN OUT PVOID Data) { - return KsTopologyPropertyHandler(Irp, - Request, - Data, - NULL /* FIXME */); + PSUBDEVICE_DESCRIPTOR Descriptor; + + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + return KsTopologyPropertyHandler(Irp, Request, Data, Descriptor->Topology); } NTSTATUS diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.c b/reactos/drivers/wdm/audio/backpln/portcls/undoc.c index 315b4e5f556..e5dbb853722 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.c @@ -210,6 +210,37 @@ PcCreateSubdeviceDescriptor( } } + Descriptor->Topology = AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); + if (!Descriptor->Topology) + goto cleanup; + + if (FilterDescription->ConnectionCount) + { + Descriptor->Topology->TopologyConnections = AllocateItem(NonPagedPool, sizeof(PCCONNECTION_DESCRIPTOR) * FilterDescription->ConnectionCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyConnections) + goto cleanup; + + RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR)); + Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount; + } + + if (FilterDescription->NodeCount) + { + Descriptor->Topology->TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyNodes) + goto cleanup; + + Descriptor->Topology->TopologyNodesNames = AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyNodesNames) + goto cleanup; + + for(Index = 0; Index < FilterDescription->NodeCount; Index++) + { + RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID)); + RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID)); + } + Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount; + } if (FilterDescription->PinCount) { diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 579b8353f28..c713e55a38f 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -17,6 +17,7 @@ const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; +const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; NTSTATUS SetIrpIoStatus( @@ -146,6 +147,11 @@ WdmAudControlOpen( ULONG FilterId; ULONG PinId; + if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE) + { + return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo); + } + if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE) { DPRINT1("FIXME: only waveout / wavein devices are supported\n"); @@ -240,11 +246,11 @@ WdmAudControlOpen( Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned); if (NT_SUCCESS(Status)) { - PHANDLE Handels; + PWDMAUD_HANDLE Handels; for(Index = 0; Index < ClientInfo->NumPins; Index++) { - if (ClientInfo->hPins[Index] == PinHandle) + if (ClientInfo->hPins[Index].Handle == PinHandle) { /* the pin handle has been re-used */ DeviceInfo->hDevice = PinHandle; @@ -253,18 +259,19 @@ WdmAudControlOpen( } - Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumPins+1)); + Handels = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1)); if (Handels) { if (ClientInfo->NumPins) { - RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(HANDLE) * ClientInfo->NumPins); + RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins); ExFreePool(ClientInfo->hPins); } ClientInfo->hPins = Handels; - ClientInfo->hPins[ClientInfo->NumPins] = PinHandle; + ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle; + ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceInfo->DeviceType; ClientInfo->NumPins++; } DeviceInfo->hDevice = PinHandle; @@ -291,7 +298,13 @@ WdmAudControlDeviceType( KSPIN_DATAFLOW DataFlow; PWDMAUD_DEVICE_EXTENSION DeviceExtension; - if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE && DeviceInfo->DeviceType != MIXER_DEVICE_TYPE) + if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE) + { + DeviceInfo->DeviceCount = GetNumOfMixerDevices(DeviceObject); + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); + } + + if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE) { DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); @@ -563,11 +576,11 @@ WdmAudIoctlClose( for(Index = 0; Index < ClientInfo->NumPins; Index++) { - if (ClientInfo->hPins[Index] == DeviceInfo->hDevice) + if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE) { DPRINT1("Closing device %p\n", DeviceInfo->hDevice); ZwClose(DeviceInfo->hDevice); - ClientInfo->hPins[Index] = NULL; + ClientInfo->hPins[Index].Handle = NULL; SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); return STATUS_SUCCESS; } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c index 842bf26e2a0..281f25928da 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c @@ -204,9 +204,9 @@ WdmAudCleanup( { for (Index = 0; Index < pClient->NumPins; Index++) { - if (pClient->hPins[Index]) + if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE) { - ZwClose(pClient->hPins[Index]); + ZwClose(pClient->hPins[Index].Handle); } } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c new file mode 100644 index 00000000000..715342d52d9 --- /dev/null +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -0,0 +1,209 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/legacy/wdmaud/mixer.c + * PURPOSE: System Audio graph builder + * PROGRAMMER: Andrew Greenwood + * Johannes Anderwald + */ +#include "wdmaud.h" + +ULONG +IsVirtualDeviceATopologyFilter( + IN PDEVICE_OBJECT DeviceObject, + ULONG VirtualDeviceId) +{ + KSP_PIN Pin; + ULONG Count, BytesReturned, Index, NumPins; + NTSTATUS Status; + KSPIN_COMMUNICATION Communication; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; + ULONG MixerPinCount; + + Pin.Property.Set = KSPROPSETID_Sysaudio; + Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT; + Pin.Property.Flags = KSPROPERTY_TYPE_GET; + + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned); + if (!NT_SUCCESS(Status)) + return FALSE; + + if (VirtualDeviceId >= Count) + return FALSE; + + /* query number of pins */ + Pin.Reserved = VirtualDeviceId; // see sysaudio + Pin.Property.Flags = KSPROPERTY_TYPE_GET; + Pin.Property.Set = KSPROPSETID_Pin; + Pin.Property.Id = KSPROPERTY_PIN_CTYPES; + Pin.PinId = 0; + + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned); + if (!NT_SUCCESS(Status)) + return FALSE; + + /* enumerate now all pins */ + MixerPinCount = 0; + for(Index = 0; Index < NumPins; Index++) + { + Pin.PinId = Index; + Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION; + Communication = KSPIN_COMMUNICATION_NONE; + + /* get pin communication type */ + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); + if (NT_SUCCESS(Status)) + { + if (Communication == KSPIN_COMMUNICATION_NONE) + MixerPinCount++; + } + + } + + if (MixerPinCount == NumPins) + { + /* filter has no pins which can be instantiated -> topology filter */ + return TRUE; + } + + return FALSE; +} + +ULONG +GetNumOfMixerPinsFromTopologyFilter( + IN PDEVICE_OBJECT DeviceObject, + ULONG VirtualDeviceId) +{ + KSP_PIN Pin; + ULONG BytesReturned, Index, NumPins; + NTSTATUS Status; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; + PKSMULTIPLE_ITEM MultipleItem; + PKSTOPOLOGY_CONNECTION Conn; + + Pin.PinId = 0; + Pin.Reserved = VirtualDeviceId; + Pin.Property.Set = KSPROPSETID_Topology; + Pin.Property.Id = KSPROPERTY_TOPOLOGY_CONNECTIONS; + Pin.Property.Flags = KSPROPERTY_TYPE_GET; + + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + BytesReturned = 0; + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned); + + if (Status != STATUS_BUFFER_TOO_SMALL) + return 0; + + MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned); + if (!MultipleItem) + return 0; + + RtlZeroMemory(MultipleItem, BytesReturned); + + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned); + if (!NT_SUCCESS(Status)) + { + ExFreePool(MultipleItem); + return 0; + } + + Conn = (PKSTOPOLOGY_CONNECTION)(MultipleItem + 1); + NumPins = 0; + for (Index = 0; Index < MultipleItem->Count; Index++) + { + if (Conn[Index].ToNode == PCFILTER_NODE) + { + NumPins++; + } + } + + ExFreePool(MultipleItem); + return NumPins; +} + +ULONG +GetNumOfMixerDevices( + IN PDEVICE_OBJECT DeviceObject) +{ + KSP_PIN Pin; + ULONG Count, BytesReturned, Index, NumPins; + NTSTATUS Status; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; + + + Pin.Property.Set = KSPROPSETID_Sysaudio; + Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT; + Pin.Property.Flags = KSPROPERTY_TYPE_GET; + + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + Count = 0; + Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned); + if (!NT_SUCCESS(Status) || !Count) + return STATUS_UNSUCCESSFUL; + + NumPins = 0; + for(Index = 0; Index < Count; Index++) + { + if (IsVirtualDeviceATopologyFilter(DeviceObject, Index)) + { + NumPins += GetNumOfMixerPinsFromTopologyFilter(DeviceObject, Index); + } + } + + return NumPins; +} + +NTSTATUS +WdmAudControlOpenMixer( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + ULONG Index; + PWDMAUD_HANDLE Handels; + + if (DeviceInfo->DeviceIndex >= GetNumOfMixerDevices(DeviceObject)) + { + /* mixer index doesnt exist */ + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + + for(Index = 0; Index < ClientInfo->NumPins; Index++) + { + if (ClientInfo->hPins[Index].Handle == (HANDLE)DeviceInfo->DeviceIndex && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE) + { + /* re-use pseudo handle */ + DeviceInfo->hDevice = (HANDLE)DeviceInfo->DeviceIndex; + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); + } + } + + Handels = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1)); + + if (Handels) + { + if (ClientInfo->NumPins) + { + RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins); + ExFreePool(ClientInfo->hPins); + } + + ClientInfo->hPins = Handels; + ClientInfo->hPins[ClientInfo->NumPins].Handle = (HANDLE)DeviceInfo->DeviceIndex; + ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE; + ClientInfo->NumPins++; + } + else + { + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); + } + DeviceInfo->hDevice = (HANDLE)DeviceInfo->DeviceIndex; + + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); +} + diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 8b440d82c0d..64e3f650fa0 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -12,11 +12,18 @@ #include "interface.h" +typedef struct +{ + HANDLE Handle; + SOUND_DEVICE_TYPE Type; +}WDMAUD_HANDLE, *PWDMAUD_HANDLE; + + typedef struct { HANDLE hProcess; ULONG NumPins; - HANDLE * hPins; + WDMAUD_HANDLE * hPins; }WDMAUD_CLIENT, *PWDMAUD_CLIENT; @@ -83,5 +90,21 @@ WdmAudWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +NTSTATUS +WdmAudControlOpenMixer( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo); + +ULONG +GetNumOfMixerDevices( + IN PDEVICE_OBJECT DeviceObject); + +NTSTATUS +SetIrpIoStatus( + IN PIRP Irp, + IN NTSTATUS Status, + IN ULONG Length); #endif diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild index f912d02033b..fda6c011d24 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild @@ -10,5 +10,6 @@ control.c deviface.c entry.c + mixer.c wdmaud.rc diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index da9c3ca8f3c..12da3d4a221 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -13,6 +13,7 @@ const GUID KSPROPSETID_Sysaudio_Pin = {0xA3A53220L, 0xC6E4, 0x11D0, const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; @@ -137,7 +138,6 @@ GetListEntry( PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; PLIST_ENTRY SubEntry, Entry = Head->Flink; - DPRINT1("device index %u\n", Index); while(Entry != Head) { DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); @@ -158,8 +158,8 @@ GetListEntry( Entry = Entry->Flink; } - DPRINT1("Not Found index %u\n", Index); - DbgBreakPoint(); + DPRINT1("Not Found index %u\n", Index); + return NULL; } @@ -988,6 +988,8 @@ SysAudioHandleProperty( ULONG BytesReturned; PKSOBJECT_CREATE_ITEM CreateItem; UNICODE_STRING GuidString; + PKSP_PIN Pin; + /* access the create item */ CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); @@ -1007,6 +1009,27 @@ SysAudioHandleProperty( { return HandleSysAudioFilterPinProperties(Irp, Property, DeviceExtension); } + else if(IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Topology)) + { + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_PIN)) + { + /* too small buffer */ + return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSP_PIN)); + } + Pin = (PKSP_PIN)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Pin->Reserved); + ASSERT(Entry != NULL); + + /* forward request to the filter implementing the property */ + Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, + (PVOID)IoStack->Parameters.DeviceIoControl.Type3InputBuffer, + IoStack->Parameters.DeviceIoControl.InputBufferLength, + Irp->UserBuffer, + IoStack->Parameters.DeviceIoControl.OutputBufferLength, + &BytesReturned); + + return SetIrpIoStatus(Irp, Status, BytesReturned); + } else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio)) { if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID)