mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-08 04:52:10 -05:00
tst: passthrough-dotnet: major refactoring and testing
This commit is contained in:
parent
e40505adb5
commit
f2d98bbf25
@ -29,32 +29,212 @@ namespace passthrough
|
|||||||
{
|
{
|
||||||
class Ptfs : FileSystem
|
class Ptfs : FileSystem
|
||||||
{
|
{
|
||||||
protected class FileDesc
|
protected const int ALLOCATION_UNIT = 4096;
|
||||||
{
|
|
||||||
public FileSystemInfo Info;
|
|
||||||
public FileStream Stream;
|
|
||||||
public DirectoryBuffer DirBuffer;
|
|
||||||
|
|
||||||
public FileDesc(FileSystemInfo Info, FileStream Stream)
|
protected static void ThrowIoExceptionWithHResult(Int32 HResult)
|
||||||
{
|
{
|
||||||
this.Info = Info;
|
throw new IOException(null, HResult);
|
||||||
this.Stream = Stream;
|
}
|
||||||
}
|
protected static void ThrowIoExceptionWithWin32(Int32 Error)
|
||||||
public UInt32 FileAttributes
|
{
|
||||||
{
|
ThrowIoExceptionWithHResult(unchecked((Int32)(0x80070000 | Error)));
|
||||||
get
|
}
|
||||||
{
|
protected static void ThrowIoExceptionWithNtStatus(Int32 Status)
|
||||||
return (UInt32)Info.Attributes;
|
{
|
||||||
}
|
ThrowIoExceptionWithWin32((Int32)Win32FromNtStatus(Status));
|
||||||
set
|
|
||||||
{
|
|
||||||
Info.Attributes = 0 == value ?
|
|
||||||
System.IO.FileAttributes.Normal : (FileAttributes)value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int ALLOCATION_UNIT = 4096;
|
protected class FileDesc
|
||||||
|
{
|
||||||
|
public FileStream Stream;
|
||||||
|
public DirectoryInfo DirInfo;
|
||||||
|
public DirectoryBuffer DirBuffer;
|
||||||
|
|
||||||
|
public FileDesc(FileStream Stream)
|
||||||
|
{
|
||||||
|
this.Stream = Stream;
|
||||||
|
}
|
||||||
|
public FileDesc(DirectoryInfo DirInfo)
|
||||||
|
{
|
||||||
|
this.DirInfo = DirInfo;
|
||||||
|
}
|
||||||
|
public static void GetFileInfoFromFileSystemInfo(
|
||||||
|
FileSystemInfo Info,
|
||||||
|
out FileInfo FileInfo)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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,46 +312,53 @@ namespace passthrough
|
|||||||
out FileInfo FileInfo,
|
out FileInfo FileInfo,
|
||||||
out String NormalizedName)
|
out String NormalizedName)
|
||||||
{
|
{
|
||||||
FileDesc FileDesc;
|
FileDesc FileDesc = null;
|
||||||
FileName = ConcatPath(FileName);
|
try
|
||||||
if (0 != (CreateOptions & FILE_DIRECTORY_FILE))
|
|
||||||
{
|
{
|
||||||
if (Directory.Exists(FileName))
|
FileName = ConcatPath(FileName);
|
||||||
ThrowIoException(STATUS_OBJECT_NAME_COLLISION);
|
if (0 == (CreateOptions & FILE_DIRECTORY_FILE))
|
||||||
DirectorySecurity Security = null;
|
|
||||||
if (null != SecurityDescriptor)
|
|
||||||
{
|
{
|
||||||
Security = new DirectorySecurity();
|
FileSecurity Security = null;
|
||||||
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor);
|
if (null != SecurityDescriptor)
|
||||||
|
{
|
||||||
|
Security = new FileSecurity();
|
||||||
|
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor);
|
||||||
|
}
|
||||||
|
FileDesc = new FileDesc(
|
||||||
|
new FileStream(
|
||||||
|
FileName,
|
||||||
|
FileMode.CreateNew,
|
||||||
|
(FileSystemRights)GrantedAccess | FileSystemRights.WriteAttributes,
|
||||||
|
FileShare.Read | FileShare.Write | FileShare.Delete,
|
||||||
|
4096,
|
||||||
|
0,
|
||||||
|
Security));
|
||||||
}
|
}
|
||||||
FileDesc = new FileDesc(
|
else
|
||||||
Directory.CreateDirectory(FileName, Security),
|
{
|
||||||
null);
|
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);
|
||||||
|
FileDesc0 = FileDesc;
|
||||||
|
NormalizedName = default(String);
|
||||||
|
return FileDesc.GetFileInfo(out FileInfo);
|
||||||
}
|
}
|
||||||
else
|
catch
|
||||||
{
|
{
|
||||||
FileSecurity Security = null;
|
if (null != FileDesc && null != FileDesc.Stream)
|
||||||
if (null != SecurityDescriptor)
|
FileDesc.Stream.Dispose();
|
||||||
{
|
throw;
|
||||||
Security = new FileSecurity();
|
|
||||||
Security.SetSecurityDescriptorBinaryForm(SecurityDescriptor);
|
|
||||||
}
|
|
||||||
FileDesc = new FileDesc(
|
|
||||||
new System.IO.FileInfo(FileName),
|
|
||||||
new FileStream(
|
|
||||||
FileName,
|
|
||||||
FileMode.CreateNew,
|
|
||||||
(FileSystemRights)GrantedAccess,
|
|
||||||
FileShare.Read | FileShare.Write | FileShare.Delete,
|
|
||||||
4096,
|
|
||||||
0,
|
|
||||||
Security));
|
|
||||||
}
|
}
|
||||||
FileDesc.FileAttributes = FileAttributes;
|
|
||||||
FileNode = default(Object);
|
|
||||||
FileDesc0 = FileDesc;
|
|
||||||
NormalizedName = default(String);
|
|
||||||
return GetFileInfoInternal(FileDesc.Info, false, out FileInfo);
|
|
||||||
}
|
}
|
||||||
protected override Int32 Open(
|
protected override Int32 Open(
|
||||||
String FileName,
|
String FileName,
|
||||||
@ -209,30 +369,37 @@ namespace passthrough
|
|||||||
out FileInfo FileInfo,
|
out FileInfo FileInfo,
|
||||||
out String NormalizedName)
|
out String NormalizedName)
|
||||||
{
|
{
|
||||||
FileDesc FileDesc;
|
FileDesc FileDesc = null;
|
||||||
FileName = ConcatPath(FileName);
|
try
|
||||||
if (Directory.Exists(FileName))
|
|
||||||
{
|
{
|
||||||
FileDesc = new FileDesc(
|
FileName = ConcatPath(FileName);
|
||||||
new System.IO.DirectoryInfo(FileName),
|
if (!Directory.Exists(FileName))
|
||||||
null);
|
{
|
||||||
|
FileDesc = new FileDesc(
|
||||||
|
new FileStream(
|
||||||
|
FileName,
|
||||||
|
FileMode.Open,
|
||||||
|
(FileSystemRights)GrantedAccess,
|
||||||
|
FileShare.Read | FileShare.Write | FileShare.Delete,
|
||||||
|
4096,
|
||||||
|
0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FileDesc = new FileDesc(
|
||||||
|
new DirectoryInfo(FileName));
|
||||||
|
}
|
||||||
|
FileNode = default(Object);
|
||||||
|
FileDesc0 = FileDesc;
|
||||||
|
NormalizedName = default(String);
|
||||||
|
return FileDesc.GetFileInfo(out FileInfo);
|
||||||
}
|
}
|
||||||
else
|
catch
|
||||||
{
|
{
|
||||||
FileDesc = new FileDesc(
|
if (null != FileDesc && null != FileDesc.Stream)
|
||||||
new System.IO.FileInfo(FileName),
|
FileDesc.Stream.Dispose();
|
||||||
new FileStream(
|
throw;
|
||||||
FileName,
|
|
||||||
FileMode.Open,
|
|
||||||
(FileSystemRights)GrantedAccess,
|
|
||||||
FileShare.Read | FileShare.Write | FileShare.Delete,
|
|
||||||
4096,
|
|
||||||
0));
|
|
||||||
}
|
}
|
||||||
FileNode = default(Object);
|
|
||||||
FileDesc0 = FileDesc;
|
|
||||||
NormalizedName = default(String);
|
|
||||||
return GetFileInfoInternal(FileDesc.Info, false, out FileInfo);
|
|
||||||
}
|
}
|
||||||
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);
|
||||||
FileDesc.Stream.Seek((Int64)Offset, SeekOrigin.Begin);
|
if (!WriteToEndOfFile)
|
||||||
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user