X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Flookup_table.c;h=6f0786500b817b3bb3568f344778afe1fe623165;hb=117e52b79b02f1889f1bccd9d8560b73a965c559;hp=c30c479b0e97af7e3cecb4fee337bb8adf549e23;hpb=07e37b8d03fb6cd8bd5905905dd52807774204cd;p=wimlib diff --git a/src/lookup_table.c b/src/lookup_table.c index c30c479b..6f078650 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2012, 2013 Eric Biggers + * Copyright (C) 2012, 2013, 2014 Eric Biggers * * This file is part of wimlib, a library for working with WIM files. * @@ -94,17 +94,11 @@ do_free_lookup_table_entry(struct wim_lookup_table_entry *entry, void *ignore) void free_lookup_table(struct wim_lookup_table *table) { - DEBUG("Freeing lookup table."); - if (table == NULL) - return; - - if (table->array) { - for_lookup_table_entry(table, - do_free_lookup_table_entry, - NULL); + if (table) { + for_lookup_table_entry(table, do_free_lookup_table_entry, NULL); FREE(table->array); + FREE(table); } - FREE(table); } struct wim_lookup_table_entry * @@ -429,7 +423,7 @@ cmp_streams_by_sequential_order(const void *p1, const void *p2) /* Different (possibly split) WIMs? */ if (wim1 != wim2) { - v = memcmp(wim1->hdr.guid, wim2->hdr.guid, WIM_GID_LEN); + v = memcmp(wim1->hdr.guid, wim2->hdr.guid, WIM_GUID_LEN); if (v) return v; } @@ -1021,6 +1015,10 @@ read_wim_lookup_table(WIMStruct *wim) /* cur_entry is now a stream bound to a resource. */ + /* Ignore entries with all zeroes in the hash field. */ + if (is_zero_hash(cur_entry->hash)) + goto free_cur_entry_and_continue; + /* Verify that the part number matches that of the underlying * WIM file. */ if (part_number != wim->hdr.part_number) { @@ -1028,10 +1026,6 @@ read_wim_lookup_table(WIMStruct *wim) goto free_cur_entry_and_continue; } - /* Ignore entries with all zeroes in the hash field. */ - if (is_zero_hash(cur_entry->hash)) - goto free_cur_entry_and_continue; - if (reshdr.flags & WIM_RESHDR_FLAG_METADATA) { /* Lookup table entry for a metadata resource. */ @@ -1156,6 +1150,10 @@ put_wim_lookup_table_entry(struct wim_lookup_table_entry_disk *disk_entry, copy_hash(disk_entry->hash, hash); } +/* Note: the list of stream entries must be sorted so that all entries for the + * same packed resource are consecutive. In addition, entries with + * WIM_RESHDR_FLAG_METADATA set must be in the same order as the indices of the + * underlying images. */ int write_wim_lookup_table_from_stream_list(struct list_head *stream_list, struct filedes *out_fd, @@ -1169,6 +1167,8 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list, struct wim_lookup_table_entry_disk *table_buf_ptr; int ret; u64 prev_res_offset_in_wim = ~0ULL; + u64 prev_uncompressed_size; + u64 logical_offset; table_size = 0; list_for_each_entry(lte, stream_list, lookup_table_list) { @@ -1194,38 +1194,46 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list, table_buf_ptr = table_buf; prev_res_offset_in_wim = ~0ULL; + prev_uncompressed_size = 0; + logical_offset = 0; list_for_each_entry(lte, stream_list, lookup_table_list) { + if (lte->out_reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS) { + struct wim_reshdr tmp_reshdr; - put_wim_lookup_table_entry(table_buf_ptr++, - <e->out_reshdr, - part_number, - lte->out_refcnt, - lte->hash); - if (lte->out_reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS && - lte->out_res_offset_in_wim != prev_res_offset_in_wim) - { - /* Put the main resource entry for the pack. */ + /* Eww. When WIMGAPI sees multiple resource packs, it + * expects the offsets to be adjusted as if there were + * really only one pack. */ - struct wim_reshdr reshdr; + if (lte->out_res_offset_in_wim != prev_res_offset_in_wim) { + /* Put the resource entry for pack */ + tmp_reshdr.offset_in_wim = lte->out_res_offset_in_wim; + tmp_reshdr.size_in_wim = lte->out_res_size_in_wim; + tmp_reshdr.uncompressed_size = WIM_PACK_MAGIC_NUMBER; + tmp_reshdr.flags = WIM_RESHDR_FLAG_PACKED_STREAMS; - reshdr.offset_in_wim = lte->out_res_offset_in_wim; - reshdr.size_in_wim = lte->out_res_size_in_wim; - reshdr.uncompressed_size = WIM_PACK_MAGIC_NUMBER; - reshdr.flags = WIM_RESHDR_FLAG_PACKED_STREAMS; + put_wim_lookup_table_entry(table_buf_ptr++, + &tmp_reshdr, + part_number, + 1, zero_hash); - DEBUG("Putting main entry for pack: " - "size_in_wim=%"PRIu64", " - "offset_in_wim=%"PRIu64", " - "uncompressed_size=%"PRIu64, - reshdr.size_in_wim, - reshdr.offset_in_wim, - reshdr.uncompressed_size); + logical_offset += prev_uncompressed_size; + prev_res_offset_in_wim = lte->out_res_offset_in_wim; + prev_uncompressed_size = lte->out_res_uncompressed_size; + } + tmp_reshdr = lte->out_reshdr; + tmp_reshdr.offset_in_wim += logical_offset; put_wim_lookup_table_entry(table_buf_ptr++, - &reshdr, + &tmp_reshdr, part_number, - 1, zero_hash); - prev_res_offset_in_wim = lte->out_res_offset_in_wim; + lte->out_refcnt, + lte->hash); + } else { + put_wim_lookup_table_entry(table_buf_ptr++, + <e->out_reshdr, + part_number, + lte->out_refcnt, + lte->hash); } } @@ -1420,7 +1428,7 @@ wimlib_iterate_lookup_table(WIMStruct *wim, int flags, .cb = cb, .user_ctx = user_ctx, }; - if (wim->hdr.part_number == 1) { + if (wim_has_metadata(wim)) { int ret; for (int i = 0; i < wim->hdr.image_count; i++) { ret = do_iterate_lte(wim->image_metadata[i]->metadata_lte,