mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: FSP_FSCTL_TRANSACT/FSP_FSCTL_TRANSACT_BATCH
This commit is contained in:
		| @@ -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); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user