mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +00:00
- 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:
parent
9639b5995d
commit
9d6768ef65
|
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue