X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fntfs-3g_apply.c;h=ef4346f6f96f05c2062ce7fd84c89c34e399b0f7;hb=958cc5438f3ade80baafcfbf15da370e819a6b90;hp=ff145a61871a2cc98184bd9599672b8a0085ee7b;hpb=57318a10de8d50cd338fa4c0e4e0b9f60e7c0143;p=wimlib diff --git a/src/ntfs-3g_apply.c b/src/ntfs-3g_apply.c index ff145a61..ef4346f6 100644 --- a/src/ntfs-3g_apply.c +++ b/src/ntfs-3g_apply.c @@ -12,20 +12,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/. */ #ifdef HAVE_CONFIG_H @@ -44,6 +42,7 @@ #include "wimlib/dentry.h" #include "wimlib/encoding.h" #include "wimlib/error.h" +#include "wimlib/lookup_table.h" #include "wimlib/metadata.h" #include "wimlib/ntfs_3g.h" #include "wimlib/reparse.h" @@ -70,8 +69,6 @@ ntfs_3g_get_supported_features(const char *target, return 0; } -#define MAX_OPEN_ATTRS 1024 - struct ntfs_3g_apply_ctx { /* Extract flags, the pointer to the WIMStruct, etc. */ struct apply_ctx common; @@ -79,9 +76,9 @@ struct ntfs_3g_apply_ctx { /* Pointer to the open NTFS volume */ ntfs_volume *vol; - ntfs_attr *open_attrs[MAX_OPEN_ATTRS]; + ntfs_attr *open_attrs[MAX_OPEN_STREAMS]; unsigned num_open_attrs; - ntfs_inode *open_inodes[MAX_OPEN_ATTRS]; + ntfs_inode *open_inodes[MAX_OPEN_STREAMS]; unsigned num_open_inodes; struct reparse_buffer_disk rpbuf; @@ -91,8 +88,8 @@ struct ntfs_3g_apply_ctx { u64 offset; unsigned num_reparse_inodes; - ntfs_inode *ntfs_reparse_inodes[MAX_OPEN_ATTRS]; - struct wim_inode *wim_reparse_inodes[MAX_OPEN_ATTRS]; + ntfs_inode *ntfs_reparse_inodes[MAX_OPEN_STREAMS]; + struct wim_inode *wim_reparse_inodes[MAX_OPEN_STREAMS]; }; static size_t @@ -403,9 +400,10 @@ ntfs_3g_set_metadata(ntfs_inode *ni, const struct wim_inode *inode, ERROR_WITH_ERRNO("Failed to set security descriptor " "on \"%s\" in NTFS volume", dentry_full_path(one_dentry)); - fprintf(stderr, "The security descriptor is: "); - print_byte_field(desc, desc_size, stderr); - fprintf(stderr, "\n"); + fprintf(wimlib_error_file, + "The security descriptor is: "); + print_byte_field(desc, desc_size, wimlib_error_file); + fprintf(wimlib_error_file, "\n"); } return ret; } @@ -426,7 +424,7 @@ ntfs_3g_set_metadata(ntfs_inode *ni, const struct wim_inode *inode, * the NTFS inode @dir_ni. */ static int ntfs_3g_create_dirs_recursive(ntfs_inode *dir_ni, struct wim_dentry *dir, - const struct ntfs_3g_apply_ctx *ctx) + struct ntfs_3g_apply_ctx *ctx) { struct wim_dentry *child; @@ -449,7 +447,9 @@ ntfs_3g_create_dirs_recursive(ntfs_inode *dir_ni, struct wim_dentry *dir, child->d_inode->i_mft_no = ni->mft_no; - ret = ntfs_3g_set_metadata(ni, child->d_inode, ctx); + ret = report_file_created(&ctx->common); + if (!ret) + ret = ntfs_3g_set_metadata(ni, child->d_inode, ctx); if (!ret) ret = ntfs_3g_create_any_empty_ads(ni, child->d_inode, ctx); if (!ret) @@ -471,7 +471,7 @@ ntfs_3g_create_dirs_recursive(ntfs_inode *dir_ni, struct wim_dentry *dir, static int ntfs_3g_create_directories(struct wim_dentry *root, struct list_head *dentry_list, - const struct ntfs_3g_apply_ctx *ctx) + struct ntfs_3g_apply_ctx *ctx) { ntfs_inode *root_ni; int ret; @@ -505,6 +505,9 @@ ntfs_3g_create_directories(struct wim_dentry *root, ret = ntfs_3g_restore_dos_name(NULL, NULL, dentry, ctx->vol); if (ret) return ret; + ret = report_file_created(&ctx->common); + if (ret) + return ret; } return 0; } @@ -627,7 +630,6 @@ ntfs_3g_create_nondirectory(struct wim_inode *inode, /* Create additional links if present. */ next = inode->i_extraction_aliases.next; - ret = 0; do { dentry = list_entry(next, struct wim_dentry, d_extraction_alias_node); @@ -662,7 +664,7 @@ out_close_ni: * Directories must have already been created. */ static int ntfs_3g_create_nondirectories(struct list_head *dentry_list, - const struct ntfs_3g_apply_ctx *ctx) + struct ntfs_3g_apply_ctx *ctx) { struct wim_dentry *dentry; struct wim_inode *inode; @@ -672,9 +674,12 @@ ntfs_3g_create_nondirectories(struct list_head *dentry_list, inode = dentry->d_inode; if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) continue; - if (dentry != inode_first_extraction_dentry(inode)) - continue; - ret = ntfs_3g_create_nondirectory(inode, ctx); + if (dentry == inode_first_extraction_dentry(inode)) { + ret = ntfs_3g_create_nondirectory(inode, ctx); + if (ret) + return ret; + } + ret = report_file_created(&ctx->common); if (ret) return ret; } @@ -726,6 +731,9 @@ ntfs_3g_begin_extract_stream_to_attr(struct wim_lookup_table_entry *stream, return WIMLIB_ERR_NTFS_3G; } + /* This should be ensured by extract_stream_list() */ + wimlib_assert(ctx->num_open_attrs < MAX_OPEN_STREAMS); + attr = ntfs_attr_open(ni, AT_DATA, stream_name, stream_name_nchars); if (!attr) { ERROR_WITH_ERRNO("Failed to open data stream of \"%s\"", @@ -791,8 +799,7 @@ ntfs_3g_open_inode(struct wim_inode *inode, struct ntfs_3g_apply_ctx *ctx) } static int -ntfs_3g_begin_extract_stream(struct wim_lookup_table_entry *stream, - u32 flags, void *_ctx) +ntfs_3g_begin_extract_stream(struct wim_lookup_table_entry *stream, void *_ctx) { struct ntfs_3g_apply_ctx *ctx = _ctx; const struct stream_owner *owners = stream_owners(stream); @@ -883,6 +890,25 @@ out: return ret; } +static uint64_t +ntfs_3g_count_dentries(const struct list_head *dentry_list) +{ + const struct wim_dentry *dentry; + uint64_t count = 0; + + list_for_each_entry(dentry, dentry_list, d_extraction_list_node) { + count++; + if ((dentry->d_inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) && + dentry_has_short_name(dentry)) + { + count++; + } + + } + + return count; +} + static int ntfs_3g_extract(struct list_head *dentry_list, struct apply_ctx *_ctx) { @@ -908,6 +934,11 @@ ntfs_3g_extract(struct list_head *dentry_list, struct apply_ctx *_ctx) /* Create all inodes and aliases, including short names, and set * metadata (attributes, security descriptors, and timestamps). */ + ret = start_file_structure_phase(&ctx->common, + ntfs_3g_count_dentries(dentry_list)); + if (ret) + goto out_unmount; + ret = ntfs_3g_create_directories(root, dentry_list, ctx); if (ret) goto out_unmount; @@ -916,6 +947,10 @@ ntfs_3g_extract(struct list_head *dentry_list, struct apply_ctx *_ctx) if (ret) goto out_unmount; + ret = end_file_structure_phase(&ctx->common); + if (ret) + goto out_unmount; + /* Extract streams. */ struct read_stream_list_callbacks cbs = { .begin_stream = ntfs_3g_begin_extract_stream,