/* Number of files on which we couldn't set System Compression. */
unsigned long num_system_compression_failures;
- /* The number of files on which we used XPRESS4K System Compression
- * rather than a stronger variant, to be compatible with the Windows
- * bootloader. */
- unsigned long num_xpress4k_forced_files;
+ /* The number of files which, for compatibility with the Windows
+ * bootloader, were not compressed using the requested system
+ * compression format. This includes matches with the hardcoded pattern
+ * list only; it does not include matches with patterns in
+ * [PrepopulateList]. */
+ unsigned long num_system_compression_exclusions;
+
+ /* The Windows build number of the image being applied, or 0 if unknown.
+ */
+ u64 windows_build_number;
/* Have we tried to enable short name support on the target volume yet?
*/
}
}
+/* 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);
return status;
}
-/* Hard-coded list of files which the Windows bootloader needs to access before
- * the WOF driver has been loaded. Since the Windows bootloader only supports
- * the XPRESS4K variant of System Compression, such files should not be
- * compressed using other variants. */
-static wchar_t *xpress4k_only_pattern_strings[] = {
+/* Hard-coded list of files which the Windows bootloader may need to access
+ * before the WOF driver has been loaded. */
+static wchar_t *bootloader_pattern_strings[] = {
L"*winload.*",
L"*winresume.*",
L"\\Windows\\AppPatch\\drvmain.sdb",
L"\\Windows\\System32\\CodeIntegrity\\driver.stl",
};
-static const struct string_set xpress4k_only_patterns = {
- .strings = xpress4k_only_pattern_strings,
- .num_strings = ARRAY_LEN(xpress4k_only_pattern_strings),
+static const struct string_set bootloader_patterns = {
+ .strings = bootloader_pattern_strings,
+ .num_strings = ARRAY_LEN(bootloader_pattern_strings),
};
static NTSTATUS
NTSTATUS status;
HANDLE h;
- /* If needed, force the XPRESS4K format for this file. */
- if (format != FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS4K) {
+ /* 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)
+ {
/* We need to check the patterns against every name of the
* inode, in case any of them match. */
struct wim_dentry *dentry;
inode_for_each_extraction_alias(dentry, inode) {
bool incompatible;
+ bool warned;
if (calculate_dentry_full_path(dentry)) {
ERROR("Unable to compute file path!");
}
incompatible = match_pattern_list(dentry->d_full_path,
- &xpress4k_only_patterns);
+ &bootloader_patterns);
FREE(dentry->d_full_path);
dentry->d_full_path = NULL;
- if (incompatible) {
- if (ctx->num_xpress4k_forced_files++ == 0) {
+ if (!incompatible)
+ continue;
+
+ warned = (ctx->num_system_compression_exclusions++ > 0);
+
+ if (is_image_windows_10_or_later(ctx)) {
+ /* Force to XPRESS4K */
+ if (!warned) {
WARNING("For compatibility with the "
"Windows bootloader, some "
"files are being\n"
}
format = FILE_PROVIDER_COMPRESSION_FORMAT_XPRESS4K;
break;
+ } else {
+ /* Force to uncompressed */
+ if (!warned) {
+ WARNING("For compatibility with the "
+ "Windows bootloader, some "
+ "files will not\n"
+ " be compressed with"
+ " system compression "
+ "(\"compacted\").");
+ }
+ return STATUS_SUCCESS;
}
+
}
}
goto out;
}
+ ctx->windows_build_number = wim_info_get_windows_build_number(ctx->common.wim->wim_info,
+ ctx->common.wim->current_image);
+
dentry_count = count_dentries(dentry_list);
ret = start_file_structure_phase(&ctx->common, dentry_count);