mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
tst: passthrough-dotnet: ReadDirectory
This commit is contained in:
parent
a0df9babf9
commit
f938bf5e3f
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
@ -32,6 +33,7 @@ namespace passthrough
|
|||||||
{
|
{
|
||||||
public FileSystemInfo Info;
|
public FileSystemInfo Info;
|
||||||
public FileStream Stream;
|
public FileStream Stream;
|
||||||
|
public DirectoryBuffer DirBuffer;
|
||||||
|
|
||||||
public FileDesc(FileSystemInfo Info, FileStream Stream)
|
public FileDesc(FileSystemInfo Info, FileStream Stream)
|
||||||
{
|
{
|
||||||
@ -84,20 +86,20 @@ namespace passthrough
|
|||||||
{
|
{
|
||||||
return Path.Combine(_Path, FileName);
|
return Path.Combine(_Path, FileName);
|
||||||
}
|
}
|
||||||
protected Int32 GetFileInfoInternal(FileDesc FileDesc, Boolean Refresh,
|
protected Int32 GetFileInfoInternal(FileSystemInfo Info, Boolean Refresh,
|
||||||
out FileInfo FileInfo)
|
out FileInfo FileInfo)
|
||||||
{
|
{
|
||||||
if (Refresh)
|
if (Refresh)
|
||||||
FileDesc.Info.Refresh();
|
Info.Refresh();
|
||||||
FileInfo.FileAttributes = FileDesc.FileAttributes;
|
FileInfo.FileAttributes = (UInt32)Info.Attributes;
|
||||||
FileInfo.ReparseTag = 0;
|
FileInfo.ReparseTag = 0;
|
||||||
FileInfo.FileSize = FileDesc.Info is System.IO.FileInfo ?
|
FileInfo.FileSize = Info is System.IO.FileInfo ?
|
||||||
(UInt64)((System.IO.FileInfo)FileDesc.Info).Length : 0;
|
(UInt64)((System.IO.FileInfo)Info).Length : 0;
|
||||||
FileInfo.AllocationSize = (FileInfo.FileSize + ALLOCATION_UNIT - 1)
|
FileInfo.AllocationSize = (FileInfo.FileSize + ALLOCATION_UNIT - 1)
|
||||||
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
|
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
|
||||||
FileInfo.CreationTime = (UInt64)FileDesc.Info.CreationTimeUtc.ToFileTimeUtc();
|
FileInfo.CreationTime = (UInt64)Info.CreationTimeUtc.ToFileTimeUtc();
|
||||||
FileInfo.LastAccessTime = (UInt64)FileDesc.Info.LastAccessTimeUtc.ToFileTimeUtc();
|
FileInfo.LastAccessTime = (UInt64)Info.LastAccessTimeUtc.ToFileTimeUtc();
|
||||||
FileInfo.LastWriteTime = (UInt64)FileDesc.Info.LastWriteTimeUtc.ToFileTimeUtc();
|
FileInfo.LastWriteTime = (UInt64)Info.LastWriteTimeUtc.ToFileTimeUtc();
|
||||||
FileInfo.ChangeTime = FileInfo.LastWriteTime;
|
FileInfo.ChangeTime = FileInfo.LastWriteTime;
|
||||||
FileInfo.IndexNumber = 0;
|
FileInfo.IndexNumber = 0;
|
||||||
FileInfo.HardLinks = 0;
|
FileInfo.HardLinks = 0;
|
||||||
@ -186,7 +188,7 @@ namespace passthrough
|
|||||||
FileNode = default(Object);
|
FileNode = default(Object);
|
||||||
FileDesc0 = FileDesc;
|
FileDesc0 = FileDesc;
|
||||||
NormalizedName = default(String);
|
NormalizedName = default(String);
|
||||||
return GetFileInfoInternal(FileDesc, false, out FileInfo);
|
return GetFileInfoInternal(FileDesc.Info, false, out FileInfo);
|
||||||
}
|
}
|
||||||
protected override Int32 Open(
|
protected override Int32 Open(
|
||||||
String FileName,
|
String FileName,
|
||||||
@ -223,7 +225,7 @@ namespace passthrough
|
|||||||
FileNode = default(Object);
|
FileNode = default(Object);
|
||||||
FileDesc0 = FileDesc;
|
FileDesc0 = FileDesc;
|
||||||
NormalizedName = default(String);
|
NormalizedName = default(String);
|
||||||
return GetFileInfoInternal(FileDesc, false, out FileInfo);
|
return GetFileInfoInternal(FileDesc.Info, false, out FileInfo);
|
||||||
}
|
}
|
||||||
protected override Int32 Overwrite(
|
protected override Int32 Overwrite(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -239,7 +241,7 @@ namespace passthrough
|
|||||||
else if (0 != FileAttributes)
|
else if (0 != FileAttributes)
|
||||||
FileDesc.FileAttributes |= FileAttributes;
|
FileDesc.FileAttributes |= FileAttributes;
|
||||||
FileDesc.Stream.SetLength(0);
|
FileDesc.Stream.SetLength(0);
|
||||||
return GetFileInfoInternal(FileDesc, true, out FileInfo);
|
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo);
|
||||||
}
|
}
|
||||||
protected override void Cleanup(
|
protected override void Cleanup(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -257,6 +259,8 @@ namespace passthrough
|
|||||||
{
|
{
|
||||||
FileDesc FileDesc = (FileDesc)FileDesc0;
|
FileDesc FileDesc = (FileDesc)FileDesc0;
|
||||||
FileDesc.Stream.Dispose();
|
FileDesc.Stream.Dispose();
|
||||||
|
if (null != FileDesc.DirBuffer)
|
||||||
|
FileDesc.DirBuffer.Dispose();
|
||||||
}
|
}
|
||||||
protected override Int32 Read(
|
protected override Int32 Read(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -304,7 +308,7 @@ namespace passthrough
|
|||||||
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, true, out FileInfo);
|
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo);
|
||||||
}
|
}
|
||||||
protected override Int32 Flush(
|
protected override Int32 Flush(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -319,7 +323,7 @@ namespace passthrough
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
FileDesc.Stream.Flush(true);
|
FileDesc.Stream.Flush(true);
|
||||||
return GetFileInfoInternal(FileDesc, true, out FileInfo);
|
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo);
|
||||||
}
|
}
|
||||||
protected override Int32 GetFileInfo(
|
protected override Int32 GetFileInfo(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -327,7 +331,7 @@ namespace passthrough
|
|||||||
out FileInfo FileInfo)
|
out FileInfo FileInfo)
|
||||||
{
|
{
|
||||||
FileDesc FileDesc = (FileDesc)FileDesc0;
|
FileDesc FileDesc = (FileDesc)FileDesc0;
|
||||||
return GetFileInfoInternal(FileDesc, true, out FileInfo);
|
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo);
|
||||||
}
|
}
|
||||||
protected override Int32 SetBasicInfo(
|
protected override Int32 SetBasicInfo(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -348,7 +352,7 @@ namespace passthrough
|
|||||||
FileDesc.Info.LastAccessTimeUtc = DateTime.FromFileTimeUtc((Int64)LastAccessTime);
|
FileDesc.Info.LastAccessTimeUtc = DateTime.FromFileTimeUtc((Int64)LastAccessTime);
|
||||||
if (0 != LastWriteTime)
|
if (0 != LastWriteTime)
|
||||||
FileDesc.Info.LastWriteTimeUtc = DateTime.FromFileTimeUtc((Int64)LastWriteTime);
|
FileDesc.Info.LastWriteTimeUtc = DateTime.FromFileTimeUtc((Int64)LastWriteTime);
|
||||||
return GetFileInfoInternal(FileDesc, true, out FileInfo);
|
return GetFileInfoInternal(FileDesc.Info, true, out FileInfo);
|
||||||
}
|
}
|
||||||
protected override Int32 SetFileSize(
|
protected override Int32 SetFileSize(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
@ -358,7 +362,7 @@ namespace passthrough
|
|||||||
out FileInfo FileInfo)
|
out FileInfo FileInfo)
|
||||||
{
|
{
|
||||||
FileDesc FileDesc = (FileDesc)FileDesc0;
|
FileDesc FileDesc = (FileDesc)FileDesc0;
|
||||||
GetFileInfoInternal(FileDesc, true, out FileInfo);
|
GetFileInfoInternal(FileDesc.Info, true, out FileInfo);
|
||||||
if (!SetAllocationSize || FileInfo.FileSize > NewSize)
|
if (!SetAllocationSize || FileInfo.FileSize > NewSize)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -451,15 +455,48 @@ namespace passthrough
|
|||||||
}
|
}
|
||||||
protected override Int32 ReadDirectory(
|
protected override Int32 ReadDirectory(
|
||||||
Object FileNode,
|
Object FileNode,
|
||||||
Object FileDesc,
|
Object FileDesc0,
|
||||||
String Pattern,
|
String Pattern,
|
||||||
String Marker,
|
String Marker,
|
||||||
IntPtr Buffer,
|
IntPtr Buffer,
|
||||||
UInt32 Length,
|
UInt32 Length,
|
||||||
out UInt32 PBytesTransferred)
|
out UInt32 PBytesTransferred)
|
||||||
{
|
{
|
||||||
PBytesTransferred = default(UInt32);
|
FileDesc FileDesc = (FileDesc)FileDesc0;
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
if (null == FileDesc.DirBuffer)
|
||||||
|
FileDesc.DirBuffer = new DirectoryBuffer();
|
||||||
|
return BufferedReadDirectory(FileDesc.DirBuffer,
|
||||||
|
FileNode, FileDesc, Pattern, Marker, Buffer, Length, out PBytesTransferred);
|
||||||
|
}
|
||||||
|
protected override Boolean ReadDirectoryEntry(
|
||||||
|
Object FileNode,
|
||||||
|
Object FileDesc0,
|
||||||
|
String Pattern,
|
||||||
|
String Marker,
|
||||||
|
ref Object Context,
|
||||||
|
out String FileName,
|
||||||
|
out FileInfo FileInfo)
|
||||||
|
{
|
||||||
|
if (null == Context)
|
||||||
|
{
|
||||||
|
FileDesc FileDesc = (FileDesc)FileDesc0;
|
||||||
|
if (null == Pattern)
|
||||||
|
Pattern = "*";
|
||||||
|
Context = (FileDesc.Info as DirectoryInfo).EnumerateFileSystemInfos(Pattern);
|
||||||
|
}
|
||||||
|
IEnumerator<FileSystemInfo> InfoEnumerator = (IEnumerator<FileSystemInfo>)Context;
|
||||||
|
if (InfoEnumerator.MoveNext())
|
||||||
|
{
|
||||||
|
FileName = InfoEnumerator.Current.Name;
|
||||||
|
GetFileInfoInternal(InfoEnumerator.Current, false, out FileInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FileName = default(String);
|
||||||
|
FileInfo = default(FileInfo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String _Path;
|
private String _Path;
|
||||||
@ -563,7 +600,7 @@ namespace passthrough
|
|||||||
Ptfs.SetPath(PassThrough);
|
Ptfs.SetPath(PassThrough);
|
||||||
|
|
||||||
FailMessage = "cannot mount file system";
|
FailMessage = "cannot mount file system";
|
||||||
Ptfs.Mount(MountPoint, null, false, DebugFlags);
|
Ptfs.Mount(MountPoint, null, true, DebugFlags);
|
||||||
MountPoint = Ptfs.MountPoint();
|
MountPoint = Ptfs.MountPoint();
|
||||||
_Ptfs = Ptfs;
|
_Ptfs = Ptfs;
|
||||||
|
|
||||||
@ -669,105 +706,3 @@ namespace passthrough
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if false
|
|
||||||
|
|
||||||
using namespace Fsp;
|
|
||||||
|
|
||||||
struct PTFS_FILE_DESC
|
|
||||||
{
|
|
||||||
PTFS_FILE_DESC() : Handle(INVALID_HANDLE_VALUE), DirBuffer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~PTFS_FILE_DESC()
|
|
||||||
{
|
|
||||||
CloseHandle(Handle);
|
|
||||||
PTFS::DeleteDirectoryBuffer(&DirBuffer);
|
|
||||||
}
|
|
||||||
HANDLE Handle;
|
|
||||||
PVOID DirBuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
NTSTATUS PTFS::ReadDirectory(
|
|
||||||
const FILE_CONTEXT *FileContext, PWSTR Pattern, PWSTR Marker,
|
|
||||||
PVOID Buffer, ULONG BufferLength, PULONG PBytesTransferred)
|
|
||||||
{
|
|
||||||
PTFS_FILE_DESC *FileDesc = (PTFS_FILE_DESC *)FileContext->FileDesc;
|
|
||||||
HANDLE Handle = FileDesc->Handle;
|
|
||||||
WCHAR FullPath[FULLPATH_SIZE];
|
|
||||||
ULONG Length, PatternLength;
|
|
||||||
HANDLE FindHandle;
|
|
||||||
WIN32_FIND_DATAW FindData;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) + MAX_PATH * sizeof(WCHAR)];
|
|
||||||
FSP_FSCTL_DIR_INFO D;
|
|
||||||
} DirInfoBuf;
|
|
||||||
FSP_FSCTL_DIR_INFO *DirInfo = &DirInfoBuf.D;
|
|
||||||
NTSTATUS DirBufferResult;
|
|
||||||
|
|
||||||
DirBufferResult = STATUS_SUCCESS;
|
|
||||||
if (AcquireDirectoryBuffer(&FileDesc->DirBuffer, 0 == Marker, &DirBufferResult))
|
|
||||||
{
|
|
||||||
if (0 == Pattern)
|
|
||||||
Pattern = L"*";
|
|
||||||
PatternLength = (ULONG)wcslen(Pattern);
|
|
||||||
|
|
||||||
Length = GetFinalPathNameByHandleW(Handle, FullPath, FULLPATH_SIZE - 1, 0);
|
|
||||||
if (0 == Length)
|
|
||||||
DirBufferResult = NtStatusFromWin32(GetLastError());
|
|
||||||
else if (Length + 1 + PatternLength >= FULLPATH_SIZE)
|
|
||||||
DirBufferResult = STATUS_OBJECT_NAME_INVALID;
|
|
||||||
if (!NT_SUCCESS(DirBufferResult))
|
|
||||||
{
|
|
||||||
ReleaseDirectoryBuffer(&FileDesc->DirBuffer);
|
|
||||||
return DirBufferResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (L'\\' != FullPath[Length - 1])
|
|
||||||
FullPath[Length++] = L'\\';
|
|
||||||
memcpy(FullPath + Length, Pattern, PatternLength * sizeof(WCHAR));
|
|
||||||
FullPath[Length + PatternLength] = L'\0';
|
|
||||||
|
|
||||||
FindHandle = FindFirstFileW(FullPath, &FindData);
|
|
||||||
if (INVALID_HANDLE_VALUE != FindHandle)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
memset(DirInfo, 0, sizeof *DirInfo);
|
|
||||||
Length = (ULONG)wcslen(FindData.cFileName);
|
|
||||||
DirInfo->Size = (UINT16)(FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) + Length * sizeof(WCHAR));
|
|
||||||
DirInfo->FileInfo.FileAttributes = FindData.dwFileAttributes;
|
|
||||||
DirInfo->FileInfo.ReparseTag = 0;
|
|
||||||
DirInfo->FileInfo.FileSize =
|
|
||||||
((UINT64)FindData.nFileSizeHigh << 32) | (UINT64)FindData.nFileSizeLow;
|
|
||||||
DirInfo->FileInfo.AllocationSize = (DirInfo->FileInfo.FileSize + ALLOCATION_UNIT - 1)
|
|
||||||
/ ALLOCATION_UNIT * ALLOCATION_UNIT;
|
|
||||||
DirInfo->FileInfo.CreationTime = ((PLARGE_INTEGER)&FindData.ftCreationTime)->QuadPart;
|
|
||||||
DirInfo->FileInfo.LastAccessTime = ((PLARGE_INTEGER)&FindData.ftLastAccessTime)->QuadPart;
|
|
||||||
DirInfo->FileInfo.LastWriteTime = ((PLARGE_INTEGER)&FindData.ftLastWriteTime)->QuadPart;
|
|
||||||
DirInfo->FileInfo.ChangeTime = DirInfo->FileInfo.LastWriteTime;
|
|
||||||
DirInfo->FileInfo.IndexNumber = 0;
|
|
||||||
DirInfo->FileInfo.HardLinks = 0;
|
|
||||||
memcpy(DirInfo->FileNameBuf, FindData.cFileName, Length * sizeof(WCHAR));
|
|
||||||
|
|
||||||
if (!FillDirectoryBuffer(&FileDesc->DirBuffer, DirInfo, &DirBufferResult))
|
|
||||||
break;
|
|
||||||
} while (FindNextFileW(FindHandle, &FindData));
|
|
||||||
|
|
||||||
FindClose(FindHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseDirectoryBuffer(&FileDesc->DirBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(DirBufferResult))
|
|
||||||
return DirBufferResult;
|
|
||||||
|
|
||||||
ReadDirectoryBuffer(&FileDesc->DirBuffer,
|
|
||||||
Marker, Buffer, BufferLength, PBytesTransferred);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user