]> wimlib.net Git - wimlib/blobdiff - src/ntfs-capture.c
Calculate SHA1 md of NTFS reparse points correctly
[wimlib] / src / ntfs-capture.c
index 9739d9e1a55fd3a0d674b5e2a6968301f4dfae22..d23776b889d39cc4c990ebcd4cb130439fefef75 100644 (file)
@@ -87,12 +87,12 @@ static void insert_sd_node(struct sd_node *new, struct sd_node *root)
        if (cmp < 0) {
                if (root->left)
                        insert_sd_node(new, root->left);
-               else 
+               else
                        root->left = new;
        } else if (cmp > 0) {
                if (root->right)
                        insert_sd_node(new, root->right);
-               else 
+               else
                        root->right = new;
        } else {
                wimlib_assert(0);
@@ -100,7 +100,7 @@ static void insert_sd_node(struct sd_node *new, struct sd_node *root)
 }
 
 /* Returns the security ID of the security data having a SHA1 message digest of
- * @hash in the security descriptor index tree rooted at @root. 
+ * @hash in the security descriptor index tree rooted at @root.
  *
  * If not found, return -1. */
 static int lookup_sd(const u8 hash[SHA1_HASH_SIZE], struct sd_node *root)
@@ -191,7 +191,7 @@ static inline ntfschar *attr_record_name(ATTR_RECORD *ar)
        return (ntfschar*)((u8*)ar + le16_to_cpu(ar->name_offset));
 }
 
-/* Calculates the SHA1 message digest of a NTFS attribute. 
+/* Calculates the SHA1 message digest of a NTFS attribute.
  *
  * @ni:  The NTFS inode containing the attribute.
  * @ar:         The ATTR_RECORD describing the attribute.
@@ -204,6 +204,7 @@ static inline ntfschar *attr_record_name(ATTR_RECORD *ar)
  */
 static int ntfs_attr_sha1sum(ntfs_inode *ni, ATTR_RECORD *ar,
                             u8 md[SHA1_HASH_SIZE],
+                            bool is_reparse_point,
                             u32 *reparse_tag_ret)
 {
        s64 pos = 0;
@@ -220,19 +221,20 @@ static int ntfs_attr_sha1sum(ntfs_inode *ni, ATTR_RECORD *ar,
        }
 
        bytes_remaining = na->data_size;
-       sha1_init(&ctx);
 
-       DEBUG2("Calculating SHA1 message digest (%"PRIu64" bytes)",
-              bytes_remaining);
+       if (is_reparse_point) {
+               if (ntfs_attr_pread(na, 0, 8, buf) != 8)
+                       goto out_error;
+               *reparse_tag_ret = le32_to_cpu(*(u32*)buf);
+               pos = 8;
+               bytes_remaining -= 8;
+       }
 
+       sha1_init(&ctx);
        while (bytes_remaining) {
                s64 to_read = min(bytes_remaining, sizeof(buf));
-               if (ntfs_attr_pread(na, pos, to_read, buf) != to_read) {
-                       ERROR_WITH_ERRNO("Error reading NTFS attribute");
-                       return WIMLIB_ERR_NTFS_3G;
-               }
-               if (bytes_remaining == na->data_size && reparse_tag_ret)
-                       *reparse_tag_ret = le32_to_cpu(*(u32*)buf);
+               if (ntfs_attr_pread(na, pos, to_read, buf) != to_read)
+                       goto out_error;
                sha1_update(&ctx, buf, to_read);
                pos += to_read;
                bytes_remaining -= to_read;
@@ -240,10 +242,13 @@ static int ntfs_attr_sha1sum(ntfs_inode *ni, ATTR_RECORD *ar,
        sha1_final(md, &ctx);
        ntfs_attr_close(na);
        return 0;
+out_error:
+       ERROR_WITH_ERRNO("Error reading NTFS attribute");
+       return WIMLIB_ERR_NTFS_3G;
 }
 
-/* Load the streams from a WIM file or reparse point in the NTFS volume into the
- * WIM lookup table */
+/* Load the streams from a file or reparse point in the NTFS volume into the WIM
+ * lookup table */
 static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni,
                                char path[], size_t path_len,
                                struct lookup_table *lookup_table,
@@ -271,12 +276,11 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni,
                                 CASE_SENSITIVE, 0, NULL, 0, actx))
        {
                char *stream_name_utf8;
-               size_t stream_name_utf16_len;
                u32 reparse_tag;
                u64 data_size = ntfs_get_attribute_value_length(actx->attr);
                u64 name_length = actx->attr->name_length;
 
-               if (data_size == 0) { 
+               if (data_size == 0) {
                        if (errno != 0) {
                                ERROR_WITH_ERRNO("Failed to get size of attribute of "
                                                 "`%s'", path);
@@ -293,7 +297,8 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni,
                                goto out_put_actx;
                        }
                        /* Checksum the stream. */
-                       ret = ntfs_attr_sha1sum(ni, actx->attr, attr_hash, &reparse_tag);
+                       ret = ntfs_attr_sha1sum(ni, actx->attr, attr_hash,
+                                               type == AT_REPARSE_POINT, &reparse_tag);
                        if (ret != 0)
                                goto out_put_actx;
 
@@ -371,7 +376,7 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni,
                                goto out_free_lte;
 
                        wimlib_assert(new_ads_entry->stream_name_len == name_length * 2);
-                               
+
                        new_ads_entry->lte = lte;
                }
        }
@@ -464,7 +469,7 @@ static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
                                               ctx->flags);
 
        if (child)
-               link_dentry(child, ctx->parent);
+               dentry_add_child(ctx->parent, child);
 
        ntfs_inode_close(ni);
 out_free_utf8_name:
@@ -508,7 +513,6 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p,
 {
        u32 attributes;
        int mrec_flags;
-       u32 sd_size = 0;
        int ret;
        char dos_name_utf8[64];
        struct dentry *root;
@@ -660,7 +664,7 @@ static int build_dentry_tree_ntfs(struct dentry **root_p,
        ntfs_volume **ntfs_vol_p = extra_arg;
 
        DEBUG("Mounting NTFS volume `%s' read-only", device);
-       
+
        vol = ntfs_mount(device, MS_RDONLY);
        if (!vol) {
                ERROR_WITH_ERRNO("Failed to mount NTFS volume `%s' read-only",