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);
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;
}
}
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
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) &&
* 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,
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);
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) {
* 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) {
ret = 0;
goto out_free_buf;
-out_free_cur_entry:
+err:
+ if (cur_rspec && list_empty(&cur_rspec->stream_list))
+ FREE(cur_rspec);
free_lookup_table_entry(cur_entry);
-out_free_lookup_table:
free_lookup_table(table);
out_free_buf:
FREE(buf);