[PATCH v6 0/4] MR8030: Draft: wineserver: Allow NtOpenFile with read-only files.
Co-authored-by: Bernhard Übelacker <bernhardu@mailbox.org> -- v6: server: Open file read-only when writing only attributes. server: Open code FILE_UNIX_READ_ACCESS flags. server: Open code FILE_UNIX_WRITE_ACCESS flags. ntdll/tests: Test opening read-only files only for read/write 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 ead174f0d1f..fe23489c02f 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -5954,6 +5954,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: Joel Holdsworth <joel@airwebreathe.org.uk> --- server/fd.c | 5 +++-- server/file.h | 3 --- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/server/fd.c b/server/fd.c index efb6e8e76b9..9982d57aeb8 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1979,7 +1979,8 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam flags &= ~(O_CREAT | O_EXCL | O_TRUNC); } - if ((access & FILE_UNIX_WRITE_ACCESS) && !(options & FILE_DIRECTORY_FILE)) + if ((access & (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)) && + !(options & FILE_DIRECTORY_FILE)) { if (access & FILE_UNIX_READ_ACCESS) rw_mode = O_RDWR; else rw_mode = O_WRONLY; @@ -1991,7 +1992,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam /* if we tried to open a directory for write access, retry read-only */ if (errno == EISDIR) { - if ((access & FILE_UNIX_WRITE_ACCESS) || (flags & O_CREAT)) + if ((access & (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)) || (flags & O_CREAT)) fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode ); } diff --git a/server/file.h b/server/file.h index e1485e4d5fc..7a7c599bd6b 100644 --- a/server/file.h +++ b/server/file.h @@ -296,9 +296,6 @@ 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) -/* access rights that require Unix write permission */ -#define FILE_UNIX_WRITE_ACCESS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA) - /* magic file access rights for mappings */ #define FILE_MAPPING_IMAGE 0x80000000 /* set for SEC_IMAGE mappings */ #define FILE_MAPPING_WRITE 0x40000000 /* set for writable shared mappings */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8030
From: Joel Holdsworth <joel@airwebreathe.org.uk> --- server/fd.c | 2 +- server/file.h | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/server/fd.c b/server/fd.c index 9982d57aeb8..6e9a975f342 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1982,7 +1982,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam if ((access & (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)) && !(options & FILE_DIRECTORY_FILE)) { - if (access & FILE_UNIX_READ_ACCESS) rw_mode = O_RDWR; + if (access & (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)) rw_mode = O_RDWR; else rw_mode = O_WRONLY; } else rw_mode = O_RDONLY; diff --git a/server/file.h b/server/file.h index 7a7c599bd6b..fd691802b79 100644 --- a/server/file.h +++ b/server/file.h @@ -292,10 +292,6 @@ static inline int async_queued( struct async_queue *queue ) return !list_empty( &queue->queue ); } - -/* access rights that require Unix read permission */ -#define FILE_UNIX_READ_ACCESS (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA) - /* magic file access rights for mappings */ #define FILE_MAPPING_IMAGE 0x80000000 /* set for SEC_IMAGE mappings */ #define FILE_MAPPING_WRITE 0x40000000 /* set for writable shared mappings */ -- 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/fd.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index fe23489c02f..aedddc2b156 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -5956,12 +5956,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/fd.c b/server/fd.c index 6e9a975f342..ab7943d9e80 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1979,7 +1979,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam flags &= ~(O_CREAT | O_EXCL | O_TRUNC); } - if ((access & (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)) && + if ((access & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(options & FILE_DIRECTORY_FILE)) { if (access & (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)) rw_mode = O_RDWR; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8030
* Rebased on `master`. * Both `FILE_UNIX_READ_ACCESS` and `FILE_UNIX_WRITE_ACCESS` access are now open-coded in server. They were virtually unused and only obscured the behaviour of the code. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8030#note_134104
I think this should be ready for acceptance.
Probably should be no longer marked as "draft" then. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8030#note_134106
On Fri Mar 27 20:56:58 2026 +0000, Elizabeth Figura wrote:
I think this should be ready for acceptance. Probably should be no longer marked as "draft" then. Oops! - fixed now.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8030#note_134136
Both FILE_UNIX_READ_ACCESS and FILE_UNIX_WRITE_ACCESS access are now open-coded in server. They were virtually unused and only obscured the behaviour of the code.
As Jinoh predicted, the usage of write access flags is now inconsistent. I'm not sure this was an improvement. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8030#note_134517
participants (4)
-
Alexandre Julliard (@julliard) -
Elizabeth Figura (@zfigura) -
Joel Holdsworth -
Joel Holdsworth (@jhol)