DroidDeck-Proton 11-11.7: don't report Wine's own DLLs as read-only (MapleStory) (#6)

This commit is contained in:
MaxsTechReview authored and GitHub committed 2026-10-25 23:56:07 -04:00
1 parent 776396b88c
commit 1eb16860c8
5 files changed
+88 -3

No files matched your search

+1
View File
@@ -260,6 +260,7 @@ jobs:
has include/wine/asm.h "ldr x16, [x16, #8]"
has server/file.c "security_unix_uid_to_sid( file_sd_owner( unix_fd, &st ) )"
has dlls/ntdll/sync.c "ret = wait_for_wake( &entry, timeout );"
has dlls/ntdll/unix/file.c "is_wine_install_fd( fd )"
has include/wine/asm.h "__ASM_NAME(\"__wine_syscall_dispatcher\")"
has dlls/ntdll/unix/syscall.c "(ULONG_PTR *)__wine_syscall_dispatcher"
has dlls/ntdll/unix/syscall.c "ntdll_arm64ec_sync_syscall_dispatch"
+4 -2
View File
@@ -39,7 +39,7 @@ Wine source: [`The412Banner/proton-wine`](https://github.com/The412Banner/proton
_Formerly Banner-Proton; releases up to 11-7.2 used the old name._
<details>
<summary><b>Pins (11-11.6)</b></summary>
<summary><b>Pins (11-11.7)</b></summary>
| Component | Commit |
|---|---|
@@ -56,6 +56,7 @@ tier 7. 11-11.3 is 11-11.2 plus the WoW ARM64EC game patch. 11-11.4 is 11-11.3 p
11-11.5 is 11-11.4 plus the 32-bit lost wake fix (Battle.net freezes). 11-11.6 is 11-11.5 plus the winex11
offscreen-check cache for DroidDeck's Performance mode: off unless `WINE_OFFSCREEN_CHECK_MS` is set (DroidDeck sets
100 only with Performance mode on), so the present path does not ask wineserver for the window's relatives twice a frame.
11-11.7 is 11-11.6 plus Wine's own DLLs no longer reported read-only (MapleStory copies ws2_32.dll and crashed).
</details>
@@ -236,7 +237,8 @@ instead of `patches/protonprep-valve-staging.sh` and
[CachyOS](https://github.com/CachyOS/proton-cachyos) · NelloKudo · Etaash Mathamsetty ·
Elizabeth Figura (esync, fsync, ntsync) · maxjivi05 / DroidDeck (droiddeck-esync) ·
Arihany and GameNative (SD card fixes) · Brendan Shanks, utkarshdalal, whatsupbros
(.NET fix) · arusiasotto (WoW ARM64EC fix) · FEX-Emu, DXVK, vkd3d-proton, dxvk-nvapi, d7vk and every
(.NET fix) · arusiasotto (WoW ARM64EC fix) · oldschoola
([linux_maplestory](https://github.com/oldschoola/linux_maplestory), MapleStory research) · FEX-Emu, DXVK, vkd3d-proton, dxvk-nvapi, d7vk and every
patch author named in the commit history.
## License
+1 -1
View File
@@ -1 +1 @@
11-11.6
11-11.7
@@ -10,3 +10,4 @@ apply() {
apply "$root/patches/game-patches/wow-forever-arm64ec-ntdll.patch"
apply "$root/patches/wine-hotfixes/pending/server-android-shared-storage-owner.patch"
apply "$root/patches/wine-hotfixes/pending/ntdll-i386-recover-lost-wake-on-address.patch"
apply "$root/patches/wine-hotfixes/pending/ntdll-wine-files-not-readonly.patch"
@@ -0,0 +1,81 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: maxjivi05 <[email protected]>
Date: Sun, 25 Oct 2026 22:23:25 -0400
Subject: [PATCH] ntdll: Don't report Wine's own installed files as read-only.
Proton ships its builtin modules read-only (the dist step runs chmod a-w
on lib/wine), and the prefix's system32 and syswow64 entries are
symlinks to them, so GetFileAttributesW() and GetFileInformationByHandle()
report FILE_ATTRIBUTE_READONLY for every system DLL. On Windows the
system DLLs are not read-only.
Copying one of them carries the attribute over: CopyFileW() creates the
copy read-only, and opening the copy for writing then fails with
STATUS_ACCESS_DENIED. MapleStory (Steam app 216150) copies ws2_32.dll
into %TEMP% and opens the copy read/write while it starts; on ARM64
Proton it then uses the invalid handle and dies with an access violation
in its protector before any window shows up.
Regular files whose real path is inside Wine's installation (the same
lib/wine, lib64/wine and share/wine rule is_wine_file() uses) are now
reported without FILE_ATTRIBUTE_READONLY. Their unix permissions still
refuse writes, so the installation stays protected; only copies come out
writable, as they would on Windows.
---
dlls/ntdll/unix/file.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index cb318149ed..5b4d6c8113 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -1675,6 +1675,31 @@ static BOOL fd_is_mount_point( int fd, const struct stat *st )
static unsigned int server_get_unix_name( HANDLE handle, char **unix_name );
+static BOOL is_wine_unix_name( const char *name )
+{
+ return strstr( name, "/lib/wine/" ) || strstr( name, "/lib64/wine/" ) || strstr( name, "/share/wine/" );
+}
+
+static BOOL is_wine_install_path( const char *path )
+{
+ char *real = realpath( path, NULL );
+ BOOL ret = real && is_wine_unix_name( real );
+
+ free( real );
+ return ret;
+}
+
+static BOOL is_wine_install_fd( int fd )
+{
+ char link[32], target[PATH_MAX];
+ ssize_t len;
+
+ snprintf( link, sizeof(link), "/proc/self/fd/%d", fd );
+ if ((len = readlink( link, target, sizeof(target) - 1 )) <= 0) return FALSE;
+ target[len] = 0;
+ return is_wine_unix_name( target );
+}
+
/* get the stat info and file attributes for a file (by file descriptor) */
static int fd_get_file_info( HANDLE handle, int fd, unsigned int options,
struct stat *st, ULONG *attr, ULONG *reparse_tag )
@@ -1687,6 +1712,8 @@ static int fd_get_file_info( HANDLE handle, int fd, unsigned int options,
ret = fstat( fd, st );
if (ret == -1) return ret;
*attr |= get_file_attributes( st );
+ if ((*attr & FILE_ATTRIBUTE_READONLY) && S_ISREG( st->st_mode ) && is_wine_install_fd( fd ))
+ *attr &= ~FILE_ATTRIBUTE_READONLY;
if (reparse_tag) *reparse_tag = 0;
/* consider mount points to be reparse points (IO_REPARSE_TAG_MOUNT_POINT) */
if (options & FILE_OPEN_REPARSE_POINT)
@@ -1837,6 +1864,8 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr, ULONG
free( parent_path );
}
*attr |= get_file_attributes( st );
+ if ((*attr & FILE_ATTRIBUTE_READONLY) && S_ISREG( st->st_mode ) && is_wine_install_path( path ))
+ *attr &= ~FILE_ATTRIBUTE_READONLY;
attr_len = xattr_get( path, XATTR_REPARSE, buffer, sizeof(buffer) );
if (attr_len >= 0 && attr_len >= sizeof(ULONG))