From c97f2cb66023eccd2f87b21f5d5297ed8f1a9cd6 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sun, 7 Jul 2019 12:12:04 -0700 Subject: [PATCH] dotnet: add MountEx and fine-grained timeouts --- src/dotnet/FileSystemHost.cs | 188 +++++++++++++++++++++++++++-------- src/dotnet/Interop.cs | 15 +++ 2 files changed, 163 insertions(+), 40 deletions(-) diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs index 1c53a06f..ec2e5bda 100644 --- a/src/dotnet/FileSystemHost.cs +++ b/src/dotnet/FileSystemHost.cs @@ -40,6 +40,7 @@ namespace Fsp /// The file system to host. public FileSystemHost(FileSystemBase FileSystem) { + _VolumeParams.Version = (UInt16)Marshal.SizeOf(_VolumeParams); _VolumeParams.Flags = VolumeParams.UmFileContextIsFullContext; _FileSystem = FileSystem; } @@ -126,6 +127,86 @@ namespace Fsp set { _VolumeParams.FileInfoTimeout = value; } } /// + /// Gets or sets the volume information timeout. + /// + public UInt32 VolumeInfoTimeout + { + get + { + return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.VolumeInfoTimeoutValid) ? + _VolumeParams.VolumeInfoTimeout : _VolumeParams.FileInfoTimeout; + } + set + { + _VolumeParams.AdditionalFlags |= VolumeParams.VolumeInfoTimeoutValid; + _VolumeParams.VolumeInfoTimeout = value; + } + } + /// + /// Gets or sets the directory information timeout. + /// + public UInt32 DirInfoTimeout + { + get + { + return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.DirInfoTimeoutValid) ? + _VolumeParams.DirInfoTimeout : _VolumeParams.FileInfoTimeout; + } + set + { + _VolumeParams.AdditionalFlags |= VolumeParams.DirInfoTimeoutValid; + _VolumeParams.DirInfoTimeout = value; + } + } + /// + /// Gets or sets the security information timeout. + /// + public UInt32 SecurityTimeout + { + get + { + return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.SecurityTimeoutValid) ? + _VolumeParams.SecurityTimeout : _VolumeParams.FileInfoTimeout; + } + set + { + _VolumeParams.AdditionalFlags |= VolumeParams.SecurityTimeoutValid; + _VolumeParams.SecurityTimeout = value; + } + } + /// + /// Gets or sets the stream information timeout. + /// + public UInt32 StreamInfoTimeout + { + get + { + return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.StreamInfoTimeoutValid) ? + _VolumeParams.StreamInfoTimeout : _VolumeParams.FileInfoTimeout; + } + set + { + _VolumeParams.AdditionalFlags |= VolumeParams.StreamInfoTimeoutValid; + _VolumeParams.StreamInfoTimeout = value; + } + } + /// + /// Gets or sets the EA information timeout. + /// + public UInt32 EaTimeout + { + get + { + return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.EaTimeoutValid) ? + _VolumeParams.EaTimeout : _VolumeParams.FileInfoTimeout; + } + set + { + _VolumeParams.AdditionalFlags |= VolumeParams.EaTimeoutValid; + _VolumeParams.EaTimeout = value; + } + } + /// /// Gets or sets a value that determines whether the file system is case sensitive. /// public Boolean CaseSensitiveSearch @@ -279,11 +360,44 @@ namespace Fsp /// A value of 0 disables all debug logging. /// A value of -1 enables all debug logging. /// - /// + /// STATUS_SUCCESS or error code. public Int32 Mount(String MountPoint, Byte[] SecurityDescriptor = null, Boolean Synchronized = false, UInt32 DebugLog = 0) + { + return MountEx(MountPoint, 0, SecurityDescriptor, Synchronized, DebugLog); + } + /// + /// Mounts a file system. + /// + /// + /// The mount point for the new file system. A value of null means that + /// the file system should use the next available drive letter counting + /// downwards from Z: as its mount point. + /// + /// + /// Number of threads to use to service file system requests. A value + /// of 0 means that the default number of threads should be used. + /// + /// + /// Security descriptor to use if mounting on (newly created) directory. + /// A value of null means the directory should be created with default + /// security. + /// + /// + /// If true file system operations are synchronized using an exclusive lock. + /// + /// + /// A value of 0 disables all debug logging. + /// A value of -1 enables all debug logging. + /// + /// STATUS_SUCCESS or error code. + public Int32 MountEx(String MountPoint, + UInt32 ThreadCount, + Byte[] SecurityDescriptor = null, + Boolean Synchronized = false, + UInt32 DebugLog = 0) { Int32 Result; try @@ -320,7 +434,7 @@ namespace Fsp } if (0 <= Result) { - Result = Api.FspFileSystemStartDispatcher(_FileSystemPtr, 0); + Result = Api.FspFileSystemStartDispatcher(_FileSystemPtr, ThreadCount); if (0 > Result) try { @@ -394,6 +508,28 @@ namespace Fsp return Api.FspFileSystemGetOperationRequestHint(); } /// + /// Asynchronously complete a Read operation. + /// + /// + /// A reference to the operation to complete. + /// + /// + /// STATUS_SUCCESS or error code. + /// + /// + /// Number of bytes read. + /// + public void SendReadResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred) + { + FspFsctlTransactRsp Response = default(FspFsctlTransactRsp); + Response.Size = 128; + Response.Kind = (UInt32)FspFsctlTransact.ReadKind; + Response.Hint = RequestHint; + Response.IoStatus.Information = BytesTransferred; + Response.IoStatus.Status = (UInt32)Status; + Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response); + } + /// /// Asynchronously complete a Write operation. /// /// @@ -410,42 +546,16 @@ namespace Fsp /// public void SendWriteResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred, ref FileInfo FileInfo) { - var Response = new FspFsctlTransactRsp() - { - Size = 128, - Kind = (UInt32) FspFsctlTransact.WriteKind, - Hint = RequestHint - }; + FspFsctlTransactRsp Response = default(FspFsctlTransactRsp); + Response.Size = 128; + Response.Kind = (UInt32)FspFsctlTransact.WriteKind; + Response.Hint = RequestHint; Response.IoStatus.Information = BytesTransferred; - Response.IoStatus.Status = (UInt32) Status; + Response.IoStatus.Status = (UInt32)Status; Response.WriteFileInfo = FileInfo; Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response); } /// - /// Asynchronously complete a Read operation. - /// - /// - /// A reference to the operation to complete. - /// - /// - /// STATUS_SUCCESS or error code. - /// - /// - /// Number of bytes read. - /// - public void SendReadResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred) - { - var Response = new FspFsctlTransactRsp() - { - Size = 128, - Kind = (UInt32) FspFsctlTransact.ReadKind, - Hint = RequestHint - }; - Response.IoStatus.Information = BytesTransferred; - Response.IoStatus.Status = (UInt32) Status; - Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response); - } - /// /// Asynchronously complete a ReadDirectory operation. /// /// @@ -459,14 +569,12 @@ namespace Fsp /// public void SendReadDirectoryResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred) { - var Response = new FspFsctlTransactRsp() - { - Size = 128, - Kind = (UInt32) FspFsctlTransact.QueryDirectoryKind, - Hint = RequestHint - }; + FspFsctlTransactRsp Response = default(FspFsctlTransactRsp); + Response.Size = 128; + Response.Kind = (UInt32)FspFsctlTransact.QueryDirectoryKind; + Response.Hint = RequestHint; Response.IoStatus.Information = BytesTransferred; - Response.IoStatus.Status = (UInt32) Status; + Response.IoStatus.Status = (UInt32)Status; Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response); } diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index bb627a6b..bc0379a5 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -57,6 +57,12 @@ namespace Fsp.Interop internal const int PrefixSize = 192; internal const int FileSystemNameSize = 16; + internal const UInt32 VolumeInfoTimeoutValid = 0x00000001; + internal const UInt32 DirInfoTimeoutValid = 0x00000002; + internal const UInt32 SecurityTimeoutValid = 0x00000004; + internal const UInt32 StreamInfoTimeoutValid = 0x00000008; + internal const UInt32 EaTimeoutValid = 0x00000010; + internal UInt16 Version; internal UInt16 SectorSize; internal UInt16 SectorsPerAllocationUnit; @@ -70,6 +76,15 @@ namespace Fsp.Interop internal UInt32 Flags; internal unsafe fixed UInt16 Prefix[PrefixSize]; internal unsafe fixed UInt16 FileSystemName[FileSystemNameSize]; + internal UInt32 AdditionalFlags; + internal UInt32 VolumeInfoTimeout; + internal UInt32 DirInfoTimeout; + internal UInt32 SecurityTimeout; + internal UInt32 StreamInfoTimeout; + internal UInt32 EaTimeout; + internal UInt32 FsextControlCode; + internal unsafe fixed UInt32 Reserved32[1]; + internal unsafe fixed UInt64 Reserved64[2]; internal unsafe String GetPrefix() {