]> wimlib.net Git - wimlib/blobdiff - src/extract.c
Windows: improved error messages
[wimlib] / src / extract.c
index caf56b4606bf70edb056c084b02d9983ce2071cc..a5be7d1b333486bc21cdf4e24626b4e61b6ca124 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/.
  */
 
 /*
 #  include "config.h"
 #endif
 
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
 #include "wimlib/apply.h"
+#include "wimlib/assert.h"
 #include "wimlib/dentry.h"
 #include "wimlib/encoding.h"
 #include "wimlib/endianness.h"
 #include "wimlib/wildcard.h"
 #include "wimlib/wim.h"
 
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
 #define WIMLIB_EXTRACT_FLAG_FROM_PIPE   0x80000000
 #define WIMLIB_EXTRACT_FLAG_IMAGEMODE   0x40000000
 
 int
 do_file_extract_progress(struct apply_ctx *ctx, enum wimlib_progress_msg msg)
 {
-       ctx->count_until_file_progress = 512;  /* Arbitrary value to limit calls  */
+       ctx->count_until_file_progress = 500;  /* Arbitrary value to limit calls  */
        return extract_progress(ctx, msg);
 }
 
+static int
+start_file_phase(struct apply_ctx *ctx, uint64_t end_file_count, enum wimlib_progress_msg msg)
+{
+       ctx->progress.extract.current_file_count = 0;
+       ctx->progress.extract.end_file_count = end_file_count;
+       return do_file_extract_progress(ctx, msg);
+}
+
+int
+start_file_structure_phase(struct apply_ctx *ctx, uint64_t end_file_count)
+{
+       return start_file_phase(ctx, end_file_count, WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE);
+}
+
+int
+start_file_metadata_phase(struct apply_ctx *ctx, uint64_t end_file_count)
+{
+       return start_file_phase(ctx, end_file_count, WIMLIB_PROGRESS_MSG_EXTRACT_METADATA);
+}
+
+static int
+end_file_phase(struct apply_ctx *ctx, enum wimlib_progress_msg msg)
+{
+       ctx->progress.extract.current_file_count = ctx->progress.extract.end_file_count;
+       return do_file_extract_progress(ctx, msg);
+}
+
+int
+end_file_structure_phase(struct apply_ctx *ctx)
+{
+       return end_file_phase(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE);
+}
+
+int
+end_file_metadata_phase(struct apply_ctx *ctx)
+{
+       return end_file_phase(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_METADATA);
+}
+
 /* Check whether the extraction of a dentry should be skipped completely.  */
 static bool
 dentry_is_supported(struct wim_dentry *dentry,
@@ -107,16 +144,22 @@ dentry_is_supported(struct wim_dentry *dentry,
        struct wim_inode *inode = dentry->d_inode;
 
        if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
-               return supported_features->reparse_points ||
-                       (inode_is_symlink(inode) &&
-                        supported_features->symlink_reparse_points);
+               if (!(supported_features->reparse_points ||
+                     (inode_is_symlink(inode) &&
+                      supported_features->symlink_reparse_points)))
+                       return false;
        }
+
        if (inode->i_attributes & FILE_ATTRIBUTE_ENCRYPTED) {
-               if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY)
-                       return supported_features->encrypted_directories != 0;
-               else
-                       return supported_features->encrypted_files != 0;
+               if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) {
+                       if (!supported_features->encrypted_directories)
+                               return false;
+               } else {
+                       if (!supported_features->encrypted_files)
+                               return false;
+               }
        }
+
        return true;
 }
 
@@ -700,6 +743,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;
@@ -770,7 +814,7 @@ dentry_calculate_extraction_name(struct wim_dentry *dentry,
 {
        int ret;
 
-       if (!dentry_is_supported(dentry, &ctx->supported_features))
+       if (unlikely(!dentry_is_supported(dentry, &ctx->supported_features)))
                goto skip_dentry;
 
        if (dentry_is_root(dentry))
@@ -970,7 +1014,7 @@ dentry_list_resolve_streams(struct list_head *dentry_list,
 }
 
 static int
-ref_stream(struct wim_lookup_table_entry *lte, u32 stream_idx,
+ref_stream(struct wim_lookup_table_entry *lte, unsigned stream_idx,
           struct wim_dentry *dentry, struct apply_ctx *ctx)
 {
        struct wim_inode *inode = dentry->d_inode;
@@ -1045,12 +1089,9 @@ ref_unnamed_stream(struct wim_dentry *dentry, struct apply_ctx *ctx)
 {
        struct wim_inode *inode = dentry->d_inode;
        int ret;
-       u16 stream_idx;
+       unsigned stream_idx;
        struct wim_lookup_table_entry *stream;
 
-       if (unlikely(inode_is_encrypted_directory(inode)))
-               return 0;
-
        if (unlikely(ctx->apply_ops->will_externally_back)) {
                ret = (*ctx->apply_ops->will_externally_back)(dentry, ctx);
                if (ret >= 0) {
@@ -1082,8 +1123,8 @@ dentry_ref_streams(struct wim_dentry *dentry, struct apply_ctx *ctx)
         * extraction mode and volume, and to avoid complications, if not doing
         * a linked extraction.  */
        if (ctx->supported_features.named_data_streams) {
-               for (u16 i = 0; i < inode->i_num_ads; i++) {
-                       if (!ads_entry_is_named_stream(&inode->i_ads_entries[i]))
+               for (unsigned i = 0; i < inode->i_num_ads; i++) {
+                       if (!inode->i_ads_entries[i].stream_name_nbytes)
                                continue;
                        ret = ref_stream(inode->i_ads_entries[i].lte, i + 1,
                                         dentry, ctx);
@@ -1435,16 +1476,21 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
        if (ret)
                goto out_cleanup;
 
+       if (unlikely(list_empty(&dentry_list))) {
+               WARNING("There is nothing to extract!");
+               goto out_cleanup;
+       }
+
        ret = dentry_list_resolve_streams(&dentry_list, ctx);
        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
@@ -1979,7 +2025,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;