Author: janderwald Date: Sat Oct 23 18:51:17 2010 New Revision: 49243
URL: http://svn.reactos.org/svn/reactos?rev=49243&view=rev Log: [PORTCLS] - Rewrite the topology filter / pin / node property handling - Store property sets of filter / pins / nodes in a common property set array - Write a common dispatch function, which serves as a trampoline for filter / pin / node property requests - Private property handlers of the drivers are now accessible
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] Sat Oct 23 18:51:17 2010 @@ -8,22 +8,6 @@
#include "private.hpp"
- -KSPIN_INTERFACE PinInterfaces[] = -{ - { - {STATIC_KSINTERFACESETID_Standard}, - KSINTERFACE_STANDARD_STREAMING, - 0 - }, - { - {STATIC_KSINTERFACESETID_Standard}, - KSINTERFACE_STANDARD_LOOPED_STREAMING, - 0 - } -}; - - NTSTATUS NTAPI KsoDispatchCreateWithGenericFactory( @@ -84,274 +68,6 @@ // FIXME seh probing
return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock); -} - -NTSTATUS -PcHandleGuidNullRequest( - IN OUT PIRP Irp, - IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) -{ - 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; SubIndex++) - { - 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; - - // 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; - } - - // sanity checks - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); - - 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); - - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - 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)) - { - // 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; -} - - -NTSTATUS -PcHandleNodePropertyRequest( - PIRP Irp, - IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) -{ - PIO_STACK_LOCATION IoStack; - PPCPROPERTY_ITEM PropertyItem; - PPCPROPERTY_REQUEST PropertyRequest; - PKSP_NODE Property; - NTSTATUS Status; - - // get current irp stack location - IoStack = IoGetCurrentIrpStackLocation(Irp); - - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) - { - // certainly not a node property request - return STATUS_NOT_FOUND; - } - - // 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); - } - - // find property handler - Status = PcFindNodePropertyHandler(Irp, SubDeviceDescriptor, &PropertyItem); - - // check for success - if (!NT_SUCCESS(Status)) - { - // might not be a node property request - DPRINT("NotFound\n"); - return STATUS_NOT_FOUND; - } - - if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) - { - // caller issued a basic property request - if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) - { - // driver does not have a basic support handler - return PcNodeBasicSupportHandler(Irp, PropertyItem); - } - } - - // sanity check - PC_ASSERT(SubDeviceDescriptor->UnknownMiniport); - - // allocate a property request - PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); - if (!PropertyRequest) - return STATUS_INSUFFICIENT_RESOURCES; - - // initialize property request - 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; - FreeItem(PropertyRequest, TAG_PORTCLASS); - } - - // done - DPRINT("Status %x\n", Status); - return Status; }
NTSTATUS @@ -362,21 +78,22 @@ IN PKSPROPERTY_SET PropertySet, IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) { - NTSTATUS Status; - - // try handle it as node property request - Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor); - - if (Status == STATUS_NOT_FOUND) - { - // store device descriptor - KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; - - /* then try KsPropertyHandler */ - Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet); - } - - return Status; + PIO_STACK_LOCATION IoStack; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) + { + // certainly an invalid request + return STATUS_INVALID_PARAMETER; + } + + // store device descriptor + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; + + // then try KsPropertyHandler + return KsPropertyHandler(Irp, PropertySetCount, PropertySet); }
VOID @@ -406,15 +123,377 @@ }
NTSTATUS +NTAPI +PropertyItemDispatch( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PPCPROPERTY_REQUEST PropertyRequest; + PSUBDEVICE_DESCRIPTOR Descriptor; + PKSPROPERTY Property; + PPCNODE_DESCRIPTOR NodeDescriptor; + PKSNODEPROPERTY NodeProperty; + PKSPROPERTY_SET PropertySet; + PPCPROPERTY_ITEM PropertyItem; + PPCAUTOMATION_TABLE NodeAutomation; + PIO_STACK_LOCATION IoStack; + ULONG InstanceSize, ValueSize, Index; + PVOID Instance; + NTSTATUS Status; + + // allocate a property request + PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); + if (!PropertyRequest) + return STATUS_INSUFFICIENT_RESOURCES; + + // grab device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get input property request + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + // get property set + PropertySet = (PKSPROPERTY_SET)KSPROPERTY_SET_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->UnknownMiniport); + + // get instance / value size + InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength; + Instance = Data; + ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; + + // initialize property request + PropertyRequest->MajorTarget = Descriptor->UnknownMiniport; + PropertyRequest->MinorTarget = Descriptor->UnknownStream; + PropertyRequest->Irp = Irp; + PropertyRequest->Verb = Property->Flags; + + + // check if this is filter / pin property request + if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY)) + { + // adjust input buffer size + InstanceSize -= sizeof(KSPROPERTY); + Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSPROPERTY)); + + // filter / pin property request dont use node field + PropertyRequest->Node = MAXULONG; + } + else if (InstanceSize >= sizeof(KSNODEPROPERTY)) + { + // request is for a node + InstanceSize -= sizeof(KSNODEPROPERTY); + Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSNODEPROPERTY)); + + // cast node property request + NodeProperty = (PKSNODEPROPERTY)Request; + + // store node id + PropertyRequest->Node = NodeProperty->NodeId; + } + else + { + // invalid buffer size + return STATUS_INVALID_BUFFER_SIZE; + } + + // store instance size + PropertyRequest->InstanceSize = InstanceSize; + PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL); + + // store value size + PropertyRequest->ValueSize = ValueSize; + PropertyRequest->Value = (ValueSize != 0 ? Irp->UserBuffer : NULL); + + // now scan the property set for the attached property set item stored in Relations member + if (PropertySet) + { + // sanity check + PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set)); + + for(Index = 0; Index < PropertySet->PropertiesCount; Index++) + { + // check if they got the same property id + if (PropertySet->PropertyItem[Index].PropertyId == Property->Id) + { + // found item + PropertyRequest->PropertyItem = (const PCPROPERTY_ITEM*)PropertySet->PropertyItem[Index].Relations; + + // done + break; + } + } + } + + // check if there has been a property set item attached + if (!PropertyRequest->PropertyItem) + { + // is topology node id valid + if (PropertyRequest->Node < Descriptor->DeviceDescriptor->NodeCount) + { + // get node descriptor + NodeDescriptor = (PPCNODE_DESCRIPTOR) ((ULONG_PTR)Descriptor->DeviceDescriptor->Nodes + PropertyRequest->Node * Descriptor->DeviceDescriptor->NodeSize); + + // get node automation table + NodeAutomation = (PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable; + + // has it got a automation table + if (NodeAutomation) + { + // now scan the properties and check if it supports this request + PropertyItem = (PPCPROPERTY_ITEM)NodeAutomation->Properties; + for(Index = 0; Index < NodeAutomation->PropertyCount; Index++) + { + // are they same property + if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Set)) + { + if (PropertyItem->Id == Property->Id) + { + // found match + PropertyRequest->PropertyItem = PropertyItem; + + // done + break; + } + } + + // move to next property item + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeAutomation->PropertyItemSize); + } + } + } + } + + if (PropertyRequest->PropertyItem && PropertyRequest->PropertyItem->Handler) + { + // now call the handler + UNICODE_STRING GuidBuffer; + RtlStringFromGUID(Property->Set, &GuidBuffer); + DPRINT1("Calling Node %lu MajorTarget %p MinorTarget %p PropertySet %S PropertyId %lu PropertyFlags %lx InstanceSize %lu ValueSize %lu Handler %p PropertyRequest %p\n", + PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize, + PropertyRequest->PropertyItem->Handler, PropertyRequest); + Status = PropertyRequest->PropertyItem->Handler(PropertyRequest); + + Irp->IoStatus.Information = PropertyRequest->ValueSize; + + if (Status != STATUS_PENDING) + { + // free property request + FreeItem(PropertyRequest, TAG_PORTCLASS); + } + } + else + { + FreeItem(PropertyRequest, TAG_PORTCLASS); + Status = STATUS_NOT_FOUND; + } + + /* done */ + return Status; +} + +NTSTATUS PcAddToPropertyTable( - PVOID Ptr, - LONG Unknown, - LONG Unknown2, - LONG Unknown3, - CHAR Unknown4) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, + IN PPCPROPERTY_ITEM PropertyItem, + IN ULONG bNode) +{ + ULONG bFound = FALSE; + ULONG Index, PropertySetIndex, PropertySetItemIndex; + PKSPROPERTY_SET NewPropertySet; + PKSPROPERTY_ITEM FilterPropertyItem, NewFilterPropertyItem; + LPGUID Guid; + //UNICODE_STRING GuidBuffer; + +ASSERT(PropertyItem->Set); + // RtlStringFromGUID(*PropertyItem->Set, &GuidBuffer); + // DPRINT1("PcAddToPropertyTable Adding Item Set %S Id %lu Flags %lx\n", GuidBuffer.Buffer, PropertyItem->Id, PropertyItem->Flags); + + + + //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount); + // first step check if the property set is present already + for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySetCount; Index++) + { + + //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer); + //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount); + if (IsEqualGUIDAligned(*SubDeviceDescriptor->FilterPropertySet[Index].Set, *PropertyItem->Set)) + { + // property set is already present + bFound = TRUE; + PropertySetIndex = Index; + + // break out + break; + } + } + + // is the property set present + if (!bFound) + { + // need to allocate a property set + NewPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySetCount + 1) * sizeof(KSPROPERTY_SET), TAG_PORTCLASS); + if (!NewPropertySet) + { + // out of memory + return STATUS_INSUFFICIENT_RESOURCES; + } + + // need to allocate property set guid + Guid = (LPGUID)AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS); + if (!Guid) + { + // out of memory + FreeItem(NewPropertySet, TAG_PORTCLASS); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // are any existing property sets + if (SubDeviceDescriptor->FilterPropertySetCount) + { + // copy property sets + RtlMoveMemory(NewPropertySet, SubDeviceDescriptor->FilterPropertySet, SubDeviceDescriptor->FilterPropertySetCount * sizeof(KSPROPERTY_SET)); + + // release memory + FreeItem(SubDeviceDescriptor->FilterPropertySet, TAG_PORTCLASS); + } + + // store new property set descriptors + SubDeviceDescriptor->FilterPropertySet = NewPropertySet; + + // store index + PropertySetIndex = SubDeviceDescriptor->FilterPropertySetCount; + + // increment property set count + SubDeviceDescriptor->FilterPropertySetCount++; + + // copy property guid + RtlMoveMemory(Guid, PropertyItem->Set, sizeof(GUID)); + + // initialize property set + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].Set = Guid; + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount = 0; + } + + // as the property set has been indentified, now search for duplicate property set item entries + FilterPropertyItem = (PKSPROPERTY_ITEM)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem; + bFound = FALSE; + + for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; Index++) + { + // now search for an equal property set item + if (FilterPropertyItem->PropertyId == PropertyItem->Id) + { + // found existing property set item + bFound = TRUE; + PropertySetItemIndex = Index; + break; + } + + // move to next entry + FilterPropertyItem++; + } + + if (!bFound) + { + // need to allocate memory for new property set item + NewFilterPropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount + 1) * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS); + if (!NewFilterPropertyItem) + { + // out of memory + return STATUS_INSUFFICIENT_RESOURCES; + } + + // are any existing property set items + if (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount) + { + // copy property item sets + RtlMoveMemory(NewFilterPropertyItem, + (PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount * sizeof(KSPROPERTY_ITEM)); + + // release old descriptors + FreeItem((PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, TAG_PORTCLASS); + } + + // store new descriptor + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem = NewFilterPropertyItem; + + // store index + PropertySetItemIndex = SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; + + // increment property item set count + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount++; + + // now initialize property item + FilterPropertyItem = (PKSPROPERTY_ITEM)&SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex]; + FilterPropertyItem->PropertyId = PropertyItem->Id; + FilterPropertyItem->MinProperty = sizeof(KSPROPERTY); + FilterPropertyItem->MinData = 0; + + // are any set operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_SET) + { + // setup handler + FilterPropertyItem->SetPropertyHandler = PropertyItemDispatch; + } + + // are set operation supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET) + { + // setup handler + FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch; + } + + // are get operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET) + { + // setup handler + FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch; + } + + // are basic support operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_BASICSUPPORT) + { + // setup handler + FilterPropertyItem->SupportHandler = PropertyItemDispatch; + } + + if (!bNode) + { + // store property item in relations + // only store property item of filter properties / pin properties + // because filter & pin properties do not require a specific context + // on the other hand node properties are specifically bound to a node + + FilterPropertyItem->Relations = (const KSPROPERTY*)PropertyItem; + } + } + else + { + // property set item handler already present + + if (bNode) + { + // filter & pin properties should not be exposed on a node + ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations == NULL); + } + else + { + // node properties should not be exposed on a filter & pin + ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations != NULL); + } + } + + // done + return STATUS_SUCCESS; }
NTSTATUS @@ -491,6 +570,15 @@ EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + NodeDescriptor->AutomationTable->EventItemSize); }
+ DPRINT1(" Index %u PropertyCount %u\n", Index, NodeDescriptor->AutomationTable->PropertyCount); + PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties; + for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + RtlStringFromGUID(*PropertyItem->Set, &GuidString); + DPRINT1(" PropertyIndex %u GUID %S Id %u Flags %x\n", SubIndex, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags); + + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize); + } }
@@ -539,10 +627,13 @@ IN PPCFILTER_DESCRIPTOR FilterDescription) { SUBDEVICE_DESCRIPTOR * Descriptor; - ULONG Index; + ULONG Index, SubIndex; NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; PPCPIN_DESCRIPTOR SrcDescriptor; - + PPCNODE_DESCRIPTOR NodeDescriptor; + PPCPROPERTY_ITEM PropertyItem; + + // allocate subdevice descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS); if (!Descriptor) return STATUS_INSUFFICIENT_RESOURCES; @@ -551,6 +642,7 @@ InitializeListHead(&Descriptor->SymbolicLinkList); InitializeListHead(&Descriptor->PhysicalConnectionList);
+ //FIXME add driver category guids Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS); if (!Descriptor->Interfaces) goto cleanup; @@ -559,98 +651,215 @@ RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount); Descriptor->InterfaceCount = InterfaceCount;
+ //DumpFilterDescriptor(FilterDescription); + + // are any property sets supported by the portcls if (FilterPropertiesCount) { - /// FIXME - /// handle driver properties - - DumpFilterDescriptor(FilterDescription); - + // first allocate filter properties set Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS); if (! Descriptor->FilterPropertySet) goto cleanup;
+ // now copy all filter property sets Descriptor->FilterPropertySetCount = FilterPropertiesCount; for(Index = 0; Index < FilterPropertiesCount; Index++) { + // copy property set RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET)); + + if (Descriptor->FilterPropertySet[Index].PropertiesCount) + { + // copy property items to make sure they are dynamically allocated + Descriptor->FilterPropertySet[Index].PropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS); + if (!Descriptor->FilterPropertySet[Index].PropertyItem) + { + // no memory + goto cleanup; + } + + // copy filter property items + RtlMoveMemory((PVOID)Descriptor->FilterPropertySet[Index].PropertyItem, FilterProperties[Index].PropertyItem, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM)); + } } }
- Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); - if (!Descriptor->Topology) - goto cleanup; - - if (FilterDescription->ConnectionCount) - { - Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * 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 = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); - if (!Descriptor->Topology->TopologyNodes) - goto cleanup; - - Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); - if (!Descriptor->Topology->TopologyNodesNames) - goto cleanup; - - for(Index = 0; Index < FilterDescription->NodeCount; Index++) - { - if (FilterDescription->Nodes[Index].Type) - { - RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID)); - } - if (FilterDescription->Nodes[Index].Name) - { - RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID)); - } - } - Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount; - } - + // now check if the filter descriptor supports filter properties + if (FilterDescription->AutomationTable) + { + // get first entry + PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties; + + // copy driver filter property sets + for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++) + { + // add the property item + Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE); + + // check for success + if (Status != STATUS_SUCCESS) + { + // goto cleanup + goto cleanup; + } + + // move to next entry + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize); + } + } + + // check if the filter has pins if (FilterDescription->PinCount) { + // allocate pin factory descriptors Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS); if (!Descriptor->Factory.KsPinDescriptor) goto cleanup;
+ // allocate pin instance info Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS); if (!Descriptor->Factory.Instances) goto cleanup;
+ // initialize pin factory descriptor Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount; Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
+ // grab first entry SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins; - DPRINT("Size %u Expected %u\n", FilterDescription->PinSize, sizeof(PCPIN_DESCRIPTOR));
// copy pin factories for(Index = 0; Index < FilterDescription->PinCount; Index++) { + // copy pin descriptor RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
- Descriptor->Factory.KsPinDescriptor[Index].Interfaces = PinInterfaces; - Descriptor->Factory.KsPinDescriptor[Index].InterfacesCount = sizeof(PinInterfaces) / sizeof(KSPIN_INTERFACE); - - DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount); - + // initialize pin factory instance data Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0; Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount; Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount; Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount; + + // check if the descriptor has an automation table + if (SrcDescriptor->AutomationTable) + { + // it has, grab first entry + PropertyItem = (PPCPROPERTY_ITEM)SrcDescriptor->AutomationTable->Properties; + + // now add all supported property items + for(SubIndex = 0; SubIndex < SrcDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + // add the property item to the table + Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE); + + // check for success + if (Status != STATUS_SUCCESS) + { + // goto cleanup + goto cleanup; + } + + // move to next entry + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + SrcDescriptor->AutomationTable->PropertyItemSize); + } + } + + // move to next entry SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize); } }
+ // allocate topology descriptor + Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); + if (!Descriptor->Topology) + goto cleanup; + + // are there any connections + if (FilterDescription->ConnectionCount) + { + // allocate connection descriptor + Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyConnections) + goto cleanup; + + // copy connection descriptor + RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR)); + + // store connection count + Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount; + } + + // does the filter have nodes + if (FilterDescription->NodeCount) + { + // allocate topology node types array + Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyNodes) + goto cleanup; + + // allocate topology node names array + Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyNodesNames) + goto cleanup; + + // grab first entry + NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes; + + // iterate all nodes and copy node types / names and node properties + for(Index = 0; Index < FilterDescription->NodeCount; Index++) + { + // does it have a type + if (NodeDescriptor->Type) + { + // copy node type + RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID)); + } + + // does it have a node name + if (NodeDescriptor->Name) + { + // copy node name + RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID)); + } + + // check if has an automation table + if (NodeDescriptor->AutomationTable) + { + // grab first entry + PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties; + + // copy all node properties into the global property set + for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + // add to property set + Status = PcAddToPropertyTable(Descriptor, PropertyItem, TRUE); + + // check for success + if (Status != STATUS_SUCCESS) + { + // failed + goto cleanup; + } + + // move to next property item + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize); + } + } + + // move to next descriptor + NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize); + } + + // now store the topology node count + Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount; + } + + // store descriptor Descriptor->DeviceDescriptor = FilterDescription; + + // store result *OutSubdeviceDescriptor = Descriptor; + // done return STATUS_SUCCESS;
cleanup: