+lte_overwrite_prepare_2(struct wim_lookup_table_entry *lte, void *_args)
+{
+ struct lte_overwrite_prepare_args *args = _args;
+
+ if (lte->resource_location == RESOURCE_IN_WIM && lte->wim == args->wim) {
+ /* We can't do an in place overwrite on the WIM if there are
+ * streams after the XML data. */
+ if (lte->resource_entry.offset +
+ lte->resource_entry.size > args->end_offset)
+ {
+ if (wimlib_print_errors) {
+ ERROR("The following resource is after the XML data:");
+ print_lookup_table_entry(lte, stderr);
+ }
+ return WIMLIB_ERR_RESOURCE_ORDER;
+ }
+ copy_resource_entry(<e->output_resource_entry,
+ <e->resource_entry);
+ }
+ return 0;
+}
+
+/* Given a WIM that we are going to overwrite in place with zero or more
+ * additional streams added, construct a list the list of new unique streams
+ * ('struct wim_lookup_table_entry's) that must be written, plus any unhashed
+ * streams that need to be added but may be identical to other hashed or
+ * unhashed streams. These unhashed streams are checksummed while the streams
+ * are being written. To aid this process, the member @unique_size is set to 1
+ * on streams that have a unique size and therefore must be written.
+ *
+ * The out_refcnt member of each 'struct wim_lookup_table_entry' is set to
+ * indicate the number of times the stream is referenced in only the streams
+ * that are being written; this may still be adjusted later when unhashed
+ * streams are being resolved.
+ */
+static int
+prepare_streams_for_overwrite(WIMStruct *wim, off_t end_offset,
+ struct list_head *stream_list)
+{
+ int ret;
+ struct lte_overwrite_prepare_args args;
+ unsigned i;
+
+ args.wim = wim;
+ args.end_offset = end_offset;
+ ret = init_stream_size_table(&args.stream_size_tab,
+ wim->lookup_table->capacity);
+ if (ret)
+ return ret;
+
+ INIT_LIST_HEAD(&args.stream_list);
+ for (i = 0; i < wim->hdr.image_count; i++) {
+ struct wim_image_metadata *imd;
+ struct wim_lookup_table_entry *lte;
+
+ imd = wim->image_metadata[i];
+ image_for_each_unhashed_stream(lte, imd)
+ lte_overwrite_prepare(lte, &args);
+ }
+ for_lookup_table_entry(wim->lookup_table, lte_overwrite_prepare, &args);
+ list_transfer(&args.stream_list, stream_list);
+
+ for (i = 0; i < wim->hdr.image_count; i++) {
+ ret = lte_overwrite_prepare_2(wim->image_metadata[i]->metadata_lte,
+ &args);
+ if (ret)
+ goto out_destroy_stream_size_table;
+ }
+ ret = for_lookup_table_entry(wim->lookup_table,
+ lte_overwrite_prepare_2, &args);
+out_destroy_stream_size_table:
+ destroy_stream_size_table(&args.stream_size_tab);
+ return ret;
+}
+
+
+struct find_streams_ctx {
+ struct list_head stream_list;
+ struct stream_size_table stream_size_tab;
+};
+
+static void