new internal image deletion helper
[wimlib] / src / delete_image.c
1 /*
2  * delete_image.c
3  */
4
5 /*
6  * Copyright (C) 2012, 2013, 2014 Eric Biggers
7  *
8  * This file is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU Lesser General Public License as published by the Free
10  * Software Foundation; either version 3 of the License, or (at your option) any
11  * later version.
12  *
13  * This file is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this file; if not, see http://www.gnu.org/licenses/.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include "wimlib.h"
29 #include "wimlib/metadata.h"
30 #include "wimlib/wim.h"
31 #include "wimlib/xml.h"
32
33 /* Internal method for single-image deletion.  This doesn't set the
34  * image_deletion_occurred' flag on the WIMStruct.  */
35 int
36 delete_wim_image(WIMStruct *wim, int image)
37 {
38         int ret;
39
40         /* Load the metadata for the image to be deleted.  This is necessary
41          * because streams referenced by files in the image need to have their
42          * reference counts decremented.  */
43         ret = select_wim_image(wim, image);
44         if (ret)
45                 return ret;
46
47         /* Release the reference to the image metadata and decrement reference
48          * counts on the streams referenced by files in the image.  */
49         put_image_metadata(wim->image_metadata[image - 1], wim->lookup_table);
50
51         /* Remove the empty slot from the image metadata array.  */
52         memmove(&wim->image_metadata[image - 1], &wim->image_metadata[image],
53                 (wim->hdr.image_count - image) *
54                         sizeof(wim->image_metadata[0]));
55
56         /* Decrement the image count. */
57         --wim->hdr.image_count;
58
59         /* Remove the image from the XML information. */
60         xml_delete_image(&wim->wim_info, image);
61
62         /* Fix the boot index. */
63         if (wim->hdr.boot_idx == image)
64                 wim->hdr.boot_idx = 0;
65         else if (wim->hdr.boot_idx > image)
66                 wim->hdr.boot_idx--;
67
68         /* The image is no longer valid.  */
69         wim->current_image = WIMLIB_NO_IMAGE;
70         return 0;
71 }
72
73 /* API function documented in wimlib.h  */
74 WIMLIBAPI int
75 wimlib_delete_image(WIMStruct *wim, int image)
76 {
77         int ret;
78         int first, last;
79
80         if (image == WIMLIB_ALL_IMAGES) {
81                 /* Deleting all images  */
82                 last = wim->hdr.image_count;
83                 first = 1;
84         } else {
85                 /* Deleting one image  */
86                 last = image;
87                 first = image;
88         }
89
90         for (image = last; image >= first; image--) {
91                 ret = delete_wim_image(wim, image);
92                 if (ret)
93                         return ret;
94                 wim->image_deletion_occurred = 1;
95         }
96         return 0;
97 }