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, + ¶ms); +#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