X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fblob_table.c;h=08859c42787baa5147a398bdacdecae579f69275;hb=593660b74e10631a4e1acca5ea684e4a55e84682;hp=c94635f105b57add5fc422cf6017da9c57944bbb;hpb=d8af927e5d02cbcfc45cd1a3568b31c9814ec6f5;p=wimlib diff --git a/src/blob_table.c b/src/blob_table.c index c94635f1..08859c42 100644 --- a/src/blob_table.c +++ b/src/blob_table.c @@ -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 * @@ -147,26 +138,11 @@ clone_blob_descriptor(const struct blob_descriptor *old) break; #ifdef WITH_NTFS_3G case BLOB_IN_NTFS_VOLUME: - if (old->ntfs_loc) { - new->ntfs_loc = memdup(old->ntfs_loc, - 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) { - new->ntfs_loc->attr_name = - utf16le_dup(old->ntfs_loc->attr_name); - if (new->ntfs_loc->attr_name == NULL) - goto out_free; - } - } + new->ntfs_loc = clone_ntfs_location(old->ntfs_loc); + if (!new->ntfs_loc) + goto out_free; break; #endif - default: - break; } return new; @@ -201,15 +177,10 @@ blob_release_location(struct blob_descriptor *blob) break; #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); - } + if (blob->ntfs_loc) + free_ntfs_location(blob->ntfs_loc); break; #endif - default: - break; } } @@ -327,7 +298,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 +311,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 +346,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 +361,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); @@ -425,7 +395,7 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2) v = (int)blob1->blob_location - (int)blob2->blob_location; - /* Different resource locations? */ + /* Different locations? */ if (v) return v; @@ -459,13 +429,17 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2) #ifdef __WIN32__ case BLOB_IN_WINNT_FILE_ON_DISK: case BLOB_WIN32_ENCRYPTED: + /* Windows: compare by starting LCN (logical cluster number) */ + v = cmp_u64(blob1->sort_key, blob2->sort_key); + if (v) + return v; #endif /* Compare files by path: just a heuristic that will place files * in the same directory next to each other. */ 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_ntfs_locations(blob1->ntfs_loc, blob2->ntfs_loc); #endif default: /* No additional sorting order defined for this resource @@ -740,8 +714,7 @@ assign_blob_to_solid_resource(const struct wim_reshdr *reshdr, blob->size = reshdr->size_in_wim; 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; @@ -1011,10 +984,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; - - 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. */ @@ -1052,6 +1022,13 @@ read_blob_table(WIMStruct *wim) goto out; } + if (reshdr.flags & WIM_RESHDR_FLAG_SOLID) { + ERROR("Image metadata in solid resources " + "is unsupported."); + ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; + goto out; + } + if (wim->hdr.part_number != 1) { WARNING("Ignoring metadata resource found in a " "non-first part of the split WIM"); @@ -1258,29 +1235,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; } @@ -1373,7 +1348,8 @@ blob_to_wimlib_resource_entry(const struct blob_descriptor *blob, 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_metadata = blob->is_metadata; } @@ -1409,10 +1385,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);