]> wimlib.net Git - wimlib/blob - src/join.c
Improve write streams performance and handling of 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/util.h"
33 #include "wimlib/wim.h"
34
35 /* API function documented in wimlib.h  */
36 WIMLIBAPI int
37 wimlib_join(const tchar * const *swm_names,
38             unsigned num_swms,
39             const tchar *output_path,
40             int swm_open_flags,
41             int wim_write_flags,
42             wimlib_progress_func_t progress_func)
43 {
44         int ret;
45         unsigned i;
46         unsigned j;
47         WIMStruct *swm0;
48         WIMStruct **swms;
49         unsigned num_additional_swms;
50         WIMStruct *wim;
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         swms = CALLOC(num_additional_swms, sizeof(swms[0]));
59         if (!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                         swms[j++] = swm;
74         }
75
76         if (!swm0) {
77                 ret = WIMLIB_ERR_SPLIT_INVALID;
78                 goto out_free_swms;
79         }
80
81         ret = wimlib_create_new_wim(swm0->compression_type, &wim);
82         if (ret)
83                 goto out_free_swms;
84
85         ret = wimlib_export_image(swm0, WIMLIB_ALL_IMAGES, wim, NULL, NULL, 0,
86                                   swms, num_additional_swms, progress_func);
87         if (ret)
88                 goto out_free_wim;
89
90         wim->hdr.flags |= swm0->hdr.flags & (WIM_HDR_FLAG_RP_FIX |
91                                              WIM_HDR_FLAG_READONLY);
92         if (!(wim_write_flags & (WIMLIB_WRITE_FLAG_CHECK_INTEGRITY |
93                                  WIMLIB_WRITE_FLAG_NO_CHECK_INTEGRITY)))
94         {
95                 if (wim_has_integrity_table(swm0))
96                         wim_write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY;
97         }
98         if (!(wim_write_flags & (WIMLIB_WRITE_FLAG_PIPABLE |
99                                  WIMLIB_WRITE_FLAG_NOT_PIPABLE)))
100         {
101                 if (wim_is_pipable(swm0))
102                         wim_write_flags |= WIMLIB_WRITE_FLAG_PIPABLE;
103         }
104
105
106         ret = wimlib_write(wim, output_path, WIMLIB_ALL_IMAGES,
107                            wim_write_flags, 1, progress_func);
108 out_free_wim:
109         wimlib_free(wim);
110 out_free_swms:
111         for (i = 0; i < num_additional_swms; i++)
112                 wimlib_free(swms[i]);
113         FREE(swms);
114         wimlib_free(swm0);
115         return ret;
116 }