]> wimlib.net Git - wimlib/blobdiff - src/win32_apply.c
configure.ac: generate version number from git commit and tags
[wimlib] / src / win32_apply.c
index 1434bd22d8d656969d03cc1fe829538199d77096..a1301d646290f4d8671428119698e3a41871e619 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (C) 2013-2018 Eric Biggers
+ * Copyright (C) 2013-2021 Eric Biggers
  *
  * This file is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License as published by the Free
@@ -244,14 +244,6 @@ get_vol_flags(const wchar_t *target, DWORD *vol_flags_ret,
        }
 }
 
-/* Is the image being extracted an OS image for Windows 10 or later?  */
-static bool
-is_image_windows_10_or_later(struct win32_apply_ctx *ctx)
-{
-       /* Note: if no build number is available, this returns false.  */
-       return ctx->windows_build_number >= 10240;
-}
-
 static const wchar_t *
 current_path(struct win32_apply_ctx *ctx);
 
@@ -415,10 +407,10 @@ load_prepopulate_pats(struct win32_apply_ctx *ctx)
        sec.name = T("PrepopulateList");
        sec.strings = strings;
 
-       ret = do_load_text_file(path, buf, blob->size, &mem, &sec, 1,
-                               LOAD_TEXT_FILE_REMOVE_QUOTES |
-                                       LOAD_TEXT_FILE_NO_WARNINGS,
-                               mangle_pat);
+       ret = load_text_file(path, buf, blob->size, &mem, &sec, 1,
+                            LOAD_TEXT_FILE_REMOVE_QUOTES |
+                            LOAD_TEXT_FILE_NO_WARNINGS,
+                            mangle_pat);
        STATIC_ASSERT(OS_PREFERRED_PATH_SEPARATOR == WIM_PATH_SEPARATOR);
        FREE(buf);
        if (ret) {
@@ -437,7 +429,8 @@ can_externally_back_path(const wchar_t *path, const struct win32_apply_ctx *ctx)
 {
        /* Does the path match a pattern given in the [PrepopulateList] section
         * of WimBootCompress.ini?  */
-       if (ctx->prepopulate_pats && match_pattern_list(path, ctx->prepopulate_pats))
+       if (ctx->prepopulate_pats && match_pattern_list(path, ctx->prepopulate_pats,
+                                                       MATCH_RECURSIVELY))
                return false;
 
        /* Since we attempt to modify the SYSTEM registry after it's extracted
@@ -449,7 +442,7 @@ can_externally_back_path(const wchar_t *path, const struct win32_apply_ctx *ctx)
         * However, a WIM that wasn't specifically captured in "WIMBoot mode"
         * may contain SYSTEM.* files.  So to make things "just work", hard-code
         * the pattern.  */
-       if (match_path(path, L"\\Windows\\System32\\config\\SYSTEM*", false))
+       if (match_path(path, L"\\Windows\\System32\\config\\SYSTEM*", 0))
                return false;
 
        return true;
@@ -1093,7 +1086,7 @@ prepare_target(struct list_head *dentry_list, struct win32_apply_ctx *ctx)
 
        path_max = compute_path_max(dentry_list);
        /* Add some extra for building Win32 paths for the file encryption APIs,
-        * and ensure we have at least enough to potentially use a 8.3 name for
+        * and ensure we have at least enough to potentially use an 8.3 name for
         * the last component.  */
        path_max += max(2 + (ctx->target_ntpath.Length / sizeof(wchar_t)),
                        8 + 1 + 3);
@@ -2431,15 +2424,15 @@ static int
 get_system_compression_format(int extract_flags)
 {
        if (extract_flags & WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS4K)
-               return FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS4K;
+               return FILE_PROVIDER_COMPRESSION_XPRESS4K;
 
        if (extract_flags & WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS8K)
-               return FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS8K;
+               return FILE_PROVIDER_COMPRESSION_XPRESS8K;
 
        if (extract_flags & WIMLIB_EXTRACT_FLAG_COMPACT_XPRESS16K)
-               return FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS16K;
+               return FILE_PROVIDER_COMPRESSION_XPRESS16K;
 
-       return FILE_PROVIDER_COMPRESSION_FORMAT_LZX;
+       return FILE_PROVIDER_COMPRESSION_LZX;
 }
 
 
@@ -2447,11 +2440,11 @@ static const wchar_t *
 get_system_compression_format_string(int format)
 {
        switch (format) {
-       case FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS4K:
+       case FILE_PROVIDER_COMPRESSION_XPRESS4K:
                return L"XPRESS4K";
-       case FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS8K:
+       case FILE_PROVIDER_COMPRESSION_XPRESS8K:
                return L"XPRESS8K";
-       case FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS16K:
+       case FILE_PROVIDER_COMPRESSION_XPRESS16K:
                return L"XPRESS16K";
        default:
                return L"LZX";
@@ -2463,16 +2456,16 @@ set_system_compression(HANDLE h, int format)
 {
        NTSTATUS status;
        struct {
-               struct wof_external_info wof_info;
-               struct file_provider_external_info file_info;
+               WOF_EXTERNAL_INFO wof_info;
+               FILE_PROVIDER_EXTERNAL_INFO_V1 file_info;
        } in = {
                .wof_info = {
-                       .version = WOF_CURRENT_VERSION,
-                       .provider = WOF_PROVIDER_FILE,
+                       .Version = WOF_CURRENT_VERSION,
+                       .Provider = WOF_PROVIDER_FILE,
                },
                .file_info = {
-                       .version = FILE_PROVIDER_CURRENT_VERSION,
-                       .compression_format = format,
+                       .Version = FILE_PROVIDER_CURRENT_VERSION,
+                       .Algorithm = format,
                },
        };
 
@@ -2529,6 +2522,22 @@ static const struct string_list bootloader_patterns = {
        .num_strings = ARRAY_LEN(bootloader_pattern_strings),
 };
 
+/* Returns true if the specified system compression format is supported by the
+ * bootloader of the image being applied.  */
+static bool
+bootloader_supports_compression_format(struct win32_apply_ctx *ctx, int format)
+{
+       /* Windows 10 and later support XPRESS4K */
+       if (format == FILE_PROVIDER_COMPRESSION_XPRESS4K)
+               return ctx->windows_build_number >= 10240;
+
+       /*
+        * Windows 10 version 1903 and later support the other formats;
+        * see https://wimlib.net/forums/viewtopic.php?f=1&t=444
+        */
+       return ctx->windows_build_number >= 18362;
+}
+
 static NTSTATUS
 set_system_compression_on_inode(struct wim_inode *inode, int format,
                                struct win32_apply_ctx *ctx)
@@ -2538,12 +2547,8 @@ set_system_compression_on_inode(struct wim_inode *inode, int format,
        HANDLE h;
 
        /* If it may be needed for compatibility with the Windows bootloader,
-        * force this file to XPRESS4K or uncompressed format.  The bootloader
-        * of Windows 10 supports XPRESS4K only; older versions don't support
-        * system compression at all.  */
-       if (!is_image_windows_10_or_later(ctx) ||
-           format != FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS4K)
-       {
+        * force this file to XPRESS4K or uncompressed format.  */
+       if (!bootloader_supports_compression_format(ctx, format)) {
                /* We need to check the patterns against every name of the
                 * inode, in case any of them match.  */
                struct wim_dentry *dentry;
@@ -2557,7 +2562,8 @@ set_system_compression_on_inode(struct wim_inode *inode, int format,
                        }
 
                        incompatible = match_pattern_list(dentry->d_full_path,
-                                                         &bootloader_patterns);
+                                                         &bootloader_patterns,
+                                                         MATCH_RECURSIVELY);
                        FREE(dentry->d_full_path);
                        dentry->d_full_path = NULL;
 
@@ -2566,7 +2572,9 @@ set_system_compression_on_inode(struct wim_inode *inode, int format,
 
                        warned = (ctx->num_system_compression_exclusions++ > 0);
 
-                       if (is_image_windows_10_or_later(ctx)) {
+                       if (bootloader_supports_compression_format(ctx,
+                                  FILE_PROVIDER_COMPRESSION_XPRESS4K))
+                       {
                                /* Force to XPRESS4K  */
                                if (!warned) {
                                        WARNING("For compatibility with the "
@@ -2578,7 +2586,7 @@ set_system_compression_on_inode(struct wim_inode *inode, int format,
                                                "          you requested.",
                                                get_system_compression_format_string(format));
                                }
-                               format = FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS4K;
+                               format = FILE_PROVIDER_COMPRESSION_XPRESS4K;
                                break;
                        } else {
                                /* Force to uncompressed  */