diff --git a/build/VStudio/dotnet/winfsp.net.csproj b/build/VStudio/dotnet/winfsp.net.csproj index a66d08ed..44854520 100644 --- a/build/VStudio/dotnet/winfsp.net.csproj +++ b/build/VStudio/dotnet/winfsp.net.csproj @@ -47,11 +47,14 @@ - - FileSystem+Const.cs + + FileSystemBase+Const.cs - - FileSystem.cs + + FileSystemBase.cs + + + FileSystemHost.cs Interop.cs diff --git a/src/dotnet/FileSystem+Const.cs b/src/dotnet/FileSystemBase+Const.cs similarity index 99% rename from src/dotnet/FileSystem+Const.cs rename to src/dotnet/FileSystemBase+Const.cs index 346d5f2c..8c5da6da 100644 --- a/src/dotnet/FileSystem+Const.cs +++ b/src/dotnet/FileSystemBase+Const.cs @@ -1,5 +1,5 @@ /** - * @file dotnet/FileSystem+Const.cs + * @file dotnet/FileSystemBase+Const.cs * * @copyright 2015-2017 Bill Zissimopoulos */ @@ -20,7 +20,7 @@ using System; namespace Fsp { - public partial class FileSystem + public partial class FileSystemBase { /* CreateOptions */ public const UInt32 FILE_DIRECTORY_FILE = 0x00000001; diff --git a/src/dotnet/FileSystemBase.cs b/src/dotnet/FileSystemBase.cs new file mode 100644 index 00000000..05534d8c --- /dev/null +++ b/src/dotnet/FileSystemBase.cs @@ -0,0 +1,454 @@ +/** + * @file dotnet/FileSystemBase.cs + * + * @copyright 2015-2017 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * software. + */ + +using System; +using System.Runtime.InteropServices; +using System.Security.AccessControl; + +using Fsp.Interop; + +namespace Fsp +{ + + public partial class FileSystemBase + { + /* types */ + public class DirectoryBuffer : IDisposable + { + ~DirectoryBuffer() + { + Dispose(false); + } + public void Dispose() + { + lock (this) + Dispose(true); + GC.SuppressFinalize(true); + } + protected virtual void Dispose(bool disposing) + { + Api.FspFileSystemDeleteDirectoryBuffer(ref DirBuffer); + } + + internal IntPtr DirBuffer; + } + + /* operations */ + public virtual Int32 ExceptionHandler(Exception ex) + { + return STATUS_UNEXPECTED_IO_ERROR; + } + public virtual Int32 Init(Object Host) + { + return STATUS_SUCCESS; + } + public virtual Int32 Mounted(Object Host) + { + return STATUS_SUCCESS; + } + public virtual void Unmounted(Object Host) + { + } + public virtual Int32 GetVolumeInfo( + out VolumeInfo VolumeInfo) + { + VolumeInfo = default(VolumeInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 SetVolumeLabel( + String VolumeLabel, + out VolumeInfo VolumeInfo) + { + VolumeInfo = default(VolumeInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 GetSecurityByName( + String FileName, + out UInt32 FileAttributes/* or ReparsePointIndex */, + ref Byte[] SecurityDescriptor) + { + FileAttributes = default(UInt32); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 Create( + String FileName, + UInt32 CreateOptions, + UInt32 GrantedAccess, + UInt32 FileAttributes, + Byte[] SecurityDescriptor, + UInt64 AllocationSize, + out Object FileNode, + out Object FileDesc, + out FileInfo FileInfo, + out String NormalizedName) + { + FileNode = default(Object); + FileDesc = default(Object); + FileInfo = default(FileInfo); + NormalizedName = default(String); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 Open( + String FileName, + UInt32 CreateOptions, + UInt32 GrantedAccess, + out Object FileNode, + out Object FileDesc, + out FileInfo FileInfo, + out String NormalizedName) + { + FileNode = default(Object); + FileDesc = default(Object); + FileInfo = default(FileInfo); + NormalizedName = default(String); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 Overwrite( + Object FileNode, + Object FileDesc, + UInt32 FileAttributes, + Boolean ReplaceFileAttributes, + UInt64 AllocationSize, + out FileInfo FileInfo) + { + FileInfo = default(FileInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual void Cleanup( + Object FileNode, + Object FileDesc, + String FileName, + UInt32 Flags) + { + } + public virtual void Close( + Object FileNode, + Object FileDesc) + { + } + public virtual Int32 Read( + Object FileNode, + Object FileDesc, + IntPtr Buffer, + UInt64 Offset, + UInt32 Length, + out UInt32 BytesTransferred) + { + BytesTransferred = default(UInt32); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 Write( + Object FileNode, + Object FileDesc, + IntPtr Buffer, + UInt64 Offset, + UInt32 Length, + Boolean WriteToEndOfFile, + Boolean ConstrainedIo, + out UInt32 BytesTransferred, + out FileInfo FileInfo) + { + BytesTransferred = default(UInt32); + FileInfo = default(FileInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 Flush( + Object FileNode, + Object FileDesc, + out FileInfo FileInfo) + { + FileInfo = default(FileInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 GetFileInfo( + Object FileNode, + Object FileDesc, + out FileInfo FileInfo) + { + FileInfo = default(FileInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 SetBasicInfo( + Object FileNode, + Object FileDesc, + UInt32 FileAttributes, + UInt64 CreationTime, + UInt64 LastAccessTime, + UInt64 LastWriteTime, + UInt64 ChangeTime, + out FileInfo FileInfo) + { + FileInfo = default(FileInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 SetFileSize( + Object FileNode, + Object FileDesc, + UInt64 NewSize, + Boolean SetAllocationSize, + out FileInfo FileInfo) + { + FileInfo = default(FileInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 CanDelete( + Object FileNode, + Object FileDesc, + String FileName) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 Rename( + Object FileNode, + Object FileDesc, + String FileName, + String NewFileName, + Boolean ReplaceIfExists) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 GetSecurity( + Object FileNode, + Object FileDesc, + ref Byte[] SecurityDescriptor) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 SetSecurity( + Object FileNode, + Object FileDesc, + AccessControlSections Sections, + Byte[] SecurityDescriptor) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 ReadDirectory( + Object FileNode, + Object FileDesc, + String Pattern, + String Marker, + IntPtr Buffer, + UInt32 Length, + out UInt32 BytesTransferred) + { + return SeekableReadDirectory(FileNode, FileDesc, Pattern, Marker, Buffer, Length, + out BytesTransferred); + } + public virtual Boolean ReadDirectoryEntry( + Object FileNode, + Object FileDesc, + String Pattern, + String Marker, + ref Object Context, + out String FileName, + out FileInfo FileInfo) + { + FileName = default(String); + FileInfo = default(FileInfo); + return false; + } + public virtual Int32 ResolveReparsePoints( + String FileName, + UInt32 ReparsePointIndex, + Boolean ResolveLastPathComponent, + out IoStatusBlock IoStatus, + IntPtr Buffer, + ref UIntPtr Size) + { + GCHandle Handle = GCHandle.Alloc(this, GCHandleType.Normal); + try + { + return Api.FspFileSystemResolveReparsePoints( + IntPtr.Zero, + GetReparsePointByName, + (IntPtr)Handle, + FileName, + ReparsePointIndex, + ResolveLastPathComponent, + out IoStatus, + Buffer, + ref Size); + } + finally + { + Handle.Free(); + } + } + public virtual Int32 GetReparsePointByName( + String FileName, + Boolean IsDirectory, + IntPtr Buffer, + ref UIntPtr Size) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 GetReparsePoint( + Object FileNode, + Object FileDesc, + String FileName, + IntPtr Buffer, + out UIntPtr Size) + { + Size = default(UIntPtr); + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 SetReparsePoint( + Object FileNode, + Object FileDesc, + String FileName, + IntPtr Buffer, + UIntPtr Size) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 DeleteReparsePoint( + Object FileNode, + Object FileDesc, + String FileName, + IntPtr Buffer, + UIntPtr Size) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + public virtual Int32 GetStreamInfo( + Object FileNode, + Object FileDesc, + IntPtr Buffer, + UInt32 Length, + out UInt32 BytesTransferred) + { + BytesTransferred = default(UInt32); + return STATUS_INVALID_DEVICE_REQUEST; + } + + /* helpers */ + public static Int32 NtStatusFromWin32(UInt32 Error) + { + return Api.FspNtStatusFromWin32(Error); + } + public static UInt32 Win32FromNtStatus(Int32 Status) + { + return Api.FspWin32FromNtStatus(Status); + } + public Int32 SeekableReadDirectory( + Object FileNode, + Object FileDesc, + String Pattern, + String Marker, + IntPtr Buffer, + UInt32 Length, + out UInt32 BytesTransferred) + { + Object Context = null; + String FileName; + DirInfo DirInfo = default(DirInfo); + BytesTransferred = default(UInt32); + while (ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, + ref Context, out FileName, out DirInfo.FileInfo)) + { + DirInfo.SetFileNameBuf(FileName); + if (!Api.FspFileSystemAddDirInfo(ref DirInfo, Buffer, Length, + out BytesTransferred)) + break; + } + return STATUS_SUCCESS; + } + public Int32 BufferedReadDirectory( + DirectoryBuffer DirectoryBuffer, + Object FileNode, + Object FileDesc, + String Pattern, + String Marker, + IntPtr Buffer, + UInt32 Length, + out UInt32 BytesTransferred) + { + Object Context = null; + String FileName; + DirInfo DirInfo = default(DirInfo); + Int32 DirBufferResult = STATUS_SUCCESS; + BytesTransferred = default(UInt32); + if (Api.FspFileSystemAcquireDirectoryBuffer(ref DirectoryBuffer.DirBuffer, null == Marker, + out DirBufferResult)) + try + { + while (ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, + ref Context, out FileName, out DirInfo.FileInfo)) + { + DirInfo.SetFileNameBuf(FileName); + if (!Api.FspFileSystemFillDirectoryBuffer( + ref DirectoryBuffer.DirBuffer, ref DirInfo, out DirBufferResult)) + break; + } + } + finally + { + Api.FspFileSystemReleaseDirectoryBuffer(ref DirectoryBuffer.DirBuffer); + } + if (0 > DirBufferResult) + { + BytesTransferred = default(UInt32); + return DirBufferResult; + } + Api.FspFileSystemReadDirectoryBuffer(ref DirectoryBuffer.DirBuffer, + Marker, Buffer, Length, out BytesTransferred); + return STATUS_SUCCESS; + } + public Int32 FindReparsePoint( + String FileName, + out UInt32 ReparsePointIndex) + { + GCHandle Handle = GCHandle.Alloc(this, GCHandleType.Normal); + try + { + return Api.FspFileSystemFindReparsePoint( + IntPtr.Zero, + GetReparsePointByName, + (IntPtr)Handle, + FileName, + out ReparsePointIndex); + } + finally + { + Handle.Free(); + } + } + private static Int32 GetReparsePointByName( + IntPtr FileSystem, + IntPtr Context, + String FileName, + Boolean IsDirectory, + IntPtr Buffer, + ref UIntPtr Size) + { + FileSystemBase self = (FileSystemBase)GCHandle.FromIntPtr(Context).Target; + try + { + return self.GetReparsePointByName( + FileName, + IsDirectory, + Buffer, + ref Size); + } + catch (Exception ex) + { + return self.ExceptionHandler(ex); + } + } + } + +} diff --git a/src/dotnet/FileSystem.cs b/src/dotnet/FileSystemHost.cs similarity index 57% rename from src/dotnet/FileSystem.cs rename to src/dotnet/FileSystemHost.cs index 35b792ce..7a409f96 100644 --- a/src/dotnet/FileSystem.cs +++ b/src/dotnet/FileSystemHost.cs @@ -1,5 +1,5 @@ /** - * @file dotnet/FileSystem.cs + * @file dotnet/FileSystemHost.cs * * @copyright 2015-2017 Bill Zissimopoulos */ @@ -24,35 +24,15 @@ using Fsp.Interop; namespace Fsp { - public partial class FileSystem : IDisposable + public class FileSystemHost : IDisposable { - /* types */ - public class DirectoryBuffer : IDisposable - { - ~DirectoryBuffer() - { - Dispose(false); - } - public void Dispose() - { - lock (this) - Dispose(true); - GC.SuppressFinalize(true); - } - protected virtual void Dispose(bool disposing) - { - Api.FspFileSystemDeleteDirectoryBuffer(ref DirBuffer); - } - - internal IntPtr DirBuffer; - } - /* ctor/dtor */ - public FileSystem() + public FileSystemHost(FileSystemBase FileSystem) { _VolumeParams.Flags = VolumeParams.UmFileContextIsFullContext; + _FileSystem = FileSystem; } - ~FileSystem() + ~FileSystemHost() { Dispose(false); } @@ -64,12 +44,21 @@ namespace Fsp } protected virtual void Dispose(bool disposing) { - if (IntPtr.Zero != _FileSystem) + if (IntPtr.Zero != _FileSystemPtr) { - Api.FspFileSystemStopDispatcher(_FileSystem); - Api.SetUserContext(_FileSystem, null); - Api.FspFileSystemDelete(_FileSystem); - _FileSystem = IntPtr.Zero; + Api.FspFileSystemStopDispatcher(_FileSystemPtr); + if (disposing) + try + { + _FileSystem.Unmounted(this); + } + catch (Exception ex) + { + ExceptionHandler(_FileSystem, ex); + } + Api.SetUserContext(_FileSystemPtr, null); + Api.FspFileSystemDelete(_FileSystemPtr); + _FileSystemPtr = IntPtr.Zero; } } @@ -173,26 +162,57 @@ namespace Fsp UInt32 DebugLog = 0) { Int32 Result; + try + { + Result = _FileSystem.Init(this); + } + catch (Exception ex) + { + Result = ExceptionHandler(_FileSystem, ex); + } + if (0 > Result) + return Result; Result = Api.FspFileSystemCreate( _VolumeParams.IsPrefixEmpty() ? "WinFsp.Disk" : "WinFsp.Net", - ref _VolumeParams, _FileSystemInterfacePtr, out _FileSystem); + ref _VolumeParams, _FileSystemInterfacePtr, out _FileSystemPtr); + if (0 > Result) + return Result; + Api.SetUserContext(_FileSystemPtr, _FileSystem); + Api.FspFileSystemSetOperationGuardStrategy(_FileSystemPtr, Synchronized ? + 1/*FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE*/ : + 0/*FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE*/); + Api.FspFileSystemSetDebugLog(_FileSystemPtr, DebugLog); + Result = Api.FspFileSystemSetMountPointEx(_FileSystemPtr, MountPoint, + SecurityDescriptor); if (0 <= Result) { - Api.SetUserContext(_FileSystem, this); - Api.FspFileSystemSetOperationGuardStrategy(_FileSystem, Synchronized ? - 1/*FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE*/ : - 0/*FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE*/); - Api.FspFileSystemSetDebugLog(_FileSystem, DebugLog); - Result = Api.FspFileSystemSetMountPointEx(_FileSystem, MountPoint, - SecurityDescriptor); + try + { + Result = _FileSystem.Mounted(this); + } + catch (Exception ex) + { + Result = ExceptionHandler(_FileSystem, ex); + } if (0 <= Result) - Result = Api.FspFileSystemStartDispatcher(_FileSystem, 0); + { + Result = Api.FspFileSystemStartDispatcher(_FileSystemPtr, 0); + if (0 > Result) + try + { + _FileSystem.Unmounted(this); + } + catch (Exception ex) + { + ExceptionHandler(_FileSystem, ex); + } + } } - if (0 > Result && IntPtr.Zero != _FileSystem) + if (0 > Result) { - Api.SetUserContext(_FileSystem, null); - Api.FspFileSystemDelete(_FileSystem); - _FileSystem = IntPtr.Zero; + Api.SetUserContext(_FileSystemPtr, null); + Api.FspFileSystemDelete(_FileSystemPtr); + _FileSystemPtr = IntPtr.Zero; } return Result; } @@ -202,405 +222,79 @@ namespace Fsp } public String MountPoint() { - return IntPtr.Zero != _FileSystem ? - Marshal.PtrToStringUni(Api.FspFileSystemMountPoint(_FileSystem)) : null; + return IntPtr.Zero != _FileSystemPtr ? + Marshal.PtrToStringUni(Api.FspFileSystemMountPoint(_FileSystemPtr)) : null; } public IntPtr FileSystemHandle() + { + return _FileSystemPtr; + } + public FileSystemBase FileSystem() { return _FileSystem; } - - /* helpers */ - public Int32 SeekableReadDirectory( - Object FileNode, - Object FileDesc, - String Pattern, - String Marker, - IntPtr Buffer, - UInt32 Length, - out UInt32 PBytesTransferred) - { - Object Context = null; - String FileName; - DirInfo DirInfo = default(DirInfo); - PBytesTransferred = default(UInt32); - while (ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, - ref Context, out FileName, out DirInfo.FileInfo)) - { - DirInfo.SetFileNameBuf(FileName); - if (!Api.FspFileSystemAddDirInfo(ref DirInfo, Buffer, Length, - out PBytesTransferred)) - break; - } - return STATUS_SUCCESS; - } - public Int32 BufferedReadDirectory( - DirectoryBuffer DirectoryBuffer, - Object FileNode, - Object FileDesc, - String Pattern, - String Marker, - IntPtr Buffer, - UInt32 Length, - out UInt32 PBytesTransferred) - { - Object Context = null; - String FileName; - DirInfo DirInfo = default(DirInfo); - Int32 DirBufferResult = STATUS_SUCCESS; - PBytesTransferred = default(UInt32); - if (Api.FspFileSystemAcquireDirectoryBuffer(ref DirectoryBuffer.DirBuffer, null == Marker, - out DirBufferResult)) - try - { - while (ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker, - ref Context, out FileName, out DirInfo.FileInfo)) - { - DirInfo.SetFileNameBuf(FileName); - if (!Api.FspFileSystemFillDirectoryBuffer( - ref DirectoryBuffer.DirBuffer, ref DirInfo, out DirBufferResult)) - break; - } - } - finally - { - Api.FspFileSystemReleaseDirectoryBuffer(ref DirectoryBuffer.DirBuffer); - } - if (0 > DirBufferResult) - { - PBytesTransferred = default(UInt32); - return DirBufferResult; - } - Api.FspFileSystemReadDirectoryBuffer(ref DirectoryBuffer.DirBuffer, - Marker, Buffer, Length, out PBytesTransferred); - return STATUS_SUCCESS; - } - public static Int32 NtStatusFromWin32(UInt32 Error) - { - return Api.FspNtStatusFromWin32(Error); - } - public static UInt32 Win32FromNtStatus(Int32 Status) - { - return Api.FspWin32FromNtStatus(Status); - } public static Int32 SetDebugLogFile(String FileName) { return Api.SetDebugLogFile(FileName); } - /* operations */ - protected virtual Int32 ExceptionHandler(Exception ex) - { - return STATUS_UNEXPECTED_IO_ERROR; - } - protected virtual Int32 GetVolumeInfo( - out VolumeInfo VolumeInfo) - { - VolumeInfo = default(VolumeInfo); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 SetVolumeLabel( - String VolumeLabel, - out VolumeInfo VolumeInfo) - { - VolumeInfo = default(VolumeInfo); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 GetSecurityByName( - String FileName, - out UInt32 FileAttributes/* or ReparsePointIndex */, - ref Byte[] SecurityDescriptor) - { - FileAttributes = default(UInt32); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 Create( - String FileName, - UInt32 CreateOptions, - UInt32 GrantedAccess, - UInt32 FileAttributes, - Byte[] SecurityDescriptor, - UInt64 AllocationSize, - out Object FileNode, - out Object FileDesc, - out FileInfo FileInfo, - out String NormalizedName) - { - FileNode = default(Object); - FileDesc = default(Object); - FileInfo = default(FileInfo); - NormalizedName = default(String); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 Open( - String FileName, - UInt32 CreateOptions, - UInt32 GrantedAccess, - out Object FileNode, - out Object FileDesc, - out FileInfo FileInfo, - out String NormalizedName) - { - FileNode = default(Object); - FileDesc = default(Object); - FileInfo = default(FileInfo); - NormalizedName = default(String); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 Overwrite( - Object FileNode, - Object FileDesc, - UInt32 FileAttributes, - Boolean ReplaceFileAttributes, - UInt64 AllocationSize, - out FileInfo FileInfo) - { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual void Cleanup( - Object FileNode, - Object FileDesc, - String FileName, - UInt32 Flags) - { - } - protected virtual void Close( - Object FileNode, - Object FileDesc) - { - } - protected virtual Int32 Read( - Object FileNode, - Object FileDesc, - IntPtr Buffer, - UInt64 Offset, - UInt32 Length, - out UInt32 PBytesTransferred) - { - PBytesTransferred = default(UInt32); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 Write( - Object FileNode, - Object FileDesc, - IntPtr Buffer, - UInt64 Offset, - UInt32 Length, - Boolean WriteToEndOfFile, - Boolean ConstrainedIo, - out UInt32 PBytesTransferred, - out FileInfo FileInfo) - { - PBytesTransferred = default(UInt32); - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 Flush( - Object FileNode, - Object FileDesc, - out FileInfo FileInfo) - { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 GetFileInfo( - Object FileNode, - Object FileDesc, - out FileInfo FileInfo) - { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 SetBasicInfo( - Object FileNode, - Object FileDesc, - UInt32 FileAttributes, - UInt64 CreationTime, - UInt64 LastAccessTime, - UInt64 LastWriteTime, - UInt64 ChangeTime, - out FileInfo FileInfo) - { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 SetFileSize( - Object FileNode, - Object FileDesc, - UInt64 NewSize, - Boolean SetAllocationSize, - out FileInfo FileInfo) - { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 CanDelete( - Object FileNode, - Object FileDesc, - String FileName) - { - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 Rename( - Object FileNode, - Object FileDesc, - String FileName, - String NewFileName, - Boolean ReplaceIfExists) - { - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 GetSecurity( - Object FileNode, - Object FileDesc, - ref Byte[] SecurityDescriptor) - { - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 SetSecurity( - Object FileNode, - Object FileDesc, - AccessControlSections Sections, - Byte[] SecurityDescriptor) - { - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 ReadDirectory( - Object FileNode, - Object FileDesc, - String Pattern, - String Marker, - IntPtr Buffer, - UInt32 Length, - out UInt32 PBytesTransferred) - { - return SeekableReadDirectory(FileNode, FileDesc, Pattern, Marker, Buffer, Length, - out PBytesTransferred); - } - protected virtual Boolean ReadDirectoryEntry( - Object FileNode, - Object FileDesc, - String Pattern, - String Marker, - ref Object Context, - out String FileName, - out FileInfo FileInfo) - { - FileName = default(String); - FileInfo = default(FileInfo); - return false; - } - protected virtual Int32 ResolveReparsePoints( - String FileName, - UInt32 ReparsePointIndex, - Boolean ResolveLastPathComponent, - out IoStatusBlock PIoStatus, - IntPtr Buffer, - ref UIntPtr PSize) - { - return Api.FspFileSystemResolveReparsePoints( - _FileSystem, - GetReparsePointByName, - IntPtr.Zero, - FileName, - ReparsePointIndex, - ResolveLastPathComponent, - out PIoStatus, - Buffer, - ref PSize); - } - protected virtual Int32 GetReparsePointByName( - String FileName, - Boolean IsDirectory, - IntPtr Buffer, - ref UIntPtr PSize) - { - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 GetReparsePoint( - Object FileNode, - Object FileDesc, - String FileName, - IntPtr Buffer, - out UIntPtr PSize) - { - PSize = default(UIntPtr); - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 SetReparsePoint( - Object FileNode, - Object FileDesc, - String FileName, - IntPtr Buffer, - UIntPtr Size) - { - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 DeleteReparsePoint( - Object FileNode, - Object FileDesc, - String FileName, - IntPtr Buffer, - UIntPtr Size) - { - return STATUS_INVALID_DEVICE_REQUEST; - } - protected virtual Int32 GetStreamInfo( - Object FileNode, - Object FileDesc, - IntPtr Buffer, - UInt32 Length, - out UInt32 PBytesTransferred) - { - PBytesTransferred = default(UInt32); - return STATUS_INVALID_DEVICE_REQUEST; - } - /* FSP_FILE_SYSTEM_INTERFACE */ private static Byte[] SecurityDescriptorNotNull = new Byte[0]; - private static Int32 GetVolumeInfo( - IntPtr FileSystem, - out VolumeInfo VolumeInfo) + private static Int32 ExceptionHandler( + FileSystemBase FileSystem, + Exception ex) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); try { - return self.GetVolumeInfo( + return FileSystem.ExceptionHandler(ex); + } + catch + { + return unchecked((Int32)0xc00000e9)/*STATUS_UNEXPECTED_IO_ERROR*/; + } + } + private static Int32 GetVolumeInfo( + IntPtr FileSystemPtr, + out VolumeInfo VolumeInfo) + { + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); + try + { + return FileSystem.GetVolumeInfo( out VolumeInfo); } catch (Exception ex) { VolumeInfo = default(VolumeInfo); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 SetVolumeLabel( - IntPtr FileSystem, + IntPtr FileSystemPtr, String VolumeLabel, out VolumeInfo VolumeInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { - return self.SetVolumeLabel( + return FileSystem.SetVolumeLabel( VolumeLabel, out VolumeInfo); } catch (Exception ex) { VolumeInfo = default(VolumeInfo); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 GetSecurityByName( - IntPtr FileSystem, + IntPtr FileSystemPtr, String FileName, IntPtr PFileAttributes/* or ReparsePointIndex */, IntPtr SecurityDescriptor, IntPtr PSecurityDescriptorSize) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { UInt32 FileAttributes; @@ -608,7 +302,7 @@ namespace Fsp Int32 Result; if (IntPtr.Zero != PSecurityDescriptorSize) SecurityDescriptorBytes = SecurityDescriptorNotNull; - Result = self.GetSecurityByName( + Result = FileSystem.GetSecurityByName( FileName, out FileAttributes, ref SecurityDescriptorBytes); @@ -623,11 +317,11 @@ namespace Fsp } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 Create( - IntPtr FileSystem, + IntPtr FileSystemPtr, String FileName, UInt32 CreateOptions, UInt32 GrantedAccess, @@ -637,13 +331,13 @@ namespace Fsp ref FullContext FullContext, ref OpenFileInfo OpenFileInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; String NormalizedName; Int32 Result; - Result = self.Create( + Result = FileSystem.Create( FileName, CreateOptions, GrantedAccess, @@ -664,24 +358,24 @@ namespace Fsp } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 Open( - IntPtr FileSystem, + IntPtr FileSystemPtr, String FileName, UInt32 CreateOptions, UInt32 GrantedAccess, ref FullContext FullContext, ref OpenFileInfo OpenFileInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; String NormalizedName; Int32 Result; - Result = self.Open( + Result = FileSystem.Open( FileName, CreateOptions, GrantedAccess, @@ -699,23 +393,23 @@ namespace Fsp } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 Overwrite( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, UInt32 FileAttributes, Boolean ReplaceFileAttributes, UInt64 AllocationSize, out FileInfo FileInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.Overwrite( + return FileSystem.Overwrite( FileNode, FileDesc, FileAttributes, @@ -726,21 +420,21 @@ namespace Fsp catch (Exception ex) { FileInfo = default(FileInfo); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static void Cleanup( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, String FileName, UInt32 Flags) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - self.Cleanup( + FileSystem.Cleanup( FileNode, FileDesc, FileName, @@ -748,42 +442,42 @@ namespace Fsp } catch (Exception ex) { - self.ExceptionHandler(ex); + ExceptionHandler(FileSystem, ex); } } private static void Close( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - self.Close( + FileSystem.Close( FileNode, FileDesc); Api.SetFullContext(ref FullContext, null, null); } catch (Exception ex) { - self.ExceptionHandler(ex); + ExceptionHandler(FileSystem, ex); } } private static Int32 Read( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, IntPtr Buffer, UInt64 Offset, UInt32 Length, out UInt32 PBytesTransferred) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.Read( + return FileSystem.Read( FileNode, FileDesc, Buffer, @@ -794,11 +488,11 @@ namespace Fsp catch (Exception ex) { PBytesTransferred = default(UInt32); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 Write( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, IntPtr Buffer, UInt64 Offset, @@ -808,12 +502,12 @@ namespace Fsp out UInt32 PBytesTransferred, out FileInfo FileInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.Write( + return FileSystem.Write( FileNode, FileDesc, Buffer, @@ -828,20 +522,20 @@ namespace Fsp { PBytesTransferred = default(UInt32); FileInfo = default(FileInfo); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 Flush( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, out FileInfo FileInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.Flush( + return FileSystem.Flush( FileNode, FileDesc, out FileInfo); @@ -849,20 +543,20 @@ namespace Fsp catch (Exception ex) { FileInfo = default(FileInfo); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 GetFileInfo( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, out FileInfo FileInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.GetFileInfo( + return FileSystem.GetFileInfo( FileNode, FileDesc, out FileInfo); @@ -870,11 +564,11 @@ namespace Fsp catch (Exception ex) { FileInfo = default(FileInfo); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 SetBasicInfo( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, UInt32 FileAttributes, UInt64 CreationTime, @@ -883,12 +577,12 @@ namespace Fsp UInt64 ChangeTime, out FileInfo FileInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.SetBasicInfo( + return FileSystem.SetBasicInfo( FileNode, FileDesc, FileAttributes, @@ -901,22 +595,22 @@ namespace Fsp catch (Exception ex) { FileInfo = default(FileInfo); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 SetFileSize( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, UInt64 NewSize, Boolean SetAllocationSize, out FileInfo FileInfo) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.SetFileSize( + return FileSystem.SetFileSize( FileNode, FileDesc, NewSize, @@ -926,42 +620,42 @@ namespace Fsp catch (Exception ex) { FileInfo = default(FileInfo); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 CanDelete( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, String FileName) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.CanDelete( + return FileSystem.CanDelete( FileNode, FileDesc, FileName); } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 Rename( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, String FileName, String NewFileName, Boolean ReplaceIfExists) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.Rename( + return FileSystem.Rename( FileNode, FileDesc, FileName, @@ -970,16 +664,16 @@ namespace Fsp } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 GetSecurity( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, IntPtr SecurityDescriptor, IntPtr PSecurityDescriptorSize) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; @@ -987,7 +681,7 @@ namespace Fsp Int32 Result; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); SecurityDescriptorBytes = SecurityDescriptorNotNull; - Result = self.GetSecurity( + Result = FileSystem.GetSecurity( FileNode, FileDesc, ref SecurityDescriptorBytes); @@ -996,16 +690,16 @@ namespace Fsp } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 SetSecurity( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, UInt32 SecurityInformation, IntPtr ModificationDescriptor) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; @@ -1020,7 +714,7 @@ namespace Fsp Sections |= AccessControlSections.Access; if (0 != (SecurityInformation & 8/*SACL_SECURITY_INFORMATION*/)) Sections |= AccessControlSections.Audit; - return self.SetSecurity( + return FileSystem.SetSecurity( FileNode, FileDesc, Sections, @@ -1028,11 +722,11 @@ namespace Fsp } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 ReadDirectory( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, String Pattern, String Marker, @@ -1040,12 +734,12 @@ namespace Fsp UInt32 Length, out UInt32 PBytesTransferred) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.ReadDirectory( + return FileSystem.ReadDirectory( FileNode, FileDesc, Pattern, @@ -1057,11 +751,11 @@ namespace Fsp catch (Exception ex) { PBytesTransferred = default(UInt32); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 ResolveReparsePoints( - IntPtr FileSystem, + IntPtr FileSystemPtr, String FileName, UInt32 ReparsePointIndex, Boolean ResolveLastPathComponent, @@ -1069,10 +763,10 @@ namespace Fsp IntPtr Buffer, ref UIntPtr PSize) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { - return self.ResolveReparsePoints( + return FileSystem.ResolveReparsePoints( FileName, ReparsePointIndex, ResolveLastPathComponent, @@ -1083,44 +777,22 @@ namespace Fsp catch (Exception ex) { PIoStatus = default(IoStatusBlock); - return self.ExceptionHandler(ex); - } - } - private static Int32 GetReparsePointByName( - IntPtr FileSystem, - IntPtr Context, - String FileName, - Boolean IsDirectory, - IntPtr Buffer, - ref UIntPtr PSize) - { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); - try - { - return self.GetReparsePointByName( - FileName, - IsDirectory, - Buffer, - ref PSize); - } - catch (Exception ex) - { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 GetReparsePoint( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, String FileName, IntPtr Buffer, out UIntPtr PSize) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.GetReparsePoint( + return FileSystem.GetReparsePoint( FileNode, FileDesc, FileName, @@ -1130,22 +802,22 @@ namespace Fsp catch (Exception ex) { PSize = default(UIntPtr); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 SetReparsePoint( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, String FileName, IntPtr Buffer, UIntPtr Size) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.SetReparsePoint( + return FileSystem.SetReparsePoint( FileNode, FileDesc, FileName, @@ -1154,22 +826,22 @@ namespace Fsp } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 DeleteReparsePoint( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, String FileName, IntPtr Buffer, UIntPtr Size) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.DeleteReparsePoint( + return FileSystem.DeleteReparsePoint( FileNode, FileDesc, FileName, @@ -1178,22 +850,22 @@ namespace Fsp } catch (Exception ex) { - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } private static Int32 GetStreamInfo( - IntPtr FileSystem, + IntPtr FileSystemPtr, ref FullContext FullContext, IntPtr Buffer, UInt32 Length, out UInt32 PBytesTransferred) { - FileSystem self = (FileSystem)Api.GetUserContext(FileSystem); + FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { Object FileNode, FileDesc; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return self.GetStreamInfo( + return FileSystem.GetStreamInfo( FileNode, FileDesc, Buffer, @@ -1203,11 +875,11 @@ namespace Fsp catch (Exception ex) { PBytesTransferred = default(UInt32); - return self.ExceptionHandler(ex); + return ExceptionHandler(FileSystem, ex); } } - static FileSystem() + static FileSystemHost() { _FileSystemInterface.GetVolumeInfo = GetVolumeInfo; _FileSystemInterface.SetVolumeLabel = SetVolumeLabel; @@ -1241,7 +913,8 @@ namespace Fsp private static FileSystemInterface _FileSystemInterface; private static IntPtr _FileSystemInterfacePtr; private VolumeParams _VolumeParams; - private IntPtr _FileSystem; + private IntPtr _FileSystemPtr; + private FileSystemBase _FileSystem; } } diff --git a/tst/passthrough-dotnet/Program.cs b/tst/passthrough-dotnet/Program.cs index 280fe240..382070fd 100644 --- a/tst/passthrough-dotnet/Program.cs +++ b/tst/passthrough-dotnet/Program.cs @@ -27,7 +27,7 @@ using FileInfo = Fsp.Interop.FileInfo; namespace passthrough { - class Ptfs : FileSystem + class Ptfs : FileSystemBase { protected const int ALLOCATION_UNIT = 4096; @@ -277,40 +277,41 @@ namespace passthrough private static DirectoryEntryComparer _DirectoryEntryComparer = new DirectoryEntryComparer(); - public Ptfs() : base() + public Ptfs(String Path0) { - SectorSize = ALLOCATION_UNIT; - SectorsPerAllocationUnit = 1; - MaxComponentLength = 255; - FileInfoTimeout = 1000; - CaseSensitiveSearch = false; - CasePreservedNames = true; - UnicodeOnDisk = true; - PersistentAcls = true; - PostCleanupWhenModifiedOnly = true; - PassQueryDirectoryPattern = true; - } - public void SetPath(String value) - { - _Path = Path.GetFullPath(value); + _Path = Path.GetFullPath(Path0); if (_Path.EndsWith("\\")) _Path = _Path.Substring(0, _Path.Length - 1); - VolumeCreationTime = (UInt64)File.GetCreationTimeUtc(_Path).ToFileTimeUtc(); - VolumeSerialNumber = 0; } - - protected override Int32 ExceptionHandler(Exception ex) + public String ConcatPath(String FileName) + { + return _Path + FileName; + } + public override Int32 ExceptionHandler(Exception ex) { Int32 HResult = ex.HResult; /* needs Framework 4.5 */ if (0x80070000 == (HResult & 0xFFFF0000)) return NtStatusFromWin32((UInt32)HResult & 0xFFFF); return STATUS_UNEXPECTED_IO_ERROR; } - protected String ConcatPath(String FileName) + public override Int32 Init(Object Host0) { - return _Path + FileName; + FileSystemHost Host = (FileSystemHost)Host0; + Host.SectorSize = ALLOCATION_UNIT; + Host.SectorsPerAllocationUnit = 1; + Host.MaxComponentLength = 255; + Host.FileInfoTimeout = 1000; + Host.CaseSensitiveSearch = false; + Host.CasePreservedNames = true; + Host.UnicodeOnDisk = true; + Host.PersistentAcls = true; + Host.PostCleanupWhenModifiedOnly = true; + Host.PassQueryDirectoryPattern = true; + Host.VolumeCreationTime = (UInt64)File.GetCreationTimeUtc(_Path).ToFileTimeUtc(); + Host.VolumeSerialNumber = 0; + return STATUS_SUCCESS; } - protected override Int32 GetVolumeInfo( + public override Int32 GetVolumeInfo( out VolumeInfo VolumeInfo) { VolumeInfo = default(VolumeInfo); @@ -329,7 +330,7 @@ namespace passthrough } return STATUS_SUCCESS; } - protected override Int32 GetSecurityByName( + public override Int32 GetSecurityByName( String FileName, out UInt32 FileAttributes/* or ReparsePointIndex */, ref Byte[] SecurityDescriptor) @@ -341,7 +342,7 @@ namespace passthrough SecurityDescriptor = Info.GetAccessControl().GetSecurityDescriptorBinaryForm(); return STATUS_SUCCESS; } - protected override Int32 Create( + public override Int32 Create( String FileName, UInt32 CreateOptions, UInt32 GrantedAccess, @@ -401,7 +402,7 @@ namespace passthrough throw; } } - protected override Int32 Open( + public override Int32 Open( String FileName, UInt32 CreateOptions, UInt32 GrantedAccess, @@ -442,7 +443,7 @@ namespace passthrough throw; } } - protected override Int32 Overwrite( + public override Int32 Overwrite( Object FileNode, Object FileDesc0, UInt32 FileAttributes, @@ -458,7 +459,7 @@ namespace passthrough FileDesc.Stream.SetLength(0); return FileDesc.GetFileInfo(out FileInfo); } - protected override void Cleanup( + public override void Cleanup( Object FileNode, Object FileDesc0, String FileName, @@ -472,7 +473,7 @@ namespace passthrough FileDesc.Stream.Dispose(); } } - protected override void Close( + public override void Close( Object FileNode, Object FileDesc0) { @@ -480,7 +481,7 @@ namespace passthrough if (null != FileDesc.Stream) FileDesc.Stream.Dispose(); } - protected override Int32 Read( + public override Int32 Read( Object FileNode, Object FileDesc0, IntPtr Buffer, @@ -497,7 +498,7 @@ namespace passthrough Marshal.Copy(Bytes, 0, Buffer, Bytes.Length); return STATUS_SUCCESS; } - protected override Int32 Write( + public override Int32 Write( Object FileNode, Object FileDesc0, IntPtr Buffer, @@ -528,7 +529,7 @@ namespace passthrough PBytesTransferred = (UInt32)Bytes.Length; return FileDesc.GetFileInfo(out FileInfo); } - protected override Int32 Flush( + public override Int32 Flush( Object FileNode, Object FileDesc0, out FileInfo FileInfo) @@ -543,7 +544,7 @@ namespace passthrough FileDesc.Stream.Flush(true); return FileDesc.GetFileInfo(out FileInfo); } - protected override Int32 GetFileInfo( + public override Int32 GetFileInfo( Object FileNode, Object FileDesc0, out FileInfo FileInfo) @@ -551,7 +552,7 @@ namespace passthrough FileDesc FileDesc = (FileDesc)FileDesc0; return FileDesc.GetFileInfo(out FileInfo); } - protected override Int32 SetBasicInfo( + public override Int32 SetBasicInfo( Object FileNode, Object FileDesc0, UInt32 FileAttributes, @@ -565,7 +566,7 @@ namespace passthrough FileDesc.SetBasicInfo(FileAttributes, CreationTime, LastAccessTime, LastWriteTime); return FileDesc.GetFileInfo(out FileInfo); } - protected override Int32 SetFileSize( + public override Int32 SetFileSize( Object FileNode, Object FileDesc0, UInt64 NewSize, @@ -584,7 +585,7 @@ namespace passthrough } return FileDesc.GetFileInfo(out FileInfo); } - protected override Int32 CanDelete( + public override Int32 CanDelete( Object FileNode, Object FileDesc0, String FileName) @@ -593,7 +594,7 @@ namespace passthrough FileDesc.SetDisposition(false); return STATUS_SUCCESS; } - protected override Int32 Rename( + public override Int32 Rename( Object FileNode, Object FileDesc0, String FileName, @@ -605,7 +606,7 @@ namespace passthrough FileDesc.Rename(FileName, NewFileName, ReplaceIfExists); return STATUS_SUCCESS; } - protected override Int32 GetSecurity( + public override Int32 GetSecurity( Object FileNode, Object FileDesc0, ref Byte[] SecurityDescriptor) @@ -614,7 +615,7 @@ namespace passthrough SecurityDescriptor = FileDesc.GetSecurityDescriptor(); return STATUS_SUCCESS; } - protected override Int32 SetSecurity( + public override Int32 SetSecurity( Object FileNode, Object FileDesc0, AccessControlSections Sections, @@ -624,7 +625,7 @@ namespace passthrough FileDesc.SetSecurityDescriptor(Sections, SecurityDescriptor); return STATUS_SUCCESS; } - protected override Boolean ReadDirectoryEntry( + public override Boolean ReadDirectoryEntry( Object FileNode, Object FileDesc0, String Pattern, @@ -703,7 +704,6 @@ namespace passthrough protected override void OnStart(String[] Args) { - String FailMessage = null; try { String DebugLogFile = null; @@ -712,6 +712,7 @@ namespace passthrough String PassThrough = null; String MountPoint = null; IntPtr DebugLogHandle = (IntPtr)(-1); + FileSystemHost Host = null; Ptfs Ptfs = null; int I; @@ -770,18 +771,15 @@ namespace passthrough throw new CommandLineUsageException(); if (null != DebugLogFile) - if (0 > FileSystem.SetDebugLogFile(DebugLogFile)) + if (0 > FileSystemHost.SetDebugLogFile(DebugLogFile)) throw new CommandLineUsageException("cannot open debug log file"); - FailMessage = "cannot create file system"; - Ptfs = new Ptfs(); - Ptfs.Prefix = VolumePrefix; - Ptfs.SetPath(PassThrough); - - FailMessage = "cannot mount file system"; - Ptfs.Mount(MountPoint, null, true, DebugFlags); - MountPoint = Ptfs.MountPoint(); - _Ptfs = Ptfs; + Host = new FileSystemHost(Ptfs = new Ptfs(PassThrough)); + Host.Prefix = VolumePrefix; + if (0 > Host.Mount(MountPoint, null, true, DebugFlags)) + throw new IOException("cannot mount file system"); + MountPoint = Host.MountPoint(); + _Host = Host; Log(EVENTLOG_INFORMATION_TYPE, String.Format("{0}{1}{2} -p {3} -m {4}", PROGNAME, @@ -808,16 +806,14 @@ namespace passthrough } catch (Exception ex) { - Log(EVENTLOG_ERROR_TYPE, String.Format("{0}{1}", - null != FailMessage ? FailMessage + "\n" : "", - ex.Message)); + Log(EVENTLOG_ERROR_TYPE, String.Format("{0}", ex.Message)); throw; } } protected override void OnStop() { - _Ptfs.Unmount(); - _Ptfs = null; + _Host.Unmount(); + _Host = null; } private static void argtos(String[] Args, ref int I, ref String V) @@ -836,7 +832,7 @@ namespace passthrough throw new CommandLineUsageException(); } - private Ptfs _Ptfs; + private FileSystemHost _Host; } class Program