/*
* 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/.
*/
/*
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,
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;
}
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. */
}
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)
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
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;