]> wimlib.net Git - wimlib/blobdiff - programs/imagex.c
wimappend: fix setting of chunk size when using --wimboot flag
[wimlib] / programs / imagex.c
index 3c25d1e1c79dbb443941c9ef5b590b45291dacd8..b7ff47ef14aa829eb2a75190e13d99c60c0dfa3f 100644 (file)
@@ -194,6 +194,7 @@ enum {
        IMAGEX_THREADS_OPTION,
        IMAGEX_TO_STDOUT_OPTION,
        IMAGEX_UNIX_DATA_OPTION,
+       IMAGEX_UNSAFE_COMPACT_OPTION,
        IMAGEX_UPDATE_OF_OPTION,
        IMAGEX_VERBOSE_OPTION,
        IMAGEX_WIMBOOT_CONFIG_OPTION,
@@ -254,12 +255,14 @@ static const struct option capture_or_append_options[] = {
        {T("update-of"),   required_argument, NULL, IMAGEX_UPDATE_OF_OPTION},
        {T("delta-from"),  required_argument, NULL, IMAGEX_DELTA_FROM_OPTION},
        {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
+       {T("unsafe-compact"), no_argument,    NULL, IMAGEX_UNSAFE_COMPACT_OPTION},
        {NULL, 0, NULL, 0},
 };
 
 static const struct option delete_options[] = {
        {T("check"), no_argument, NULL, IMAGEX_CHECK_OPTION},
        {T("soft"),  no_argument, NULL, IMAGEX_SOFT_OPTION},
+       {T("unsafe-compact"), no_argument, NULL, IMAGEX_UNSAFE_COMPACT_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -293,6 +296,7 @@ static const struct option export_options[] = {
        {T("pipable"),     no_argument,       NULL, IMAGEX_PIPABLE_OPTION},
        {T("not-pipable"), no_argument,       NULL, IMAGEX_NOT_PIPABLE_OPTION},
        {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
+       {T("unsafe-compact"), no_argument,    NULL, IMAGEX_UNSAFE_COMPACT_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -366,6 +370,7 @@ static const struct option optimize_options[] = {
        {T("threads"),     required_argument, NULL, IMAGEX_THREADS_OPTION},
        {T("pipable"),     no_argument,       NULL, IMAGEX_PIPABLE_OPTION},
        {T("not-pipable"), no_argument,       NULL, IMAGEX_NOT_PIPABLE_OPTION},
+       {T("unsafe-compact"), no_argument,    NULL, IMAGEX_UNSAFE_COMPACT_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -410,6 +415,7 @@ static const struct option update_options[] = {
        {T("no-acls"),     no_argument,       NULL, IMAGEX_NO_ACLS_OPTION},
        {T("strict-acls"), no_argument,       NULL, IMAGEX_STRICT_ACLS_OPTION},
        {T("no-replace"),  no_argument,       NULL, IMAGEX_NO_REPLACE_OPTION},
+       {T("unsafe-compact"), no_argument,    NULL, IMAGEX_UNSAFE_COMPACT_OPTION},
 
        {NULL, 0, NULL, 0},
 };
@@ -662,6 +668,17 @@ do_resource_not_found_warning(const tchar *wimfile,
        }
 }
 
+static void
+do_metadata_not_found_warning(const tchar *wimfile,
+                             const struct wimlib_wim_info *info)
+{
+       if (info->part_number != 1) {
+               imagex_error(T("\"%"TS"\" is not the first part of the split WIM.\n"
+                              "       You must specify the first part."),
+                              wimfile);
+       }
+}
+
 /* Returns the size of a file given its name, or -1 if the file does not exist
  * or its size cannot be determined.  */
 static off_t
@@ -1758,6 +1775,8 @@ imagex_apply(int argc, tchar **argv, int cmd)
                                       "       make sure you have "
                                       "concatenated together all parts."));
                }
+       } else if (ret == WIMLIB_ERR_METADATA_NOT_FOUND && wim) {
+               do_metadata_not_found_warning(wimfile, &info);
        }
 out_wimlib_free:
        wimlib_free(wim);
@@ -1938,6 +1957,14 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                case IMAGEX_WIMBOOT_OPTION:
                        add_flags |= WIMLIB_ADD_FLAG_WIMBOOT;
                        break;
+               case IMAGEX_UNSAFE_COMPACT_OPTION:
+                       if (cmd != CMD_APPEND) {
+                               imagex_error(T("'--unsafe-compact' is only "
+                                              "valid for append!"));
+                               goto out_err;
+                       }
+                       write_flags |= WIMLIB_WRITE_FLAG_UNSAFE_COMPACT;
+                       break;
                default:
                        goto out_usage;
                }
@@ -2095,11 +2122,21 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                ret = wimlib_set_output_chunk_size(wim, chunk_size);
                if (ret)
                        goto out_free_wim;
-       } else if ((add_flags & WIMLIB_ADD_FLAG_WIMBOOT) &&
-                  compression_type == WIMLIB_COMPRESSION_TYPE_XPRESS) {
-               ret = wimlib_set_output_chunk_size(wim, 4096);
-               if (ret)
-                       goto out_free_wim;
+       } else if ((add_flags & WIMLIB_ADD_FLAG_WIMBOOT)) {
+
+               int ctype = compression_type;
+
+               if (cmd == CMD_APPEND) {
+                       struct wimlib_wim_info info;
+                       wimlib_get_wim_info(wim, &info);
+                       ctype = info.compression_type;
+               }
+
+               if (ctype == WIMLIB_COMPRESSION_TYPE_XPRESS) {
+                       ret = wimlib_set_output_chunk_size(wim, 4096);
+                       if (ret)
+                               goto out_free_wim;
+               }
        }
        if (solid_ctype != WIMLIB_COMPRESSION_TYPE_INVALID) {
                ret = wimlib_set_output_pack_compression_type(wim, solid_ctype);
@@ -2340,6 +2377,9 @@ imagex_delete(int argc, tchar **argv, int cmd)
                case IMAGEX_SOFT_OPTION:
                        write_flags |= WIMLIB_WRITE_FLAG_SOFT_DELETE;
                        break;
+               case IMAGEX_UNSAFE_COMPACT_OPTION:
+                       write_flags |= WIMLIB_WRITE_FLAG_UNSAFE_COMPACT;
+                       break;
                default:
                        goto out_usage;
                }
@@ -2710,6 +2750,12 @@ imagex_dir(int argc, tchar **argv, int cmd)
 
        ret = wimlib_iterate_dir_tree(wim, image, path, iterate_flags,
                                      print_dentry, &options);
+       if (ret == WIMLIB_ERR_METADATA_NOT_FOUND) {
+               struct wimlib_wim_info info;
+
+               wimlib_get_wim_info(wim, &info);
+               do_metadata_not_found_warning(wimfile, &info);
+       }
 out_wimlib_free:
        wimlib_free(wim);
 out_free_refglobs:
@@ -2818,6 +2864,9 @@ imagex_export(int argc, tchar **argv, int cmd)
                case IMAGEX_WIMBOOT_OPTION:
                        export_flags |= WIMLIB_EXPORT_FLAG_WIMBOOT;
                        break;
+               case IMAGEX_UNSAFE_COMPACT_OPTION:
+                       write_flags |= WIMLIB_WRITE_FLAG_UNSAFE_COMPACT;
+                       break;
                default:
                        goto out_usage;
                }
@@ -2907,6 +2956,13 @@ imagex_export(int argc, tchar **argv, int cmd)
                        goto out_free_src_wim;
                }
 
+               if (write_flags & WIMLIB_WRITE_FLAG_UNSAFE_COMPACT) {
+                       imagex_error(T("'--unsafe-compact' is only valid when "
+                                      "exporting to an existing WIM file!"));
+                       ret = -1;
+                       goto out_free_src_wim;
+               }
+
                /* dest_wimfile is not an existing file, so create a new WIM. */
 
                if (compression_type == WIMLIB_COMPRESSION_TYPE_INVALID) {
@@ -2984,6 +3040,8 @@ imagex_export(int argc, tchar **argv, int cmd)
                if (ret == WIMLIB_ERR_RESOURCE_NOT_FOUND) {
                        do_resource_not_found_warning(src_wimfile,
                                                      &src_info, &refglobs);
+               } else if (ret == WIMLIB_ERR_METADATA_NOT_FOUND) {
+                       do_metadata_not_found_warning(src_wimfile, &src_info);
                }
                goto out_free_dest_wim;
        }
@@ -3181,6 +3239,11 @@ imagex_extract(int argc, tchar **argv, int cmd)
 
                wimlib_get_wim_info(wim, &info);
                do_resource_not_found_warning(wimfile, &info, &refglobs);
+       } else if (ret == WIMLIB_ERR_METADATA_NOT_FOUND) {
+               struct wimlib_wim_info info;
+
+               wimlib_get_wim_info(wim, &info);
+               do_metadata_not_found_warning(wimfile, &info);
        }
 out_wimlib_free:
        wimlib_free(wim);
@@ -3615,9 +3678,13 @@ imagex_mount_rw_or_ro(int argc, tchar **argv, int cmd)
 
        ret = wimlib_mount_image(wim, image, dir, mount_flags, staging_dir);
        if (ret) {
-               imagex_error(T("Failed to mount image %d from \"%"TS"\" "
-                              "on \"%"TS"\""),
-                            image, wimfile, dir);
+               if (ret == WIMLIB_ERR_METADATA_NOT_FOUND) {
+                       do_metadata_not_found_warning(wimfile, &info);
+               } else {
+                       imagex_error(T("Failed to mount image %d from \"%"TS"\" "
+                                      "on \"%"TS"\""),
+                                    image, wimfile, dir);
+               }
        }
 out_free_wim:
        wimlib_free(wim);
@@ -3705,6 +3772,9 @@ imagex_optimize(int argc, tchar **argv, int cmd)
                case IMAGEX_NOT_PIPABLE_OPTION:
                        write_flags |= WIMLIB_WRITE_FLAG_NOT_PIPABLE;
                        break;
+               case IMAGEX_UNSAFE_COMPACT_OPTION:
+                       write_flags |= WIMLIB_WRITE_FLAG_UNSAFE_COMPACT;
+                       break;
                default:
                        goto out_usage;
                }
@@ -4002,6 +4072,9 @@ imagex_update(int argc, tchar **argv, int cmd)
                case IMAGEX_NO_REPLACE_OPTION:
                        default_add_flags |= WIMLIB_ADD_FLAG_NO_REPLACE;
                        break;
+               case IMAGEX_UNSAFE_COMPACT_OPTION:
+                       write_flags |= WIMLIB_WRITE_FLAG_UNSAFE_COMPACT;
+                       break;
                default:
                        goto out_usage;
                }