}
}
-static inline bool
-blob_is_in_file(const struct blob_descriptor *blob)
-{
- return blob->blob_location == BLOB_IN_FILE_ON_DISK
-#ifdef __WIN32__
- || blob->blob_location == BLOB_IN_WINNT_FILE_ON_DISK
- || blob->blob_location == BLOB_WIN32_ENCRYPTED
-#endif
- ;
-}
-
static void
init_done_with_file_info(struct list_head *blob_list)
{
wim_has_solid_resources(wim);
}
+/* Update the images' filecount/bytecount stats (in the XML info) to take into
+ * account any recent modifications. */
+static int
+update_image_stats(WIMStruct *wim)
+{
+ if (!wim_has_metadata(wim))
+ return 0;
+ for (int i = 0; i < wim->hdr.image_count; i++) {
+ struct wim_image_metadata *imd = wim->image_metadata[i];
+ if (imd->stats_outdated) {
+ int ret = xml_update_image_info(wim, i + 1);
+ if (ret)
+ return ret;
+ imd->stats_outdated = false;
+ }
+ }
+ return 0;
+}
+
/* Write a standalone WIM or split WIM (SWM) part to a new file or to a file
* descriptor. */
int
wim->out_hdr.boot_idx = 1;
}
+ /* Update image stats if needed. */
+ ret = update_image_stats(wim);
+ if (ret)
+ return ret;
+
/* Set up the output file descriptor. */
if (write_flags & WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR) {
/* File descriptor was explicitly provided. */
return 0;
}
+static int
+free_blob_if_invalidated(struct blob_descriptor *blob, void *_wim)
+{
+ const WIMStruct *wim = _wim;
+
+ if (!blob->will_be_in_output_wim &&
+ blob->blob_location == BLOB_IN_WIM && blob->rdesc->wim == wim)
+ {
+ blob_table_unlink(wim->blob_table, blob);
+ free_blob_descriptor(blob);
+ }
+ return 0;
+}
+
/*
* Overwrite a WIM, possibly appending new resources to it.
*
if (ret)
goto out;
+ /* Prevent new files from being deduplicated with existing blobs
+ * in the WIM that we haven't decided to write. Such blobs will
+ * be overwritten during the compaction. */
+ for_blob_in_table(wim->blob_table, free_blob_if_invalidated, wim);
+
if (wim_has_metadata(wim)) {
/* Add existing metadata resources to be compacted along
* with the file resources. */
wimlib_assert(list_empty(&blob_list));
}
+ /* Update image stats if needed. */
+ ret = update_image_stats(wim);
+ if (ret)
+ goto out;
+
ret = open_wim_writable(wim, wim->filename, O_RDWR);
if (ret)
goto out;