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/propert... ============================================================================== --- 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; }