NTFS-3g capture: use reference-counted NTFS volumes
authorEric Biggers <ebiggers3@gmail.com>
Sat, 2 May 2015 16:35:59 +0000 (11:35 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sat, 2 May 2015 17:07:36 +0000 (12:07 -0500)
This avoids the hack of storing the NTFS volume in
'struct wim_image_metadata'.

include/wimlib.h
include/wimlib/blob_table.h
include/wimlib/capture.h
include/wimlib/metadata.h
include/wimlib/ntfs_3g.h
src/blob_table.c
src/ntfs-3g_capture.c
src/resource.c
src/update_image.c
src/wim.c

index 712202d..2dcbd12 100644 (file)
@@ -2564,15 +2564,9 @@ wimlib_add_image(WIMStruct *wim,
  * capture</b> for full details on how this mode works.
  *
  * In addition to the error codes that wimlib_add_image() can return,
- * wimlib_add_image_multisource() can return ::WIMLIB_ERR_INVALID_OVERLAY
- * when trying to overlay a non-directory on a directory or when otherwise
- * trying to overlay multiple conflicting files to the same location in the WIM
- * image.  It will also return ::WIMLIB_ERR_INVALID_PARAM if
- * ::WIMLIB_ADD_FLAG_NTFS was specified in @p add_flags but there
- * was not exactly one capture source with the target being the root directory.
- * (In this respect, there is no advantage to using
- * wimlib_add_image_multisource() instead of wimlib_add_image() when requesting
- * NTFS mode.)
+ * wimlib_add_image_multisource() can return ::WIMLIB_ERR_INVALID_OVERLAY when
+ * trying to overlay a non-directory on a directory or when otherwise trying to
+ * overlay multiple conflicting files to the same location in the WIM image.
  */
 extern int
 wimlib_add_image_multisource(WIMStruct *wim,
@@ -4258,12 +4252,9 @@ wimlib_unmount_image_with_progress(const wimlib_tchar *dir,
  *     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
- *     An unknown operation type was specified in the update commands; or,
- *     attempted to execute an add command where ::WIMLIB_ADD_FLAG_NTFS was set
- *     in the @p add_flags, but the same image had previously already been
- *     added from an NTFS volume; or, both ::WIMLIB_ADD_FLAG_RPFIX and
- *     ::WIMLIB_ADD_FLAG_NORPFIX were specified in the @p add_flags for one add
- *     command; or, ::WIMLIB_ADD_FLAG_NTFS or ::WIMLIB_ADD_FLAG_RPFIX were
+ *     An unknown operation type was specified in the update commands; or, both
+ *     ::WIMLIB_ADD_FLAG_RPFIX and ::WIMLIB_ADD_FLAG_NORPFIX were specified in
+ *     the @p add_flags for one add command; or ::WIMLIB_ADD_FLAG_RPFIX were
  *     specified in the @p add_flags for an add command in which @p
  *     wim_target_path was not the root directory of the WIM image.
  * @retval ::WIMLIB_ERR_INVALID_REPARSE_DATA
index 672dedf..556187e 100644 (file)
@@ -35,9 +35,8 @@ enum blob_location {
 
 #ifdef WITH_NTFS_3G
        /* The blob's data is available as the contents of an NTFS attribute
-        * accessible through libntfs-3g.  The attribute is identified by
-        * volume, path to an inode, attribute name, and attribute type.
-        * @ntfs_loc points to a structure containing this information.  */
+        * accessible through libntfs-3g.  @ntfs_loc points to a structure which
+        * identifies the attribute.  */
        BLOB_IN_NTFS_VOLUME,
 #endif
 
index 7b352dc..e41e1b0 100644 (file)
@@ -42,10 +42,6 @@ struct capture_params {
        /* Flags that affect the capture operation (WIMLIB_ADD_FLAG_*) */
        int add_flags;
 
-       /* Extra argument; set to point to a pointer to the ntfs_volume for
-        * libntfs-3g capture.  */
-       void *extra_arg;
-
        /* If non-NULL, the user-supplied progress function. */
        wimlib_progress_func_t progfunc;
        void *progctx;
index cb456bc..00647a1 100644 (file)
@@ -5,10 +5,6 @@
 #include "wimlib/types.h"
 #include "wimlib/wim.h"
 
-#ifdef WITH_NTFS_3G
-struct _ntfs_volume;
-#endif
-
 /* Metadata for a WIM image  */
 struct wim_image_metadata {
 
@@ -39,10 +35,6 @@ struct wim_image_metadata {
         * the WIM file.  If this is the case, the memory for the dentry tree
         * should not be freed when switching to a different WIM image. */
        u8 modified : 1;
-
-#ifdef WITH_NTFS_3G
-       struct _ntfs_volume *ntfs_vol;
-#endif
 };
 
 /* Retrieve the metadata of the image in @wim currently selected with
index 3d92dff..2641801 100644 (file)
@@ -1,23 +1,13 @@
 #ifndef _WIMLIB_NTFS_3G_H
 #define _WIMLIB_NTFS_3G_H
 
+#ifdef WITH_NTFS_3G
+
 #include "wimlib/callback.h"
 #include "wimlib/types.h"
 
 struct blob_descriptor;
-struct _ntfs_volume;
-
-#ifdef WITH_NTFS_3G
-struct _ntfs_volume;
-struct ntfs_location {
-       struct _ntfs_volume *ntfs_vol;
-       u64 mft_no;
-       utf16lechar *attr_name;
-       unsigned attr_name_nchars;
-       unsigned attr_type;
-       u64 sort_key;
-};
-#endif
+struct ntfs_location;
 
 extern void
 libntfs3g_global_init(void);
@@ -26,7 +16,16 @@ extern int
 read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size,
                           consume_data_callback_t cb, void *cb_ctx);
 
+extern struct ntfs_location *
+clone_ntfs_location(const struct ntfs_location *loc);
+
+extern void
+free_ntfs_location(struct ntfs_location *loc);
+
 extern int
-do_ntfs_umount(struct _ntfs_volume *vol);
+cmp_ntfs_locations(const struct ntfs_location *loc1,
+                  const struct ntfs_location *loc2);
+
+#endif /* WITH_NTFS_3G */
 
-#endif
+#endif /* _WIMLIB_NTFS_3G_H */
index 0ddd13a..1d87a71 100644 (file)
@@ -138,18 +138,9 @@ clone_blob_descriptor(const struct blob_descriptor *old)
                break;
 #ifdef WITH_NTFS_3G
        case BLOB_IN_NTFS_VOLUME:
-               if (old->ntfs_loc) {
-                       new->ntfs_loc = memdup(old->ntfs_loc,
-                                              sizeof(struct ntfs_location));
-                       if (new->ntfs_loc == NULL)
-                               goto out_free;
-                       if (new->ntfs_loc->attr_name != NULL) {
-                               new->ntfs_loc->attr_name =
-                                       utf16le_dup(new->ntfs_loc->attr_name);
-                               if (new->ntfs_loc->attr_name == NULL)
-                                       goto out_free;
-                       }
-               }
+               new->ntfs_loc = clone_ntfs_location(old->ntfs_loc);
+               if (!new->ntfs_loc)
+                       goto out_free;
                break;
 #endif
        }
@@ -186,14 +177,10 @@ blob_release_location(struct blob_descriptor *blob)
                break;
 #ifdef WITH_NTFS_3G
        case BLOB_IN_NTFS_VOLUME:
-               if (blob->ntfs_loc) {
-                       FREE(blob->ntfs_loc->attr_name);
-                       FREE(blob->ntfs_loc);
-               }
+               if (blob->ntfs_loc)
+                       free_ntfs_location(blob->ntfs_loc);
                break;
 #endif
-       default:
-               break;
        }
 }
 
@@ -448,7 +435,7 @@ cmp_blobs_by_sequential_order(const void *p1, const void *p2)
                return tstrcmp(blob1->file_on_disk, blob2->file_on_disk);
 #ifdef WITH_NTFS_3G
        case BLOB_IN_NTFS_VOLUME:
-               return cmp_u64(blob1->ntfs_loc->sort_key, blob2->ntfs_loc->sort_key);
+               return cmp_ntfs_locations(blob1->ntfs_loc, blob2->ntfs_loc);
 #endif
        default:
                /* No additional sorting order defined for this resource
index c0bd907..ab20511 100644 (file)
 #include "wimlib/reparse.h"
 #include "wimlib/security.h"
 
+/* A reference-counted NTFS volume than is automatically unmounted when the
+ * reference count reaches 0  */
+struct ntfs_volume_wrapper {
+       ntfs_volume *vol;
+       size_t refcnt;
+};
+
+/* Description of where data is located in an NTFS volume  */
+struct ntfs_location {
+       struct ntfs_volume_wrapper *volume;
+       u64 mft_no;
+       utf16lechar *attr_name;
+       unsigned attr_name_nchars;
+       unsigned attr_type;
+       u64 sort_key;
+};
+
+static struct ntfs_volume_wrapper *
+get_ntfs_volume(struct ntfs_volume_wrapper *volume)
+{
+       volume->refcnt++;
+       return volume;
+}
+
+static void
+put_ntfs_volume(struct ntfs_volume_wrapper *volume)
+{
+       if (--volume->refcnt == 0) {
+               ntfs_umount(volume->vol, FALSE);
+               FREE(volume);
+       }
+}
+
 static inline const ntfschar *
 attr_record_name(const ATTR_RECORD *record)
 {
@@ -76,7 +109,7 @@ read_ntfs_attribute_prefix(const struct blob_descriptor *blob, u64 size,
                           consume_data_callback_t cb, void *cb_ctx)
 {
        const struct ntfs_location *loc = blob->ntfs_loc;
-       ntfs_volume *vol = loc->ntfs_vol;
+       ntfs_volume *vol = loc->volume->vol;
        ntfs_inode *ni;
        ntfs_attr *na;
        s64 pos;
@@ -123,6 +156,41 @@ out:
        return ret;
 }
 
+void
+free_ntfs_location(struct ntfs_location *loc)
+{
+       put_ntfs_volume(loc->volume);
+       FREE(loc->attr_name);
+       FREE(loc);
+}
+
+struct ntfs_location *
+clone_ntfs_location(const struct ntfs_location *loc)
+{
+       struct ntfs_location *new = memdup(loc, sizeof(*loc));
+       if (!new)
+               goto err0;
+       if (loc->attr_name) {
+               new->attr_name = utf16le_dup(loc->attr_name);
+               if (!new->attr_name)
+                       goto err1;
+       }
+       new->volume = get_ntfs_volume(loc->volume);
+       return new;
+
+err1:
+       FREE(new);
+err0:
+       return NULL;
+}
+
+int
+cmp_ntfs_locations(const struct ntfs_location *loc1,
+                  const struct ntfs_location *loc2)
+{
+       return cmp_u64(loc1->sort_key, loc2->sort_key);
+}
+
 static int
 read_reparse_tag(ntfs_inode *ni, struct ntfs_location *loc,
                 u32 *reparse_tag_ret)
@@ -199,7 +267,7 @@ scan_ntfs_attr(struct wim_inode *inode,
               const char *path,
               size_t path_len,
               struct list_head *unhashed_blobs,
-              ntfs_volume *vol,
+              struct ntfs_volume_wrapper *volume,
               ATTR_TYPES type,
               const ATTR_RECORD *record)
 {
@@ -236,7 +304,7 @@ scan_ntfs_attr(struct wim_inode *inode,
 
                blob->blob_location = BLOB_IN_NTFS_VOLUME;
                blob->size = data_size;
-               blob->ntfs_loc->ntfs_vol = vol;
+               blob->ntfs_loc->volume = get_ntfs_volume(volume);
                blob->ntfs_loc->attr_type = type;
                blob->ntfs_loc->mft_no = ni->mft_no;
 
@@ -293,7 +361,7 @@ scan_ntfs_attrs_with_type(struct wim_inode *inode,
                          char *path,
                          size_t path_len,
                          struct list_head *unhashed_blobs,
-                         ntfs_volume *vol,
+                         struct ntfs_volume_wrapper *volume,
                          ATTR_TYPES type)
 {
        ntfs_attr_search_ctx *actx;
@@ -316,7 +384,7 @@ scan_ntfs_attrs_with_type(struct wim_inode *inode,
                                     path,
                                     path_len,
                                     unhashed_blobs,
-                                    vol,
+                                    volume,
                                     type,
                                     actx->attr);
                if (ret)
@@ -455,7 +523,7 @@ struct readdir_ctx {
        char *path;
        size_t path_len;
        struct dos_name_map *dos_name_map;
-       ntfs_volume *vol;
+       struct ntfs_volume_wrapper *volume;
        struct capture_params *params;
        int ret;
 };
@@ -466,7 +534,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p,
                                 char *path,
                                 size_t path_len,
                                 int name_type,
-                                ntfs_volume *ntfs_vol,
+                                struct ntfs_volume_wrapper *volume,
                                 struct capture_params *params);
 
 static int
@@ -512,7 +580,7 @@ wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
 
        /* Open the inode for this directory entry and recursively capture the
         * directory tree rooted at it */
-       ntfs_inode *ni = ntfs_inode_open(ctx->vol, mref);
+       ntfs_inode *ni = ntfs_inode_open(ctx->volume->vol, mref);
        if (!ni) {
                /* XXX This used to be treated as an error, but NTFS-3g seemed
                 * to be unable to read some inodes on a Windows 8 image for
@@ -530,7 +598,7 @@ wim_ntfs_capture_filldir(void *dirent, const ntfschar *name,
        child = NULL;
        ret = build_dentry_tree_ntfs_recursive(&child, ni, ctx->path,
                                               path_len, name_type,
-                                              ctx->vol, ctx->params);
+                                              ctx->volume, ctx->params);
        path_len -= mbs_name_nbytes + 1;
        if (child)
                dentry_add_child(ctx->parent, child);
@@ -550,7 +618,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret,
                                 char *path,
                                 size_t path_len,
                                 int name_type,
-                                ntfs_volume *vol,
+                                struct ntfs_volume_wrapper *volume,
                                 struct capture_params *params)
 {
        u32 attributes;
@@ -611,7 +679,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret,
                /* Scan the reparse point stream.  */
                ret = scan_ntfs_attrs_with_type(inode, ni, path, path_len,
                                                params->unhashed_blobs,
-                                               vol, AT_REPARSE_POINT);
+                                               volume, AT_REPARSE_POINT);
                if (ret)
                        goto out;
        }
@@ -623,7 +691,8 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret,
         * points) can have an unnamed data stream as well as named data
         * streams.  */
        ret = scan_ntfs_attrs_with_type(inode, ni, path, path_len,
-                                       params->unhashed_blobs, vol, AT_DATA);
+                                       params->unhashed_blobs,
+                                       volume, AT_DATA);
        if (ret)
                goto out;
 
@@ -637,7 +706,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret,
                        .path            = path,
                        .path_len        = path_len,
                        .dos_name_map    = &dos_name_map,
-                       .vol             = vol,
+                       .volume          = volume,
                        .params          = params,
                        .ret             = 0,
                };
@@ -680,7 +749,7 @@ build_dentry_tree_ntfs_recursive(struct wim_dentry **root_ret,
 
                /* Get security descriptor */
                memset(&sec_ctx, 0, sizeof(sec_ctx));
-               sec_ctx.vol = vol;
+               sec_ctx.vol = volume->vol;
 
                errno = 0;
                sd = _sd;
@@ -728,36 +797,31 @@ out:
        return ret;
 }
 
-
-int
-do_ntfs_umount(struct _ntfs_volume *vol)
-{
-       DEBUG("Unmounting NTFS volume");
-       if (ntfs_umount(vol, FALSE))
-               return WIMLIB_ERR_NTFS_3G;
-       else
-               return 0;
-}
-
 int
 build_dentry_tree_ntfs(struct wim_dentry **root_p,
                       const char *device,
                       struct capture_params *params)
 {
+       struct ntfs_volume_wrapper *volume;
        ntfs_volume *vol;
        ntfs_inode *root_ni;
+       char *path;
        int ret;
 
+       volume = MALLOC(sizeof(struct ntfs_volume_wrapper));
+       if (!volume)
+               return WIMLIB_ERR_NOMEM;
+
        DEBUG("Mounting NTFS volume `%s' read-only", device);
 
-/* NTFS-3g 2013 renamed the "read-only" mount flag from MS_RDONLY to
- * NTFS_MNT_RDONLY.
- *
- * Unfortunately we can't check for defined(NTFS_MNT_RDONLY) because
- * NTFS_MNT_RDONLY is an enumerated constant.  Also, the NTFS-3g headers don't
- * seem to contain any explicit version information.  So we have to rely on a
- * test done at configure time to detect whether NTFS_MNT_RDONLY should be used.
* */
+       /* NTFS-3g 2013 renamed the "read-only" mount flag from MS_RDONLY to
       * NTFS_MNT_RDONLY.
       *
       * Unfortunately we can't check for defined(NTFS_MNT_RDONLY) because
+        * NTFS_MNT_RDONLY is an enumerated constant.  Also, the NTFS-3g headers
+        * don't seem to contain any explicit version information.  So we have
+        * to rely on a test done at configure time to detect whether
       * NTFS_MNT_RDONLY should be used.  */
 #ifdef HAVE_NTFS_MNT_RDONLY
        /* NTFS-3g 2013 */
        vol = ntfs_mount(device, NTFS_MNT_RDONLY);
@@ -770,8 +834,13 @@ build_dentry_tree_ntfs(struct wim_dentry **root_p,
        if (!vol) {
                ERROR_WITH_ERRNO("Failed to mount NTFS volume `%s' read-only",
                                 device);
+               FREE(volume);
                return WIMLIB_ERR_NTFS_3G;
        }
+
+       volume->vol = vol;
+       volume->refcnt = 1;
+
        ntfs_open_secure(vol);
 
        /* We don't want to capture the special NTFS files such as $Bitmap.  Not
@@ -785,40 +854,29 @@ build_dentry_tree_ntfs(struct wim_dentry **root_p,
                ERROR_WITH_ERRNO("Failed to open root inode of NTFS volume "
                                 "`%s'", device);
                ret = WIMLIB_ERR_NTFS_3G;
-               goto out;
+               goto out_put_ntfs_volume;
        }
 
        /* Currently we assume that all the paths fit into this length and there
         * is no check for overflow. */
-       char *path = MALLOC(32768);
+       path = MALLOC(32768);
        if (!path) {
-               ERROR("Could not allocate memory for NTFS pathname");
                ret = WIMLIB_ERR_NOMEM;
-               goto out_cleanup;
+               goto out_close_root_ni;
        }
 
        path[0] = '/';
        path[1] = '\0';
        ret = build_dentry_tree_ntfs_recursive(root_p, root_ni, path, 1,
-                                              FILE_NAME_POSIX, vol, params);
-out_cleanup:
+                                              FILE_NAME_POSIX, volume, params);
        FREE(path);
+out_close_root_ni:
        ntfs_inode_close(root_ni);
-out:
+out_put_ntfs_volume:
        ntfs_index_ctx_put(vol->secure_xsii);
        ntfs_index_ctx_put(vol->secure_xsdh);
        ntfs_inode_close(vol->secure_ni);
-
-       if (ret) {
-               if (do_ntfs_umount(vol)) {
-                       ERROR_WITH_ERRNO("Failed to unmount NTFS volume `%s'",
-                                        device);
-               }
-       } else {
-               /* We need to leave the NTFS volume mounted so that we can read
-                * the NTFS files again when we are actually writing the WIM */
-               *(ntfs_volume**)params->extra_arg = vol;
-       }
+       put_ntfs_volume(volume);
        return ret;
 }
 #endif /* WITH_NTFS_3G */
index 2c04882..fb1047e 100644 (file)
@@ -36,6 +36,7 @@
 #include "wimlib/endianness.h"
 #include "wimlib/error.h"
 #include "wimlib/file_io.h"
+#include "wimlib/ntfs_3g.h" /* for read_ntfs_attribute_prefix() */
 #include "wimlib/resource.h"
 #include "wimlib/sha1.h"
 #include "wimlib/wim.h"
 #  include "wimlib/win32.h"
 #endif
 
-#ifdef WITH_NTFS_3G
-/* for read_ntfs_attribute_prefix() */
-#  include "wimlib/ntfs_3g.h"
-#endif
-
-
 /*
  *                         Compressed WIM resources
  *
index b2eceec..f36f9ec 100644 (file)
@@ -62,9 +62,6 @@
 #include "wimlib/endianness.h"
 #include "wimlib/error.h"
 #include "wimlib/metadata.h"
-#ifdef WITH_NTFS_3G
-#  include "wimlib/ntfs_3g.h" /* for do_ntfs_umount() */
-#endif
 #include "wimlib/paths.h"
 #include "wimlib/progress.h"
 #include "wimlib/xml.h"
@@ -792,10 +789,6 @@ execute_add_command(struct update_command_journal *j,
        struct capture_params params;
        struct capture_config config;
        capture_tree_t capture_tree = platform_default_capture_tree;
-#ifdef WITH_NTFS_3G
-       struct _ntfs_volume *ntfs_vol = NULL;
-#endif
-       void *extra_arg = NULL;
        struct wim_dentry *branch;
 
        add_flags = add_cmd->add.add_flags;
@@ -809,15 +802,8 @@ execute_add_command(struct update_command_journal *j,
        memset(&params, 0, sizeof(params));
 
 #ifdef WITH_NTFS_3G
-       if (add_flags & WIMLIB_ADD_FLAG_NTFS) {
+       if (add_flags & WIMLIB_ADD_FLAG_NTFS)
                capture_tree = build_dentry_tree_ntfs;
-               extra_arg = &ntfs_vol;
-               if (wim_get_current_image_metadata(wim)->ntfs_vol != NULL) {
-                       ERROR("NTFS volume already set");
-                       ret = WIMLIB_ERR_INVALID_PARAM;
-                       goto out;
-               }
-       }
 #endif
 
        ret = get_capture_config(config_file, &config,
@@ -831,7 +817,6 @@ execute_add_command(struct update_command_journal *j,
        params.sd_set = sd_set;
        params.config = &config;
        params.add_flags = add_flags;
-       params.extra_arg = extra_arg;
 
        params.progfunc = wim->progfunc;
        params.progctx = wim->progctx;
@@ -852,7 +837,7 @@ execute_add_command(struct update_command_journal *j,
                            &params.progress, params.progctx);
        if (ret) {
                free_dentry_tree(branch, wim->blob_table);
-               goto out_cleanup_after_capture;
+               goto out_destroy_config;
        }
 
        if (WIMLIB_IS_WIM_ROOT_PATH(wim_target_path) &&
@@ -861,13 +846,13 @@ execute_add_command(struct update_command_journal *j,
                ERROR("\"%"TS"\" is not a directory!", fs_source_path);
                ret = WIMLIB_ERR_NOTDIR;
                free_dentry_tree(branch, wim->blob_table);
-               goto out_cleanup_after_capture;
+               goto out_destroy_config;
        }
 
        ret = attach_branch(branch, wim_target_path, j,
                            add_flags, params.progfunc, params.progctx);
        if (ret)
-               goto out_cleanup_after_capture;
+               goto out_destroy_config;
 
        if (config_file && (add_flags & WIMLIB_ADD_FLAG_WIMBOOT) &&
            WIMLIB_IS_WIM_ROOT_PATH(wim_target_path))
@@ -881,23 +866,14 @@ execute_add_command(struct update_command_journal *j,
                 * /Windows/System32/WimBootCompress.ini in the WIM image. */
                ret = platform_default_capture_tree(&branch, config_file, &params);
                if (ret)
-                       goto out_cleanup_after_capture;
+                       goto out_destroy_config;
 
                ret = attach_branch(branch, wimboot_cfgfile, j, 0, NULL, NULL);
                if (ret)
-                       goto out_cleanup_after_capture;
+                       goto out_destroy_config;
        }
 
-#ifdef WITH_NTFS_3G
-       wim_get_current_image_metadata(wim)->ntfs_vol = ntfs_vol;
-#endif
        ret = 0;
-       goto out_destroy_config;
-out_cleanup_after_capture:
-#ifdef WITH_NTFS_3G
-       if (ntfs_vol)
-               do_ntfs_umount(ntfs_vol);
-#endif
 out_destroy_config:
        destroy_capture_config(&config);
 out:
@@ -1252,9 +1228,8 @@ check_add_command(struct wimlib_update_command *cmd,
 
 #ifndef WITH_NTFS_3G
        if (add_flags & WIMLIB_ADD_FLAG_NTFS) {
-               ERROR("wimlib was compiled without support for NTFS-3g, so\n"
-                     "        we cannot capture a WIM image directly "
-                     "from an NTFS volume");
+               ERROR("NTFS-3g capture mode is unsupported because wimlib "
+                     "was compiled --without-ntfs-3g");
                return WIMLIB_ERR_UNSUPPORTED;
        }
 #endif
@@ -1299,12 +1274,6 @@ check_add_command(struct wimlib_update_command *cmd,
        }
 
        if (!is_entire_image) {
-               if (add_flags & WIMLIB_ADD_FLAG_NTFS) {
-                       ERROR("Cannot add directly from an NTFS volume "
-                             "when not capturing a full image!");
-                       return WIMLIB_ERR_INVALID_PARAM;
-               }
-
                if (add_flags & WIMLIB_ADD_FLAG_RPFIX) {
                        ERROR("Cannot do reparse point fixups when "
                              "not capturing a full image!");
index a82bd47..f06f25f 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
@@ -40,9 +40,7 @@
 #include "wimlib/file_io.h"
 #include "wimlib/integrity.h"
 #include "wimlib/metadata.h"
-#ifdef WITH_NTFS_3G
-#  include "wimlib/ntfs_3g.h" /* for do_ntfs_umount() */
-#endif
+#include "wimlib/ntfs_3g.h" /* for libntfs3g_global_init() */
 #include "wimlib/security.h"
 #include "wimlib/wim.h"
 #include "wimlib/xml.h"
@@ -218,12 +216,6 @@ destroy_image_metadata(struct wim_image_metadata *imd,
        }
        INIT_LIST_HEAD(&imd->unhashed_blobs);
        INIT_HLIST_HEAD(&imd->inode_list);
-#ifdef WITH_NTFS_3G
-       if (imd->ntfs_vol) {
-               do_ntfs_umount(imd->ntfs_vol);
-               imd->ntfs_vol = NULL;
-       }
-#endif
 }
 
 void