]> wimlib.net Git - wimlib/blobdiff - src/blob_table.c
NTFS-3g capture: open inodes by inode number
[wimlib] / src / blob_table.c
index 6cc0a98de30fe059beea7dc529e99a4abdbad4a4..39dc865bf048c6e6e7fbde2789be29f4dcc32ba1 100644 (file)
@@ -99,17 +99,8 @@ free_blob_table(struct blob_table *table)
 struct blob_descriptor *
 new_blob_descriptor(void)
 {
-       struct blob_descriptor *blob;
-
-       blob = CALLOC(1, sizeof(struct blob_descriptor));
-       if (blob == NULL)
-               return NULL;
-
-       /* blob->refcnt = 0  */
-       /* blob->blob_location = BLOB_NONEXISTENT  */
        BUILD_BUG_ON(BLOB_NONEXISTENT != 0);
-
-       return blob;
+       return CALLOC(1, sizeof(struct blob_descriptor));
 }
 
 struct blob_descriptor *
@@ -152,21 +143,15 @@ clone_blob_descriptor(const struct blob_descriptor *old)
                                               sizeof(struct ntfs_location));
                        if (new->ntfs_loc == NULL)
                                goto out_free;
-                       new->ntfs_loc->path = STRDUP(old->ntfs_loc->path);
-                       new->ntfs_loc->attr_name = NULL;
-                       if (new->ntfs_loc->path == NULL)
-                               goto out_free;
-                       if (new->ntfs_loc->attr_name_nchars != 0) {
+                       if (new->ntfs_loc->attr_name != NULL) {
                                new->ntfs_loc->attr_name =
-                                       utf16le_dup(old->ntfs_loc->attr_name);
+                                       utf16le_dup(new->ntfs_loc->attr_name);
                                if (new->ntfs_loc->attr_name == NULL)
                                        goto out_free;
                        }
                }
                break;
 #endif
-       default:
-               break;
        }
        return new;
 
@@ -202,7 +187,6 @@ blob_release_location(struct blob_descriptor *blob)
 #ifdef WITH_NTFS_3G
        case BLOB_IN_NTFS_VOLUME:
                if (blob->ntfs_loc) {
-                       FREE(blob->ntfs_loc->path);
                        FREE(blob->ntfs_loc->attr_name);
                        FREE(blob->ntfs_loc);
                }
@@ -327,7 +311,7 @@ enlarge_blob_table(struct blob_table *table)
        size_t old_capacity, new_capacity;
        struct hlist_head *old_array, *new_array;
        struct blob_descriptor *blob;
-       struct hlist_node *cur, *tmp;
+       struct hlist_node *tmp;
        size_t i;
 
        old_capacity = table->capacity;
@@ -340,7 +324,7 @@ enlarge_blob_table(struct blob_table *table)
        table->capacity = new_capacity;
 
        for (i = 0; i < old_capacity; i++) {
-               hlist_for_each_entry_safe(blob, cur, tmp, &old_array[i], hash_list) {
+               hlist_for_each_entry_safe(blob, tmp, &old_array[i], hash_list) {
                        hlist_del(&blob->hash_list);
                        blob_table_insert_raw(table, blob);
                }
@@ -375,10 +359,9 @@ lookup_blob(const struct blob_table *table, const u8 *hash)
 {
        size_t i;
        struct blob_descriptor *blob;
-       struct hlist_node *pos;
 
        i = load_size_t_unaligned(hash) % table->capacity;
-       hlist_for_each_entry(blob, pos, &table->array[i], hash_list)
+       hlist_for_each_entry(blob, &table->array[i], hash_list)
                if (hashes_equal(hash, blob->hash))
                        return blob;
        return NULL;
@@ -391,11 +374,11 @@ for_blob_in_table(struct blob_table *table,
                  int (*visitor)(struct blob_descriptor *, void *), void *arg)
 {
        struct blob_descriptor *blob;
-       struct hlist_node *pos, *tmp;
+       struct hlist_node *tmp;
        int ret;
 
        for (size_t i = 0; i < table->capacity; i++) {
-               hlist_for_each_entry_safe(blob, pos, tmp, &table->array[i],
+               hlist_for_each_entry_safe(blob, tmp, &table->array[i],
                                          hash_list)
                {
                        ret = visitor(blob, arg);
@@ -465,7 +448,7 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2)
                return tstrcmp(blob1->file_on_disk, blob2->file_on_disk);
 #ifdef WITH_NTFS_3G
        case BLOB_IN_NTFS_VOLUME:
-               return tstrcmp(blob1->ntfs_loc->path, blob2->ntfs_loc->path);
+               return cmp_u64(blob1->ntfs_loc->mft_no, blob2->ntfs_loc->mft_no);
 #endif
        default:
                /* No additional sorting order defined for this resource
@@ -738,11 +721,9 @@ assign_blob_to_solid_resource(const struct wim_reshdr *reshdr,
        /* XXX: This linear search will be slow in the degenerate case where the
         * number of solid resources in the run is huge.  */
        blob->size = reshdr->size_in_wim;
-       blob->flags = reshdr->flags;
        for (size_t i = 0; i < num_rdescs; i++) {
                if (offset + blob->size <= rdescs[i]->uncompressed_size) {
-                       blob->offset_in_res = offset;
-                       blob_set_is_located_in_wim_resource(blob, rdescs[i]);
+                       blob_set_is_located_in_wim_resource(blob, rdescs[i], offset);
                        return 0;
                }
                offset -= rdescs[i]->uncompressed_size;
@@ -1012,11 +993,7 @@ read_blob_table(WIMStruct *wim)
 
                        wim_res_hdr_to_desc(&reshdr, wim, rdesc);
 
-                       cur_blob->offset_in_res = 0;
-                       cur_blob->size = reshdr.uncompressed_size;
-                       cur_blob->flags = reshdr.flags;
-
-                       blob_set_is_located_in_wim_resource(cur_blob, rdesc);
+                       blob_set_is_located_in_nonsolid_wim_resource(cur_blob, rdesc);
                }
 
                /* cur_blob is now a blob bound to a resource.  */
@@ -1034,6 +1011,8 @@ read_blob_table(WIMStruct *wim)
 
                if (reshdr.flags & WIM_RESHDR_FLAG_METADATA) {
 
+                       cur_blob->is_metadata = 1;
+
                        /* Blob table entry for a metadata resource.  */
 
                        /* Metadata entries with no references must be ignored.
@@ -1155,9 +1134,9 @@ write_blob_descriptor(struct blob_descriptor_disk *disk_entry,
 }
 
 /* Note: the list of blob descriptors must be sorted so that all entries for the
- * same solid resource are consecutive.  In addition, blob descriptors with
- * WIM_RESHDR_FLAG_METADATA set must be in the same order as the indices of the
- * underlying images.  */
+ * same solid resource are consecutive.  In addition, blob descriptors for
+ * metadata resources must be in the same order as the indices of the underlying
+ * images.  */
 int
 write_blob_table_from_blob_list(struct list_head *blob_list,
                                struct filedes *out_fd,
@@ -1239,7 +1218,7 @@ write_blob_table_from_blob_list(struct list_head *blob_list,
         * compressed blob table, MS software cannot.  */
        ret = write_wim_resource_from_buffer(table_buf,
                                             table_size,
-                                            WIM_RESHDR_FLAG_METADATA,
+                                            true,
                                             out_fd,
                                             WIMLIB_COMPRESSION_TYPE_NONE,
                                             0,
@@ -1258,29 +1237,27 @@ new_blob_from_data_buffer(const void *buffer, size_t size,
                          struct blob_table *blob_table)
 {
        u8 hash[SHA1_HASH_SIZE];
-       struct blob_descriptor *blob, *existing_blob;
+       struct blob_descriptor *blob;
+       void *buffer_copy;
 
        sha1_buffer(buffer, size, hash);
-       existing_blob = lookup_blob(blob_table, hash);
-       if (existing_blob) {
-               wimlib_assert(existing_blob->size == size);
-               blob = existing_blob;
-       } else {
-               void *buffer_copy;
-               blob = new_blob_descriptor();
-               if (blob == NULL)
-                       return NULL;
-               buffer_copy = memdup(buffer, size);
-               if (buffer_copy == NULL) {
-                       free_blob_descriptor(blob);
-                       return NULL;
-               }
-               blob->blob_location = BLOB_IN_ATTACHED_BUFFER;
-               blob->attached_buffer = buffer_copy;
-               blob->size = size;
-               copy_hash(blob->hash, hash);
-               blob_table_insert(blob_table, blob);
+
+       blob = lookup_blob(blob_table, hash);
+       if (blob)
+               return blob;
+
+       blob = new_blob_descriptor();
+       if (!blob)
+               return NULL;
+
+       buffer_copy = memdup(buffer, size);
+       if (!buffer_copy) {
+               free_blob_descriptor(blob);
+               return NULL;
        }
+       blob_set_is_located_in_attached_buffer(blob, buffer_copy, size);
+       copy_hash(blob->hash, hash);
+       blob_table_insert(blob_table, blob);
        return blob;
 }
 
@@ -1355,8 +1332,10 @@ blob_to_wimlib_resource_entry(const struct blob_descriptor *blob,
 
        wentry->uncompressed_size = blob->size;
        if (blob->blob_location == BLOB_IN_WIM) {
+               unsigned res_flags = blob->rdesc->flags;
+
                wentry->part_number = blob->rdesc->wim->hdr.part_number;
-               if (blob->flags & WIM_RESHDR_FLAG_SOLID) {
+               if (res_flags & WIM_RESHDR_FLAG_SOLID) {
                        wentry->offset = blob->offset_in_res;
                } else {
                        wentry->compressed_size = blob->rdesc->size_in_wim;
@@ -1365,14 +1344,16 @@ blob_to_wimlib_resource_entry(const struct blob_descriptor *blob,
                wentry->raw_resource_offset_in_wim = blob->rdesc->offset_in_wim;
                wentry->raw_resource_compressed_size = blob->rdesc->size_in_wim;
                wentry->raw_resource_uncompressed_size = blob->rdesc->uncompressed_size;
+
+               wentry->is_compressed = (res_flags & WIM_RESHDR_FLAG_COMPRESSED) != 0;
+               wentry->is_free = (res_flags & WIM_RESHDR_FLAG_FREE) != 0;
+               wentry->is_spanned = (res_flags & WIM_RESHDR_FLAG_SPANNED) != 0;
+               wentry->packed = (res_flags & WIM_RESHDR_FLAG_SOLID) != 0;
        }
-       copy_hash(wentry->sha1_hash, blob->hash);
+       if (!blob->unhashed)
+               copy_hash(wentry->sha1_hash, blob->hash);
        wentry->reference_count = blob->refcnt;
-       wentry->is_compressed = (blob->flags & WIM_RESHDR_FLAG_COMPRESSED) != 0;
-       wentry->is_metadata = (blob->flags & WIM_RESHDR_FLAG_METADATA) != 0;
-       wentry->is_free = (blob->flags & WIM_RESHDR_FLAG_FREE) != 0;
-       wentry->is_spanned = (blob->flags & WIM_RESHDR_FLAG_SPANNED) != 0;
-       wentry->packed = (blob->flags & WIM_RESHDR_FLAG_SOLID) != 0;
+       wentry->is_metadata = blob->is_metadata;
 }
 
 struct iterate_blob_context {
@@ -1406,10 +1387,17 @@ wimlib_iterate_lookup_table(WIMStruct *wim, int flags,
        if (wim_has_metadata(wim)) {
                int ret;
                for (int i = 0; i < wim->hdr.image_count; i++) {
-                       ret = do_iterate_blob(wim->image_metadata[i]->metadata_blob,
-                                             &ctx);
+                       struct blob_descriptor *blob;
+                       struct wim_image_metadata *imd = wim->image_metadata[i];
+
+                       ret = do_iterate_blob(imd->metadata_blob, &ctx);
                        if (ret)
                                return ret;
+                       image_for_each_unhashed_blob(blob, imd) {
+                               ret = do_iterate_blob(blob, &ctx);
+                               if (ret)
+                                       return ret;
+                       }
                }
        }
        return for_blob_in_table(wim->blob_table, do_iterate_blob, &ctx);