X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fupdate_image.c;h=f1776ec93cfb192cf1f5064c7a9a839f73eae915;hb=4eb18e0c42c31de268f428c355f7a661f614a80f;hp=e85cd60671fa4350c11e3f41fe7ce5e25b978757;hpb=726f9bbd0bd664294fce8a50be1d5b6881df8d16;p=wimlib diff --git a/src/update_image.c b/src/update_image.c index e85cd606..f1776ec9 100644 --- a/src/update_image.c +++ b/src/update_image.c @@ -21,16 +21,22 @@ * along with wimlib; if not, see http://www.gnu.org/licenses/. */ -#include "wimlib_internal.h" -#include "dentry.h" -#include "lookup_table.h" -#include "security.h" -#include "xml.h" -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -#ifdef __WIN32__ -# include "win32.h" +#include "wimlib/capture.h" +#include "wimlib/dentry.h" +#include "wimlib/error.h" +#include "wimlib/lookup_table.h" +#include "wimlib/metadata.h" +#ifdef WITH_NTFS_3G +# include "wimlib/ntfs_3g.h" /* for do_ntfs_umount() */ #endif +#include "wimlib/paths.h" +#include "wimlib/xml.h" + +#include /* Overlays @branch onto @target, both of which must be directories. */ static int @@ -128,7 +134,7 @@ attach_branch(struct wim_dentry **root_p, struct wim_dentry *branch, /* Walk the path to the branch, creating filler directories as needed. * */ parent = *root_p; - while ((slash = tstrchr(target_path, T('/')))) { + while ((slash = tstrchr(target_path, WIM_PATH_SEPARATOR))) { *slash = T('\0'); dentry = get_dentry_child_with_name(parent, target_path); if (!dentry) { @@ -144,7 +150,7 @@ attach_branch(struct wim_dentry **root_p, struct wim_dentry *branch, * trailing slashes were tripped. */ do { ++target_path; - } while (*target_path == T('/')); + } while (*target_path == WIM_PATH_SEPARATOR); } /* If the target path already existed, overlay the branch onto it. @@ -237,11 +243,13 @@ execute_add_command(WIMStruct *wim, progress.scan.wim_target_path = wim_target_path; progress_func(WIMLIB_PROGRESS_MSG_SCAN_BEGIN, &progress); } - config->_prefix = fs_source_path; - config->_prefix_num_tchars = tstrlen(fs_source_path); + if (config) { + config->_prefix = fs_source_path; + config->_prefix_num_tchars = tstrlen(fs_source_path); + } if (wim_target_path[0] == T('\0')) - add_flags |= WIMLIB_ADD_FLAG_ROOT; + params.add_flags |= WIMLIB_ADD_FLAG_ROOT; ret = (*capture_tree)(&branch, fs_source_path, ¶ms); if (ret) { ERROR("Failed to build dentry tree for \"%"TS"\"", @@ -454,6 +462,7 @@ update_op_to_str(int op) return T("rename"); default: wimlib_assert(0); + return NULL; } } @@ -461,12 +470,23 @@ static int execute_update_commands(WIMStruct *wim, const struct wimlib_update_command *cmds, size_t num_cmds, + int update_flags, wimlib_progress_func_t progress_func) { int ret = 0; + union wimlib_progress_info info; + info.update.completed_commands = 0; + info.update.total_commands = num_cmds; for (size_t i = 0; i < num_cmds; i++) { DEBUG("Executing update command %zu of %zu (op=%"TS")", i + 1, num_cmds, update_op_to_str(cmds[i].op)); + if (update_flags & WIMLIB_UPDATE_FLAG_SEND_PROGRESS && + progress_func) + { + info.update.command = &cmds[i]; + (*progress_func)(WIMLIB_PROGRESS_MSG_UPDATE_BEGIN_COMMAND, + &info); + } switch (cmds[i].op) { case WIMLIB_UPDATE_OP_ADD: ret = execute_add_command(wim, &cmds[i], progress_func); @@ -482,6 +502,13 @@ execute_update_commands(WIMStruct *wim, } if (ret) break; + info.update.completed_commands++; + if (update_flags & WIMLIB_UPDATE_FLAG_SEND_PROGRESS && + progress_func) + { + (*progress_func)(WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND, + &info); + } } return ret; } @@ -589,7 +616,7 @@ check_update_commands(struct wimlib_update_command *cmds, size_t num_cmds, } -extern void +static void free_update_commands(struct wimlib_update_command *cmds, size_t num_cmds) { if (cmds) { @@ -690,15 +717,21 @@ wimlib_update_image(WIMStruct *wim, { int ret; struct wimlib_update_command *cmds_copy; + bool deletion_requested = false; DEBUG("Updating image %d with %zu commands", image, num_cmds); - /* Refuse to update a split WIM. */ - if (wim->hdr.total_parts != 1) { - ERROR("Cannot update a split WIM!"); - ret = WIMLIB_ERR_SPLIT_UNSUPPORTED; + for (size_t i = 0; i < num_cmds; i++) + if (cmds[i].op == WIMLIB_UPDATE_OP_DELETE) + deletion_requested = true; + + if (deletion_requested) + ret = can_delete_from_wim(wim); + else + ret = can_modify_wim(wim); + + if (ret) goto out; - } /* Load the metadata for the image to modify (if not loaded already) */ ret = select_wim_image(wim, image); @@ -728,7 +761,8 @@ wimlib_update_image(WIMStruct *wim, /* Actually execute the update commands. */ DEBUG("Executing %zu update commands", num_cmds); - ret = execute_update_commands(wim, cmds_copy, num_cmds, progress_func); + ret = execute_update_commands(wim, cmds_copy, num_cmds, update_flags, + progress_func); if (ret) goto out_free_cmds_copy;