+#include <string.h>
+#include <sys/stat.h>
+
+#include "wimlib/alloca.h"
+#include "wimlib/assert.h"
+#include "wimlib/blob_table.h"
+#include "wimlib/capture.h"
+#include "wimlib/dentry.h"
+#include "wimlib/encoding.h"
+#include "wimlib/endianness.h"
+#include "wimlib/error.h"
+#include "wimlib/metadata.h"
+#include "wimlib/paths.h"
+#include "wimlib/progress.h"
+#include "wimlib/xml.h"
+
+/* Saved specification of a "primitive" update operation that was performed. */
+struct update_primitive {
+ enum {
+ /* Unlinked a dentry from its parent directory. */
+ UNLINK_DENTRY,
+
+ /* Linked a dentry into its parent directory. */
+ LINK_DENTRY,
+
+ /* Changed the file name of a dentry. */
+ CHANGE_FILE_NAME,
+
+ /* Changed the short name of a dentry. */
+ CHANGE_SHORT_NAME,
+ } type;
+
+ union {
+ /* For UNLINK_DENTRY and LINK_DENTRY operations */
+ struct {
+ /* Dentry that was linked or unlinked. */
+ struct wim_dentry *subject;
+
+ /* For link operations, the directory into which
+ * @subject was linked, or NULL if @subject was set as
+ * the root of the image.
+ *
+ * For unlink operations, the directory from which
+ * @subject was unlinked, or NULL if @subject was unset
+ * as the root of the image. */
+ struct wim_dentry *parent;
+ } link;
+
+ /* For CHANGE_FILE_NAME and CHANGE_SHORT_NAME operations */
+ struct {
+ /* Dentry that had its name changed. */
+ struct wim_dentry *subject;
+
+ /* The old name. */
+ utf16lechar *old_name;
+ } name;
+ };
+};
+
+/* Chronological list of primitive operations that were executed for a single
+ * logical update command, such as 'add', 'delete', or 'rename'. */
+struct update_primitive_list {
+ struct update_primitive *entries;
+ struct update_primitive inline_entries[4];
+ size_t num_entries;
+ size_t num_alloc_entries;
+};
+
+/* Journal for managing the executing of zero or more logical update commands,
+ * such as 'add', 'delete', or 'rename'. This allows either committing or
+ * rolling back the commands. */
+struct update_command_journal {
+ /* Number of update commands this journal contains. */
+ size_t num_cmds;
+
+ /* Index of currently executing update command. */
+ size_t cur_cmd;
+
+ /* Location of the WIM image's root pointer. */
+ struct wim_dentry **root_p;
+
+ /* Pointer to the blob table of the WIM (may needed for rollback) */
+ struct blob_table *blob_table;
+
+ /* List of dentries that are currently unlinked from the WIM image.
+ * These must be freed when no longer needed for commit or rollback. */
+ struct list_head orphans;
+
+ /* Per-command logs. */
+ struct update_primitive_list cmd_prims[];
+};
+
+static void
+init_update_primitive_list(struct update_primitive_list *l)
+{
+ l->entries = l->inline_entries;
+ l->num_entries = 0;
+ l->num_alloc_entries = ARRAY_LEN(l->inline_entries);
+}