]> wimlib.net Git - wimlib/blobdiff - programs/imagex.c
Don't use the old ADD_IMAGE flag names
[wimlib] / programs / imagex.c
index 6dd8bdbb03df7b4f9b125cc9e9c328dd227a5839..19ef736124a58eac0a9d519cbac3d3da23e1bf5d 100644 (file)
@@ -124,6 +124,7 @@ enum {
        CMD_UNMOUNT,
 #endif
        CMD_UPDATE,
+       CMD_VERIFY,
        CMD_MAX,
 };
 
@@ -404,6 +405,13 @@ static const struct option update_options[] = {
        {NULL, 0, NULL, 0},
 };
 
+static const struct option verify_options[] = {
+       {T("ref"), required_argument, NULL, IMAGEX_REF_OPTION},
+       {T("nocheck"), no_argument, NULL, IMAGEX_NOCHECK_OPTION},
+
+       {NULL, 0, NULL, 0},
+};
+
 #if 0
 #      define _format_attribute(type, format_str, args_start) \
                        __attribute__((format(type, format_str, args_start)))
@@ -1153,6 +1161,17 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                         T("NTFS volume") : T("directory")),
                        info->extract.target);
                break;
+       case WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE:
+               if (info->extract.end_file_count >= 2000) {
+                       percent_done = TO_PERCENT(info->extract.current_file_count,
+                                                 info->extract.end_file_count);
+                       imagex_printf(T("\rCreating files: %"PRIu64" of %"PRIu64" (%u%%) done"),
+                                     info->extract.current_file_count,
+                                     info->extract.end_file_count, percent_done);
+                       if (info->extract.current_file_count == info->extract.end_file_count)
+                               imagex_printf(T("\n"));
+               }
+               break;
        case WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS:
                percent_done = TO_PERCENT(info->extract.completed_bytes,
                                          info->extract.total_bytes);
@@ -1167,6 +1186,17 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                if (info->extract.completed_bytes >= info->extract.total_bytes)
                        imagex_printf(T("\n"));
                break;
+       case WIMLIB_PROGRESS_MSG_EXTRACT_METADATA:
+               if (info->extract.end_file_count >= 2000) {
+                       percent_done = TO_PERCENT(info->extract.current_file_count,
+                                                 info->extract.end_file_count);
+                       imagex_printf(T("\rApplying metadata to files: %"PRIu64" of %"PRIu64" (%u%%) done"),
+                                     info->extract.current_file_count,
+                                     info->extract.end_file_count, percent_done);
+                       if (info->extract.current_file_count == info->extract.end_file_count)
+                               imagex_printf(T("\n"));
+               }
+               break;
        case WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN:
                if (info->extract.total_parts != 1) {
                        imagex_printf(T("\nReading split pipable WIM part %u of %u\n"),
@@ -1234,6 +1264,25 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                        }
                }
                break;
+       case WIMLIB_PROGRESS_MSG_BEGIN_VERIFY_IMAGE:
+               imagex_printf(T("Verifying metadata for image %"PRIu32" of %"PRIu32"\n"),
+                             info->verify_image.current_image,
+                             info->verify_image.total_images);
+               break;
+       case WIMLIB_PROGRESS_MSG_VERIFY_STREAMS:
+               percent_done = TO_PERCENT(info->verify_streams.completed_bytes,
+                                         info->verify_streams.total_bytes);
+               unit_shift = get_unit(info->verify_streams.total_bytes, &unit_name);
+               imagex_printf(T("\rVerifying streams: "
+                         "%"PRIu64" %"TS" of %"PRIu64" %"TS" (%u%%) done"),
+                       info->verify_streams.completed_bytes >> unit_shift,
+                       unit_name,
+                       info->verify_streams.total_bytes >> unit_shift,
+                       unit_name,
+                       percent_done);
+               if (info->verify_streams.completed_bytes == info->verify_streams.total_bytes)
+                       imagex_printf(T("\n"));
+               break;
        default:
                break;
        }
@@ -1664,10 +1713,10 @@ static int
 imagex_capture_or_append(int argc, tchar **argv, int cmd)
 {
        int c;
-       int open_flags = WIMLIB_OPEN_FLAG_WRITE_ACCESS;
-       int add_image_flags = WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE |
-                             WIMLIB_ADD_IMAGE_FLAG_WINCONFIG |
-                             WIMLIB_ADD_IMAGE_FLAG_VERBOSE;
+       int open_flags = 0;
+       int add_flags = WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE |
+                       WIMLIB_ADD_FLAG_WINCONFIG |
+                       WIMLIB_ADD_FLAG_VERBOSE;
        int write_flags = 0;
        int compression_type = WIMLIB_COMPRESSION_TYPE_INVALID;
        uint32_t chunk_size = UINT32_MAX;
@@ -1707,7 +1756,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
        for_opt(c, capture_or_append_options) {
                switch (c) {
                case IMAGEX_BOOT_OPTION:
-                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_BOOT;
+                       add_flags |= WIMLIB_ADD_FLAG_BOOT;
                        break;
                case IMAGEX_CHECK_OPTION:
                        open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY;
@@ -1718,7 +1767,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                        break;
                case IMAGEX_CONFIG_OPTION:
                        config_file = optarg;
-                       add_image_flags &= ~WIMLIB_ADD_IMAGE_FLAG_WINCONFIG;
+                       add_flags &= ~WIMLIB_ADD_FLAG_WINCONFIG;
                        break;
                case IMAGEX_COMPRESS_OPTION:
                        compression_type = get_compression_type(optarg);
@@ -1750,7 +1799,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                        flags_element = optarg;
                        break;
                case IMAGEX_DEREFERENCE_OPTION:
-                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE;
+                       add_flags |= WIMLIB_ADD_FLAG_DEREFERENCE;
                        break;
                case IMAGEX_VERBOSE_OPTION:
                        /* No longer does anything.  */
@@ -1764,22 +1813,22 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                        write_flags |= WIMLIB_WRITE_FLAG_REBUILD;
                        break;
                case IMAGEX_UNIX_DATA_OPTION:
-                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA;
+                       add_flags |= WIMLIB_ADD_FLAG_UNIX_DATA;
                        break;
                case IMAGEX_SOURCE_LIST_OPTION:
                        source_list = true;
                        break;
                case IMAGEX_NO_ACLS_OPTION:
-                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_NO_ACLS;
+                       add_flags |= WIMLIB_ADD_FLAG_NO_ACLS;
                        break;
                case IMAGEX_STRICT_ACLS_OPTION:
-                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_STRICT_ACLS;
+                       add_flags |= WIMLIB_ADD_FLAG_STRICT_ACLS;
                        break;
                case IMAGEX_RPFIX_OPTION:
-                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_RPFIX;
+                       add_flags |= WIMLIB_ADD_FLAG_RPFIX;
                        break;
                case IMAGEX_NORPFIX_OPTION:
-                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_NORPFIX;
+                       add_flags |= WIMLIB_ADD_FLAG_NORPFIX;
                        break;
                case IMAGEX_PIPABLE_OPTION:
                        write_flags |= WIMLIB_WRITE_FLAG_PIPABLE;
@@ -1818,7 +1867,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                        write_flags |= WIMLIB_WRITE_FLAG_SKIP_EXTERNAL_WIMS;
                        break;
                case IMAGEX_WIMBOOT_OPTION:
-                       add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_WIMBOOT;
+                       add_flags |= WIMLIB_ADD_FLAG_WIMBOOT;
                        break;
                default:
                        goto out_usage;
@@ -1839,7 +1888,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
        if (compression_type == WIMLIB_COMPRESSION_TYPE_INVALID) {
                /* No compression type specified.  Use the default.  */
 
-               if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_WIMBOOT) {
+               if (add_flags & WIMLIB_ADD_FLAG_WIMBOOT) {
                        /* With --wimboot, default to XPRESS compression.  */
                        compression_type = WIMLIB_COMPRESSION_TYPE_XPRESS;
                } else if (write_flags & WIMLIB_WRITE_FLAG_PACK_STREAMS) {
@@ -1958,8 +2007,11 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
 
        /* Open the existing WIM, or create a new one.  */
        if (cmd == CMD_APPEND) {
-               ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
-                                                   imagex_progress_func, NULL);
+               ret = wimlib_open_wim_with_progress(wimfile,
+                                                   open_flags | WIMLIB_OPEN_FLAG_WRITE_ACCESS,
+                                                   &wim,
+                                                   imagex_progress_func,
+                                                   NULL);
                if (ret)
                        goto out_free_capture_sources;
        } else {
@@ -1974,7 +2026,7 @@ 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_image_flags & WIMLIB_ADD_IMAGE_FLAG_WIMBOOT) &&
+       } else if ((add_flags & WIMLIB_ADD_FLAG_WIMBOOT) &&
                   compression_type == WIMLIB_COMPRESSION_TYPE_XPRESS) {
                ret = wimlib_set_output_chunk_size(wim, 4096);
                if (ret)
@@ -2001,7 +2053,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                        if (S_ISBLK(stbuf.st_mode) || S_ISREG(stbuf.st_mode)) {
                                imagex_printf(T("Capturing WIM image from NTFS "
                                          "filesystem on \"%"TS"\"\n"), source);
-                               add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_NTFS;
+                               add_flags |= WIMLIB_ADD_FLAG_NTFS;
                        }
                } else {
                        if (errno != ENOENT) {
@@ -2041,9 +2093,8 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
 
                for (size_t i = 0; i < base_wimfiles.num_strings; i++) {
                        ret = wimlib_open_wim_with_progress(
-                                   base_wimfiles.strings[i],
-                                   open_flags, &base_wims[i],
-                                   imagex_progress_func, NULL);
+                                   base_wimfiles.strings[i], open_flags,
+                                   &base_wims[i], imagex_progress_func, NULL);
                        if (ret)
                                goto out_free_base_wims;
 
@@ -2117,7 +2168,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                                           num_sources,
                                           name,
                                           config_file,
-                                          add_image_flags);
+                                          add_flags);
        if (ret)
                goto out_free_template_wim;
 
@@ -3959,7 +4010,85 @@ out_err:
        goto out_free_command_str;
 }
 
+/* Verify a WIM file.  */
+static int
+imagex_verify(int argc, tchar **argv, int cmd)
+{
+       int ret;
+       const tchar *wimfile;
+       WIMStruct *wim;
+       int open_flags = WIMLIB_OPEN_FLAG_CHECK_INTEGRITY;
+       int verify_flags = 0;
+       STRING_SET(refglobs);
+       int c;
 
+       for_opt(c, verify_options) {
+               switch (c) {
+               case IMAGEX_REF_OPTION:
+                       ret = string_set_append(&refglobs, optarg);
+                       if (ret)
+                               goto out_free_refglobs;
+                       break;
+               case IMAGEX_NOCHECK_OPTION:
+                       open_flags &= ~WIMLIB_OPEN_FLAG_CHECK_INTEGRITY;
+                       break;
+               default:
+                       goto out_usage;
+               }
+       }
+
+       argv += optind;
+       argc -= optind;
+
+       if (argc != 1) {
+               if (argc == 0)
+                       imagex_error(T("Must specify a WIM file!"));
+               else
+                       imagex_error(T("At most one WIM file can be specified!"));
+               goto out_usage;
+       }
+
+       wimfile = argv[0];
+
+       ret = wimlib_open_wim_with_progress(wimfile,
+                                           open_flags,
+                                           &wim,
+                                           imagex_progress_func,
+                                           NULL);
+       if (ret)
+               goto out_free_refglobs;
+
+       ret = wim_reference_globs(wim, &refglobs, open_flags);
+       if (ret)
+               goto out_wimlib_free;
+
+       ret = wimlib_verify_wim(wim, verify_flags);
+       if (ret) {
+               tputc(T('\n'), stderr);
+               imagex_error(T("\"%"TS"\" failed verification!"),
+                            wimfile);
+               if (ret == WIMLIB_ERR_RESOURCE_NOT_FOUND &&
+                   refglobs.num_strings == 0)
+               {
+                       imagex_printf(T("Note: if this WIM file is not standalone, "
+                                       "use the --ref option to specify the other parts.\n"));
+               }
+       } else {
+               imagex_printf(T("\n\"%"TS"\" was successfully verified.\n"),
+                             wimfile);
+       }
+
+out_wimlib_free:
+       wimlib_free(wim);
+out_free_refglobs:
+       string_set_destroy(&refglobs);
+       return ret;
+
+out_usage:
+       usage(CMD_VERIFY, stderr);
+       ret = -1;
+       goto out_free_refglobs;
+}
 
 struct imagex_command {
        const tchar *name;
@@ -3986,6 +4115,7 @@ static const struct imagex_command imagex_commands[] = {
        [CMD_UNMOUNT]  = {T("unmount"),  imagex_unmount},
 #endif
        [CMD_UPDATE]   = {T("update"),   imagex_update},
+       [CMD_VERIFY]   = {T("verify"),   imagex_verify},
 };
 
 #ifdef __WIN32__
@@ -4105,6 +4235,10 @@ T(
 "                    [--command=STRING] [--wimboot-config=FILE]\n"
 "                    [< CMDFILE]\n"
 ),
+[CMD_VERIFY] =
+T(
+"    %"TS" WIMFILE [--ref=\"GLOB\"]\n"
+),
 };
 
 static const tchar *invocation_name;