/*
- * add_image.c - Add an image to a WIM file.
+ * add_image.c - Add an image to a WIMStruct.
*/
/*
- * Copyright (C) 2012, 2013, 2014 Eric Biggers
+ * Copyright (C) 2012-2016 Eric Biggers
*
* 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
#endif
#include "wimlib.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"
-/* Creates and appends a 'struct wim_image_metadata' for an empty image.
- *
- * The resulting image will be the last in the WIM, so its index will be
- * the new value of wim->hdr.image_count. */
-static int
-add_empty_image_metadata(WIMStruct *wim)
-{
- int ret;
- struct wim_lookup_table_entry *metadata_lte;
- struct wim_security_data *sd;
- struct wim_image_metadata *imd;
-
- /* Create lookup table entry for this metadata resource (for now really
- * just a dummy entry). */
- ret = WIMLIB_ERR_NOMEM;
- metadata_lte = new_lookup_table_entry();
- if (!metadata_lte)
- goto out;
-
- metadata_lte->flags = WIM_RESHDR_FLAG_METADATA;
- metadata_lte->unhashed = 1;
-
- /* Create empty security data (no security descriptors). */
- sd = new_wim_security_data();
- if (!sd)
- goto out_free_metadata_lte;
-
- imd = new_image_metadata();
- if (!imd)
- goto out_free_security_data;
-
- /* A NULL root_dentry indicates a completely empty image, without even a
- * root directory. */
- imd->root_dentry = NULL;
- imd->metadata_lte = metadata_lte;
- imd->security_data = sd;
- imd->modified = 1;
-
- /* Append as next image index. */
- ret = append_image_metadata(wim, imd);
- if (ret)
- put_image_metadata(imd, NULL);
- goto out;
-
-out_free_security_data:
- free_wim_security_data(sd);
-out_free_metadata_lte:
- free_lookup_table_entry(metadata_lte);
-out:
- 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;
- if (!name)
- name = T("");
-
if (wimlib_image_name_in_use(wim, name)) {
ERROR("There is already an image named \"%"TS"\" in the WIM!",
name);
return WIMLIB_ERR_IMAGE_NAME_COLLISION;
}
- ret = add_empty_image_metadata(wim);
+ imd = new_empty_image_metadata();
+ if (!imd)
+ return WIMLIB_ERR_NOMEM;
+
+ ret = append_image_metadata(wim, imd);
if (ret)
- return ret;
+ goto err_put_imd;
- ret = xml_add_image(wim, name);
- if (ret) {
- put_image_metadata(wim->image_metadata[--wim->hdr.image_count],
- NULL);
- return ret;
- }
+ ret = xml_add_image(wim->xml_info, name);
+ if (ret)
+ goto err_undo_append;
if (new_idx_ret)
*new_idx_ret = wim->hdr.image_count;
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
if (ret)
goto out_delete_image;
+ /* 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;
- /* If requested, mark new image as WIMBoot-compatible. */
- if (add_flags & WIMLIB_ADD_FLAG_WIMBOOT)
- wim_info_set_wimboot(wim->wim_info, wim->hdr.image_count, true);
-
return 0;
out_delete_image:
- /* Unsuccessful; rollback the WIM to its original state. */
-
- /* wimlib_update_image() is now all-or-nothing, so no dentries remain
- * and there's no need to pass the lookup table here. */
- put_image_metadata(wim->image_metadata[wim->hdr.image_count - 1], NULL);
-
- xml_delete_image(&wim->wim_info, wim->hdr.image_count);
- wim->hdr.image_count--;
+ /* Unsuccessful; rollback by removing the new image. */
+ delete_wim_image(wim, wim->hdr.image_count);
return ret;
}