X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fadd_image.c;h=740f11d6aea27f29738651e1da2e2fb7dadf8c3c;hp=746c06a92dd43ed6d1cf0c427b5e1080988699ec;hb=b41816aff9a66099bd44c93729c89bbd514f9c3f;hpb=61db93f82eca3fe9f7676355c709c58cc425a6ad diff --git a/src/add_image.c b/src/add_image.c index 746c06a9..740f11d6 100644 --- a/src/add_image.c +++ b/src/add_image.c @@ -1,24 +1,22 @@ /* - * add_image.c - Add an image to a WIM file. + * add_image.c - Add an image to a WIMStruct. */ /* - * Copyright (C) 2012, 2013 Eric Biggers + * Copyright (C) 2012-2016 Eric Biggers * - * This file is part of wimlib, a library for working with WIM files. + * This file is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. * - * wimlib is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at your option) - * any later version. - * - * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more + * This file is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * - * You should have received a copy of the GNU General Public License - * along with wimlib; if not, see http://www.gnu.org/licenses/. + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, see http://www.gnu.org/licenses/. */ #ifdef HAVE_CONFIG_H @@ -26,124 +24,75 @@ #endif #include "wimlib.h" -#include "wimlib/capture.h" +#include "wimlib/blob_table.h" #include "wimlib/error.h" -#include "wimlib/lookup_table.h" #include "wimlib/metadata.h" +#include "wimlib/security.h" #include "wimlib/xml.h" -/* - * Adds the dentry tree and security data for a new image to the image metadata - * array of the WIMStruct. - */ -static int -add_new_dentry_tree(WIMStruct *wim, struct wim_dentry *root_dentry, - struct wim_security_data *sd) -{ - struct wim_image_metadata *new_imd; - struct wim_lookup_table_entry *metadata_lte; - int ret; - - metadata_lte = new_lookup_table_entry(); - if (!metadata_lte) - return WIMLIB_ERR_NOMEM; - - metadata_lte->resource_entry.flags = WIM_RESHDR_FLAG_METADATA; - metadata_lte->unhashed = 1; - - new_imd = new_image_metadata(); - if (!new_imd) { - free_lookup_table_entry(metadata_lte); - return WIMLIB_ERR_NOMEM; - } - - new_imd->root_dentry = root_dentry; - new_imd->metadata_lte = metadata_lte; - new_imd->security_data = sd; - new_imd->modified = 1; - - ret = append_image_metadata(wim, new_imd); - if (ret) - put_image_metadata(new_imd, NULL); - return ret; -} - /* API function documented in wimlib.h */ WIMLIBAPI int wimlib_add_empty_image(WIMStruct *wim, const tchar *name, int *new_idx_ret) { + struct wim_image_metadata *imd; int ret; - struct wim_security_data *sd; - - DEBUG("Adding empty image \"%"TS"\"", name); - - if (name == NULL) - name = T(""); - - ret = can_modify_wim(wim); - if (ret) - goto out; if (wimlib_image_name_in_use(wim, name)) { ERROR("There is already an image named \"%"TS"\" in the WIM!", name); - ret = WIMLIB_ERR_IMAGE_NAME_COLLISION; - goto out; + return WIMLIB_ERR_IMAGE_NAME_COLLISION; } - sd = new_wim_security_data(); - if (!sd) { - ret = WIMLIB_ERR_NOMEM; - goto out; - } + imd = new_empty_image_metadata(); + if (!imd) + return WIMLIB_ERR_NOMEM; - ret = add_new_dentry_tree(wim, NULL, sd); + ret = append_image_metadata(wim, imd); if (ret) - goto out_free_security_data; + goto err_put_imd; - ret = xml_add_image(wim, name); + ret = xml_add_image(wim->xml_info, name); if (ret) - goto out_put_image_metadata; + goto err_undo_append; if (new_idx_ret) *new_idx_ret = wim->hdr.image_count; - DEBUG("Successfully added new image (index %d)", - wim->hdr.image_count); - goto out; -out_put_image_metadata: - put_image_metadata(wim->image_metadata[--wim->hdr.image_count], - wim->lookup_table); - goto out; -out_free_security_data: - free_wim_security_data(sd); -out: + return 0; + +err_undo_append: + wim->hdr.image_count--; +err_put_imd: + put_image_metadata(imd); return ret; } +/* Translate the 'struct wimlib_capture_source's passed to + * wimlib_add_image_multisource() into 'struct wimlib_update_command's for + * wimlib_update_image(). */ static struct wimlib_update_command * capture_sources_to_add_cmds(const struct wimlib_capture_source *sources, size_t num_sources, int add_flags, - const struct wimlib_capture_config *config) + const tchar *config_file) { struct wimlib_update_command *add_cmds; - DEBUG("Translating %zu capture sources to `struct wimlib_update_command's", - num_sources); add_cmds = CALLOC(num_sources, sizeof(add_cmds[0])); - if (add_cmds) { - for (size_t i = 0; i < num_sources; i++) { - DEBUG("Source %zu of %zu: fs_source_path=\"%"TS"\", " - "wim_target_path=\"%"TS"\"", - i + 1, num_sources, - sources[i].fs_source_path, - sources[i].wim_target_path); - add_cmds[i].op = WIMLIB_UPDATE_OP_ADD; - add_cmds[i].add.add_flags = add_flags; - add_cmds[i].add.config = (struct wimlib_capture_config*)config; - add_cmds[i].add.fs_source_path = sources[i].fs_source_path; - add_cmds[i].add.wim_target_path = sources[i].wim_target_path; - } + if (!add_cmds) + return NULL; + + /* WIMLIB_ADD_FLAG_BOOT is handled by wimlib_add_image_multisource(), + * not wimlib_update_image(), so mask it out. + * + * However, WIMLIB_ADD_FLAG_WIMBOOT is handled by both. */ + add_flags &= ~WIMLIB_ADD_FLAG_BOOT; + + for (size_t i = 0; i < num_sources; i++) { + add_cmds[i].op = WIMLIB_UPDATE_OP_ADD; + add_cmds[i].add.fs_source_path = sources[i].fs_source_path; + add_cmds[i].add.wim_target_path = sources[i].wim_target_path; + add_cmds[i].add.add_flags = add_flags; + add_cmds[i].add.config_file = (tchar *)config_file; } return add_cmds; } @@ -154,48 +103,52 @@ wimlib_add_image_multisource(WIMStruct *wim, const struct wimlib_capture_source *sources, size_t num_sources, const tchar *name, - const struct wimlib_capture_config *config, - int add_flags, - wimlib_progress_func_t progress_func) + const tchar *config_file, + int add_flags) { int ret; struct wimlib_update_command *add_cmds; - DEBUG("Adding image \"%"TS"\" from %zu sources (add_flags=%#x)", - name, num_sources, add_flags); + /* Make sure no reserved fields are set. */ + for (size_t i = 0; i < num_sources; i++) + if (sources[i].reserved != 0) + return WIMLIB_ERR_INVALID_PARAM; - /* Add the new image (initially empty) */ + /* Add the new image (initially empty). */ ret = wimlib_add_empty_image(wim, name, NULL); if (ret) - goto out; + return ret; - /* Translate the "capture sources" into generic update commands. */ + /* Translate the "capture sources" into generic update commands. */ + ret = WIMLIB_ERR_NOMEM; add_cmds = capture_sources_to_add_cmds(sources, num_sources, - add_flags, config); - if (!add_cmds) { - ret = WIMLIB_ERR_NOMEM; + add_flags, config_file); + if (!add_cmds) goto out_delete_image; - } - /* Delegate the work to wimlib_update_image(). */ + /* Delegate the work to wimlib_update_image(). */ ret = wimlib_update_image(wim, wim->hdr.image_count, add_cmds, - num_sources, 0, progress_func); + num_sources, 0); FREE(add_cmds); if (ret) goto out_delete_image; - /* Success; set boot index if requested. */ + /* If requested, mark the new image as WIMBoot-compatible. */ + if (add_flags & WIMLIB_ADD_FLAG_WIMBOOT) { + ret = xml_set_wimboot(wim->xml_info, wim->hdr.image_count); + if (ret) + goto out_delete_image; + } + + /* If requested, set this image as the WIM's bootable image. */ if (add_flags & WIMLIB_ADD_FLAG_BOOT) wim->hdr.boot_idx = wim->hdr.image_count; - ret = 0; - goto out; + + return 0; + out_delete_image: - /* Roll back the image we added */ - put_image_metadata(wim->image_metadata[wim->hdr.image_count - 1], - wim->lookup_table); - xml_delete_image(&wim->wim_info, wim->hdr.image_count); - wim->hdr.image_count--; -out: + /* Unsuccessful; rollback by removing the new image. */ + delete_wim_image(wim, wim->hdr.image_count); return ret; } @@ -204,18 +157,15 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *wim, const tchar *source, const tchar *name, - const struct wimlib_capture_config *config, - int add_flags, - wimlib_progress_func_t progress_func) + const tchar *config_file, + int add_flags) { - /* Delegate the work to the more general wimlib_add_image_multisource(). - * */ + /* Use the more general wimlib_add_image_multisource(). */ const struct wimlib_capture_source capture_src = { - .fs_source_path = (tchar*)source, - .wim_target_path = T(""), + .fs_source_path = (tchar *)source, + .wim_target_path = WIMLIB_WIM_ROOT_PATH, .reserved = 0, }; return wimlib_add_image_multisource(wim, &capture_src, 1, name, - config, add_flags, - progress_func); + config_file, add_flags); }