Calculate SHA1 md of NTFS reparse points correctly
authorEric Biggers <ebiggers3@gmail.com>
Sun, 18 Nov 2012 23:26:58 +0000 (17:26 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 18 Nov 2012 23:26:58 +0000 (17:26 -0600)
src/ntfs-capture.c
src/resource.c

index cc31377..d23776b 100644 (file)
@@ -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,6 +242,9 @@ 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 file or reparse point in the NTFS volume into the WIM
@@ -292,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;
 
index 5ffba67..51bde70 100644 (file)
@@ -574,17 +574,15 @@ int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[],
        case RESOURCE_IN_NTFS_VOLUME:
                wimlib_assert(lte->ntfs_loc != NULL);
                wimlib_assert(lte->attr != NULL);
-               {
-                       if (lte->ntfs_loc->is_reparse_point)
-                               offset += 8;
-                       if (ntfs_attr_pread(lte->attr, offset, size, buf) != size) {
-                               ERROR_WITH_ERRNO("Error reading NTFS attribute "
-                                                "at `%s'",
-                                                lte->ntfs_loc->path_utf8);
-                               ret = WIMLIB_ERR_NTFS_3G;
-                       }
-                       break;
+               if (lte->ntfs_loc->is_reparse_point)
+                       offset += 8;
+               if (ntfs_attr_pread(lte->attr, offset, size, buf) != size) {
+                       ERROR_WITH_ERRNO("Error reading NTFS attribute "
+                                        "at `%s'",
+                                        lte->ntfs_loc->path_utf8);
+                       ret = WIMLIB_ERR_NTFS_3G;
                }
+               break;
 #endif
        default:
                wimlib_assert(0);