]> wimlib.net Git - wimlib/blobdiff - src/win32.c
add_image => add
[wimlib] / src / win32.c
index 43336469005f17c89e18a06d35ae4c3ee10cfc07..f9f4276510c6b066bb0329592504dd359aa7eb5c 100644 (file)
@@ -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,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;
 }