X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fextract.c;h=9a43e630b7c0e3d2b840be0bc83769aafcaae29e;hp=c6711ec902dd36f43df80b972531bfa14fc22da1;hb=5d3d469e410dc5f4a28814ad231336fc174cba56;hpb=3ce89e945a252d62169280e2d7cc460fca7d0820 diff --git a/src/extract.c b/src/extract.c index c6711ec9..9a43e630 100644 --- a/src/extract.c +++ b/src/extract.c @@ -93,7 +93,7 @@ dentry_resolve_and_zero_lte_refcnt(struct wim_dentry *dentry, void *_ctx) * "resolve" the inode's streams anyway by allocating new entries. */ if (ctx->extract_flags & WIMLIB_EXTRACT_FLAG_FROM_PIPE) force = true; - ret = inode_resolve_ltes(inode, ctx->wim->lookup_table, force); + ret = inode_resolve_streams(inode, ctx->wim->lookup_table, force); if (ret) return ret; for (unsigned i = 0; i <= inode->i_num_ads; i++) { @@ -1147,7 +1147,8 @@ dentry_extract_skeleton(struct wim_dentry *dentry, void *_ctx) inode_for_each_dentry(other_dentry, dentry->d_inode) { if (dentry_has_short_name(other_dentry) && !other_dentry->skeleton_extracted - && other_dentry->in_extraction_tree) + && other_dentry->in_extraction_tree + && !other_dentry->extraction_skipped) { DEBUG("Creating %"TS" before %"TS" " "to guarantee correct DOS name extraction", @@ -1507,7 +1508,7 @@ extract_streams_from_pipe(struct apply_ctx *ctx) if ((found_lte->resource_location != RESOURCE_NONEXISTENT) && !(found_lte->flags & WIM_RESHDR_FLAG_METADATA) - && (needed_lte = lookup_resource(lookup_table, found_lte->hash)) + && (needed_lte = lookup_stream(lookup_table, found_lte->hash)) && (needed_lte->out_refcnt)) { tchar *tmpfile_name = NULL; @@ -1527,8 +1528,10 @@ extract_streams_from_pipe(struct apply_ctx *ctx) /* Extract stream to temporary file. */ ret = create_temporary_file(&tmpfile_fd, &tmpfile_name); - if (ret) + if (ret) { + lte_unbind_wim_resource_spec(needed_lte); goto out_free_found_lte; + } ret = extract_full_stream_to_fd(needed_lte, &tmpfile_fd); @@ -2374,7 +2377,12 @@ extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees, * directory tree. (If not, extract_dentry_to_stdout() will * return an error.) */ if (extract_flags & WIMLIB_EXTRACT_FLAG_TO_STDOUT) { - ret = extract_dentry_to_stdout(ctx.extract_root); + ret = 0; + for (size_t i = 0; i < num_trees; i++) { + ret = extract_dentry_to_stdout(trees[i]); + if (ret) + break; + } goto out_teardown_stream_list; } @@ -2592,19 +2600,12 @@ extract_tree(WIMStruct *wim, const tchar *wim_source_path, target, extract_flags, progress_func); } -/* Validates a single wimlib_extract_command, mostly checking to make sure the - * extract flags make sense. */ +/* Make sure the extraction flags make sense, and update them if needed. */ static int -check_extract_command(struct wimlib_extract_command *cmd, int wim_header_flags) +check_extract_flags(int extract_flags, + const u32 wim_header_flags, + int *updated_extract_flags_ret) { - int extract_flags; - - /* Empty destination path? */ - if (cmd->fs_dest_path[0] == T('\0')) - return WIMLIB_ERR_INVALID_PARAM; - - extract_flags = cmd->extract_flags; - /* Check for invalid flag combinations */ if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | @@ -2612,9 +2613,6 @@ check_extract_command(struct wimlib_extract_command *cmd, int wim_header_flags) WIMLIB_EXTRACT_FLAG_HARDLINK)) return WIMLIB_ERR_INVALID_PARAM; - if (extract_flags & WIMLIB_EXTRACT_FLAG_GLOB_PATHS) - return WIMLIB_ERR_INVALID_PARAM; - if ((extract_flags & (WIMLIB_EXTRACT_FLAG_NO_ACLS | WIMLIB_EXTRACT_FLAG_STRICT_ACLS)) == (WIMLIB_EXTRACT_FLAG_NO_ACLS | @@ -2632,13 +2630,13 @@ check_extract_command(struct wimlib_extract_command *cmd, int wim_header_flags) WIMLIB_EXTRACT_FLAG_FROM_PIPE)) == WIMLIB_EXTRACT_FLAG_RESUME) return WIMLIB_ERR_INVALID_PARAM; - if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) { #ifndef WITH_NTFS_3G + if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) { ERROR("wimlib was compiled without support for NTFS-3g, so\n" " we cannot apply a WIM image directly to a NTFS volume."); return WIMLIB_ERR_UNSUPPORTED; -#endif } +#endif if ((extract_flags & (WIMLIB_EXTRACT_FLAG_RPFIX | WIMLIB_EXTRACT_FLAG_NORPFIX)) == 0) @@ -2669,7 +2667,8 @@ check_extract_command(struct wimlib_extract_command *cmd, int wim_header_flags) } } - cmd->extract_flags = extract_flags; + if (updated_extract_flags_ret) + *updated_extract_flags_ret = extract_flags; return 0; } @@ -2700,7 +2699,16 @@ do_wimlib_extract_files(WIMStruct *wim, /* Check for problems with the extraction commands */ for (size_t i = 0; i < num_cmds; i++) { - ret = check_extract_command(&cmds[i], wim->hdr.flags); + + if (cmds[i].fs_dest_path[0] == T('\0')) + return WIMLIB_ERR_INVALID_PARAM; + + if (cmds[i].extract_flags & WIMLIB_EXTRACT_FLAG_GLOB_PATHS) + return WIMLIB_ERR_INVALID_PARAM; + + ret = check_extract_flags(cmds[i].extract_flags, + wim->hdr.flags, + &cmds[i].extract_flags); if (ret) return ret; if (cmds[i].extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | @@ -3117,8 +3125,11 @@ wimlib_extract_pathlist(WIMStruct *wim, int image, void *mem; ret = read_path_list_file(path_list_file, &paths, &num_paths, &mem); - if (ret) + if (ret) { + ERROR("Failed to read path list file \"%"TS"\"", + path_list_file); return ret; + } ret = wimlib_extract_paths(wim, image, target, (const tchar * const *)paths, num_paths, @@ -3167,24 +3178,32 @@ wimlib_extract_paths(WIMStruct *wim, wimlib_progress_func_t progress_func) { int ret; - struct append_dentry_ctx append_dentry_ctx = { - .dentries = NULL, - .num_dentries = 0, - .num_alloc_dentries = 0, - }; struct wim_dentry **trees; size_t num_trees; extract_flags &= WIMLIB_EXTRACT_MASK_PUBLIC; - if (target == NULL || (num_paths != 0 && paths == NULL)) + if (wim == NULL || target == NULL || target[0] == T('\0') || + (num_paths != 0 && paths == NULL)) return WIMLIB_ERR_INVALID_PARAM; + ret = check_extract_flags(extract_flags, wim->hdr.flags, + &extract_flags); + if (ret) + return ret; + ret = select_wim_image(wim, image); if (ret) return ret; if (extract_flags & WIMLIB_EXTRACT_FLAG_GLOB_PATHS) { + + struct append_dentry_ctx append_dentry_ctx = { + .dentries = NULL, + .num_dentries = 0, + .num_alloc_dentries = 0, + }; + u32 wildcard_flags = 0; if (extract_flags & WIMLIB_EXTRACT_FLAG_STRICT_GLOB) @@ -3196,10 +3215,17 @@ wimlib_extract_paths(WIMStruct *wim, wildcard_flags |= WILDCARD_FLAG_CASE_INSENSITIVE; for (size_t i = 0; i < num_paths; i++) { - ret = expand_wildcard(wim, paths[i], + tchar *path = canonicalize_wim_path(paths[i]); + if (path == NULL) { + ret = WIMLIB_ERR_NOMEM; + trees = append_dentry_ctx.dentries; + goto out_free_trees; + } + ret = expand_wildcard(wim, path, append_dentry_cb, &append_dentry_ctx, wildcard_flags); + FREE(path); if (ret) { trees = append_dentry_ctx.dentries; goto out_free_trees; @@ -3213,8 +3239,16 @@ wimlib_extract_paths(WIMStruct *wim, return WIMLIB_ERR_NOMEM; for (size_t i = 0; i < num_paths; i++) { - trees[i] = get_dentry(wim, paths[i], + + tchar *path = canonicalize_wim_path(paths[i]); + if (path == NULL) { + ret = WIMLIB_ERR_NOMEM; + goto out_free_trees; + } + + trees[i] = get_dentry(wim, path, WIMLIB_CASE_PLATFORM_DEFAULT); + FREE(path); if (trees[i] == NULL) { ERROR("Path \"%"TS"\" does not exist " "in WIM image %d", @@ -3237,6 +3271,14 @@ wimlib_extract_paths(WIMStruct *wim, ~WIMLIB_EXTRACT_FLAG_GLOB_PATHS) | WIMLIB_EXTRACT_FLAG_PATHMODE), progress_func); + + if (extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | + WIMLIB_EXTRACT_FLAG_HARDLINK)) + { + for_lookup_table_entry(wim->lookup_table, + lte_free_extracted_file, + NULL); + } out_free_trees: FREE(trees); return ret;