tst: passthrough-dotnet: major refactoring and testing

This commit is contained in:
Bill Zissimopoulos 2017-04-10 14:48:26 -07:00
parent e40505adb5
commit f2d98bbf25

View File

@ -29,32 +29,212 @@ namespace passthrough
{ {
class Ptfs : FileSystem class Ptfs : FileSystem
{ {
protected const int ALLOCATION_UNIT = 4096;
protected static void ThrowIoExceptionWithHResult(Int32 HResult)
{
throw new IOException(null, HResult);
}
protected static void ThrowIoExceptionWithWin32(Int32 Error)
{
ThrowIoExceptionWithHResult(unchecked((Int32)(0x80070000 | Error)));
}
protected static void ThrowIoExceptionWithNtStatus(Int32 Status)
{
ThrowIoExceptionWithWin32((Int32)Win32FromNtStatus(Status));
}
protected class FileDesc protected class FileDesc
{ {
public FileSystemInfo Info;
public FileStream Stream; public FileStream Stream;
public DirectoryInfo DirInfo;
public DirectoryBuffer DirBuffer; public DirectoryBuffer DirBuffer;
public FileDesc(FileSystemInfo Info, FileStream Stream) public FileDesc(FileStream Stream)
{ {
this.Info = Info;
this.Stream = Stream; this.Stream = Stream;
} }
public UInt32 FileAttributes public FileDesc(DirectoryInfo DirInfo)
{ {
get this.DirInfo = DirInfo;
{
return (UInt32)Info.Attributes;
} }
set public static void GetFileInfoFromFileSystemInfo(
FileSystemInfo Info,
out FileInfo FileInfo)
{ {
Info.Attributes = 0 == value ? FileInfo.FileAttributes = (UInt32)Info.Attributes;
System.IO.FileAttributes.Normal : (FileAttributes)value; FileInfo.ReparseTag = 0;
FileInfo.FileSize = Info is System.IO.FileInfo ?
(UInt64)((System.IO.FileInfo)Info).Length : 0;
FileInfo.AllocationSize = (FileInfo.FileSize + ALLOCATION_UNIT - 1)
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
FileInfo.CreationTime = (UInt64)Info.CreationTimeUtc.ToFileTimeUtc();
FileInfo.LastAccessTime = (UInt64)Info.LastAccessTimeUtc.ToFileTimeUtc();
FileInfo.LastWriteTime = (UInt64)Info.LastWriteTimeUtc.ToFileTimeUtc();
FileInfo.ChangeTime = FileInfo.LastWriteTime;
FileInfo.IndexNumber = 0;
FileInfo.HardLinks = 0;
} }
public Int32 GetFileInfo(out FileInfo FileInfo)
{
if (null != Stream)
{
BY_HANDLE_FILE_INFORMATION Info;
if (!GetFileInformationByHandle(Stream.SafeFileHandle.DangerousGetHandle(),
out Info))
ThrowIoExceptionWithWin32(Marshal.GetLastWin32Error());
FileInfo.FileAttributes = Info.dwFileAttributes;
FileInfo.ReparseTag = 0;
FileInfo.FileSize = (UInt64)Stream.Length;
FileInfo.AllocationSize = (FileInfo.FileSize + ALLOCATION_UNIT - 1)
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
FileInfo.CreationTime = Info.ftCreationTime;
FileInfo.LastAccessTime = Info.ftLastAccessTime;
FileInfo.LastWriteTime = Info.ftLastWriteTime;
FileInfo.ChangeTime = FileInfo.LastWriteTime;
FileInfo.IndexNumber = 0;
FileInfo.HardLinks = 0;
}
else
GetFileInfoFromFileSystemInfo(DirInfo, out FileInfo);
return STATUS_SUCCESS;
}
public void SetBasicInfo(
UInt32 FileAttributes,
UInt64 CreationTime,
UInt64 LastAccessTime,
UInt64 LastWriteTime)
{
if (0 == FileAttributes)
FileAttributes = (UInt32)System.IO.FileAttributes.Normal;
if (null != Stream)
{
FILE_BASIC_INFO Info = default(FILE_BASIC_INFO);
if (unchecked((UInt32)(-1)) != FileAttributes)
Info.FileAttributes = FileAttributes;
if (0 != CreationTime)
Info.CreationTime = CreationTime;
if (0 != LastAccessTime)
Info.LastAccessTime = LastAccessTime;
if (0 != LastWriteTime)
Info.LastWriteTime = LastWriteTime;
if (!SetFileInformationByHandle(Stream.SafeFileHandle.DangerousGetHandle(),
0/*FileBasicInfo*/, ref Info, (UInt32)Marshal.SizeOf(Info)))
ThrowIoExceptionWithWin32(Marshal.GetLastWin32Error());
}
else
{
if (unchecked((UInt32)(-1)) != FileAttributes)
DirInfo.Attributes = (System.IO.FileAttributes)FileAttributes;
if (0 != CreationTime)
DirInfo.CreationTimeUtc = DateTime.FromFileTimeUtc((Int64)CreationTime);
if (0 != LastAccessTime)
DirInfo.LastAccessTimeUtc = DateTime.FromFileTimeUtc((Int64)LastAccessTime);
if (0 != LastWriteTime)
DirInfo.LastWriteTimeUtc = DateTime.FromFileTimeUtc((Int64)LastWriteTime);
}
}
public UInt32 GetFileAttributes()
{
FileInfo FileInfo;
GetFileInfo(out FileInfo);
return FileInfo.FileAttributes;
}
public void SetFileAttributes(UInt32 FileAttributes)
{
SetBasicInfo(FileAttributes, 0, 0, 0);
}
public Byte[] GetSecurityDescriptor()
{
if (null != Stream)
return Stream.GetAccessControl().GetSecurityDescriptorBinaryForm();
else
return DirInfo.GetAccessControl().GetSecurityDescriptorBinaryForm();
}
public void SetSecurityDescriptor(AccessControlSections Sections, Byte[] SecurityDescriptor)
{
if (null != Stream)
{
FileSecurity Security = Stream.GetAccessControl();
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor, Sections);
Stream.SetAccessControl(Security);
}
else
{
DirectorySecurity Security = DirInfo.GetAccessControl();
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor, Sections);
DirInfo.SetAccessControl(Security);
}
}
public void SetDisposition(Boolean Safe)
{
if (null != Stream)
{
FILE_DISPOSITION_INFO Info;
Info.DeleteFile = true;
if (!SetFileInformationByHandle(Stream.SafeFileHandle.DangerousGetHandle(),
4/*FileDispositionInfo*/, ref Info, (UInt32)Marshal.SizeOf(Info)))
if (!Safe)
ThrowIoExceptionWithWin32(Marshal.GetLastWin32Error());
}
else
try
{
DirInfo.Delete();
}
catch (Exception ex)
{
if (!Safe)
ThrowIoExceptionWithHResult(ex.HResult);
} }
} }
private const int ALLOCATION_UNIT = 4096; /* interop */
[StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct BY_HANDLE_FILE_INFORMATION
{
public UInt32 dwFileAttributes;
public UInt64 ftCreationTime;
public UInt64 ftLastAccessTime;
public UInt64 ftLastWriteTime;
public UInt32 dwVolumeSerialNumber;
public UInt32 nFileSizeHigh;
public UInt32 nFileSizeLow;
public UInt32 nNumberOfLinks;
public UInt32 nFileIndexHigh;
public UInt32 nFileIndexLow;
}
[StructLayout(LayoutKind.Sequential)]
private struct FILE_BASIC_INFO
{
public UInt64 CreationTime;
public UInt64 LastAccessTime;
public UInt64 LastWriteTime;
public UInt64 ChangeTime;
public UInt32 FileAttributes;
}
[StructLayout(LayoutKind.Sequential)]
private struct FILE_DISPOSITION_INFO
{
public Boolean DeleteFile;
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern Boolean GetFileInformationByHandle(
IntPtr hFile,
out BY_HANDLE_FILE_INFORMATION lpFileInformation);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern Boolean SetFileInformationByHandle(
IntPtr hFile,
Int32 FileInformationClass,
ref FILE_BASIC_INFO lpFileInformation,
UInt32 dwBufferSize);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern Boolean SetFileInformationByHandle(
IntPtr hFile,
Int32 FileInformationClass,
ref FILE_DISPOSITION_INFO lpFileInformation,
UInt32 dwBufferSize);
}
public Ptfs() : base() public Ptfs() : base()
{ {
@ -85,37 +265,10 @@ namespace passthrough
return NtStatusFromWin32((UInt32)HResult & 0xFFFF); return NtStatusFromWin32((UInt32)HResult & 0xFFFF);
return STATUS_UNEXPECTED_IO_ERROR; return STATUS_UNEXPECTED_IO_ERROR;
} }
private Int32 HResultFromWin32(UInt32 Error)
{
return unchecked((Int32)(0x80070000 | Error));
}
private void ThrowIoException(Int32 Result)
{
throw new IOException(null, HResultFromWin32(Win32FromNtStatus(Result)));
}
protected String ConcatPath(String FileName) protected String ConcatPath(String FileName)
{ {
return _Path + FileName; return _Path + FileName;
} }
protected Int32 GetFileInfoInternal(FileSystemInfo Info, Boolean Refresh,
out FileInfo FileInfo)
{
if (Refresh)
Info.Refresh();
FileInfo.FileAttributes = (UInt32)Info.Attributes;
FileInfo.ReparseTag = 0;
FileInfo.FileSize = Info is System.IO.FileInfo ?
(UInt64)((System.IO.FileInfo)Info).Length : 0;
FileInfo.AllocationSize = (FileInfo.FileSize + ALLOCATION_UNIT - 1)
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
FileInfo.CreationTime = (UInt64)Info.CreationTimeUtc.ToFileTimeUtc();
FileInfo.LastAccessTime = (UInt64)Info.LastAccessTimeUtc.ToFileTimeUtc();
FileInfo.LastWriteTime = (UInt64)Info.LastWriteTimeUtc.ToFileTimeUtc();
FileInfo.ChangeTime = FileInfo.LastWriteTime;
FileInfo.IndexNumber = 0;
FileInfo.HardLinks = 0;
return STATUS_SUCCESS;
}
protected override Int32 GetVolumeInfo( protected override Int32 GetVolumeInfo(
out VolumeInfo VolumeInfo) out VolumeInfo VolumeInfo)
{ {
@ -159,23 +312,11 @@ namespace passthrough
out FileInfo FileInfo, out FileInfo FileInfo,
out String NormalizedName) out String NormalizedName)
{ {
FileDesc FileDesc; FileDesc FileDesc = null;
try
{
FileName = ConcatPath(FileName); FileName = ConcatPath(FileName);
if (0 != (CreateOptions & FILE_DIRECTORY_FILE)) if (0 == (CreateOptions & FILE_DIRECTORY_FILE))
{
if (Directory.Exists(FileName))
ThrowIoException(STATUS_OBJECT_NAME_COLLISION);
DirectorySecurity Security = null;
if (null != SecurityDescriptor)
{
Security = new DirectorySecurity();
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor);
}
FileDesc = new FileDesc(
Directory.CreateDirectory(FileName, Security),
null);
}
else
{ {
FileSecurity Security = null; FileSecurity Security = null;
if (null != SecurityDescriptor) if (null != SecurityDescriptor)
@ -184,21 +325,40 @@ namespace passthrough
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor); Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor);
} }
FileDesc = new FileDesc( FileDesc = new FileDesc(
new System.IO.FileInfo(FileName),
new FileStream( new FileStream(
FileName, FileName,
FileMode.CreateNew, FileMode.CreateNew,
(FileSystemRights)GrantedAccess, (FileSystemRights)GrantedAccess | FileSystemRights.WriteAttributes,
FileShare.Read | FileShare.Write | FileShare.Delete, FileShare.Read | FileShare.Write | FileShare.Delete,
4096, 4096,
0, 0,
Security)); Security));
} }
FileDesc.FileAttributes = FileAttributes; else
{
if (Directory.Exists(FileName))
ThrowIoExceptionWithNtStatus(STATUS_OBJECT_NAME_COLLISION);
DirectorySecurity Security = null;
if (null != SecurityDescriptor)
{
Security = new DirectorySecurity();
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor);
}
FileDesc = new FileDesc(
Directory.CreateDirectory(FileName, Security));
}
FileDesc.SetFileAttributes(FileAttributes);
FileNode = default(Object); FileNode = default(Object);
FileDesc0 = FileDesc; FileDesc0 = FileDesc;
NormalizedName = default(String); NormalizedName = default(String);
return GetFileInfoInternal(FileDesc.Info, false, out FileInfo); return FileDesc.GetFileInfo(out FileInfo);
}
catch
{
if (null != FileDesc && null != FileDesc.Stream)
FileDesc.Stream.Dispose();
throw;
}
} }
protected override Int32 Open( protected override Int32 Open(
String FileName, String FileName,
@ -209,18 +369,13 @@ namespace passthrough
out FileInfo FileInfo, out FileInfo FileInfo,
out String NormalizedName) out String NormalizedName)
{ {
FileDesc FileDesc; FileDesc FileDesc = null;
try
{
FileName = ConcatPath(FileName); FileName = ConcatPath(FileName);
if (Directory.Exists(FileName)) if (!Directory.Exists(FileName))
{ {
FileDesc = new FileDesc( FileDesc = new FileDesc(
new System.IO.DirectoryInfo(FileName),
null);
}
else
{
FileDesc = new FileDesc(
new System.IO.FileInfo(FileName),
new FileStream( new FileStream(
FileName, FileName,
FileMode.Open, FileMode.Open,
@ -229,10 +384,22 @@ namespace passthrough
4096, 4096,
0)); 0));
} }
else
{
FileDesc = new FileDesc(
new DirectoryInfo(FileName));
}
FileNode = default(Object); FileNode = default(Object);
FileDesc0 = FileDesc; FileDesc0 = FileDesc;
NormalizedName = default(String); NormalizedName = default(String);
return GetFileInfoInternal(FileDesc.Info, false, out FileInfo); return FileDesc.GetFileInfo(out FileInfo);
}
catch
{
if (null != FileDesc && null != FileDesc.Stream)
FileDesc.Stream.Dispose();
throw;
}
} }
protected override Int32 Overwrite( protected override Int32 Overwrite(
Object FileNode, Object FileNode,
@ -244,11 +411,11 @@ namespace passthrough
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
if (ReplaceFileAttributes) if (ReplaceFileAttributes)
FileDesc.FileAttributes = FileAttributes; FileDesc.SetFileAttributes(FileAttributes);
else if (0 != FileAttributes) else if (0 != FileAttributes)
FileDesc.FileAttributes |= FileAttributes; FileDesc.SetFileAttributes(FileDesc.GetFileAttributes() | FileAttributes);
FileDesc.Stream.SetLength(0); FileDesc.Stream.SetLength(0);
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo); return FileDesc.GetFileInfo(out FileInfo);
} }
protected override void Cleanup( protected override void Cleanup(
Object FileNode, Object FileNode,
@ -259,13 +426,7 @@ namespace passthrough
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
if (0 != (Flags & CleanupDelete)) if (0 != (Flags & CleanupDelete))
{ {
try FileDesc.SetDisposition(true);
{
FileDesc.Info.Delete();
}
catch
{
}
if (null != FileDesc.Stream) if (null != FileDesc.Stream)
FileDesc.Stream.Dispose(); FileDesc.Stream.Dispose();
} }
@ -289,6 +450,8 @@ namespace passthrough
out UInt32 PBytesTransferred) out UInt32 PBytesTransferred)
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
if (Offset >= (UInt64)FileDesc.Stream.Length)
ThrowIoExceptionWithNtStatus(STATUS_END_OF_FILE);
Byte[] Bytes = new byte[Length]; Byte[] Bytes = new byte[Length];
FileDesc.Stream.Seek((Int64)Offset, SeekOrigin.Begin); FileDesc.Stream.Seek((Int64)Offset, SeekOrigin.Begin);
PBytesTransferred = (UInt32)FileDesc.Stream.Read(Bytes, 0, Bytes.Length); PBytesTransferred = (UInt32)FileDesc.Stream.Read(Bytes, 0, Bytes.Length);
@ -307,26 +470,24 @@ namespace passthrough
out FileInfo FileInfo) out FileInfo FileInfo)
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
UInt64 FileSize;
if (ConstrainedIo) if (ConstrainedIo)
{ {
FileDesc.Info.Refresh(); if (Offset >= (UInt64)FileDesc.Stream.Length)
FileSize = (UInt64)((System.IO.FileInfo)FileDesc.Info).Length;
if (Offset >= FileSize)
{ {
PBytesTransferred = default(UInt32); PBytesTransferred = default(UInt32);
FileInfo = default(FileInfo); FileInfo = default(FileInfo);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
if (Offset + Length > FileSize) if (Offset + Length > (UInt64)FileDesc.Stream.Length)
Length = (UInt32)(FileSize - Offset); Length = (UInt32)((UInt64)FileDesc.Stream.Length - Offset);
} }
Byte[] Bytes = new byte[Length]; Byte[] Bytes = new byte[Length];
Marshal.Copy(Buffer, Bytes, 0, Bytes.Length); Marshal.Copy(Buffer, Bytes, 0, Bytes.Length);
if (!WriteToEndOfFile)
FileDesc.Stream.Seek((Int64)Offset, SeekOrigin.Begin); FileDesc.Stream.Seek((Int64)Offset, SeekOrigin.Begin);
FileDesc.Stream.Write(Bytes, 0, Bytes.Length); FileDesc.Stream.Write(Bytes, 0, Bytes.Length);
PBytesTransferred = (UInt32)Bytes.Length; PBytesTransferred = (UInt32)Bytes.Length;
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo); return FileDesc.GetFileInfo(out FileInfo);
} }
protected override Int32 Flush( protected override Int32 Flush(
Object FileNode, Object FileNode,
@ -341,7 +502,7 @@ namespace passthrough
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
FileDesc.Stream.Flush(true); FileDesc.Stream.Flush(true);
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo); return FileDesc.GetFileInfo(out FileInfo);
} }
protected override Int32 GetFileInfo( protected override Int32 GetFileInfo(
Object FileNode, Object FileNode,
@ -349,7 +510,7 @@ namespace passthrough
out FileInfo FileInfo) out FileInfo FileInfo)
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo); return FileDesc.GetFileInfo(out FileInfo);
} }
protected override Int32 SetBasicInfo( protected override Int32 SetBasicInfo(
Object FileNode, Object FileNode,
@ -362,15 +523,8 @@ namespace passthrough
out FileInfo FileInfo) out FileInfo FileInfo)
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
if (unchecked((UInt32)(-1)) != FileAttributes) FileDesc.SetBasicInfo(FileAttributes, CreationTime, LastAccessTime, LastWriteTime);
FileDesc.FileAttributes = FileAttributes; return FileDesc.GetFileInfo(out FileInfo);
if (0 != CreationTime)
FileDesc.Info.CreationTimeUtc = DateTime.FromFileTimeUtc((Int64)CreationTime);
if (0 != LastAccessTime)
FileDesc.Info.LastAccessTimeUtc = DateTime.FromFileTimeUtc((Int64)LastAccessTime);
if (0 != LastWriteTime)
FileDesc.Info.LastWriteTimeUtc = DateTime.FromFileTimeUtc((Int64)LastWriteTime);
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo);
} }
protected override Int32 SetFileSize( protected override Int32 SetFileSize(
Object FileNode, Object FileNode,
@ -380,8 +534,7 @@ namespace passthrough
out FileInfo FileInfo) out FileInfo FileInfo)
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
GetFileInfoInternal(FileDesc.Info, true, out FileInfo); if (!SetAllocationSize || (UInt64)FileDesc.Stream.Length > NewSize)
if (!SetAllocationSize || FileInfo.FileSize > NewSize)
{ {
/* /*
* "FileInfo.FileSize > NewSize" explanation: * "FileInfo.FileSize > NewSize" explanation:
@ -389,11 +542,8 @@ namespace passthrough
* is less than the current FileSize we must truncate the file. * is less than the current FileSize we must truncate the file.
*/ */
FileDesc.Stream.SetLength((Int64)NewSize); FileDesc.Stream.SetLength((Int64)NewSize);
FileInfo.FileSize = NewSize;
FileInfo.AllocationSize = (FileInfo.FileSize + ALLOCATION_UNIT - 1)
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
} }
return STATUS_SUCCESS; return FileDesc.GetFileInfo(out FileInfo);
} }
protected override Int32 CanDelete( protected override Int32 CanDelete(
Object FileNode, Object FileNode,
@ -401,11 +551,7 @@ namespace passthrough
String FileName) String FileName)
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
/* FileDesc.SetDisposition(false);
* If a file has an open handle the Delete call below
* will only mark it for disposition.
*/
FileDesc.Info.Delete();
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
protected override Int32 Rename( protected override Int32 Rename(
@ -418,18 +564,18 @@ namespace passthrough
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
FileName = ConcatPath(FileName); FileName = ConcatPath(FileName);
NewFileName = ConcatPath(NewFileName); NewFileName = ConcatPath(NewFileName);
if (null == FileDesc.Stream) if (null != FileDesc.Stream)
{
if (ReplaceIfExists)
throw new UnauthorizedAccessException();
Directory.Move(FileName, NewFileName);
}
else
{ {
if (ReplaceIfExists) if (ReplaceIfExists)
File.Delete(NewFileName); File.Delete(NewFileName);
File.Move(FileName, NewFileName); File.Move(FileName, NewFileName);
} }
else
{
if (ReplaceIfExists)
throw new UnauthorizedAccessException();
Directory.Move(FileName, NewFileName);
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
protected override Int32 GetSecurity( protected override Int32 GetSecurity(
@ -438,12 +584,7 @@ namespace passthrough
ref Byte[] SecurityDescriptor) ref Byte[] SecurityDescriptor)
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
if (null == FileDesc.Stream) SecurityDescriptor = FileDesc.GetSecurityDescriptor();
SecurityDescriptor = ((System.IO.DirectoryInfo)FileDesc.Info).GetAccessControl().
GetSecurityDescriptorBinaryForm();
else
SecurityDescriptor = ((System.IO.FileInfo)FileDesc.Info).GetAccessControl().
GetSecurityDescriptorBinaryForm();
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
protected override Int32 SetSecurity( protected override Int32 SetSecurity(
@ -453,18 +594,7 @@ namespace passthrough
Byte[] SecurityDescriptor) Byte[] SecurityDescriptor)
{ {
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
if (null == FileDesc.Stream) FileDesc.SetSecurityDescriptor(Sections, SecurityDescriptor);
{
DirectorySecurity Security = ((System.IO.DirectoryInfo)FileDesc.Info).GetAccessControl();
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor, Sections);
((System.IO.DirectoryInfo)FileDesc.Info).SetAccessControl(Security);
}
else
{
FileSecurity Security = ((System.IO.FileInfo)FileDesc.Info).GetAccessControl();
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor, Sections);
((System.IO.FileInfo)FileDesc.Info).SetAccessControl(Security);
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
protected override Int32 ReadDirectory( protected override Int32 ReadDirectory(
@ -496,14 +626,13 @@ namespace passthrough
FileDesc FileDesc = (FileDesc)FileDesc0; FileDesc FileDesc = (FileDesc)FileDesc0;
if (null == Pattern) if (null == Pattern)
Pattern = "*"; Pattern = "*";
Context = (FileDesc.Info as DirectoryInfo).EnumerateFileSystemInfos(Pattern). Context = FileDesc.DirInfo.EnumerateFileSystemInfos(Pattern).GetEnumerator();
GetEnumerator();
} }
IEnumerator<FileSystemInfo> InfoEnumerator = (IEnumerator<FileSystemInfo>)Context; IEnumerator<FileSystemInfo> InfoEnumerator = (IEnumerator<FileSystemInfo>)Context;
if (InfoEnumerator.MoveNext()) if (InfoEnumerator.MoveNext())
{ {
FileName = InfoEnumerator.Current.Name; FileName = InfoEnumerator.Current.Name;
GetFileInfoInternal(InfoEnumerator.Current, false, out FileInfo); FileDesc.GetFileInfoFromFileSystemInfo(InfoEnumerator.Current, out FileInfo);
return true; return true;
} }
else else