X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fdelete_image.c;h=9cbec0a2ef90ba8c6ce288bbdd0b70c085dfd967;hp=2ad5a27a8f0d4e95962968dc90852e6e5631f190;hb=76689b1cac26c545260568997ae7fb949846f302;hpb=61db93f82eca3fe9f7676355c709c58cc425a6ad diff --git a/src/delete_image.c b/src/delete_image.c index 2ad5a27a..9cbec0a2 100644 --- a/src/delete_image.c +++ b/src/delete_image.c @@ -3,35 +3,79 @@ */ /* - * Copyright (C) 2012, 2013 Eric Biggers + * Copyright (C) 2012-2016 Eric Biggers * - * This file is part of wimlib, a library for working with WIM files. + * This file is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. * - * wimlib is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at your option) - * any later version. - * - * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more + * This file is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * - * You should have received a copy of the GNU General Public License - * along with wimlib; if not, see http://www.gnu.org/licenses/. + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, see http://www.gnu.org/licenses/. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif +#include + #include "wimlib.h" -#include "wimlib/error.h" +#include "wimlib/dentry.h" #include "wimlib/metadata.h" -#include "wimlib/util.h" #include "wimlib/wim.h" #include "wimlib/xml.h" +/* Internal method for single-image deletion. This doesn't set the + * image_deletion_occurred' flag on the WIMStruct. */ +int +delete_wim_image(WIMStruct *wim, int image) +{ + int ret; + struct wim_image_metadata *imd; + + /* Load the metadata for the image to be deleted. This is necessary + * because blobs referenced by files in the image need to have their + * reference counts decremented. */ + ret = select_wim_image(wim, image); + if (ret) + return ret; + + /* Release the files and decrement the reference counts of the blobs + * they reference. */ + imd = wim->image_metadata[image - 1]; + free_dentry_tree(imd->root_dentry, wim->blob_table); + imd->root_dentry = NULL; + + /* Deselect the image and release its metadata. */ + deselect_current_wim_image(wim); + put_image_metadata(imd); + + /* Remove the empty slot from the image metadata array. */ + memmove(&wim->image_metadata[image - 1], &wim->image_metadata[image], + (wim->hdr.image_count - image) * + sizeof(wim->image_metadata[0])); + + /* Decrement the image count. */ + wim->hdr.image_count--; + + /* Remove the image from the XML information. */ + xml_delete_image(wim->xml_info, image); + + /* Fix the boot index. */ + if (wim->hdr.boot_idx == image) + wim->hdr.boot_idx = 0; + else if (wim->hdr.boot_idx > image) + wim->hdr.boot_idx--; + + return 0; +} + /* API function documented in wimlib.h */ WIMLIBAPI int wimlib_delete_image(WIMStruct *wim, int image) @@ -39,52 +83,21 @@ 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) { + /* Deleting all images */ last = wim->hdr.image_count; first = 1; } else { + /* Deleting one image */ last = image; first = 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. */ - ret = select_wim_image(wim, image); + ret = delete_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(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 < wim->hdr.image_count - 1; i++) - wim->image_metadata[i] = wim->image_metadata[i + 1]; - - /* Decrement the image count. */ - --wim->hdr.image_count; - - /* Fix the boot index. */ - if (wim->hdr.boot_idx == image) - wim->hdr.boot_idx = 0; - else if (wim->hdr.boot_idx > image) - wim->hdr.boot_idx--; - - wim->current_image = WIMLIB_NO_IMAGE; - - /* Remove the image from the XML information. */ - xml_delete_image(&wim->wim_info, image); - - wim->deletion_occurred = 1; + wim->image_deletion_occurred = 1; } return 0; }