]> wimlib.net Git - wimlib/blob - src/delete_image.c
win32_common.c: add extra error messages if pread() or pwrite() fails
[wimlib] / src / delete_image.c
1 /*
2  * delete_image.c
3  */
4
5 /*
6  * Copyright (C) 2012-2016 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/dentry.h"
30 #include "wimlib/metadata.h"
31 #include "wimlib/wim.h"
32 #include "wimlib/xml.h"
33
34 /* Internal method for single-image deletion.  This doesn't set the
35  * image_deletion_occurred' flag on the WIMStruct.  */
36 int
37 delete_wim_image(WIMStruct *wim, int image)
38 {
39         int ret;
40         struct wim_image_metadata *imd;
41
42         /* Load the metadata for the image to be deleted.  This is necessary
43          * because blobs referenced by files in the image need to have their
44          * reference counts decremented.  */
45         ret = select_wim_image(wim, image);
46         if (ret)
47                 return ret;
48
49         /* Release the files and decrement the reference counts of the blobs
50          * they reference.  */
51         imd = wim->image_metadata[image - 1];
52         free_dentry_tree(imd->root_dentry, wim->blob_table);
53         imd->root_dentry = NULL;
54
55         /* Deselect the image and release its metadata.  */
56         deselect_current_wim_image(wim);
57         put_image_metadata(imd);
58
59         /* Remove the empty slot from the image metadata array.  */
60         memmove(&wim->image_metadata[image - 1], &wim->image_metadata[image],
61                 (wim->hdr.image_count - image) *
62                         sizeof(wim->image_metadata[0]));
63
64         /* Decrement the image count. */
65         wim->hdr.image_count--;
66
67         /* Remove the image from the XML information. */
68         xml_delete_image(wim->xml_info, image);
69
70         /* Fix the boot index. */
71         if (wim->hdr.boot_idx == image)
72                 wim->hdr.boot_idx = 0;
73         else if (wim->hdr.boot_idx > image)
74                 wim->hdr.boot_idx--;
75
76         return 0;
77 }
78
79 /* API function documented in wimlib.h  */
80 WIMLIBAPI int
81 wimlib_delete_image(WIMStruct *wim, int image)
82 {
83         int ret;
84         int first, last;
85
86         if (image == WIMLIB_ALL_IMAGES) {
87                 /* Deleting all images  */
88                 last = wim->hdr.image_count;
89                 first = 1;
90         } else {
91                 /* Deleting one image  */
92                 last = image;
93                 first = image;
94         }
95
96         for (image = last; image >= first; image--) {
97                 ret = delete_wim_image(wim, image);
98                 if (ret)
99                         return ret;
100                 wim->image_deletion_occurred = 1;
101         }
102         return 0;
103 }