windows-nt/Source/XPSP1/NT/base/fs/rdr2/inc/fsctlbuf.h
2020-09-26 16:20:57 +08:00

158 lines
5.4 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
FsCtlBuf.h
Abstract:
This module defines routines that get the buffers for the various types of ioctl/fsctls. It is essntially
just the reverse of the IopXXXControlFile routine in io\internal.c, the appropriate parts of which are
reproduced here.
Author:
Joe Linn [JoeLinn] 4-aug-1994
Revision History:
--*/
#ifndef _fsctlbuf_
#define _fsctlbuf_
// the presentation here is in three pieces: the macros for METHODBUFFERED, METHODDIRECT, AND METHODNEITHER.
// it's set up this way so that you can find out what you've got just by reading this and not looking thru
// IO system....
/* here is the code for case 0
case 0:
//
// For this case, allocate a buffer that is large enough to contain
// both the input and the output buffers. Copy the input buffer to
// the allocated buffer and set the appropriate IRP fields.
//
try {
if (InputBufferLength || OutputBufferLength) {
irp->AssociatedIrp.SystemBuffer =
RxAllocatePool( poolType,
(InputBufferLength > OutputBufferLength) ? InputBufferLength : OutputBufferLength );
if (ARGUMENT_PRESENT( InputBuffer )) {
RtlCopyMemory( irp->AssociatedIrp.SystemBuffer,
InputBuffer,
InputBufferLength );
}
irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
irp->UserBuffer = OutputBuffer;
if (ARGUMENT_PRESENT( OutputBuffer )) {
irp->Flags |= IRP_INPUT_OPERATION;
}
} else {
irp->Flags = 0;
irp->UserBuffer = (PVOID) NULL;
}
} except(EXCEPTION_EXECUTE_HANDLER) {
<<<elided>>>
}
break;
So, the bottom line is that irp->AssociatedIrp.SystemBuffer is a buffer of length (I-length+O-length) and
is preloaded with the input. Even though the original outputbuffer is passed thru in irp->UserBuffer, it is not to be used
in the FS; rather the FS writes its answer into the same buffer. we get the
following macros:
*/
#define METHODBUFFERED_SharedBuffer(IRP) (IRP)->AssociatedIrp.SystemBuffer
/* for 1 and 2
case 1:
case 2:
//
// For these two cases, allocate a buffer that is large enough to
// contain the input buffer, if any, and copy the information to
// the allocated buffer. Then build an MDL for either read or write
// access, depending on the method, for the output buffer. Note
// that the buffer length parameters have been jammed to zero for
// users if the buffer parameter was not passed. (Kernel callers
// should be calling the service correctly in the first place.)
//
// Note also that it doesn't make a whole lot of sense to specify
// either method #1 or #2 if the IOCTL does not require the caller
// to specify an output buffer.
//
try {
if (InputBufferLength && ARGUMENT_PRESENT( InputBuffer )) {
irp->AssociatedIrp.SystemBuffer =
RxAllocatePool( poolType, InputBufferLength );
RtlCopyMemory( irp->AssociatedIrp.SystemBuffer,
InputBuffer,
InputBufferLength );
irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
} else {
irp->Flags = 0;
}
if (OutputBufferLength != 0) {
irp->MdlAddress = IoAllocateMdl( OutputBuffer,
OutputBufferLength,
FALSE,
TRUE,
irp );
if (irp->MdlAddress == NULL) {
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
}
MmProbeAndLockPages( irp->MdlAddress,
requestorMode,
(LOCK_OPERATION) ((method == 1) ? IoReadAccess : IoWriteAccess) );
}
} except(EXCEPTION_EXECUTE_HANDLER) {
<<<ELIDED>>>
}
break;
So the deal is that the input buffer has been copied in as in case 0 but what we have is an MDL for
the output buffer. this leads to the following
*/
#define METHODDIRECT_BufferedInputBuffer(IRP) ((IRP)->AssociatedIrp.SystemBuffer)
#define METHODDIRECT_DirectBuffer(IRP) (((IRP)->MdlAddress) \
? MmGetSystemAddressForMdlSafe((IRP)->MdlAddress,NormalPagePriority):NULL)
/* and finally
case 3:
//
// For this case, do nothing. Everything is up to the driver.
// Simply give the driver a copy of the caller's parameters and
// let the driver do everything itself.
//
irp->UserBuffer = OutputBuffer;
irpSp->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
}
So we can get 'em.....but we don't really know how they're gonna be used. Nevertheless.......
*/
#define METHODNEITHER_OriginalInputBuffer(IRPSP) ((IRPSP)->Parameters.DeviceIoControl.Type3InputBuffer)
#define METHODNEITHER_OriginalOutputBuffer(IRP) ((IRP)->UserBuffer)
#endif // _fsctlbuf_