]> wimlib.net Git - wimlib/commitdiff
wimlib-imagex: Add --wimboot options
authorEric Biggers <ebiggers3@gmail.com>
Fri, 18 Apr 2014 06:00:48 +0000 (01:00 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Fri, 18 Apr 2014 06:23:11 +0000 (01:23 -0500)
doc/imagex-apply.1.in
doc/imagex-capture.1.in
doc/imagex-extract.1.in
programs/imagex.c

index ab9efcd0fbe7acb503a5ddf329fd4ea3e4100af4..e869174d10ba87c85e4f5bb6230493a457622823 100644 (file)
@@ -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.
 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
 .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
index 25212292072f4f2f3aa227146a57c9997de3a2fd..a6d93b0ad585a0e7a621e1c147670f68a42f5738 100644 (file)
@@ -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
 .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
 \fIWIMFILE\fRs.
 .IP ""
 To operate on the resulting delta WIM using other commands such as
index e8cdb52e4401af8b6c9c05fc80be5f8188ff50b5..309430b8d4569d39577bfb5c8274f7839b1b8ffa 100644 (file)
@@ -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.
 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.
 .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.
index 6a95b0411a33dc9767d9ff1679a845bb47ba1761..e80d3e6ce6aecd111d98e216e27c469ae0092a2e 100644 (file)
@@ -198,6 +198,7 @@ enum {
        IMAGEX_UNIX_DATA_OPTION,
        IMAGEX_UPDATE_OF_OPTION,
        IMAGEX_VERBOSE_OPTION,
        IMAGEX_UNIX_DATA_OPTION,
        IMAGEX_UPDATE_OF_OPTION,
        IMAGEX_VERBOSE_OPTION,
+       IMAGEX_WIMBOOT_OPTION,
        IMAGEX_XML_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},
 
        /* --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},
 };
 
        {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("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},
 };
 
        {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("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},
 };
 
        {NULL, 0, NULL, 0},
 };
 
@@ -413,6 +417,17 @@ imagex_error(const tchar *format, ...)
        va_end(va);
 }
 
        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, ...)
 /* 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 (;;) {
 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;
                        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 {
                         "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;
                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);
        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) {
                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');
                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;
                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_RESUME_OPTION:
                        extract_flags |= WIMLIB_EXTRACT_FLAG_RESUME;
                        break;
+               case IMAGEX_WIMBOOT_OPTION:
+                       extract_flags |= WIMLIB_EXTRACT_FLAG_WIMBOOT;
+                       break;
                default:
                        goto out_usage;
                }
                default:
                        goto out_usage;
                }
@@ -1820,7 +1841,7 @@ imagex_capture_or_append(int argc, tchar **argv, int cmd)
        tchar *source;
        tchar *source_copy;
 
        tchar *source;
        tchar *source_copy;
 
-       const tchar *config_file = NULL;
+       tchar *config_file = NULL;
        tchar *config_str;
        struct wimlib_capture_config *config;
 
        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;
                                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;
                }
                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) {
 
 
        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,
-                                                            &params.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,
+                                                                    &params.hdr);
+                       }
                }
                }
+
        }
 
        if (compress_slow)
                set_compress_slow();
 
        }
 
        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
        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;
                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);
        }
        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_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;
                }
                default:
                        goto out_usage;
                }