KsoGetIrpTargetFromIrp(
PIRP Irp)
{
- PKSOBJECT_CREATE_ITEM CreateItem;
+ PIO_STACK_LOCATION IoStack;
- // access the create item
- CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+ // get current irp stack location
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
// IIrpTarget is stored in Context member
- return (IIrpTarget*)CreateItem->Context;
+ return (IIrpTarget*)IoStack->FileObject->FsContext;
+}
+
+NTSTATUS
+NTAPI
+PcHandleEnableEventWithTable(
+ IN PIRP Irp,
+ IN PSUBDEVICE_DESCRIPTOR Descriptor)
+{
+ // store descriptor
+ KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
+
+ // FIXME seh probing
+ return KsEnableEvent(Irp, Descriptor->EventSetCount, Descriptor->EventSet, NULL, KSEVENTS_NONE, NULL);
+}
+
+NTSTATUS
+NTAPI
+PcHandleDisableEventWithTable(
+ IN PIRP Irp,
+ IN PSUBDEVICE_DESCRIPTOR Descriptor)
+{
+ // store descriptor
+ KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
+
+ // FIXME seh probing
+
+ return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock);
}
NTSTATUS
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;
-
- /* 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(KSPROPERTY))
{
- 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));
-
- 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);
-
- 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));
-
- 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);
-
- PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
- //Flags = (PULONG)Irp->UserBuffer;
+ // certainly an invalid request
+ return STATUS_INVALID_PARAMETER;
+ }
- 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
+ // store device descriptor
+ KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
- 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;
+ // then try KsPropertyHandler
+ return KsPropertyHandler(Irp, PropertySetCount, PropertySet);
}
VOID
return STATUS_NOT_IMPLEMENTED;
}
+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);
+#if 0
+ Status = PropertyRequest->PropertyItem->Handler(PropertyRequest);
+#else
+ Status = STATUS_NOT_FOUND;
+#endif
+ 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)
+ IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor,
+ IN PPCPROPERTY_ITEM PropertyItem,
+ IN ULONG bNode)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ 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
DumpFilterDescriptor(
IN PPCFILTER_DESCRIPTOR FilterDescription)
{
- ULONG Index;
+ ULONG Index, SubIndex;
PPCPROPERTY_ITEM PropertyItem;
+ PPCEVENT_ITEM EventItem;
+ PPCNODE_DESCRIPTOR NodeDescriptor;
UNICODE_STRING GuidString;
- DPRINT1("======================\n");
- DPRINT1("Descriptor Automation Table%p\n",FilterDescription->AutomationTable);
+
+
+ DPRINT("======================\n");
+ DPRINT("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));
+ DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM),
+ FilterDescription->AutomationTable->EventCount, FilterDescription->AutomationTable->EventItemSize, sizeof(PCEVENT_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);
+ DPRINT("Property 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);
}
+
+ EventItem = (PPCEVENT_ITEM)FilterDescription->AutomationTable->Events;
+ for(Index = 0; Index < FilterDescription->AutomationTable->EventCount; Index++)
+ {
+ RtlStringFromGUID(*EventItem->Set, &GuidString);
+ DPRINT("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags);
+
+ EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize);
+ }
+
}
}
+ if (FilterDescription->Nodes)
+ {
+ DPRINT("NodeCount %u NodeSize %u expected %u\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR));
+ NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
+ for(Index = 0; Index < FilterDescription->NodeCount; Index++)
+ {
+ DPRINT("Index %u AutomationTable %p\n", Index, NodeDescriptor->AutomationTable);
+
+ if (NodeDescriptor->AutomationTable)
+ {
+ DPRINT(" Index %u EventCount %u\n", Index, NodeDescriptor->AutomationTable->EventCount);
+ EventItem = (PPCEVENT_ITEM)NodeDescriptor->AutomationTable->Events;
+ for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->EventCount; SubIndex++)
+ {
+ RtlStringFromGUID(*EventItem->Set, &GuidString);
+ DPRINT(" EventIndex %u GUID %S Id %u Flags %x\n", SubIndex, GuidString.Buffer, EventItem->Id, EventItem->Flags);
+
+ 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);
+ }
+ }
+
+
+ NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
+ }
+
+
+
+ }
+
+ DPRINT("ConnectionCount: %lu\n", FilterDescription->ConnectionCount);
+
+ if (FilterDescription->ConnectionCount)
+ {
+ DPRINT("------ Start of Nodes Connections ----------------\n");
+ for(Index = 0; Index < FilterDescription->ConnectionCount; Index++)
+ {
+ DPRINT1("Index %ld FromPin %ld FromNode %ld -> ToPin %ld ToNode %ld\n", Index,
+ FilterDescription->Connections[Index].FromNodePin,
+ FilterDescription->Connections[Index].FromNode,
+ FilterDescription->Connections[Index].ToNodePin,
+ FilterDescription->Connections[Index].ToNode);
+ }
+ DPRINT("------ End of Nodes Connections----------------\n");
+ }
DPRINT1("======================\n");
- DbgBreakPoint();
}
NTSTATUS
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;
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;
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));
+ }
}
}
+ // 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;
+
+ // copy pin factories
+ for(Index = 0; Index < FilterDescription->PinCount; Index++)
+ {
+ // copy pin descriptor
+ RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
+
+ // 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++)
{
- if (FilterDescription->Nodes[Index].Type)
+ // does it have a type
+ if (NodeDescriptor->Type)
{
- RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID));
+ // copy node type
+ RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID));
}
- if (FilterDescription->Nodes[Index].Name)
+
+ // does it have a node name
+ if (NodeDescriptor->Name)
{
- RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID));
+ // copy node name
+ RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID));
}
- }
- Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount;
- }
-
- if (FilterDescription->PinCount)
- {
- Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS);
- if (!Descriptor->Factory.KsPinDescriptor)
- goto cleanup;
- Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
- if (!Descriptor->Factory.Instances)
- goto cleanup;
+ // check if has an automation table
+ if (NodeDescriptor->AutomationTable)
+ {
+ // grab first entry
+ PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties;
- Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
- Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
+ // 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);
- SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
- DPRINT("Size %u Expected %u Ex Size %u\n", FilterDescription->PinSize, sizeof(KSPIN_DESCRIPTOR), sizeof(KSPIN_DESCRIPTOR_EX));
+ // check for success
+ if (Status != STATUS_SUCCESS)
+ {
+ // failed
+ goto cleanup;
+ }
- // copy pin factories
- for(Index = 0; Index < FilterDescription->PinCount; Index++)
- {
- RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
+ // move to next property item
+ PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize);
+ }
+ }
- Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
- Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = FilterDescription->Pins[Index].MaxFilterInstanceCount;
- Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = FilterDescription->Pins[Index].MaxGlobalInstanceCount;
- Descriptor->Factory.Instances[Index].MinFilterInstanceCount = FilterDescription->Pins[Index].MinFilterInstanceCount;
- SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize);
+ // 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: