]> wimlib.net Git - wimlib/blobdiff - src/export_image.c
mount_image.c: add fallback definitions of RENAME_* constants
[wimlib] / src / export_image.c
index b7f4511e879d1303f64b4cab39ba6b97ea2480c6..1dff266d4228df6107803203f6664cdcb86fe01e 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
- * 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
@@ -16,7 +16,7 @@
  * details.
  *
  * 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/.
+ * along with this file; if not, see https://www.gnu.org/licenses/.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -128,7 +128,7 @@ wimlib_export_image(WIMStruct *src_wim,
                             WIMLIB_EXPORT_FLAG_WIMBOOT))
                return WIMLIB_ERR_INVALID_PARAM;
 
-       if (!src_wim || !dest_wim || src_wim == dest_wim)
+       if (!src_wim || !dest_wim)
                return WIMLIB_ERR_INVALID_PARAM;
 
        if (!wim_has_metadata(src_wim) || !wim_has_metadata(dest_wim))
@@ -153,6 +153,21 @@ wimlib_export_image(WIMStruct *src_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)
@@ -164,6 +179,26 @@ wimlib_export_image(WIMStruct *src_wim,
        /* Enable rollbacks  */
        for_blob_in_table(dest_wim->blob_table, blob_set_not_exported, NULL);
 
+       /* Forbid exports where the destination WIM already contains image(s)
+        * with the requested name(s).  However, allow multi-image exports where
+        * there is a duplication among the source names only.  */
+       if (!(export_flags & WIMLIB_EXPORT_FLAG_NO_NAMES)) {
+               for (src_image = start_src_image;
+                    src_image <= end_src_image;
+                    src_image++)
+               {
+                       const tchar *name = dest_name ? dest_name :
+                               wimlib_get_image_name(src_wim, src_image);
+
+                       if (wimlib_image_name_in_use(dest_wim, name)) {
+                               ERROR("There is already an image named \"%"TS"\" "
+                                     "in the destination WIM", name);
+                               ret = WIMLIB_ERR_IMAGE_NAME_COLLISION;
+                               goto out_rollback;
+                       }
+               }
+       }
+
        /* Export each requested image.  */
        for (src_image = start_src_image;
             src_image <= end_src_image;
@@ -189,14 +224,6 @@ wimlib_export_image(WIMStruct *src_wim,
                else
                        next_dest_description = wimlib_get_image_description(src_wim, src_image);
 
-               /* Check for name conflict.  */
-               if (wimlib_image_name_in_use(dest_wim, next_dest_name)) {
-                       ERROR("There is already an image named \"%"TS"\" "
-                             "in the destination WIM", next_dest_name);
-                       ret = WIMLIB_ERR_IMAGE_NAME_COLLISION;
-                       goto out_rollback;
-               }
-
                /* Load metadata for source image into memory.  */
                ret = select_wim_image(src_wim, src_image);
                if (ret)
@@ -229,11 +256,6 @@ wimlib_export_image(WIMStruct *src_wim,
                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
@@ -254,10 +276,6 @@ wimlib_export_image(WIMStruct *src_wim,
                        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:
@@ -269,7 +287,7 @@ out_rollback:
        while (dest_wim->hdr.image_count > orig_dest_image_count)
        {
                put_image_metadata(dest_wim->image_metadata[
-                                       --dest_wim->hdr.image_count], NULL);
+                                       --dest_wim->hdr.image_count]);
        }
        for_blob_in_table(dest_wim->blob_table, blob_rollback_export,
                          dest_wim->blob_table);