mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
sys: FSP_FSCTL_TRANSACT/FSP_FSCTL_TRANSACT_BATCH
This commit is contained in:
parent
440f66a786
commit
d1fe27f996
@ -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
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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,
|
||||||
|
@ -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'
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user