Author: janderwald
Date: Wed Aug 19 14:24:28 2009
New Revision: 42784
URL:
http://svn.reactos.org/svn/reactos?rev=42784&view=rev
Log:
- Implement KsProbeStreamIrp
- Currently commented out as gcc finds it hard to find a member in a struct
Modified:
trunk/reactos/drivers/ksfilter/ks/irp.c
Modified: trunk/reactos/drivers/ksfilter/ks/irp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Wed Aug 19 14:24:28 2009
@@ -645,8 +645,402 @@
IN ULONG ProbeFlags,
IN ULONG HeaderSize)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+#if 0
+ PMDL Mdl;
+ PVOID Buffer;
+ LOCK_OPERATION Operation;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PKSSTREAM_HEADER StreamHeader;
+ PIO_STACK_LOCATION IoStack;
+ ULONG Length;
+ BOOLEAN AllocateMdl = FALSE;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ Length = IoStack->Parameters.DeviceIoControl.InputBufferLength;
+
+ if (Irp->RequestorMode == KernelMode || Irp->AssociatedIrp.SystemBuffer)
+ {
+AllocMdl:
+ /* check if alloc mdl flag is passed */
+ if (!(ProbeFlags & KSPROBE_ALLOCATEMDL))
+ {
+ /* nothing more to do */
+ return STATUS_SUCCESS;
+ }
+ if (Irp->MdlAddress)
+ {
+ProbeMdl:
+ if (ProbeFlags & KSPROBE_PROBEANDLOCK)
+ {
+ if (Irp->MdlAddress->MdlFlags & (MDL_PAGES_LOCKED |
MDL_SOURCE_IS_NONPAGED_POOL))
+ {
+ if (ProbeFlags & KSPROBE_SYSTEMADDRESS)
+ {
+ _SEH2_TRY
+ {
+ /* loop through all mdls and probe them */
+ Mdl = Irp->MdlAddress;
+ do
+ {
+ /* the mapping can fail */
+ Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
+
+ if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
MDL_SOURCE_IS_NONPAGED_POOL))
+ {
+ /* no need to probe these pages */
+ Buffer = Mdl->MappedSystemVa;
+ }
+ else
+ {
+ /* probe that mdl */
+ Buffer = MmMapLockedPages(Mdl, KernelMode);
+ }
+
+ /* check if the mapping succeeded */
+ if (!Buffer)
+ {
+ /* raise exception we'll catch */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* iterate to next mdl */
+ Mdl = Mdl->Next;
+
+ }while(Mdl);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ } _SEH2_END;
+ }
+ }
+ else
+ {
+ _SEH2_TRY
+ {
+ /* loop through all mdls and probe them */
+ Mdl = Irp->MdlAddress;
+
+ /* determine operation */
+ Operation = (ProbeFlags & KSPROBE_STREAMWRITE) ?
IoWriteAccess : IoReadAccess;
+
+ do
+ {
+ /* probe the pages */
+ MmProbeAndLockPages(Mdl, Irp->RequestorMode, Operation);
+
+ if (ProbeFlags & KSPROBE_SYSTEMADDRESS)
+ {
+ /* the mapping can fail */
+ Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
+
+ if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
MDL_SOURCE_IS_NONPAGED_POOL))
+ {
+ /* no need to probe these pages */
+ Buffer = Mdl->MappedSystemVa;
+ }
+ else
+ {
+ /* probe that mdl */
+ Buffer = MmMapLockedPages(Mdl, KernelMode);
+ }
+
+ /* check if the mapping succeeded */
+ if (!Buffer)
+ {
+ /* raise exception we'll catch */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+ }
+
+ /* iterate to next mdl */
+ Mdl = Mdl->Next;
+
+ }while(Mdl);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ } _SEH2_END;
+ }
+ }
+ return Status;
+ }
+
+ /* check all stream headers */
+ StreamHeader = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
+
+ _SEH2_TRY
+ {
+ do
+ {
+ if (HeaderSize)
+ {
+ /* does the supplied header size match stream header size and no type
changed */
+ if (StreamHeader->Size != HeaderSize &&
!(StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED))
+ {
+ /* invalid stream header */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+ }
+ else
+ {
+ /* stream must be at least of size KSSTREAM_HEADER and size must be
8-byte block aligned */
+ if (StreamHeader->Size < sizeof(KSSTREAM_HEADER) ||
(StreamHeader->Size & 7))
+ {
+ /* invalid stream header */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+ }
+
+ if (Length < StreamHeader->Size)
+ {
+ /* length is too short */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (ProbeFlags & KSPROBE_STREAMWRITE)
+ {
+ if (StreamHeader->DataUsed > StreamHeader->FrameExtent)
+ {
+ /* frame extend can never be smaller */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ /* is this stream change packet */
+ if (StreamHeader->OptionsFlags &
KSSTREAM_HEADER_OPTIONSF_TYPECHANGED)
+ {
+ if (Length != sizeof(KSSTREAM_HEADER) || (PVOID)StreamHeader !=
Irp->AssociatedIrp.SystemBuffer)
+ {
+ /* stream changed - must be send in a single packet */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (!(ProbeFlags & KSPROBE_ALLOWFORMATCHANGE))
+ {
+ /* caller does not permit format changes */
+ ExRaiseStatus(STATUS_INVALID_PARAMETER);
+ }
+
+ if (StreamHeader->FrameExtend)
+ {
+ /* allocate an mdl */
+ Mdl = IoAllocateMdl(StreamHeader->Data,
StreamHeader->FrameExtend, FALSE, TRUE, Irp);
+
+ if (!Mdl)
+ {
+ /* not enough memory */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* break-out to probe for the irp */
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (StreamHeader->DataUsed)
+ {
+ /* DataUsed must be zero for stream read operation */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (StreamHeader->OptionsFlags)
+ {
+ /* no flags supported for reading */
+ ExRaiseStatus(STATUS_INVALID_PARAMETER);
+ }
+ }
+
+ if (StreamHeader->FrameExtend)
+ {
+ /* allocate an mdl */
+ Mdl = IoAllocateMdl(StreamHeader->Data,
StreamHeader->FrameExtend, Irp->MdlAddress != NULL, TRUE, Irp);
+ if (!Mdl)
+ {
+ /* not enough memory */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+ }
+
+ /* move to next stream header */
+ Length -= StreamHeader->Size;
+ StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader +
StreamHeader->Size);
+ }while(Length);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }_SEH2_END;
+
+ /* now probe the allocated mdl's */
+ if (!NT_SUCCESS(Status))
+ return Status;
+ else
+ goto ProbeMdl;
+ }
+
+ /* probe user mode buffers */
+ if (Length && ( (!HeaderSize) || (Length % HeaderSize == 0) || ((ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE) && (Length == sizeof(KSSTREAM_HEADER))) ) )
+ {
+ /* allocate stream header buffer */
+ Irp->AssociatedIrp.SystemBuffer = ExAllocatePool(NonPagedPool, Length);
+
+ if (!Irp->AssociatedIrp.SystemBuffer)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ _SEH2_TRY
+ {
+ if (ProbeFlags & KSPROBE_STREAMWRITE)
+ {
+ if (ProbeFlags & KSPROBE_MODIFY)
+ ProbeForWrite(Irp->UserBuffer, Length, sizeof(UCHAR));
+ else
+ ProbeForRead(Irp->UserBuffer, Length, sizeof(UCHAR));
+ }
+ else
+ {
+ /* stream reads means writing */
+ ProbeForWrite(Irp->UserBuffer, Length, sizeof(UCHAR));
+ }
+
+ /* copy stream buffer */
+ RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, Irp->UserBuffer,
Length);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }_SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ return Status;
+ }
+
+ if (ProbeFlags & KSPROBE_ALLOCATEMDL)
+ {
+ /* alloc mdls */
+ goto AllocMdl;
+ }
+
+ _SEH2_TRY
+ {
+ do
+ {
+ if (HeaderSize)
+ {
+ /* does the supplied header size match stream header size and no type
changed */
+ if (StreamHeader->Size != HeaderSize &&
!(StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED))
+ {
+ /* invalid stream header */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+ }
+ else
+ {
+ /* stream must be at least of size KSSTREAM_HEADER and size must be
8-byte block aligned */
+ if (StreamHeader->Size < sizeof(KSSTREAM_HEADER) ||
(StreamHeader->Size & 7))
+ {
+ /* invalid stream header */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+ }
+
+ if (Length < StreamHeader->Size)
+ {
+ /* length is too short */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (ProbeFlags & KSPROBE_STREAMWRITE)
+ {
+ if (StreamHeader->DataUsed > StreamHeader->FrameExtend)
+ {
+ /* frame extend can never be smaller */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ /* is this stream change packet */
+ if (StreamHeader->OptionsFlags &
KSSTREAM_HEADER_OPTIONSF_TYPECHANGED)
+ {
+ if (Length != sizeof(KSSTREAM_HEADER) || (PVOID)StreamHeader !=
Irp->AssociatedIrp.SystemBuffer)
+ {
+ /* stream changed - must be send in a single packet */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (!(ProbeFlags & KSPROBE_ALLOWFORMATCHANGE))
+ {
+ /* caller does not permit format changes */
+ ExRaiseStatus(STATUS_INVALID_PARAMETER);
+ }
+
+ if (StreamHeader->FrameExtend)
+ {
+ /* allocate an mdl */
+ Mdl = IoAllocateMdl(StreamHeader->Data,
StreamHeader->FrameExtend, FALSE, TRUE, Irp);
+
+ if (!Mdl)
+ {
+ /* not enough memory */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* break out to probe for the irp */
+ AllocateMdl = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (StreamHeader->DataUsed)
+ {
+ /* DataUsed must be zero for stream read operation */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (StreamHeader->OptionsFlags)
+ {
+ /* no flags supported for reading */
+ ExRaiseStatus(STATUS_INVALID_PARAMETER);
+ }
+ }
+
+ /* move to next stream header */
+ Length -= StreamHeader->Size;
+ StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader +
StreamHeader->Size);
+ }while(Length);
+
+ }_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }_SEH2_END;
+
+ /* now probe the allocated mdl's */
+ if (NT_SUCCESS(Status))
+ goto AllocMdl;
+ else
+ return Status;
+ }
+
+ return STATUS_INVALID_BUFFER_SIZE;
+#else
+ UNIMPLEMENTED
+ return STATUS_NOT_IMPLEMENTED;
+#endif
}
/*