From: Eric Biggers Date: Fri, 18 Apr 2014 06:00:48 +0000 (-0500) Subject: wimlib-imagex: Add --wimboot options X-Git-Tag: v1.7.0~289 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=7dba3a8ea5918399518f350c3071f986cf1d050a wimlib-imagex: Add --wimboot options --- diff --git a/doc/imagex-apply.1.in b/doc/imagex-apply.1.in index ab9efcd0..e869174d 100644 --- a/doc/imagex-apply.1.in +++ b/doc/imagex-apply.1.in @@ -392,6 +392,13 @@ default, invalid names will be ignored, and if there are multiple names differing only in case, one will be chosen to extract arbitrarily; however, with \fB--include-invalid-names\fR, all names will be sanitized and extracted in some form. +.TP +\fB--wimboot\fR +Windows only: Instead of extracting the files themselves, extract "pointer +files" back to the original WIM. This is only expected to work on Windows 8.1 +and later, since only those versions of Windows contain the Windows Overlay File +System Filter Driver that is necessary for this feature. See Microsoft's +documentation for "WIMBoot" for more information. .SH NOTES \fIData integrity\fR: WIM files include SHA1 message digests for file data. \fB@IMAGEX_PROGNAME@ apply\fR calculates the SHA1 message digest of every file diff --git a/doc/imagex-capture.1.in b/doc/imagex-capture.1.in index 25212292..a6d93b0a 100644 --- a/doc/imagex-capture.1.in +++ b/doc/imagex-capture.1.in @@ -485,6 +485,16 @@ metadata, but this is typically only a small fraction of a WIM's total size. .IP "" This option can be specified multiple times, in which case the resulting delta WIM will only contain streams not present in any of the specified base +.TP +\fB--wimboot\fR +Windows only: mark the image as WIMBoot-compatible. See Microsoft's +documentation for more information about WIMBoot. This option will, by default, +change the compression type to XPRESS and the chunk size to 4096 bytes; these +can, however, still be overridden through the \fB--compress\fR and +\fB--chunk-size\fR parameters, respectively. In addition, this option will, by +default, set the configuration file to +\fISOURCE\fR\\Windows\\System32\\WimBootCompress.ini if present and accessible; +however, this may still be overridden through the \fB--config\fR parameter. \fIWIMFILE\fRs. .IP "" To operate on the resulting delta WIM using other commands such as diff --git a/doc/imagex-extract.1.in b/doc/imagex-extract.1.in index e8cdb52e..309430b8 100644 --- a/doc/imagex-extract.1.in +++ b/doc/imagex-extract.1.in @@ -140,6 +140,9 @@ extracting the file or directory tree named by each path directly to the destination directory. Note: \fB--preserve-dir-structure\fR is already the default behavior for paths in listfiles, but not paths directly specified on the command line. +.TP +\fB--wimboot\fR +See the documentation for this option in \fB@IMAGEX_PROGNAME@-apply\fR (1). .SH NOTES See the documentation \fB@IMAGEX_PROGNAME@ apply\fR (1) for documentation about what data and metadata are extracted on UNIX-like systems versus on Windows. diff --git a/programs/imagex.c b/programs/imagex.c index 6a95b041..e80d3e6c 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -198,6 +198,7 @@ enum { IMAGEX_UNIX_DATA_OPTION, IMAGEX_UPDATE_OF_OPTION, IMAGEX_VERBOSE_OPTION, + IMAGEX_WIMBOOT_OPTION, IMAGEX_XML_OPTION, }; @@ -218,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}, }; @@ -250,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}, }; @@ -301,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}, }; @@ -413,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, ...) @@ -714,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; @@ -856,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; @@ -894,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) { @@ -941,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; @@ -1665,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; } @@ -1820,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; @@ -1941,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; } @@ -1958,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 @@ -2113,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); @@ -3009,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; }