]> wimlib.net Git - wimlib/blob - src/join.c
join.c, write.c: Optimize WIMLIB_ALL_IMAGES writes (and joins)
[wimlib] / src / join.c
1 /*
2  * join.c
3  *
4  * Join split WIMs (sometimes named as .swm files) together into one WIM.
5  */
6
7 /*
8  * Copyright (C) 2012, 2013 Eric Biggers
9  *
10  * This file is part of wimlib, a library for working with WIM files.
11  *
12  * wimlib is free software; you can redistribute it and/or modify it under the
13  * terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 3 of the License, or (at your option)
15  * any later version.
16  *
17  * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
18  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19  * A PARTICULAR PURPOSE. See the GNU General Public License for more
20  * details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with wimlib; if not, see http://www.gnu.org/licenses/.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #  include "config.h"
28 #endif
29
30 #include "wimlib.h"
31 #include "wimlib/types.h"
32 #include "wimlib/swm.h"
33 #include "wimlib/util.h"
34 #include "wimlib/wim.h"
35
36 /* API function documented in wimlib.h  */
37 WIMLIBAPI int
38 wimlib_join(const tchar * const *swm_names,
39             unsigned num_swms,
40             const tchar *output_path,
41             int swm_open_flags,
42             int wim_write_flags,
43             wimlib_progress_func_t progress_func)
44 {
45         int ret;
46         unsigned i;
47         unsigned j;
48         WIMStruct *swm0;
49         WIMStruct **additional_swms;
50         unsigned num_additional_swms;
51
52         swm_open_flags |= WIMLIB_OPEN_FLAG_SPLIT_OK;
53
54         if (num_swms < 1 || num_swms > 0xffff)
55                 return WIMLIB_ERR_INVALID_PARAM;
56         num_additional_swms = num_swms - 1;
57
58         additional_swms = CALLOC(num_additional_swms, sizeof(additional_swms[0]));
59         if (!additional_swms)
60                 return WIMLIB_ERR_NOMEM;
61
62         swm0 = NULL;
63         for (i = 0, j = 0; i < num_swms; i++) {
64                 WIMStruct *swm;
65
66                 ret = wimlib_open_wim(swm_names[i], swm_open_flags, &swm,
67                                       progress_func);
68                 if (ret)
69                         goto out_free_swms;
70                 if (swm->hdr.part_number == 1 && swm0 == NULL)
71                         swm0 = swm;
72                 else
73                         additional_swms[j++] = swm;
74         }
75
76         if (!swm0) {
77                 ret = WIMLIB_ERR_SPLIT_INVALID;
78                 goto out_free_swms;
79         }
80
81         ret = verify_swm_set(swm0, additional_swms, num_additional_swms);
82         if (ret)
83                 goto out_free_swms;
84
85         merge_lookup_tables(swm0, additional_swms, num_additional_swms);
86
87         ret = wimlib_write(swm0, output_path, WIMLIB_ALL_IMAGES,
88                            wim_write_flags, 1, progress_func);
89 out_free_swms:
90         for (i = 0; i < num_additional_swms; i++)
91                 wimlib_free(additional_swms[i]);
92         FREE(additional_swms);
93         wimlib_free(swm0);
94         return ret;
95 }