Author: janderwald
Date: Fri Aug 14 21:44:01 2009
New Revision: 42669

URL: http://svn.reactos.org/svn/reactos?rev=42669&view=rev
Log:
- Implement KsPropertyHandler, KsPropertyHandlerWithAllocator, 
KsFastPropertyHandler

Modified:
    trunk/reactos/drivers/ksfilter/ks/filter.c
    trunk/reactos/drivers/ksfilter/ks/property.c

Modified: trunk/reactos/drivers/ksfilter/ks/filter.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filter.c?rev=42669&r1=42668&r2=42669&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] Fri Aug 14 21:44:01 
2009
@@ -637,57 +637,6 @@
 }
 
 NTSTATUS
-FindPropertyHandler(
-    IN PIO_STATUS_BLOCK IoStatus,
-    IN KSPROPERTY_SET * FilterPropertySet,
-    IN ULONG FilterPropertySetCount,
-    IN PKSPROPERTY Property,
-    IN ULONG InputBufferLength,
-    IN ULONG OutputBufferLength,
-    OUT PFNKSHANDLER *PropertyHandler)
-{
-    ULONG Index, ItemIndex;
-
-    for(Index = 0; Index < FilterPropertySetCount; Index++)
-    {
-        if (IsEqualGUIDAligned(&Property->Set, FilterPropertySet[Index].Set))
-        {
-            for(ItemIndex = 0; ItemIndex < 
FilterPropertySet[Index].PropertiesCount; ItemIndex++)
-            {
-                if 
(FilterPropertySet[Index].PropertyItem[ItemIndex].PropertyId == Property->Id)
-                {
-                    if (Property->Flags & KSPROPERTY_TYPE_SET)
-                        *PropertyHandler = 
FilterPropertySet[Index].PropertyItem[ItemIndex].SetPropertyHandler;
-
-                    if (Property->Flags & KSPROPERTY_TYPE_GET)
-                        *PropertyHandler = 
FilterPropertySet[Index].PropertyItem[ItemIndex].GetPropertyHandler;
-
-                    if 
(FilterPropertySet[Index].PropertyItem[ItemIndex].MinProperty > 
InputBufferLength)
-                    {
-                        /* too small input buffer */
-                        IoStatus->Information = 
FilterPropertySet[Index].PropertyItem[ItemIndex].MinProperty;
-                        IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
-                        return STATUS_BUFFER_TOO_SMALL;
-                    }
-
-                    if 
(FilterPropertySet[Index].PropertyItem[ItemIndex].MinData > OutputBufferLength)
-                    {
-                        /* too small output buffer */
-                        IoStatus->Information = 
FilterPropertySet[Index].PropertyItem[ItemIndex].MinData;
-                        IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
-                        return STATUS_BUFFER_TOO_SMALL;
-                    }
-                    return STATUS_SUCCESS;
-                }
-            }
-        }
-    }
-    return STATUS_UNSUCCESSFUL;
-}
-
-
-
-NTSTATUS
 NTAPI
 IKsFilter_DispatchDeviceIoControl(
     IN PDEVICE_OBJECT DeviceObject,
@@ -724,7 +673,7 @@
     }
 
     /* find a supported property handler */
-    Status = FindPropertyHandler(&Irp->IoStatus, FilterPropertySet, 2, 
IoStack->Parameters.DeviceIoControl.Type3InputBuffer, 
IoStack->Parameters.DeviceIoControl.InputBufferLength, 
IoStack->Parameters.DeviceIoControl.OutputBufferLength, &PropertyHandler);
+    Status = KsPropertyHandler(Irp, 2, FilterPropertySet);
     if (NT_SUCCESS(Status))
     {
         KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)This;

Modified: trunk/reactos/drivers/ksfilter/ks/property.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/property.c?rev=42669&r1=42668&r2=42669&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/property.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/property.c [iso-8859-1] Fri Aug 14 
21:44:01 2009
@@ -8,8 +8,129 @@
 
 #include "priv.h"
 
-/*
-    @unimplemented
+
+NTSTATUS
+FindPropertyHandler(
+    IN PIO_STATUS_BLOCK IoStatus,
+    IN  const KSPROPERTY_SET* PropertySet,
+    IN ULONG PropertySetCount,
+    IN PKSPROPERTY Property,
+    IN ULONG InputBufferLength,
+    IN ULONG OutputBufferLength,
+    OUT PFNKSHANDLER *PropertyHandler)
+{
+    ULONG Index, ItemIndex;
+
+    for(Index = 0; Index < PropertySetCount; Index++)
+    {
+        if (IsEqualGUIDAligned(&Property->Set, PropertySet[Index].Set))
+        {
+            for(ItemIndex = 0; ItemIndex < PropertySet[Index].PropertiesCount; 
ItemIndex++)
+            {
+                if (PropertySet[Index].PropertyItem[ItemIndex].PropertyId == 
Property->Id)
+                {
+                    if (PropertySet[Index].PropertyItem[ItemIndex].MinProperty 
> InputBufferLength)
+                    {
+                        /* too small input buffer */
+                        IoStatus->Information = 
PropertySet[Index].PropertyItem[ItemIndex].MinProperty;
+                        return STATUS_INVALID_PARAMETER;
+                    }
+
+                    if (PropertySet[Index].PropertyItem[ItemIndex].MinData > 
OutputBufferLength)
+                    {
+                        /* too small output buffer */
+                        IoStatus->Information = 
PropertySet[Index].PropertyItem[ItemIndex].MinData;
+                        return STATUS_BUFFER_TOO_SMALL;
+                    }
+
+                    if (Property->Flags & KSPROPERTY_TYPE_SET)
+                        *PropertyHandler = 
PropertySet[Index].PropertyItem[ItemIndex].SetPropertyHandler;
+
+                    if (Property->Flags & KSPROPERTY_TYPE_GET)
+                        *PropertyHandler = 
PropertySet[Index].PropertyItem[ItemIndex].GetPropertyHandler;
+
+                    return STATUS_SUCCESS;
+                }
+            }
+        }
+    }
+    return STATUS_NOT_FOUND;
+}
+
+
+NTSTATUS
+KspPropertyHandler(
+    IN PIRP Irp,
+    IN  ULONG PropertySetsCount,
+    IN  const KSPROPERTY_SET* PropertySet,
+    IN  PFNKSALLOCATOR Allocator OPTIONAL,
+    IN  ULONG PropertyItemSize OPTIONAL)
+{
+    PKSPROPERTY Property;
+    PIO_STACK_LOCATION IoStack;
+    NTSTATUS Status;
+    PFNKSHANDLER PropertyHandler;
+
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* check if inputbuffer at least holds KSPROPERTY item */
+    if (IoStack->Parameters.DeviceIoControl.InputBufferLength < 
sizeof(KSPROPERTY))
+    {
+        /* invalid parameter */
+        Irp->IoStatus.Information = sizeof(KSPROPERTY);
+        return STATUS_INVALID_BUFFER_SIZE;
+    }
+
+    /* FIXME probe the input / output buffer if from user mode */
+
+
+    /* get input property request */
+    Property = 
(PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    /* 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);
+
+    if (NT_SUCCESS(Status))
+    {
+        /* call property handler */
+        Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
+
+        if (Status == STATUS_BUFFER_TOO_SMALL)
+        {
+            /* output buffer is too small */
+            if (Allocator)
+            {
+                /* allocate the requested amount */
+                Status = Allocator(Irp, Irp->IoStatus.Information, FALSE);
+
+                /* check if the block was allocated */
+                if (!NT_SUCCESS(Status))
+                {
+                    /* no memory */
+                    return STATUS_INSUFFICIENT_RESOURCES;
+                }
+
+                /* re-call property handler */
+                Status = PropertyHandler(Irp, Property, Irp->UserBuffer);
+            }
+        }
+    }
+
+    /* done */
+    return Status;
+}
+
+/*
+    @implemented
 */
 KSDDKAPI
 NTSTATUS
@@ -19,13 +140,12 @@
     IN  ULONG PropertySetsCount,
     IN  const KSPROPERTY_SET* PropertySet)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
-}
-
-
-/*
-    @unimplemented
+    return KspPropertyHandler(Irp, PropertySetsCount, PropertySet, NULL, 0);
+}
+
+
+/*
+    @implemented
 */
 KSDDKAPI
 NTSTATUS
@@ -37,9 +157,47 @@
     IN  PFNKSALLOCATOR Allocator OPTIONAL,
     IN  ULONG PropertyItemSize OPTIONAL)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
-}
+    return KspPropertyHandler(Irp, PropertySetsCount, PropertySet, Allocator, 
PropertyItemSize);
+}
+
+NTSTATUS
+FindFastPropertyHandler(
+    IN ULONG FastIoCount,
+    IN const KSFASTPROPERTY_ITEM * FastIoTable,
+    IN PKSPROPERTY PropertyId,
+    OUT PFNKSFASTHANDLER * FastPropertyHandler)
+{
+    ULONG Index;
+
+    /* iterate through all items */
+    for(Index = 0; Index < FastIoCount; Index++)
+    {
+        if (PropertyId->Id == FastIoTable[Index].PropertyId)
+        {
+            if (PropertyId->Flags & KSPROPERTY_TYPE_SET)
+            {
+                if (FastIoTable[Index].SetSupported)
+                {
+                    *FastPropertyHandler = 
FastIoTable[Index].SetPropertyHandler;
+                    return STATUS_SUCCESS;
+                }
+            }
+
+            if (PropertyId->Flags & KSPROPERTY_TYPE_GET)
+            {
+                if (FastIoTable[Index].GetSupported)
+                {
+                    *FastPropertyHandler = 
FastIoTable[Index].GetPropertyHandler;
+                    return STATUS_SUCCESS;
+                }
+            }
+        }
+
+    }
+    /* no fast property handler found */
+    return STATUS_NOT_FOUND;
+}
+
 
 /*
     @unimplemented
@@ -57,6 +215,68 @@
     IN  ULONG PropertySetsCount,
     IN  const KSPROPERTY_SET* PropertySet)
 {
-    UNIMPLEMENTED;
+    KSPROPERTY PropRequest;
+    KPROCESSOR_MODE Mode;
+    NTSTATUS Status = STATUS_SUCCESS;
+    ULONG Index;
+    PFNKSFASTHANDLER FastPropertyHandler;
+
+    if (PropertyLength < sizeof(KSPROPERTY))
+    {
+        /* invalid request */
+        return FALSE;
+    }
+
+    /* get previous mode */
+    Mode = ExGetPreviousMode();
+
+    if (Mode == KernelMode)
+    {
+        /* just copy it */
+        RtlMoveMemory(&PropRequest, Property, sizeof(KSPROPERTY));
+    }
+    else
+    {
+        /* need to probe the buffer */
+        _SEH2_TRY
+        {
+            ProbeForRead(Property, sizeof(KSPROPERTY), sizeof(UCHAR));
+            RtlMoveMemory(&PropRequest, Property, sizeof(KSPROPERTY));
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            /* Exception, get the error code */
+            Status = _SEH2_GetExceptionCode();
+        }_SEH2_END;
+
+        if (!NT_SUCCESS(Status))
+            return FALSE;
+    }
+
+    /* are there any property sets provided */
+    if (PropertySetsCount)
+    {
+        /* iterate through all property sets count */
+        Index = 0;
+        do
+        {
+            /* does the property id match */
+            if (IsEqualGUIDAligned(PropertySet[Index].Set, &PropRequest.Set))
+            {
+                /* try to find a fast property handler */
+                Status = 
FindFastPropertyHandler(PropertySet[Index].FastIoCount, 
PropertySet[Index].FastIoTable, &PropRequest, &FastPropertyHandler);
+
+                if (NT_SUCCESS(Status))
+                {
+                    /* call fast property handler */
+                    ASSERT(PropertyLength == sizeof(KSPROPERTY)); /* FIXME 
check if property length is bigger -> copy params */
+                    ASSERT(Mode == KernelMode); /* FIXME need to probe 
usermode output buffer */
+                    return FastPropertyHandler(FileObject, &PropRequest, 
sizeof(KSPROPERTY), Data, DataLength, IoStatus);
+                }
+            }
+            /* move to next item */
+            Index++;
+        }while(Index < PropertySetsCount);
+    }
     return FALSE;
 }


Reply via email to