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…
==============================================================================
--- 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/proper…
==============================================================================
--- 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;
}