[PATCH v10 0/4] MR8030: wineserver: Allow NtOpenFile with read-only files.
Co-authored-by: Bernhard Übelacker <bernhardu@mailbox.org> -- v10: server: Don't require Unix read permission for reading only attributes. server: Open file read-only when writing only attributes. https://gitlab.winehq.org/wine/wine/-/merge_requests/8030
From: Joel Holdsworth <joel@airwebreathe.org.uk> Co-authored-by: Bernhard Übelacker <bernhardu@mailbox.org> --- dlls/ntdll/tests/file.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 6268870bc08..817a9cd818a 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -5951,6 +5951,16 @@ static void test_file_readonly_access(void) status = pNtOpenFile(&handle, GENERIC_WRITE, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status); + /* NtOpenFile FILE_{READ,WRITE}_ATTRIBUTES */ + status = pNtOpenFile(&handle, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); + todo_wine ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status); + CloseHandle(handle); + + /* NtOpenFile FILE_{READ,WRITE}_EA */ + status = pNtOpenFile(&handle, FILE_READ_EA | FILE_WRITE_EA, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); + todo_wine ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status); + CloseHandle(handle); + /* NtOpenFile DELETE without FILE_DELETE_ON_CLOSE */ status = pNtOpenFile(&handle, DELETE, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8030
From: Bernhard Übelacker <bernhardu@mailbox.org> --- dlls/ntdll/tests/file.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 817a9cd818a..5788761228a 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -5951,6 +5951,16 @@ static void test_file_readonly_access(void) status = pNtOpenFile(&handle, GENERIC_WRITE, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status); + /* NtOpenFile FILE_READ_ATTRIBUTES with FILE_WRITE_DATA */ + status = pNtOpenFile(&handle, FILE_READ_ATTRIBUTES | FILE_WRITE_DATA, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); + ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status); + CloseHandle(handle); + + /* NtOpenFile FILE_READ_ATTRIBUTES with FILE_APPEND_DATA */ + status = pNtOpenFile(&handle, FILE_READ_ATTRIBUTES | FILE_APPEND_DATA, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); + ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status); + CloseHandle(handle); + /* NtOpenFile FILE_{READ,WRITE}_ATTRIBUTES */ status = pNtOpenFile(&handle, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); todo_wine ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8030
From: Joel Holdsworth <joel@airwebreathe.org.uk> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56925 --- dlls/ntdll/tests/file.c | 4 ++-- server/file.c | 4 ++-- server/file.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 5788761228a..f479b03c120 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -5963,12 +5963,12 @@ static void test_file_readonly_access(void) /* NtOpenFile FILE_{READ,WRITE}_ATTRIBUTES */ status = pNtOpenFile(&handle, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); - todo_wine ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status); CloseHandle(handle); /* NtOpenFile FILE_{READ,WRITE}_EA */ status = pNtOpenFile(&handle, FILE_READ_EA | FILE_WRITE_EA, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE); - todo_wine ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status); + ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status); CloseHandle(handle); /* NtOpenFile DELETE without FILE_DELETE_ON_CLOSE */ diff --git a/server/file.c b/server/file.c index 7b3324e9938..2a7ee5381ee 100644 --- a/server/file.c +++ b/server/file.c @@ -232,12 +232,12 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si { case FILE_CREATE: flags = O_CREAT | O_EXCL; break; case FILE_OVERWRITE_IF: /* FIXME: the difference is whether we trash existing attr or not */ - access |= FILE_WRITE_ATTRIBUTES; + access |= FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES; case FILE_SUPERSEDE: flags = O_CREAT | O_TRUNC; break; case FILE_OPEN: flags = 0; break; case FILE_OPEN_IF: flags = O_CREAT; break; case FILE_OVERWRITE: flags = O_TRUNC; - access |= FILE_WRITE_ATTRIBUTES; break; + access |= FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES; break; default: set_error( STATUS_INVALID_PARAMETER ); goto done; } diff --git a/server/file.h b/server/file.h index e1485e4d5fc..b77cffbb442 100644 --- a/server/file.h +++ b/server/file.h @@ -297,7 +297,7 @@ static inline int async_queued( struct async_queue *queue ) #define FILE_UNIX_READ_ACCESS (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA) /* access rights that require Unix write permission */ -#define FILE_UNIX_WRITE_ACCESS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA) +#define FILE_UNIX_WRITE_ACCESS (FILE_WRITE_DATA|FILE_APPEND_DATA) /* magic file access rights for mappings */ #define FILE_MAPPING_IMAGE 0x80000000 /* set for SEC_IMAGE mappings */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8030
From: Joel Holdsworth <joel@airwebreathe.org.uk> --- server/file.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/file.h b/server/file.h index b77cffbb442..12e9158a0a4 100644 --- a/server/file.h +++ b/server/file.h @@ -294,7 +294,7 @@ static inline int async_queued( struct async_queue *queue ) /* access rights that require Unix read permission */ -#define FILE_UNIX_READ_ACCESS (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA) +#define FILE_UNIX_READ_ACCESS (FILE_READ_DATA) /* access rights that require Unix write permission */ #define FILE_UNIX_WRITE_ACCESS (FILE_WRITE_DATA|FILE_APPEND_DATA) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8030
We have a clean build now. The only issues reported by `test-linux-32` appear to be pre-existing flakey tests. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8030#note_139601
Hello Joel, the patch 71994a6b seems to cause the test kernel32:actctx to fail, [link to the failure](https://gitlab.winehq.org/wine/wine/-/jobs/265476#L1167), and seems not to be some flakyness. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8030#note_140011
On Fri May 15 15:03:20 2026 +0000, Bernhard Übelacker wrote:
Hello Joel, the patch 71994a6b seems to cause the test kernel32:actctx to fail, [link to the failure](https://gitlab.winehq.org/wine/wine/-/jobs/265476#L1167), and seems not to be some flakyness. Yeah, looks like `access` is used not only for Unix perm checks, but also for share locks.
The test is failing because `CREATE_ALWAYS` forces opening with `FILE_WRITE_DATA`, which conflicts with `CreateActCtx` which doesn't share the file for writing. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8030#note_140034
On Fri May 15 15:03:20 2026 +0000, Jinoh Kang wrote:
Yeah, looks like `access` is used not only for Unix perm checks, but also for share locks. The test is failing because `CREATE_ALWAYS` forces opening with `FILE_WRITE_DATA`, which conflicts with `CreateActCtx` which doesn't share the file for writing. (The test keeps the handle open until the end; this is deliberate as indicated by `test_CreateActCtx_share_mode`'s name. I wrote that test.)
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8030#note_140035
participants (5)
-
Bernhard Übelacker -
Bernhard Übelacker (@bernhardu) -
Jinoh Kang (@iamahuman) -
Joel Holdsworth -
Joel Holdsworth (@jhol)