tst: memfs-dotnet: ea support

This commit is contained in:
Bill Zissimopoulos 2019-03-18 13:51:58 -07:00
parent 4d4bf92c32
commit ad612c535d
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
2 changed files with 103 additions and 16 deletions

View File

@ -1092,8 +1092,7 @@ namespace Fsp
out FileInfo FileInfo, out FileInfo FileInfo,
out String NormalizedName) out String NormalizedName)
{ {
Int32 Result; return Create(
Result = Create(
FileName, FileName,
CreateOptions, CreateOptions,
GrantedAccess, GrantedAccess,
@ -1104,11 +1103,6 @@ namespace Fsp
out FileDesc, out FileDesc,
out FileInfo, out FileInfo,
out NormalizedName); 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( public virtual Int32 OverwriteEx(
Object FileNode, Object FileNode,
@ -1120,19 +1114,13 @@ namespace Fsp
UInt32 EaLength, UInt32 EaLength,
out FileInfo FileInfo) out FileInfo FileInfo)
{ {
Int32 Result; return Overwrite(
Result = Overwrite(
FileNode, FileNode,
FileDesc, FileDesc,
FileAttributes, FileAttributes,
ReplaceFileAttributes, ReplaceFileAttributes,
AllocationSize, AllocationSize,
out FileInfo); 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( public virtual Int32 GetEa(
Object FileNode, Object FileNode,

View File

@ -55,6 +55,12 @@ namespace memfs
} }
} }
struct EaValueData
{
public Byte[] EaValue;
public Boolean NeedEa;
}
class FileNode class FileNode
{ {
public FileNode(String FileName) public FileNode(String FileName)
@ -80,6 +86,13 @@ namespace memfs
return FileInfo; return FileInfo;
} }
} }
public SortedDictionary<String, EaValueData> GetEaMap(Boolean Force)
{
FileNode FileNode = null == MainFileNode ? this : MainFileNode;
if (null == EaMap && Force)
EaMap = new SortedDictionary<String, EaValueData>(StringComparer.OrdinalIgnoreCase);
return EaMap;
}
private static UInt64 IndexNumber = 1; private static UInt64 IndexNumber = 1;
public String FileName; public String FileName;
@ -87,6 +100,7 @@ namespace memfs
public Byte[] FileSecurity; public Byte[] FileSecurity;
public Byte[] FileData; public Byte[] FileData;
public Byte[] ReparseData; public Byte[] ReparseData;
private SortedDictionary<String, EaValueData> EaMap;
public FileNode MainFileNode; public FileNode MainFileNode;
public int OpenCount; public int OpenCount;
} }
@ -309,13 +323,15 @@ namespace memfs
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
public override Int32 Create( public override Int32 CreateEx(
String FileName, String FileName,
UInt32 CreateOptions, UInt32 CreateOptions,
UInt32 GrantedAccess, UInt32 GrantedAccess,
UInt32 FileAttributes, UInt32 FileAttributes,
Byte[] SecurityDescriptor, Byte[] SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
out Object FileNode0, out Object FileNode0,
out Object FileDesc, out Object FileDesc,
out FileInfo FileInfo, out FileInfo FileInfo,
@ -352,6 +368,12 @@ namespace memfs
FileNode.FileInfo.FileAttributes = 0 != (FileAttributes & (UInt32)System.IO.FileAttributes.Directory) ? FileNode.FileInfo.FileAttributes = 0 != (FileAttributes & (UInt32)System.IO.FileAttributes.Directory) ?
FileAttributes : FileAttributes | (UInt32)System.IO.FileAttributes.Archive; FileAttributes : FileAttributes | (UInt32)System.IO.FileAttributes.Archive;
FileNode.FileSecurity = SecurityDescriptor; FileNode.FileSecurity = SecurityDescriptor;
if (IntPtr.Zero != Ea)
{
Result = SetEa(FileNode, null, Ea, EaLength);
if (0 > Result)
return Result;
}
if (0 != AllocationSize) if (0 != AllocationSize)
{ {
Result = SetFileSizeInternal(FileNode, AllocationSize, true); Result = SetFileSizeInternal(FileNode, AllocationSize, true);
@ -393,6 +415,18 @@ namespace memfs
return Result; return Result;
} }
if (0 != (CreateOptions & FILE_NO_EA_KNOWLEDGE) &&
null == FileNode.MainFileNode)
{
SortedDictionary<String, EaValueData> EaMap = FileNode.GetEaMap(false);
if (null != EaMap)
{
foreach (KeyValuePair<String, EaValueData> Pair in EaMap)
if (Pair.Value.NeedEa)
return STATUS_ACCESS_DENIED;
}
}
Interlocked.Increment(ref FileNode.OpenCount); Interlocked.Increment(ref FileNode.OpenCount);
FileNode0 = FileNode; FileNode0 = FileNode;
FileInfo = FileNode.GetFileInfo(); FileInfo = FileNode.GetFileInfo();
@ -401,12 +435,14 @@ namespace memfs
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
public override Int32 Overwrite( public override Int32 OverwriteEx(
Object FileNode0, Object FileNode0,
Object FileDesc, Object FileDesc,
UInt32 FileAttributes, UInt32 FileAttributes,
Boolean ReplaceFileAttributes, Boolean ReplaceFileAttributes,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
out FileInfo FileInfo) out FileInfo FileInfo)
{ {
FileInfo = default(FileInfo); FileInfo = default(FileInfo);
@ -424,6 +460,13 @@ namespace memfs
FileNodeMap.Remove(StreamNode); FileNodeMap.Remove(StreamNode);
} }
if (IntPtr.Zero != Ea)
{
Result = SetEa(FileNode, null, Ea, EaLength);
if (0 > Result)
return Result;
}
Result = SetFileSizeInternal(FileNode, AllocationSize, true); Result = SetFileSizeInternal(FileNode, AllocationSize, true);
if (0 > Result) if (0 > Result)
return Result; return Result;
@ -1019,6 +1062,62 @@ namespace memfs
StreamAllocationSize = default(UInt64); StreamAllocationSize = default(UInt64);
return false; 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<KeyValuePair<String, EaValueData>> Enumerator =
(IEnumerator<KeyValuePair<String, EaValueData>>)Context;
if (null == Enumerator)
{
SortedDictionary<String, EaValueData> 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<String, EaValueData> 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<String, EaValueData> EaMap = FileNode.GetEaMap(true);
EaValueData Data;
Data.EaValue = EaValue;
Data.NeedEa = NeedEa;
EaMap[EaName] = Data;
return STATUS_SUCCESS;
}
private FileNodeMap FileNodeMap; private FileNodeMap FileNodeMap;
private UInt32 MaxFileNodes; private UInt32 MaxFileNodes;