cur_entry->refcnt = le32_to_cpu(disk_entry->refcnt);
copy_hash(cur_entry->hash, disk_entry->hash);
+ if (cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED)
+ cur_entry->compression_type = w->compression_type;
+ else
+ BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_NONE != 0);
+
if (cur_entry->part_number != w->hdr.part_number) {
WARNING("A lookup table entry in part %hu of the WIM "
"points to part %hu (ignoring it)",
}
}
- if (w->hdr.part_number == 1 && w->current_image != w->hdr.image_count)
- {
- ERROR("The WIM header says there are %u images "
- "in the WIM, but we only found %d metadata "
- "resources!", w->hdr.image_count, w->current_image);
- ret = WIMLIB_ERR_IMAGE_COUNT;
- goto out_free_lookup_table;
+ if (w->hdr.part_number == 1 && w->current_image != w->hdr.image_count) {
+ WARNING("The header of \"%"TS"\" says there are %u images in\n"
+ " the WIM, but we only found %d metadata resources! Acting as if\n"
+ " the header specified only %d images instead.",
+ w->filename, w->hdr.image_count,
+ w->current_image, w->current_image);
+ for (int i = w->current_image; i < w->hdr.image_count; i++)
+ put_image_metadata(w->image_metadata[i], NULL);
+ w->hdr.image_count = w->current_image;
}
DEBUG("Done reading lookup table.");
w->lookup_table = table;
inode = dentry->d_inode;
- wimlib_assert(inode->i_resolved);
+ if (!inode->i_resolved)
+ if (inode_resolve_ltes(inode, w->lookup_table))
+ return -EIO;
if (!(lookup_flags & LOOKUP_FLAG_DIRECTORY_OK)
&& inode_is_directory(inode))
}
#endif
-/*
- * XXX Probably should store the compression type directly in the lookup table
- * entry
- */
-int
-wim_resource_compression_type(const struct wim_lookup_table_entry *lte)
-{
- if (!(lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED)
- || lte->resource_location != RESOURCE_IN_WIM)
- return WIMLIB_COMPRESSION_TYPE_NONE;
- return wimlib_get_compression_type(lte->wim);
-}
-
/* Resolve an inode's lookup table entries
*
* This replaces the SHA1 hash fields (which are used to lookup an entry in the
* This function always succeeds; unresolved lookup table entries are given a
* NULL pointer.
*/
-void
+int
inode_resolve_ltes(struct wim_inode *inode, struct wim_lookup_table *table)
{
+ const u8 *hash;
if (!inode->i_resolved) {
- struct wim_lookup_table_entry *lte;
+ struct wim_lookup_table_entry *lte, *ads_lte;
+
/* Resolve the default file stream */
- lte = __lookup_resource(table, inode->i_hash);
- inode->i_lte = lte;
- inode->i_resolved = 1;
+ lte = NULL;
+ hash = inode->i_hash;
+ if (!is_zero_hash(hash)) {
+ lte = __lookup_resource(table, hash);
+ if (unlikely(!lte))
+ goto resource_not_found;
+ }
/* Resolve the alternate data streams */
+ struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads];
for (u16 i = 0; i < inode->i_num_ads; i++) {
- struct wim_ads_entry *cur_entry = &inode->i_ads_entries[i];
- lte = __lookup_resource(table, cur_entry->hash);
- cur_entry->lte = lte;
+ struct wim_ads_entry *cur_entry;
+
+ ads_lte = NULL;
+ cur_entry = &inode->i_ads_entries[i];
+ hash = cur_entry->hash;
+ if (!is_zero_hash(hash)) {
+ ads_lte = __lookup_resource(table, hash);
+ if (unlikely(!ads_lte))
+ goto resource_not_found;
+ }
+ ads_ltes[i] = ads_lte;
}
+ inode->i_lte = lte;
+ for (u16 i = 0; i < inode->i_num_ads; i++)
+ inode->i_ads_entries[i].lte = ads_ltes[i];
+ inode->i_resolved = 1;
+ }
+ return 0;
+resource_not_found:
+ if (wimlib_print_errors) {
+ ERROR("\"%"TS"\": resource not found", inode_first_full_path(inode));
+ tfprintf(stderr, T(" SHA-1 message digest of missing resource:\n "));
+ print_hash(hash, stderr);
+ tputc(T('\n'), stderr);
}
+ return WIMLIB_ERR_RESOURCE_NOT_FOUND;
}
void