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()
{
}