diff --git a/src/dotnet/FileSystem.cs b/src/dotnet/FileSystem.cs index 8b41a279..dff4662d 100644 --- a/src/dotnet/FileSystem.cs +++ b/src/dotnet/FileSystem.cs @@ -201,6 +201,22 @@ namespace Fsp FileAttributes = default(UInt32); return STATUS_INVALID_DEVICE_REQUEST; } + protected virtual Int32 Create( + String FileName, + UInt32 CreateOptions, + UInt32 GrantedAccess, + UInt32 FileAttributes, + Object SecurityDescriptor, + UInt64 AllocationSize, + out Object FileNode, + out Object FileDesc, + out FileInfo FileInfo) + { + FileNode = default(Object); + FileDesc = default(Object); + FileInfo = default(FileInfo); + return STATUS_INVALID_DEVICE_REQUEST; + } /* FSP_FILE_SYSTEM_INTERFACE */ private static Object SecurityDescriptorNotNull = new Object(); @@ -243,24 +259,24 @@ namespace Fsp IntPtr PSecurityDescriptorSize) { FileSystem self = (FileSystem)Api.FspFileSystemGetUserContext(FileSystem); - UInt32 FileAttributes; - Object SecurityDescriptorObject = null; - Int32 Result; try { + UInt32 FileAttributes; + Object SecurityDescriptorObject = null; + Int32 Result; if (IntPtr.Zero != PSecurityDescriptorSize) SecurityDescriptorObject = SecurityDescriptorNotNull; Result = self.GetSecurityByName(FileName, out FileAttributes, ref SecurityDescriptorObject); + if (IntPtr.Zero != PFileAttributes) + Marshal.WriteInt32(PFileAttributes, (Int32)FileAttributes); + return Api.CopySecurityDescriptor(SecurityDescriptorObject, + SecurityDescriptor, PSecurityDescriptorSize); } catch (Exception ex) { return self.ExceptionHandler(ex); } - if (IntPtr.Zero != PFileAttributes) - Marshal.WriteInt32(PFileAttributes, (Int32)FileAttributes); - return Api.CopySecurityDescriptor(SecurityDescriptorObject, - SecurityDescriptor, PSecurityDescriptorSize); } private static Int32 Create( IntPtr FileSystem, @@ -273,9 +289,30 @@ namespace Fsp out 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.Create( + FileName, + CreateOptions, + GrantedAccess, + FileAttributes, + Api.MakeSecurityDescriptor(SecurityDescriptor), + AllocationSize, + out FileNode, + out FileDesc, + out FileInfo); + Api.SetFullContext(out FullContext, FileNode, FileDesc); + return Result; + } + catch (Exception ex) + { + FullContext = default(FullContext); + FileInfo = default(FileInfo); + return self.ExceptionHandler(ex); + } } private static Int32 Open( IntPtr FileSystem, diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index c083848b..8b5aae1c 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -118,26 +118,26 @@ namespace Fsp.Interop } [StructLayout(LayoutKind.Sequential)] - internal struct FileInfo + public struct FileInfo { - internal UInt32 FileAttributes; - internal UInt32 ReparseTag; - internal UInt64 AllocationSize; - internal UInt64 FileSize; - internal UInt64 CreationTime; - internal UInt64 LastAccessTime; - internal UInt64 LastWriteTime; - internal UInt64 ChangeTime; - internal UInt64 IndexNumber; - internal UInt32 HardLinks; + public UInt32 FileAttributes; + public UInt32 ReparseTag; + public UInt64 AllocationSize; + public UInt64 FileSize; + public UInt64 CreationTime; + public UInt64 LastAccessTime; + public UInt64 LastWriteTime; + public UInt64 ChangeTime; + public UInt64 IndexNumber; + public UInt32 HardLinks; } [StructLayout(LayoutKind.Sequential)] - internal struct OpenFileInfo + public struct OpenFileInfo { - internal FileInfo FileInfo; - internal IntPtr NormalizedName; - internal UInt16 NormalizedNameSize; + public FileInfo FileInfo; + public IntPtr NormalizedName; + public UInt16 NormalizedNameSize; } [StructLayout(LayoutKind.Sequential)] @@ -150,7 +150,7 @@ namespace Fsp.Interop } [StructLayout(LayoutKind.Sequential)] - struct StreamInfo + internal struct StreamInfo { internal UInt16 Size; internal UInt64 StreamSize; @@ -159,7 +159,7 @@ namespace Fsp.Interop } [StructLayout(LayoutKind.Sequential)] - struct FullContext + internal struct FullContext { internal UInt64 UserContext; internal UInt64 UserContext2; @@ -465,6 +465,21 @@ namespace Fsp.Interop } } } + + internal static void GetFullContext(ref FullContext FullContext, + out Object FileNode, out Object FileDesc) + { + FileNode = default(Object); + FileDesc = default(Object); + } + internal static void SetFullContext(out FullContext FullContext, + Object FileNode, Object FileDesc) + { + FullContext = default(FullContext); + } + + [DllImport("advapi32.dll", CallingConvention = CallingConvention.StdCall)] + private static extern UInt32 GetSecurityDescriptorLength(IntPtr SecurityDescriptor); internal static Int32 CopySecurityDescriptor( Object SecurityDescriptorObject, IntPtr SecurityDescriptor, @@ -486,7 +501,7 @@ namespace Fsp.Interop { byte[] Bytes = new byte[GenericSecurityDescriptor.BinaryLength]; GenericSecurityDescriptor.GetBinaryForm(Bytes, 0); - Marshal.Copy(Bytes, 0, SecurityDescriptor, GenericSecurityDescriptor.BinaryLength); + Marshal.Copy(Bytes, 0, SecurityDescriptor, Bytes.Length); } } else @@ -494,6 +509,18 @@ namespace Fsp.Interop } return 0/*STATUS_SUCCESS*/; } + internal static Object MakeSecurityDescriptor( + IntPtr SecurityDescriptor) + { + if (IntPtr.Zero != SecurityDescriptor) + { + byte[] Bytes = new byte[GetSecurityDescriptorLength(SecurityDescriptor)]; + Marshal.Copy(SecurityDescriptor, Bytes, 0, Bytes.Length); + return new RawSecurityDescriptor(Bytes, 0); + } + else + return null; + } /* initialization */ [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]