From 7cd4d4faabe38a8e581cad5a486ea694d1b3a73b Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 10 May 2017 23:11:42 -0700 Subject: [PATCH] src: dotnet: add documentation --- build/VStudio/dotnet/winfsp.net.csproj | 4 + src/dotnet/FileSystemBase+Const.cs | 6 +- src/dotnet/FileSystemBase.cs | 635 ++++++++++++++++++++++++- src/dotnet/FileSystemHost.cs | 111 ++++- src/dotnet/Interop.cs | 54 ++- src/dotnet/Service.cs | 37 +- 6 files changed, 831 insertions(+), 16 deletions(-) diff --git a/build/VStudio/dotnet/winfsp.net.csproj b/build/VStudio/dotnet/winfsp.net.csproj index 44854520..e7de1b73 100644 --- a/build/VStudio/dotnet/winfsp.net.csproj +++ b/build/VStudio/dotnet/winfsp.net.csproj @@ -25,6 +25,8 @@ prompt 4 true + $(BaseIntermediateOutputPath)$(Configuration)\winfsp-msil.xml + 1591 pdbonly @@ -36,6 +38,8 @@ prompt 4 true + $(BaseIntermediateOutputPath)$(Configuration)\winfsp-msil.xml + 1591 true diff --git a/src/dotnet/FileSystemBase+Const.cs b/src/dotnet/FileSystemBase+Const.cs index 8c5da6da..19084ad9 100644 --- a/src/dotnet/FileSystemBase+Const.cs +++ b/src/dotnet/FileSystemBase+Const.cs @@ -1,7 +1,7 @@ -/** - * @file dotnet/FileSystemBase+Const.cs +/* + * dotnet/FileSystemBase+Const.cs * - * @copyright 2015-2017 Bill Zissimopoulos + * Copyright 2015-2017 Bill Zissimopoulos */ /* * This file is part of WinFsp. diff --git a/src/dotnet/FileSystemBase.cs b/src/dotnet/FileSystemBase.cs index 73876fad..c6330da8 100644 --- a/src/dotnet/FileSystemBase.cs +++ b/src/dotnet/FileSystemBase.cs @@ -1,7 +1,7 @@ -/** - * @file dotnet/FileSystemBase.cs +/* + * dotnet/FileSystemBase.cs * - * @copyright 2015-2017 Bill Zissimopoulos + * Copyright 2015-2017 Bill Zissimopoulos */ /* * This file is part of WinFsp. @@ -24,6 +24,9 @@ using Fsp.Interop; namespace Fsp { + /// + /// Provides the base class that user mode file systems must inherit from. + /// public partial class FileSystemBase { /* types */ @@ -48,28 +51,61 @@ namespace Fsp } /* operations */ + /// + /// Provides a means to customize the returned status code when an exception happens. + /// + /// + /// STATUS_SUCCESS or error code. public virtual Int32 ExceptionHandler(Exception ex) { Api.FspDebugLog("%s\n", ex.ToString()); return STATUS_UNEXPECTED_IO_ERROR; } + /// + /// Occurs just before the file system is mounted. + /// File systems may override this method to configure the file system host. + /// + /// The file system host that is mounting this file system. + /// STATUS_SUCCESS or error code. public virtual Int32 Init(Object Host) { return STATUS_SUCCESS; } + /// + /// Occurs just after the file system is mounted, + /// but prior to receiving any file system operation. + /// + /// The file system host that is mounting this file system. + /// STATUS_SUCCESS or error code. public virtual Int32 Mounted(Object Host) { return STATUS_SUCCESS; } + /// + /// Occurs just after the file system is unmounted. + /// No other file system operations will be received on this file system. + /// + /// The file system host that is mounting this file system. public virtual void Unmounted(Object Host) { } + /// + /// Gets the volume information. + /// + /// Receives the volume information. + /// STATUS_SUCCESS or error code. public virtual Int32 GetVolumeInfo( out VolumeInfo VolumeInfo) { VolumeInfo = default(VolumeInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Sets the volume label. + /// + /// The new label for the volume. + /// Receives the updated volume information. + /// STATUS_SUCCESS or error code. public virtual Int32 SetVolumeLabel( String VolumeLabel, out VolumeInfo VolumeInfo) @@ -77,6 +113,27 @@ namespace Fsp VolumeInfo = default(VolumeInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Gets file or directory attributes and security descriptor given a file name. + /// + /// + /// The name of the file or directory to get the attributes and security descriptor for. + /// + /// + /// Receives the file attributes on successful return. + /// If this call returns STATUS_REPARSE, the file system may place here the index of the + /// first reparse point within FileName. + /// + /// + /// Receives the file security descriptor. If the SecurityDescriptor parameter is null + /// on input the file system should not fill this value. + /// + /// + /// STATUS_SUCCESS, STATUS_REPARSE or error code. + /// STATUS_REPARSE should be returned by file systems that support reparse points when + /// they encounter a FileName that contains reparse points anywhere but the final path + /// component. + /// public virtual Int32 GetSecurityByName( String FileName, out UInt32 FileAttributes/* or ReparsePointIndex */, @@ -85,6 +142,40 @@ namespace Fsp FileAttributes = default(UInt32); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Creates a new file or directory. + /// + /// + /// The name of the file or directory to be created. + /// + /// + /// Create options for this request. + /// + /// + /// Determines the specific access rights that have been granted for this request. + /// + /// + /// File attributes to apply to the newly created file or directory. + /// + /// + /// Security descriptor to apply to the newly created file or directory. + /// + /// + /// Allocation size for the newly created file. + /// + /// + /// Receives the file node for the newly created file. + /// + /// + /// Receives the file descriptor for the newly created file. + /// + /// + /// Receives the file information for the newly created file. + /// + /// + /// Receives the normalized name for the newly created file. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 Create( String FileName, UInt32 CreateOptions, @@ -103,6 +194,31 @@ namespace Fsp NormalizedName = default(String); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Opens a file or directory. + /// + /// + /// The name of the file or directory to be opened. + /// + /// + /// Create options for this request. + /// + /// + /// Determines the specific access rights that have been granted for this request. + /// + /// + /// Receives the file node for the newly opened file. + /// + /// + /// Receives the file descriptor for the newly opened file. + /// + /// + /// Receives the file information for the newly opened file. + /// + /// + /// Receives the normalized name for the newly opened file. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 Open( String FileName, UInt32 CreateOptions, @@ -118,6 +234,29 @@ namespace Fsp NormalizedName = default(String); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Overwrites a file. + /// + /// + /// The file node for the file to be overwritten. + /// + /// + /// The file descriptor for the file to be overwritten. + /// + /// + /// File attributes to apply to the overwritten file. + /// + /// + /// When true the existing file attributes should be replaced with the new ones. + /// When false the existing file attributes should be merged (or'ed) with the new ones. + /// + /// + /// Allocation size for the overwritten file. + /// + /// + /// Receives the updated file information. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 Overwrite( Object FileNode, Object FileDesc, @@ -129,6 +268,64 @@ namespace Fsp FileInfo = default(FileInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Cleans up a file or directory. + /// + /// + /// + /// When CreateFile is used to open or create a file the kernel creates a kernel mode file + /// object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may + /// be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same + /// file object. When all handles for a particular file object get closed (using CloseHandle) + /// the system sends a Cleanup request to the file system. + /// + /// There will be a Cleanup operation for every Create or Open operation posted to the user mode + /// file system. However the Cleanup operation is not the final close operation on a file. + /// The file system must be ready to receive additional operations until close time. This is true + /// even when the file is being deleted! + /// + /// The Flags parameter contains information about the cleanup operation: + /// + /// CleanupDelete - + /// An important function of the Cleanup operation is to complete a delete operation. Deleting + /// a file or directory in Windows is a three-stage process where the file is first opened, then + /// tested to see if the delete can proceed and if the answer is positive the file is then + /// deleted during Cleanup. + /// When this flag is set, this is the last outstanding cleanup for this particular file node. + /// + /// CleanupSetAllocationSize - + /// The NTFS and FAT file systems reset a file's allocation size when they receive the last + /// outstanding cleanup for a particular file node. User mode file systems that implement + /// allocation size and wish to duplicate the NTFS and FAT behavior can use this flag. + /// + /// CleanupSetArchiveBit - + /// File systems that support the archive bit should set the file node's archive bit when this + /// flag is set. + /// + /// CleanupSetLastAccessTime, CleanupSetLastWriteTime, CleanupSetChangeTime - + /// File systems should set the corresponding file time when each one of these flags is set. + /// Note that updating the last access time is expensive and a file system may choose to not + /// implement it. + /// + /// + /// + /// There is no way to report failure of this operation. This is a Windows limitation. + /// + /// + /// + /// The file node of the file or directory to cleanup. + /// + /// + /// The file descriptor of the file or directory to cleanup. + /// + /// + /// The name of the file or directory to cleanup. Sent only when a Delete is requested. + /// + /// + /// These flags determine whether the file was modified and whether to delete the file. + /// + /// + /// public virtual void Cleanup( Object FileNode, Object FileDesc, @@ -136,11 +333,42 @@ namespace Fsp UInt32 Flags) { } + /// + /// Closes a file or directory. + /// + /// + /// The file node of the file or directory to close. + /// + /// + /// The file descriptor of the file or directory to close. + /// public virtual void Close( Object FileNode, Object FileDesc) { } + /// + /// Reads a file. + /// + /// + /// The file node of the file to read. + /// + /// + /// The file descriptor of the file to read. + /// + /// + /// Pointer to a buffer that receives the results of the read operation. + /// + /// + /// Offset within the file to read from. + /// + /// + /// Length of data to read. + /// + /// + /// Receives the actual number of bytes read. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 Read( Object FileNode, Object FileDesc, @@ -152,6 +380,38 @@ namespace Fsp BytesTransferred = default(UInt32); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Writes a file. + /// + /// + /// The file node of the file to write. + /// + /// + /// The file descriptor of the file to write. + /// + /// + /// Pointer to a buffer that receives the results of the write operation. + /// + /// + /// Offset within the file to write to. + /// + /// + /// Length of data to write. + /// + /// + /// When true the file system must write to the current end of file. In this case the Offset + /// parameter will contain the value -1. + /// + /// + /// When true the file system must not extend the file (i.e. change the file size). + /// + /// + /// Receives the actual number of bytes written. + /// + /// + /// Receives the updated file information. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 Write( Object FileNode, Object FileDesc, @@ -167,6 +427,24 @@ namespace Fsp FileInfo = default(FileInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Flushes a file or volume. + /// + /// + /// Note that the FSD will also flush all file/volume caches prior to invoking this operation. + /// + /// + /// The file node of the file to flush. + /// When this and the FileDesc parameter are null the whole volume is being flushed. + /// + /// + /// The file descriptor of the file to flush. + /// When this and the FileNode parameter are null the whole volume is being flushed. + /// + /// + /// Receives the updated file information. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 Flush( Object FileNode, Object FileDesc, @@ -175,6 +453,19 @@ namespace Fsp FileInfo = default(FileInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Gets file or directory information. + /// + /// + /// The file node of the file to get information for. + /// + /// + /// The file descriptor of the file to get information for. + /// + /// + /// Receives the file information. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 GetFileInfo( Object FileNode, Object FileDesc, @@ -183,6 +474,39 @@ namespace Fsp FileInfo = default(FileInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Sets file or directory basic information. + /// + /// + /// The file node of the file to set information for. + /// + /// + /// The file descriptor of the file to set information for. + /// + /// + /// File attributes to apply to the file or directory. + /// If the value -1 is sent, the file attributes should not be changed. + /// + /// + /// Creation time to apply to the file or directory. + /// If the value 0 is sent, the creation time should not be changed. + /// + /// + /// Last access time to apply to the file or directory. + /// If the value 0 is sent, the last access time should not be changed. + /// + /// + /// Last write time to apply to the file or directory. + /// If the value 0 is sent, the last write time should not be changed. + /// + /// + /// Change time to apply to the file or directory. + /// If the value 0 is sent, the change time should not be changed. + /// + /// + /// Receives the updated file information. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 SetBasicInfo( Object FileNode, Object FileDesc, @@ -196,6 +520,52 @@ namespace Fsp FileInfo = default(FileInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Sets file/allocation size. + /// + /// + /// + /// This function is used to change a file's sizes. Windows file systems maintain two kinds + /// of sizes: the file size is where the End Of File (EOF) is, and the allocation size is the + /// actual size that a file takes up on the "disk". + /// + /// The rules regarding file/allocation size are: + /// + /// + /// Allocation size must always be aligned to the allocation unit boundary. The allocation + /// unit is the product SectorSize * SectorsPerAllocationUnit. The FSD will always send + /// properly aligned allocation sizes when setting the allocation size. + /// + /// + /// Allocation size is always greater or equal to the file size. + /// + /// + /// A file size of more than the current allocation size will also extend the allocation + /// size to the next allocation unit boundary. + /// + /// + /// An allocation size of less than the current file size should also truncate the current + /// file size. + /// + /// + /// + /// + /// + /// The file node of the file to set the file/allocation size for. + /// + /// + /// The file descriptor of the file to set the file/allocation size for. + /// + /// + /// New file/allocation size to apply to the file. + /// + /// + /// If true, then the allocation size is being set. if false, then the file size is being set. + /// + /// + /// Receives the updated file information. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 SetFileSize( Object FileNode, Object FileDesc, @@ -206,6 +576,20 @@ namespace Fsp FileInfo = default(FileInfo); return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Determines whether a file or directory can be deleted. + /// + /// + /// The file node of the file or directory to test for deletion. + /// + /// + /// The file descriptor of the file or directory to test for deletion. + /// + /// + /// The name of the file or directory to test for deletion. + /// + /// STATUS_SUCCESS or error code. + /// public virtual Int32 CanDelete( Object FileNode, Object FileDesc, @@ -213,6 +597,37 @@ namespace Fsp { return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Renames a file or directory. + /// + /// + /// The kernel mode FSD provides certain guarantees prior to posting a rename operation: + /// + /// + /// A file cannot be renamed if a file with the same name exists and has open handles. + /// + /// + /// A directory cannot be renamed if it or any of its subdirectories contains a file that + /// has open handles. + /// + /// + /// + /// + /// The file node of the file or directory to be renamed. + /// + /// + /// The file descriptor of the file or directory to be renamed. + /// + /// + /// The current name of the file or directory to rename. + /// + /// + /// The new name for the file or directory. + /// + /// + /// Whether to replace a file that already exists at NewFileName. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 Rename( Object FileNode, Object FileDesc, @@ -222,6 +637,19 @@ namespace Fsp { return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Gets file or directory security descriptor. + /// + /// + /// The file node of the file or directory to get the security descriptor for. + /// + /// + /// The file descriptor of the file or directory to get the security descriptor for. + /// + /// + /// Receives the file security descriptor. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 GetSecurity( Object FileNode, Object FileDesc, @@ -229,6 +657,23 @@ namespace Fsp { return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Sets file or directory security descriptor. + /// + /// + /// The file node of the file or directory to set the security descriptor for. + /// + /// + /// The file descriptor of the file or directory to set the security descriptor for. + /// + /// + /// Describes what parts of the file or directory security descriptor should be modified. + /// + /// + /// Describes the modifications to apply to the file or directory security descriptor. + /// + /// STATUS_SUCCESS or error code. + /// public virtual Int32 SetSecurity( Object FileNode, Object FileDesc, @@ -237,6 +682,10 @@ namespace Fsp { return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Reads a directory. + /// + /// public virtual Int32 ReadDirectory( Object FileNode, Object FileDesc, @@ -249,6 +698,36 @@ namespace Fsp return SeekableReadDirectory(FileNode, FileDesc, Pattern, Marker, Buffer, Length, out BytesTransferred); } + /// + /// Reads a directory entry. + /// + /// + /// The file node of the directory to be read. + /// + /// + /// The file descriptor of the directory to be read. + /// + /// + /// The pattern to match against files in this directory. Can be null. The file system + /// can choose to ignore this parameter as the FSD will always perform its own pattern + /// matching on the returned results. + /// + /// + /// A file name that marks where in the directory to start reading. Files with names + /// that are greater than (not equal to) this marker (in the directory order determined + /// by the file system) should be returned. Can be null. + /// + /// + /// Can be used by the file system to track the ReadDirectory operation. + /// + /// + /// Receives the file name for the directory entry. + /// + /// + /// Receives the file information for the directory entry. + /// + /// True if there are additional directory entries to return. False otherwise. + /// public virtual Boolean ReadDirectoryEntry( Object FileNode, Object FileDesc, @@ -262,6 +741,9 @@ namespace Fsp FileInfo = default(FileInfo); return false; } + /// + /// Resolves reparse points. + /// public virtual Int32 ResolveReparsePoints( String FileName, UInt32 ReparsePointIndex, @@ -289,6 +771,19 @@ namespace Fsp Handle.Free(); } } + /// + /// Gets a reparse point given a file name. + /// + /// + /// The name of the file or directory to get the reparse point for. + /// + /// + /// Determines whether the passed file name is assumed to be a directory. + /// + /// + /// Receives the reparse data for the file or directory. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 GetReparsePointByName( String FileName, Boolean IsDirectory, @@ -296,6 +791,22 @@ namespace Fsp { return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Gets a reparse point. + /// + /// + /// The file node of the reparse point. + /// + /// + /// The file descriptor of the reparse point. + /// + /// + /// The file name of the reparse point. + /// + /// + /// Receives the reparse data for the reparse point. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 GetReparsePoint( Object FileNode, Object FileDesc, @@ -304,6 +815,22 @@ namespace Fsp { return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Sets a reparse point. + /// + /// + /// The file node of the reparse point. + /// + /// + /// The file descriptor of the reparse point. + /// + /// + /// The file name of the reparse point. + /// + /// + /// The new reparse data for the reparse point. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 SetReparsePoint( Object FileNode, Object FileDesc, @@ -312,6 +839,22 @@ namespace Fsp { return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Deletes a reparse point. + /// + /// + /// The file node of the reparse point. + /// + /// + /// The file descriptor of the reparse point. + /// + /// + /// The file name of the reparse point. + /// + /// + /// The reparse data for the reparse point. + /// + /// STATUS_SUCCESS or error code. public virtual Int32 DeleteReparsePoint( Object FileNode, Object FileDesc, @@ -320,6 +863,9 @@ namespace Fsp { return STATUS_INVALID_DEVICE_REQUEST; } + /// + /// Gets named streams information. + /// public virtual Int32 GetStreamInfo( Object FileNode, Object FileDesc, @@ -342,6 +888,28 @@ namespace Fsp Api.FspFileSystemEndStreamInfo(Buffer, Length, out BytesTransferred); return STATUS_SUCCESS; } + /// + /// Gets named streams information entry. + /// + /// + /// The file node of the file or directory to get stream information for. + /// + /// + /// The file descriptor of the file or directory to get stream information for. + /// + /// + /// Can be used by the file system to track the GetStreamInfo operation. + /// + /// + /// Receives the stream name for the stream entry. + /// + /// + /// Receives the stream size for the stream entry. + /// + /// + /// Receives the stream allocation size for the stream entry. + /// + /// True if there are additional stream entries to return. False otherwise. public virtual Boolean GetStreamEntry( Object FileNode, Object FileDesc, @@ -357,14 +925,37 @@ namespace Fsp } /* helpers */ + /// + /// Converts a Win32 error code to a Windows kernel status code. + /// public static Int32 NtStatusFromWin32(UInt32 Error) { return Api.FspNtStatusFromWin32(Error); } + /// + /// Converts a Windows kernel status code to a Win32 error code. + /// public static UInt32 Win32FromNtStatus(Int32 Status) { return Api.FspWin32FromNtStatus(Status); } + /// + /// Modifies a security descriptor. + /// + /// + /// This is a helper for implementing the SetSecurity operation. + /// + /// + /// The original security descriptor. + /// + /// + /// Describes what parts of the file or directory security descriptor should be modified. + /// + /// + /// Describes the modifications to apply to the file or directory security descriptor. + /// + /// The modified security descriptor. + /// public static byte[] ModifySecurityDescriptor( Byte[] SecurityDescriptor, AccessControlSections Sections, @@ -449,6 +1040,21 @@ namespace Fsp Marker, Buffer, Length, out BytesTransferred); return STATUS_SUCCESS; } + /// + /// Finds a reparse point in file name. + /// + /// + /// This is a helper for implementing the GetSecurityByName operation in file systems + /// that support reparse points. + /// + /// + /// The name of the file or directory. + /// + /// + /// Receives the index of the first reparse point within FileName. + /// + /// True if a reparse point was found, false otherwise. + /// public Boolean FindReparsePoint( String FileName, out UInt32 ReparsePointIndex) @@ -468,11 +1074,34 @@ namespace Fsp Handle.Free(); } } + /// + /// Gets the reparse tag from reparse data. + /// + /// + /// The reparse data to extract the reparse tag from. + /// + /// The reparse tag. public static UInt32 GetReparseTag( Byte[] ReparseData) { return BitConverter.ToUInt32(ReparseData, 0); } + /// + /// Tests whether reparse data can be replaced. + /// + /// + /// This is a helper for implementing the SetReparsePoint/DeleteReparsePoint operation + /// in file systems that support reparse points. + /// + /// + /// The current reparse data. + /// + /// + /// The replacement reparse data. + /// + /// STATUS_SUCCESS or error code. + /// + /// public static Int32 CanReplaceReparsePoint( Byte[] CurrentReparseData, Byte[] ReplaceReparseData) diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs index 4c4d953e..e97023ec 100644 --- a/src/dotnet/FileSystemHost.cs +++ b/src/dotnet/FileSystemHost.cs @@ -1,7 +1,7 @@ -/** - * @file dotnet/FileSystemHost.cs +/* + * dotnet/FileSystemHost.cs * - * @copyright 2015-2017 Bill Zissimopoulos + * Copyright 2015-2017 Bill Zissimopoulos */ /* * This file is part of WinFsp. @@ -24,9 +24,16 @@ using Fsp.Interop; namespace Fsp { + /// + /// Provides a means to host (mount) a file system. + /// public class FileSystemHost : IDisposable { /* ctor/dtor */ + /// + /// Creates an instance of the FileSystemHost class. + /// + /// The file system to host. public FileSystemHost(FileSystemBase FileSystem) { _VolumeParams.Flags = VolumeParams.UmFileContextIsFullContext; @@ -36,6 +43,9 @@ namespace Fsp { Dispose(false); } + /// + /// Unmounts the file system and releases all associated resources. + /// public void Dispose() { lock (this) @@ -63,66 +73,107 @@ namespace Fsp } /* properties */ + /// + /// Gets or sets the sector size used by the file system. + /// public UInt16 SectorSize { get { return _VolumeParams.SectorSize; } set { _VolumeParams.SectorSize = value; } } + /// + /// Gets or sets the sectors per allocation unit used by the file system. + /// public UInt16 SectorsPerAllocationUnit { get { return _VolumeParams.SectorsPerAllocationUnit; } set { _VolumeParams.SectorsPerAllocationUnit = value; } } + /// + /// Gets or sets the maximum path component length used by the file system. + /// public UInt16 MaxComponentLength { get { return _VolumeParams.MaxComponentLength; } set { _VolumeParams.MaxComponentLength = value; } } + /// + /// Gets or sets the volume creation time. + /// public UInt64 VolumeCreationTime { get { return _VolumeParams.VolumeCreationTime; } set { _VolumeParams.VolumeCreationTime = value; } } + /// + /// Gets or sets the volume serial number. + /// public UInt32 VolumeSerialNumber { get { return _VolumeParams.VolumeSerialNumber; } set { _VolumeParams.VolumeSerialNumber = value; } } + /// + /// Gets or sets the file information timeout. + /// public UInt32 FileInfoTimeout { get { return _VolumeParams.FileInfoTimeout; } set { _VolumeParams.FileInfoTimeout = value; } } + /// + /// Gets or sets a value that determines whether the file system is case sensitive. + /// public Boolean CaseSensitiveSearch { get { return 0 != (_VolumeParams.Flags & VolumeParams.CaseSensitiveSearch); } set { _VolumeParams.Flags |= (value ? VolumeParams.CaseSensitiveSearch : 0); } } + /// + /// Gets or sets a value that determines whether a case insensitive file system + /// preserves case in file names. + /// public Boolean CasePreservedNames { get { return 0 != (_VolumeParams.Flags & VolumeParams.CasePreservedNames); } set { _VolumeParams.Flags |= (value ? VolumeParams.CasePreservedNames : 0); } } + /// + /// Gets or sets a value that determines whether file names support unicode characters. + /// public Boolean UnicodeOnDisk { get { return 0 != (_VolumeParams.Flags & VolumeParams.UnicodeOnDisk); } set { _VolumeParams.Flags |= (value ? VolumeParams.UnicodeOnDisk : 0); } } + /// + /// Gets or sets a value that determines whether the file system supports ACL security. + /// public Boolean PersistentAcls { get { return 0 != (_VolumeParams.Flags & VolumeParams.PersistentAcls); } set { _VolumeParams.Flags |= (value ? VolumeParams.PersistentAcls : 0); } } + /// + /// Gets or sets a value that determines whether the file system supports reparse points. + /// public Boolean ReparsePoints { get { return 0 != (_VolumeParams.Flags & VolumeParams.ReparsePoints); } set { _VolumeParams.Flags |= (value ? VolumeParams.ReparsePoints : 0); } } + /// + /// Gets or sets a value that determines whether the file system allows creation of + /// symbolic links without additional privileges. + /// public Boolean ReparsePointsAccessCheck { get { return 0 != (_VolumeParams.Flags & VolumeParams.ReparsePointsAccessCheck); } set { _VolumeParams.Flags |= (value ? VolumeParams.ReparsePointsAccessCheck : 0); } } + /// + /// Gets or sets a value that determines whether the file system supports named streams. + /// public Boolean NamedStreams { get { return 0 != (_VolumeParams.Flags & VolumeParams.NamedStreams); } @@ -138,11 +189,17 @@ namespace Fsp get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryPattern); } set { _VolumeParams.Flags |= (value ? VolumeParams.PassQueryDirectoryPattern : 0); } } + /// + /// Gets or sets the prefix for a network file system. + /// public String Prefix { get { return _VolumeParams.GetPrefix(); } set { _VolumeParams.SetPrefix(value); } } + /// + /// Gets or sets the file system name. + /// public String FileSystemName { get { return _VolumeParams.GetFileSystemName(); } @@ -150,12 +207,42 @@ namespace Fsp } /* control */ + /// + /// Checks whether mounting a file system is possible. + /// + /// + /// 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. + /// + /// STATUS_SUCCESS or error code. public Int32 Preflight(String MountPoint) { return Api.FspFileSystemPreflight( _VolumeParams.IsPrefixEmpty() ? "WinFsp.Disk" : "WinFsp.Net", MountPoint); } + /// + /// 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. + /// + /// + /// 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. + /// + /// public Int32 Mount(String MountPoint, Byte[] SecurityDescriptor = null, Boolean Synchronized = false, @@ -216,10 +303,17 @@ namespace Fsp } return Result; } + /// + /// Unmounts the file system and releases all associated resources. + /// public void Unmount() { Dispose(); } + /// + /// Gets the file system mount point. + /// + /// The file system mount point. public String MountPoint() { return IntPtr.Zero != _FileSystemPtr ? @@ -229,10 +323,21 @@ namespace Fsp { return _FileSystemPtr; } + /// + /// Gets the hosted file system. + /// + /// The hosted file system. public FileSystemBase FileSystem() { return _FileSystem; } + /// + /// Sets the debug log file to use when debug logging is enabled. + /// + /// + /// The debug log file name. A value of "-" means standard error output. + /// + /// STATUS_SUCCESS or error code. public static Int32 SetDebugLogFile(String FileName) { return Api.SetDebugLogFile(FileName); diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index 0e3f3761..43eb6ded 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -1,7 +1,7 @@ -/** - * @file dotnet/Interop.cs +/* + * dotnet/Interop.cs * - * @copyright 2015-2017 Bill Zissimopoulos + * Copyright 2015-2017 Bill Zissimopoulos */ /* * This file is part of WinFsp. @@ -102,16 +102,28 @@ namespace Fsp.Interop } } + /// + /// Contains volume information about a file system. + /// [StructLayout(LayoutKind.Sequential)] public struct VolumeInfo { internal const int VolumeLabelSize = 32; + /// + /// Total size of volume in bytes. + /// public UInt64 TotalSize; + /// + /// Free size of volume in bytes. + /// public UInt64 FreeSize; internal UInt16 VolumeLabelLength; internal unsafe fixed UInt16 VolumeLabel[VolumeLabelSize]; + /// + /// Sets the volume label. + /// public unsafe void SetVolumeLabel(String Value) { fixed (UInt16 *P = VolumeLabel) @@ -126,18 +138,54 @@ namespace Fsp.Interop } } + /// + /// Contains metadata information about a file or directory. + /// [StructLayout(LayoutKind.Sequential)] public struct FileInfo { + /// + /// The file or directory attributes. + /// public UInt32 FileAttributes; + /// + /// The reparse tag of the file or directory. + /// This value is 0 if the file or directory is not a reparse point. + /// public UInt32 ReparseTag; + /// + /// The allocation size of the file. + /// public UInt64 AllocationSize; + /// + /// The file size of the file (end of file). + /// public UInt64 FileSize; + /// + /// The time that the file or directory was created. + /// public UInt64 CreationTime; + /// + /// The time that the file or directory was last accessed. + /// public UInt64 LastAccessTime; + /// + /// The time that the file or direcotry was last modified. + /// public UInt64 LastWriteTime; + /// + /// The time that the file or directory metadata was last modified. + /// public UInt64 ChangeTime; + /// + /// A unique identifier that is associated with the file or directory. + /// Not all file systems support this value. + /// public UInt64 IndexNumber; + /// + /// The number of hard links. + /// Not currently implemented. Set to 0. + /// public UInt32 HardLinks; } diff --git a/src/dotnet/Service.cs b/src/dotnet/Service.cs index 5b8aa1b4..11b744ba 100644 --- a/src/dotnet/Service.cs +++ b/src/dotnet/Service.cs @@ -1,7 +1,7 @@ -/** - * @file dotnet/Service.cs +/* + * dotnet/Service.cs * - * @copyright 2015-2017 Bill Zissimopoulos + * Copyright 2015-2017 Bill Zissimopoulos */ /* * This file is part of WinFsp. @@ -16,13 +16,16 @@ */ using System; -using System.Runtime.InteropServices; using Fsp.Interop; namespace Fsp { + /// + /// Provides the base class for a process that can be run as a service, + /// command line application or under the control of the WinFsp launcher. + /// public class Service { /* const */ @@ -31,6 +34,10 @@ namespace Fsp public const UInt32 EVENTLOG_INFORMATION_TYPE = 0x0004; /* ctor/dtor */ + /// + /// Creates an instance of the Service class. + /// + /// The name of the service. public Service(String ServiceName) { Api.FspServiceCreate(ServiceName, _OnStart, _OnStop, null, out _ServicePtr); @@ -47,6 +54,10 @@ namespace Fsp } /* control */ + /// + /// Runs a service. + /// + /// Service process exit code. public int Run() { if (IntPtr.Zero == _ServicePtr) @@ -69,6 +80,9 @@ namespace Fsp } return ExitCode; } + /// + /// Stops a running service. + /// public void Stop() { if (IntPtr.Zero == _ServicePtr) @@ -81,6 +95,9 @@ namespace Fsp throw new InvalidOperationException(); Api.FspServiceRequestTime(_ServicePtr, Time); } + /// + /// Gets or sets the service process exit code. + /// public int ExitCode { get @@ -106,13 +123,25 @@ namespace Fsp } /* start/stop */ + /// + /// Provides a means to customize the returned status code when an exception happens. + /// + /// + /// STATUS_SUCCESS or error code. protected virtual Int32 ExceptionHandler(Exception ex) { return unchecked((Int32)0xE0434f4D)/*STATUS_CLR_EXCEPTION*/; } + /// + /// Occurs when the service starts. + /// + /// Command line arguments passed to the service. protected virtual void OnStart(String[] Args) { } + /// + /// Occurs when the service stops. + /// protected virtual void OnStop() { }