X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fwin32_apply.c;h=d9bf63c2fd305b93cf932b1bbff9d0dc996f8c83;hp=d3534643115e86b93c63f0460cb6e4ed7eb0b6dc;hb=8a1b5f46145cc8be56ce09eec1513db079b86bc7;hpb=51829aecdac415b417ab5b8ac897014bb780de10 diff --git a/src/win32_apply.c b/src/win32_apply.c index d3534643..d9bf63c2 100644 --- a/src/win32_apply.c +++ b/src/win32_apply.c @@ -30,7 +30,6 @@ #include "wimlib/apply.h" #include "wimlib/assert.h" #include "wimlib/blob_table.h" -#include "wimlib/capture.h" /* for mangle_pat() and match_pattern_list() */ #include "wimlib/dentry.h" #include "wimlib/encoding.h" #include "wimlib/error.h" @@ -39,6 +38,7 @@ #include "wimlib/paths.h" #include "wimlib/pattern.h" #include "wimlib/reparse.h" +#include "wimlib/scan.h" /* for mangle_pat() and match_pattern_list() */ #include "wimlib/textfile.h" #include "wimlib/xml.h" #include "wimlib/wimboot.h" @@ -69,7 +69,7 @@ struct win32_apply_ctx { } wimboot; /* External backing information */ - struct string_set *prepopulate_pats; + struct string_list *prepopulate_pats; void *mem_prepopulate_pats; bool tried_to_load_prepopulate_list; @@ -338,7 +338,7 @@ load_prepopulate_pats(struct win32_apply_ctx *ctx) const struct blob_descriptor *blob; int ret; void *buf; - struct string_set *s; + struct string_list *strings; void *mem; struct text_file_section sec; @@ -366,14 +366,14 @@ load_prepopulate_pats(struct win32_apply_ctx *ctx) if (ret) return ret; - s = CALLOC(1, sizeof(struct string_set)); - if (!s) { + strings = CALLOC(1, sizeof(struct string_list)); + if (!strings) { FREE(buf); return WIMLIB_ERR_NOMEM; } sec.name = T("PrepopulateList"); - sec.strings = s; + sec.strings = strings; ret = do_load_text_file(path, buf, blob->size, &mem, &sec, 1, LOAD_TEXT_FILE_REMOVE_QUOTES | @@ -382,10 +382,10 @@ load_prepopulate_pats(struct win32_apply_ctx *ctx) STATIC_ASSERT(OS_PREFERRED_PATH_SEPARATOR == WIM_PATH_SEPARATOR); FREE(buf); if (ret) { - FREE(s); + FREE(strings); return ret; } - ctx->prepopulate_pats = s; + ctx->prepopulate_pats = strings; ctx->mem_prepopulate_pats = mem; return 0; } @@ -1010,8 +1010,7 @@ open_target_directory(struct win32_apply_ctx *ctx) 0, FILE_SHARE_VALID_FLAGS, FILE_OPEN_IF, - FILE_DIRECTORY_FILE | - FILE_OPEN_FOR_BACKUP_INTENT, + FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0); if (!NT_SUCCESS(status)) { @@ -1130,7 +1129,7 @@ adjust_compression_attribute(HANDLE h, const struct wim_dentry *dentry, status = winnt_fsctl(h, FSCTL_SET_COMPRESSION, &compression_state, sizeof(USHORT), NULL, 0, NULL); if (NT_SUCCESS(status)) - return status; + return 0; winnt_error(status, L"Can't %s compression attribute on \"%ls\"", (compressed ? "set" : "clear"), current_path(ctx)); @@ -1472,10 +1471,11 @@ retry: /* * Create a nondirectory file or named data stream at the current path, * superseding any that already exists at that path. If successful, return an - * open handle to the file or named data stream. + * open handle to the file or named data stream with the requested permissions. */ static int -supersede_file_or_stream(struct win32_apply_ctx *ctx, HANDLE *h_ret) +supersede_file_or_stream(struct win32_apply_ctx *ctx, DWORD perms, + HANDLE *h_ret) { NTSTATUS status; bool retried = false; @@ -1484,7 +1484,7 @@ supersede_file_or_stream(struct win32_apply_ctx *ctx, HANDLE *h_ret) * FILE_ATTRIBUTE_ENCRYPTED doesn't get set before we want it to be. */ retry: status = do_create_file(h_ret, - GENERIC_READ | GENERIC_WRITE | DELETE, + perms, NULL, FILE_ATTRIBUTE_SYSTEM, FILE_CREATE, @@ -1596,7 +1596,13 @@ create_empty_streams(const struct wim_dentry *dentry, build_extraction_path_with_ads(dentry, ctx, strm->stream_name, utf16le_len_chars(strm->stream_name)); - ret = supersede_file_or_stream(ctx, &h); + /* + * Note: do not request any permissions on the handle. + * Otherwise, we may encounter a Windows bug where the + * parent directory DACL denies read access to the new + * named data stream, even when using backup semantics! + */ + ret = supersede_file_or_stream(ctx, 0, &h); build_extraction_path(dentry, ctx); @@ -1684,25 +1690,6 @@ retry: sizeof(basic_info), FileBasicInformation); } - - /* Also try to remove the directory's DACL. This isn't supposed - * to be necessary because we *always* use backup semantics. - * However, there is a case where NtCreateFile() fails with - * STATUS_ACCESS_DENIED when creating a named data stream that - * was just deleted, using a directory-relative open. I have no - * idea why Windows is broken in this case. */ - if (!(ctx->common.extract_flags & WIMLIB_EXTRACT_FLAG_NO_ACLS)) { - static const SECURITY_DESCRIPTOR_RELATIVE desc = { - .Revision = SECURITY_DESCRIPTOR_REVISION1, - .Control = SE_SELF_RELATIVE | SE_DACL_PRESENT, - .Owner = 0, - .Group = 0, - .Sacl = 0, - .Dacl = 0, - }; - NtSetSecurityObject(h, DACL_SECURITY_INFORMATION, - (void *)&desc); - } } if (!dentry_is_root(dentry)) { @@ -1772,7 +1759,9 @@ create_nondirectory_inode(HANDLE *h_ret, const struct wim_dentry *dentry, build_extraction_path(dentry, ctx); - ret = supersede_file_or_stream(ctx, &h); + ret = supersede_file_or_stream(ctx, + GENERIC_READ | GENERIC_WRITE | DELETE, + &h); if (ret) goto out; @@ -2437,7 +2426,7 @@ static wchar_t *bootloader_pattern_strings[] = { L"\\Windows\\System32\\CodeIntegrity\\driver.stl", }; -static const struct string_set bootloader_patterns = { +static const struct string_list bootloader_patterns = { .strings = bootloader_pattern_strings, .num_strings = ARRAY_LEN(bootloader_pattern_strings), };