summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Kikhtenko <kikht@yandex-team.ru>2022-11-18 12:46:18 +0600
committerVladimir Kikhtenko <kikht@yandex-team.ru>2022-11-18 12:54:14 +0600
commit82353fbe538c991492e9145ca54b2d361aacbe06 (patch)
tree88652b762c68cb70e3f057f18b111ed18104d43e
parentfa4b613f2e2510bd036f2eeed2fece97cd18b079 (diff)
downloadlibarchive-82353fbe538c991492e9145ca54b2d361aacbe06.tar.gz
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.
-rw-r--r--libarchive/archive_read_disk_windows.c18
1 files 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());