wimlib_export_image(): improve duplicate image detection
authorEric Biggers <ebiggers3@gmail.com>
Mon, 19 Oct 2015 00:39:35 +0000 (19:39 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 19 Oct 2015 02:01:13 +0000 (21:01 -0500)
include/wimlib.h
src/error.c
src/export_image.c

index cdc2988..6842e35 100644 (file)
@@ -2493,11 +2493,12 @@ enum wimlib_error_code {
        WIMLIB_ERR_MOUNTED_IMAGE_IS_BUSY              = 79,
        WIMLIB_ERR_NOT_A_MOUNTPOINT                   = 80,
        WIMLIB_ERR_NOT_PERMITTED_TO_UNMOUNT           = 81,
        WIMLIB_ERR_MOUNTED_IMAGE_IS_BUSY              = 79,
        WIMLIB_ERR_NOT_A_MOUNTPOINT                   = 80,
        WIMLIB_ERR_NOT_PERMITTED_TO_UNMOUNT           = 81,
-       WIMLIB_ERR_FVE_LOCKED_VOLUME                  = 82,
+       WIMLIB_ERR_FVE_LOCKED_VOLUME                  = 82,
        WIMLIB_ERR_UNABLE_TO_READ_CAPTURE_CONFIG      = 83,
        WIMLIB_ERR_UNABLE_TO_READ_CAPTURE_CONFIG      = 83,
-       WIMLIB_ERR_WIM_IS_INCOMPLETE                  = 84,
+       WIMLIB_ERR_WIM_IS_INCOMPLETE                  = 84,
        WIMLIB_ERR_COMPACTION_NOT_POSSIBLE            = 85,
        WIMLIB_ERR_IMAGE_HAS_MULTIPLE_REFERENCES      = 86,
        WIMLIB_ERR_COMPACTION_NOT_POSSIBLE            = 85,
        WIMLIB_ERR_IMAGE_HAS_MULTIPLE_REFERENCES      = 86,
+       WIMLIB_ERR_DUPLICATE_EXPORTED_IMAGE           = 87,
 };
 
 
 };
 
 
@@ -2757,6 +2758,9 @@ wimlib_delete_path(WIMStruct *wim, int image,
  *
  * @return 0 on success; a ::wimlib_error_code value on failure.
  *
  *
  * @return 0 on success; a ::wimlib_error_code value on failure.
  *
+ * @retval ::WIMLIB_ERR_DUPLICATE_EXPORTED_IMAGE
+ *     One or more of the source images had already been exported into the
+ *     destination WIM.
  * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION
  *     One or more of the names being given to an exported image was already in
  *     use in the destination WIM.
  * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION
  *     One or more of the names being given to an exported image was already in
  *     use in the destination WIM.
index af212db..ea43491 100644 (file)
@@ -340,6 +340,8 @@ static const tchar * const error_strings[] = {
        [WIMLIB_ERR_IMAGE_HAS_MULTIPLE_REFERENCES]
                = T("The WIM image cannot be modified because it is currently "
                    "referenced from multiple places"),
        [WIMLIB_ERR_IMAGE_HAS_MULTIPLE_REFERENCES]
                = T("The WIM image cannot be modified because it is currently "
                    "referenced from multiple places"),
+       [WIMLIB_ERR_DUPLICATE_EXPORTED_IMAGE]
+               = T("The destination WIM already contains one of the source images"),
 };
 
 WIMLIBAPI const tchar *
 };
 
 WIMLIBAPI const tchar *
index ff20a73..da63832 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
  *
  * 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;
 
                             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))
                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;
 
        }
        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)
        /* Blob checksums must be known before proceeding.  */
        ret = wim_checksum_unhashed_blobs(src_wim);
        if (ret)
@@ -249,10 +264,6 @@ wimlib_export_image(WIMStruct *src_wim,
                        dest_wim->hdr.boot_idx = dst_image;
        }
 
                        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:
        return 0;
 
 out_rollback: