X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Flookup_table.c;h=815d576fe551177200b8b781c3a69621d7210530;hp=f54f0cc675e0de4dc3d4db1e06eaf5296b78a2ce;hb=b6034a5dd44709341c46d553b1c0294ec91f13e4;hpb=14eb8a036c98463b8cc7e33bd345708d7b2f791a diff --git a/src/lookup_table.c b/src/lookup_table.c index f54f0cc6..815d576f 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -323,7 +323,6 @@ for_lookup_table_entry(struct wim_lookup_table *table, hlist_for_each_entry_safe(lte, pos, tmp, &table->array[i], hash_list) { - wimlib_assert2(!(lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA)); ret = visitor(lte, arg); if (ret) return ret; @@ -620,7 +619,7 @@ read_wim_lookup_table(WIMStruct *wim) if (cur_entry == NULL) { ERROR("Not enough memory to read lookup table!"); ret = WIMLIB_ERR_NOMEM; - goto out_free_lookup_table; + goto err; } part_number = le16_to_cpu(disk_entry->part_number); @@ -640,7 +639,7 @@ read_wim_lookup_table(WIMStruct *wim) if (reshdr.uncompressed_size != reshdr.size_in_wim) { ERROR("Invalid resource entry!"); ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; - goto out_free_cur_entry; + goto err; } } @@ -657,17 +656,18 @@ read_wim_lookup_table(WIMStruct *wim) * resource. */ struct wim_lookup_table_entry *prev_entry = NULL; - if (back_to_back_pack) { + if (back_to_back_pack && + !list_empty(&cur_rspec->stream_list)) + { prev_entry = list_entry(cur_rspec->stream_list.prev, struct wim_lookup_table_entry, rspec_node); lte_unbind_wim_resource_spec(prev_entry); - cur_rspec->uncompressed_size -= prev_entry->size; } if (cur_rspec != NULL) { ret = validate_resource(cur_rspec); if (ret) - goto out_free_cur_entry; + goto err; } /* Allocate the resource specification and initialize it @@ -676,24 +676,12 @@ read_wim_lookup_table(WIMStruct *wim) if (cur_rspec == NULL) { ERROR("Not enough memory to read lookup table!"); ret = WIMLIB_ERR_NOMEM; - goto out_free_cur_entry; + goto err; } wim_res_hdr_to_spec(&reshdr, wim, cur_rspec); - /* If this is a packed run, the current stream entry may - * specify a stream within the resource, and not the - * resource itself. Zero possibly irrelevant data until - * it is read for certain. */ - if (reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS) { - cur_rspec->size_in_wim = 0; - cur_rspec->uncompressed_size = 0; - cur_rspec->offset_in_wim = 0; - } - - if (prev_entry) { + if (prev_entry) lte_bind_wim_resource_spec(prev_entry, cur_rspec); - cur_rspec->uncompressed_size = prev_entry->size; - } } if ((reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS) && @@ -703,11 +691,36 @@ read_wim_lookup_table(WIMStruct *wim) * Transfer the values to the `struct * wim_resource_spec', and discard the current stream * since this lookup table entry did not, in fact, - * correspond to a "stream". */ + * correspond to a "stream". + */ + + /* Uncompressed size of the resource pack is actually + * stored in the header of the resource itself. Read + * it, and also grab the chunk size and compression type + * (which are not necessarily the defaults from the WIM + * header). */ + struct alt_chunk_table_header_disk hdr; + + ret = full_pread(&wim->in_fd, &hdr, + sizeof(hdr), reshdr.offset_in_wim); + if (ret) + goto err; + cur_rspec->uncompressed_size = le64_to_cpu(hdr.res_usize); cur_rspec->offset_in_wim = reshdr.offset_in_wim; cur_rspec->size_in_wim = reshdr.size_in_wim; cur_rspec->flags = reshdr.flags; + + /* Compression format numbers must be the same as in + * WIMGAPI to be compatible here. */ + BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_NONE != 0); + BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_LZX != 1); + BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_XPRESS != 2); + BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_LZMS != 3); + cur_rspec->compression_type = le32_to_cpu(hdr.compression_format); + + cur_rspec->chunk_size = le32_to_cpu(hdr.chunk_size); + DEBUG("Full pack is %"PRIu64" compressed bytes " "at file offset %"PRIu64" (flags 0x%02x)", cur_rspec->size_in_wim, @@ -724,10 +737,10 @@ read_wim_lookup_table(WIMStruct *wim) if (reshdr.flags & WIM_RESHDR_FLAG_PACKED_STREAMS) { /* Continuing the pack with another stream. */ - DEBUG("Continuing packed run with stream: " - "%"PRIu64" uncompressed bytes @ resource offset %"PRIu64")", + DEBUG("Continuing pack with stream: " + "%"PRIu64" uncompressed bytes @ " + "resource offset %"PRIu64")", reshdr.size_in_wim, reshdr.offset_in_wim); - cur_rspec->uncompressed_size += reshdr.size_in_wim; } lte_bind_wim_resource_spec(cur_entry, cur_rspec); @@ -765,7 +778,7 @@ read_wim_lookup_table(WIMStruct *wim) print_lookup_table_entry(cur_entry, stderr); } ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY; - goto out_free_cur_entry; + goto err; } if (wim->hdr.part_number != 1) { @@ -819,12 +832,13 @@ read_wim_lookup_table(WIMStruct *wim) * its SHA1 message digest. */ lookup_table_insert(table, cur_entry); } + cur_entry = NULL; /* Validate the last resource. */ if (cur_rspec != NULL) { ret = validate_resource(cur_rspec); if (ret) - goto out_free_lookup_table; + goto err; } if (wim->hdr.part_number == 1 && wim->current_image != wim->hdr.image_count) { @@ -842,9 +856,10 @@ read_wim_lookup_table(WIMStruct *wim) ret = 0; goto out_free_buf; -out_free_cur_entry: - FREE(cur_entry); -out_free_lookup_table: +err: + if (cur_rspec && list_empty(&cur_rspec->stream_list)) + FREE(cur_rspec); + free_lookup_table_entry(cur_entry); free_lookup_table(table); out_free_buf: FREE(buf); @@ -869,8 +884,7 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list, struct filedes *out_fd, u16 part_number, struct wim_reshdr *out_reshdr, - int write_resource_flags, - struct wimlib_lzx_context **comp_ctx) + int write_resource_flags) { size_t table_size; struct wim_lookup_table_entry *lte; @@ -950,8 +964,7 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list, 0, out_reshdr, NULL, - write_resource_flags, - comp_ctx); + write_resource_flags); FREE(table_buf); DEBUG("ret=%d", ret); return ret; @@ -1177,7 +1190,7 @@ wim_pathname_to_stream(WIMStruct *wim, } } - dentry = get_dentry(wim, path); + dentry = get_dentry(wim, path, WIMLIB_CASE_SENSITIVE); if (p) *p = T(':'); if (!dentry)