dll: fuse: call chflags from Create and Overwrite

tst: winfsp-tests: file attributes test
This commit is contained in:
Bill Zissimopoulos 2017-12-04 14:08:44 -08:00
parent d02030897d
commit 266e0f4bab
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
3 changed files with 152 additions and 11 deletions

View File

@ -821,15 +821,23 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
Opened = TRUE;
if (Uid != context->uid || Gid != context->gid)
if (0 != f->ops.chown)
{
err = f->ops.chown(contexthdr->PosixPath, Uid, Gid);
if (0 != err)
if (0 != FileAttributes &&
0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags)
{
err = f->ops.chflags(contexthdr->PosixPath,
fsp_fuse_intf_MapFileAttributesToFlags(FileAttributes | FILE_ATTRIBUTE_ARCHIVE));
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
goto exit;
}
if ((Uid != context->uid || Gid != context->gid) &&
0 != f->ops.chown)
{
err = f->ops.chown(contexthdr->PosixPath, Uid, Gid);
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
goto exit;
}
/*
@ -1015,6 +1023,22 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result))
return Result;
if (0 != FileAttributes &&
0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags)
{
/*
* The code below is not strictly correct. File attributes should be
* replaced when ReplaceFileAttributes is TRUE and merged (or'ed) when
* ReplaceFileAttributes is FALSE. I am punting on this detail for now.
*/
err = f->ops.chflags(filedesc->PosixPath,
fsp_fuse_intf_MapFileAttributesToFlags(FileAttributes | FILE_ATTRIBUTE_ARCHIVE));
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
return Result;
}
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
&Uid, &Gid, &Mode, FileInfo);
}

View File

@ -784,7 +784,7 @@ cd L: >nul 2>nul || (echo Unable to find drive L: >&2 & goto fail)
L:
"%ProjRoot%\build\VStudio\build\%Configuration%\%3.exe" ^
--external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^
-create_allocation_test -create_notraverse_test -create_backup_test -create_restore_test -create_namelen_test ^
-create_fileattr_test -create_allocation_test -create_notraverse_test -create_backup_test -create_restore_test -create_namelen_test ^
-getfileinfo_name_test -setfileinfo_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -querydir_namelen_test -exec_rename_dir_test ^
-reparse* -stream*
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1

View File

@ -232,6 +232,122 @@ void create_test(void)
create_dotest(MemfsNet, L"\\\\memfs\\share");
}
static void create_fileattr_dotest(ULONG Flags, PWSTR Prefix)
{
void *memfs = memfs_start(Flags);
HANDLE Handle;
BOOLEAN Success;
DWORD FileAttributes;
WCHAR FilePath[MAX_PATH];
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
CloseHandle(Handle);
FileAttributes = GetFileAttributesW(FilePath);
ASSERT(FILE_ATTRIBUTE_ARCHIVE == FileAttributes);
Success = DeleteFileW(FilePath);
ASSERT(Success);
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_READONLY, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
CloseHandle(Handle);
FileAttributes = GetFileAttributesW(FilePath);
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY) == FileAttributes);
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
ASSERT(Success);
Success = DeleteFileW(FilePath);
ASSERT(Success);
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_SYSTEM, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
CloseHandle(Handle);
FileAttributes = GetFileAttributesW(FilePath);
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM) == FileAttributes);
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
ASSERT(Success);
Success = DeleteFileW(FilePath);
ASSERT(Success);
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_HIDDEN, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
CloseHandle(Handle);
FileAttributes = GetFileAttributesW(FilePath);
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN) == FileAttributes);
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
ASSERT(Success);
Success = DeleteFileW(FilePath);
ASSERT(Success);
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
CloseHandle(Handle);
FileAttributes = GetFileAttributesW(FilePath);
ASSERT(FILE_ATTRIBUTE_ARCHIVE == FileAttributes);
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
CloseHandle(Handle);
FileAttributes = GetFileAttributesW(FilePath);
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY) == FileAttributes);
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
ASSERT(Success);
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
CloseHandle(Handle);
FileAttributes = GetFileAttributesW(FilePath);
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM) == FileAttributes);
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
ASSERT(Success);
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
CloseHandle(Handle);
FileAttributes = GetFileAttributesW(FilePath);
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN) == FileAttributes);
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
ASSERT(Success);
Success = DeleteFileW(FilePath);
ASSERT(Success);
memfs_stop(memfs);
}
static void create_fileattr_test(void)
{
if (NtfsTests)
{
WCHAR DirBuf[MAX_PATH];
GetTestDirectory(DirBuf);
create_fileattr_dotest(-1, DirBuf);
}
if (WinFspDiskTests)
create_fileattr_dotest(MemfsDisk, 0);
if (WinFspNetTests)
create_fileattr_dotest(MemfsNet, L"\\\\memfs\\share");
}
void create_related_dotest(ULONG Flags, PWSTR Prefix)
{
void *memfs = memfs_start(Flags);
@ -1141,6 +1257,7 @@ void create_pid_test(void)
void create_tests(void)
{
TEST(create_test);
TEST(create_fileattr_test);
TEST(create_related_test);
TEST(create_allocation_test);
TEST(create_sd_test);