4 * Reference resources from external WIM file(s).
8 * Copyright (C) 2013 Eric Biggers
10 * This file is part of wimlib, a library for working with WIM files.
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)
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
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/.
31 #include "wimlib/error.h"
32 #include "wimlib/glob.h"
33 #include "wimlib/lookup_table.h"
34 #include "wimlib/wim.h"
37 lte_clone_if_new(struct wim_lookup_table_entry *lte, void *_lookup_table)
39 struct wim_lookup_table *lookup_table = _lookup_table;
41 if (lookup_stream(lookup_table, lte->hash))
42 return 0; /* Resource already present. */
44 lte = clone_lookup_table_entry(lte);
46 return WIMLIB_ERR_NOMEM;
48 lookup_table_insert(lookup_table, lte);
53 lte_delete_if_new(struct wim_lookup_table_entry *lte, void *_lookup_table)
55 struct wim_lookup_table *lookup_table = _lookup_table;
57 if (lte->out_refcnt) {
58 lookup_table_unlink(lookup_table, lte);
59 free_lookup_table_entry(lte);
64 /* API function documented in wimlib.h */
66 wimlib_reference_resources(WIMStruct *wim,
67 WIMStruct **resource_wims, unsigned num_resource_wims,
74 return WIMLIB_ERR_INVALID_PARAM;
76 if (num_resource_wims != 0 && resource_wims == NULL)
77 return WIMLIB_ERR_INVALID_PARAM;
79 for (i = 0; i < num_resource_wims; i++)
80 if (resource_wims[i] == NULL)
81 return WIMLIB_ERR_INVALID_PARAM;
83 for_lookup_table_entry(wim->lookup_table, lte_zero_out_refcnt, NULL);
85 for (i = 0; i < num_resource_wims; i++) {
86 ret = for_lookup_table_entry(resource_wims[i]->lookup_table,
95 for_lookup_table_entry(wim->lookup_table, lte_delete_if_new,
101 reference_resource_paths(WIMStruct *wim,
102 const tchar * const *resource_wimfiles,
103 unsigned num_resource_wimfiles,
106 wimlib_progress_func_t progress_func)
108 WIMStruct **resource_wims;
112 resource_wims = CALLOC(num_resource_wimfiles, sizeof(resource_wims[0]));
114 return WIMLIB_ERR_NOMEM;
116 for (i = 0; i < num_resource_wimfiles; i++) {
117 DEBUG("Referencing resources from path \"%"TS"\"",
118 resource_wimfiles[i]);
119 ret = wimlib_open_wim(resource_wimfiles[i], open_flags,
120 &resource_wims[i], progress_func);
122 goto out_free_resource_wims;
125 ret = wimlib_reference_resources(wim, resource_wims,
126 num_resource_wimfiles, ref_flags);
128 goto out_free_resource_wims;
130 for (i = 0; i < num_resource_wimfiles; i++)
131 list_add_tail(&resource_wims[i]->subwim_node, &wim->subwims);
136 out_free_resource_wims:
137 for (i = 0; i < num_resource_wimfiles; i++)
138 wimlib_free(resource_wims[i]);
145 reference_resource_glob(WIMStruct *wim, const tchar *refglob,
146 int ref_flags, int open_flags,
147 wimlib_progress_func_t progress_func)
152 /* Note: glob() is replaced in Windows native builds. */
153 ret = tglob(refglob, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf);
155 if (ret == GLOB_NOMATCH) {
156 if (ref_flags & WIMLIB_REF_FLAG_GLOB_ERR_ON_NOMATCH) {
157 ERROR("Found no files for glob \"%"TS"\"", refglob);
158 return WIMLIB_ERR_GLOB_HAD_NO_MATCHES;
160 return reference_resource_paths(wim,
168 ERROR_WITH_ERRNO("Failed to process glob \"%"TS"\"", refglob);
169 if (ret == GLOB_NOSPACE)
170 return WIMLIB_ERR_NOMEM;
172 return WIMLIB_ERR_READ;
176 ret = reference_resource_paths(wim,
177 (const tchar * const *)globbuf.gl_pathv,
186 /* API function documented in wimlib.h */
188 wimlib_reference_resource_files(WIMStruct *wim,
189 const tchar * const * resource_wimfiles_or_globs,
193 wimlib_progress_func_t progress_func)
198 if (ref_flags & WIMLIB_REF_FLAG_GLOB_ENABLE) {
199 for (i = 0; i < count; i++) {
200 ret = reference_resource_glob(wim,
201 resource_wimfiles_or_globs[i],
210 return reference_resource_paths(wim, resource_wimfiles_or_globs,
212 open_flags, progress_func);