From 858f77cdf7ecf1f716ec362264e11ec36328d9dd Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 3 Apr 2017 14:54:26 -0700 Subject: [PATCH] src: dotnet: WIP --- src/dotnet/FileSystem.cs | 582 ++++++++++++++++++++++++++++++++++++--- src/dotnet/Interop.cs | 18 +- 2 files changed, 553 insertions(+), 47 deletions(-) diff --git a/src/dotnet/FileSystem.cs b/src/dotnet/FileSystem.cs index 7730c1ed..ede1f270 100644 --- a/src/dotnet/FileSystem.cs +++ b/src/dotnet/FileSystem.cs @@ -217,6 +217,200 @@ namespace Fsp FileInfo = default(FileInfo); return STATUS_INVALID_DEVICE_REQUEST; } + protected virtual Int32 Open( + String FileName, + UInt32 CreateOptions, + UInt32 GrantedAccess, + out Object FileNode, + out Object FileDesc, + out FileInfo FileInfo) + { + FileNode = default(Object); + FileDesc = default(Object); + FileInfo = default(FileInfo); + 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 Object SecurityDescriptor) + { + return STATUS_INVALID_DEVICE_REQUEST; + } + protected virtual Int32 SetSecurity( + Object FileNode, + Object FileDesc, + UInt32 SecurityInformation, + Object 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) + { + PBytesTransferred = default(UInt32); + return STATUS_INVALID_DEVICE_REQUEST; + } + protected virtual Int32 ResolveReparsePoints( + String FileName, + UInt32 ReparsePointIndex, + Boolean ResolveLastPathComponent, + out IoStatusBlock PIoStatus, + IntPtr Buffer, + out UIntPtr PSize) + { + PIoStatus = default(IoStatusBlock); + PSize = default(UIntPtr); + 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 Object SecurityDescriptorNotNull = new Object(); @@ -227,7 +421,8 @@ namespace Fsp FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); try { - return self.GetVolumeInfo(out VolumeInfo); + return self.GetVolumeInfo( + out VolumeInfo); } catch (Exception ex) { @@ -243,7 +438,9 @@ namespace Fsp FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); try { - return self.SetVolumeLabel(VolumeLabel, out VolumeInfo); + return self.SetVolumeLabel( + VolumeLabel, + out VolumeInfo); } catch (Exception ex) { @@ -266,8 +463,10 @@ namespace Fsp Int32 Result; if (IntPtr.Zero != PSecurityDescriptorSize) SecurityDescriptorObject = SecurityDescriptorNotNull; - Result = self.GetSecurityByName(FileName, - out FileAttributes, ref SecurityDescriptorObject); + Result = self.GetSecurityByName( + FileName, + out FileAttributes, + ref SecurityDescriptorObject); if (IntPtr.Zero != PFileAttributes) Marshal.WriteInt32(PFileAttributes, (Int32)FileAttributes); return Api.CopySecurityDescriptor(SecurityDescriptorObject, @@ -309,7 +508,6 @@ namespace Fsp } catch (Exception ex) { - FullContext = default(FullContext); FileInfo = default(FileInfo); return self.ExceptionHandler(ex); } @@ -322,9 +520,26 @@ namespace Fsp ref FullContext FullContext, out FileInfo FileInfo) { - FullContext = default(FullContext); - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Int32 Result; + Result = self.Open( + FileName, + CreateOptions, + GrantedAccess, + out FileNode, + out FileDesc, + out FileInfo); + Api.SetFullContext(ref FullContext, FileNode, FileDesc); + return Result; + } + catch (Exception ex) + { + FileInfo = default(FileInfo); + return self.ExceptionHandler(ex); + } } private static Int32 Overwrite( IntPtr FileSystem, @@ -334,8 +549,24 @@ namespace Fsp UInt64 AllocationSize, out FileInfo FileInfo) { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.Overwrite( + FileNode, + FileDesc, + FileAttributes, + ReplaceFileAttributes, + AllocationSize, + out FileInfo); + } + catch (Exception ex) + { + FileInfo = default(FileInfo); + return self.ExceptionHandler(ex); + } } private static void Cleanup( IntPtr FileSystem, @@ -343,11 +574,40 @@ namespace Fsp String FileName, UInt32 Flags) { + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + self.Cleanup( + FileNode, + FileDesc, + FileName, + Flags); + } + catch (Exception ex) + { + self.ExceptionHandler(ex); + } } private static void Close( IntPtr FileSystem, ref FullContext FullContext) { + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + self.Close( + FileNode, + FileDesc); + Api.SetFullContext(ref FullContext, null, null); + } + catch (Exception ex) + { + self.ExceptionHandler(ex); + } } private static Int32 Read( IntPtr FileSystem, @@ -357,8 +617,24 @@ namespace Fsp UInt32 Length, out UInt32 PBytesTransferred) { - PBytesTransferred = default(UInt32); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.Read( + FileNode, + FileDesc, + Buffer, + Offset, + Length, + out PBytesTransferred); + } + catch (Exception ex) + { + PBytesTransferred = default(UInt32); + return self.ExceptionHandler(ex); + } } private static Int32 Write( IntPtr FileSystem, @@ -371,25 +647,70 @@ namespace Fsp out UInt32 PBytesTransferred, out FileInfo FileInfo) { - PBytesTransferred = default(UInt32); - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.Write( + FileNode, + FileDesc, + Buffer, + Offset, + Length, + WriteToEndOfFile, + ConstrainedIo, + out PBytesTransferred, + out FileInfo); + } + catch (Exception ex) + { + PBytesTransferred = default(UInt32); + FileInfo = default(FileInfo); + return self.ExceptionHandler(ex); + } } private static Int32 Flush( IntPtr FileSystem, ref FullContext FullContext, out FileInfo FileInfo) { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.Flush( + FileNode, + FileDesc, + out FileInfo); + } + catch (Exception ex) + { + FileInfo = default(FileInfo); + return self.ExceptionHandler(ex); + } } private static Int32 GetFileInfo( IntPtr FileSystem, ref FullContext FullContext, out FileInfo FileInfo) { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.GetFileInfo( + FileNode, + FileDesc, + out FileInfo); + } + catch (Exception ex) + { + FileInfo = default(FileInfo); + return self.ExceptionHandler(ex); + } } private static Int32 SetBasicInfo( IntPtr FileSystem, @@ -401,8 +722,26 @@ namespace Fsp UInt64 ChangeTime, out FileInfo FileInfo) { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.SetBasicInfo( + FileNode, + FileDesc, + FileAttributes, + CreationTime, + LastAccessTime, + LastWriteTime, + ChangeTime, + out FileInfo); + } + catch (Exception ex) + { + FileInfo = default(FileInfo); + return self.ExceptionHandler(ex); + } } private static Int32 SetFileSize( IntPtr FileSystem, @@ -411,15 +750,43 @@ namespace Fsp Boolean SetAllocationSize, out FileInfo FileInfo) { - FileInfo = default(FileInfo); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.SetFileSize( + FileNode, + FileDesc, + NewSize, + SetAllocationSize, + out FileInfo); + } + catch (Exception ex) + { + FileInfo = default(FileInfo); + return self.ExceptionHandler(ex); + } } private static Int32 CanDelete( IntPtr FileSystem, ref FullContext FullContext, String FileName) { - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.CanDelete( + FileNode, + FileDesc, + FileName); + } + catch (Exception ex) + { + return self.ExceptionHandler(ex); + } } private static Int32 Rename( IntPtr FileSystem, @@ -428,7 +795,22 @@ namespace Fsp String NewFileName, Boolean ReplaceIfExists) { - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.Rename( + FileNode, + FileDesc, + FileName, + NewFileName, + ReplaceIfExists); + } + catch (Exception ex) + { + return self.ExceptionHandler(ex); + } } private static Int32 GetSecurity( IntPtr FileSystem, @@ -436,7 +818,26 @@ namespace Fsp IntPtr SecurityDescriptor, IntPtr PSecurityDescriptorSize) { - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Object SecurityDescriptorObject = null; + Int32 Result; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + if (IntPtr.Zero != PSecurityDescriptorSize) + SecurityDescriptorObject = SecurityDescriptorNotNull; + Result = self.GetSecurity( + FileNode, + FileDesc, + ref SecurityDescriptorObject); + return Api.CopySecurityDescriptor(SecurityDescriptorObject, + SecurityDescriptor, PSecurityDescriptorSize); + } + catch (Exception ex) + { + return self.ExceptionHandler(ex); + } } private static Int32 SetSecurity( IntPtr FileSystem, @@ -444,7 +845,21 @@ namespace Fsp UInt32 SecurityInformation, IntPtr ModificationDescriptor) { - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.SetSecurity( + FileNode, + FileDesc, + SecurityInformation, + Api.MakeSecurityDescriptor(ModificationDescriptor)); + } + catch (Exception ex) + { + return self.ExceptionHandler(ex); + } } private static Int32 ReadDirectory( IntPtr FileSystem, @@ -455,8 +870,25 @@ namespace Fsp UInt32 Length, out UInt32 PBytesTransferred) { - PBytesTransferred = default(UInt32); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.ReadDirectory( + FileNode, + FileDesc, + Pattern, + Marker, + Buffer, + Length, + out PBytesTransferred); + } + catch (Exception ex) + { + PBytesTransferred = default(UInt32); + return self.ExceptionHandler(ex); + } } private static Int32 ResolveReparsePoints( IntPtr FileSystem, @@ -467,9 +899,23 @@ namespace Fsp IntPtr Buffer, out UIntPtr PSize) { - PIoStatus = default(IoStatusBlock); - PSize = default(UIntPtr); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + return self.ResolveReparsePoints( + FileName, + ReparsePointIndex, + ResolveLastPathComponent, + out PIoStatus, + Buffer, + out PSize); + } + catch (Exception ex) + { + PIoStatus = default(IoStatusBlock); + PSize = default(UIntPtr); + return self.ExceptionHandler(ex); + } } private static Int32 GetReparsePoint( IntPtr FileSystem, @@ -478,8 +924,23 @@ namespace Fsp IntPtr Buffer, out UIntPtr PSize) { - PSize = default(UIntPtr); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.GetReparsePoint( + FileNode, + FileDesc, + FileName, + Buffer, + out PSize); + } + catch (Exception ex) + { + PSize = default(UIntPtr); + return self.ExceptionHandler(ex); + } } private static Int32 SetReparsePoint( IntPtr FileSystem, @@ -488,7 +949,22 @@ namespace Fsp IntPtr Buffer, UIntPtr Size) { - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.SetReparsePoint( + FileNode, + FileDesc, + FileName, + Buffer, + Size); + } + catch (Exception ex) + { + return self.ExceptionHandler(ex); + } } private static Int32 DeleteReparsePoint( IntPtr FileSystem, @@ -497,7 +973,22 @@ namespace Fsp IntPtr Buffer, UIntPtr Size) { - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.DeleteReparsePoint( + FileNode, + FileDesc, + FileName, + Buffer, + Size); + } + catch (Exception ex) + { + return self.ExceptionHandler(ex); + } } private static Int32 GetStreamInfo( IntPtr FileSystem, @@ -506,8 +997,23 @@ namespace Fsp UInt32 Length, out UInt32 PBytesTransferred) { - PBytesTransferred = default(UInt32); - return STATUS_INVALID_DEVICE_REQUEST; + FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); + try + { + Object FileNode, FileDesc; + Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); + return self.GetStreamInfo( + FileNode, + FileDesc, + Buffer, + Length, + out PBytesTransferred); + } + catch (Exception ex) + { + PBytesTransferred = default(UInt32); + return self.ExceptionHandler(ex); + } } static FileSystem() diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index 04f81693..94c7ca1c 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -166,10 +166,10 @@ namespace Fsp.Interop } [StructLayout(LayoutKind.Sequential)] - internal struct IoStatusBlock + public struct IoStatusBlock { - internal IntPtr Status; - internal IntPtr Information; + public IntPtr Status; + public IntPtr Information; } [StructLayout(LayoutKind.Sequential)] @@ -443,7 +443,7 @@ namespace Fsp.Interop IntPtr FileSystem) { IntPtr UserContext = *(IntPtr *)((byte *)FileSystem + sizeof(IntPtr)); - return IntPtr.Zero != UserContext ? ((GCHandle)UserContext).Target : null; + return IntPtr.Zero != UserContext ? GCHandle.FromIntPtr(UserContext).Target : null; } internal unsafe static void FspFileSystemSetUserContext( IntPtr FileSystem, @@ -460,7 +460,7 @@ namespace Fsp.Interop IntPtr UserContext = *(IntPtr *)((byte *)FileSystem + sizeof(IntPtr)); if (IntPtr.Zero != UserContext) { - ((GCHandle)UserContext).Free(); + GCHandle.FromIntPtr(UserContext).Free(); *(IntPtr *)((byte *)FileSystem + sizeof(IntPtr)) = IntPtr.Zero; } } @@ -470,9 +470,9 @@ namespace Fsp.Interop out Object FileNode, out Object FileDesc) { FileNode = 0 != FullContext.UserContext ? - ((GCHandle)(IntPtr)FullContext.UserContext).Target : null; + GCHandle.FromIntPtr((IntPtr)FullContext.UserContext).Target : null; FileDesc = 0 != FullContext.UserContext2 ? - ((GCHandle)(IntPtr)FullContext.UserContext2).Target : null; + GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Target : null; } internal static void SetFullContext(ref FullContext FullContext, Object FileNode, Object FileDesc) @@ -487,7 +487,7 @@ namespace Fsp.Interop { if (0 != FullContext.UserContext) { - ((GCHandle)(IntPtr)FullContext.UserContext).Free(); + GCHandle.FromIntPtr((IntPtr)FullContext.UserContext).Free(); FullContext.UserContext = 0; } } @@ -501,7 +501,7 @@ namespace Fsp.Interop { if (0 != FullContext.UserContext2) { - ((GCHandle)(IntPtr)FullContext.UserContext2).Free(); + GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Free(); FullContext.UserContext2 = 0; } }