*/
/*
- * Copyright (C) 2012, 2013, 2014 Eric Biggers
+ * Copyright (C) 2012, 2013, 2014, 2015 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
const u8 *hash;
struct blob_descriptor *src_blob, *dest_blob;
- inode_unresolve_streams(inode);
-
for (i = 0; i < inode->i_num_streams; i++) {
/* Retrieve SHA-1 message digest of blob to export. */
hash = stream_hash(&inode->i_streams[i]);
- if (is_zero_hash(hash)) /* Empty blob? */
+ if (is_zero_hash(hash)) /* Empty stream? */
continue;
/* Search for the blob (via SHA-1 message digest) in the
/* Blob not yet present in destination WIM. Search for
* it in the source WIM, then export it into the
* destination WIM. */
- src_blob = lookup_blob(src_blob_table, hash);
+ src_blob = stream_blob(&inode->i_streams[i],
+ src_blob_table);
if (!src_blob)
return blob_not_found_error(inode, hash);
WIMLIB_EXPORT_FLAG_WIMBOOT))
return WIMLIB_ERR_INVALID_PARAM;
- if (src_wim == NULL || dest_wim == NULL)
+ if (!src_wim || !dest_wim)
return WIMLIB_ERR_INVALID_PARAM;
if (!wim_has_metadata(src_wim) || !wim_has_metadata(dest_wim))
}
orig_dest_image_count = dest_wim->hdr.image_count;
+ /* We don't yet support having a single WIMStruct contain duplicate
+ * 'image_metadata' structures, so we must forbid this from happening.
+ * A duplication is possible if 'src_wim == dest_wim', if the same image
+ * is exported to the same destination WIMStruct multiple times, or if
+ * an image is exported in an A => B => A manner. */
+ for (src_image = start_src_image;
+ src_image <= end_src_image; src_image++)
+ {
+ const struct wim_image_metadata *src_imd =
+ src_wim->image_metadata[src_image - 1];
+ for (int i = 0; i < dest_wim->hdr.image_count; i++)
+ if (dest_wim->image_metadata[i] == src_imd)
+ return WIMLIB_ERR_DUPLICATE_EXPORTED_IMAGE;
+ }
+
/* Blob checksums must be known before proceeding. */
ret = wim_checksum_unhashed_blobs(src_wim);
if (ret)
/* Determine destination image name and description. */
if (export_flags & WIMLIB_EXPORT_FLAG_NO_NAMES)
- next_dest_name = T("");
+ next_dest_name = NULL;
else if (dest_name)
next_dest_name = dest_name;
else
next_dest_name = wimlib_get_image_name(src_wim, src_image);
if (export_flags & WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS)
- next_dest_description = T("");
+ next_dest_description = NULL;
else if (dest_description)
next_dest_description = dest_description;
else
}
/* Export XML information into the destination WIM. */
- ret = xml_export_image(src_wim->wim_info, src_image,
- &dest_wim->wim_info, next_dest_name,
- next_dest_description);
+ ret = xml_export_image(src_wim->xml_info, src_image,
+ dest_wim->xml_info, next_dest_name,
+ next_dest_description,
+ export_flags & WIMLIB_EXPORT_FLAG_WIMBOOT);
if (ret)
goto out_rollback;
if (ret)
goto out_rollback;
src_imd->refcnt++;
-
- /* Lock the metadata into memory. XXX: need better solution for
- * this. */
- src_imd->modified = 1;
-
}
/* Image export complete. Finish by setting any needed special metadata
int dst_image = orig_dest_image_count + 1 +
(src_image - start_src_image);
- if (export_flags & WIMLIB_EXPORT_FLAG_WIMBOOT)
- wim_info_set_wimboot(dest_wim->wim_info, dst_image, true);
-
if ((export_flags & WIMLIB_EXPORT_FLAG_BOOT) &&
(!all_images || src_image == src_wim->hdr.boot_idx))
dest_wim->hdr.boot_idx = dst_image;
}
- if (export_flags & WIMLIB_EXPORT_FLAG_GIFT) {
- free_blob_table(src_wim->blob_table);
- src_wim->blob_table = NULL;
- }
return 0;
out_rollback:
- while ((image = wim_info_get_num_images(dest_wim->wim_info))
+ while ((image = xml_get_image_count(dest_wim->xml_info))
> orig_dest_image_count)
{
- xml_delete_image(&dest_wim->wim_info, image);
+ xml_delete_image(dest_wim->xml_info, image);
}
while (dest_wim->hdr.image_count > orig_dest_image_count)
{