]> wimlib.net Git - wimlib/blobdiff - src/dentry.c
NTFS capture updates
[wimlib] / src / dentry.c
index b62f53ae6d73e4dc46092e3170061e6a48ca390c..a0d0febde3e9894c5e11b7d66e396ec1c82b7392 100644 (file)
@@ -59,7 +59,7 @@ static bool dentry_has_name(const struct dentry *dentry, const char *name,
 u64 dentry_total_length(const struct dentry *dentry)
 {
        u64 length = (dentry->length + 7) & ~7;
-       for (u16 i = 0 ; i < dentry->num_ads; i++)
+       for (u16 i = 0; i < dentry->num_ads; i++)
                length += ads_entry_length(&dentry->ads_entries[i]);
        return length;
 }
@@ -99,13 +99,18 @@ void dentry_update_all_timestamps(struct dentry *dentry)
 struct ads_entry *dentry_get_ads_entry(struct dentry *dentry,
                                       const char *stream_name)
 {
-       size_t stream_name_len = strlen(stream_name);
+       size_t stream_name_len;
        if (!stream_name)
                return NULL;
-       for (u16 i = 0; i < dentry->num_ads; i++)
-               if (ads_entry_has_name(&dentry->ads_entries[i],
-                                      stream_name, stream_name_len))
-                       return &dentry->ads_entries[i];
+       if (dentry->num_ads) {
+               u16 i = 0;
+               stream_name_len = strlen(stream_name);
+               do {
+                       if (ads_entry_has_name(&dentry->ads_entries[i],
+                                              stream_name, stream_name_len))
+                               return &dentry->ads_entries[i];
+               } while (++i != dentry->num_ads);
+       }
        return NULL;
 }
 
@@ -124,6 +129,9 @@ struct ads_entry *dentry_add_ads(struct dentry *dentry, const char *stream_name)
        struct ads_entry *ads_entries;
        struct ads_entry *new_entry;
 
+       DEBUG("Add alternate data stream %s:%s",
+              dentry->file_name_utf8, stream_name);
+
        if (dentry->num_ads == 0xffff)
                return NULL;
        num_ads = dentry->num_ads + 1;
@@ -139,13 +147,13 @@ struct ads_entry *dentry_add_ads(struct dentry *dentry, const char *stream_name)
                        cur->next->prev = cur;
                }
        }
-       dentry->ads_entries = ads_entries;
 
        new_entry = &ads_entries[num_ads - 1];
+       ads_entry_init(new_entry);
        if (change_ads_name(new_entry, stream_name) != 0)
                return NULL;
+       dentry->ads_entries = ads_entries;
        dentry->num_ads = num_ads;
-       ads_entry_init(new_entry);
        return new_entry;
 }
 
@@ -419,6 +427,7 @@ struct file_attr_flag file_attr_flags[] = {
 int print_dentry(struct dentry *dentry, void *lookup_table)
 {
        const u8 *hash;
+       struct lookup_table_entry *lte;
 
        printf("[DENTRY]\n");
        printf("Length            = %"PRIu64"\n", dentry->length);
@@ -446,12 +455,6 @@ int print_dentry(struct dentry *dentry, void *lookup_table)
        printf("Last Access Time  = %s", asctime(localtime(&access_time)));
        printf("Last Write Time   = %s", asctime(localtime(&mod_time)));
 
-       hash = dentry_stream_hash(dentry, 0);
-       if (hash) {
-               printf("Hash              = 0x"); 
-               print_hash(hash);
-               putchar('\n');
-       }
        printf("Reparse Tag       = 0x%"PRIx32"\n", dentry->reparse_tag);
        printf("Hard Link Group   = 0x%"PRIx64"\n", dentry->hard_link);
        printf("Number of Alternate Data Streams = %hu\n", dentry->num_ads);
@@ -466,7 +469,18 @@ int print_dentry(struct dentry *dentry, void *lookup_table)
        puts("\"");
        printf("Short Name Length = %hu\n", dentry->short_name_len);
        printf("Full Path (UTF-8) = \"%s\"\n", dentry->full_path_utf8);
-       print_lookup_table_entry(dentry_stream_lte(dentry, 0, lookup_table));
+       lte = dentry_stream_lte(dentry, 0, lookup_table);
+       if (lte) {
+               print_lookup_table_entry(lte);
+       } else {
+               hash = dentry_stream_hash(dentry, 0);
+               if (hash) {
+                       printf("Hash              = 0x"); 
+                       print_hash(hash);
+                       putchar('\n');
+                       putchar('\n');
+               }
+       }
        for (u16 i = 0; i < dentry->num_ads; i++) {
                printf("[Alternate Stream Entry %u]\n", i);
                printf("Name = \"%s\"\n", dentry->ads_entries[i].stream_name_utf8);
@@ -746,7 +760,7 @@ int change_ads_name(struct ads_entry *entry, const char *new_name)
        return get_names(&entry->stream_name, &entry->stream_name_utf8,
                         &entry->stream_name_len,
                         &entry->stream_name_utf8_len,
-                         new_name);
+                        new_name);
 }
 
 /* Parameters for calculate_dentry_statistics(). */
@@ -1040,19 +1054,15 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len,
         * aligned on the next 8-byte boundary.  Here's an example of the
         * aligned data:
         *
-        * 01000000400000006c786bbac58ede11b0bb00261870892ab6adb76fe63a3
-        * e468fca86530d2effa16c786bbac58ede11b0bb00261870892a0000000000
-        * 0000000000000000000000
+        * 01000000 40000000 6c786bba c58ede11 b0bb0026 1870892a b6adb76f
+        * e63a3e46 8fca8653 0d2effa1 6c786bba c58ede11 b0bb0026 1870892a
+        * 00000000 00000000 00000000 00000000
         *
         * Here's one interpretation of how the data is laid out.
         *
         * struct unknown {
         *      u32 field1; (always 0x00000001)
         *      u32 field2; (always 0x40000000)
-        *      u16 field3;
-        *      u32 field4;
-        *      u32 field5;
-        *      u32 field6;
         *      u8  data[48]; (???)
         *      u64 reserved1; (always 0)
         *      u64 reserved2; (always 0)
@@ -1133,7 +1143,7 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p)
                p = put_zeroes(p, 4);
        } else {
                u64 hard_link;
-               p = put_u32(p, dentry->reparse_tag);
+               p = put_u32(p, 0);
                if (dentry->link_group_list.next == &dentry->link_group_list)
                        hard_link = 0;
                else
@@ -1151,7 +1161,7 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p)
        if (p - orig_p < dentry->length)
                p = put_zeroes(p, dentry->length - (p - orig_p));
 
-       p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
+       p = put_zeroes(p, (8 - dentry->length % 8) % 8);
 
        for (u16 i = 0; i < dentry->num_ads; i++) {
                p = put_u64(p, ads_entry_length(&dentry->ads_entries[i]));
@@ -1164,6 +1174,7 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p)
                p = put_u16(p, dentry->ads_entries[i].stream_name_len);
                p = put_bytes(p, dentry->ads_entries[i].stream_name_len,
                                 (u8*)dentry->ads_entries[i].stream_name);
+               p = put_u16(p, 0);
                p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
        }
        return p;