sys: FSP_FSCTL_TRANSACT/FSP_FSCTL_TRANSACT_BATCH

This commit is contained in:
Bill Zissimopoulos
2016-02-15 15:07:05 -08:00
parent 440f66a786
commit d1fe27f996
8 changed files with 31 additions and 14 deletions

View File

@ -84,7 +84,8 @@ exit:
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
PVOID ResponseBuf, SIZE_T ResponseBufSize,
PVOID RequestBuf, SIZE_T *PRequestBufSize)
PVOID RequestBuf, SIZE_T *PRequestBufSize,
BOOLEAN Batch)
{
NTSTATUS Result = STATUS_SUCCESS;
DWORD Bytes = 0;
@ -95,7 +96,8 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
*PRequestBufSize = 0;
}
if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_TRANSACT,
if (!DeviceIoControl(VolumeHandle,
Batch ? FSP_FSCTL_TRANSACT_BATCH : FSP_FSCTL_TRANSACT,
ResponseBuf, (DWORD)ResponseBufSize, RequestBuf, Bytes,
&Bytes, 0))
{

View File

@ -70,14 +70,14 @@ FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem)
SIZE_T RequestBufSize;
FSP_FSCTL_TRANSACT_REQ *Request, *NextRequest;
RequestBuf = MemAlloc(FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN);
RequestBuf = MemAlloc(FSP_FSCTL_TRANSACT_REQ_SIZEMAX);
if (0 == RequestBuf)
return STATUS_INSUFFICIENT_RESOURCES;
for (;;)
{
RequestBufSize = FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN;
Result = FspFsctlTransact(FileSystem->VolumeHandle, 0, 0, RequestBuf, &RequestBufSize);
RequestBufSize = FSP_FSCTL_TRANSACT_REQ_SIZEMAX;
Result = FspFsctlTransact(FileSystem->VolumeHandle, 0, 0, RequestBuf, &RequestBufSize, FALSE);
if (!NT_SUCCESS(Result))
goto exit;
@ -178,7 +178,7 @@ FSP_API VOID FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem,
FSP_API NTSTATUS FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_RSP *Response)
{
return FspFsctlTransact(FileSystem->VolumeHandle, Response, Response->Size, 0, 0);
return FspFsctlTransact(FileSystem->VolumeHandle, Response, Response->Size, 0, 0, FALSE);
}
FSP_API NTSTATUS FspFileSystemSendResponseWithStatus(FSP_FILE_SYSTEM *FileSystem,

View File

@ -159,6 +159,7 @@ const char *IoctlCodeSym(ULONG ControlCode)
{
SYM(FSP_FSCTL_VOLUME_NAME)
SYM(FSP_FSCTL_TRANSACT)
SYM(FSP_FSCTL_TRANSACT_BATCH)
SYM(FSP_FSCTL_WORK)
SYM(FSP_FSCTL_WORK_BEST_EFFORT)
// cygwin: sed -n '/[IF][OS]CTL.*CTL_CODE/s/^#define[ \t]*\([^ \t]*\).*/SYM(\1)/p'

View File

@ -36,6 +36,7 @@ static NTSTATUS FspFsctlFileSystemControl(
Result = FspVolumeGetName(DeviceObject, Irp, IrpSp);
break;
case FSP_FSCTL_TRANSACT:
case FSP_FSCTL_TRANSACT_BATCH:
if (0 != IrpSp->FileObject->FsContext2)
Result = FspVolumeTransact(DeviceObject, Irp, IrpSp);
break;

View File

@ -496,11 +496,14 @@ NTSTATUS FspVolumeTransact(
ASSERT(IRP_MJ_FILE_SYSTEM_CONTROL == IrpSp->MajorFunction);
ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction);
ASSERT(FSP_FSCTL_TRANSACT == IrpSp->Parameters.FileSystemControl.FsControlCode);
ASSERT(
FSP_FSCTL_TRANSACT == IrpSp->Parameters.FileSystemControl.FsControlCode ||
FSP_FSCTL_TRANSACT_BATCH == IrpSp->Parameters.FileSystemControl.FsControlCode);
ASSERT(0 != IrpSp->FileObject->FsContext2);
/* check parameters */
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
ULONG ControlCode = IrpSp->Parameters.FileSystemControl.FsControlCode;
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
PVOID SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
@ -509,7 +512,10 @@ NTSTATUS FspVolumeTransact(
FSP_FSCTL_DEFAULT_ALIGN_UP(sizeof(FSP_FSCTL_TRANSACT_RSP)) > InputBufferLength)
return STATUS_INVALID_PARAMETER;
if (0 != OutputBufferLength &&
FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN > OutputBufferLength)
((FSP_FSCTL_TRANSACT == ControlCode &&
FSP_FSCTL_TRANSACT_REQ_SIZEMAX > OutputBufferLength) ||
(FSP_FSCTL_TRANSACT_BATCH == ControlCode &&
FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN > OutputBufferLength)))
return STATUS_BUFFER_TOO_SMALL;
if (!FspDeviceReference(FsvolDeviceObject))
@ -645,6 +651,10 @@ NTSTATUS FspVolumeTransact(
goto exit;
}
/* are we doing single request or batch mode? */
if (FSP_FSCTL_TRANSACT == ControlCode)
break;
/* check that we have enough space before pulling the next pending IRP off the queue */
if (!FspFsctlTransactCanProduceRequest(Request, BufferEnd))
break;