]> wimlib.net Git - wimlib/blobdiff - src/ntfs-3g_capture.c
Make read_huffsym() return unsigned int
[wimlib] / src / ntfs-3g_capture.c
index 066d38489fb999f46997d4acfb62d87daf06a1f7..f9825f73946ca6c629690d587dc3d74c2af25a8e 100644 (file)
@@ -189,34 +189,33 @@ cmp_ntfs_locations(const struct ntfs_location *loc1,
        return cmp_u64(loc1->sort_key, loc2->sort_key);
 }
 
+/* Read rptag and rpreserved from the NTFS inode and save them in the WIM inode.
+ */
 static int
-read_reparse_tag(ntfs_inode *ni, struct ntfs_location *loc,
-                u32 *reparse_tag_ret)
+read_reparse_header(ntfs_inode *ni, struct wim_inode *inode)
 {
-       int ret;
-       le32 reparse_tag;
+       struct {
+               le32 rptag;
+               le16 rpdatalen;
+               le16 rpreserved;
+       } hdr;
+       s64 res;
        ntfs_attr *na;
 
-       na = open_ntfs_attr(ni, loc);
-       if (!na) {
-               ret = WIMLIB_ERR_NTFS_3G;
-               goto out;
-       }
+       na = ntfs_attr_open(ni, AT_REPARSE_POINT, AT_UNNAMED, 0);
+       if (!na)
+               return WIMLIB_ERR_NTFS_3G;
+
+       res = ntfs_attr_pread(na, 0, sizeof(hdr), &hdr);
 
-       if (ntfs_attr_pread(na, 0, sizeof(reparse_tag),
-                           &reparse_tag) != sizeof(reparse_tag))
-       {
-               ERROR_WITH_ERRNO("Error reading reparse data");
-               ret = WIMLIB_ERR_NTFS_3G;
-               goto out_close_ntfs_attr;
-       }
-       *reparse_tag_ret = le32_to_cpu(reparse_tag);
-       ret = 0;
-out_close_ntfs_attr:
        ntfs_attr_close(na);
-out:
-       return ret;
 
+       if (res != sizeof(hdr))
+               return WIMLIB_ERR_NTFS_3G;
+
+       inode->i_reparse_tag = le32_to_cpu(hdr.rptag);
+       inode->i_rp_reserved = le16_to_cpu(hdr.rpreserved);
+       return 0;
 }
 
 static int
@@ -262,13 +261,12 @@ static int
 scan_ntfs_attr(struct wim_inode *inode,
               ntfs_inode *ni,
               const char *path,
-              size_t path_len,
               struct list_head *unhashed_blobs,
               struct ntfs_volume_wrapper *volume,
               ATTR_TYPES type,
               const ATTR_RECORD *record)
 {
-       const u64 data_size = ntfs_get_attribute_value_length(record);
+       u64 data_size = ntfs_get_attribute_value_length(record);
        const u32 name_nchars = record->name_length;
        struct blob_descriptor *blob = NULL;
        utf16lechar *stream_name = NULL;
@@ -285,6 +283,23 @@ scan_ntfs_attr(struct wim_inode *inode,
                }
        }
 
+       if (unlikely(type == AT_REPARSE_POINT)) {
+               if (data_size < REPARSE_DATA_OFFSET) {
+                       ERROR("Reparse point attribute of \"%s\" "
+                             "is too short!", path);
+                       ret = WIMLIB_ERR_INVALID_REPARSE_DATA;
+                       goto out_cleanup;
+               }
+               data_size -= REPARSE_DATA_OFFSET;
+
+               ret = read_reparse_header(ni, inode);
+               if (ret) {
+                       ERROR_WITH_ERRNO("Error reading reparse point header "
+                                        "of \"%s\"", path);
+                       goto out_cleanup;
+               }
+       }
+
        /* If the stream is non-empty, set up a blob descriptor for it.  */
        if (data_size != 0) {
                blob = new_blob_descriptor();
@@ -317,21 +332,6 @@ scan_ntfs_attr(struct wim_inode *inode,
                ret = set_attr_sort_key(ni, blob->ntfs_loc);
                if (ret)
                        goto out_cleanup;
-
-               if (unlikely(type == AT_REPARSE_POINT)) {
-                       if (blob->size < REPARSE_DATA_OFFSET) {
-                               ERROR("Reparse data of \"%s\" "
-                                     "is invalid (only %"PRIu64" bytes)!",
-                                     path, data_size);
-                               ret = WIMLIB_ERR_INVALID_REPARSE_DATA;
-                               goto out_cleanup;
-                       }
-                       blob->size -= REPARSE_DATA_OFFSET;
-                       ret = read_reparse_tag(ni, blob->ntfs_loc,
-                                              &inode->i_reparse_tag);
-                       if (ret)
-                               goto out_cleanup;
-               }
        }
 
        strm = inode_add_stream(inode,
@@ -356,7 +356,6 @@ static int
 scan_ntfs_attrs_with_type(struct wim_inode *inode,
                          ntfs_inode *ni,
                          const char *path,
-                         size_t path_len,
                          struct list_head *unhashed_blobs,
                          struct ntfs_volume_wrapper *volume,
                          ATTR_TYPES type)
@@ -377,7 +376,6 @@ scan_ntfs_attrs_with_type(struct wim_inode *inode,
                ret = scan_ntfs_attr(inode,
                                     ni,
                                     path,
-                                    path_len,
                                     unhashed_blobs,
                                     volume,
                                     type,
@@ -590,17 +588,13 @@ filldir(void *_ctx, const ntfschar *name, const int name_nchars,
                        goto out;
        }
 
-       /* Ignore . and .. entries  */
-       ret = 0;
-       if ((name_nchars == 1 && name[0] == cpu_to_le16('.')) ||
-           (name_nchars == 2 && name[0] == cpu_to_le16('.') &&
-                                name[1] == cpu_to_le16('.')))
-               goto out;
-
        ret = utf16le_to_tstr(name, name_nbytes, &mbs_name, &mbs_name_nbytes);
        if (ret)
                goto out;
 
+       if (should_ignore_filename(mbs_name, mbs_name_nbytes))
+               goto out_free_mbs_name;
+
        path_len = ctx->path_len;
        if (path_len != 1)
                ctx->path[path_len++] = '/';
@@ -610,8 +604,8 @@ filldir(void *_ctx, const ntfschar *name, const int name_nchars,
        ret = ntfs_3g_build_dentry_tree_recursive(&child, mref, ctx->path,
                                                  path_len, name_type,
                                                  ctx->volume, ctx->params);
-       if (child)
-               dentry_add_child(ctx->parent, child);
+       attach_scanned_tree(ctx->parent, child, ctx->params->blob_table);
+out_free_mbs_name:
        FREE(mbs_name);
 out:
        ctx->ret = ret;
@@ -733,7 +727,7 @@ ntfs_3g_build_dentry_tree_recursive(struct wim_dentry **root_ret,
 
        if (attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
                /* Scan the reparse point stream.  */
-               ret = scan_ntfs_attrs_with_type(inode, ni, path, path_len,
+               ret = scan_ntfs_attrs_with_type(inode, ni, path,
                                                params->unhashed_blobs,
                                                volume, AT_REPARSE_POINT);
                if (ret)
@@ -746,8 +740,7 @@ ntfs_3g_build_dentry_tree_recursive(struct wim_dentry **root_ret,
         * may have named data streams.  Nondirectories (including reparse
         * points) can have an unnamed data stream as well as named data
         * streams.  */
-       ret = scan_ntfs_attrs_with_type(inode, ni, path, path_len,
-                                       params->unhashed_blobs,
+       ret = scan_ntfs_attrs_with_type(inode, ni, path, params->unhashed_blobs,
                                        volume, AT_DATA);
        if (ret)
                goto out;