diff --git a/.gitignore b/.gitignore
index 9c4196a4..48511677 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
################################################################################
*.db
+*.opendb
diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs
index 55a14c2c..7d7cd53e 100644
--- a/src/dotnet/FileSystemHost.cs
+++ b/src/dotnet/FileSystemHost.cs
@@ -194,6 +194,11 @@ namespace Fsp
get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryFileName); }
set { _VolumeParams.Flags |= (value ? VolumeParams.PassQueryDirectoryFileName : 0); }
}
+ public Boolean FlushAndPurgeOnCleanup
+ {
+ get { return 0 != (_VolumeParams.Flags & VolumeParams.FlushAndPurgeOnCleanup); }
+ set { _VolumeParams.Flags |= (value ? VolumeParams.FlushAndPurgeOnCleanup : 0); }
+ }
///
/// Gets or sets the prefix for a network file system.
///
@@ -347,6 +352,14 @@ namespace Fsp
{
return Api.SetDebugLogFile(FileName);
}
+ ///
+ /// Return the installed version for WinFSP
+ ///
+ ///
+ public static Version GetFspVersion()
+ {
+ return Api.GetFspVersion();
+ }
/* FSP_FILE_SYSTEM_INTERFACE */
private static Byte[] ByteBufferNotNull = new Byte[0];
diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs
index c81e9b67..b00915e8 100644
--- a/src/dotnet/Interop.cs
+++ b/src/dotnet/Interop.cs
@@ -43,6 +43,7 @@ namespace Fsp.Interop
internal const UInt32 PassQueryDirectoryPattern = 0x00000800;
internal const UInt32 AlwaysUseDoubleBuffering = 0x00001000;
internal const UInt32 PassQueryDirectoryFileName = 0x00002000;
+ internal const UInt32 FlushAndPurgeOnCleanup = 0x00004000;
internal const UInt32 UmFileContextIsUserContext2 = 0x00010000;
internal const UInt32 UmFileContextIsFullContext = 0x00020000;
internal const int PrefixSize = 192;
@@ -903,17 +904,17 @@ namespace Fsp.Interop
Byte[] ModificationDescriptorBytes)
{
fixed (Byte *S = SecurityDescriptorBytes)
- fixed (Byte *M = ModificationDescriptorBytes)
- {
- IntPtr SecurityDescriptor;
- Int32 Result = FspSetSecurityDescriptor(
- (IntPtr)S, SecurityInformation, (IntPtr)M, out SecurityDescriptor);
- if (0 > Result)
- return null;
- SecurityDescriptorBytes = MakeSecurityDescriptor(SecurityDescriptor);
- FspDeleteSecurityDescriptor(SecurityDescriptor, _FspSetSecurityDescriptorPtr);
- return SecurityDescriptorBytes;
- }
+ fixed (Byte *M = ModificationDescriptorBytes)
+ {
+ IntPtr SecurityDescriptor;
+ Int32 Result = FspSetSecurityDescriptor(
+ (IntPtr)S, SecurityInformation, (IntPtr)M, out SecurityDescriptor);
+ if (0 > Result)
+ return null;
+ SecurityDescriptorBytes = MakeSecurityDescriptor(SecurityDescriptor);
+ FspDeleteSecurityDescriptor(SecurityDescriptor, _FspSetSecurityDescriptorPtr);
+ return SecurityDescriptorBytes;
+ }
}
internal unsafe static Int32 CopyReparsePoint(
@@ -953,10 +954,10 @@ namespace Fsp.Interop
Byte[] ReplaceReparseData)
{
fixed (Byte *C = CurrentReparseData)
- fixed (Byte *R = ReplaceReparseData)
- return _FspFileSystemCanReplaceReparsePoint(
- (IntPtr)C, (UIntPtr)CurrentReparseData.Length,
- (IntPtr)R, (UIntPtr)ReplaceReparseData.Length);
+ fixed (Byte *R = ReplaceReparseData)
+ return _FspFileSystemCanReplaceReparsePoint(
+ (IntPtr)C, (UIntPtr)CurrentReparseData.Length,
+ (IntPtr)R, (UIntPtr)ReplaceReparseData.Length);
}
internal static Int32 SetDebugLogFile(String FileName)
@@ -979,6 +980,15 @@ namespace Fsp.Interop
return 0/*STATUS_SUCCESS*/;
}
+ internal static Version GetFspVersion()
+ {
+ UInt32 Version = 0, VersionMajor, VersionMinor;
+ FspVersion(out Version);
+ VersionMajor = Version >> 16;
+ VersionMinor = Version & 0xFFFF;
+ return new System.Version((Int32)VersionMajor, (Int32)VersionMinor);
+ }
+
/* initialization */
private static IntPtr LoadDll()
{
diff --git a/tst/memfs-dotnet/Program.cs b/tst/memfs-dotnet/Program.cs
index a3802b61..f3d8c838 100644
--- a/tst/memfs-dotnet/Program.cs
+++ b/tst/memfs-dotnet/Program.cs
@@ -70,7 +70,7 @@ namespace memfs
{
FileInfo FileInfo = MainFileNode.FileInfo;
FileInfo.FileAttributes &= ~(UInt32)FileAttributes.Directory;
- /* named streams cannot be directories */
+ /* named streams cannot be directories */
FileInfo.AllocationSize = this.FileInfo.AllocationSize;
FileInfo.FileSize = this.FileInfo.FileSize;
return FileInfo;
@@ -255,6 +255,7 @@ namespace memfs
Host.NamedStreams = true;
Host.PostCleanupWhenModifiedOnly = true;
Host.PassQueryDirectoryFileName = true;
+ Host.FlushAndPurgeOnCleanup = true;
return STATUS_SUCCESS;
}
@@ -1066,40 +1067,40 @@ namespace memfs
break;
switch (Arg[1])
{
- case '?':
- throw new CommandLineUsageException();
- case 'D':
- argtos(Args, ref I, ref DebugLogFile);
- break;
- case 'd':
- argtol(Args, ref I, ref DebugFlags);
- break;
- case 'F':
- argtos(Args, ref I, ref FileSystemName);
- break;
- case 'i':
- CaseInsensitive = true;
- break;
- case 'm':
- argtos(Args, ref I, ref MountPoint);
- break;
- case 'n':
- argtol(Args, ref I, ref MaxFileNodes);
- break;
- case 'S':
- argtos(Args, ref I, ref RootSddl);
- break;
- case 's':
- argtol(Args, ref I, ref MaxFileSize);
- break;
- case 't':
- argtol(Args, ref I, ref FileInfoTimeout);
- break;
- case 'u':
- argtos(Args, ref I, ref VolumePrefix);
- break;
- default:
- throw new CommandLineUsageException();
+ case '?':
+ throw new CommandLineUsageException();
+ case 'D':
+ argtos(Args, ref I, ref DebugLogFile);
+ break;
+ case 'd':
+ argtol(Args, ref I, ref DebugFlags);
+ break;
+ case 'F':
+ argtos(Args, ref I, ref FileSystemName);
+ break;
+ case 'i':
+ CaseInsensitive = true;
+ break;
+ case 'm':
+ argtos(Args, ref I, ref MountPoint);
+ break;
+ case 'n':
+ argtol(Args, ref I, ref MaxFileNodes);
+ break;
+ case 'S':
+ argtos(Args, ref I, ref RootSddl);
+ break;
+ case 's':
+ argtol(Args, ref I, ref MaxFileSize);
+ break;
+ case 't':
+ argtol(Args, ref I, ref FileInfoTimeout);
+ break;
+ case 'u':
+ argtos(Args, ref I, ref VolumePrefix);
+ break;
+ default:
+ throw new CommandLineUsageException();
}
}