mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	dll: fuse: call chflags from Create and Overwrite
tst: winfsp-tests: file attributes test
This commit is contained in:
		| @@ -821,16 +821,24 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem, | |||||||
|  |  | ||||||
|     Opened = TRUE; |     Opened = TRUE; | ||||||
|  |  | ||||||
|     if (Uid != context->uid || Gid != context->gid) |     if (0 != FileAttributes && | ||||||
|         if (0 != f->ops.chown) |         0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags) | ||||||
|         { |     { | ||||||
|             err = f->ops.chown(contexthdr->PosixPath, Uid, Gid); |         err = f->ops.chflags(contexthdr->PosixPath, | ||||||
|             if (0 != err) |             fsp_fuse_intf_MapFileAttributesToFlags(FileAttributes | FILE_ATTRIBUTE_ARCHIVE)); | ||||||
|             { |         Result = fsp_fuse_ntstatus_from_errno(f->env, err); | ||||||
|                 Result = fsp_fuse_ntstatus_from_errno(f->env, err); |         if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result) | ||||||
|                 goto exit; |             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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /* |     /* | ||||||
|      * Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache. |      * Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache. | ||||||
| @@ -1015,6 +1023,22 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem, | |||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|         return 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, |     return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, | ||||||
|         &Uid, &Gid, &Mode, FileInfo); |         &Uid, &Gid, &Mode, FileInfo); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -784,7 +784,7 @@ cd L: >nul 2>nul || (echo Unable to find drive L: >&2 & goto fail) | |||||||
| L: | L: | ||||||
| "%ProjRoot%\build\VStudio\build\%Configuration%\%3.exe" ^ | "%ProjRoot%\build\VStudio\build\%Configuration%\%3.exe" ^ | ||||||
|     --external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^ |     --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 ^ |     -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* |     -reparse* -stream* | ||||||
| if !ERRORLEVEL! neq 0 set RunSampleTestExit=1 | if !ERRORLEVEL! neq 0 set RunSampleTestExit=1 | ||||||
|   | |||||||
| @@ -232,6 +232,122 @@ void create_test(void) | |||||||
|         create_dotest(MemfsNet, L"\\\\memfs\\share"); |         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 create_related_dotest(ULONG Flags, PWSTR Prefix) | ||||||
| { | { | ||||||
|     void *memfs = memfs_start(Flags); |     void *memfs = memfs_start(Flags); | ||||||
| @@ -1141,6 +1257,7 @@ void create_pid_test(void) | |||||||
| void create_tests(void) | void create_tests(void) | ||||||
| { | { | ||||||
|     TEST(create_test); |     TEST(create_test); | ||||||
|  |     TEST(create_fileattr_test); | ||||||
|     TEST(create_related_test); |     TEST(create_related_test); | ||||||
|     TEST(create_allocation_test); |     TEST(create_allocation_test); | ||||||
|     TEST(create_sd_test); |     TEST(create_sd_test); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user