+NTSTATUS
+PcCountProperties(
+ IN PIRP Irp,
+ IN PSUBDEVICE_DESCRIPTOR Descriptor)
+{
+ ULONG Properties;
+ ULONG Index, Offset;
+ PIO_STACK_LOCATION IoStack;
+ LPGUID Guid;
+
+ /* count property items */
+ Properties = Descriptor->FilterPropertySet.FreeKsPropertySetOffset;
+
+ if (Descriptor->DeviceDescriptor->AutomationTable)
+ {
+ Properties = Descriptor->DeviceDescriptor->AutomationTable->PropertyCount;
+ }
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* store output size */
+ Irp->IoStatus.Information = sizeof(GUID) * Properties;
+
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * Properties)
+ {
+ /* buffer too small */
+ Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ /* get output buffer */
+ Guid = Irp->UserBuffer;
+
+
+ /* copy property guids from filter */
+ Offset = 0;
+ for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
+ {
+ RtlMoveMemory(&Guid[Offset], Descriptor->FilterPropertySet.Properties[Index].Set, sizeof(GUID));
+ Offset++;
+ }
+
+ if (Descriptor->DeviceDescriptor->AutomationTable)
+ {
+ /* copy property guids from driver */
+ for(Index = 0; Index < Descriptor->DeviceDescriptor->AutomationTable->PropertyCount; Index++)
+ {
+ RtlMoveMemory(&Guid[Offset], Descriptor->DeviceDescriptor->AutomationTable->Properties[Index].Set, sizeof(GUID));
+ Offset++;
+ }
+ }
+
+ /* done */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+