[WDMAUD_KERNEL]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 29 Nov 2009 18:56:56 +0000 (18:56 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 29 Nov 2009 18:56:56 +0000 (18:56 +0000)
- 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

reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp
reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c

index 71e7b33..c1850b0 100644 (file)
@@ -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;
 }
index 4e567d1..45e11cf 100644 (file)
@@ -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;
 }
 
index 946d45b..5de3872 100644 (file)
@@ -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;