Also unifies hidden file handling.
Fixes bug [53826](https://bugs.winehq.org/show_bug.cgi?id=53826).
From: Torge Matthies tmatthies@codeweavers.com
--- dlls/ntdll/tests/file.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index c011733626f..6865abd9568 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3971,6 +3971,32 @@ static void test_file_attribute_tag_information(void) CloseHandle( h ); }
+static void test_dotfile_file_attributes(void) +{ + char temppath[MAX_PATH], filename[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" ); + if (h == INVALID_HANDLE_VALUE) return; + + 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", info.FileAttributes ); + + 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; @@ -5391,6 +5417,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();
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- 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 8a599a289f8..cf0465ab199 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1281,7 +1281,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] != '\'))); }
@@ -2202,6 +2202,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) { @@ -2231,8 +2232,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 );
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/ntdll/tests/file.c | 2 +- dlls/ntdll/unix/file.c | 97 ++++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 42 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 6865abd9568..347a86406ff 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3992,7 +3992,7 @@ static void test_dotfile_file_attributes(void)
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 ); + todo_wine ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
CloseHandle( h ); } diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index cf0465ab199..4826519558e 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1268,20 +1268,20 @@ static BOOLEAN get_dir_case_sensitivity( const char *dir )
/*********************************************************************** - * is_hidden_file + * is_hidden_file_unix * - * 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_unix( 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--; - return (p < end && p + 1 != end && p[0] == '.' && p[1] != '\' && (p[1] != '.' || (p + 2 != end && p[2] != '\'))); + 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] != '/'))); }
@@ -1549,7 +1549,7 @@ static BOOL fd_is_mount_point( int fd, const struct stat *st )
/* get the stat info and file attributes for a file (by file descriptor) */ -static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULONG *attr ) +static int fd_get_file_info( int fd, const char *unix_name, unsigned int options, struct stat *st, ULONG *attr ) { char attr_data[65]; int attr_len, ret; @@ -1562,6 +1562,9 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
+ if (unix_name && is_hidden_file_unix( unix_name )) + *attr |= FILE_ATTRIBUTE_HIDDEN; + attr_len = xattr_fget( fd, SAMBA_XATTR_DOS_ATTRIB, attr_data, sizeof(attr_data)-1 ); if (attr_len != -1) *attr |= parse_samba_dos_attrib_data( attr_data, attr_len ); @@ -1655,6 +1658,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) } *attr |= get_file_attributes( st );
+ if (is_hidden_file_unix( 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 ); @@ -2202,7 +2208,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) { @@ -2231,11 +2236,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 ); }
@@ -4192,7 +4192,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 ); } @@ -4223,10 +4222,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 ); @@ -4335,18 +4331,26 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, switch (class) { case FileBasicInformation: - if (fd_get_file_info( fd, options, &st, &attr ) == -1) - status = errno_to_status( errno ); - else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) - status = STATUS_INVALID_INFO_CLASS; - else - fill_file_info( &st, attr, ptr, class ); - break; + { + char *unix_name; + + if (server_get_unix_name( handle, &unix_name )) + unix_name = NULL; + + if (fd_get_file_info( fd, unix_name, options, &st, &attr ) == -1) + status = errno_to_status( errno ); + else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) + status = STATUS_INVALID_INFO_CLASS; + else + fill_file_info( &st, attr, ptr, class ); + free( unix_name ); + break; + } case FileStandardInformation: { FILE_STANDARD_INFORMATION *info = ptr;
- if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else { fill_file_info( &st, attr, info, class ); @@ -4363,7 +4367,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileInternalInformation: - if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else fill_file_info( &st, attr, ptr, class ); break; case FileEaInformation: @@ -4373,7 +4377,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileEndOfFileInformation: - if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else fill_file_info( &st, attr, ptr, class ); break; case FileAllInformation: @@ -4381,10 +4385,13 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, FILE_ALL_INFORMATION *info = ptr; char *unix_name;
- if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + status = server_get_unix_name( handle, &unix_name ); + if (fd_get_file_info( fd, unix_name, options, &st, &attr ) == -1) status = errno_to_status( errno ); + else if (status) + break; else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) status = STATUS_INVALID_INFO_CLASS; - else if (!(status = server_get_unix_name( handle, &unix_name ))) + else { LONG name_len = len - FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
@@ -4397,9 +4404,9 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, info->AlignmentInformation.AlignmentRequirement = 1; /* FIXME */
status = fill_name_info( unix_name, &info->NameInformation, &name_len ); - free( unix_name ); io->Information = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + name_len; } + free( unix_name ); } break; case FileMailslotQueryInformation: @@ -4489,7 +4496,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileIdInformation: - if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else { struct mountmgr_unix_drive drive; @@ -4503,16 +4510,24 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileAttributeTagInformation: - if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); - else { - FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr; - info->FileAttributes = attr; - info->ReparseTag = 0; /* FIXME */ - if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, &st )) - info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + char *unix_name; + + if (server_get_unix_name( handle, &unix_name )) + unix_name = NULL; + + if (fd_get_file_info( fd, unix_name, options, &st, &attr ) == -1) status = errno_to_status( errno ); + else + { + FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr; + info->FileAttributes = attr; + info->ReparseTag = 0; /* FIXME */ + if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, &st )) + info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + } + free( unix_name ); + break; } - break; default: FIXME("Unsupported class (%d)\n", class); status = STATUS_NOT_IMPLEMENTED;
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/ntdll/unix/file.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 4826519558e..e4c00073fdc 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1562,14 +1562,13 @@ static int fd_get_file_info( int fd, const char *unix_name, unsigned int options if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
- if (unix_name && is_hidden_file_unix( unix_name )) - *attr |= FILE_ATTRIBUTE_HIDDEN; - attr_len = xattr_fget( fd, 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 (unix_name && is_hidden_file_unix( unix_name )) + *attr |= FILE_ATTRIBUTE_HIDDEN; if (errno == ENOTSUP) return ret; #ifdef ENODATA if (errno == ENODATA) return ret; @@ -1658,14 +1657,13 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) } *attr |= get_file_attributes( st );
- if (is_hidden_file_unix( 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_unix( path )) + *attr |= FILE_ATTRIBUTE_HIDDEN; if (errno == ENOTSUP) return ret; #ifdef ENODATA if (errno == ENODATA) return ret;
From: Torge Matthies tmatthies@codeweavers.com
And make sure it doesn't get deleted.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53826 Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/ntdll/tests/file.c | 4 ++-- dlls/ntdll/unix/file.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 347a86406ff..2086bd88e4f 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3988,11 +3988,11 @@ 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", info.FileAttributes ); + ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); ok( status == STATUS_SUCCESS, "got %#lx\n", status ); - todo_wine ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes ); + ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
CloseHandle( h ); } diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index e4c00073fdc..435aae7ef32 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1580,11 +1580,20 @@ static int fd_get_file_info( int fd, const char *unix_name, unsigned int options }
-static int fd_set_dos_attrib( int fd, ULONG attr ) +static BOOL fd_has_forced_dos_attrib( int fd ) +{ + char attr_data[65]; + int attr_len; + attr_len = xattr_fget( fd, SAMBA_XATTR_DOS_ATTRIB, attr_data, sizeof(attr_data)-1 ); + return attr_len != -1 && parse_samba_dos_attrib_data( attr_data, attr_len ) == 0; +} + + +static int fd_set_dos_attrib( int fd, ULONG attr, BOOL force ) { /* we only store the HIDDEN and SYSTEM attributes */ attr &= XATTR_ATTRIBS_MASK; - if (attr != 0) + if (force || attr != 0) { /* encode the attributes in Samba 3 ASCII format. Samba 4 has extended * this format with more features, but retains compatibility with the @@ -1598,7 +1607,7 @@ static int fd_set_dos_attrib( int fd, ULONG attr )
/* set the stat info and file attributes for a file (by file descriptor) */ -NTSTATUS fd_set_file_info( int fd, ULONG attr ) +NTSTATUS fd_set_file_info( int fd, ULONG attr, BOOL force_xattr ) { struct stat st;
@@ -1617,7 +1626,8 @@ NTSTATUS fd_set_file_info( int fd, ULONG attr ) } if (fchmod( fd, st.st_mode ) == -1) return errno_to_status( errno );
- if (fd_set_dos_attrib( fd, attr ) == -1 && errno != ENOTSUP) + force_xattr ||= st.st_nlink > 1 || fd_has_forced_dos_attrib( fd ); + if (fd_set_dos_attrib( fd, attr, force_xattr ) == -1 && errno != ENOTSUP) WARN( "Failed to set extended attribute " SAMBA_XATTR_DOS_ATTRIB ". errno %d (%s)\n", errno, strerror( errno ) );
@@ -3943,6 +3953,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; NTSTATUS status;
@@ -3985,6 +3996,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
if (status == STATUS_SUCCESS) { + name_hidden = is_hidden_file_unix(unix_name); status = open_unix_file( handle, unix_name, access, &new_attr, attributes, sharing, disposition, options, ea_buffer, ea_length ); free( unix_name ); @@ -4012,14 +4024,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 ); @@ -4555,10 +4568,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;
@@ -4566,9 +4583,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( 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;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=125345
Your paranoid android.
=== debian11 (build log) ===
../wine/dlls/ntdll/unix/file.c:1629:19: error: expected expression before ���=��� token Task: The win32 Wine build failed
=== debian11 (build log) ===
../wine/dlls/ntdll/unix/file.c:1629:19: error: expected expression before ���=��� token Task: The wow64 Wine build failed