]> wimlib.net Git - wimlib/blobdiff - src/lookup_table.c
xml.c: Fix writing <WINDOWS> element
[wimlib] / src / lookup_table.c
index f7fb7c3a5dff9ee263e28b5c748798adc437d1f6..553cf33b1c413f4dbfa430291b8439b85abec869 100644 (file)
@@ -574,6 +574,13 @@ read_wim_lookup_table(WIMStruct *wim)
                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);
@@ -671,7 +678,8 @@ static int
 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;
@@ -705,8 +713,10 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list,
                                             WIMLIB_COMPRESSION_TYPE_NONE,
                                             out_res_entry,
                                             NULL,
-                                            write_resource_flags);
+                                            write_resource_flags,
+                                            comp_ctx);
        FREE(table_buf);
+       DEBUG("ret=%d", ret);
        return ret;
 }
 
@@ -796,7 +806,8 @@ write_wim_lookup_table(WIMStruct *wim, int image, int write_flags,
        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);
 }
 
 
@@ -1020,8 +1031,7 @@ wim_pathname_to_stream(WIMStruct *wim,
                        return -ENOENT;
                }
        } else {
-               lte = inode->i_lte;
-               stream_idx = 0;
+               lte = inode_unnamed_stream_resolved(inode, &stream_idx);
        }
 out:
        if (dentry_ret)
@@ -1035,7 +1045,7 @@ out:
 #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));
@@ -1160,19 +1170,28 @@ inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx,
 }
 
 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)
@@ -1214,6 +1233,25 @@ inode_unnamed_lte(const struct wim_inode *inode,
                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)
 {