- Store KSPROPERTY_SET in Irp when using KsPropertyHandler
[reactos.git] / reactos / drivers / ksfilter / ks / property.c
index cc56bbb..d239395 100644 (file)
@@ -17,12 +17,17 @@ FindPropertyHandler(
     IN PKSPROPERTY Property,
     IN ULONG InputBufferLength,
     IN ULONG OutputBufferLength,
-    OUT PFNKSHANDLER *PropertyHandler)
+    OUT PVOID OutputBuffer,
+    OUT PFNKSHANDLER *PropertyHandler,
+    OUT PKSPROPERTY_SET * Set)
 {
     ULONG Index, ItemIndex;
+    //PULONG Flags;
 
     for(Index = 0; Index < PropertySetCount; Index++)
     {
+        ASSERT(PropertySet[Index].Set);
+
         if (IsEqualGUIDAligned(&Property->Set, PropertySet[Index].Set))
         {
             for(ItemIndex = 0; ItemIndex < PropertySet[Index].PropertiesCount; ItemIndex++)
@@ -40,8 +45,48 @@ FindPropertyHandler(
                     {
                         /* too small output buffer */
                         IoStatus->Information = PropertySet[Index].PropertyItem[ItemIndex].MinData;
-                        return STATUS_BUFFER_TOO_SMALL;
+                        return STATUS_MORE_ENTRIES;
                     }
+#if 0
+                    if (Property->Flags & KSPROPERTY_TYPE_BASICSUPPORT)
+                    {
+                        if (sizeof(ULONG) > OutputBufferLength)
+                        {
+                            /* too small buffer */
+                            return STATUS_INVALID_PARAMETER;
+                        }
+
+                        /* get output buffer */
+                        Flags = (PULONG)OutputBuffer;
+
+                        /* clear flags */
+                        *Flags = KSPROPERTY_TYPE_BASICSUPPORT;
+
+                        if (PropertySet[Index].PropertyItem[ItemIndex].GetSupported)
+                            *Flags |= KSPROPERTY_TYPE_GET;
+
+                        if (PropertySet[Index].PropertyItem[ItemIndex].SetSupported)
+                            *Flags |= KSPROPERTY_TYPE_SET;
+
+                        IoStatus->Information = sizeof(ULONG);
+
+                        if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION))
+                        {
+                            /* get output buffer */
+                            Description = (PKSPROPERTY_DESCRIPTION)OutputBuffer;
+
+                            /* 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;
+
+                            IoStatus->Information = sizeof(KSPROPERTY_DESCRIPTION);
+                        }
+                    }
+#endif
 
                     if (Property->Flags & KSPROPERTY_TYPE_SET)
                         *PropertyHandler = PropertySet[Index].PropertyItem[ItemIndex].SetPropertyHandler;
@@ -49,6 +94,7 @@ FindPropertyHandler(
                     if (Property->Flags & KSPROPERTY_TYPE_GET)
                         *PropertyHandler = PropertySet[Index].PropertyItem[ItemIndex].GetPropertyHandler;
 
+                    *Set = (PKSPROPERTY_SET)&PropertySet[Index];
                     return STATUS_SUCCESS;
                 }
             }
@@ -67,9 +113,12 @@ KspPropertyHandler(
     IN  ULONG PropertyItemSize OPTIONAL)
 {
     PKSPROPERTY Property;
+    PKSPROPERTY_SET Set;
     PIO_STACK_LOCATION IoStack;
     NTSTATUS Status;
-    PFNKSHANDLER PropertyHandler;
+    PFNKSHANDLER PropertyHandler = NULL;
+    ULONG Index;
+    LPGUID Guid;
 
     /* get current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -84,24 +133,21 @@ KspPropertyHandler(
 
     /* FIXME probe the input / output buffer if from user mode */
 
-
     /* get input property request */
     Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
 
+    DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
+
     /* sanity check */
     ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM));
-    if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Topology))
-    {
-        /* use KsTopologyPropertyHandler for this business */
-        return STATUS_INVALID_PARAMETER;
-    }
 
     /* find the property handler */
-    Status = FindPropertyHandler(&Irp->IoStatus, PropertySet, PropertySetsCount, Property, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &PropertyHandler);
+    Status = FindPropertyHandler(&Irp->IoStatus, PropertySet, PropertySetsCount, Property, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &PropertyHandler, &Set);
 
-    if (NT_SUCCESS(Status))
+    if (NT_SUCCESS(Status) && PropertyHandler)
     {
         /* call property handler */
+        KSPROPERTY_SET_IRP_STORAGE(Irp) = Set;
         Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
 
         if (Status == STATUS_BUFFER_TOO_SMALL)
@@ -124,6 +170,26 @@ KspPropertyHandler(
             }
         }
     }
+    else if (IsEqualGUIDAligned(&Property->Set, &GUID_NULL) && Property->Id == 0 && Property->Flags == KSPROPERTY_TYPE_SETSUPPORT)
+    {
+        // store output size
+        Irp->IoStatus.Information = sizeof(GUID) * PropertySetsCount;
+        if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * PropertySetsCount)
+        {
+            // buffer too small
+            return STATUS_BUFFER_OVERFLOW;
+        }
+
+        // get output buffer
+        Guid = (LPGUID)Irp->UserBuffer;
+
+       // copy property guids from property sets
+       for(Index = 0; Index < PropertySetsCount; Index++)
+       {
+           RtlMoveMemory(&Guid[Index], PropertySet[Index].Set, sizeof(GUID));
+       }
+       return STATUS_SUCCESS;
+    }
 
     /* done */
     return Status;
@@ -200,7 +266,7 @@ FindFastPropertyHandler(
 
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 BOOLEAN
@@ -280,3 +346,22 @@ KsFastPropertyHandler(
     }
     return FALSE;
 }
+
+/*
+    @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsDispatchSpecificProperty(
+    IN  PIRP Irp,
+    IN  PFNKSHANDLER Handler)
+{
+    PIO_STACK_LOCATION IoStack;
+
+    /* get current irp stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    return Handler(Irp, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, Irp->UserBuffer);
+}
+