From: Vladimir Kikhtenko Date: Fri, 18 Nov 2022 06:46:18 +0000 (+0600) Subject: Use FILE_SHARE_WRITE and FILE_SHARE_DELETE when opening files on Windows X-Git-Tag: v3.6.2~16^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F1806%2Fhead;p=thirdparty%2Flibarchive.git 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. --- diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c index ea32e2aac..f9d139557 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());