]> wimlib.net Git - wimlib/blobdiff - src/extract.c
Add WIMLIB_EXTRACT_FLAG_WIMBOOT
[wimlib] / src / extract.c
index ee82be2bf1e5df21f1adb86c97d60e81b63ec620..6512917c0c5ed9df4afe7c0addf23243151033c2 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 /*
- * Copyright (C) 2012, 2013 Eric Biggers
+ * Copyright (C) 2012, 2013, 2014 Eric Biggers
  *
  * This file is part of wimlib, a library for working with WIM files.
  *
@@ -94,7 +94,8 @@
         WIMLIB_EXTRACT_FLAG_GLOB_PATHS                 |       \
         WIMLIB_EXTRACT_FLAG_STRICT_GLOB                |       \
         WIMLIB_EXTRACT_FLAG_NO_ATTRIBUTES              |       \
-        WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE)
+        WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE  |       \
+        WIMLIB_EXTRACT_FLAG_WIMBOOT)
 
 static bool
 dentry_in_list(const struct wim_dentry *dentry)
@@ -1658,17 +1659,11 @@ dentry_reset_extraction_list_node(struct wim_dentry *dentry)
        dentry->extraction_list = (struct list_head){NULL, NULL};
 }
 
-static void
-dentry_delete_from_list(struct wim_dentry *dentry)
+static int
+dentry_delete_from_list(struct wim_dentry *dentry, void *_ignore)
 {
        list_del(&dentry->extraction_list);
        dentry_reset_extraction_list_node(dentry);
-}
-
-static int
-do_dentry_delete_from_list(struct wim_dentry *dentry, void *_ignore)
-{
-       dentry_delete_from_list(dentry);
        return 0;
 }
 
@@ -1795,8 +1790,8 @@ dentry_calculate_extraction_name(struct wim_dentry *dentry,
        if (!ctx->ops->supports_case_sensitive_filenames)
        {
                struct wim_dentry *other;
-               list_for_each_entry(other, &dentry->case_insensitive_conflict_list,
-                                   case_insensitive_conflict_list)
+               list_for_each_entry(other, &dentry->d_ci_conflict_list,
+                                   d_ci_conflict_list)
                {
                        if (dentry_in_list(other)) {
                                if (ctx->extract_flags &
@@ -1885,7 +1880,7 @@ out_replace:
        return 0;
 
 skip_dentry:
-       for_dentry_in_tree(dentry, do_dentry_delete_from_list, NULL);
+       for_dentry_in_tree(dentry, dentry_delete_from_list, NULL);
        return 0;
 }
 
@@ -1907,8 +1902,8 @@ dentry_list_calculate_extraction_names(struct list_head *dentry_list,
        struct list_head *prev, *cur;
 
        /* Can't use list_for_each_entry() because a call to
-        * dentry_calculate_extraction_name() may the current dentry and its
-        * children from the list.  */
+        * dentry_calculate_extraction_name() may delete the current dentry and
+        * its children from the list.  */
 
        prev = dentry_list;
        for (;;) {
@@ -2490,7 +2485,7 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
         * volume.  */
        ret = ctx.ops->start_extract(target, &ctx);
        if (ret)
-               return ret;
+               goto out_destroy_dentry_list;
 
        /* Get and check the features required to extract the dentries.  */
        dentry_list_get_features(&dentry_list, &required_features);
@@ -2506,12 +2501,12 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
         * can't be extracted due to naming problems.  */
        ret = dentry_list_calculate_extraction_names(&dentry_list, &ctx);
        if (ret)
-               goto out_destroy_dentry_list;
+               goto out_finish_or_abort_extract;
 
        /* Build list of streams to extract.  */
        ret = dentry_list_resolve_streams(&dentry_list, &ctx);
        if (ret)
-               goto out_destroy_dentry_list;
+               goto out_finish_or_abort_extract;
        INIT_LIST_HEAD(&ctx.stream_list);
        ret = dentry_list_ref_streams(&dentry_list, &ctx);
        if (ret)
@@ -2677,8 +2672,6 @@ out_free_realtarget:
 out_destroy_stream_list:
        if (!(ctx.extract_flags & WIMLIB_EXTRACT_FLAG_FILE_ORDER))
                destroy_stream_list(&ctx.stream_list);
-out_destroy_dentry_list:
-       destroy_dentry_list(&dentry_list);
 out_finish_or_abort_extract:
        if (ret) {
                if (ctx.ops->abort_extract)
@@ -2687,6 +2680,8 @@ out_finish_or_abort_extract:
                if (ctx.ops->finish_extract)
                        ret = ctx.ops->finish_extract(&ctx);
        }
+out_destroy_dentry_list:
+       destroy_dentry_list(&dentry_list);
        return ret;
 }
 
@@ -2750,6 +2745,13 @@ check_extract_flags(const WIMStruct *wim, int *extract_flags_p)
        }
 #endif
 
+#ifndef __WIN32__
+       if (extract_flags & WIMLIB_EXTRACT_FLAG_WIMBOOT) {
+               ERROR("WIMBoot extraction is only supported on Windows!");
+               return WIMLIB_ERR_UNSUPPORTED;
+       }
+#endif
+
        if ((extract_flags & (WIMLIB_EXTRACT_FLAG_RPFIX |
                              WIMLIB_EXTRACT_FLAG_NORPFIX |
                              WIMLIB_EXTRACT_FLAG_IMAGEMODE)) ==