]> wimlib.net Git - wimlib/blobdiff - programs/imagex.c
compiler.h: remove _unused_attribute
[wimlib] / programs / imagex.c
index 2d407fac422b885dd6a4882b51abe25f93aec54c..25cc2477d2ad422b68751f185c0125ed8dc97154 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 /*
- * Copyright (C) 2012-2018 Eric Biggers
+ * Copyright (C) 2012-2023 Eric Biggers
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #define WIMLIB_COMPRESSION_TYPE_INVALID (-1)
 
-#ifdef __WIN32__
+#ifdef _WIN32
 #  include "imagex-win32.h"
 #  define print_security_descriptor     win32_print_security_descriptor
-#else /* __WIN32__ */
+#else /* _WIN32 */
 #  include <getopt.h>
 #  include <langinfo.h>
 #  define print_security_descriptor    default_print_security_descriptor
@@ -62,13 +62,13 @@ static inline void set_fd_to_binary_mode(int fd)
 #ifndef HAVE_GETOPT_LONG_ONLY
 #  define getopt_long_only getopt_long
 #endif
-#endif /* !__WIN32 */
+#endif /* !_WIN32 */
 
 /* Don't confuse the user by presenting the mounting commands on Windows when
  * they will never work.  However on UNIX-like systems we always present them,
  * even if WITH_FUSE is not defined at this point, as to not tie the build of
  * wimlib-imagex to a specific build of wimlib.  */
-#ifdef __WIN32__
+#ifdef _WIN32
 #  define WIM_MOUNTING_SUPPORTED 0
 #else
 #  define WIM_MOUNTING_SUPPORTED 1
@@ -202,6 +202,7 @@ enum {
        IMAGEX_PRESERVE_DIR_STRUCTURE_OPTION,
        IMAGEX_REBUILD_OPTION,
        IMAGEX_RECOMPRESS_OPTION,
+       IMAGEX_RECOVER_DATA_OPTION,
        IMAGEX_RECURSIVE_OPTION,
        IMAGEX_REF_OPTION,
        IMAGEX_RPFIX_OPTION,
@@ -239,6 +240,7 @@ static const struct option apply_options[] = {
        {T("include-invalid-names"), no_argument,       NULL, IMAGEX_INCLUDE_INVALID_NAMES_OPTION},
        {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
        {T("compact"),     required_argument, NULL, IMAGEX_COMPACT_OPTION},
+       {T("recover-data"), no_argument,      NULL, IMAGEX_RECOVER_DATA_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -336,6 +338,7 @@ static const struct option extract_options[] = {
        {T("preserve-dir-structure"), no_argument, NULL, IMAGEX_PRESERVE_DIR_STRUCTURE_OPTION},
        {T("wimboot"),     no_argument,       NULL, IMAGEX_WIMBOOT_OPTION},
        {T("compact"),     required_argument, NULL, IMAGEX_COMPACT_OPTION},
+       {T("recover-data"), no_argument,      NULL, IMAGEX_RECOVER_DATA_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -1052,12 +1055,12 @@ stdin_get_contents(size_t *len_ret)
 static tchar *
 translate_text_to_tstr(char *text, size_t num_bytes, size_t *num_tchars_ret)
 {
-#ifndef __WIN32__
+#ifndef _WIN32
        /* On non-Windows, assume an ASCII-compatible encoding, such as UTF-8.
         * */
        *num_tchars_ret = num_bytes;
        return text;
-#else /* !__WIN32__ */
+#else /* !_WIN32 */
        /* On Windows, translate the text to UTF-16LE */
        wchar_t *text_wstr;
        size_t num_wchars;
@@ -1084,7 +1087,7 @@ translate_text_to_tstr(char *text, size_t num_bytes, size_t *num_tchars_ret)
        }
        *num_tchars_ret = num_wchars;
        return text_wstr;
-#endif /* __WIN32__ */
+#endif /* _WIN32 */
 }
 
 static tchar *
@@ -1163,6 +1166,31 @@ report_scan_progress(const struct wimlib_progress_info_scan *scan, bool done)
                last_scan_progress = *scan;
        }
 }
+
+static struct wimlib_progress_info_split last_split_progress;
+
+static void
+report_split_progress(uint64_t bytes_completed_in_part)
+{
+       uint64_t completed_bytes = last_split_progress.completed_bytes +
+                                  bytes_completed_in_part;
+       unsigned percent_done = TO_PERCENT(completed_bytes,
+                                          last_split_progress.total_bytes);
+       unsigned unit_shift;
+       const tchar *unit_name;
+
+       unit_shift = get_unit(last_split_progress.total_bytes, &unit_name);
+       imagex_printf(T("\rSplitting WIM: %"PRIu64" %"TS" of "
+                       "%"PRIu64" %"TS" (%u%%) written, part %u of %u"),
+                     completed_bytes >> unit_shift,
+                     unit_name,
+                     last_split_progress.total_bytes >> unit_shift,
+                     unit_name,
+                     percent_done,
+                     last_split_progress.cur_part_number,
+                     last_split_progress.total_parts);
+}
+
 /* Progress callback function passed to various wimlib functions. */
 static enum wimlib_progress_status
 imagex_progress_func(enum wimlib_progress_msg msg,
@@ -1175,6 +1203,12 @@ imagex_progress_func(enum wimlib_progress_msg msg,
 
        switch (msg) {
        case WIMLIB_PROGRESS_MSG_WRITE_STREAMS:
+               if (last_split_progress.total_bytes != 0) {
+                       /* wimlib_split() in progress; use the split-specific
+                        * progress message.  */
+                       report_split_progress(info->write_streams.completed_compressed_bytes);
+                       break;
+               }
                {
                        static bool started;
                        if (!started) {
@@ -1231,7 +1265,7 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                         * default installation.  On UNIX-like systems, warn the
                         * user when fixing the target of an absolute symbolic
                         * link, so they know to disable this if they want.  */
-               #ifndef __WIN32__
+               #ifndef _WIN32
                        imagex_printf(T("\nWARNING: Adjusted target of "
                                        "absolute symbolic link \"%"TS"\"\n"
                                        "           (Use --norpfix to capture "
@@ -1330,26 +1364,9 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                }
                break;
        case WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART:
-               percent_done = TO_PERCENT(info->split.completed_bytes,
-                                         info->split.total_bytes);
-               unit_shift = get_unit(info->split.total_bytes, &unit_name);
-               imagex_printf(T("Writing \"%"TS"\" (part %u of %u): %"PRIu64" %"TS" of "
-                         "%"PRIu64" %"TS" (%u%%) written\n"),
-                       info->split.part_name,
-                       info->split.cur_part_number,
-                       info->split.total_parts,
-                       info->split.completed_bytes >> unit_shift,
-                       unit_name,
-                       info->split.total_bytes >> unit_shift,
-                       unit_name,
-                       percent_done);
-               break;
        case WIMLIB_PROGRESS_MSG_SPLIT_END_PART:
-               if (info->split.completed_bytes == info->split.total_bytes) {
-                       imagex_printf(T("Finished writing split WIM part %u of %u\n"),
-                               info->split.cur_part_number,
-                               info->split.total_parts);
-               }
+               last_split_progress = info->split;
+               report_split_progress(0);
                break;
        case WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND:
                switch (info->update.command->op) {
@@ -1733,6 +1750,9 @@ imagex_apply(int argc, tchar **argv, int cmd)
                        if (ret)
                                goto out_free_refglobs;
                        break;
+               case IMAGEX_RECOVER_DATA_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_RECOVER_DATA;
+                       break;
                default:
                        goto out_usage;
                }
@@ -1797,7 +1817,7 @@ imagex_apply(int argc, tchar **argv, int cmd)
                        goto out_wimlib_free;
        }
 
-#ifndef __WIN32__
+#ifndef _WIN32
        {
                /* Interpret a regular file or block device target as an NTFS
                 * volume.  */
@@ -2020,7 +2040,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                                        template_image_name_or_num = optarg;
                                }
                        }
-               #ifdef __WIN32__
+               #ifdef _WIN32
                        imagex_printf(T("[WARNING] '--update-of' is unreliable on Windows!\n"));
                #endif
                        break;
@@ -2258,7 +2278,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
                        goto out_free_wim;
        }
 
-#ifndef __WIN32__
+#ifndef _WIN32
        /* Detect if source is regular file or block device and set NTFS volume
         * capture mode.  */
        if (!source_list) {
@@ -2701,7 +2721,7 @@ print_blobs(WIMStruct *wim)
        wimlib_iterate_lookup_table(wim, 0, print_resource, NULL);
 }
 
-#ifndef __WIN32__
+#ifndef _WIN32
 static void
 default_print_security_descriptor(const uint8_t *sd, size_t size)
 {
@@ -3280,6 +3300,9 @@ imagex_extract(int argc, tchar **argv, int cmd)
                        if (ret)
                                goto out_free_refglobs;
                        break;
+               case IMAGEX_RECOVER_DATA_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_RECOVER_DATA;
+                       break;
                default:
                        goto out_usage;
                }
@@ -3983,7 +4006,7 @@ imagex_split(int argc, tchar **argv, int cmd)
        int c;
        int open_flags = 0;
        int write_flags = 0;
-       unsigned long part_size;
+       uint64_t part_size;
        tchar *tmp;
        int ret;
        WIMStruct *wim;
@@ -4019,6 +4042,8 @@ imagex_split(int argc, tchar **argv, int cmd)
                goto out;
 
        ret = wimlib_split(wim, argv[1], part_size, write_flags);
+       if (ret == 0)
+               tprintf(T("\nFinished splitting \"%"TS"\"\n"), argv[0]);
        wimlib_free(wim);
 out:
        return ret;
@@ -4435,7 +4460,7 @@ static const struct imagex_command imagex_commands[] = {
        [CMD_VERIFY]   = {T("verify"),   imagex_verify},
 };
 
-#ifdef __WIN32__
+#ifdef _WIN32
 
    /* Can be a directory or source list file.  But source list file is probably
     * a rare use case, so just say directory.  */
@@ -4469,7 +4494,7 @@ T(
 "                    [--check] [--ref=\"GLOB\"] [--no-acls] [--strict-acls]\n"
 "                    [--no-attributes] [--rpfix] [--norpfix]\n"
 "                    [--include-invalid-names] [--wimboot] [--unix-data]\n"
-"                    [--compact=FORMAT]\n"
+"                    [--compact=FORMAT] [--recover-data]\n"
 ),
 [CMD_CAPTURE] =
 T(
@@ -4502,8 +4527,8 @@ T(
 "    %"TS" WIMFILE IMAGE [(PATH | @LISTFILE)...]\n"
 "                    [--check] [--ref=\"GLOB\"] [--dest-dir=CMD_DIR]\n"
 "                    [--to-stdout] [--no-acls] [--strict-acls]\n"
-"                    [--no-attributes] [--include-invalid-names]\n"
-"                    [--no-globs] [--nullglob] [--preserve-dir-structure]\n"
+"                    [--no-attributes] [--include-invalid-names] [--no-globs]\n"
+"                    [--nullglob] [--preserve-dir-structure] [--recover-data]\n"
 ),
 [CMD_INFO] =
 T(
@@ -4587,7 +4612,7 @@ version(void)
        static const tchar * const fmt =
        T(
 "wimlib-imagex " PACKAGE_VERSION " (using wimlib %"TS")\n"
-"Copyright (C) 2012-2018 Eric Biggers\n"
+"Copyright (C) 2012-2023 Eric Biggers\n"
 "License GPLv3+; GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n"
 "This is free software: you are free to change and redistribute it.\n"
 "There is NO WARRANTY, to the extent permitted by law.\n"
@@ -4641,7 +4666,7 @@ static void
 recommend_man_page(int cmd, FILE *fp)
 {
        const tchar *format_str;
-#ifdef __WIN32__
+#ifdef _WIN32
        format_str = T("Some uncommon options are not listed;\n"
                       "See %"TS".pdf in the doc directory for more details.\n");
 #else
@@ -4682,8 +4707,8 @@ usage_all(FILE *fp)
        recommend_man_page(CMD_NONE, fp);
 }
 
-#ifdef __WIN32__
-extern int wmain(int argc, wchar_t **argv);
+#ifdef _WIN32
+int wmain(int argc, wchar_t **argv);
 #define main wmain
 #endif