]> wimlib.net Git - wimlib/blobdiff - programs/imagex.c
Improve handling of invalid filenames
[wimlib] / programs / imagex.c
index 601ad01ca53374a06c63007c5174b4fee5b4f26b..9ee6df34ed630e99198f13584456f2f2c823d74a 100644 (file)
@@ -104,6 +104,7 @@ IMAGEX_PROGNAME" apply WIMFILE [IMAGE_NUM | IMAGE_NAME | all]\n"
 "                    (DIRECTORY | NTFS_VOLUME) [--check] [--hardlink]\n"
 "                    [--symlink] [--verbose] [--ref=\"GLOB\"] [--unix-data]\n"
 "                    [--no-acls] [--strict-acls] [--rpfix] [--norpfix]\n"
+"                    [--force-all-files]\n"
 ),
 [CAPTURE] =
 T(
@@ -134,6 +135,7 @@ T(
 IMAGEX_PROGNAME" extract WIMFILE (IMAGE_NUM | IMAGE_NAME) [PATH...]\n"
 "              [--check] [--ref=\"GLOB\"] [--verbose] [--unix-data]\n"
 "              [--no-acls] [--strict-acls] [--to-stdout] [--dest-dir=DIR]\n"
+"              [--force-all-files]\n"
 ),
 [INFO] =
 T(
@@ -206,6 +208,7 @@ enum {
        IMAGEX_EXTRACT_XML_OPTION,
        IMAGEX_FLAGS_OPTION,
        IMAGEX_FORCE_OPTION,
+       IMAGEX_FORCE_ALL_FILES_OPTION,
        IMAGEX_HARDLINK_OPTION,
        IMAGEX_HEADER_OPTION,
        IMAGEX_LAZY_OPTION,
@@ -243,6 +246,7 @@ static const struct option apply_options[] = {
        {T("strict-acls"), no_argument,       NULL, IMAGEX_STRICT_ACLS_OPTION},
        {T("rpfix"),       no_argument,       NULL, IMAGEX_RPFIX_OPTION},
        {T("norpfix"),     no_argument,       NULL, IMAGEX_NORPFIX_OPTION},
+       {T("force-all-files"), no_argument,       NULL, IMAGEX_FORCE_ALL_FILES_OPTION},
        {NULL, 0, NULL, 0},
 };
 static const struct option capture_or_append_options[] = {
@@ -290,6 +294,7 @@ static const struct option extract_options[] = {
        {T("strict-acls"), no_argument,       NULL, IMAGEX_STRICT_ACLS_OPTION},
        {T("dest-dir"),    required_argument, NULL, IMAGEX_DEST_DIR_OPTION},
        {T("to-stdout"),   no_argument,       NULL, IMAGEX_TO_STDOUT_OPTION},
+       {T("force-all-files"), no_argument,       NULL, IMAGEX_FORCE_ALL_FILES_OPTION},
        {NULL, 0, NULL, 0},
 };
 
@@ -999,16 +1004,41 @@ get_data_type(int ctype)
        return NULL;
 }
 
+#define GIBIBYTE_MIN_NBYTES 10000000000ULL
+#define MEBIBYTE_MIN_NBYTES 10000000ULL
+#define KIBIBYTE_MIN_NBYTES 10000ULL
+
+static unsigned
+get_unit(uint64_t total_bytes, const tchar **name_ret)
+{
+       if (total_bytes >= GIBIBYTE_MIN_NBYTES) {
+               *name_ret = T("GiB");
+               return 30;
+       } else if (total_bytes >= MEBIBYTE_MIN_NBYTES) {
+               *name_ret = T("MiB");
+               return 20;
+       } else if (total_bytes >= KIBIBYTE_MIN_NBYTES) {
+               *name_ret = T("KiB");
+               return 10;
+       } else {
+               *name_ret = T("bytes");
+               return 0;
+       }
+}
+
 /* Progress callback function passed to various wimlib functions. */
 static int
 imagex_progress_func(enum wimlib_progress_msg msg,
                     const union wimlib_progress_info *info)
 {
        unsigned percent_done;
+       unsigned unit_shift;
+       const tchar *unit_name;
        if (imagex_be_quiet)
                return 0;
        switch (msg) {
        case WIMLIB_PROGRESS_MSG_WRITE_STREAMS:
+               unit_shift = get_unit(info->write_streams.total_bytes, &unit_name);
                percent_done = TO_PERCENT(info->write_streams.completed_bytes,
                                          info->write_streams.total_bytes);
                if (info->write_streams.completed_streams == 0) {
@@ -1019,10 +1049,12 @@ imagex_progress_func(enum wimlib_progress_msg msg,
                                data_type, info->write_streams.num_threads,
                                (info->write_streams.num_threads == 1) ? T("") : T("s"));
                }
-               tprintf(T("\r%"PRIu64" MiB of %"PRIu64" MiB (uncompressed) "
+               tprintf(T("\r%"PRIu64" %"TS" of %"PRIu64" %"TS" (uncompressed) "
                        "written (%u%% done)"),
-                       info->write_streams.completed_bytes >> 20,
-                       info->write_streams.total_bytes >> 20,
+                       info->write_streams.completed_bytes >> unit_shift,
+                       unit_name,
+                       info->write_streams.total_bytes >> unit_shift,
+                       unit_name,
                        percent_done);
                if (info->write_streams.completed_bytes >= info->write_streams.total_bytes)
                        tputchar(T('\n'));
@@ -1045,24 +1077,30 @@ imagex_progress_func(enum wimlib_progress_msg msg,
        /*case WIMLIB_PROGRESS_MSG_SCAN_END:*/
                /*break;*/
        case WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY:
+               unit_shift = get_unit(info->integrity.total_bytes, &unit_name);
                percent_done = TO_PERCENT(info->integrity.completed_bytes,
                                          info->integrity.total_bytes);
-               tprintf(T("\rVerifying integrity of \"%"TS"\": %"PRIu64" MiB "
-                       "of %"PRIu64" MiB (%u%%) done"),
+               tprintf(T("\rVerifying integrity of \"%"TS"\": %"PRIu64" "TS" "
+                       "of %"PRIu64" "TS" (%u%%) done"),
                        info->integrity.filename,
-                       info->integrity.completed_bytes >> 20,
-                       info->integrity.total_bytes >> 20,
+                       info->integrity.completed_bytes >> unit_shift,
+                       unit_name,
+                       info->integrity.total_bytes >> unit_shift,
+                       unit_name,
                        percent_done);
                if (info->integrity.completed_bytes == info->integrity.total_bytes)
                        tputchar(T('\n'));
                break;
        case WIMLIB_PROGRESS_MSG_CALC_INTEGRITY:
+               unit_shift = get_unit(info->integrity.total_bytes, &unit_name);
                percent_done = TO_PERCENT(info->integrity.completed_bytes,
                                          info->integrity.total_bytes);
-               tprintf(T("\rCalculating integrity table for WIM: %"PRIu64" MiB "
-                         "of %"PRIu64" MiB (%u%%) done"),
-                       info->integrity.completed_bytes >> 20,
-                       info->integrity.total_bytes >> 20,
+               tprintf(T("\rCalculating integrity table for WIM: %"PRIu64" %"TS" "
+                         "of %"PRIu64" %"TS" (%u%%) done"),
+                       info->integrity.completed_bytes >> unit_shift,
+                       unit_name,
+                       info->integrity.total_bytes >> unit_shift,
+                       unit_name,
                        percent_done);
                if (info->integrity.completed_bytes == info->integrity.total_bytes)
                        tputchar(T('\n'));
@@ -1093,10 +1131,13 @@ imagex_progress_func(enum wimlib_progress_msg msg,
        case WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS:
                percent_done = TO_PERCENT(info->extract.completed_bytes,
                                          info->extract.total_bytes);
+               unit_shift = get_unit(info->extract.total_bytes, &unit_name);
                tprintf(T("\rExtracting files: "
-                         "%"PRIu64" MiB of %"PRIu64" MiB (%u%%) done"),
-                       info->extract.completed_bytes >> 20,
-                       info->extract.total_bytes >> 20,
+                         "%"PRIu64" %"TS" of %"PRIu64" %"TS" (%u%%) done"),
+                       info->extract.completed_bytes >> unit_shift,
+                       unit_name,
+                       info->extract.total_bytes >> unit_shift,
+                       unit_name,
                        percent_done);
                if (info->extract.completed_bytes >= info->extract.total_bytes)
                        tputchar(T('\n'));
@@ -1117,23 +1158,29 @@ imagex_progress_func(enum wimlib_progress_msg msg,
        case WIMLIB_PROGRESS_MSG_JOIN_STREAMS:
                percent_done = TO_PERCENT(info->join.completed_bytes,
                                          info->join.total_bytes);
+               unit_shift = get_unit(info->join.total_bytes, &unit_name);
                tprintf(T("Writing resources from part %u of %u: "
-                         "%"PRIu64 " MiB of %"PRIu64" MiB (%u%%) written\n"),
+                         "%"PRIu64 " %"TS" of %"PRIu64" %"TS" (%u%%) written\n"),
                        (info->join.completed_parts == info->join.total_parts) ?
                        info->join.completed_parts : info->join.completed_parts + 1,
                        info->join.total_parts,
-                       info->join.completed_bytes >> 20,
-                       info->join.total_bytes >> 20,
+                       info->join.completed_bytes >> unit_shift,
+                       unit_name,
+                       info->join.total_bytes >> unit_shift,
+                       unit_name,
                        percent_done);
                break;
        case WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART:
                percent_done = TO_PERCENT(info->split.completed_bytes,
                                          info->split.total_bytes);
-               tprintf(T("Writing \"%"TS"\": %"PRIu64" MiB of "
-                         "%"PRIu64" MiB (%u%%) written\n"),
+               unit_shift = get_unit(info->split.total_bytes, &unit_name);
+               tprintf(T("Writing \"%"TS"\": %"PRIu64" %"TS" of "
+                         "%"PRIu64" %"TS" (%u%%) written\n"),
                        info->split.part_name,
-                       info->split.completed_bytes >> 20,
-                       info->split.total_bytes >> 20,
+                       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:
@@ -1486,6 +1533,10 @@ imagex_apply(int argc, tchar **argv)
                case IMAGEX_RPFIX_OPTION:
                        extract_flags |= WIMLIB_EXTRACT_FLAG_RPFIX;
                        break;
+               case IMAGEX_FORCE_ALL_FILES_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_REPLACE_INVALID_FILENAMES;
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_ALL_CASE_CONFLICTS;
+                       break;
                default:
                        usage(APPLY);
                        return -1;
@@ -2217,6 +2268,10 @@ imagex_extract(int argc, tchar **argv)
                        extract_flags |= WIMLIB_EXTRACT_FLAG_TO_STDOUT;
                        imagex_be_quiet = true;
                        break;
+               case IMAGEX_FORCE_ALL_FILES_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_REPLACE_INVALID_FILENAMES;
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_ALL_CASE_CONFLICTS;
+                       break;
                default:
                        goto out_usage;
                }