From: Eric Biggers Date: Tue, 14 Oct 2014 00:42:16 +0000 (-0500) Subject: Limit can_modify_wim() calls; remove can_delete_from_wim() X-Git-Tag: v1.7.3~23 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=4c73e29d8d74a4e969782d2d40e209337414034c Limit can_modify_wim() calls; remove can_delete_from_wim() It isn't necessary to check for permission to modify a WIM for in-memory operations such as wimlib_add_image(), wimlib_update_image(), and wimlib_delete_image(). It is only when the user attempts to modify an on-disk WIM file using wimlib_overwrite() --- or when the user explicitly opens an on-disk WIM file for write access --- that write permissions need to be checked. This change prevents the library from getting in the way of "unusual" use cases, such as making last-minute changes to a WIM before extracting it even when the underlying file is located on read-only media, which otherwise are fully supported by the existing code. Also part of this change is the removal of can_delete_from_wim(). This function did a lot of work (decompressing each metadata resource) that usually turns out to be a waste of time. And it turns out that it really needs to be called for any 'wimlib_update_command', including "add" and "rename", because both "add" and "rename" can cause files to be deleted (specifically, replaced). But this is gone too far. Instead, just get rid of can_delete_from_wim() completely: it's not needed if we retain 0-reference streams when not recalculating reference counts as part of wimlib_write() anyway. --- diff --git a/include/wimlib.h b/include/wimlib.h index 529de437..59e4fb68 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -1248,14 +1248,15 @@ struct wimlib_capture_source { long reserved; }; -/** Set or unset the WIM header flag that marks it read-only - * (WIM_HDR_FLAG_READONLY in Microsoft's documentation), based on the - * ::wimlib_wim_info.is_marked_readonly member of the @p info parameter. This - * is distinct from basic file permissions; this flag can be set on a WIM file - * that is physically writable. If this flag is set, all further operations to - * modify the WIM will fail, except calling wimlib_overwrite() with - * ::WIMLIB_WRITE_FLAG_IGNORE_READONLY_FLAG specified, which is a loophole that - * allows you to set this flag persistently on the underlying WIM file. +/** Set or unset the "readonly" WIM header flag (WIM_HDR_FLAG_READONLY in + * Microsoft's documentation), based on the ::wimlib_wim_info.is_marked_readonly + * member of the @p info parameter. This is distinct from basic file + * permissions; this flag can be set on a WIM file that is physically writable. + * + * wimlib disallows modifying on-disk WIM files with the readonly flag set. + * However, wimlib_overwrite() with ::WIMLIB_WRITE_FLAG_IGNORE_READONLY_FLAG + * will override this --- and in fact, this is necessary to set the readonly + * flag persistently on an existing WIM file. */ #define WIMLIB_CHANGE_READONLY_FLAG 0x00000001 @@ -1973,8 +1974,8 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour * only if it is writable at the filesystem level, does not have the * WIM_HDR_FLAG_READONLY flag set in its header, and is not part of a spanned * set. It is not required to provide this flag before attempting to make - * changes to the WIM, but with this flag you get an error sooner rather than - * later. */ + * changes to the WIM, but with this flag you get an error immediately rather + * than potentially much later, when wimlib_overwrite() is finally called. */ #define WIMLIB_OPEN_FLAG_WRITE_ACCESS 0x00000004 /** @} */ @@ -2468,10 +2469,6 @@ enum wimlib_error_code { * There is already an image in @p wim named @p name. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to add the new image. - * @retval ::WIMLIB_ERR_WIM_IS_READONLY - * The WIM file is considered read-only because of any of the reasons - * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS - * flag. */ extern int wimlib_add_empty_image(WIMStruct *wim, @@ -2634,10 +2631,6 @@ wimlib_create_new_wim(int ctype, WIMStruct **wim_ret); * * @retval ::WIMLIB_ERR_INVALID_IMAGE * @p image does not exist in the WIM and is not ::WIMLIB_ALL_IMAGES. - * @retval ::WIMLIB_ERR_WIM_IS_READONLY - * The WIM file is considered read-only because of any of the reasons - * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS - * flag. * * This function can additionally return ::WIMLIB_ERR_DECOMPRESSION, * ::WIMLIB_ERR_INVALID_METADATA_RESOURCE, ::WIMLIB_ERR_METADATA_NOT_FOUND, @@ -2728,10 +2721,6 @@ wimlib_delete_path(WIMStruct *wim, int image, * WIM parts were not referenced with wimlib_reference_resources() or * wimlib_reference_resource_files() before the call to * wimlib_export_image(). - * @retval ::WIMLIB_ERR_WIM_IS_READONLY - * @p dest_wim is considered read-only because of any of the reasons - * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS - * flag. * * This function can additionally return ::WIMLIB_ERR_DECOMPRESSION, * ::WIMLIB_ERR_INVALID_METADATA_RESOURCE, ::WIMLIB_ERR_METADATA_NOT_FOUND, @@ -3962,9 +3951,6 @@ wimlib_set_error_file_by_name(const wimlib_tchar *path); * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @p description * string. - * @retval ::WIMLIB_ERR_WIM_IS_READONLY - * @p wim is considered read-only because of any of the reasons mentioned - * in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag. */ extern int wimlib_set_image_descripton(WIMStruct *wim, int image, @@ -4056,12 +4042,6 @@ wimlib_set_output_pack_compression_type(WIMStruct *wim, int ctype); * ::WIMLIB_CHANGE_BOOT_INDEX, and/or ::WIMLIB_CHANGE_RPFIX_FLAG. * * @return 0 on success; nonzero on failure. - * @retval ::WIMLIB_ERR_WIM_IS_READONLY - * The WIM file is considered read-only because of any of the reasons - * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS - * flag. However, as a special case, if you are using - * ::WIMLIB_CHANGE_READONLY_FLAG to unset the readonly flag, then this - * function will not fail due to the readonly flag being previously set. * @retval ::WIMLIB_ERR_IMAGE_COUNT * ::WIMLIB_CHANGE_BOOT_INDEX was specified, but * ::wimlib_wim_info.boot_index did not specify 0 or a valid 1-based image @@ -4090,9 +4070,6 @@ wimlib_set_wim_info(WIMStruct *wim, const struct wimlib_wim_info *info, * @p image does not specify a single existing image in @p wim. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @p flags string. - * @retval ::WIMLIB_ERR_WIM_IS_READONLY - * @p wim is considered read-only because of any of the reasons mentioned - * in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag. */ extern int wimlib_set_image_flags(WIMStruct *wim, int image, const wimlib_tchar *flags); @@ -4118,9 +4095,6 @@ wimlib_set_image_flags(WIMStruct *wim, int image, const wimlib_tchar *flags); * @p image does not specify a single existing image in @p wim. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @p name string. - * @retval ::WIMLIB_ERR_WIM_IS_READONLY - * @p wim is considered read-only because of any of the reasons mentioned - * in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag. */ extern int wimlib_set_image_name(WIMStruct *wim, int image, const wimlib_tchar *name); @@ -4405,10 +4379,6 @@ wimlib_unmount_image_with_progress(const wimlib_tchar *dir, * a supported file type (e.g. a device file). Only if * ::WIMLIB_ADD_FLAG_NO_UNSUPPORTED_EXCLUDE specified in @p the add_flags * for an update command. - * @retval ::WIMLIB_ERR_WIM_IS_READONLY - * The WIM file is considered read-only because of any of the reasons - * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS - * flag. * * This function can additionally return ::WIMLIB_ERR_DECOMPRESSION, * ::WIMLIB_ERR_INVALID_METADATA_RESOURCE, ::WIMLIB_ERR_METADATA_NOT_FOUND, diff --git a/include/wimlib/lookup_table.h b/include/wimlib/lookup_table.h index 8857fd83..bfd219c8 100644 --- a/include/wimlib/lookup_table.h +++ b/include/wimlib/lookup_table.h @@ -134,10 +134,10 @@ struct wim_lookup_table_entry { /* Number of times this lookup table entry is referenced by dentries in * the WIM. When a WIM's lookup table is read, this field is - * initialized from a corresponding entry; while it should be correct, - * in general it may not be. wim_recalculate_refcnts() recalculates the - * reference counts for all streams and is run before doing any - * deletions. */ + * initialized from a corresponding entry. + * + * However, see lte_decrement_refcnt() for information about the + * limitations of this field. */ u32 refcnt; /* When a WIM file is written, this is set to the number of references @@ -228,10 +228,6 @@ struct wim_lookup_table_entry { u32 alloc_stream_owners; }; }; - - /* Actual reference count to this stream (only used while - * verifying an image). */ - u32 real_refcnt; }; /* Temporary list fields. */ @@ -346,9 +342,6 @@ sort_stream_list_by_sequential_order(struct list_head *stream_list, extern int lte_zero_out_refcnt(struct wim_lookup_table_entry *lte, void *ignore); -extern int -lte_zero_real_refcnt(struct wim_lookup_table_entry *lte, void *ignore); - static inline bool lte_is_partial(const struct wim_lookup_table_entry * lte) { diff --git a/include/wimlib/wim.h b/include/wimlib/wim.h index 587e2f69..50db70d7 100644 --- a/include/wimlib/wim.h +++ b/include/wimlib/wim.h @@ -59,13 +59,6 @@ struct WIMStruct { /* Have any images been deleted? */ u8 deletion_occurred : 1; - /* Do we know that all the stream reference counts in the WIM are - * correct? If so, this is set to 1 and deletions are safe; otherwise - * this is set to 0 and deletions are not safe until reference counts - * are recalculated. (This is due to a bug in M$'s software that - * generates WIMs with invalid reference counts.) */ - u8 refcnts_ok : 1; - /* Has the underlying WIM file been locked for appending? */ u8 locked_for_append : 1; @@ -115,9 +108,6 @@ static inline bool wim_has_metadata(const WIMStruct *wim) return (wim->image_metadata != NULL || wim->hdr.image_count == 0); } -extern int -wim_recalculate_refcnts(WIMStruct *wim); - extern int set_wim_hdr_cflags(int ctype, struct wim_header *hdr); @@ -158,7 +148,4 @@ open_wim_as_WIMStruct(const void *wim_filename_or_fd, int open_flags, extern int can_modify_wim(WIMStruct *wim); -extern int -can_delete_from_wim(WIMStruct *wim); - #endif /* _WIMLIB_WIM_H */ diff --git a/programs/imagex.c b/programs/imagex.c index eec90698..f2414af7 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -1713,7 +1713,7 @@ static int imagex_capture_or_append(int argc, tchar **argv, int cmd) { int c; - int open_flags = WIMLIB_OPEN_FLAG_WRITE_ACCESS; + int open_flags = 0; int add_image_flags = WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE | WIMLIB_ADD_IMAGE_FLAG_WINCONFIG | WIMLIB_ADD_IMAGE_FLAG_VERBOSE; @@ -2007,8 +2007,11 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) /* Open the existing WIM, or create a new one. */ if (cmd == CMD_APPEND) { - ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim, - imagex_progress_func, NULL); + ret = wimlib_open_wim_with_progress(wimfile, + open_flags | WIMLIB_OPEN_FLAG_WRITE_ACCESS, + &wim, + imagex_progress_func, + NULL); if (ret) goto out_free_capture_sources; } else { @@ -2090,8 +2093,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) for (size_t i = 0; i < base_wimfiles.num_strings; i++) { ret = wimlib_open_wim_with_progress( - base_wimfiles.strings[i], - open_flags & ~WIMLIB_OPEN_FLAG_WRITE_ACCESS, + base_wimfiles.strings[i], open_flags, &base_wims[i], imagex_progress_func, NULL); if (ret) goto out_free_base_wims; @@ -2127,7 +2129,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) template_wim = wim; } else { ret = wimlib_open_wim_with_progress(template_wimfile, - open_flags & ~WIMLIB_OPEN_FLAG_WRITE_ACCESS, + open_flags, &template_wim, imagex_progress_func, NULL); diff --git a/src/add_image.c b/src/add_image.c index e01f80a8..0aed1deb 100644 --- a/src/add_image.c +++ b/src/add_image.c @@ -88,10 +88,6 @@ wimlib_add_empty_image(WIMStruct *wim, const tchar *name, int *new_idx_ret) { int ret; - ret = can_modify_wim(wim); - if (ret) - return ret; - if (!name) name = T(""); diff --git a/src/delete_image.c b/src/delete_image.c index 131ec8d9..7e33ea3c 100644 --- a/src/delete_image.c +++ b/src/delete_image.c @@ -37,10 +37,6 @@ wimlib_delete_image(WIMStruct *wim, int image) int ret; int first, last; - ret = can_delete_from_wim(wim); - if (ret) - return ret; - if (image == WIMLIB_ALL_IMAGES) { last = wim->hdr.image_count; first = 1; @@ -52,16 +48,16 @@ wimlib_delete_image(WIMStruct *wim, int image) for (image = last; image >= first; image--) { DEBUG("Deleting image %d", 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. */ + /* Even if the dentry tree is not allocated, we must select it + * (and therefore allocate it) so that we can decrement stream + * reference counts. */ 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. */ + /* Unless the image metadata is shared by another WIMStruct, + * free the dentry tree, free the security data, and decrement + * stream reference counts. */ put_image_metadata(wim->image_metadata[image - 1], wim->lookup_table); /* Get rid of the empty slot in the image metadata array. */ diff --git a/src/export_image.c b/src/export_image.c index 77e9e541..54532dd1 100644 --- a/src/export_image.c +++ b/src/export_image.c @@ -131,11 +131,6 @@ wimlib_export_image(WIMStruct *src_wim, if (!wim_has_metadata(dest_wim)) return WIMLIB_ERR_METADATA_NOT_FOUND; - /* Destination WIM must be writable. */ - ret = can_modify_wim(dest_wim); - if (ret) - return ret; - if (src_image == WIMLIB_ALL_IMAGES) { /* Multi-image export. */ if ((!(export_flags & WIMLIB_EXPORT_FLAG_NO_NAMES) && diff --git a/src/lookup_table.c b/src/lookup_table.c index 08612f65..882e7dd7 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -243,20 +243,34 @@ finalize_lte(struct wim_lookup_table_entry *lte) } /* - * Decrements the reference count for the lookup table entry @lte, which must be - * inserted in the stream lookup table @table. + * Decrements the reference count of the single-instance stream @lte, which must + * be inserted in the stream lookup table @table. * - * If the reference count reaches 0, this may cause @lte to be destroyed. - * However, we may retain entries with 0 reference count. This does not affect - * correctness, but it prevents the entries for valid streams in a WIM archive, - * which will continue to be present after appending to the file, from being - * lost merely because we dropped all references to them. + * If the stream's reference count reaches 0, we may unlink it from @table and + * free it. However, we retain streams with 0 reference count that originated + * from WIM files (RESOURCE_IN_WIM). We do this for two reasons: + * + * 1. This prevents information about valid streams in a WIM file --- streams + * which will continue to be present after appending to the WIM file --- from + * being lost merely because we dropped all references to them. + * + * 2. Stream reference counts we read from WIM files can't be trusted. It's + * possible that a WIM has reference counts that are too low; WIMGAPI + * sometimes creates WIMs where this is the case. It's also possible that + * streams have been referenced from an external WIM; those streams can + * potentially have any reference count at all, either lower or higher than + * would be expected for this WIM ("this WIM" meaning the owner of @table) if + * it were a standalone WIM. + * + * So we can't take the reference counts too seriously. But at least, we do + * recalculate by default when writing a new WIM file. */ void lte_decrement_refcnt(struct wim_lookup_table_entry *lte, struct wim_lookup_table *table) { - wimlib_assert(lte->refcnt != 0); + if (unlikely(lte->refcnt == 0)) /* See comment above */ + return; if (--lte->refcnt == 0) { if (lte->unhashed) { @@ -563,7 +577,8 @@ struct wim_lookup_table_entry_disk { /* Which part of the split WIM this stream is in; indexed from 1. */ le16 part_number; - /* Reference count of this stream over all WIM images. */ + /* Reference count of this stream over all WIM images. (But see comment + * above lte_decrement_refcnt().) */ le32 refcnt; /* SHA1 message digest of the uncompressed data of this stream, or @@ -1256,13 +1271,6 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list, return ret; } -int -lte_zero_real_refcnt(struct wim_lookup_table_entry *lte, void *_ignore) -{ - lte->real_refcnt = 0; - return 0; -} - int lte_zero_out_refcnt(struct wim_lookup_table_entry *lte, void *_ignore) { diff --git a/src/mount_image.c b/src/mount_image.c index 1133ad7d..18db8571 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -2100,7 +2100,7 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir, if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) { if (!wim->filename) return WIMLIB_ERR_NO_FILENAME; - ret = can_delete_from_wim(wim); + ret = can_modify_wim(wim); if (ret) return ret; } diff --git a/src/update_image.c b/src/update_image.c index 81c17244..fc149f0a 100644 --- a/src/update_image.c +++ b/src/update_image.c @@ -1433,14 +1433,6 @@ wimlib_update_image(WIMStruct *wim, DEBUG("Updating image %d with %zu commands", image, num_cmds); - if (have_command_type(cmds, num_cmds, WIMLIB_UPDATE_OP_DELETE)) - 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); if (ret) diff --git a/src/verify.c b/src/verify.c index 6ee918f4..c06e7029 100644 --- a/src/verify.c +++ b/src/verify.c @@ -32,71 +32,6 @@ #include "wimlib/progress.h" #include "wimlib/security.h" -static int -lte_fix_refcnt(struct wim_lookup_table_entry *lte, void *ctr) -{ - if (lte->refcnt != lte->real_refcnt) { - lte->refcnt = lte->real_refcnt; - ++*(unsigned long *)ctr; - } - return 0; -} - -static void -tally_inode_refcnts(const struct wim_inode *inode, - const struct wim_lookup_table *lookup_table) -{ - for (unsigned i = 0; i <= inode->i_num_ads; i++) { - struct wim_lookup_table_entry *lte; - lte = inode_stream_lte(inode, i, lookup_table); - if (lte) - lte->real_refcnt += inode->i_nlink; - } -} - - -static int -tally_image_refcnts(WIMStruct *wim) -{ - const struct wim_image_metadata *imd; - const struct wim_inode *inode; - - imd = wim_get_current_image_metadata(wim); - image_for_each_inode(inode, imd) - tally_inode_refcnts(inode, wim->lookup_table); - return 0; -} - - -/* Ideally this would be unnecessary... however, the WIMs for Windows 8 are - * screwed up because some lookup table entries are referenced more times than - * their stated reference counts. So theoretically, if we delete all the - * references to a stream and then remove it, it might still be referenced - * somewhere else, making a file be missing from the WIM... So, work around this - * problem by looking at ALL the images to re-calculate the reference count of - * EVERY lookup table entry. This only absolutely has to be done before an image - * is deleted or before an image is mounted read-write. */ -int -wim_recalculate_refcnts(WIMStruct *wim) -{ - unsigned long num_ltes_with_bogus_refcnt = 0; - int ret; - - for_lookup_table_entry(wim->lookup_table, lte_zero_real_refcnt, NULL); - ret = for_image(wim, WIMLIB_ALL_IMAGES, tally_image_refcnts); - if (ret) - return ret; - num_ltes_with_bogus_refcnt = 0; - for_lookup_table_entry(wim->lookup_table, lte_fix_refcnt, - &num_ltes_with_bogus_refcnt); - if (num_ltes_with_bogus_refcnt != 0) { - WARNING("%lu stream(s) had incorrect reference count.", - num_ltes_with_bogus_refcnt); - } - wim->refcnts_ok = 1; - return 0; -} - static int append_lte_to_list(struct wim_lookup_table_entry *lte, void *_list) { diff --git a/src/wim.c b/src/wim.c index e7025daf..7b1347dd 100644 --- a/src/wim.c +++ b/src/wim.c @@ -203,7 +203,6 @@ wimlib_create_new_wim(int ctype, WIMStruct **wim_ret) goto out_free_wim; } wim->lookup_table = table; - wim->refcnts_ok = 1; wim->compression_type = ctype; wim->out_compression_type = ctype; wim->chunk_size = wim->hdr.chunk_size; @@ -472,14 +471,16 @@ wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info) WIMLIBAPI int wimlib_set_wim_info(WIMStruct *wim, const struct wimlib_wim_info *info, int which) { - int ret; - if (which & ~(WIMLIB_CHANGE_READONLY_FLAG | WIMLIB_CHANGE_GUID | WIMLIB_CHANGE_BOOT_INDEX | WIMLIB_CHANGE_RPFIX_FLAG)) return WIMLIB_ERR_INVALID_PARAM; + if ((which & WIMLIB_CHANGE_BOOT_INDEX) && + info->boot_index > wim->hdr.image_count) + return WIMLIB_ERR_INVALID_IMAGE; + if (which & WIMLIB_CHANGE_READONLY_FLAG) { if (info->is_marked_readonly) wim->hdr.flags |= WIM_HDR_FLAG_READONLY; @@ -487,21 +488,11 @@ wimlib_set_wim_info(WIMStruct *wim, const struct wimlib_wim_info *info, int whic wim->hdr.flags &= ~WIM_HDR_FLAG_READONLY; } - if ((which & ~WIMLIB_CHANGE_READONLY_FLAG) == 0) - return 0; - - ret = can_modify_wim(wim); - if (ret) - return ret; - if (which & WIMLIB_CHANGE_GUID) memcpy(wim->hdr.guid, info->guid, WIM_GUID_LEN); - if (which & WIMLIB_CHANGE_BOOT_INDEX) { - if (info->boot_index > wim->hdr.image_count) - return WIMLIB_ERR_INVALID_IMAGE; + if (which & WIMLIB_CHANGE_BOOT_INDEX) wim->hdr.boot_idx = info->boot_index; - } if (which & WIMLIB_CHANGE_RPFIX_FLAG) { if (info->has_rpfix) @@ -872,33 +863,6 @@ can_modify_wim(WIMStruct *wim) return 0; } -/* - * can_delete_from_wim - Check if files or images can be deleted from a given - * WIM file. - * - * This theoretically should be exactly the same as can_modify_wim(), but - * unfortunately, due to bugs in Microsoft's software that generate incorrect - * reference counts for some WIM resources, we need to run expensive - * verifications to make sure the reference counts are correct on all WIM - * resources. Otherwise we might delete a WIM resource whose reference count - * has fallen to 0, but is actually still referenced somewhere. - */ -int -can_delete_from_wim(WIMStruct *wim) -{ - int ret; - - ret = can_modify_wim(wim); - if (ret) - return ret; - if (!wim->refcnts_ok) { - ret = wim_recalculate_refcnts(wim); - if (ret) - return ret; - } - return 0; -} - /* API function documented in wimlib.h */ WIMLIBAPI void wimlib_free(WIMStruct *wim) diff --git a/src/xml.c b/src/xml.c index 383e2034..ecb73b22 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1667,14 +1667,9 @@ wimlib_set_image_name(WIMStruct *wim, int image, const tchar *name) { tchar *p; int i; - int ret; DEBUG("Setting the name of image %d to %"TS, image, name); - ret = can_modify_wim(wim); - if (ret) - return ret; - if (name == NULL) name = T(""); @@ -1708,11 +1703,6 @@ do_set_image_info_str(WIMStruct *wim, int image, const tchar *tstr, { tchar *tstr_copy; tchar **dest_tstr_p; - int ret; - - ret = can_modify_wim(wim); - if (ret) - return ret; if (image < 1 || image > wim->hdr.image_count) { ERROR("%d is not a valid image", image);