From b38a89e485e014a63da49aa95a64648eafd56632 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Fri, 5 May 2017 18:23:52 -0700 Subject: [PATCH] dotnet: reparse point changes --- src/dotnet/FileSystemBase.cs | 43 +++++++++++++++++++++++------------- src/dotnet/FileSystemHost.cs | 24 +++++++++++--------- src/dotnet/Interop.cs | 41 ++++++++++++++++++++++++++++++---- 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/src/dotnet/FileSystemBase.cs b/src/dotnet/FileSystemBase.cs index b6de1583..903f02e1 100644 --- a/src/dotnet/FileSystemBase.cs +++ b/src/dotnet/FileSystemBase.cs @@ -267,7 +267,7 @@ namespace Fsp Boolean ResolveLastPathComponent, out IoStatusBlock IoStatus, IntPtr Buffer, - ref UIntPtr Size) + IntPtr PSize) { GCHandle Handle = GCHandle.Alloc(this, GCHandleType.Normal); try @@ -281,7 +281,7 @@ namespace Fsp ResolveLastPathComponent, out IoStatus, Buffer, - ref Size); + PSize); } finally { @@ -291,8 +291,7 @@ namespace Fsp public virtual Int32 GetReparsePointByName( String FileName, Boolean IsDirectory, - IntPtr Buffer, - ref UIntPtr Size) + ref Byte[] ReparsePoint) { return STATUS_INVALID_DEVICE_REQUEST; } @@ -300,18 +299,15 @@ namespace Fsp Object FileNode, Object FileDesc, String FileName, - IntPtr Buffer, - out UIntPtr Size) + ref Byte[] ReparsePoint) { - Size = default(UIntPtr); return STATUS_INVALID_DEVICE_REQUEST; } public virtual Int32 SetReparsePoint( Object FileNode, Object FileDesc, String FileName, - IntPtr Buffer, - UIntPtr Size) + Byte[] ReparsePoint) { return STATUS_INVALID_DEVICE_REQUEST; } @@ -319,8 +315,7 @@ namespace Fsp Object FileNode, Object FileDesc, String FileName, - IntPtr Buffer, - UIntPtr Size) + Byte[] ReparsePoint) { return STATUS_INVALID_DEVICE_REQUEST; } @@ -427,22 +422,40 @@ namespace Fsp Handle.Free(); } } + public static UInt32 GetReparseTag( + Byte[] ReparseData) + { + return 0; + } + public static Int32 CanReplaceReparsePoint( + Byte[] CurrentReparseData, + Byte[] ReplaceReparseData) + { + // !!!: NOT IMPLEMENTED + return STATUS_SUCCESS; + } private static Int32 GetReparsePointByName( IntPtr FileSystem, IntPtr Context, String FileName, Boolean IsDirectory, IntPtr Buffer, - ref UIntPtr Size) + IntPtr PSize) { FileSystemBase self = (FileSystemBase)GCHandle.FromIntPtr(Context).Target; try { - return self.GetReparsePointByName( + Byte[] ReparsePointBytes; + Int32 Result; + ReparsePointBytes = null; + Result = self.GetReparsePointByName( FileName, IsDirectory, - Buffer, - ref Size); + ref ReparsePointBytes); + if (0 <= Result) + Result = Api.CopyReparsePoint(ReparsePointBytes, Buffer, PSize); + return Result; + } catch (Exception ex) { diff --git a/src/dotnet/FileSystemHost.cs b/src/dotnet/FileSystemHost.cs index 94f55f80..02a5e0bd 100644 --- a/src/dotnet/FileSystemHost.cs +++ b/src/dotnet/FileSystemHost.cs @@ -763,7 +763,7 @@ namespace Fsp Boolean ResolveLastPathComponent, out IoStatusBlock PIoStatus, IntPtr Buffer, - ref UIntPtr PSize) + IntPtr PSize) { FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try @@ -774,7 +774,7 @@ namespace Fsp ResolveLastPathComponent, out PIoStatus, Buffer, - ref PSize); + PSize); } catch (Exception ex) { @@ -787,23 +787,27 @@ namespace Fsp ref FullContext FullContext, String FileName, IntPtr Buffer, - out UIntPtr PSize) + IntPtr PSize) { FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); try { + Byte[] ReparsePointBytes; Object FileNode, FileDesc; + Int32 Result; Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); - return FileSystem.GetReparsePoint( + ReparsePointBytes = null; + Result = FileSystem.GetReparsePoint( FileNode, FileDesc, FileName, - Buffer, - out PSize); + ref ReparsePointBytes); + if (0 <= Result) + Result = Api.CopyReparsePoint(ReparsePointBytes, Buffer, PSize); + return Result; } catch (Exception ex) { - PSize = default(UIntPtr); return ExceptionHandler(FileSystem, ex); } } @@ -823,8 +827,7 @@ namespace Fsp FileNode, FileDesc, FileName, - Buffer, - Size); + Api.MakeReparsePoint(Buffer, Size)); } catch (Exception ex) { @@ -847,8 +850,7 @@ namespace Fsp FileNode, FileDesc, FileName, - Buffer, - Size); + Api.MakeReparsePoint(Buffer, Size)); } catch (Exception ex) { diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index 30e49293..6ebee057 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -354,14 +354,14 @@ namespace Fsp.Interop [MarshalAs(UnmanagedType.U1)] Boolean ResolveLastPathComponent, out IoStatusBlock PIoStatus, IntPtr Buffer, - ref UIntPtr PSize); + IntPtr PSize); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Int32 GetReparsePoint( IntPtr FileSystem, ref FullContext FullContext, [MarshalAs(UnmanagedType.LPWStr)] String FileName, IntPtr Buffer, - out UIntPtr PSize); + IntPtr PSize); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Int32 SetReparsePoint( IntPtr FileSystem, @@ -488,7 +488,7 @@ namespace Fsp.Interop [MarshalAs(UnmanagedType.U1)] Boolean ResolveLastPathComponent, out IoStatusBlock PIoStatus, IntPtr Buffer, - ref UIntPtr PSize); + IntPtr PSize); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Int32 FspFileSystemCanReplaceReparsePoint( IntPtr CurrentReparseData, @@ -587,7 +587,7 @@ namespace Fsp.Interop [MarshalAs(UnmanagedType.LPWStr)] String FileName, [MarshalAs(UnmanagedType.U1)] Boolean IsDirectory, IntPtr Buffer, - ref UIntPtr PSize); + IntPtr PSize); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate Int32 ServiceStart( IntPtr Service, @@ -770,6 +770,39 @@ namespace Fsp.Interop return null; } + internal unsafe static Int32 CopyReparsePoint( + Byte[] ReparsePointBytes, + IntPtr Buffer, + IntPtr PSize) + { + if (IntPtr.Zero != Buffer) + { + if (null != ReparsePointBytes) + { + if (ReparsePointBytes.Length > (int)*(UIntPtr *)PSize) + return unchecked((Int32)0xc0000023)/*STATUS_BUFFER_TOO_SMALL*/; + *(UIntPtr *)PSize = (UIntPtr)ReparsePointBytes.Length; + Marshal.Copy(ReparsePointBytes, 0, Buffer, ReparsePointBytes.Length); + } + else + *(UIntPtr *)PSize = UIntPtr.Zero; + } + return 0/*STATUS_SUCCESS*/; + } + internal static Byte[] MakeReparsePoint( + IntPtr Buffer, + UIntPtr Size) + { + if (IntPtr.Zero != Buffer) + { + Byte[] ReparsePointBytes = new Byte[(int)Size]; + Marshal.Copy(Buffer, ReparsePointBytes, 0, ReparsePointBytes.Length); + return ReparsePointBytes; + } + else + return null; + } + internal static Int32 SetDebugLogFile(String FileName) { IntPtr Handle;