From be92c5d768145372c6441ba193aeb3b493099c90 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Sat, 1 Apr 2023 11:07:21 +1100 Subject: [PATCH] Added ntdll-hidden_file_attr patchset --- ...test-for-file-attributes-of-files-wi.patch | 123 ++++++++++++++++ ...n-code-hidden-file-handling-in-get_d.patch | 46 ++++++ ...den-file-names-inside-get_file_info-.patch | 91 ++++++++++++ ...-hidden-attribute-from-file-name-if-.patch | 49 +++++++ ...in-NtCreateFile-if-inferred-and-requ.patch | 132 ++++++++++++++++++ ...rease-margins-in-timer-merging-tests.patch | 43 ++++++ patches/ntdll-hidden_file_attr/definition | 2 + 7 files changed, 486 insertions(+) create mode 100644 patches/ntdll-hidden_file_attr/0001-ntdll-tests-Add-test-for-file-attributes-of-files-wi.patch create mode 100644 patches/ntdll-hidden_file_attr/0002-ntdll-Do-not-open-code-hidden-file-handling-in-get_d.patch create mode 100644 patches/ntdll-hidden_file_attr/0003-ntdll-Handle-hidden-file-names-inside-get_file_info-.patch create mode 100644 patches/ntdll-hidden_file_attr/0004-ntdll-Only-infer-hidden-attribute-from-file-name-if-.patch create mode 100644 patches/ntdll-hidden_file_attr/0005-ntdll-Set-xattr-in-NtCreateFile-if-inferred-and-requ.patch create mode 100644 patches/ntdll-hidden_file_attr/0006-ntdll-tests-Increase-margins-in-timer-merging-tests.patch create mode 100644 patches/ntdll-hidden_file_attr/definition diff --git a/patches/ntdll-hidden_file_attr/0001-ntdll-tests-Add-test-for-file-attributes-of-files-wi.patch b/patches/ntdll-hidden_file_attr/0001-ntdll-tests-Add-test-for-file-attributes-of-files-wi.patch new file mode 100644 index 00000000..5a3d0a0a --- /dev/null +++ b/patches/ntdll-hidden_file_attr/0001-ntdll-tests-Add-test-for-file-attributes-of-files-wi.patch @@ -0,0 +1,123 @@ +From cd0e7d0bd693a35fde5a83f76af16cd04b17c5e3 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Thu, 30 Mar 2023 05:46:38 +0200 +Subject: [PATCH 1/6] ntdll/tests: Add test for file attributes of files with + names beginning with a dot. + +--- + dlls/ntdll/tests/file.c | 92 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 92 insertions(+) + +diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c +index 6186afdfb63..beaa4734931 100644 +--- a/dlls/ntdll/tests/file.c ++++ b/dlls/ntdll/tests/file.c +@@ -4051,6 +4051,97 @@ static void test_file_attribute_tag_information(void) + CloseHandle( h ); + } + ++static void rename_file( HANDLE h, const WCHAR *filename ) ++{ ++ FILE_RENAME_INFORMATION *fri; ++ UNICODE_STRING ntpath; ++ IO_STATUS_BLOCK io; ++ NTSTATUS status; ++ BOOLEAN ret; ++ ULONG size; ++ ++ ret = pRtlDosPathNameToNtPathName_U( filename, &ntpath, NULL, NULL ); ++ ok( ret, "RtlDosPathNameToNtPathName_U failed\n" ); ++ ++ size = offsetof( FILE_RENAME_INFORMATION, FileName ) + ntpath.Length; ++ fri = HeapAlloc( GetProcessHeap(), 0, size ); ++ ok( fri != NULL, "HeapAlloc failed\n" ); ++ fri->ReplaceIfExists = TRUE; ++ fri->RootDirectory = NULL; ++ fri->FileNameLength = ntpath.Length; ++ memcpy( fri->FileName, ntpath.Buffer, ntpath.Length ); ++ pRtlFreeUnicodeString( &ntpath ); ++ ++ status = pNtSetInformationFile( h, &io, fri, size, FileRenameInformation ); ++ HeapFree( GetProcessHeap(), 0, fri ); ++ ok( status == STATUS_SUCCESS, "got %#lx\n", status ); ++} ++ ++static void test_dotfile_file_attributes(void) ++{ ++ char temppath[MAX_PATH], filename[MAX_PATH]; ++ WCHAR temppathW[MAX_PATH], filenameW[MAX_PATH]; ++ FILE_BASIC_INFORMATION info = {}; ++ IO_STATUS_BLOCK io; ++ NTSTATUS status; ++ DWORD attrs; ++ HANDLE h; ++ ++ GetTempPathA( MAX_PATH, temppath ); ++ GetTempFileNameA( temppath, ".foo", 0, filename ); ++ h = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0 ); ++ ok( h != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); ++ ++ status = nt_get_file_attrs(filename, &attrs); ++ ok( status == STATUS_SUCCESS, "got %#lx\n", status ); ++ todo_wine ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs ); ++ ++ status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); ++ ok( status == STATUS_SUCCESS, "got %#lx\n", status ); ++ ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes ); ++ ++ info.FileAttributes = FILE_ATTRIBUTE_SYSTEM; ++ status = pNtSetInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); ++ ok( status == STATUS_SUCCESS, "got %#lx\n", status ); ++ ++ status = nt_get_file_attrs(filename, &attrs); ++ ok( status == STATUS_SUCCESS, "got %#lx\n", status ); ++ ok( attrs & FILE_ATTRIBUTE_SYSTEM, "got attributes %#lx\n", attrs ); ++ todo_wine ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs ); ++ ++ status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); ++ ok( status == STATUS_SUCCESS, "got %#lx\n", status ); ++ ok( info.FileAttributes & FILE_ATTRIBUTE_SYSTEM, "got attributes %#lx\n", info.FileAttributes ); ++ ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes ); ++ ++ CloseHandle( h ); ++ ++ GetTempPathW( MAX_PATH, temppathW ); ++ GetTempFileNameW( temppathW, L"foo", 0, filenameW ); ++ h = CreateFileW( filenameW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0 ); ++ ok( h != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); ++ ++ GetTempFileNameW( temppathW, L".foo", 0, filenameW ); ++ winetest_push_context("foo -> .foo"); ++ rename_file( h, filenameW ); ++ winetest_pop_context(); ++ ++ status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); ++ ok( status == STATUS_SUCCESS, "got %#lx\n", status ); ++ ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes ); ++ ++ GetTempFileNameW( temppathW, L"foo", 0, filenameW ); ++ winetest_push_context(".foo -> foo"); ++ rename_file( h, filenameW ); ++ winetest_pop_context(); ++ ++ status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); ++ ok( status == STATUS_SUCCESS, "got %#lx\n", status ); ++ ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes ); ++ ++ CloseHandle( h ); ++} ++ + static void test_file_mode(void) + { + UNICODE_STRING file_name, pipe_dev_name, mountmgr_dev_name, mailslot_dev_name; +@@ -5499,6 +5590,7 @@ START_TEST(file) + test_file_id_information(); + test_file_access_information(); + test_file_attribute_tag_information(); ++ test_dotfile_file_attributes(); + test_file_mode(); + test_file_readonly_access(); + test_query_volume_information_file(); +-- +2.40.0 + diff --git a/patches/ntdll-hidden_file_attr/0002-ntdll-Do-not-open-code-hidden-file-handling-in-get_d.patch b/patches/ntdll-hidden_file_attr/0002-ntdll-Do-not-open-code-hidden-file-handling-in-get_d.patch new file mode 100644 index 00000000..54ef9640 --- /dev/null +++ b/patches/ntdll-hidden_file_attr/0002-ntdll-Do-not-open-code-hidden-file-handling-in-get_d.patch @@ -0,0 +1,46 @@ +From bf28841ea6e717ed625ccd02a025fb6153f45677 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Thu, 30 Mar 2023 05:46:39 +0200 +Subject: [PATCH 2/6] ntdll: Do not open-code hidden file handling in + get_dir_data_entry. + +Signed-off-by: Torge Matthies +--- + dlls/ntdll/unix/file.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c +index eca75b2d4fb..f48de4641b3 100644 +--- a/dlls/ntdll/unix/file.c ++++ b/dlls/ntdll/unix/file.c +@@ -1303,7 +1303,7 @@ static BOOL is_hidden_file( const UNICODE_STRING *name ) + end = p = name->Buffer + name->Length/sizeof(WCHAR); + while (p > name->Buffer && p[-1] == '\\') p--; + while (p > name->Buffer && p[-1] != '\\') p--; +- return (p < end && *p == '.'); ++ return (p < end && p + 1 != end && p[0] == '.' && p[1] != '\\' && (p[1] != '.' || (p + 2 != end && p[2] != '\\'))); + } + + +@@ -2224,6 +2224,7 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I + union file_directory_info *info; + struct stat st; + ULONG name_len, start, dir_size, attributes; ++ UNICODE_STRING name; + + if (get_file_info( names->unix_name, &st, &attributes ) == -1) + { +@@ -2253,8 +2254,8 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I + { + if (st.st_dev != dir_data->id.dev) st.st_ino = 0; /* ignore inode if on a different device */ + +- if (!show_dot_files && names->long_name[0] == '.' && names->long_name[1] && +- (names->long_name[1] != '.' || names->long_name[2])) ++ RtlInitUnicodeString( &name, names->long_name ); ++ if (is_hidden_file( &name )) + attributes |= FILE_ATTRIBUTE_HIDDEN; + + fill_file_info( &st, attributes, info, class ); +-- +2.40.0 + diff --git a/patches/ntdll-hidden_file_attr/0003-ntdll-Handle-hidden-file-names-inside-get_file_info-.patch b/patches/ntdll-hidden_file_attr/0003-ntdll-Handle-hidden-file-names-inside-get_file_info-.patch new file mode 100644 index 00000000..2e50c012 --- /dev/null +++ b/patches/ntdll-hidden_file_attr/0003-ntdll-Handle-hidden-file-names-inside-get_file_info-.patch @@ -0,0 +1,91 @@ +From 46d8829db7ced55d93da228e7777b9f7a6a02e7d Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Thu, 30 Mar 2023 05:46:39 +0200 +Subject: [PATCH 3/6] ntdll: Handle hidden file names inside get_file_info + instead of after it. + +Signed-off-by: Torge Matthies +--- + dlls/ntdll/unix/file.c | 25 +++++++++---------------- + 1 file changed, 9 insertions(+), 16 deletions(-) + +diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c +index f48de4641b3..59e96a88279 100644 +--- a/dlls/ntdll/unix/file.c ++++ b/dlls/ntdll/unix/file.c +@@ -1292,17 +1292,17 @@ static BOOLEAN get_dir_case_sensitivity( const char *dir ) + /*********************************************************************** + * is_hidden_file + * +- * Check if the specified file should be hidden based on its name and the show dot files option. ++ * Check if the specified file should be hidden based on its unix path and the show dot files option. + */ +-static BOOL is_hidden_file( const UNICODE_STRING *name ) ++static BOOL is_hidden_file( const char *name ) + { +- WCHAR *p, *end; ++ const char *p, *end; + + if (show_dot_files) return FALSE; + +- end = p = name->Buffer + name->Length/sizeof(WCHAR); +- while (p > name->Buffer && p[-1] == '\\') p--; +- while (p > name->Buffer && p[-1] != '\\') p--; ++ end = p = name + strlen( name ); ++ while (p > name && p[-1] == '/') p--; ++ while (p > name && p[-1] != '/') p--; + return (p < end && p + 1 != end && p[0] == '.' && p[1] != '\\' && (p[1] != '.' || (p + 2 != end && p[2] != '\\'))); + } + +@@ -1677,6 +1677,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) + } + *attr |= get_file_attributes( st ); + ++ if (is_hidden_file( path )) ++ *attr |= FILE_ATTRIBUTE_HIDDEN; ++ + attr_len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, attr_data, sizeof(attr_data)-1 ); + if (attr_len != -1) + *attr |= parse_samba_dos_attrib_data( attr_data, attr_len ); +@@ -2224,7 +2227,6 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I + union file_directory_info *info; + struct stat st; + ULONG name_len, start, dir_size, attributes; +- UNICODE_STRING name; + + if (get_file_info( names->unix_name, &st, &attributes ) == -1) + { +@@ -2253,11 +2255,6 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I + if (class != FileNamesInformation) + { + if (st.st_dev != dir_data->id.dev) st.st_ino = 0; /* ignore inode if on a different device */ +- +- RtlInitUnicodeString( &name, names->long_name ); +- if (is_hidden_file( &name )) +- attributes |= FILE_ATTRIBUTE_HIDDEN; +- + fill_file_info( &st, attributes, info, class ); + } + +@@ -4219,7 +4216,6 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr, + info->AllocationSize = std.AllocationSize; + info->EndOfFile = std.EndOfFile; + info->FileAttributes = basic.FileAttributes; +- if (is_hidden_file( attr->ObjectName )) info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN; + } + free( unix_name ); + } +@@ -4250,10 +4246,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC + else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) + status = STATUS_INVALID_INFO_CLASS; + else +- { + status = fill_file_info( &st, attributes, info, FileBasicInformation ); +- if (is_hidden_file( attr->ObjectName )) info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN; +- } + free( unix_name ); + } + else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), status ); +-- +2.40.0 + diff --git a/patches/ntdll-hidden_file_attr/0004-ntdll-Only-infer-hidden-attribute-from-file-name-if-.patch b/patches/ntdll-hidden_file_attr/0004-ntdll-Only-infer-hidden-attribute-from-file-name-if-.patch new file mode 100644 index 00000000..6543f35c --- /dev/null +++ b/patches/ntdll-hidden_file_attr/0004-ntdll-Only-infer-hidden-attribute-from-file-name-if-.patch @@ -0,0 +1,49 @@ +From 0fa1566f7cab73de95f7d4b51b83766576a60727 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Thu, 30 Mar 2023 05:46:39 +0200 +Subject: [PATCH 4/6] ntdll: Only infer hidden attribute from file name if + xattr is not present. + +Signed-off-by: Torge Matthies +--- + dlls/ntdll/tests/file.c | 2 +- + dlls/ntdll/unix/file.c | 5 ++--- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c +index beaa4734931..cdd924a7226 100644 +--- a/dlls/ntdll/tests/file.c ++++ b/dlls/ntdll/tests/file.c +@@ -4107,7 +4107,7 @@ static void test_dotfile_file_attributes(void) + status = nt_get_file_attrs(filename, &attrs); + ok( status == STATUS_SUCCESS, "got %#lx\n", status ); + ok( attrs & FILE_ATTRIBUTE_SYSTEM, "got attributes %#lx\n", attrs ); +- todo_wine ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs ); ++ ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs ); + + status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); + ok( status == STATUS_SUCCESS, "got %#lx\n", status ); +diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c +index 59e96a88279..d127e113230 100644 +--- a/dlls/ntdll/unix/file.c ++++ b/dlls/ntdll/unix/file.c +@@ -1677,14 +1677,13 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) + } + *attr |= get_file_attributes( st ); + +- if (is_hidden_file( path )) +- *attr |= FILE_ATTRIBUTE_HIDDEN; +- + attr_len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, attr_data, sizeof(attr_data)-1 ); + if (attr_len != -1) + *attr |= parse_samba_dos_attrib_data( attr_data, attr_len ); + else + { ++ if (is_hidden_file( path )) ++ *attr |= FILE_ATTRIBUTE_HIDDEN; + if (errno == ENOTSUP) return ret; + #ifdef ENODATA + if (errno == ENODATA) return ret; +-- +2.40.0 + diff --git a/patches/ntdll-hidden_file_attr/0005-ntdll-Set-xattr-in-NtCreateFile-if-inferred-and-requ.patch b/patches/ntdll-hidden_file_attr/0005-ntdll-Set-xattr-in-NtCreateFile-if-inferred-and-requ.patch new file mode 100644 index 00000000..94f85877 --- /dev/null +++ b/patches/ntdll-hidden_file_attr/0005-ntdll-Set-xattr-in-NtCreateFile-if-inferred-and-requ.patch @@ -0,0 +1,132 @@ +From 2ad3cf7addcbf191db85365c0c52aa24935dcdf5 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Thu, 30 Mar 2023 05:46:39 +0200 +Subject: [PATCH 5/6] ntdll: Set xattr in NtCreateFile if inferred and + requested attributes don't match. + +And make sure it doesn't get deleted. + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53826 +Signed-off-by: Torge Matthies +--- + dlls/ntdll/tests/file.c | 2 +- + dlls/ntdll/unix/file.c | 26 +++++++++++++++++++------- + 2 files changed, 20 insertions(+), 8 deletions(-) + +diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c +index cdd924a7226..b96b2e5b072 100644 +--- a/dlls/ntdll/tests/file.c ++++ b/dlls/ntdll/tests/file.c +@@ -4094,7 +4094,7 @@ static void test_dotfile_file_attributes(void) + + status = nt_get_file_attrs(filename, &attrs); + ok( status == STATUS_SUCCESS, "got %#lx\n", status ); +- todo_wine ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs ); ++ ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs ); + + status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); + ok( status == STATUS_SUCCESS, "got %#lx\n", status ); +diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c +index d127e113230..5f5aa9be87c 100644 +--- a/dlls/ntdll/unix/file.c ++++ b/dlls/ntdll/unix/file.c +@@ -1600,11 +1600,11 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON + } + + +-static int fd_set_dos_attrib( int fd, UINT attr ) ++static int fd_set_dos_attrib( int fd, UINT attr, BOOL force_set ) + { + /* we only store the HIDDEN and SYSTEM attributes */ + attr &= XATTR_ATTRIBS_MASK; +- if (attr != 0) ++ if (force_set || attr != 0) + { + /* encode the attributes in Samba 3 ASCII format. Samba 4 has extended + * this format with more features, but retains compatibility with the +@@ -1618,7 +1618,7 @@ static int fd_set_dos_attrib( int fd, UINT attr ) + + + /* set the stat info and file attributes for a file (by file descriptor) */ +-static NTSTATUS fd_set_file_info( int fd, UINT attr ) ++static NTSTATUS fd_set_file_info( int fd, UINT attr, BOOL force_set_xattr ) + { + struct stat st; + +@@ -1637,7 +1637,8 @@ static NTSTATUS fd_set_file_info( int fd, UINT attr ) + } + if (fchmod( fd, st.st_mode ) == -1) return errno_to_status( errno ); + +- if (fd_set_dos_attrib( fd, attr ) == -1 && errno != ENOTSUP) ++ force_set_xattr = force_set_xattr || st.st_nlink > 1; ++ if (fd_set_dos_attrib( fd, attr, force_set_xattr ) == -1 && errno != ENOTSUP) + WARN( "Failed to set extended attribute " SAMBA_XATTR_DOS_ATTRIB ". errno %d (%s)\n", + errno, strerror( errno ) ); + +@@ -3963,6 +3964,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU + OBJECT_ATTRIBUTES new_attr; + UNICODE_STRING nt_name; + char *unix_name; ++ BOOL name_hidden = FALSE; + BOOL created = FALSE; + unsigned int status; + +@@ -4005,6 +4007,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU + + if (status == STATUS_SUCCESS) + { ++ name_hidden = is_hidden_file( unix_name ); + status = open_unix_file( handle, unix_name, access, &new_attr, attributes, + sharing, disposition, options, ea_buffer, ea_length ); + free( unix_name ); +@@ -4032,14 +4035,15 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU + break; + } + +- if (io->Information == FILE_CREATED && (attributes & XATTR_ATTRIBS_MASK)) ++ if (io->Information == FILE_CREATED && ++ ((attributes & XATTR_ATTRIBS_MASK) || name_hidden)) + { + int fd, needs_close; + + /* set any DOS extended attributes */ + if (!server_get_unix_fd( *handle, 0, &fd, &needs_close, NULL, NULL )) + { +- if (fd_set_dos_attrib( fd, attributes ) == -1 && errno != ENOTSUP) ++ if (fd_set_dos_attrib( fd, attributes, TRUE ) == -1 && errno != ENOTSUP) + WARN( "Failed to set extended attribute " SAMBA_XATTR_DOS_ATTRIB ". errno %d (%s)", + errno, strerror( errno ) ); + if (needs_close) close( fd ); +@@ -4561,10 +4565,14 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, + { + const FILE_BASIC_INFORMATION *info = ptr; + LARGE_INTEGER mtime, atime; ++ char *unix_name; + + if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) + return io->u.Status = status; + ++ if ((status = server_get_unix_name( handle, &unix_name ))) ++ unix_name = NULL; ++ + mtime.QuadPart = info->LastWriteTime.QuadPart == -1 ? 0 : info->LastWriteTime.QuadPart; + atime.QuadPart = info->LastAccessTime.QuadPart == -1 ? 0 : info->LastAccessTime.QuadPart; + +@@ -4572,9 +4580,13 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, + status = set_file_times( fd, &mtime, &atime ); + + if (status == STATUS_SUCCESS && info->FileAttributes) +- status = fd_set_file_info( fd, info->FileAttributes ); ++ { ++ BOOL force_xattr = unix_name && is_hidden_file( unix_name ); ++ status = fd_set_file_info( fd, info->FileAttributes, force_xattr ); ++ } + + if (needs_close) close( fd ); ++ free( unix_name ); + } + else status = STATUS_INVALID_PARAMETER_3; + break; +-- +2.40.0 + diff --git a/patches/ntdll-hidden_file_attr/0006-ntdll-tests-Increase-margins-in-timer-merging-tests.patch b/patches/ntdll-hidden_file_attr/0006-ntdll-tests-Increase-margins-in-timer-merging-tests.patch new file mode 100644 index 00000000..d4c97307 --- /dev/null +++ b/patches/ntdll-hidden_file_attr/0006-ntdll-tests-Increase-margins-in-timer-merging-tests.patch @@ -0,0 +1,43 @@ +From 6fa8d2eea71223e52ab957247cb91011404ee381 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Thu, 30 Mar 2023 05:46:39 +0200 +Subject: [PATCH 6/6] ntdll/tests: Increase margins in timer merging tests. + +This test failed in the GitLab test runner. + +Signed-off-by: Torge Matthies +--- + dlls/ntdll/tests/threadpool.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c +index 168f00c2852..c23157d3207 100644 +--- a/dlls/ntdll/tests/threadpool.c ++++ b/dlls/ntdll/tests/threadpool.c +@@ -1563,18 +1563,18 @@ static void test_tp_window_length(void) + info2.ticks = 0; + + NtQuerySystemTime( &when ); +- when.QuadPart += (ULONGLONG)250 * 10000; ++ when.QuadPart += (ULONGLONG)500 * 10000; + pTpSetTimer(timer2, &when, 0, 0); +- Sleep(50); +- when.QuadPart -= (ULONGLONG)150 * 10000; +- pTpSetTimer(timer1, &when, 0, 75); ++ Sleep(100); ++ when.QuadPart -= (ULONGLONG)300 * 10000; ++ pTpSetTimer(timer1, &when, 0, 150); + + result = WaitForSingleObject(semaphore, 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + result = WaitForSingleObject(semaphore, 1000); + ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result); + ok(info1.ticks != 0 && info2.ticks != 0, "expected that ticks are nonzero\n"); +- ok(info2.ticks >= info1.ticks + 75 || broken(info2.ticks < info1.ticks + 75) /* Win 2008 */, ++ ok(info2.ticks >= info1.ticks + 150 || broken(info2.ticks < info1.ticks + 150) /* Win 2008 */, + "expected that timers are not merged\n"); + + /* timers will be merged */ +-- +2.40.0 + diff --git a/patches/ntdll-hidden_file_attr/definition b/patches/ntdll-hidden_file_attr/definition new file mode 100644 index 00000000..bec02c1a --- /dev/null +++ b/patches/ntdll-hidden_file_attr/definition @@ -0,0 +1,2 @@ +Fixes: [53826] Attempting to install / update battle.net fails with Qt error +MR: [1148] ntdll: Mark created files beginning with a dot as not hidden.