Module: wine Branch: master Commit: a98319d0c58cc448b14037cae32d042adfedd94d URL: https://gitlab.winehq.org/wine/wine/-/commit/a98319d0c58cc448b14037cae32d042...
Author: Paul Gofman pgofman@codeweavers.com Date: Wed Jan 11 12:32:58 2023 -0600
ntdll: Do not use extended context in RtlCopyContext() if extended state is not copied.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54289
---
dlls/ntdll/exception.c | 12 ++++++++++-- dlls/ntdll/tests/exception.c | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index fa30118f142..556b424ac6e 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -994,6 +994,7 @@ NTSTATUS WINAPI RtlCopyContext( CONTEXT *dst, DWORD context_flags, CONTEXT *src { DWORD context_size, arch_flag, flags_offset, dst_flags, src_flags; static const DWORD arch_mask = CONTEXT_i386 | CONTEXT_AMD64; + const struct context_parameters *p; BYTE *d, *s;
TRACE("dst %p, context_flags %#lx, src %p.\n", dst, context_flags, src); @@ -1026,8 +1027,15 @@ NTSTATUS WINAPI RtlCopyContext( CONTEXT *dst, DWORD context_flags, CONTEXT *src context_flags &= src_flags; if (context_flags & ~dst_flags & 0x40) return STATUS_BUFFER_OVERFLOW;
- return RtlCopyExtendedContext( (CONTEXT_EX *)(d + context_size), context_flags, - (CONTEXT_EX *)(s + context_size) ); + if (context_flags & 0x40) + return RtlCopyExtendedContext( (CONTEXT_EX *)(d + context_size), context_flags, + (CONTEXT_EX *)(s + context_size) ); + + if (!(p = context_get_parameters( context_flags ))) + return STATUS_INVALID_PARAMETER; + + context_copy_ranges( d, context_flags, s, p ); + return STATUS_SUCCESS; }
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index a09beee2203..94b2ccf61a6 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -10499,6 +10499,26 @@ static void test_copy_context(void)
enabled_features = pRtlGetEnabledExtendedFeatures(~(ULONG64)0);
+ memset(dst_context_buffer, 0xdd, sizeof(dst_context_buffer)); + memset(src_context_buffer, 0xcc, sizeof(src_context_buffer)); + + status = pRtlInitializeExtendedContext(src_context_buffer, CONTEXT_ALL | CONTEXT_XSTATE, &src_ex); + if (!status) + { + src = pRtlLocateLegacyContext(src_ex, NULL); + dst = (CONTEXT *)dst_context_buffer; + dst->ContextFlags = CONTEXT_ALL; + status = pRtlCopyContext(dst, dst->ContextFlags, src); + ok(!status, "Got status %#lx.\n", status); + check_changes_in_range((BYTE *)dst, CONTEXT_ALL & CONTEXT_AMD64 ? &ranges_amd64[0] : &ranges_x86[0], + CONTEXT_ALL, sizeof(CONTEXT)); + } + else + { + ok(status == STATUS_NOT_SUPPORTED, "Got status %#lx.\n", status); + skip("Extended context is not supported.\n"); + } + for (i = 0; i < ARRAY_SIZE(tests); ++i) { flags = tests[i];