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

@ -36,6 +36,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS) CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSP_FSCTL_TRANSACT \ #define FSP_FSCTL_TRANSACT \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_OUT_DIRECT, FILE_ANY_ACCESS) CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define FSP_FSCTL_TRANSACT_BATCH \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 't', METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define FSP_FSCTL_VOLUME_NAME_SIZEMAX 128 #define FSP_FSCTL_VOLUME_NAME_SIZEMAX 128
@ -317,7 +319,8 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
PHANDLE PVolumeHandle); PHANDLE PVolumeHandle);
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
PVOID ResponseBuf, SIZE_T ResponseBufSize, PVOID ResponseBuf, SIZE_T ResponseBufSize,
PVOID RequestBuf, SIZE_T *PRequestBufSize); PVOID RequestBuf, SIZE_T *PRequestBufSize,
BOOLEAN Batch);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

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

View File

@ -70,14 +70,14 @@ FSP_API NTSTATUS FspFileSystemLoop(FSP_FILE_SYSTEM *FileSystem)
SIZE_T RequestBufSize; SIZE_T RequestBufSize;
FSP_FSCTL_TRANSACT_REQ *Request, *NextRequest; FSP_FSCTL_TRANSACT_REQ *Request, *NextRequest;
RequestBuf = MemAlloc(FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN); RequestBuf = MemAlloc(FSP_FSCTL_TRANSACT_REQ_SIZEMAX);
if (0 == RequestBuf) if (0 == RequestBuf)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
for (;;) for (;;)
{ {
RequestBufSize = FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMIN; RequestBufSize = FSP_FSCTL_TRANSACT_REQ_SIZEMAX;
Result = FspFsctlTransact(FileSystem->VolumeHandle, 0, 0, RequestBuf, &RequestBufSize); Result = FspFsctlTransact(FileSystem->VolumeHandle, 0, 0, RequestBuf, &RequestBufSize, FALSE);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -178,7 +178,7 @@ FSP_API VOID FspFileSystemPoolDispatcher(FSP_FILE_SYSTEM *FileSystem,
FSP_API NTSTATUS FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_RSP *Response) 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, 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_VOLUME_NAME)
SYM(FSP_FSCTL_TRANSACT) SYM(FSP_FSCTL_TRANSACT)
SYM(FSP_FSCTL_TRANSACT_BATCH)
SYM(FSP_FSCTL_WORK) SYM(FSP_FSCTL_WORK)
SYM(FSP_FSCTL_WORK_BEST_EFFORT) SYM(FSP_FSCTL_WORK_BEST_EFFORT)
// cygwin: sed -n '/[IF][OS]CTL.*CTL_CODE/s/^#define[ \t]*\([^ \t]*\).*/SYM(\1)/p' // 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); Result = FspVolumeGetName(DeviceObject, Irp, IrpSp);
break; break;
case FSP_FSCTL_TRANSACT: case FSP_FSCTL_TRANSACT:
case FSP_FSCTL_TRANSACT_BATCH:
if (0 != IrpSp->FileObject->FsContext2) if (0 != IrpSp->FileObject->FsContext2)
Result = FspVolumeTransact(DeviceObject, Irp, IrpSp); Result = FspVolumeTransact(DeviceObject, Irp, IrpSp);
break; break;

View File

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

View File

@ -184,7 +184,7 @@ void mount_volume_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
ResponseBufSize = 0; ResponseBufSize = 0;
RequestBufSize = sizeof RequestBuf; RequestBufSize = sizeof RequestBuf;
Result = FspFsctlTransact(VolumeHandle, 0, 0, RequestBuf, &RequestBufSize); Result = FspFsctlTransact(VolumeHandle, 0, 0, RequestBuf, &RequestBufSize, TRUE);
ASSERT(STATUS_SUCCESS == Result); ASSERT(STATUS_SUCCESS == Result);
RequestBufEnd = RequestBuf + RequestBufSize; RequestBufEnd = RequestBuf + RequestBufSize;
@ -235,7 +235,7 @@ void mount_volume_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
ResponseBufSize = (PUINT8)Response - ResponseBuf; ResponseBufSize = (PUINT8)Response - ResponseBuf;
RequestBufSize = 0; RequestBufSize = 0;
Result = FspFsctlTransact(VolumeHandle, ResponseBuf, ResponseBufSize, 0, &RequestBufSize); Result = FspFsctlTransact(VolumeHandle, ResponseBuf, ResponseBufSize, 0, &RequestBufSize, TRUE);
ASSERT(STATUS_SUCCESS == Result); ASSERT(STATUS_SUCCESS == Result);
Success = CloseHandle(VolumeHandle); Success = CloseHandle(VolumeHandle);

View File

@ -179,7 +179,7 @@ void timeout_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
ResponseBufSize = 0; ResponseBufSize = 0;
RequestBufSize = sizeof RequestBuf; RequestBufSize = sizeof RequestBuf;
Result = FspFsctlTransact(VolumeHandle, ResponseBuf, ResponseBufSize, RequestBuf, &RequestBufSize); Result = FspFsctlTransact(VolumeHandle, ResponseBuf, ResponseBufSize, RequestBuf, &RequestBufSize, TRUE);
ASSERT(STATUS_SUCCESS == Result); ASSERT(STATUS_SUCCESS == Result);
ASSERT(0 == RequestBufSize); ASSERT(0 == RequestBufSize);
@ -190,7 +190,7 @@ void timeout_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
ResponseBufSize = 0; ResponseBufSize = 0;
RequestBufSize = sizeof RequestBuf; RequestBufSize = sizeof RequestBuf;
Result = FspFsctlTransact(VolumeHandle, ResponseBuf, ResponseBufSize, RequestBuf, &RequestBufSize); Result = FspFsctlTransact(VolumeHandle, ResponseBuf, ResponseBufSize, RequestBuf, &RequestBufSize, TRUE);
ASSERT(STATUS_SUCCESS == Result); ASSERT(STATUS_SUCCESS == Result);
RequestBufEnd = RequestBuf + RequestBufSize; RequestBufEnd = RequestBuf + RequestBufSize;
@ -222,7 +222,7 @@ void timeout_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
ResponseBufSize = 0; ResponseBufSize = 0;
RequestBufSize = sizeof RequestBuf; RequestBufSize = sizeof RequestBuf;
Result = FspFsctlTransact(VolumeHandle, ResponseBuf, ResponseBufSize, RequestBuf, &RequestBufSize); Result = FspFsctlTransact(VolumeHandle, ResponseBuf, ResponseBufSize, RequestBuf, &RequestBufSize, TRUE);
ASSERT(STATUS_SUCCESS == Result); ASSERT(STATUS_SUCCESS == Result);
ASSERT(0 == RequestBufSize); ASSERT(0 == RequestBufSize);