- Add KSPROPSETID_Audio guid
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Fri, 2 Oct 2009 21:55:53 +0000 (21:55 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Fri, 2 Oct 2009 21:55:53 +0000 (21:55 +0000)
- Allocate data format after successful initialization of IPinWaveCyclic
- Store Miniport Adapter in subdevice descriptor
- Implement GUID_NULL handler for topology nodes
- Implement setting / retrieving properties for topology nodes

svn path=/trunk/; revision=43258

reactos/drivers/wdm/audio/backpln/portcls/guids.cpp
reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp
reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp
reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp
reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp

index dc4d1e0..abc5325 100644 (file)
@@ -82,6 +82,7 @@ const GUID KSPROPTYPESETID_General             = {0x97E99BA0L, 0xBDEA, 0x11CF, {
 
 const GUID IID_IAllocatorMXF                   = {0xa5f0d62cL, 0xb30f, 0x11d2, {0xb7, 0xa3, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
 
+const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
 ///
 /// undocumented guids
 
index d407d85..4be3324 100644 (file)
@@ -161,6 +161,8 @@ DECLARE_INTERFACE_(IIrpTarget, IUnknown)
     DEFINE_ABSTRACT_IRPTARGET()
 };
 
+typedef IIrpTarget *PIRPTARGET;
+
 /*****************************************************************************
  * ISubdevice
  *****************************************************************************
@@ -212,6 +214,7 @@ typedef struct
     LIST_ENTRY SymbolicLinkList;
     LIST_ENTRY PhysicalConnectionList;
     UNICODE_STRING RefString;
+    PUNKNOWN UnknownMiniport;
 }SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
 
 #undef INTERFACE
index 3a5d014..2518af4 100644 (file)
@@ -913,12 +913,6 @@ CPortPinWaveCyclic::Init(
 
     DPRINT("CPortPinWaveCyclic::Init entered Size %u\n", DataFormat->FormatSize);
 
-    m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
-    if (!m_Format)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
-
     Status = NewIrpQueue(&m_IrpQueue);
     if (!NT_SUCCESS(Status))
         return Status;
@@ -943,7 +937,7 @@ CPortPinWaveCyclic::Init(
                                    NonPagedPool,
                                    ConnectDetails->PinId,
                                    Capture,
-                                   m_Format,
+                                   DataFormat,
                                    &m_DmaChannel,
                                    &m_ServiceGroup);
 #if 0
@@ -999,6 +993,13 @@ CPortPinWaveCyclic::Init(
        return Status;
     }
 
+    m_Format = (PKSDATAFORMAT)ExAllocatePoolWithTag(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
+    if (!m_Format)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
+
+
     Port->AddRef();
     Filter->AddRef();
 
index 291a017..072eb59 100644 (file)
@@ -273,6 +273,12 @@ CPortTopology::Init(
 
 
     DPRINT("IPortTopology_fnInit success\n");
+    if (NT_SUCCESS(Status))
+    {
+        // store for node property requests
+        m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport;
+    }
+
     return STATUS_SUCCESS;
 }
 
@@ -455,7 +461,7 @@ CreatePinWorkerRoutine(
     DPRINT("CreatePinWorkerRoutine called\n");
     // create the pin
     Status = WorkerContext->Filter->NewIrpTarget(&Pin,
-                                                 NULL,
+                                                 KSSTRING_Pin,
                                                  NULL,
                                                  NonPagedPool,
                                                  DeviceObject,
index d9136c9..77e1ecd 100644 (file)
@@ -298,6 +298,9 @@ CPortWaveCyclic::Init(
         return Status;
     }
 
+    // store for node property requests
+    m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport;
+
     // check if it supports IPinCount interface
     Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount);
     if (NT_SUCCESS(Status))
index bdc04e4..f9c60a3 100644 (file)
@@ -51,8 +51,133 @@ PcHandlePropertyWithTable(
     IN PKSPROPERTY_SET PropertySet,
     IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
 {
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStack;
+    PKSP_NODE Property;
+    PPCNODE_DESCRIPTOR Node;
+    PPCPROPERTY_ITEM PropertyItem;
+    ULONG Index;
+    LPGUID Buffer;
+    //PULONG Flags;
+    PPCPROPERTY_REQUEST PropertyRequest;
+
     KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
-    return KsPropertyHandler(Irp, PropertySetCount, PropertySet);
+
+    /* try first KsPropertyHandler */
+    Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
+
+    // get current irp stack location
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    // access property
+    Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    // check if this a GUID_NULL request
+    if (Status == STATUS_NOT_FOUND)
+    {
+        if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE))
+            return Status;
+
+        // 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));
+
+            PC_ASSERT(Node->AutomationTable);
+            PC_ASSERT(Node->AutomationTable->PropertyCount);
+            PC_ASSERT(Node->AutomationTable->PropertyItemSize);
+
+            Irp->IoStatus.Information = sizeof(GUID) * Node->AutomationTable->PropertyCount;
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * Node->AutomationTable->PropertyCount)
+            {
+                // buffer too small
+                return STATUS_MORE_ENTRIES;
+            }
+
+            PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
+            Buffer = (LPGUID)Irp->UserBuffer;
+
+            for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
+            {
+                RtlMoveMemory(Buffer, PropertyItem->Set, sizeof(GUID));
+                Buffer++;
+
+                PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
+            }
+            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->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));
+
+            PC_ASSERT(Node->AutomationTable);
+            PC_ASSERT(Node->AutomationTable->PropertyCount);
+            PC_ASSERT(Node->AutomationTable->PropertyItemSize);
+
+            PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
+            //Flags = (PULONG)Irp->UserBuffer;
+
+            for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
+            {
+                if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id)
+                {
+                    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 = (PUNKNOWN)0xABADCAFE;
+                    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)
+                    {
+                        //DPRINT1("Status %x ValueSize %u 
+
+                        Irp->IoStatus.Information = PropertyRequest->ValueSize;
+                        ExFreePool(PropertyRequest);
+                    }
+                    return Status;
+                }
+                PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
+            }
+        }
+#if 0
+        else
+               {
+                       UNICODE_STRING GuidString;
+            RtlStringFromGUID(Property->Property.Set, &GuidString);
+                       DPRINT1("Id %u Flags %x Set %S\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer);
+                       DbgBreakPoint();
+               }
+#endif
+    }
+    return Status;
 }
 
 VOID
@@ -104,6 +229,39 @@ PcCaptureFormat(
     return STATUS_NOT_IMPLEMENTED;
 }
 
+VOID
+DumpFilterDescriptor(
+    IN PPCFILTER_DESCRIPTOR FilterDescription)
+{
+    ULONG Index;
+    PPCPROPERTY_ITEM PropertyItem;
+    UNICODE_STRING GuidString;
+
+    DPRINT1("======================\n");
+    DPRINT1("Descriptor Automation Table%p\n",FilterDescription->AutomationTable);
+
+    if (FilterDescription->AutomationTable)
+    {
+        DPRINT1("FilterPropertiesCount %u FilterPropertySize %u Expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM));
+        if (FilterDescription->AutomationTable->PropertyCount)
+        {
+            PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties;
+
+            for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++)
+            {
+                RtlStringFromGUID(*PropertyItem->Set, &GuidString);
+                DPRINT1("Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
+
+                PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize);
+            }
+        }
+    }
+
+
+    DPRINT1("======================\n");
+    DbgBreakPoint();
+}
+
 NTSTATUS
 NTAPI
 PcCreateSubdeviceDescriptor(
@@ -147,6 +305,9 @@ PcCreateSubdeviceDescriptor(
     {
        /// FIXME
        /// handle driver properties
+
+       //DumpFilterDescriptor(FilterDescription);
+
        Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS);
        if (! Descriptor->FilterPropertySet)
            goto cleanup;