mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +00:00
- Implement KsPropertyHandler, KsPropertyHandlerWithAllocator, KsFastPropertyHandler
svn path=/trunk/; revision=42669
This commit is contained in:
parent
11a3ac6f28
commit
74bd2a036d
|
@ -636,57 +636,6 @@ KspPinPropertyHandler(
|
|||
return Status;
|
||||
}
|
||||
|
||||
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(
|
||||
|
@ -724,7 +673,7 @@ IKsFilter_DispatchDeviceIoControl(
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
|
|
@ -8,8 +8,129 @@
|
|||
|
||||
#include "priv.h"
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
@unimplemented
|
||||
@implemented
|
||||
*/
|
||||
KSDDKAPI
|
||||
NTSTATUS
|
||||
|
@ -19,13 +140,12 @@ KsPropertyHandler(
|
|||
IN ULONG PropertySetsCount,
|
||||
IN const KSPROPERTY_SET* PropertySet)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
return KspPropertyHandler(Irp, PropertySetsCount, PropertySet, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@unimplemented
|
||||
@implemented
|
||||
*/
|
||||
KSDDKAPI
|
||||
NTSTATUS
|
||||
|
@ -37,10 +157,48 @@ KsPropertyHandlerWithAllocator(
|
|||
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 @@ KsFastPropertyHandler(
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue