dotnet: extended attributes support

This commit is contained in:
Bill Zissimopoulos
2019-03-14 15:05:17 -07:00
parent 795caec679
commit 3553aec992
3 changed files with 319 additions and 5 deletions

View File

@ -52,6 +52,7 @@ namespace Fsp.Interop
internal const UInt32 UmFileContextIsUserContext2 = 0x00010000;
internal const UInt32 UmFileContextIsFullContext = 0x00020000;
internal const UInt32 AllowOpenInKernelMode = 0x01000000;
internal const UInt32 CasePreservedExtendedAttributes = 0x02000000;
internal const int PrefixSize = 192;
internal const int FileSystemNameSize = 16;
@ -270,6 +271,40 @@ namespace Fsp.Interop
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct FullEaInformation
{
internal const int EaNameSize = 16384 - 8;
internal UInt32 NextEntryOffset;
internal Byte Flags;
internal Byte EaNameLength;
internal UInt16 EaValueLength;
internal unsafe fixed Byte EaName[EaNameSize];
internal unsafe void Set(String Name, Byte[] Value, Boolean NeedEa)
{
int NameLength = 254 < Name.Length ? 254 : Name.Length;
int ValueLength = EaNameSize - Name.Length - 1 < Value.Length ?
EaNameSize - Name.Length - 1 : Value.Length;
NextEntryOffset = 0;
Flags = NeedEa ? (Byte)0x80/*FILE_NEED_EA*/ : (Byte)0;
EaNameLength = (Byte)NameLength;
EaValueLength = (UInt16)ValueLength;
fixed (Byte *P = EaName)
{
int I = 0;
for (; NameLength > I; I++)
P[I] = (Byte)Name[I];
P[I] = 0;
for (; ValueLength > I; I++)
P[I] = Value[I];
}
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct FullContext
{
@ -478,6 +513,42 @@ namespace Fsp.Interop
ref FullContext FullContext,
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
[MarshalAs(UnmanagedType.U1)] Boolean DeleteFile);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 CreateEx(
IntPtr FileSystem,
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
UInt32 CreateOptions,
UInt32 GrantedAccess,
UInt32 FileAttributes,
IntPtr SecurityDescriptor,
UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
ref FullContext FullContext,
ref OpenFileInfo OpenFileInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 OverwriteEx(
IntPtr FileSystem,
ref FullContext FullContext,
UInt32 FileAttributes,
[MarshalAs(UnmanagedType.U1)] Boolean ReplaceFileAttributes,
UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
out FileInfo FileInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 GetEa(
IntPtr FileSystem,
ref FullContext FullContext,
IntPtr Ea,
UInt32 EaLength,
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 SetEa(
IntPtr FileSystem,
ref FullContext FullContext,
IntPtr Ea,
UInt32 EaLength);
}
internal static int Size = IntPtr.Size * 64;
@ -509,7 +580,11 @@ namespace Fsp.Interop
internal Proto.GetDirInfoByName GetDirInfoByName;
internal Proto.Control Control;
internal Proto.SetDelete SetDelete;
/* NTSTATUS (*Reserved[37])(); */
internal Proto.CreateEx CreateEx;
internal Proto.OverwriteEx OverwriteEx;
internal Proto.GetEa GetEa;
internal Proto.SetEa SetEa;
/* NTSTATUS (*Reserved[33])(); */
}
[SuppressUnmanagedCodeSecurity]
@ -604,6 +679,13 @@ namespace Fsp.Interop
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
internal delegate Boolean FspFileSystemAddEa(
IntPtr SingleEa,
IntPtr Ea,
UInt32 EaLength,
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
ref IntPtr PDirBuffer,
[MarshalAs(UnmanagedType.U1)] Boolean Reset,
@ -737,6 +819,7 @@ namespace Fsp.Interop
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
internal static Proto.FspFileSystemCanReplaceReparsePoint _FspFileSystemCanReplaceReparsePoint;
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
internal static Proto.FspFileSystemAddEa _FspFileSystemAddEa;
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
@ -806,6 +889,57 @@ namespace Fsp.Interop
return _FspFileSystemAddStreamInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
}
internal delegate Int32 EnumerateEa(
Object FileNode,
Object FileDesc,
ref Object Context,
String EaName,
Byte[] EaValue,
Boolean NeedEa);
internal static unsafe Int32 FspFileSystemEnumerateEa(
Object FileNode,
Object FileDesc,
EnumerateEa EnumerateEa,
IntPtr Ea,
UInt32 EaLength)
{
Object Context = null;
FullEaInformation *P = (FullEaInformation *)Ea;
FullEaInformation *EndP = (FullEaInformation *)(Ea.ToInt64() + EaLength);
Int32 Result;
Result = 0/*STATUS_SUCCESS*/;
for (;
EndP > P && 0 != P->NextEntryOffset;
P = (FullEaInformation *)(((IntPtr)P).ToInt64() + P->NextEntryOffset))
{
String EaName = Marshal.PtrToStringAnsi((IntPtr)P->EaName, P->EaNameLength);
Byte[] EaValue = new Byte[P->EaValueLength];
Marshal.Copy((IntPtr)(((IntPtr)P->EaName).ToInt64() + P->EaNameLength + 1),
EaValue, 0, P->EaValueLength);
Boolean NeedEa = 0 != (0x80/*FILE_NEED_EA*/ & P->Flags);
Result = EnumerateEa(FileNode, FileDesc, ref Context, EaName, EaValue, NeedEa);
if (0 > Result)
break;
}
return Result;
}
internal static unsafe Boolean FspFileSystemAddEa(
ref FullEaInformation EaInfo,
IntPtr Buffer,
UInt32 Length,
out UInt32 PBytesTransferred)
{
fixed (FullEaInformation *P = &EaInfo)
return _FspFileSystemAddEa((IntPtr)P, Buffer, Length, out PBytesTransferred);
}
internal static unsafe Boolean FspFileSystemEndEa(
IntPtr Buffer,
UInt32 Length,
out UInt32 PBytesTransferred)
{
return _FspFileSystemAddEa(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
}
internal unsafe static Object GetUserContext(
IntPtr NativePtr)
{
@ -1074,6 +1208,7 @@ namespace Fsp.Interop
FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module);
_FspFileSystemCanReplaceReparsePoint = GetEntryPoint<Proto.FspFileSystemCanReplaceReparsePoint>(Module);
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
_FspFileSystemAddEa = GetEntryPoint<Proto.FspFileSystemAddEa>(Module);
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);