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);
// 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;
}