From 82353fbe538c991492e9145ca54b2d361aacbe06 Mon Sep 17 00:00:00 2001 From: Vladimir Kikhtenko Date: Fri, 18 Nov 2022 12:46:18 +0600 Subject: Use FILE_SHARE_WRITE and FILE_SHARE_DELETE when opening files on Windows Many standard libraries( [libc++](https://github.com/llvm/llvm-project/blob/main/libcxx/src/filesystem/posix_compat.h#L159), [go](https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/syscall/syscall_windows.go;l=331), [rust](https://doc.rust-lang.org/src/std/os/windows/fs.rs.html#126-131) ) open files on windows with `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE` mode by default. Libarchive uses only `FILE_SHARE_READ`, so when file is being opened by any program that uses these standard libraries libarchive fails to open it. Here we change libarchive shared flags, so it plays well with common practice in other programs. --- libarchive/archive_read_disk_windows.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c index ea32e2aa..f9d13955 100644 --- a/libarchive/archive_read_disk_windows.c +++ b/libarchive/archive_read_disk_windows.c @@ -418,8 +418,9 @@ la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype) FILE_FLAG_OPEN_REPARSE_POINT; int ret; - h = CreateFileW(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, flag, - NULL); + h = CreateFileW(path, 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, flag, NULL); if (h == INVALID_HANDLE_VALUE) { la_dosmaperr(GetLastError()); return (-1); @@ -1073,7 +1074,9 @@ next_entry(struct archive_read_disk *a, struct tree *t, else flags |= FILE_FLAG_SEQUENTIAL_SCAN; t->entry_fh = CreateFileW(tree_current_access_path(t), - GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL); + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, flags, NULL); if (t->entry_fh == INVALID_HANDLE_VALUE) { la_dosmaperr(GetLastError()); archive_set_error(&a->archive, errno, @@ -2046,7 +2049,8 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st, if (sim_lstat && tree_current_is_physical_link(t)) flag |= FILE_FLAG_OPEN_REPARSE_POINT; - h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL, + h = CreateFileW(tree_current_access_path(t), 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, flag, NULL); if (h == INVALID_HANDLE_VALUE) { la_dosmaperr(GetLastError()); @@ -2275,7 +2279,8 @@ archive_read_disk_entry_from_file(struct archive *_a, } else desiredAccess = GENERIC_READ; - h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL, + h = CreateFileW(path, desiredAccess, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, flag, NULL); if (h == INVALID_HANDLE_VALUE) { la_dosmaperr(GetLastError()); @@ -2337,7 +2342,8 @@ archive_read_disk_entry_from_file(struct archive *_a, if (fd >= 0) { h = (HANDLE)_get_osfhandle(fd); } else { - h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, + h = CreateFileW(path, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (h == INVALID_HANDLE_VALUE) { la_dosmaperr(GetLastError()); -- cgit v1.2.1