* @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);
* @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,
* @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);
* @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);
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 */
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!",
* 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;
/* 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;
}
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) {
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)
{
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);
/* 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;
}
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
{
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);
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;
{
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);