From 28d3d79a1894375e457237097bc80f0d92746018 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 21 May 2013 14:42:37 -0500 Subject: [PATCH] Add can_modify_wim(), can_delete_from_wim() --- include/wimlib.h | 15 ++++++++++----- include/wimlib/wim.h | 6 ++++++ src/add_image.c | 6 ++---- src/delete_image.c | 41 +++++++++++++++++------------------------ src/export_image.c | 8 +++----- src/mount_image.c | 18 ++++-------------- src/update_image.c | 16 +++++++++++----- src/wim.c | 39 ++++++++++++++++++++++++++++++++------- src/xml.c | 18 +++++++++++++----- 9 files changed, 98 insertions(+), 69 deletions(-) diff --git a/include/wimlib.h b/include/wimlib.h index 85b2f291..c1c00e42 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -2275,8 +2275,7 @@ wimlib_resolve_image(WIMStruct *wim, * @a boot_idx does not specify an existing image in @a wim, and it was not * 0. * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED - * @a wim is part of a split WIM. We do not support changing the boot - * index of a split WIM. + * @a wim is part of a split WIM. */ extern int wimlib_set_boot_idx(WIMStruct *wim, int boot_idx); @@ -2300,6 +2299,8 @@ wimlib_set_boot_idx(WIMStruct *wim, int boot_idx); * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @a description * string. + * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED + * @a wim is part of a split WIM. */ extern int wimlib_set_image_descripton(WIMStruct *wim, int image, @@ -2324,6 +2325,8 @@ wimlib_set_image_descripton(WIMStruct *wim, int image, * @a image does not specify a single existing image in @a wim. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @a flags string. + * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED + * @a wim is part of a split WIM. */ extern int wimlib_set_image_flags(WIMStruct *wim, int image, const wimlib_tchar *flags); @@ -2338,17 +2341,19 @@ extern int wimlib_set_image_flags(WIMStruct *wim, int image, * @param image * The number of the image for which to change the name. * @param name - * The new name to give the image. It must be a nonempty string. + * New name to give the new image. If @c NULL or empty, the new image is + * given no name. If nonempty, it must specify a name that does not + * already exist in @a wim. * * @return 0 on success; nonzero on error. * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION * There is already an image named @a name in @a wim. - * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a name was @c NULL or the empty string. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not specify a single existing image in @a wim. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @a name string. + * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED + * @a wim is part of a split WIM. */ extern int wimlib_set_image_name(WIMStruct *wim, int image, const wimlib_tchar *name); diff --git a/include/wimlib/wim.h b/include/wimlib/wim.h index 946eee1f..c1e669f9 100644 --- a/include/wimlib/wim.h +++ b/include/wimlib/wim.h @@ -83,4 +83,10 @@ reopen_wim(WIMStruct *w); extern int close_wim(WIMStruct *w); +extern int +can_modify_wim(WIMStruct *wim); + +extern int +can_delete_from_wim(WIMStruct *wim); + #endif /* _WIMLIB_WIM_H */ diff --git a/src/add_image.c b/src/add_image.c index 7dcee10b..d40dfa09 100644 --- a/src/add_image.c +++ b/src/add_image.c @@ -80,11 +80,9 @@ wimlib_add_empty_image(WIMStruct *wim, const tchar *name, int *new_idx_ret) if (name == NULL) name = T(""); - if (wim->hdr.total_parts != 1) { - ERROR("Cannot add an image to a split WIM"); - ret = WIMLIB_ERR_SPLIT_UNSUPPORTED; + ret = can_modify_wim(wim); + if (ret) goto out; - } if (wimlib_image_name_in_use(wim, name)) { ERROR("There is already an image named \"%"TS"\" in the WIM!", diff --git a/src/delete_image.c b/src/delete_image.c index 862fb66e..e73efab2 100644 --- a/src/delete_image.c +++ b/src/delete_image.c @@ -36,24 +36,17 @@ * Deletes an image from the WIM. */ WIMLIBAPI int -wimlib_delete_image(WIMStruct *w, int image) +wimlib_delete_image(WIMStruct *wim, int image) { int ret; int first, last; - if (w->hdr.total_parts != 1) { - ERROR("Deleting an image from a split WIM is not supported."); - return WIMLIB_ERR_SPLIT_UNSUPPORTED; - } - - if (!w->all_images_verified) { - ret = wim_run_full_verifications(w); - if (ret) - return ret; - } + ret = can_delete_from_wim(wim); + if (ret) + return ret; if (image == WIMLIB_ALL_IMAGES) { - last = w->hdr.image_count; + last = wim->hdr.image_count; first = 1; } else { last = image; @@ -66,34 +59,34 @@ wimlib_delete_image(WIMStruct *w, int image) /* Even if the dentry tree is not allocated, we must select it (and * therefore allocate it) so that we can decrement the reference counts * in the lookup table. */ - ret = select_wim_image(w, image); + ret = select_wim_image(wim, image); if (ret) return ret; /* Unless the image metadata is shared by another WIMStruct, free the * dentry tree, any lookup table entries that have their refcnt * decremented to 0, and the security data. */ - put_image_metadata(w->image_metadata[image - 1], w->lookup_table); + put_image_metadata(wim->image_metadata[image - 1], wim->lookup_table); /* Get rid of the empty slot in the image metadata array. */ - for (int i = image - 1; i < w->hdr.image_count - 1; i++) - w->image_metadata[i] = w->image_metadata[i + 1]; + for (int i = image - 1; i < wim->hdr.image_count - 1; i++) + wim->image_metadata[i] = wim->image_metadata[i + 1]; /* Decrement the image count. */ - --w->hdr.image_count; + --wim->hdr.image_count; /* Fix the boot index. */ - if (w->hdr.boot_idx == image) - w->hdr.boot_idx = 0; - else if (w->hdr.boot_idx > image) - w->hdr.boot_idx--; + if (wim->hdr.boot_idx == image) + wim->hdr.boot_idx = 0; + else if (wim->hdr.boot_idx > image) + wim->hdr.boot_idx--; - w->current_image = WIMLIB_NO_IMAGE; + wim->current_image = WIMLIB_NO_IMAGE; /* Remove the image from the XML information. */ - xml_delete_image(&w->wim_info, image); + xml_delete_image(&wim->wim_info, image); - w->deletion_occurred = 1; + wim->deletion_occurred = 1; } return 0; } diff --git a/src/export_image.c b/src/export_image.c index 455baa91..9f8bfa3f 100644 --- a/src/export_image.c +++ b/src/export_image.c @@ -114,11 +114,9 @@ wimlib_export_image(WIMStruct *src_wim, struct list_head lte_list_head; struct wim_inode *inode; - if (dest_wim->hdr.total_parts != 1) { - ERROR("Exporting an image to a split WIM is " - "unsupported"); - return WIMLIB_ERR_SPLIT_UNSUPPORTED; - } + ret = can_modify_wim(dest_wim); + if (ret) + return ret; if (src_image == WIMLIB_ALL_IMAGES) { if (src_wim->hdr.image_count > 1) { diff --git a/src/mount_image.c b/src/mount_image.c index f3e0a427..fbcc1ea7 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -2407,24 +2407,14 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir, if (ret) goto out; - if ((mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) && (wim->hdr.total_parts != 1)) { - ERROR("Cannot mount a split WIM read-write"); - ret = WIMLIB_ERR_SPLIT_UNSUPPORTED; - goto out; - } - - if (num_additional_swms) - merge_lookup_tables(wim, additional_swms, num_additional_swms); - if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) { - ret = wim_run_full_verifications(wim); + ret = can_delete_from_wim(wim); if (ret) - goto out_restore_lookup_table; + goto out; } - ret = wim_checksum_unhashed_streams(wim); - if (ret) - goto out_restore_lookup_table; + if (num_additional_swms) + merge_lookup_tables(wim, additional_swms, num_additional_swms); ret = select_wim_image(wim, image); if (ret) diff --git a/src/update_image.c b/src/update_image.c index dd63854e..f1776ec9 100644 --- a/src/update_image.c +++ b/src/update_image.c @@ -717,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); diff --git a/src/wim.c b/src/wim.c index 2907cd31..9e73c761 100644 --- a/src/wim.c +++ b/src/wim.c @@ -366,15 +366,16 @@ wimlib_print_files(WIMStruct *w, int image) /* Sets the index of the bootable image. */ WIMLIBAPI int -wimlib_set_boot_idx(WIMStruct *w, int boot_idx) +wimlib_set_boot_idx(WIMStruct *wim, int boot_idx) { - if (w->hdr.total_parts != 1) { - ERROR("Cannot modify the boot index of a split WIM!"); - return WIMLIB_ERR_SPLIT_UNSUPPORTED; - } - if (boot_idx < 0 || boot_idx > w->hdr.image_count) + int ret; + + ret = can_modify_wim(wim); + if (ret) + return ret; + if (boot_idx < 0 || boot_idx > wim->hdr.image_count) return WIMLIB_ERR_INVALID_IMAGE; - w->hdr.boot_idx = boot_idx; + wim->hdr.boot_idx = boot_idx; return 0; } @@ -671,6 +672,30 @@ wim_checksum_unhashed_streams(WIMStruct *w) return 0; } +int +can_modify_wim(WIMStruct *wim) +{ + if (wim->hdr.total_parts != 1) { + if (wim->filename) + ERROR("Cannot modify \"%"TS"\": is a split WIM!", wim->filename); + else + ERROR("Cannot modify a split WIM!"); + return WIMLIB_ERR_SPLIT_UNSUPPORTED; + } + return 0; +} + +int +can_delete_from_wim(WIMStruct *wim) +{ + int ret; + + ret = can_modify_wim(wim); + if (ret == 0 && !wim->all_images_verified) + ret = wim_run_full_verifications(wim); + return ret; +} + /* Frees the memory for the WIMStruct, including all internal memory; also * closes all files associated with the WIMStruct. */ WIMLIBAPI void diff --git a/src/xml.c b/src/xml.c index 67e0a222..6adba78c 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1542,13 +1542,16 @@ wimlib_set_image_name(WIMStruct *w, int image, const tchar *name) { tchar *p; int i; + int ret; DEBUG("Setting the name of image %d to %"TS, image, name); - if (!name || !*name) { - ERROR("Must specify a non-empty string for the image name"); - return WIMLIB_ERR_INVALID_PARAM; - } + ret = can_modify_wim(w); + if (ret) + return ret; + + if (name == NULL) + name = T(""); if (image < 1 || image > w->hdr.image_count) { ERROR("%d is not a valid image", image); @@ -1558,7 +1561,7 @@ wimlib_set_image_name(WIMStruct *w, int image, const tchar *name) for (i = 1; i <= w->hdr.image_count; i++) { if (i == image) continue; - if (tstrcmp(w->wim_info->images[i - 1].name, name) == 0) { + if (!tstrcmp(w->wim_info->images[i - 1].name, name)) { ERROR("The name \"%"TS"\" is already in use in the WIM!", name); return WIMLIB_ERR_IMAGE_NAME_COLLISION; @@ -1580,6 +1583,11 @@ do_set_image_info_str(WIMStruct *w, int image, const tchar *tstr, { tchar *tstr_copy; tchar **dest_tstr_p; + int ret; + + ret = can_modify_wim(w); + if (ret) + return ret; if (image < 1 || image > w->hdr.image_count) { ERROR("%d is not a valid image", image); -- 2.43.0