- Implement KsProbeStreamIrp

- Currently commented out as gcc finds it hard to find a member in a struct

svn path=/trunk/; revision=42784
This commit is contained in:
Johannes Anderwald 2009-08-19 12:24:28 +00:00
parent 9639b5995d
commit 9d6768ef65

View file

@ -645,8 +645,402 @@ KsProbeStreamIrp(
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
}
/*