]> wimlib.net Git - wimlib/blobdiff - src/extract.c
Remove unused 'wim' argument to read_metadata_resource()
[wimlib] / src / extract.c
index 8e35994aa6a48c60079c31198c1c7a25fdeffa24..39899c4094e2c5eb80b296bc93d6e09161123de0 100644 (file)
@@ -8,20 +8,18 @@
 /*
  * Copyright (C) 2012, 2013, 2014 Eric Biggers
  *
- * This file is part of wimlib, a library for working with WIM files.
+ * This file is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option) any
+ * later version.
  *
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version.
- *
- * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
- * You should have received a copy of the GNU General Public License
- * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this file; if not, see http://www.gnu.org/licenses/.
  */
 
 /*
@@ -739,6 +737,7 @@ destroy_dentry_list(struct list_head *dentry_list)
                inode = dentry->d_inode;
                dentry_reset_extraction_list_node(dentry);
                inode->i_visited = 0;
+               inode->i_can_externally_back = 0;
                if ((void *)dentry->d_extraction_name != (void *)dentry->file_name)
                        FREE(dentry->d_extraction_name);
                dentry->d_extraction_name = NULL;
@@ -1080,23 +1079,43 @@ ref_stream(struct wim_lookup_table_entry *lte, u32 stream_idx,
 }
 
 static int
-dentry_ref_streams(struct wim_dentry *dentry, struct apply_ctx *ctx)
+ref_unnamed_stream(struct wim_dentry *dentry, struct apply_ctx *ctx)
 {
        struct wim_inode *inode = dentry->d_inode;
        int ret;
+       u16 stream_idx;
+       struct wim_lookup_table_entry *stream;
 
-       /* The unnamed data stream will always be extracted, except in an
-        * unlikely case.  */
-       if (!inode_is_encrypted_directory(inode)) {
-               u16 stream_idx;
-               struct wim_lookup_table_entry *stream;
+       if (unlikely(inode_is_encrypted_directory(inode)))
+               return 0;
 
-               stream = inode_unnamed_stream_resolved(inode, &stream_idx);
-               ret = ref_stream(stream, stream_idx, dentry, ctx);
-               if (ret)
-                       return ret;
+       if (unlikely(ctx->apply_ops->will_externally_back)) {
+               ret = (*ctx->apply_ops->will_externally_back)(dentry, ctx);
+               if (ret >= 0) {
+                       if (ret) /* Error */
+                               return ret;
+                       /* Will externally back */
+                       return 0;
+               }
+               /* Won't externally back */
        }
 
+       stream = inode_unnamed_stream_resolved(inode, &stream_idx);
+       return ref_stream(stream, stream_idx, dentry, ctx);
+}
+
+static int
+dentry_ref_streams(struct wim_dentry *dentry, struct apply_ctx *ctx)
+{
+       struct wim_inode *inode = dentry->d_inode;
+       int ret;
+
+       /* The unnamed data stream will almost always be extracted, but there
+        * exist cases in which it won't be.  */
+       ret = ref_unnamed_stream(dentry, ctx);
+       if (ret)
+               return ret;
+
        /* Named data streams will be extracted only if supported in the current
         * extraction mode and volume, and to avoid complications, if not doing
         * a linked extraction.  */
@@ -1433,6 +1452,7 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
        }
        INIT_LIST_HEAD(&ctx->stream_list);
        filedes_invalidate(&ctx->tmpfile_fd);
+       ctx->apply_ops = ops;
 
        ret = (*ops->get_supported_features)(target, &ctx->supported_features);
        if (ret)
@@ -1457,12 +1477,12 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
        if (ret)
                goto out_cleanup;
 
+       dentry_list_build_inode_alias_lists(&dentry_list);
+
        ret = dentry_list_ref_streams(&dentry_list, ctx);
        if (ret)
                goto out_cleanup;
 
-       dentry_list_build_inode_alias_lists(&dentry_list);
-
        if (extract_flags & WIMLIB_EXTRACT_FLAG_FROM_PIPE) {
                /* When extracting from a pipe, the number of bytes of data to
                 * extract can't be determined in the normal way (examining the
@@ -1997,7 +2017,7 @@ wimlib_extract_image_from_pipe_with_progress(int pipe_fd,
                if (i == image) {
                        /* Metadata resource is for the image being extracted.
                         * Parse it and save the metadata in memory.  */
-                       ret = read_metadata_resource(pwm, imd);
+                       ret = read_metadata_resource(imd);
                        if (ret)
                                goto out_wimlib_free;
                        imd->modified = 1;