X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fextract.c;h=a5be7d1b333486bc21cdf4e24626b4e61b6ca124;hp=caf56b4606bf70edb056c084b02d9983ce2071cc;hb=a10b5d147146cf9d6b0279aca63474b101df9e2f;hpb=685da37ac736e4cff2cd69cd03188c28b14b3be7 diff --git a/src/extract.c b/src/extract.c index caf56b46..a5be7d1b 100644 --- a/src/extract.c +++ b/src/extract.c @@ -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/. */ /* @@ -41,7 +39,13 @@ # include "config.h" #endif +#include +#include +#include +#include + #include "wimlib/apply.h" +#include "wimlib/assert.h" #include "wimlib/dentry.h" #include "wimlib/encoding.h" #include "wimlib/endianness.h" @@ -61,12 +65,6 @@ #include "wimlib/wildcard.h" #include "wimlib/wim.h" -#include -#include -#include -#include -#include - #define WIMLIB_EXTRACT_FLAG_FROM_PIPE 0x80000000 #define WIMLIB_EXTRACT_FLAG_IMAGEMODE 0x40000000 @@ -95,10 +93,49 @@ 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;