]> wimlib.net Git - wimlib/blobdiff - src/export_image.c
wimlib_export_image(): improve duplicate image detection
[wimlib] / src / export_image.c
index e88107a96030f6cae0aa646d48bc5dc673361f99..da638322ee06c32d19217986653be498eea4e63d 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
- * 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
@@ -128,7 +128,7 @@ wimlib_export_image(WIMStruct *src_wim,
                             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))
@@ -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)
@@ -176,14 +191,14 @@ wimlib_export_image(WIMStruct *src_wim,
                /* 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
@@ -216,9 +231,10 @@ wimlib_export_image(WIMStruct *src_wim,
                }
 
                /* 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;
 
@@ -228,11 +244,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
@@ -248,25 +259,18 @@ wimlib_export_image(WIMStruct *src_wim,
                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)
        {