X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fwin32.c;h=f9f4276510c6b066bb0329592504dd359aa7eb5c;hp=789eacce6c5adf6dbbb7ddfd5f862053ed894be5;hb=143db75c035e6ecaca451ce70a4ed58a01102b43;hpb=3b5ae49e2ed3c288a00f8ad4dc45c443939204f2 diff --git a/src/win32.c b/src/win32.c index 789eacce..f9f42765 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; @@ -701,7 +702,7 @@ win32_get_security_descriptor(struct wim_dentry *dentry, struct sd_set *sd_set, const wchar_t *path, struct win32_capture_state *state, - int add_image_flags) + int add_flags) { SECURITY_INFORMATION requestedInformation; DWORD lenNeeded = 0; @@ -736,7 +737,7 @@ again: } } - if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_STRICT_ACLS) + if (add_flags & WIMLIB_ADD_FLAG_STRICT_ACLS) goto fail; switch (err) { @@ -926,7 +927,7 @@ enum rp_status { * fixup where we change it to be absolute relative to the root of the directory * tree being captured. * - * Note that this is only executed when WIMLIB_ADD_IMAGE_FLAG_RPFIX has been + * Note that this is only executed when WIMLIB_ADD_FLAG_RPFIX has been * set. * * @capture_root_ino and @capture_root_dev indicate the inode number and device @@ -1084,7 +1085,7 @@ win32_get_reparse_data(HANDLE hFile, const wchar_t *path, rpbuflen = bytesReturned; reparse_tag = le32_to_cpu(*(u32*)rpbuf); - if (params->add_image_flags & WIMLIB_ADD_IMAGE_FLAG_RPFIX && + if (params->add_flags & WIMLIB_ADD_FLAG_RPFIX && (reparse_tag == WIM_IO_REPARSE_TAG_SYMLINK || reparse_tag == WIM_IO_REPARSE_TAG_MOUNT_POINT)) { @@ -1404,12 +1405,12 @@ win32_build_dentry_tree_recursive(struct wim_dentry **root_ret, u16 not_rpfixed; if (exclude_path(path, path_num_chars, params->config, true)) { - if (params->add_image_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) { + if (params->add_flags & WIMLIB_ADD_FLAG_ROOT) { ERROR("Cannot exclude the root directory from capture"); ret = WIMLIB_ERR_INVALID_CAPTURE_CONFIG; goto out; } - if ((params->add_image_flags & WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE) + if ((params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE) && params->progress_func) { union wimlib_progress_info info; @@ -1421,7 +1422,7 @@ win32_build_dentry_tree_recursive(struct wim_dentry **root_ret, goto out; } - if ((params->add_image_flags & WIMLIB_ADD_IMAGE_FLAG_VERBOSE) + if ((params->add_flags & WIMLIB_ADD_FLAG_VERBOSE) && params->progress_func) { union wimlib_progress_info info; @@ -1500,14 +1501,14 @@ win32_build_dentry_tree_recursive(struct wim_dentry **root_ret, inode->i_last_access_time = FILETIME_to_u64(&file_info.ftLastAccessTime); inode->i_resolved = 1; - params->add_image_flags &= ~(WIMLIB_ADD_IMAGE_FLAG_ROOT | WIMLIB_ADD_IMAGE_FLAG_SOURCE); + params->add_flags &= ~WIMLIB_ADD_FLAG_ROOT; - if (!(params->add_image_flags & WIMLIB_ADD_IMAGE_FLAG_NO_ACLS) + if (!(params->add_flags & WIMLIB_ADD_FLAG_NO_ACLS) && (vol_flags & FILE_PERSISTENT_ACLS)) { ret = win32_get_security_descriptor(root, params->sd_set, path, state, - params->add_image_flags); + params->add_flags); if (ret) goto out_close_handle; } @@ -1557,7 +1558,7 @@ out: static void win32_do_capture_warnings(const struct win32_capture_state *state, - int add_image_flags) + int add_flags) { if (state->num_get_sacl_priv_notheld == 0 && state->num_get_sd_access_denied == 0) @@ -1580,7 +1581,7 @@ win32_do_capture_warnings(const struct win32_capture_state *state, " desired metadata has been captured exactly. However, if you\n" " do not care about capturing security descriptors correctly, then\n" " nothing more needs to be done%ls\n", - (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_NO_ACLS) ? L"." : + (add_flags & WIMLIB_ADD_FLAG_NO_ACLS) ? L"." : L", although you might consider\n" " passing the --no-acls flag to `wimlib-imagex capture' or\n" " `wimlib-imagex append' to explicitly capture no security\n" @@ -1636,7 +1637,7 @@ win32_build_dentry_tree(struct wim_dentry **root_ret, &state, vol_flags); FREE(path); if (ret == 0) - win32_do_capture_warnings(&state, params->add_image_flags); + win32_do_capture_warnings(&state, params->add_flags); return ret; } @@ -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; } @@ -2601,7 +2617,7 @@ win32_extract_streams(const struct wim_dentry *dentry, continue; /* Skip special UNIX data entries (see documentation for - * WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA) */ + * WIMLIB_ADD_FLAG_UNIX_DATA) */ if (ads_entry->stream_name_nbytes == WIMLIB_UNIX_DATA_TAG_UTF16LE_NBYTES && !memcmp(ads_entry->stream_name, WIMLIB_UNIX_DATA_TAG_UTF16LE, @@ -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,7 +2863,6 @@ out: int fsync(int fd) { - DWORD err; HANDLE h; h = (HANDLE)_get_osfhandle(fd); @@ -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; }