X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fupdate_image.c;h=c088c831786f18e7920c2667cb66f55b067a5169;hp=3e7613fcfa5dbc12e37a7bdd3985a1cc24b764cb;hb=e3dc3c76cf0896eb98f455f2538999d23f95b61a;hpb=8c502bdb549cddf3d42d56731467c45cc2b8e503 diff --git a/src/update_image.c b/src/update_image.c index 3e7613fc..c088c831 100644 --- a/src/update_image.c +++ b/src/update_image.c @@ -328,15 +328,13 @@ static int journaled_link(struct update_command_journal *j, struct wim_dentry *subject, struct wim_dentry *parent) { - struct update_primitive prim = { - .type = LINK_DENTRY, - .link = { - .subject = subject, - .parent = parent, - }, - }; + struct update_primitive prim; int ret; + prim.type = LINK_DENTRY; + prim.link.subject = subject; + prim.link.parent = parent; + ret = record_update_primitive(j, prim); if (ret) return ret; @@ -356,21 +354,18 @@ journaled_link(struct update_command_journal *j, static int journaled_unlink(struct update_command_journal *j, struct wim_dentry *subject) { - int ret; struct wim_dentry *parent; + struct update_primitive prim; + int ret; if (dentry_is_root(subject)) parent = NULL; else parent = subject->parent; - struct update_primitive prim = { - .type = UNLINK_DENTRY, - .link = { - .subject = subject, - .parent = parent, - }, - }; + prim.type = UNLINK_DENTRY; + prim.link.subject = subject; + prim.link.parent = parent; ret = record_update_primitive(j, prim); if (ret) @@ -458,21 +453,33 @@ rollback_update(struct update_command_journal *j) free_update_command_journal(j); } +/* + * Set the name of @branch for placing it at @target in the WIM image. This + * assumes that @target is in "canonical form", as produced by + * canonicalize_wim_path(). + * + * Note: for the root target this produces the empty name. + */ static int set_branch_name(struct wim_dentry *branch, const utf16lechar *target) { const utf16lechar *p; + /* Find end of string. (We can assume it contains at least one + * character, the leading slash.) */ + wimlib_assert(target[0] == cpu_to_le16(WIM_PATH_SEPARATOR)); p = target; - while (*p) + do { p++; + } while (*p); - /* No trailing slashes allowed */ - wimlib_assert(p == target || *(p - 1) != cpu_to_le16(WIM_PATH_SEPARATOR)); - - while (p > target && *(p - 1) != cpu_to_le16(WIM_PATH_SEPARATOR)) + while (*(p - 1) != cpu_to_le16(WIM_PATH_SEPARATOR)) p--; + + /* We're assuming no trailing slashes. */ + wimlib_assert(*p || p == &target[1]); + return dentry_set_name_utf16le(branch, p); } @@ -715,6 +722,7 @@ static const char wincfg[] = "/$ntfs.log\n" "/hiberfil.sys\n" "/pagefile.sys\n" +"/swapfile.sys\n" "/System Volume Information\n" "/RECYCLER\n" "/Windows/CSC\n"; @@ -808,8 +816,8 @@ execute_add_command(struct update_command_journal *j, memset(¶ms, 0, sizeof(params)); +#ifdef WITH_NTFS_3G if (add_flags & WIMLIB_ADD_FLAG_NTFS) { - #ifdef WITH_NTFS_3G capture_tree = build_dentry_tree_ntfs; extra_arg = &ntfs_vol; if (wim_get_current_image_metadata(wim)->ntfs_vol != NULL) { @@ -817,11 +825,8 @@ execute_add_command(struct update_command_journal *j, ret = WIMLIB_ERR_INVALID_PARAM; goto out; } - #else - ret = WIMLIB_ERR_INVALID_PARAM; - goto out; - #endif } +#endif ret = get_capture_config(config_file, &config, add_flags, fs_source_path); @@ -842,10 +847,7 @@ execute_add_command(struct update_command_journal *j, if (progress_func) progress_func(WIMLIB_PROGRESS_MSG_SCAN_BEGIN, ¶ms.progress); - config.prefix = fs_source_path; - config.prefix_num_tchars = tstrlen(fs_source_path); - - if (wim_target_path[0] == T('\0')) + if (WIMLIB_IS_WIM_ROOT_PATH(wim_target_path)) params.add_flags |= WIMLIB_ADD_FLAG_ROOT; ret = (*capture_tree)(&branch, fs_source_path, ¶ms); if (ret) @@ -854,7 +856,7 @@ execute_add_command(struct update_command_journal *j, if (progress_func) progress_func(WIMLIB_PROGRESS_MSG_SCAN_END, ¶ms.progress); - if (wim_target_path[0] == T('\0') && + if (WIMLIB_IS_WIM_ROOT_PATH(wim_target_path) && branch && !dentry_is_directory(branch)) { ERROR("\"%"TS"\" is not a directory!", fs_source_path); @@ -869,7 +871,7 @@ execute_add_command(struct update_command_journal *j, goto out_cleanup_after_capture; if (config_file && (add_flags & WIMLIB_ADD_FLAG_WIMBOOT) && - wim_target_path[0] == T('\0')) + WIMLIB_IS_WIM_ROOT_PATH(wim_target_path)) { params.add_flags = 0; params.progress_func = NULL; @@ -1022,28 +1024,23 @@ rename_wim_path(WIMStruct *wim, const tchar *from, const tchar *to, return -EBUSY; if (j) { + if (dst) + if (journaled_unlink(j, dst)) + return -ENOMEM; + if (journaled_unlink(j, src)) + return -ENOMEM; if (journaled_change_name(j, src, path_basename(to))) return -ENOMEM; + if (journaled_link(j, src, parent_of_dst)) + return -ENOMEM; } else { ret = dentry_set_name(src, path_basename(to)); if (ret) return -ENOMEM; - } - if (dst) { - if (j) { - if (journaled_unlink(j, dst)) - return -ENOMEM; - } else { + if (dst) { unlink_dentry(dst); free_dentry_tree(dst, wim->lookup_table); } - } - if (j) { - if (journaled_unlink(j, src)) - return -ENOMEM; - if (journaled_link(j, src, parent_of_dst)) - return -ENOMEM; - } else { unlink_dentry(src); dentry_add_child(parent_of_dst, src); } @@ -1253,20 +1250,19 @@ check_add_command(struct wimlib_update_command *cmd, WIMLIB_ADD_FLAG_NO_REPLACE)) return WIMLIB_ERR_INVALID_PARAM; - /* Are we adding the entire image or not? An empty wim_target_path - * indicates that the tree we're adding is to be placed in the root of - * the image. We consider this to be capturing the entire image, - * although it could potentially be an overlay on an existing root as - * well. */ - bool is_entire_image = cmd->add.wim_target_path[0] == T('\0'); + bool is_entire_image = WIMLIB_IS_WIM_ROOT_PATH(cmd->add.wim_target_path); -#ifdef __WIN32__ - /* Check for flags not supported on Windows */ +#ifndef WITH_NTFS_3G if (add_flags & WIMLIB_ADD_FLAG_NTFS) { - ERROR("wimlib was compiled without support for NTFS-3g, so"); - ERROR("we cannot capture a WIM image directly from a NTFS volume"); + ERROR("wimlib was compiled without support for NTFS-3g, so\n" + " we cannot capture a WIM image directly " + "from an NTFS volume"); return WIMLIB_ERR_UNSUPPORTED; } +#endif + +#ifdef __WIN32__ + /* Check for flags not supported on Windows */ if (add_flags & WIMLIB_ADD_FLAG_UNIX_DATA) { ERROR("Capturing UNIX-specific data is not supported on Windows"); return WIMLIB_ERR_UNSUPPORTED; @@ -1375,9 +1371,7 @@ free_update_commands(struct wimlib_update_command *cmds, size_t num_cmds) for (size_t i = 0; i < num_cmds; i++) { switch (cmds[i].op) { case WIMLIB_UPDATE_OP_ADD: - FREE(cmds[i].add.fs_source_path); FREE(cmds[i].add.wim_target_path); - FREE(cmds[i].add.config_file); break; case WIMLIB_UPDATE_OP_DELETE: FREE(cmds[i].delete_.wim_path); @@ -1408,18 +1402,12 @@ copy_update_commands(const struct wimlib_update_command *cmds, cmds_copy[i].op = cmds[i].op; switch (cmds[i].op) { case WIMLIB_UPDATE_OP_ADD: - cmds_copy[i].add.fs_source_path = - canonicalize_fs_path(cmds[i].add.fs_source_path); + cmds_copy[i].add.fs_source_path = cmds[i].add.fs_source_path; cmds_copy[i].add.wim_target_path = canonicalize_wim_path(cmds[i].add.wim_target_path); - if (!cmds_copy[i].add.fs_source_path || - !cmds_copy[i].add.wim_target_path) + if (!cmds_copy[i].add.wim_target_path) goto oom; - if (cmds[i].add.config_file) { - cmds_copy[i].add.config_file = TSTRDUP(cmds[i].add.config_file); - if (!cmds_copy[i].add.config_file) - goto oom; - } + cmds_copy[i].add.config_file = cmds[i].add.config_file; cmds_copy[i].add.add_flags = cmds[i].add.add_flags; break; case WIMLIB_UPDATE_OP_DELETE: