if (cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) {
/* Lookup table entry for a metadata resource */
if (cur_entry->refcnt != 1) {
+ /* Metadata entries with no references must be
+ * ignored. See for example the WinPE WIMs from
+ * WAIK v2.1. */
+ if (cur_entry->refcnt == 0) {
+ free_lookup_table_entry(cur_entry);
+ continue;
+ }
if (wimlib_print_errors) {
ERROR("Found metadata resource with refcnt != 1:");
print_lookup_table_entry(cur_entry, stderr);
write_wim_lookup_table_from_stream_list(struct list_head *stream_list,
struct filedes *out_fd,
struct resource_entry *out_res_entry,
- int write_resource_flags)
+ int write_resource_flags,
+ struct wimlib_lzx_context **comp_ctx)
{
size_t table_size;
struct wim_lookup_table_entry *lte;
WIMLIB_COMPRESSION_TYPE_NONE,
out_res_entry,
NULL,
- write_resource_flags);
+ write_resource_flags,
+ comp_ctx);
FREE(table_buf);
return ret;
}
return write_wim_lookup_table_from_stream_list(stream_list,
&wim->out_fd,
out_res_entry,
- write_resource_flags);
+ write_resource_flags,
+ &wim->lzx_context);
}
return -ENOENT;
}
} else {
- lte = inode->i_lte;
- stream_idx = 0;
+ lte = inode_unnamed_stream_resolved(inode, &stream_idx);
}
out:
if (dentry_ret)
#endif
int
-resource_not_found_error(struct wim_inode *inode, const u8 *hash)
+resource_not_found_error(const struct wim_inode *inode, const u8 *hash)
{
if (wimlib_print_errors) {
ERROR("\"%"TS"\": resource not found", inode_first_full_path(inode));
}
struct wim_lookup_table_entry *
-inode_unnamed_lte_resolved(const struct wim_inode *inode)
+inode_unnamed_stream_resolved(const struct wim_inode *inode, u16 *stream_idx_ret)
{
wimlib_assert(inode->i_resolved);
for (unsigned i = 0; i <= inode->i_num_ads; i++) {
if (inode_stream_name_nbytes(inode, i) == 0 &&
!is_zero_hash(inode_stream_hash_resolved(inode, i)))
{
+ *stream_idx_ret = i;
return inode_stream_lte_resolved(inode, i);
}
}
+ *stream_idx_ret = 0;
return NULL;
}
+struct wim_lookup_table_entry *
+inode_unnamed_lte_resolved(const struct wim_inode *inode)
+{
+ u16 stream_idx;
+ return inode_unnamed_stream_resolved(inode, &stream_idx);
+}
+
struct wim_lookup_table_entry *
inode_unnamed_lte_unresolved(const struct wim_inode *inode,
const struct wim_lookup_table *table)
return inode_unnamed_lte_unresolved(inode, table);
}
+/* Returns the SHA1 message digest of the unnamed data stream of a WIM inode, or
+ * 'zero_hash' if the unnamed data stream is missing has all zeroes in its SHA1
+ * message digest field. */
+const u8 *
+inode_unnamed_stream_hash(const struct wim_inode *inode)
+{
+ const u8 *hash;
+
+ for (unsigned i = 0; i <= inode->i_num_ads; i++) {
+ if (inode_stream_name_nbytes(inode, i) == 0) {
+ hash = inode_stream_hash(inode, i);
+ if (!is_zero_hash(hash))
+ return hash;
+ }
+ }
+ return zero_hash;
+}
+
+
static int
lte_add_stream_size(struct wim_lookup_table_entry *lte, void *total_bytes_p)
{
unsigned i;
int ret;
- open_flags |= WIMLIB_OPEN_FLAG_SPLIT_OK;
-
resource_wims = CALLOC(num_resource_wimfiles, sizeof(resource_wims[0]));
if (!resource_wims)
return WIMLIB_ERR_NOMEM;