From b319d0e8e35f0e9b06e9863400a66f64f155bda0 Mon Sep 17 00:00:00 2001
From: Steve Lhomme <robux4@ycbcr.xyz>
Date: Mon, 31 Mar 2025 08:04:34 +0200
Subject: [PATCH 1/2] win32/spawn: use _open directly

This is what vlc_open uses but we don't need to convert the string
or parse extra flags.
---
 src/win32/spawn.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/win32/spawn.c b/src/win32/spawn.c
index 591ba09fd6a4..2fe45c4f24de 100755
--- a/src/win32/spawn.c
+++ b/src/win32/spawn.c
@@ -116,7 +116,7 @@ static int vlc_spawn_inner(pid_t *restrict pid, const char *path,
     char *cmdline = NULL;
 
     if (fdv[0] == -1 || fdv[1] == -1) {
-        nulfd = vlc_open("\\\\.\\NUL", O_RDWR);
+        nulfd = _open ("\\\\.\\NUL", O_RDWR);
         if (unlikely(nulfd == -1))
             goto error;
 
-- 
GitLab


From 091bb687cc5f61716fbad3b4702818340ed0f1e3 Mon Sep 17 00:00:00 2001
From: Steve Lhomme <robux4@ycbcr.xyz>
Date: Mon, 31 Mar 2025 09:02:37 +0200
Subject: [PATCH 2/2] win32/filesystem: use CreateFileW with FILE_SHARE_DELETE
 in vlc_open()

So the file can be renamed while we read it [^1].

The file permission creation mode is not used anymore.
Only 0666 and 0600 were used.

Fixes #19700.

[^1]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#file_share_delete
---
 src/win32/filesystem.c | 65 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 55 insertions(+), 10 deletions(-)

diff --git a/src/win32/filesystem.c b/src/win32/filesystem.c
index ea953cc34537..79dbffc3d3dc 100644
--- a/src/win32/filesystem.c
+++ b/src/win32/filesystem.c
@@ -65,24 +65,46 @@ static wchar_t *widen_path (const char *path)
 
 int vlc_open (const char *filename, int flags, ...)
 {
-    int mode = 0;
-    va_list ap;
+    DWORD dwDesiredAccess, dwCreationDisposition, dwFlagsAndAttributes;
 
     flags |= O_NOINHERIT; /* O_CLOEXEC */
     /* Defaults to binary mode */
     if ((flags & O_TEXT) == 0)
         flags |= O_BINARY;
 
-    va_start (ap, flags);
+    if (flags & O_WRONLY)
+    {
+        dwDesiredAccess = GENERIC_WRITE;
+    }
+    else if (flags & O_RDWR)
+    {
+        dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
+    }
+    else // if (flags & O_RDONLY)
+    {
+        dwDesiredAccess = GENERIC_READ;
+    }
+
     if (flags & O_CREAT)
     {
-        int unixmode = va_arg(ap, int);
-        if (unixmode & 0444)
-            mode |= _S_IREAD;
-        if (unixmode & 0222)
-            mode |= _S_IWRITE;
+        if (flags & O_EXCL)
+            dwCreationDisposition = CREATE_NEW;
+        else
+            dwCreationDisposition = CREATE_ALWAYS;
     }
-    va_end (ap);
+    else if (flags & O_TRUNC)
+    {
+        dwCreationDisposition = TRUNCATE_EXISTING;
+    }
+    else
+    {
+        dwCreationDisposition = OPEN_EXISTING;
+    }
+
+    dwFlagsAndAttributes = FILE_FLAG_RANDOM_ACCESS | SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION;
+
+    // if (flags & O_NONBLOCK)
+    //     dwFlagsAndAttributes |= FILE_FLAG_OVERLAPPED;
 
     /*
      * open() cannot open files with non-“ANSI” characters on Windows.
@@ -92,8 +114,31 @@ int vlc_open (const char *filename, int flags, ...)
     if (wpath == NULL)
         return -1;
 
-    int fd = _wopen (wpath, flags, mode);
+    HANDLE h;
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+    h = CreateFileW(wpath, dwDesiredAccess,
+        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+        NULL, dwCreationDisposition,
+        dwFlagsAndAttributes, NULL);
+#else
+    CREATEFILE2_EXTENDED_PARAMETERS params = { 0 };
+    params.dwSize = sizeof(params);
+    params.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF;
+    params.dwFileFlags = dwFlagsAndAttributes & ~(0xFFFF | SECURITY_VALID_SQOS_FLAGS);
+    params.dwSecurityQosFlags = dwFlagsAndAttributes & SECURITY_VALID_SQOS_FLAGS;
+    h = CreateFile2(wpath, dwDesiredAccess,
+        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+        dwCreationDisposition,
+        &params);
+#endif
     free (wpath);
+    if (h == INVALID_HANDLE_VALUE)
+        return -1;
+    int fd = _open_osfhandle((intptr_t)h, flags);
+    if (unlikely(fd == -1))
+    {
+        CloseHandle(h);
+    }
     return fd;
 }
 
-- 
GitLab