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
}
/*