From ad612c535da047c848ef2b1157ffd1dac1aa86c2 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 18 Mar 2019 13:51:58 -0700 Subject: [PATCH] tst: memfs-dotnet: ea support --- src/dotnet/FileSystemBase.cs | 16 +----- tst/memfs-dotnet/Program.cs | 103 ++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 16 deletions(-) diff --git a/src/dotnet/FileSystemBase.cs b/src/dotnet/FileSystemBase.cs index 6fb0e68d..1991d188 100644 --- a/src/dotnet/FileSystemBase.cs +++ b/src/dotnet/FileSystemBase.cs @@ -1092,8 +1092,7 @@ namespace Fsp out FileInfo FileInfo, out String NormalizedName) { - Int32 Result; - Result = Create( + return Create( FileName, CreateOptions, GrantedAccess, @@ -1104,11 +1103,6 @@ namespace Fsp out FileDesc, out FileInfo, out NormalizedName); - if (0 > Result) - return Result; - if (IntPtr.Zero != Ea) - Result = SetEa(FileNode, FileDesc, Ea, EaLength); /* ignore Result */ - return STATUS_SUCCESS; } public virtual Int32 OverwriteEx( Object FileNode, @@ -1120,19 +1114,13 @@ namespace Fsp UInt32 EaLength, out FileInfo FileInfo) { - Int32 Result; - Result = Overwrite( + return Overwrite( FileNode, FileDesc, FileAttributes, ReplaceFileAttributes, AllocationSize, out FileInfo); - if (0 > Result) - return Result; - if (IntPtr.Zero != Ea) - Result = SetEa(FileNode, FileDesc, Ea, EaLength); /* ignore Result */ - return STATUS_SUCCESS; } public virtual Int32 GetEa( Object FileNode, diff --git a/tst/memfs-dotnet/Program.cs b/tst/memfs-dotnet/Program.cs index 70bce965..ad224c56 100644 --- a/tst/memfs-dotnet/Program.cs +++ b/tst/memfs-dotnet/Program.cs @@ -55,6 +55,12 @@ namespace memfs } } + struct EaValueData + { + public Byte[] EaValue; + public Boolean NeedEa; + } + class FileNode { public FileNode(String FileName) @@ -80,6 +86,13 @@ namespace memfs return FileInfo; } } + public SortedDictionary GetEaMap(Boolean Force) + { + FileNode FileNode = null == MainFileNode ? this : MainFileNode; + if (null == EaMap && Force) + EaMap = new SortedDictionary(StringComparer.OrdinalIgnoreCase); + return EaMap; + } private static UInt64 IndexNumber = 1; public String FileName; @@ -87,6 +100,7 @@ namespace memfs public Byte[] FileSecurity; public Byte[] FileData; public Byte[] ReparseData; + private SortedDictionary EaMap; public FileNode MainFileNode; public int OpenCount; } @@ -309,13 +323,15 @@ namespace memfs return STATUS_SUCCESS; } - public override Int32 Create( + public override Int32 CreateEx( String FileName, UInt32 CreateOptions, UInt32 GrantedAccess, UInt32 FileAttributes, Byte[] SecurityDescriptor, UInt64 AllocationSize, + IntPtr Ea, + UInt32 EaLength, out Object FileNode0, out Object FileDesc, out FileInfo FileInfo, @@ -352,6 +368,12 @@ namespace memfs FileNode.FileInfo.FileAttributes = 0 != (FileAttributes & (UInt32)System.IO.FileAttributes.Directory) ? FileAttributes : FileAttributes | (UInt32)System.IO.FileAttributes.Archive; FileNode.FileSecurity = SecurityDescriptor; + if (IntPtr.Zero != Ea) + { + Result = SetEa(FileNode, null, Ea, EaLength); + if (0 > Result) + return Result; + } if (0 != AllocationSize) { Result = SetFileSizeInternal(FileNode, AllocationSize, true); @@ -393,6 +415,18 @@ namespace memfs return Result; } + if (0 != (CreateOptions & FILE_NO_EA_KNOWLEDGE) && + null == FileNode.MainFileNode) + { + SortedDictionary EaMap = FileNode.GetEaMap(false); + if (null != EaMap) + { + foreach (KeyValuePair Pair in EaMap) + if (Pair.Value.NeedEa) + return STATUS_ACCESS_DENIED; + } + } + Interlocked.Increment(ref FileNode.OpenCount); FileNode0 = FileNode; FileInfo = FileNode.GetFileInfo(); @@ -401,12 +435,14 @@ namespace memfs return STATUS_SUCCESS; } - public override Int32 Overwrite( + public override Int32 OverwriteEx( Object FileNode0, Object FileDesc, UInt32 FileAttributes, Boolean ReplaceFileAttributes, UInt64 AllocationSize, + IntPtr Ea, + UInt32 EaLength, out FileInfo FileInfo) { FileInfo = default(FileInfo); @@ -424,6 +460,13 @@ namespace memfs FileNodeMap.Remove(StreamNode); } + if (IntPtr.Zero != Ea) + { + Result = SetEa(FileNode, null, Ea, EaLength); + if (0 > Result) + return Result; + } + Result = SetFileSizeInternal(FileNode, AllocationSize, true); if (0 > Result) return Result; @@ -1019,6 +1062,62 @@ namespace memfs StreamAllocationSize = default(UInt64); return false; } + public override Boolean GetEaEntry( + Object FileNode0, + Object FileDesc, + ref Object Context, + out String EaName, + out Byte[] EaValue, + out Boolean NeedEa) + { + FileNode FileNode = (FileNode)FileNode0; + IEnumerator> Enumerator = + (IEnumerator>)Context; + + if (null == Enumerator) + { + SortedDictionary EaMap = FileNode.GetEaMap(false); + if (null == EaMap) + { + EaName = default(String); + EaValue = default(Byte[]); + NeedEa = default(Boolean); + return false; + } + + Context = Enumerator = EaMap.GetEnumerator(); + } + + while (Enumerator.MoveNext()) + { + KeyValuePair Pair = Enumerator.Current; + EaName = Pair.Key; + EaValue = Pair.Value.EaValue; + NeedEa = Pair.Value.NeedEa; + return true; + } + + EaName = default(String); + EaValue = default(Byte[]); + NeedEa = default(Boolean); + return false; + } + public override Int32 SetEaEntry( + Object FileNode0, + Object FileDesc, + ref Object Context, + String EaName, + Byte[] EaValue, + Boolean NeedEa) + { + FileNode FileNode = (FileNode)FileNode0; + SortedDictionary EaMap = FileNode.GetEaMap(true); + EaValueData Data; + Data.EaValue = EaValue; + Data.NeedEa = NeedEa; + EaMap[EaName] = Data; + return STATUS_SUCCESS; + } private FileNodeMap FileNodeMap; private UInt32 MaxFileNodes;