mingw_open_existing: handle directories better

CreateFileW() requires FILE_FLAG_BACKUP_SEMANTICS to create a directory handle [1] and errors out with ERROR_ACCESS_DENIED without this flag. Fall back to accessing Directory handles this way. [1] https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#directories This fixes https://github.com/git-for-windows/git/issues/5068 Signed-off-by: Matthias Aßhauer <mha1993@live.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Matthias Aßhauer committed Aug 3, 2025 at 21:25 UTC 5f277fc5f25dc0fb54aa42bad62c23325bab9200
1 file changed +16 -5
compat/mingw.c
+16 -5
@@ -588,13 +588,24 @@ static int mingw_open_existing(const wchar_t *filename, int oflags, ...)
588 &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
589 if (handle == INVALID_HANDLE_VALUE) {
590 DWORD err = GetLastError();
591 + if (err == ERROR_ACCESS_DENIED) {
592 + DWORD attrs = GetFileAttributesW(filename);
593 + if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
594 + handle = CreateFileW(filename, access,
595 + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
596 + &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_BACKUP_SEMANTICS, NULL);
597 + }
598
592 - /* See `mingw_open_append()` for why we have this conversion. */
593 - if (err == ERROR_INVALID_PARAMETER)
594 - err = ERROR_PATH_NOT_FOUND;
599 + if (handle == INVALID_HANDLE_VALUE) {
600 + err = GetLastError();
601
596 - errno = err_win_to_posix(err);
597 - return -1;
602 + /* See `mingw_open_append()` for why we have this conversion. */
603 + if (err == ERROR_INVALID_PARAMETER)
604 + err = ERROR_PATH_NOT_FOUND;
605 +
606 + errno = err_win_to_posix(err);
607 + return -1;
608 + }
609 }
610
611 fd = _open_osfhandle((intptr_t)handle, oflags | O_BINARY);