if (!fp) {
ERROR_WITH_ERRNO("Failed to open the file "
"`%s'", lte->file_on_disk);
+ return WIMLIB_ERR_OPEN;
}
}
ret = read_uncompressed_resource(fp, offset, size, buf);
unsigned *compressed_chunk_len_ret,
int ctype)
{
- unsigned compressed_chunk_sz;
int (*compress)(const void *, unsigned, void *, unsigned *);
switch (ctype) {
case WIM_COMPRESSION_TYPE_LZX:
} else {
u8 *compressed_chunk = alloca(chunk_size);
int ret;
- unsigned compressed_chunk_len;
ret = compress_chunk(chunk, chunk_size, compressed_chunk,
&out_chunk_size, out_ctype);
{
size_t bytes_written;
if (fseeko(out_fp, chunk_tab->file_offset, SEEK_SET) != 0) {
- ERROR_WITH_ERRNO("Failed to seek to byte "PRIu64" of output "
+ ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" of output "
"WIM file", chunk_tab->file_offset);
return WIMLIB_ERR_WRITE;
}
return 0;
/* Buffer for reading chunks for the resource */
- char buf[min(WIM_CHUNK_SIZE, bytes_remaining)];
+ u8 buf[min(WIM_CHUNK_SIZE, bytes_remaining)];
/* If we are writing a compressed resource and not doing a raw copy, we
* need to initialize the chunk table */
}
}
- if (new_compressed_size > original_size) {
+ if (new_compressed_size >= original_size &&
+ out_ctype != WIM_COMPRESSION_TYPE_NONE && !raw)
+ {
/* Oops! We compressed the resource to larger than the original
* size. Write the resource uncompressed instead. */
if (fseeko(out_fp, file_offset, SEEK_SET) != 0) {
- ERROR_WITH_ERRNO("Failed to seek to byte "PRIu64" "
+ ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" "
"of output WIM file", file_offset);
ret = WIMLIB_ERR_WRITE;
goto out_fclose;
u64 size)
{
u64 bytes_remaining = size;
- char buf[min(WIM_CHUNK_SIZE, bytes_remaining)];
+ u8 buf[min(WIM_CHUNK_SIZE, bytes_remaining)];
u64 offset = 0;
int ret = 0;
u8 hash[SHA1_HASH_SIZE];
*
* @return: Zero on success, nonzero on failure.
*/
-int read_metadata_resource(FILE *fp, int wim_ctype, struct image_metadata *imd)
+int read_metadata_resource(WIMStruct *w, struct image_metadata *imd)
{
u8 *buf;
- int ctype;
u32 dentry_offset;
int ret;
struct dentry *dentry;
- struct wim_security_data *sd;
struct link_group_table *lgt;
const struct lookup_table_entry *metadata_lte;
u64 metadata_len;
* no security descriptors) and WIM_DENTRY_DISK_SIZE is for the root
* dentry. */
if (metadata_len < 8 + WIM_DENTRY_DISK_SIZE) {
- ERROR("Expected at least %zu bytes for the metadata resource",
+ ERROR("Expected at least %u bytes for the metadata resource",
8 + WIM_DENTRY_DISK_SIZE);
return WIMLIB_ERR_INVALID_RESOURCE_SIZE;
}
* and if successful, go ahead and calculate the offset in the metadata
* resource of the root dentry. */
- ret = read_security_data(buf, metadata_len, &sd);
+ ret = read_security_data(buf, metadata_len, &imd->security_data);
if (ret != 0)
goto out_free_buf;
if (ret != 0)
goto out_free_lgt;
- DEBUG("Freeing duplicate ADS entries in link group table");
- ret = link_groups_free_duplicate_data(lgt);
+ DEBUG("Fixing inconsistencies in the link groups");
+ ret = fix_link_groups(lgt);
if (ret != 0)
goto out_free_lgt;
+
+ DEBUG("Running miscellaneous verifications on the dentry tree");
+ ret = for_dentry_in_tree(dentry, verify_dentry, w);
+ if (ret != 0)
+ goto out_free_lgt;
+
DEBUG("Done reading image metadata");
imd->lgt = lgt;
- imd->security_data = sd;
imd->root_dentry = dentry;
goto out_free_buf;
out_free_lgt:
out_free_dentry_tree:
free_dentry_tree(dentry, NULL);
out_free_security_data:
- free_security_data(sd);
+ free_security_data(imd->security_data);
+ imd->security_data = NULL;
out_free_buf:
FREE(buf);
return ret;
int ret;
u64 subdir_offset;
struct dentry *root;
- struct lookup_table_entry *lte, *duplicate_lte;
+ struct lookup_table_entry *lte;
u64 metadata_original_size;
const struct wim_security_data *sd;
const unsigned random_tail_len = 20;
* - plus 8 bytes for an end-of-directory entry following the root
* dentry (shouldn't really be needed, but just in case...)
*/
- subdir_offset = ((sd->total_length + 7) & ~7) + dentry_total_length(root) + 8;
+ subdir_offset = ((sd->total_length + 7) & ~7) +
+ dentry_correct_total_length(root) + 8;
/* Calculate the subdirectory offsets for the entire dentry tree. */
calculate_subdir_offsets(root, &subdir_offset);