X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=programs%2Fimagex.c;h=e80d3e6ce6aecd111d98e216e27c469ae0092a2e;hb=c07877105822d01725b36b011c93609559164b06;hp=7914573f59fa45a5213e610316ae7eae817c371f;hpb=1a08ade3f32c5557445562148e897f27ac942e3f;p=wimlib diff --git a/programs/imagex.c b/programs/imagex.c index 7914573f..e80d3e6c 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2012, 2013 Eric Biggers + * Copyright (C) 2012, 2013, 2014 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 @@ -167,6 +167,7 @@ enum { IMAGEX_LAZY_OPTION, IMAGEX_LOOKUP_TABLE_OPTION, IMAGEX_METADATA_OPTION, + IMAGEX_NEW_IMAGE_OPTION, IMAGEX_NOCHECK_OPTION, IMAGEX_NORPFIX_OPTION, IMAGEX_NOT_PIPABLE_OPTION, @@ -197,6 +198,7 @@ enum { IMAGEX_UNIX_DATA_OPTION, IMAGEX_UPDATE_OF_OPTION, IMAGEX_VERBOSE_OPTION, + IMAGEX_WIMBOOT_OPTION, IMAGEX_XML_OPTION, }; @@ -217,6 +219,7 @@ static const struct option apply_options[] = { /* --resume is undocumented for now as it needs improvement. */ {T("resume"), no_argument, NULL, IMAGEX_RESUME_OPTION}, + {T("wimboot"), no_argument, NULL, IMAGEX_WIMBOOT_OPTION}, {NULL, 0, NULL, 0}, }; @@ -249,6 +252,7 @@ static const struct option capture_or_append_options[] = { {T("not-pipable"), no_argument, NULL, IMAGEX_NOT_PIPABLE_OPTION}, {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}, {NULL, 0, NULL, 0}, }; @@ -271,6 +275,7 @@ static const struct option export_options[] = { {T("nocheck"), no_argument, NULL, IMAGEX_NOCHECK_OPTION}, {T("no-check"), no_argument, NULL, IMAGEX_NOCHECK_OPTION}, {T("compress"), required_argument, NULL, IMAGEX_COMPRESS_OPTION}, + {T("compress-slow"), no_argument, NULL, IMAGEX_COMPRESS_SLOW_OPTION}, {T("pack-streams"),no_argument, NULL, IMAGEX_PACK_STREAMS_OPTION}, {T("solid"), no_argument, NULL, IMAGEX_PACK_STREAMS_OPTION}, {T("chunk-size"), required_argument, NULL, IMAGEX_CHUNK_SIZE_OPTION}, @@ -299,6 +304,7 @@ static const struct option extract_options[] = { {T("no-wildcards"), no_argument, NULL, IMAGEX_NO_WILDCARDS_OPTION}, {T("nullglob"), no_argument, NULL, IMAGEX_NULLGLOB_OPTION}, {T("preserve-dir-structure"), no_argument, NULL, IMAGEX_PRESERVE_DIR_STRUCTURE_OPTION}, + {T("wimboot"), no_argument, NULL, IMAGEX_WIMBOOT_OPTION}, {NULL, 0, NULL, 0}, }; @@ -360,6 +366,7 @@ static const struct option unmount_options[] = { {T("check"), no_argument, NULL, IMAGEX_CHECK_OPTION}, {T("rebuild"), no_argument, NULL, IMAGEX_REBUILD_OPTION}, {T("lazy"), no_argument, NULL, IMAGEX_LAZY_OPTION}, + {T("new-image"), no_argument, NULL, IMAGEX_NEW_IMAGE_OPTION}, {NULL, 0, NULL, 0}, }; @@ -410,6 +417,17 @@ imagex_error(const tchar *format, ...) va_end(va); } +static void _format_attribute(printf, 1, 2) +imagex_warning(const tchar *format, ...) +{ + va_list va; + va_start(va, format); + tfputs(T("WARNING: "), stderr); + tvfprintf(stderr, format, va); + tputc(T('\n'), stderr); + va_end(va); +} + /* Print formatted error message to stderr. */ static void _format_attribute(printf, 1, 2) imagex_error_with_errno(const tchar *format, ...) @@ -711,7 +729,7 @@ static bool is_comment_line(const tchar *line, size_t len) { for (;;) { - if (*line == T('#')) + if (*line == T('#') || *line == T(';')) return true; if (!istspace(*line) && *line != T('\0')) return false; @@ -853,8 +871,8 @@ check_config_section(tchar *line, size_t len, "of capture config file\n"), stderr); } else { - imagex_error(T("Invalid capture config file section \"%"TS"\""), - line - 1); + imagex_warning(T("Unknown capture config file section \"%"TS"\""), + line - 1); return CAPTURE_CONFIG_INVALID_SECTION; } return CAPTURE_CONFIG_CHANGED_SECTION; @@ -891,9 +909,8 @@ parse_capture_config_line(tchar *line, size_t len, int ret; ret = check_config_section(line, len, cur_section); - if (ret == CAPTURE_CONFIG_INVALID_SECTION) - return false; - if (ret == CAPTURE_CONFIG_CHANGED_SECTION) + if (ret == CAPTURE_CONFIG_CHANGED_SECTION || + ret == CAPTURE_CONFIG_INVALID_SECTION) return true; switch (*cur_section) { @@ -938,6 +955,10 @@ parse_capture_config(tchar **contents_p, size_t nchars, tchar *endp = tmemchr(p, T('\n'), nchars); size_t len = endp - p + 1; *endp = T('\0'); + if (p != endp && *(endp - 1) == T('\r')) { + *(endp - 1) = '\0'; + len--; + } if (!is_comment_line(p, len)) if (!parse_capture_config_line(p, len, &cur_section, config)) return -1; @@ -1662,6 +1683,9 @@ imagex_apply(int argc, tchar **argv, int cmd) case IMAGEX_RESUME_OPTION: extract_flags |= WIMLIB_EXTRACT_FLAG_RESUME; break; + case IMAGEX_WIMBOOT_OPTION: + extract_flags |= WIMLIB_EXTRACT_FLAG_WIMBOOT; + break; default: goto out_usage; } @@ -1817,7 +1841,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) tchar *source; tchar *source_copy; - const tchar *config_file = NULL; + tchar *config_file = NULL; tchar *config_str; struct wimlib_capture_config *config; @@ -1938,6 +1962,9 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) goto out_free_base_wimfiles; write_flags |= WIMLIB_WRITE_FLAG_SKIP_EXTERNAL_WIMS; break; + case IMAGEX_WIMBOOT_OPTION: + add_image_flags |= WIMLIB_ADD_IMAGE_FLAG_WIMBOOT; + break; default: goto out_usage; } @@ -1955,22 +1982,46 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd) if (compression_type == WIMLIB_COMPRESSION_TYPE_INVALID) { - compression_type = WIMLIB_COMPRESSION_TYPE_LZX; - - if (!compress_slow) { - struct wimlib_lzx_compressor_params params = { - .hdr.size = sizeof(params), - .algorithm = WIMLIB_LZX_ALGORITHM_FAST, - .use_defaults = 1, - }; - wimlib_set_default_compressor_params(WIMLIB_COMPRESSION_TYPE_LZX, - ¶ms.hdr); + if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_WIMBOOT) { + compression_type = WIMLIB_COMPRESSION_TYPE_XPRESS; + } else { + compression_type = WIMLIB_COMPRESSION_TYPE_LZX; + if (!compress_slow) { + struct wimlib_lzx_compressor_params params = { + .hdr.size = sizeof(params), + .algorithm = WIMLIB_LZX_ALGORITHM_FAST, + .use_defaults = 1, + }; + wimlib_set_default_compressor_params(WIMLIB_COMPRESSION_TYPE_LZX, + ¶ms.hdr); + } } + } if (compress_slow) set_compress_slow(); + /* Set default configuration file */ +#ifdef __WIN32__ + if ((add_image_flags & WIMLIB_ADD_IMAGE_FLAG_WIMBOOT) && !config) { + struct stat st; + + config_file = alloca(wcslen(source) * sizeof(wchar_t) + 100); + swprintf(config_file, L"%ls\\%ls", + source, L"Windows\\System32\\WimBootCompress.ini"); + + if (tstat(config_file, &st)) { + imagex_printf(L"\"%ls\" does not exist; using " + "default configuration\n", + config_file); + config_file = NULL; + } else { + add_image_flags &= ~WIMLIB_ADD_IMAGE_FLAG_WINCONFIG; + } + } +#endif + if (!tstrcmp(wimfile, T("-"))) { /* Writing captured WIM to standard output. */ #if 0 @@ -2110,6 +2161,11 @@ 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) && + compression_type == WIMLIB_COMPRESSION_TYPE_XPRESS) { + ret = wimlib_set_output_chunk_size(wim, 4096); + if (ret) + goto out_free_wim; } if (pack_chunk_size != UINT32_MAX) { ret = wimlib_set_output_pack_chunk_size(wim, pack_chunk_size); @@ -2731,6 +2787,10 @@ imagex_export(int argc, tchar **argv, int cmd) if (compression_type == WIMLIB_COMPRESSION_TYPE_INVALID) goto out_err; break; + case IMAGEX_COMPRESS_SLOW_OPTION: + write_flags |= WIMLIB_WRITE_FLAG_RECOMPRESS; + set_compress_slow(); + break; case IMAGEX_PACK_STREAMS_OPTION: write_flags |= WIMLIB_WRITE_FLAG_PACK_STREAMS; break; @@ -3002,6 +3062,9 @@ imagex_extract(int argc, tchar **argv, int cmd) case IMAGEX_PRESERVE_DIR_STRUCTURE_OPTION: notlist_extract_flags &= ~WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE; break; + case IMAGEX_WIMBOOT_OPTION: + extract_flags |= WIMLIB_EXTRACT_FLAG_WIMBOOT; + break; default: goto out_usage; } @@ -3750,6 +3813,9 @@ imagex_unmount(int argc, tchar **argv, int cmd) case IMAGEX_LAZY_OPTION: unmount_flags |= WIMLIB_UNMOUNT_FLAG_LAZY; break; + case IMAGEX_NEW_IMAGE_OPTION: + unmount_flags |= WIMLIB_UNMOUNT_FLAG_NEW_IMAGE; + break; default: goto out_usage; } @@ -3759,6 +3825,15 @@ imagex_unmount(int argc, tchar **argv, int cmd) if (argc != 1) goto out_usage; + if (unmount_flags & WIMLIB_UNMOUNT_FLAG_NEW_IMAGE) { + if (!(unmount_flags & WIMLIB_UNMOUNT_FLAG_COMMIT)) { + imagex_error(T("--new-image is meaningless " + "without --commit also specified!")); + goto out_err; + } + imagex_printf(T("Committing changes as new image...\n")); + } + ret = wimlib_unmount_image(argv[0], unmount_flags, imagex_progress_func); if (ret) @@ -3768,6 +3843,7 @@ out: out_usage: usage(CMD_UNMOUNT, stderr); +out_err: ret = -1; goto out; } @@ -4108,6 +4184,7 @@ T( [CMD_UNMOUNT] = T( " %"TS" DIRECTORY [--commit] [--check] [--rebuild] [--lazy]\n" +" [--new-image]\n" ), #endif [CMD_UPDATE] = @@ -4145,8 +4222,8 @@ version(void) { static const tchar *s = T( -IMAGEX_PROGNAME " (" PACKAGE ") " PACKAGE_VERSION "\n" -"Copyright (C) 2012, 2013 Eric Biggers\n" +IMAGEX_PROGNAME " (distributed with " PACKAGE " " PACKAGE_VERSION ")\n" +"Copyright (C) 2012, 2013, 2014 Eric Biggers\n" "License GPLv3+; GNU GPL version 3 or later .\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"