From f21af7347fa03230c1653ad95f48ac9f39eae6a0 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 29 Nov 2009 18:56:56 +0000 Subject: [PATCH] [WDMAUD_KERNEL] - Always set Mute control on first channel [PORTCLS] - Rewrite node property handling. Fixes lots of bugs and fixes all winmm_winetest mixer failures svn path=/trunk/; revision=44323 --- .../audio/backpln/portcls/pin_wavecyclic.cpp | 4 +- .../wdm/audio/backpln/portcls/undoc.cpp | 425 ++++++++++-------- .../drivers/wdm/audio/legacy/wdmaud/mixer.c | 2 +- 3 files changed, 253 insertions(+), 178 deletions(-) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index 71e7b33bb66..c1850b00dfe 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -1243,8 +1243,8 @@ CPortPinWaveCyclic::Init( m_Port = Port; m_Filter = Filter; - //DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); - //DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); + DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); + DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); return STATUS_SUCCESS; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp index 4e567d18aa8..45e11cf90c1 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -86,32 +86,150 @@ PcHandleDisableEventWithTable( return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock); } - NTSTATUS -NTAPI -PcHandlePropertyWithTable( - IN PIRP Irp, - IN ULONG PropertySetCount, - IN PKSPROPERTY_SET PropertySet, +PcHandleGuidNullRequest( + IN OUT PIRP Irp, IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) { - NTSTATUS Status; + PPCNODE_DESCRIPTOR Node; + PPCPROPERTY_ITEM PropertyItem; PIO_STACK_LOCATION IoStack; PKSP_NODE Property; + LPGUID Buffer; + ULONG Count = 0, SubIndex, Index; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + + // access property + Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) + { + // request is out of bounds + Irp->IoStatus.Information = 0; + return STATUS_INVALID_PARAMETER; + } + + Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); + + if (!Node->AutomationTable) + { + // request is out of bounds + Irp->IoStatus.Information = 0; + return STATUS_INVALID_PARAMETER; + } + + PC_ASSERT(Node->AutomationTable); + PC_ASSERT(Node->AutomationTable->PropertyCount); + PC_ASSERT(Node->AutomationTable->PropertyItemSize); + + Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; + for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) + { + BOOL Found = FALSE; + for (SubIndex = 0; SubIndex < Count; Index++) + { + if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set)) + { + Found = TRUE; + break; + } + } + if (!Found) + { + RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID)); + Count++; + } + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); + } + + // store result length + Irp->IoStatus.Information = sizeof (GUID) * Count; + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count) + { + // buffer too small + FreeItem(Buffer, TAG_PORTCLASS); + return STATUS_MORE_ENTRIES; + } + + RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count); + FreeItem(Buffer, TAG_PORTCLASS); + return STATUS_SUCCESS; +} + +NTSTATUS +PcFindNodePropertyHandler( + PIRP Irp, + PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, + OUT PPCPROPERTY_ITEM * OutPropertyItem) +{ PPCNODE_DESCRIPTOR Node; PPCPROPERTY_ITEM PropertyItem; + PIO_STACK_LOCATION IoStack; + PKSP_NODE Property; ULONG Index; - LPGUID Buffer; - //PULONG Flags; - PPCPROPERTY_REQUEST PropertyRequest; - KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // access property + Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) + { + // request is out of bounds + DPRINT("InvalidIndex %u %u\n", Property->NodeId, SubDeviceDescriptor->DeviceDescriptor->NodeCount); + return STATUS_INVALID_PARAMETER; + } + + Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); + + if (!Node->AutomationTable) + { + // request is out of bounds + Irp->IoStatus.Information = 0; + return STATUS_NOT_FOUND; + } - /* try first KsPropertyHandler */ - Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet); + // sanity checks + PC_ASSERT(Node->AutomationTable); + PC_ASSERT(Node->AutomationTable->PropertyCount); + PC_ASSERT(Node->AutomationTable->PropertyItemSize); - if (Status != STATUS_NOT_FOUND) - return Status; + PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; + + DPRINT("NodeId %u PropertyCount %u\n", Property->NodeId, Node->AutomationTable->PropertyCount); + for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) + { + if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id) + { + //found property handler + *OutPropertyItem = PropertyItem; + return STATUS_SUCCESS; + } + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); + } + + // no handler yet found + DPRINT("NotFound\n"); + return STATUS_NOT_FOUND; +} + +NTSTATUS +PcNodeBasicSupportHandler( + PIRP Irp, + PPCPROPERTY_ITEM PropertyItem) +{ + PULONG Flags; + PIO_STACK_LOCATION IoStack; + PKSPROPERTY_DESCRIPTION Description; + PKSP_NODE Property; // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -119,184 +237,141 @@ PcHandlePropertyWithTable( // access property Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - // check if this a GUID_NULL request - if (Status == STATUS_NOT_FOUND) + PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG)); + Flags= (PULONG)Irp->UserBuffer; + + // reset flags + *Flags = 0; + + if (PropertyItem->Flags & KSPROPERTY_TYPE_SET) + *Flags |= KSPROPERTY_TYPE_SET; + + if (PropertyItem->Flags & KSPROPERTY_TYPE_GET) + *Flags |= KSPROPERTY_TYPE_GET; + + // store result length + Irp->IoStatus.Information = sizeof(ULONG); + + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) { - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) - return Status; + // get output buffer + Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer; + + // store result + Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); + Description->PropTypeSet.Set = KSPROPTYPESETID_General; + Description->PropTypeSet.Id = 0; + Description->PropTypeSet.Flags = 0; + Description->MembersListCount = 0; + Description->Reserved = 0; + + Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION); + } + return STATUS_SUCCESS; +} - // check if its a request for a topology node - if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY)) - { - if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } - Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); +NTSTATUS +PcHandleNodePropertyRequest( + PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) +{ + PIO_STACK_LOCATION IoStack; + PPCPROPERTY_ITEM PropertyItem; + PPCPROPERTY_REQUEST PropertyRequest; + PKSP_NODE Property; + NTSTATUS Status; - if (!Node->AutomationTable) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) + { + // certainly not a node property request + return STATUS_NOT_FOUND; + } - Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS); - if (!Buffer) - return STATUS_INSUFFICIENT_RESOURCES; + // access property + Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY)) + { + return PcHandleGuidNullRequest(Irp, SubDeviceDescriptor); + } - ULONG Count = 0, SubIndex; - PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; - for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) - { - BOOL Found = FALSE; - for (SubIndex = 0; SubIndex < Count; Index++) - { - if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set)) - { - Found = TRUE; - break; - } - } - if (!Found) - { - RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID)); - Count++; - } - PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); - } + // find property handler + Status = PcFindNodePropertyHandler(Irp, SubDeviceDescriptor, &PropertyItem); - Irp->IoStatus.Information = sizeof (GUID) * Count; - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count) - { - // buffer too small - FreeItem(Buffer, TAG_PORTCLASS); - return STATUS_MORE_ENTRIES; - } + // check for success + if (!NT_SUCCESS(Status)) + { + // might not be a node property request + DPRINT("NotFound\n"); + return STATUS_NOT_FOUND; + } - RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count); - FreeItem(Buffer, TAG_PORTCLASS); - return STATUS_SUCCESS; - } - else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY) || - Property->Property.Flags == (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY) || - Property->Property.Flags == (KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY)) */ + if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) + { + // caller issued a basic property request + if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) { - //UNICODE_STRING GuidString; + // driver does not have a basic support handler + return PcNodeBasicSupportHandler(Irp, PropertyItem); + } + } - if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } + // allocate a property request + PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); + if (!PropertyRequest) + return STATUS_INSUFFICIENT_RESOURCES; - Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); + PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport; + PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream; + PropertyRequest->Irp = Irp; + PropertyRequest->Node = Property->NodeId; + PropertyRequest->PropertyItem = PropertyItem; + PropertyRequest->Verb = Property->Property.Flags; + PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY); + PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY)); + PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; + PropertyRequest->Value = Irp->UserBuffer; + + Status = PropertyItem->Handler(PropertyRequest); + + if (Status != STATUS_PENDING) + { + //request completed + Irp->IoStatus.Information = PropertyRequest->ValueSize; + ExFreePool(PropertyRequest); + } + + // done + DPRINT("Status %x\n", Status); + return Status; +} - if (!Node->AutomationTable) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_NOT_FOUND; - } +NTSTATUS +NTAPI +PcHandlePropertyWithTable( + IN PIRP Irp, + IN ULONG PropertySetCount, + IN PKSPROPERTY_SET PropertySet, + IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) +{ + NTSTATUS Status; - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); + // try handle it as node property request + Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor); - PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; + if (Status == STATUS_NOT_FOUND) + { + // store device descriptor + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; - for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) - { - if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id) - { - if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) - { - if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) - { - PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG)); - PULONG Flags = (PULONG)Irp->UserBuffer; - - /* reset flags */ - *Flags = 0; - - if (PropertyItem->Flags & KSPROPERTY_TYPE_SET) - *Flags |= KSPROPERTY_TYPE_SET; - - if (PropertyItem->Flags & KSPROPERTY_TYPE_GET) - *Flags |= KSPROPERTY_TYPE_GET; - - Irp->IoStatus.Information = sizeof(ULONG); - - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) - { - /* get output buffer */ - PKSPROPERTY_DESCRIPTION Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer; - - /* store result */ - Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); - Description->PropTypeSet.Set = KSPROPTYPESETID_General; - Description->PropTypeSet.Id = 0; - Description->PropTypeSet.Flags = 0; - Description->MembersListCount = 0; - Description->Reserved = 0; - - Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION); - } - return STATUS_SUCCESS; - } - } - - - PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); - if (!PropertyRequest) - return STATUS_INSUFFICIENT_RESOURCES; - - PC_ASSERT(SubDeviceDescriptor->UnknownMiniport); - PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport; - PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream; - PropertyRequest->Irp = Irp; - PropertyRequest->Node = Property->NodeId; - PropertyRequest->PropertyItem = PropertyItem; - PropertyRequest->Verb = Property->Property.Flags; - PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY); - PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY)); - PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; - PropertyRequest->Value = Irp->UserBuffer; - - Status = PropertyItem->Handler(PropertyRequest); - - if (Status != STATUS_PENDING) - { - //DPRINT("Status %x ValueSize %u - - Irp->IoStatus.Information = PropertyRequest->ValueSize; - ExFreePool(PropertyRequest); - } -#if 0 - RtlStringFromGUID(Property->Property.Set, &GuidString); - DPRINT("Id %u Flags %x Set %S FlagsItem %x Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, PropertyItem->Flags, Status); - RtlFreeUnicodeString(&GuidString); -#endif - return Status; - } - PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); - } -#if 0 - RtlStringFromGUID(Property->Property.Set, &GuidString); - DPRINT("Id %u Flags %x Set %S Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, Status); - RtlFreeUnicodeString(&GuidString); -#endif - } + /* then try KsPropertyHandler */ + Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet); } + return Status; } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c index 946d45bb9c8..5de3872e55d 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -2162,7 +2162,7 @@ SetGetMuteControlDetails( Value = Input->fValue; /* set control details */ - Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, MAXULONG, &Value); + Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value); if (!NT_SUCCESS(Status)) return Status; -- 2.17.1