mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-07 20:42:09 -05:00
tst: passthrough file system: WIP
This commit is contained in:
parent
f8e4c1bbc4
commit
b774aea4f4
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#define PROGNAME "passthrough"
|
#define PROGNAME "passthrough"
|
||||||
#define ALLOCATION_UNIT 4096
|
#define ALLOCATION_UNIT 4096
|
||||||
#define FULLPATH_LENGTH (MAX_PATH + FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR))
|
#define FULLPATH_SIZE (MAX_PATH + FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR))
|
||||||
|
|
||||||
#define info(format, ...) FspServiceLog(EVENTLOG_INFORMATION_TYPE, format, __VA_ARGS__)
|
#define info(format, ...) FspServiceLog(EVENTLOG_INFORMATION_TYPE, format, __VA_ARGS__)
|
||||||
#define warn(format, ...) FspServiceLog(EVENTLOG_WARNING_TYPE, format, __VA_ARGS__)
|
#define warn(format, ...) FspServiceLog(EVENTLOG_WARNING_TYPE, format, __VA_ARGS__)
|
||||||
@ -51,8 +51,7 @@ static NTSTATUS GetFileInfoInternal(HANDLE Handle, FSP_FSCTL_FILE_INFO *FileInfo
|
|||||||
FileInfo->LastAccessTime = ((PLARGE_INTEGER)&ByHandleFileInfo.ftLastAccessTime)->QuadPart;
|
FileInfo->LastAccessTime = ((PLARGE_INTEGER)&ByHandleFileInfo.ftLastAccessTime)->QuadPart;
|
||||||
FileInfo->LastWriteTime = ((PLARGE_INTEGER)&ByHandleFileInfo.ftLastWriteTime)->QuadPart;
|
FileInfo->LastWriteTime = ((PLARGE_INTEGER)&ByHandleFileInfo.ftLastWriteTime)->QuadPart;
|
||||||
FileInfo->ChangeTime = FileInfo->LastWriteTime;
|
FileInfo->ChangeTime = FileInfo->LastWriteTime;
|
||||||
FileInfo->IndexNumber =
|
FileInfo->IndexNumber = 0;
|
||||||
((UINT64)ByHandleFileInfo.nFileIndexHigh << 32) | (UINT64)ByHandleFileInfo.nFileIndexLow;
|
|
||||||
FileInfo->HardLinks = 0;
|
FileInfo->HardLinks = 0;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -89,7 +88,7 @@ static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
|
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
|
||||||
{
|
{
|
||||||
PTFS *Ptfs = (PTFS *)FileSystem->UserContext;
|
PTFS *Ptfs = (PTFS *)FileSystem->UserContext;
|
||||||
WCHAR FullPath[FULLPATH_LENGTH];
|
WCHAR FullPath[FULLPATH_SIZE];
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
FILE_ATTRIBUTE_TAG_INFO AttributeTagInfo;
|
FILE_ATTRIBUTE_TAG_INFO AttributeTagInfo;
|
||||||
DWORD SecurityDescriptorSizeNeeded;
|
DWORD SecurityDescriptorSizeNeeded;
|
||||||
@ -154,7 +153,7 @@ static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo)
|
PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
PTFS *Ptfs = (PTFS *)FileSystem->UserContext;
|
PTFS *Ptfs = (PTFS *)FileSystem->UserContext;
|
||||||
WCHAR FullPath[FULLPATH_LENGTH];
|
WCHAR FullPath[FULLPATH_SIZE];
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
|
|
||||||
if (!ConcatPath(Ptfs, FileName, FullPath))
|
if (!ConcatPath(Ptfs, FileName, FullPath))
|
||||||
@ -166,6 +165,8 @@ static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (INVALID_HANDLE_VALUE == Handle)
|
if (INVALID_HANDLE_VALUE == Handle)
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
*PFileContext = Handle;
|
||||||
|
|
||||||
return GetFileInfoInternal(Handle, FileInfo);
|
return GetFileInfoInternal(Handle, FileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,11 +262,94 @@ static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length,
|
PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG BufferLength,
|
||||||
PWSTR Pattern,
|
PWSTR Pattern,
|
||||||
PULONG PBytesTransferred)
|
PULONG PBytesTransferred)
|
||||||
{
|
{
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
PTFS *Ptfs = (PTFS *)FileSystem->UserContext;
|
||||||
|
HANDLE Handle = FileContext;
|
||||||
|
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;
|
||||||
|
UINT64 NextOffset = 0;
|
||||||
|
|
||||||
|
if (0 == Pattern)
|
||||||
|
Pattern = L"*";
|
||||||
|
PatternLength = (ULONG)wcslen(Pattern);
|
||||||
|
|
||||||
|
Length = GetFinalPathNameByHandleW(Handle, FullPath, FULLPATH_SIZE - 1, 0);
|
||||||
|
if (0 == Length)
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
if (Length + 1 + PatternLength >= FULLPATH_SIZE)
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
|
||||||
|
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)
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The simple conditional `Offset > NextOffset++` only works when files
|
||||||
|
* are not created/deleted in the directory while it is being read.
|
||||||
|
* This is perhaps ok for this sample file system, but a "real" file
|
||||||
|
* system would probably have to handle this better.
|
||||||
|
*
|
||||||
|
* The best approach for a file system is to use directory offsets that
|
||||||
|
* do not change when files are created/deleted. If this is not possible
|
||||||
|
* it is also acceptable to have directory offsets that do not change
|
||||||
|
* for as long as the directory remains open.
|
||||||
|
*
|
||||||
|
* The easiest method to achieve this is to buffer all directory contents
|
||||||
|
* in a call to ReadDirectory with Offset == 0 and then return offsets
|
||||||
|
* within the directory content buffer. Subsequent ReadDirectory operation
|
||||||
|
* return directory contents directly from the buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (Offset <= NextOffset++)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
DirInfo->NextOffset = NextOffset;
|
||||||
|
memcpy(DirInfo->FileNameBuf, FindData.cFileName, Length * sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (!FspFileSystemAddDirInfo(DirInfo, Buffer, BufferLength, PBytesTransferred))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FindNextFileW(FindHandle, &FindData))
|
||||||
|
{
|
||||||
|
/* add "End-Of-Listing" marker */
|
||||||
|
FspFileSystemAddDirInfo(0, Buffer, BufferLength, PBytesTransferred);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FSP_FILE_SYSTEM_INTERFACE PtfsInterface =
|
static FSP_FILE_SYSTEM_INTERFACE PtfsInterface =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user