]> wimlib.net Git - wimlib/blobdiff - src/win32_capture.c
Strip trailing slashes from Windows filesystem paths
[wimlib] / src / win32_capture.c
index 6f29828c842a95d70e7aea9a0df66cd7a06a3375..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"
@@ -795,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.
@@ -806,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;
@@ -916,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);
@@ -946,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)
 {
@@ -1032,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;
                }
@@ -1089,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;
@@ -1116,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
@@ -1139,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;
        }
@@ -1216,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,
@@ -1250,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;
@@ -1266,7 +1266,7 @@ again:
                                    path,
                                    path_num_chars,
                                    inode,
-                                   params->lookup_table,
+                                   params->unhashed_streams,
                                    file_size,
                                    vol_flags);
        if (ret)
@@ -1411,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)