X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fwin32.c;h=2977ffc8b1b810ae5476808e4762aaa70f0fa1ee;hb=fb964811a120ad28cac62a9a3343def5bf474f03;hp=43336469005f17c89e18a06d35ae4c3ee10cfc07;hpb=161e7cdd2c0d3b3c1025da452a3192d381297465;p=wimlib diff --git a/src/win32.c b/src/win32.c index 43336469..2977ffc8 100644 --- a/src/win32.c +++ b/src/win32.c @@ -48,6 +48,7 @@ #define MAX_GET_SD_ACCESS_DENIED_WARNINGS 1 #define MAX_GET_SACL_PRIV_NOTHELD_WARNINGS 1 #define MAX_CREATE_HARD_LINK_WARNINGS 5 +#define MAX_CREATE_SOFT_LINK_WARNINGS 5 struct win32_capture_state { unsigned long num_get_sd_access_denied; unsigned long num_get_sacl_priv_notheld; @@ -1733,7 +1734,7 @@ win32_set_reparse_data(HANDLE h, const struct wim_inode *inode, const struct wim_lookup_table_entry *lte, const wchar_t *path, - const struct apply_args *args) + struct apply_args *args) { int ret; u8 rpbuf[REPARSE_POINT_MAX_SIZE]; @@ -1785,15 +1786,30 @@ win32_set_reparse_data(HANDLE h, NULL /* lpOverlapped */)) { DWORD err = GetLastError(); - ERROR("Failed to set reparse data on \"%ls\"", path); - win32_error(err); if (err == ERROR_ACCESS_DENIED || err == ERROR_PRIVILEGE_NOT_HELD) - return WIMLIB_ERR_INSUFFICIENT_PRIVILEGES_TO_EXTRACT; - else if (inode->i_reparse_tag == WIM_IO_REPARSE_TAG_SYMLINK || - inode->i_reparse_tag == WIM_IO_REPARSE_TAG_MOUNT_POINT) - return WIMLIB_ERR_LINK; - else - return WIMLIB_ERR_WRITE; + { + args->num_soft_links_failed++; + if (args->num_soft_links_failed <= MAX_CREATE_SOFT_LINK_WARNINGS) { + WARNING("Can't set reparse data on \"%ls\": Access denied!\n" + " You may be trying to extract a symbolic " + "link without the\n" + " SeCreateSymbolicLink privilege, which by " + "default non-Administrator\n" + " accounts do not have.", path); + } + if (args->num_hard_links_failed == MAX_CREATE_HARD_LINK_WARNINGS) { + WARNING("Suppressing further warnings regarding failure to extract\n" + " reparse points due to insufficient privileges..."); + } + } else { + ERROR("Failed to set reparse data on \"%ls\"", path); + win32_error(err); + if (inode->i_reparse_tag == WIM_IO_REPARSE_TAG_SYMLINK || + inode->i_reparse_tag == WIM_IO_REPARSE_TAG_MOUNT_POINT) + return WIMLIB_ERR_LINK; + else + return WIMLIB_ERR_WRITE; + } } return 0; } @@ -2708,12 +2724,13 @@ win32_try_hard_link(const wchar_t *output_path, const struct wim_inode *inode, return WIMLIB_ERR_LINK; } else { args->num_hard_links_failed++; - if (args->num_hard_links_failed < MAX_CREATE_HARD_LINK_WARNINGS) { + if (args->num_hard_links_failed <= MAX_CREATE_HARD_LINK_WARNINGS) { WARNING("Can't create hard link \"%ls => %ls\":\n" " Volume does not support hard links!\n" " Falling back to extracting a copy of the file.", output_path, inode->i_extracted_file); - } else if (args->num_hard_links_failed == MAX_CREATE_HARD_LINK_WARNINGS) { + } + if (args->num_hard_links_failed == MAX_CREATE_HARD_LINK_WARNINGS) { WARNING("Suppressing further hard linking warnings..."); } return -1; @@ -2788,8 +2805,8 @@ win32_do_apply_dentry(const wchar_t *output_path, int win32_do_apply_dentry_timestamps(const wchar_t *path, size_t path_num_chars, - const struct wim_dentry *dentry, - const struct apply_args *args) + struct wim_dentry *dentry, + struct apply_args *args) { DWORD err; HANDLE h; @@ -2846,17 +2863,17 @@ out: int fsync(int fd) { - DWORD err; HANDLE h; h = (HANDLE)_get_osfhandle(fd); if (h == INVALID_HANDLE_VALUE) goto err; if (!FlushFileBuffers(h)) - goto err; + goto err_set_errno; return 0; -err: +err_set_errno: set_errno_from_GetLastError(); +err: return -1; } @@ -2985,15 +3002,13 @@ do_pread_or_pwrite(int fd, void *buf, size_t count, off_t offset, wimlib_assert(count <= 0xffffffff); h = (HANDLE)_get_osfhandle(fd); - if (h == INVALID_HANDLE_VALUE) { - errno = EBADF; - return -1; - } + if (h == INVALID_HANDLE_VALUE) + goto err; /* Get original position */ relative_offset.QuadPart = 0; if (!SetFilePointerEx(h, relative_offset, &orig_offset, FILE_CURRENT)) - goto err; + goto err_set_errno; memset(&overlapped, 0, sizeof(overlapped)); overlapped.Offset = offset; @@ -3005,15 +3020,16 @@ do_pread_or_pwrite(int fd, void *buf, size_t count, off_t offset, else bret = ReadFile(h, buf, count, &bytes_read_or_written, &overlapped); if (!bret) - goto err; + goto err_set_errno; /* Restore the original position */ if (!SetFilePointerEx(h, orig_offset, NULL, FILE_BEGIN)) - goto err; + goto err_set_errno; return bytes_read_or_written; -err: +err_set_errno: set_errno_from_GetLastError(); +err: return -1; } @@ -3040,14 +3056,23 @@ win32_pwrite(int fd, const void *buf, size_t count, off_t offset) extern ssize_t win32_writev(int fd, const struct iovec *iov, int iovcnt) { - size_t total_bytes_written = 0; - for (int i = 0; i < iovcnt; i++) { - size_t bytes_written; + ssize_t total_bytes_written = 0; - bytes_written = full_write(fd, iov[i].iov_base, iov[i].iov_len); - total_bytes_written += bytes_written; - if (bytes_written != iov[i].iov_len) + if (iovcnt <= 0) { + errno = EINVAL; + return -1; + } + for (int i = 0; i < iovcnt; i++) { + ssize_t bytes_written; + + bytes_written = write(fd, iov[i].iov_base, iov[i].iov_len); + if (bytes_written >= 0) + total_bytes_written += bytes_written; + if (bytes_written != iov[i].iov_len) { + if (total_bytes_written == 0) + total_bytes_written = -1; break; + } } return total_bytes_written; }