]> wimlib.net Git - wimlib/commitdiff
Document wimlib_update_image()
authorEric Biggers <ebiggers3@gmail.com>
Sun, 12 May 2013 02:51:58 +0000 (21:51 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 12 May 2013 02:51:58 +0000 (21:51 -0500)
src/capture_common.c
src/dentry.c
src/dentry.h
src/metadata_resource.c
src/mount_image.c
src/unix_capture.c
src/update_image.c
src/util.c
src/wimlib.h
src/win32.c

index 431a468116decb92d4aaef4b7167f1bc9a3c45b5..a18b49ca9e226740080920401152d51fb676bdea 100644 (file)
@@ -1,3 +1,7 @@
+/*
+ * capture_common.c - Mostly code to handle excluding paths from capture.
+ */
+
 /*
  * Copyright (C) 2013 Eric Biggers
  *
 /*
  * Copyright (C) 2013 Eric Biggers
  *
@@ -178,6 +182,8 @@ bool
 exclude_path(const tchar *path, size_t path_len,
             const struct wimlib_capture_config *config, bool exclude_prefix)
 {
 exclude_path(const tchar *path, size_t path_len,
             const struct wimlib_capture_config *config, bool exclude_prefix)
 {
+       if (!config)
+               return false;
        const tchar *basename = path_basename_with_len(path, path_len);
        if (exclude_prefix) {
                wimlib_assert(path_len >= config->_prefix_num_tchars);
        const tchar *basename = path_basename_with_len(path, path_len);
        if (exclude_prefix) {
                wimlib_assert(path_len >= config->_prefix_num_tchars);
index 48b310411f2d1ed447bcd6eb19298f4ab90e01fc..1d367bfe06e6d5a4e7260173d11240ad945bd380 100644 (file)
@@ -499,6 +499,10 @@ get_dentry_utf16le(WIMStruct *w, const utf16lechar *path,
        const utf16lechar *p, *pp;
 
        cur_dentry = parent_dentry = wim_root_dentry(w);
        const utf16lechar *p, *pp;
 
        cur_dentry = parent_dentry = wim_root_dentry(w);
+       if (!cur_dentry) {
+               errno = ENOENT;
+               return NULL;
+       }
        p = path;
        while (1) {
                while (*p == cpu_to_le16('/'))
        p = path;
        while (1) {
                while (*p == cpu_to_le16('/'))
@@ -805,6 +809,25 @@ new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret)
        return __new_dentry_with_inode(name, dentry_ret, false);
 }
 
        return __new_dentry_with_inode(name, dentry_ret, false);
 }
 
+int
+new_filler_directory(const tchar *name, struct wim_dentry **dentry_ret)
+{
+       int ret;
+       struct wim_dentry *dentry;
+
+       DEBUG("Creating filler directory \"%"TS"\"", name);
+       ret = new_dentry_with_inode(name, &dentry);
+       if (ret)
+               goto out;
+       /* Leave the inode number as 0; this is allowed for non
+        * hard-linked files. */
+       dentry->d_inode->i_resolved = 1;
+       dentry->d_inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY;
+       *dentry_ret = dentry;
+       ret = 0;
+out:
+       return ret;
+}
 
 static int
 init_ads_entry(struct wim_ads_entry *ads_entry, const void *name,
 
 static int
 init_ads_entry(struct wim_ads_entry *ads_entry, const void *name,
index 58adb5e681a9022b599be911d90219097d96f4a9..06fa445e7afb499e1859424a5a50eb9886b2621f 100644 (file)
@@ -408,6 +408,9 @@ new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret);
 extern int
 new_dentry_with_timeless_inode(const tchar *name, struct wim_dentry **dentry_ret);
 
 extern int
 new_dentry_with_timeless_inode(const tchar *name, struct wim_dentry **dentry_ret);
 
+extern int
+new_filler_directory(const tchar *name, struct wim_dentry **dentry_ret);
+
 extern void
 free_inode(struct wim_inode *inode);
 
 extern void
 free_inode(struct wim_inode *inode);
 
index 3e8b7283e17f3267fb5d660df3db0412e41c9150..2f7dfeb6e729ce0ae3dd4c0f7a59ca05f9f96e49 100644 (file)
@@ -225,6 +225,7 @@ write_metadata_resource(WIMStruct *w)
        struct wim_lookup_table_entry *lte;
        u64 metadata_original_size;
        struct wim_security_data *sd;
        struct wim_lookup_table_entry *lte;
        u64 metadata_original_size;
        struct wim_security_data *sd;
+       struct wim_image_metadata *imd;
 
        wimlib_assert(w->out_fd != -1);
        wimlib_assert(w->current_image != WIMLIB_NO_IMAGE);
 
        wimlib_assert(w->out_fd != -1);
        wimlib_assert(w->current_image != WIMLIB_NO_IMAGE);
@@ -232,9 +233,18 @@ write_metadata_resource(WIMStruct *w)
        DEBUG("Writing metadata resource for image %d (offset = %"PRIu64")",
              w->current_image, filedes_offset(w->out_fd));
 
        DEBUG("Writing metadata resource for image %d (offset = %"PRIu64")",
              w->current_image, filedes_offset(w->out_fd));
 
+       imd = w->image_metadata[w->current_image - 1];
 
 
-       root = wim_root_dentry(w);
-       sd = wim_security_data(w);
+       root = imd->root_dentry;
+       sd = imd->security_data;
+
+       if (!root) {
+               /* Empty image; create a dummy root. */
+               ret = new_filler_directory(T(""), &root);
+               if (ret)
+                       return ret;
+               imd->root_dentry = root;
+       }
 
        /* Offset of first child of the root dentry.  It's equal to:
         * - The total length of the security data, rounded to the next 8-byte
 
        /* Offset of first child of the root dentry.  It's equal to:
         * - The total length of the security data, rounded to the next 8-byte
index 0538fbc9a9da1d65dbc54e9306ad35e6b57e53aa..4c0c93e50126553f449f98806c6ca67951427e60 100644 (file)
@@ -2372,16 +2372,19 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
        DEBUG("Mount: wim = %p, image = %d, dir = %s, flags = %d, ",
              wim, image, dir, mount_flags);
 
        DEBUG("Mount: wim = %p, image = %d, dir = %s, flags = %d, ",
              wim, image, dir, mount_flags);
 
-       if (!wim || !dir)
-               return WIMLIB_ERR_INVALID_PARAM;
+       if (!wim || !dir) {
+               ret = WIMLIB_ERR_INVALID_PARAM;
+               goto out;
+       }
 
        ret = verify_swm_set(wim, additional_swms, num_additional_swms);
        if (ret)
 
        ret = verify_swm_set(wim, additional_swms, num_additional_swms);
        if (ret)
-               return ret;
+               goto out;
 
        if ((mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) && (wim->hdr.total_parts != 1)) {
                ERROR("Cannot mount a split WIM read-write");
 
        if ((mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) && (wim->hdr.total_parts != 1)) {
                ERROR("Cannot mount a split WIM read-write");
-               return WIMLIB_ERR_SPLIT_UNSUPPORTED;
+               ret = WIMLIB_ERR_SPLIT_UNSUPPORTED;
+               goto out;
        }
 
        if (num_additional_swms) {
        }
 
        if (num_additional_swms) {
@@ -2389,7 +2392,7 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
                                              num_additional_swms,
                                              &joined_tab);
                if (ret)
                                              num_additional_swms,
                                              &joined_tab);
                if (ret)
-                       return ret;
+                       goto out;
                wim_tab_save = wim->lookup_table;
                wim->lookup_table = joined_tab;
        }
                wim_tab_save = wim->lookup_table;
                wim->lookup_table = joined_tab;
        }
@@ -2397,16 +2400,16 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
        if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
                ret = wim_run_full_verifications(wim);
                if (ret)
        if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
                ret = wim_run_full_verifications(wim);
                if (ret)
-                       goto out;
+                       goto out_restore_lookup_table;
        }
 
        ret = wim_checksum_unhashed_streams(wim);
        if (ret)
        }
 
        ret = wim_checksum_unhashed_streams(wim);
        if (ret)
-               goto out;
+               goto out_restore_lookup_table;
 
        ret = select_wim_image(wim, image);
        if (ret)
 
        ret = select_wim_image(wim, image);
        if (ret)
-               goto out;
+               goto out_restore_lookup_table;
 
        DEBUG("Selected image %d", image);
 
 
        DEBUG("Selected image %d", image);
 
@@ -2416,20 +2419,20 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
                ERROR("Cannot mount image that was just exported with "
                      "wimlib_export_image()");
                ret = WIMLIB_ERR_INVALID_PARAM;
                ERROR("Cannot mount image that was just exported with "
                      "wimlib_export_image()");
                ret = WIMLIB_ERR_INVALID_PARAM;
-               goto out;
+               goto out_restore_lookup_table;
        }
 
        if (imd->modified) {
                ERROR("Cannot mount image that was added "
                      "with wimlib_add_image()");
                ret = WIMLIB_ERR_INVALID_PARAM;
        }
 
        if (imd->modified) {
                ERROR("Cannot mount image that was added "
                      "with wimlib_add_image()");
                ret = WIMLIB_ERR_INVALID_PARAM;
-               goto out;
+               goto out_restore_lookup_table;
        }
 
        if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
                ret = lock_wim(wim, wim->in_fd);
                if (ret)
        }
 
        if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
                ret = lock_wim(wim, wim->in_fd);
                if (ret)
-                       goto out;
+                       goto out_restore_lookup_table;
        }
 
        /* Use default stream interface if one was not specified */
        }
 
        /* Use default stream interface if one was not specified */
@@ -2556,11 +2559,12 @@ out_unlock:
        wim->wim_locked = 0;
 out_free_message_queue_names:
        free_message_queue_names(&ctx);
        wim->wim_locked = 0;
 out_free_message_queue_names:
        free_message_queue_names(&ctx);
-out:
+out_restore_lookup_table:
        if (num_additional_swms) {
                free_lookup_table(wim->lookup_table);
                wim->lookup_table = wim_tab_save;
        }
        if (num_additional_swms) {
                free_lookup_table(wim->lookup_table);
                wim->lookup_table = wim_tab_save;
        }
+out:
        return ret;
 }
 
        return ret;
 }
 
index 4f526f7dda1029815a5cfd553458b83b38dc7696..9a28d55a9a2fc6f552e3cafd91f626a3e9db7bd8 100644 (file)
@@ -1,3 +1,7 @@
+/*
+ * unix_capture.c:  Capture a directory tree on UNIX.
+ */
+
 /*
  * Copyright (C) 2013 Eric Biggers
  *
 /*
  * Copyright (C) 2013 Eric Biggers
  *
@@ -82,7 +86,7 @@ unix_capture_directory(struct wim_dentry *dir_dentry,
        if (!dir) {
                ERROR_WITH_ERRNO("Failed to open the directory `%s'",
                                 path);
        if (!dir) {
                ERROR_WITH_ERRNO("Failed to open the directory `%s'",
                                 path);
-               return WIMLIB_ERR_OPEN;
+               return WIMLIB_ERR_OPENDIR;
        }
 
        /* Recurse on directory contents */
        }
 
        /* Recurse on directory contents */
@@ -225,8 +229,9 @@ unix_build_dentry_tree_recursive(struct wim_dentry **root_ret,
                stat_fn = lstat;
 
        ret = (*stat_fn)(path, &stbuf);
                stat_fn = lstat;
 
        ret = (*stat_fn)(path, &stbuf);
-       if (ret != 0) {
+       if (ret) {
                ERROR_WITH_ERRNO("Failed to stat `%s'", path);
                ERROR_WITH_ERRNO("Failed to stat `%s'", path);
+               ret = WIMLIB_ERR_STAT;
                goto out;
        }
        if (!S_ISREG(stbuf.st_mode) && !S_ISDIR(stbuf.st_mode)
                goto out;
        }
        if (!S_ISREG(stbuf.st_mode) && !S_ISDIR(stbuf.st_mode)
index 6ad963f0620972d5f6b4f6c5126ee572928a7909..3d127455334ab20bc8585c9da19e37c8b749a070 100644 (file)
 #include "xml.h"
 #include <errno.h>
 
 #include "xml.h"
 #include <errno.h>
 
-/* Creates a new directory to place in the WIM image.  This is to create parent
- * directories that are not part of any target as needed.  */
-static int
-new_filler_directory(const tchar *name, struct wim_dentry **dentry_ret)
-{
-       int ret;
-       struct wim_dentry *dentry;
-
-       DEBUG("Creating filler directory \"%"TS"\"", name);
-       ret = new_dentry_with_inode(name, &dentry);
-       if (ret)
-               goto out;
-       /* Leave the inode number as 0; this is allowed for non
-        * hard-linked files. */
-       dentry->d_inode->i_resolved = 1;
-       dentry->d_inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY;
-       *dentry_ret = dentry;
-       ret = 0;
-out:
-       return ret;
-}
-
 /* Overlays @branch onto @target, both of which must be directories. */
 static int
 do_overlay(struct wim_dentry *target, struct wim_dentry *branch)
 /* Overlays @branch onto @target, both of which must be directories. */
 static int
 do_overlay(struct wim_dentry *target, struct wim_dentry *branch)
@@ -427,6 +405,8 @@ execute_rename_command(WIMStruct *wim,
                        ret = WIMLIB_ERR_NOTDIR;
                        break;
                case -ENOTEMPTY:
                        ret = WIMLIB_ERR_NOTDIR;
                        break;
                case -ENOTEMPTY:
+                       ret = WIMLIB_ERR_NOTEMPTY;
+                       break;
                case -EISDIR:
                        ret = WIMLIB_ERR_IS_DIRECTORY;
                        break;
                case -EISDIR:
                        ret = WIMLIB_ERR_IS_DIRECTORY;
                        break;
@@ -477,12 +457,11 @@ execute_update_commands(WIMStruct *wim,
                        ret = execute_rename_command(wim, &cmds[i]);
                        break;
                default:
                        ret = execute_rename_command(wim, &cmds[i]);
                        break;
                default:
-                       ret = WIMLIB_ERR_INVALID_PARAM;
+                       wimlib_assert(0);
                        break;
                }
                if (ret)
                        break;
                        break;
                }
                if (ret)
                        break;
-               wim->image_metadata[wim->current_image - 1]->modified = 1;
        }
        return ret;
 }
        }
        return ret;
 }
@@ -733,10 +712,12 @@ wimlib_update_image(WIMStruct *wim,
        if (ret)
                goto out_free_cmds_copy;
 
        if (ret)
                goto out_free_cmds_copy;
 
+       wim->image_metadata[image - 1]->modified = 1;
+
        /* Statistics about the WIM image, such as the numbers of files and
         * directories, may have changed.  Call xml_update_image_info() to
         * recalculate these statistics. */
        /* Statistics about the WIM image, such as the numbers of files and
         * directories, may have changed.  Call xml_update_image_info() to
         * recalculate these statistics. */
-       xml_update_image_info(wim, wim->current_image);
+       xml_update_image_info(wim, image);
 out_free_cmds_copy:
        free_update_commands(cmds_copy, num_cmds);
 out:
 out_free_cmds_copy:
        free_update_commands(cmds_copy, num_cmds);
 out:
index 7350111b5fea67722a0aadefd8c2f38d06d3c0d7..a5899bcd349db00366206ce934ab20cb82260527 100644 (file)
@@ -338,6 +338,8 @@ static const tchar *error_strings[] = {
                = T("Ran out of memory"),
        [WIMLIB_ERR_NOTDIR]
                = T("Expected a directory"),
                = T("Ran out of memory"),
        [WIMLIB_ERR_NOTDIR]
                = T("Expected a directory"),
+       [WIMLIB_ERR_NOTEMPTY]
+               = T("Directory was not empty"),
        [WIMLIB_ERR_NOT_A_WIM_FILE]
                = T("The file did not begin with the magic characters that "
                        "identify a WIM file"),
        [WIMLIB_ERR_NOT_A_WIM_FILE]
                = T("The file did not begin with the magic characters that "
                        "identify a WIM file"),
index 48922f55e32ef9eb4f700b42e8844c1d9dba05dc..dd20f0854bcee30999a9ee7106ec6886667b74f8 100644 (file)
@@ -665,7 +665,7 @@ struct wimlib_capture_config {
 
 
 /*****************************
 
 
 /*****************************
- * WIMLIB_ADD_FLAG_*   *
+ * WIMLIB_ADD_FLAG_*
  *****************************/
 
 /** Directly capture a NTFS volume rather than a generic directory.  This flag
  *****************************/
 
 /** Directly capture a NTFS volume rather than a generic directory.  This flag
@@ -730,12 +730,16 @@ struct wimlib_capture_config {
 #define WIMLIB_ADD_IMAGE_FLAG_VERBOSE          WIMLIB_ADD_FLAG_VERBOSE
 #define WIMLIB_ADD_IMAGE_FLAG_BOOT             WIMLIB_ADD_FLAG_BOOT
 #define WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA                WIMLIB_ADD_FLAG_UNIX_DATA
 #define WIMLIB_ADD_IMAGE_FLAG_VERBOSE          WIMLIB_ADD_FLAG_VERBOSE
 #define WIMLIB_ADD_IMAGE_FLAG_BOOT             WIMLIB_ADD_FLAG_BOOT
 #define WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA                WIMLIB_ADD_FLAG_UNIX_DATA
-#define WIMLIB_ADD_IMAGE_FLAG_NO_ACLS          WIMLIB_ADD_FLAG_NO_ACLS 
+#define WIMLIB_ADD_IMAGE_FLAG_NO_ACLS          WIMLIB_ADD_FLAG_NO_ACLS
 #define WIMLIB_ADD_IMAGE_FLAG_STRICT_ACLS      WIMLIB_ADD_FLAG_STRICT_ACLS
 #define WIMLIB_ADD_IMAGE_FLAG_STRICT_ACLS      WIMLIB_ADD_FLAG_STRICT_ACLS
-#define WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE  WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE 
+#define WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE  WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE
 #define WIMLIB_ADD_IMAGE_FLAG_RPFIX            WIMLIB_ADD_FLAG_RPFIX
 #define WIMLIB_ADD_IMAGE_FLAG_NORPFIX          WIMLIB_ADD_FLAG_NORPFIX
 
 #define WIMLIB_ADD_IMAGE_FLAG_RPFIX            WIMLIB_ADD_FLAG_RPFIX
 #define WIMLIB_ADD_IMAGE_FLAG_NORPFIX          WIMLIB_ADD_FLAG_NORPFIX
 
+/******************************
+ * WIMLIB_DELETE_FLAG_*
+ ******************************/
+
 /** Do not issue an error if the path to delete does not exist. */
 #define WIMLIB_DELETE_FLAG_FORCE                       0x00000001
 
 /** Do not issue an error if the path to delete does not exist. */
 #define WIMLIB_DELETE_FLAG_FORCE                       0x00000001
 
@@ -744,14 +748,14 @@ struct wimlib_capture_config {
 #define WIMLIB_DELETE_FLAG_RECURSIVE                   0x00000002
 
 /******************************
 #define WIMLIB_DELETE_FLAG_RECURSIVE                   0x00000002
 
 /******************************
- * WIMLIB_EXPORT_FLAG_* *
+ * WIMLIB_EXPORT_FLAG_*
  ******************************/
 
 /** See documentation for wimlib_export_image(). */
 #define WIMLIB_EXPORT_FLAG_BOOT                                0x00000001
 
 /******************************
  ******************************/
 
 /** See documentation for wimlib_export_image(). */
 #define WIMLIB_EXPORT_FLAG_BOOT                                0x00000001
 
 /******************************
- * WIMLIB_EXTRACT_FLAG_*      *
+ * WIMLIB_EXTRACT_FLAG_*
  ******************************/
 
 /** Extract the image directly to a NTFS volume rather than a generic directory.
  ******************************/
 
 /** Extract the image directly to a NTFS volume rather than a generic directory.
@@ -805,7 +809,7 @@ struct wimlib_capture_config {
 #define WIMLIB_EXTRACT_FLAG_TO_STDOUT                  0x00000400
 
 /******************************
 #define WIMLIB_EXTRACT_FLAG_TO_STDOUT                  0x00000400
 
 /******************************
- * WIMLIB_MOUNT_FLAG_*        *
+ * WIMLIB_MOUNT_FLAG_*
  ******************************/
 
 /** Mount the WIM image read-write rather than the default of read-only. */
  ******************************/
 
 /** Mount the WIM image read-write rather than the default of read-only. */
@@ -834,7 +838,7 @@ struct wimlib_capture_config {
 #define WIMLIB_MOUNT_FLAG_ALLOW_OTHER                  0x00000040
 
 /******************************
 #define WIMLIB_MOUNT_FLAG_ALLOW_OTHER                  0x00000040
 
 /******************************
- * WIMLIB_OPEN_FLAG_*         *
+ * WIMLIB_OPEN_FLAG_*
  ******************************/
 
 /** Verify the WIM contents against the WIM's integrity table, if present. */
  ******************************/
 
 /** Verify the WIM contents against the WIM's integrity table, if present. */
@@ -844,7 +848,7 @@ struct wimlib_capture_config {
 #define WIMLIB_OPEN_FLAG_SPLIT_OK                      0x00000002
 
 /******************************
 #define WIMLIB_OPEN_FLAG_SPLIT_OK                      0x00000002
 
 /******************************
- * WIMLIB_UNMOUNT_FLAG_*      *
+ * WIMLIB_UNMOUNT_FLAG_*
  ******************************/
 
 /** Include an integrity table in the WIM after it's been unmounted.  Ignored
  ******************************/
 
 /** Include an integrity table in the WIM after it's been unmounted.  Ignored
@@ -862,7 +866,7 @@ struct wimlib_capture_config {
 #define WIMLIB_UNMOUNT_FLAG_RECOMPRESS                 0x00000008
 
 /******************************
 #define WIMLIB_UNMOUNT_FLAG_RECOMPRESS                 0x00000008
 
 /******************************
- * WIMLIB_WRITE_FLAG_*        *
+ * WIMLIB_WRITE_FLAG_*
  ******************************/
 
 /** Include an integrity table in the new WIM file. */
  ******************************/
 
 /** Include an integrity table in the new WIM file. */
@@ -891,31 +895,67 @@ struct wimlib_capture_config {
  * deleting an image in this way. */
 #define WIMLIB_WRITE_FLAG_SOFT_DELETE                  0x00000010
 
  * deleting an image in this way. */
 #define WIMLIB_WRITE_FLAG_SOFT_DELETE                  0x00000010
 
+/******************************
+ * WIMLIB_INIT_FLAG_*
+ ******************************/
+
 /** Assume that strings are represented in UTF-8, even if this is not the
  * locale's character encoding. */
 #define WIMLIB_INIT_FLAG_ASSUME_UTF8                   0x00000001
 
 /** Assume that strings are represented in UTF-8, even if this is not the
  * locale's character encoding. */
 #define WIMLIB_INIT_FLAG_ASSUME_UTF8                   0x00000001
 
-/** XXX */
+/** Specification of an update to perform on a WIM image. */
 struct wimlib_update_command {
 struct wimlib_update_command {
-       enum {
+
+       /** The specific type of update to perform. */
+       enum wimlib_update_op {
+               /** Add a new file or directory tree to the WIM image in a
+                * certain location. */
                WIMLIB_UPDATE_OP_ADD = 0,
                WIMLIB_UPDATE_OP_ADD = 0,
+
+               /** Delete a file or directory tree from the WIM image. */
                WIMLIB_UPDATE_OP_DELETE,
                WIMLIB_UPDATE_OP_DELETE,
+
+               /** Rename a file or directory tree in the WIM image. */
                WIMLIB_UPDATE_OP_RENAME,
        } op;
        union {
                WIMLIB_UPDATE_OP_RENAME,
        } op;
        union {
-               struct {
+               /** Data for a ::WIMLIB_UPDATE_OP_ADD operation. */
+               struct wimlib_add_command {
+                       /** Filesystem path to the file or directory tree to
+                        * add. */
                        wimlib_tchar *fs_source_path;
                        wimlib_tchar *fs_source_path;
+                       /** Path, specified from the root of the WIM image, at
+                        * which to add the file or directory tree within the
+                        * WIM image. */
                        wimlib_tchar *wim_target_path;
                        wimlib_tchar *wim_target_path;
+
+                       /** Configuration for excluded files.  @c NULL means
+                        * exclude no files. */
                        struct wimlib_capture_config *config;
                        struct wimlib_capture_config *config;
+
+                       /** Bitwise OR of WIMLIB_ADD_FLAG_* flags. */
                        int add_flags;
                } add;
                        int add_flags;
                } add;
-               struct {
+               /** Data for a ::WIMLIB_UPDATE_OP_DELETE operation. */
+               struct wimlib_delete_command {
+                       /** Path, specified from the root of the WIM image, for
+                        * the file or directory tree within the WIM image to be
+                        * deleted. */
                        wimlib_tchar *wim_path;
                        wimlib_tchar *wim_path;
+                       /** Bitwise OR of WIMLIB_DELETE_FLAG_* flags. */
                        int delete_flags;
                } delete;
                        int delete_flags;
                } delete;
-               struct {
+               /** Data for a ::WIMLIB_UPDATE_OP_RENAME operation. */
+               struct wimlib_rename_command {
+                       /** Path, specified from the root of the WIM image, for
+                        * the source file or directory tree within the WIM
+                        * image. */
                        wimlib_tchar *wim_source_path;
                        wimlib_tchar *wim_source_path;
+                       /** Path, specified from the root of the WIM image, for
+                        * the destination file or directory tree within the WIM
+                        * image. */
                        wimlib_tchar *wim_target_path;
                        wimlib_tchar *wim_target_path;
+                       /** Reserved; set to 0. */
                        int rename_flags;
                } rename;
        };
                        int rename_flags;
                } rename;
        };
@@ -941,9 +981,6 @@ struct wimlib_extract_command {
  * See the documentation for each wimlib function to see specifically what error
  * codes can be returned by a given function, and what they mean.
  */
  * See the documentation for each wimlib function to see specifically what error
  * codes can be returned by a given function, and what they mean.
  */
-/* Note: these are currently in alphabetic order, but new error codes should be
- * added at the end to maintain a compatible ABI, except when it's being broken
- * anyway. */
 enum wimlib_error_code {
        WIMLIB_ERR_SUCCESS = 0,
        WIMLIB_ERR_ALREADY_LOCKED,
 enum wimlib_error_code {
        WIMLIB_ERR_SUCCESS = 0,
        WIMLIB_ERR_ALREADY_LOCKED,
@@ -1009,6 +1046,7 @@ enum wimlib_error_code {
        WIMLIB_ERR_PATH_DOES_NOT_EXIST,
        WIMLIB_ERR_NOT_A_REGULAR_FILE,
        WIMLIB_ERR_IS_DIRECTORY,
        WIMLIB_ERR_PATH_DOES_NOT_EXIST,
        WIMLIB_ERR_NOT_A_REGULAR_FILE,
        WIMLIB_ERR_IS_DIRECTORY,
+       WIMLIB_ERR_NOTEMPTY,
 };
 
 
 };
 
 
@@ -1070,7 +1108,8 @@ wimlib_add_empty_image(WIMStruct *wim,
  *     A path to a directory or unmounted NTFS volume that will be captured as
  *     a WIM image.
  * @param name
  *     A path to a directory or unmounted NTFS volume that will be captured as
  *     a WIM image.
  * @param name
- *     The name to give the image.  This must be non-@c NULL.
+ *     The name to give the image.  It must be nonempty and must specify a name
+ *     that does not yet exist in @a wim.
  * @param config
  *     Capture configuration that specifies files, directories, or path globs
  *     to exclude from being captured.  If @c NULL, a dummy configuration where
  * @param config
  *     Capture configuration that specifies files, directories, or path globs
  *     to exclude from being captured.  If @c NULL, a dummy configuration where
@@ -1085,45 +1124,11 @@ wimlib_add_empty_image(WIMStruct *wim,
  * discarded so that it appears to be in the same state as when this function
  * was called.
  *
  * discarded so that it appears to be in the same state as when this function
  * was called.
  *
- * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION
- *     There is already an image named @a name in @a wim.
- * @retval ::WIMLIB_ERR_INVALID_CAPTURE_CONFIG
- *     @a config was not @c NULL and did not specify a valid image capture
- *     configuration.
- * @retval ::WIMLIB_ERR_INVALID_PARAM
- *     @a dir was @c NULL, @a name was @c NULL, or @a name was the empty string.
- * @retval ::WIMLIB_ERR_NOMEM
- *     Failed to allocate needed memory.
- * @retval ::WIMLIB_ERR_NOTDIR
- *     @a source is not a directory (only if ::WIMLIB_ADD_FLAG_NTFS was
- *     not specified in @a add_flags).
- * @retval ::WIMLIB_ERR_NTFS_3G
- *     An error was returned from a libntfs-3g function when the NTFS volume
- *     was being opened, scanned, or closed (only if
- *     ::WIMLIB_ADD_FLAG_NTFS was specified in @a add_flags).
- * @retval ::WIMLIB_ERR_OPEN
- *     Failed to open a file or directory in the directory tree rooted at @a
- *     source (only if ::WIMLIB_ADD_FLAG_NTFS was not specified in @a
- *     add_flags).
- * @retval ::WIMLIB_ERR_READ
- *     Failed to read a file in the directory tree rooted at @a source (only if
- *     ::WIMLIB_ADD_FLAG_NTFS was not specified in @a add_flags).
- * @retval ::WIMLIB_ERR_SPECIAL_FILE
- *     The directory tree rooted at @a source contains a special file that is
- *     not a directory, regular file, or symbolic link.  This currently can
- *     only be returned if ::WIMLIB_ADD_FLAG_NTFS was not specified in @a
- *     add_flags, but it may be returned for unsupported NTFS files in
- *     the future.
- * @retval ::WIMLIB_ERR_STAT
- *     Failed obtain the metadata for a file or directory in the directory tree
- *     rooted at @a source (only if ::WIMLIB_ADD_FLAG_NTFS was not
- *     specified in @a add_flags).
- * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED
- *     @a wim is part of a split WIM.  Adding an image to a split WIM is
- *     unsupported.
- * @retval ::WIMLIB_ERR_UNSUPPORTED
- *     ::WIMLIB_ADD_FLAG_NTFS was specified in @a add_flags, but
- *     wimlib was configured with the @c --without-ntfs-3g flag.
+ * This function is implemented by calling wimlib_add_empty_image(), then
+ * calling wimlib_update_image() with a single "add" command, so any error code
+ * returned by wimlib_add_empty_image() may be returned, as well as any error
+ * codes returned by wimlib_update_image() other than ones documented as only
+ * being returned specifically by an update involving delete or rename commands.
  */
 extern int
 wimlib_add_image(WIMStruct *wim,
  */
 extern int
 wimlib_add_image(WIMStruct *wim,
@@ -1151,7 +1156,7 @@ wimlib_add_image(WIMStruct *wim,
  * wimlib_add_image_multisource() instead of wimlib_add_image() when requesting
  * NTFS mode.) */
 extern int
  * wimlib_add_image_multisource() instead of wimlib_add_image() when requesting
  * NTFS mode.) */
 extern int
-wimlib_add_image_multisource(WIMStruct *w,
+wimlib_add_image_multisource(WIMStruct *wim,
                             const struct wimlib_capture_source *sources,
                             size_t num_sources,
                             const wimlib_tchar *name,
                             const struct wimlib_capture_source *sources,
                             size_t num_sources,
                             const wimlib_tchar *name,
@@ -1241,16 +1246,9 @@ wimlib_delete_image(WIMStruct *wim, int image);
  * wimlib_write() or wimlib_overwrite() on @a dest_wim because @a dest_wim will
  * have references back to @a src_wim.
  *
  * wimlib_write() or wimlib_overwrite() on @a dest_wim because @a dest_wim will
  * have references back to @a src_wim.
  *
- * Previous versions of this function left @a dest_wim in an indeterminate state
- * on failure.  This is no longer the case; all changes to @a dest_wim made by
- * this function are rolled back on failure.
+ * If this function fails, all changes to @a dest_wim are rolled back.
  *
  *
- * Previous versions of this function did not allow exporting an image that had
- * been added by wimlib_add_image().  This is no longer the case; you may now
- * export an image regardless of how it was added.
- *
- * Regardless of whether this function succeeds or fails, no changes are made to
- * @a src_wim.
+ * No changes shall be made to @a src_wim by this function.
  *
  * Please note that no changes are committed to the underlying WIM file of @a
  * dest_wim (if any) until wimlib_write() or wimlib_overwrite() is called.
  *
  * Please note that no changes are committed to the underlying WIM file of @a
  * dest_wim (if any) until wimlib_write() or wimlib_overwrite() is called.
@@ -2556,8 +2554,79 @@ wimlib_unmount_image(const wimlib_tchar *dir,
  *     If non-NULL, a function that will be called periodically with the
  *     progress of the current operation.
  *
  *     If non-NULL, a function that will be called periodically with the
  *     progress of the current operation.
  *
- * @return 0 on success; nonzero on error.  There are many possible error codes
- * (TODO: document them.)
+ * @return 0 on success; nonzero on error.  On failure, some but not all of the
+ * update commands may have been executed.  No individual update command will
+ * have been partially executed.  Possible error codes include:
+ *
+ * @retval ::WIMLIB_ERR_DECOMPRESSION
+ *     Failed to decompress the metadata resource from @a image in @a wim.
+ * @retval ::WIMLIB_ERR_INVALID_CAPTURE_CONFIG
+ *     The capture configuration structure specified for an add command was
+ *     invalid.
+ * @retval ::WIMLIB_ERR_INVALID_DENTRY
+ *     A directory entry for @a image in @a wim is invalid.
+ * @retval ::WIMLIB_ERR_INVALID_IMAGE
+ *     @a image did not specify a single, existing image in @a wim.
+ * @retval ::WIMLIB_ERR_INVALID_OVERLAY
+ *     Attempted to perform an add command that conflicted with previously
+ *     existing files in the WIM when an overlay was attempted.
+ * @retval ::WIMLIB_ERR_INVALID_PARAM
+ *     Attempted to perform an add command with ::WIMLIB_ADD_FLAG_NTFS set, but
+ *     the same image had previously already been added from a NTFS volume.
+ * @retval ::WIMLIB_ERR_INVALID_REPARSE_DATA
+ *     (Windows only):  While executing an add command, tried to capture a
+ *     reparse point with invalid data.
+ * @retval ::WIMLIB_ERR_INVALID_RESOURCE_SIZE
+ *     The metadata resource for @a image in @a wim is invalid.
+ * @retval ::WIMLIB_ERR_INVALID_SECURITY_DATA
+ *     The security data for image @a image in @a wim is invalid.
+ * @retval ::WIMLIB_ERR_IS_DIRECTORY
+ *     A delete command without ::WIMLIB_DELETE_FLAG_RECURSIVE specified was
+ *     for a WIM path that corresponded to a directory; or, a rename command
+ *     attempted to rename a directory to a non-directory.
+ * @retval ::WIMLIB_ERR_NOMEM
+ *     Failed to allocate needed memory.
+ * @retval ::WIMLIB_ERR_NOTDIR
+ *     A rename command attempted to rename a directory to a non-directory; or,
+ *     an add command was executed that attempted to set the root of the WIM
+ *     image as a non-directory.
+ * @retval ::WIMLIB_ERR_NOTEMPTY
+ *     A rename command attempted to rename a directory to a non-empty
+ *     directory.
+ * @retval ::WIMLIB_ERR_NTFS_3G
+ *     While executing an add command with ::WIMLIB_ADD_FLAG_NTFS specified, an
+ *     error occurred while reading data from the NTFS volume using libntfs-3g.
+ * @retval ::WIMLIB_ERR_OPEN
+ *     Failed to open a file to be captured while executing an add command.
+ * @retval ::WIMLIB_ERR_OPENDIR
+ *     Failed to open a file to be captured while executing an add command.
+ * @retval ::WIMLIB_ERR_PATH_DOES_NOT_EXIST
+ *     A delete command without ::WIMLIB_DELETE_FLAG_FORCE specified was for a
+ *     WIM path that did not exist; or, a component of the path of the source
+ *     or destination of a rename command was used as a directory but was not,
+ *     in fact, a directory.
+ * @retval ::WIMLIB_ERR_READ
+ *     Failed to read the metadata resource for @a image in @a wim; or, while
+ *     executing an add command, failed to read data from a file or directory
+ *     to be captured.
+ * @retval ::WIMLIB_ERR_READLINK
+ *     While executing an add command, failed to read the target of a symbolic
+ *     link or junction point.
+ * @retval ::WIMLIB_ERR_REPARSE_POINT_FIXUP_FAILED
+ *     (Windows only) Failed to perform a reparse point fixup because of
+ *     problems with the data of a reparse point.
+ * @retval ::WIMLIB_ERR_SPECIAL_FILE
+ *     While executing an add command, attempted to capture a file that was not
+ *     a supported file type, such as a regular file, directory, symbolic link,
+ *     or (on Windows) a reparse point.
+ * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED
+ *     @a wim is part of a split WIM.  Updating a split WIM is unsupported.
+ * @retval ::WIMLIB_ERR_STAT
+ *     While executing an add command, failed to get attributes for a file or
+ *     directory.
+ * @retval ::WIMLIB_ERR_UNSUPPORTED
+ *     ::WIMLIB_ADD_FLAG_NTFS was specified in the @a add_flags for an update
+ *     command, but wimlib was configured with the @c --without-ntfs-3g flag.
  */
 extern int
 wimlib_update_image(WIMStruct *wim,
  */
 extern int
 wimlib_update_image(WIMStruct *wim,
index f9f4276510c6b066bb0329592504dd359aa7eb5c..6a76747294c22a5f9310e9be8b311d6b71d86245 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * win32.c
  *
 /*
  * win32.c
  *
- * All the library code specific to native Windows builds is in here.
+ * Most of the library code specific to native Windows builds is in here.
  */
 
 /*
  */
 
 /*