]> wimlib.net Git - wimlib/blobdiff - src/win32_capture.c
wincfg: Add swapfile.sys
[wimlib] / src / win32_capture.c
index 20a86b5d3e9cd84ab877e2a9d7fc7dfe4e53e97c..c62abce7c91c175a21bb8882232b0f87cde913b7 100644 (file)
@@ -30,6 +30,7 @@
 #include "wimlib/win32_common.h"
 
 #include "wimlib/capture.h"
+#include "wimlib/dentry.h"
 #include "wimlib/endianness.h"
 #include "wimlib/error.h"
 #include "wimlib/lookup_table.h"
@@ -621,7 +622,7 @@ win32_capture_maybe_rpfix_target(wchar_t *target, u16 *target_nbytes_p,
 static int
 win32_capture_try_rpfix(u8 *rpbuf, u16 *rpbuflen_p,
                        u64 capture_root_ino, u64 capture_root_dev,
-                       const wchar_t *path)
+                       const wchar_t *path, struct add_image_params *params)
 {
        struct reparse_data rpdata;
        int ret;
@@ -658,17 +659,18 @@ win32_capture_try_rpfix(u8 *rpbuf, u16 *rpbuflen_p,
                        ret = -ret;
        } else {
                if (rp_status == RP_EXCLUDED) {
+                       /* Ignoring absolute symbolic link or junction point
+                        * that points out of the tree to be captured.  */
                        size_t print_name_nchars = rpdata.print_name_nbytes / 2;
                        wchar_t print_name0[print_name_nchars + 1];
                        print_name0[print_name_nchars] = L'\0';
                        wmemcpy(print_name0, rpdata.print_name, print_name_nchars);
-                       WARNING("Ignoring %ls pointing out of capture directory:\n"
-                               "          \"%ls\" -> \"%ls\"\n"
-                               "          (Use --norpfix to capture all symbolic links "
-                               "and junction points as-is)",
-                               (rpdata.rptag == WIM_IO_REPARSE_TAG_SYMLINK) ?
-                                       L"absolute symbolic link" : L"junction point",
-                               path, print_name0);
+
+                       params->progress.scan.cur_path = path;
+                       params->progress.scan.symlink_target = print_name0;
+                       do_capture_progress(params,
+                                           WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK,
+                                           NULL);
                }
                ret = rp_status;
        }
@@ -737,7 +739,8 @@ win32_get_reparse_data(HANDLE hFile, const wchar_t *path,
                                              &rpbuflen,
                                              params->capture_root_ino,
                                              params->capture_root_dev,
-                                             path);
+                                             path,
+                                             params);
        } else {
                ret = RP_NOT_FIXED;
        }
@@ -793,7 +796,8 @@ win32_get_encrypted_file_size(const wchar_t *path, u64 *size_ret)
  *
  * @inode:              WIM inode to save the stream into.
  *
- * @lookup_table:       Stream lookup table for the WIM.
+ * @unhashed_streams:   List of unhashed streams that have been added to the WIM
+ *                      image.
  *
  * @dat:                A `WIN32_FIND_STREAM_DATA' structure that specifies the
  *                      stream name.
@@ -804,7 +808,7 @@ static int
 win32_capture_stream(const wchar_t *path,
                     size_t path_num_chars,
                     struct wim_inode *inode,
-                    struct wim_lookup_table *lookup_table,
+                    struct list_head *unhashed_streams,
                     WIN32_FIND_STREAM_DATA *dat)
 {
        struct wim_ads_entry *ads_entry;
@@ -914,7 +918,7 @@ win32_capture_stream(const wchar_t *path,
                stream_id = 0;
                inode->i_lte = lte;
        }
-       lookup_table_insert_unhashed(lookup_table, lte, inode, stream_id);
+       add_unhashed_stream(lte, inode, stream_id, unhashed_streams);
        ret = 0;
 out_free_spath:
        FREE(spath);
@@ -944,7 +948,7 @@ win32_capture_streams(HANDLE *hFile_p,
                      const wchar_t *path,
                      size_t path_num_chars,
                      struct wim_inode *inode,
-                     struct wim_lookup_table *lookup_table,
+                     struct list_head *unhashed_streams,
                      u64 file_size,
                      unsigned vol_flags)
 {
@@ -1030,7 +1034,7 @@ win32_capture_streams(HANDLE *hFile_p,
 
                        /* Capture the stream.  */
                        ret = win32_capture_stream(path, path_num_chars, inode,
-                                                  lookup_table, &dat);
+                                                  unhashed_streams, &dat);
                        if (ret)
                                goto out_free_buf;
                }
@@ -1087,7 +1091,7 @@ use_FindFirstStream:
        do {
                ret = win32_capture_stream(path,
                                           path_num_chars,
-                                          inode, lookup_table,
+                                          inode, unhashed_streams,
                                           &dat);
                if (ret)
                        goto out_find_close;
@@ -1114,7 +1118,7 @@ unnamed_only:
        wcscpy(dat.cStreamName, L"::$DATA");
        dat.StreamSize.QuadPart = file_size;
        return win32_capture_stream(path, path_num_chars,
-                                   inode, lookup_table, &dat);
+                                   inode, unhashed_streams, &dat);
 }
 
 static int
@@ -1137,12 +1141,10 @@ win32_build_dentry_tree_recursive(struct wim_dentry **root_ret,
        DWORD desiredAccess;
 
 
-       if (exclude_path(path, path_num_chars, params->config, true)) {
-               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 (exclude_path(path + params->capture_root_nchars,
+                        path_num_chars - params->capture_root_nchars,
+                        params->config))
+       {
                ret = 0;
                goto out_progress;
        }
@@ -1202,7 +1204,7 @@ again:
                        not_rpfixed = 0;
                } else if (ret == RP_EXCLUDED) {
                        ret = 0;
-                       goto out_progress;
+                       goto out;
                } else {
                        not_rpfixed = 1;
                }
@@ -1214,7 +1216,7 @@ again:
         * only 1 link and refuse to hard link them.  This is because Windows
         * has a bug where it can return duplicate File IDs for files and
         * directories on the FAT filesystem. */
-       ret = inode_table_new_dentry(&params->inode_table,
+       ret = inode_table_new_dentry(params->inode_table,
                                     path_basename_with_len(path, path_num_chars),
                                     ((u64)file_info.nFileIndexHigh << 32) |
                                         (u64)file_info.nFileIndexLow,
@@ -1248,7 +1250,7 @@ again:
            && (vol_flags & FILE_PERSISTENT_ACLS))
        {
                ret = win32_get_security_descriptor(hFile, path, inode,
-                                                   &params->sd_set, state,
+                                                   params->sd_set, state,
                                                    params->add_flags);
                if (ret)
                        goto out;
@@ -1264,7 +1266,7 @@ again:
                                    path,
                                    path_num_chars,
                                    inode,
-                                   params->lookup_table,
+                                   params->unhashed_streams,
                                    file_size,
                                    vol_flags);
        if (ret)
@@ -1409,32 +1411,22 @@ win32_build_dentry_tree(struct wim_dentry **root_ret,
                wmemcpy(path, root_disk_path, path_nchars + 1);
        }
 
-       /* Strip trailing slashes.  */
+       /* Strip trailing slashes.  If we don't do this, we may create a path
+       * with multiple consecutive backslashes, which for some reason causes
+       * Windows to report that the file cannot be found.  */
        while (path_nchars >= 2 &&
-              is_any_path_separator(path[path_nchars - 1]) &&
+              path[path_nchars - 1] == L'\\' &&
               path[path_nchars - 2] != L':')
        {
                path[--path_nchars] = L'\0';
        }
 
-       /* Update pattern prefix.  */
-       if (params->config != NULL)
-       {
-               params->config->_prefix = TSTRDUP(path);
-               params->config->_prefix_num_tchars = path_nchars;
-               if (params->config->_prefix == NULL)
-               {
-                       ret = WIMLIB_ERR_NOMEM;
-                       goto out_free_path;
-               }
-       }
+       params->capture_root_nchars = path_nchars;
 
        memset(&state, 0, sizeof(state));
        ret = win32_build_dentry_tree_recursive(root_ret, path,
                                                path_nchars, params,
                                                &state, vol_flags);
-       if (params->config != NULL)
-               FREE(params->config->_prefix);
 out_free_path:
        FREE(path);
        if (ret == 0)