if (inode_unnamed_lte_resolved(inode))
return 0;
- if (extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE)
- puts(dentry->full_path_utf8);
+ if ((extract_flags & WIMLIB_EXTRACT_FLAG_VERBOSE) &&
+ args->progress_func)
+ {
+ args->progress.extract.cur_path = dentry->full_path_utf8;
+ args->progress_func(WIMLIB_PROGRESS_MSG_EXTRACT_DENTRY,
+ &args->progress);
+ }
len = strlen(args->target);
char output_path[len + dentry->full_path_utf8_len + 1];
union wimlib_progress_info *progress)
{
struct lookup_table_entry *lte;
- struct inode *inode;
u64 total_bytes = 0;
u64 num_streams = 0;
total_bytes += wim_resource_size(lte);
}
} else {
- list_for_each_entry(inode, <e->inode_list,
- lte_inode_list)
- {
- num_streams++;
- total_bytes += wim_resource_size(lte);
- }
+ num_streams += lte->out_refcnt;
+ total_bytes += lte->out_refcnt * wim_resource_size(lte);
}
}
progress->extract.num_streams = num_streams;
static void maybe_add_stream_for_extraction(struct lookup_table_entry *lte,
struct list_head *stream_list)
{
- if (lte->out_refcnt == 0) {
- lte->out_refcnt = 1;
+ if (++lte->out_refcnt == 1) {
INIT_LIST_HEAD(<e->inode_list);
list_add_tail(<e->staging_list, stream_list);
}
if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
for (unsigned i = 0; i < inode->num_ads; i++) {
if (inode->ads_entries[i].stream_name_len != 0) {
- lte = inode_stream_lte_resolved(inode, i + 1);
+ lte = inode->ads_entries[i].lte;
if (lte) {
maybe_add_stream_for_extraction(lte,
stream_list);
#ifdef WITH_NTFS_3G
static const struct apply_operations ntfs_apply_operations = {
- .apply_dentry = wim_apply_dentry_ntfs,
- .apply_dentry_timestamps = wim_apply_dentry_timestamps,
+ .apply_dentry = apply_dentry_ntfs,
+ .apply_dentry_timestamps = apply_dentry_timestamps_ntfs,
};
#endif
struct inode *inode;
struct dentry *dentry;
int ret = 0;
+
+ /* This complicated loop is actually just looping through the dentries
+ * (as for_dentry_in_tree() does), but the outer loop is actually over
+ * the distinct streams to be extracted so that sequential reading of
+ * the WIM can be implemented. */
+
+ /* For each distinct stream to be extracted */
list_for_each_entry(lte, stream_list, staging_list) {
+ /* For each inode that contains the stream */
list_for_each_entry(inode, <e->inode_list, lte_inode_list) {
+ /* For each dentry that points to the inode */
inode_for_each_dentry(dentry, inode) {
ret = ops->apply_dentry(dentry, args);
if (ret != 0)
goto out;
- if (args->progress.extract.completed_bytes >= next_progress) {
+ if (progress_func &&
+ args->progress.extract.completed_bytes >= next_progress &&
+ args->progress.extract.total_bytes != 0)
+ {
progress_func(WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS,
&args->progress);
next_progress += bytes_per_progress;
args.num_lutimes_warnings = 0;
args.target = target;
args.stream_list = &stream_list;
+ args.progress_func = progress_func;
if (progress_func) {
- args.progress.extract.image = image;
+ args.progress.extract.wimfile_name = w->filename;
+ args.progress.extract.image = image;
+ args.progress.extract.extract_flags = (extract_flags &
+ WIMLIB_EXTRACT_MASK_PUBLIC);
args.progress.extract.image_name = wimlib_get_image_name(w, image);
- args.progress.extract.target = target;
+ args.progress.extract.target = target;
}
#ifdef WITH_NTFS_3G
ERROR_WITH_ERRNO("Failed to mount NTFS volume `%s'", target);
return WIMLIB_ERR_NTFS_3G;
}
- }
-#endif
-
-#ifdef WITH_NTFS_3G
- if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS)
ops = &ntfs_apply_operations;
- else
+ } else
#endif
ops = &normal_apply_operations;
goto out;
inode_list = &w->image_metadata[image - 1].inode_list;
- find_streams_for_extraction(inode_list,
- &stream_list,
- w->lookup_table,
- extract_flags);
+
+ find_streams_for_extraction(inode_list, &stream_list,
+ w->lookup_table, extract_flags);
calculate_bytes_to_extract(&stream_list, extract_flags,
&args.progress);
&args.progress);
}
-
args.extract_flags |= WIMLIB_EXTRACT_FLAG_NO_STREAMS;
ret = for_dentry_in_tree(wim_root_dentry(w), ops->apply_dentry, &args);
args.extract_flags &= ~WIMLIB_EXTRACT_FLAG_NO_STREAMS;
struct lookup_table *joined_tab, *w_tab_save;
int ret;
- if (!w || !target)
+ if (!target)
return WIMLIB_ERR_INVALID_PARAM;
extract_flags &= WIMLIB_EXTRACT_MASK_PUBLIC;
if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) {
#ifdef WITH_NTFS_3G
if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK))) {
- ERROR("Cannot specify symlink or hardlink flags when applying ");
- ERROR("directly to a NTFS volume");
+ ERROR("Cannot specify symlink or hardlink flags when applying\n"
+ " directly to a NTFS volume");
return WIMLIB_ERR_INVALID_PARAM;
}
if (image == WIMLIB_ALL_IMAGES) {