diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c index f1ef332a894..847005e8abe 100644 --- a/dlls/kernelbase/memory.c +++ b/dlls/kernelbase/memory.c @@ -1310,55 +1310,7 @@ BOOL WINAPI InitializeContext( void *buffer, DWORD context_flags, CONTEXT **cont */ BOOL WINAPI CopyContext( CONTEXT *dst, DWORD context_flags, CONTEXT *src ) { - DWORD context_size, arch_flag, flags_offset, dst_flags, src_flags; - static const DWORD arch_mask = 0x110000; - NTSTATUS status; - BYTE *d, *s; - - TRACE("dst %p, context_flags %#x, src %p.\n", dst, context_flags, src); - - if (context_flags & 0x40 && !RtlGetEnabledExtendedFeatures( ~(ULONG64)0 )) - { - SetLastError(ERROR_NOT_SUPPORTED); - return FALSE; - } - - arch_flag = context_flags & arch_mask; - - switch (arch_flag) - { - case 0x10000: context_size = 0x2cc; flags_offset = 0; break; - case 0x100000: context_size = 0x4d0; flags_offset = 0x30; break; - default: - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - - d = (BYTE *)dst; - s = (BYTE *)src; - dst_flags = *(DWORD *)(d + flags_offset); - src_flags = *(DWORD *)(s + flags_offset); - - if ((dst_flags & arch_mask) != arch_flag - || (src_flags & arch_mask) != arch_flag) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - - context_flags &= src_flags; - - if (context_flags & ~dst_flags & 0x40) - { - SetLastError(ERROR_MORE_DATA); - return FALSE; - } - - if ((status = RtlCopyExtendedContext( (CONTEXT_EX *)(d + context_size), context_flags, - (CONTEXT_EX *)(s + context_size) ))) - return set_ntstatus( status ); - - return TRUE; + return set_ntstatus( RtlCopyContext( dst, context_flags, src )); } #endif diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index 9e98dcc49c6..3c499c4fa80 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -961,6 +961,50 @@ ULONG64 WINAPI RtlGetExtendedFeaturesMask( CONTEXT_EX *context_ex ) } +/*********************************************************************** + * RtlCopyContext (NTDLL.@) + */ +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; + BYTE *d, *s; + + TRACE("dst %p, context_flags %#x, src %p.\n", dst, context_flags, src); + + if (context_flags & 0x40 && !RtlGetEnabledExtendedFeatures( ~(ULONG64)0 )) return STATUS_NOT_SUPPORTED; + + arch_flag = context_flags & arch_mask; + switch (arch_flag) + { + case CONTEXT_i386: + context_size = sizeof( I386_CONTEXT ); + flags_offset = offsetof( I386_CONTEXT, ContextFlags ); + break; + case CONTEXT_AMD64: + context_size = sizeof( AMD64_CONTEXT ); + flags_offset = offsetof( AMD64_CONTEXT, ContextFlags ); + break; + default: + return STATUS_INVALID_PARAMETER; + } + + d = (BYTE *)dst; + s = (BYTE *)src; + dst_flags = *(DWORD *)(d + flags_offset); + src_flags = *(DWORD *)(s + flags_offset); + + if ((dst_flags & arch_mask) != arch_flag || (src_flags & arch_mask) != arch_flag) + return STATUS_INVALID_PARAMETER; + + 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) ); +} + + /********************************************************************** * RtlCopyExtendedContext (NTDLL.@) */ diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index e2296f7cf27..9113a5d54dc 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -527,6 +527,7 @@ @ stub RtlConvertUiListToApiList @ stdcall -arch=win32 -ret64 RtlConvertUlongToLargeInteger(long) # @ stub RtlConvertVariantToProperty +@ stdcall RtlCopyContext(ptr long ptr) @ stdcall RtlCopyExtendedContext(ptr long ptr) @ stdcall RtlCopyLuid(ptr ptr) @ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr) diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 1b0cfecef3e..ad485b1359e 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -53,6 +53,7 @@ static NTSTATUS (WINAPI *pRtlGetExtendedContextLength2)(ULONG context_flags, UL static NTSTATUS (WINAPI *pRtlInitializeExtendedContext)(void *context, ULONG context_flags, CONTEXT_EX **context_ex); static NTSTATUS (WINAPI *pRtlInitializeExtendedContext2)(void *context, ULONG context_flags, CONTEXT_EX **context_ex, ULONG64 compaction_mask); +static NTSTATUS (WINAPI *pRtlCopyContext)(CONTEXT *dst, DWORD context_flags, CONTEXT *src); static NTSTATUS (WINAPI *pRtlCopyExtendedContext)(CONTEXT_EX *dst, ULONG context_flags, CONTEXT_EX *src); static void * (WINAPI *pRtlLocateExtendedFeature)(CONTEXT_EX *context_ex, ULONG feature_id, ULONG *length); static void * (WINAPI *pRtlLocateLegacyContext)(CONTEXT_EX *context_ex, ULONG *length); @@ -75,7 +76,6 @@ static BOOL (WINAPI *pInitializeContext2)(void *buffer, DWORD context_flags static void * (WINAPI *pLocateXStateFeature)(CONTEXT *context, DWORD feature_id, DWORD *length); static BOOL (WINAPI *pSetXStateFeaturesMask)(CONTEXT *context, DWORD64 feature_mask); static BOOL (WINAPI *pGetXStateFeaturesMask)(CONTEXT *context, DWORD64 *feature_mask); -static BOOL (WINAPI *pCopyContext)(CONTEXT *dst, DWORD context_flags, CONTEXT *src); #define RTL_UNLOAD_EVENT_TRACE_NUMBER 64 @@ -8140,11 +8140,10 @@ static void test_copy_context(void) *(DWORD *)((BYTE *)src + flags_offset) = 0; *(DWORD *)((BYTE *)dst + flags_offset) = 0; SetLastError(0xdeadbeef); - bret = pCopyContext(dst, flags | 0x40, src); - ok((!bret && GetLastError() == (enabled_features ? ERROR_INVALID_PARAMETER : ERROR_NOT_SUPPORTED)) - || broken(!bret && GetLastError() == ERROR_INVALID_PARAMETER), - "Got unexpected bret %#x, GetLastError() %#x, flags %#x.\n", - bret, GetLastError(), flags); + status = pRtlCopyContext(dst, flags | 0x40, src); + ok(status == (enabled_features ? STATUS_INVALID_PARAMETER : STATUS_NOT_SUPPORTED) + || broken(status == STATUS_INVALID_PARAMETER), + "Got unexpected status %#x, flags %#x.\n", status, flags); ok(*(DWORD *)((BYTE *)dst + flags_offset) == 0, "Got unexpected ContextFlags %#x, flags %#x.\n", *(DWORD *)((BYTE *)dst + flags_offset), flags); check_changes_in_range((BYTE *)dst, flags & CONTEXT_AMD64 ? &ranges_amd64[0] : &ranges_x86[0], @@ -8152,19 +8151,15 @@ static void test_copy_context(void) *(DWORD *)((BYTE *)dst + flags_offset) = flags & (CONTEXT_AMD64 | CONTEXT_i386); *(DWORD *)((BYTE *)src + flags_offset) = flags; - SetLastError(0xdeadbeef); - bret = pCopyContext(dst, flags, src); + status = pRtlCopyContext(dst, flags, src); if (flags & 0x40) - ok((!bret && GetLastError() == ERROR_MORE_DATA) - || broken(!(flags & CONTEXT_NATIVE) && !bret && GetLastError() == ERROR_INVALID_PARAMETER), - "Got unexpected bret %#x, GetLastError() %#x, flags %#x.\n", - bret, GetLastError(), flags); + ok((status == STATUS_BUFFER_OVERFLOW) + || broken(!(flags & CONTEXT_NATIVE) && status == STATUS_INVALID_PARAMETER), + "Got unexpected status %#x, flags %#x.\n", status, flags); else - ok((bret && GetLastError() == 0xdeadbeef) - || broken(!(flags & CONTEXT_NATIVE) && !bret && GetLastError() == ERROR_INVALID_PARAMETER), - "Got unexpected bret %#x, GetLastError() %#x, flags %#x.\n", - bret, GetLastError(), flags); - if (bret) + ok(!status || broken(!(flags & CONTEXT_NATIVE) && status == STATUS_INVALID_PARAMETER), + "Got unexpected status %#x, flags %#x.\n", status, flags); + if (!status) { ok(*(DWORD *)((BYTE *)dst + flags_offset) == flags, "Got unexpected ContextFlags %#x, flags %#x.\n", *(DWORD *)((BYTE *)dst + flags_offset), flags); @@ -8315,12 +8310,9 @@ static void test_copy_context(void) memset(&dst_xs->YmmContext, 0xdd, sizeof(dst_xs->YmmContext)); dst_xs->CompactionMask = 0xdddddddddddddddd; dst_xs->Mask = 0xdddddddddddddddd; - SetLastError(0xdeadbeef); - bret = pCopyContext(dst, flags, src); - ok((bret && GetLastError() == 0xdeadbeef) - || broken(!(flags & CONTEXT_NATIVE) && !bret && GetLastError() == ERROR_INVALID_PARAMETER), - "Got unexpected bret %#x, GetLastError() %#x, flags %#x.\n", - bret, GetLastError(), flags); + status = pRtlCopyContext(dst, flags, src); + ok(!status || broken(!(flags & CONTEXT_NATIVE) && status == STATUS_INVALID_PARAMETER), + "Got unexpected status %#x, flags %#x.\n", status, flags); ok(dst_xs->Mask == 0xdddddddddddddddd || broken(dst_xs->Mask == 4), "Got unexpected Mask %s, flags %#x.\n", wine_dbgstr_longlong(dst_xs->Mask), flags); ok(dst_xs->CompactionMask == 0xdddddddddddddddd || broken(dst_xs->CompactionMask == expected_compaction), @@ -8385,6 +8377,7 @@ START_TEST(exception) X(RtlLocateLegacyContext); X(RtlSetExtendedFeaturesMask); X(RtlGetExtendedFeaturesMask); + X(RtlCopyContext); X(RtlCopyExtendedContext); #undef X @@ -8397,7 +8390,6 @@ START_TEST(exception) X(LocateXStateFeature); X(SetXStateFeaturesMask); X(GetXStateFeaturesMask); - X(CopyContext); #undef X if (pRtlAddVectoredExceptionHandler && pRtlRemoveVectoredExceptionHandler) diff --git a/include/winternl.h b/include/winternl.h index 4f2fcc26682..7221c0632b0 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4065,6 +4065,8 @@ NTSYSAPI NTSTATUS WINAPI RtlCompressBuffer(USHORT,PUCHAR,ULONG,PUCHAR,ULONG,ULO NTSYSAPI DWORD WINAPI RtlComputeCrc32(DWORD,const BYTE*,INT); NTSYSAPI NTSTATUS WINAPI RtlConvertSidToUnicodeString(PUNICODE_STRING,PSID,BOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlConvertToAutoInheritSecurityObject(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR*,GUID*,BOOL,PGENERIC_MAPPING); +NTSYSAPI NTSTATUS WINAPI RtlCopyContext(CONTEXT*,DWORD,CONTEXT*); +NTSYSAPI NTSTATUS WINAPI RtlCopyExtendedContext(CONTEXT_EX*,ULONG,CONTEXT_EX*); NTSYSAPI void WINAPI RtlCopyLuid(PLUID,const LUID*); NTSYSAPI void WINAPI RtlCopyLuidAndAttributesArray(ULONG,const LUID_AND_ATTRIBUTES*,PLUID_AND_ATTRIBUTES); NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD,PSID,PSID); @@ -4174,7 +4176,11 @@ NTSYSAPI NTSTATUS WINAPI RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR, NTSYSAPI ULONG WINAPI RtlGetCurrentDirectory_U(ULONG, LPWSTR); NTSYSAPI PEB * WINAPI RtlGetCurrentPeb(void); NTSYSAPI NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,PBOOLEAN,PACL *,PBOOLEAN); +NTSYSAPI ULONG64 WINAPI RtlGetEnabledExtendedFeatures(ULONG64); NTSYSAPI NTSTATUS WINAPI RtlGetExePath(PCWSTR,PWSTR*); +NTSYSAPI NTSTATUS WINAPI RtlGetExtendedContextLength(ULONG,ULONG*); +NTSYSAPI NTSTATUS WINAPI RtlGetExtendedContextLength2(ULONG,ULONG*,ULONG64); +NTSYSAPI ULONG64 WINAPI RtlGetExtendedFeaturesMask(CONTEXT_EX*); NTSYSAPI TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void); NTSYSAPI ULONG WINAPI RtlGetFullPathName_U(PCWSTR,ULONG,PWSTR,PWSTR*); NTSYSAPI NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID *,PBOOLEAN); @@ -4216,6 +4222,8 @@ NTSYSAPI void WINAPI RtlInitializeConditionVariable(RTL_CONDITION_VARIABLE NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSection(RTL_CRITICAL_SECTION *); NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount(RTL_CRITICAL_SECTION *,ULONG); NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionEx(RTL_CRITICAL_SECTION *,ULONG,ULONG); +NTSYSAPI NTSTATUS WINAPI RtlInitializeExtendedContext(void*,ULONG,CONTEXT_EX**); +NTSYSAPI NTSTATUS WINAPI RtlInitializeExtendedContext2(void*,ULONG,CONTEXT_EX**,ULONG64); NTSYSAPI void WINAPI RtlInitializeHandleTable(ULONG,ULONG,RTL_HANDLE_TABLE *); NTSYSAPI void WINAPI RtlInitializeResource(LPRTL_RWLOCK); NTSYSAPI void WINAPI RtlInitializeSRWLock(RTL_SRWLOCK*); @@ -4239,6 +4247,9 @@ NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR); NTSYSAPI DWORD WINAPI RtlLengthSid(PSID); NTSYSAPI NTSTATUS WINAPI RtlLocalTimeToSystemTime(const LARGE_INTEGER*,PLARGE_INTEGER); NTSYSAPI NTSTATUS WINAPI RtlLocaleNameToLcid(const WCHAR*,LCID*,ULONG); +NTSYSAPI void * WINAPI RtlLocateExtendedFeature(CONTEXT_EX*,ULONG,ULONG*); +NTSYSAPI void * WINAPI RtlLocateExtendedFeature2(CONTEXT_EX*,ULONG,XSTATE_CONFIGURATION*,ULONG*); +NTSYSAPI void * WINAPI RtlLocateLegacyContext(CONTEXT_EX*,ULONG*); NTSYSAPI BOOLEAN WINAPI RtlLockHeap(HANDLE); NTSYSAPI NTSTATUS WINAPI RtlLookupAtomInAtomTable(RTL_ATOM_TABLE,const WCHAR*,RTL_ATOM*); NTSYSAPI NTSTATUS WINAPI RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD); @@ -4303,6 +4314,7 @@ NTSYSAPI NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING*); NTSYSAPI void WINAPI RtlSetCurrentEnvironment(PWSTR, PWSTR*); NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,BOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR*,PUNICODE_STRING,PUNICODE_STRING); +NTSYSAPI void WINAPI RtlSetExtendedFeaturesMask(CONTEXT_EX*,ULONG64); NTSYSAPI NTSTATUS WINAPI RtlSetHeapInformation(HANDLE,HEAP_INFORMATION_CLASS,PVOID,SIZE_T); NTSYSAPI NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID,BOOLEAN); @@ -4390,20 +4402,6 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE,WOW64_CONTEXT*); NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*); #endif -#if defined(__x86_64__) || defined(__i386__) -NTSYSAPI NTSTATUS WINAPI RtlCopyExtendedContext(CONTEXT_EX*,ULONG,CONTEXT_EX*); -NTSYSAPI NTSTATUS WINAPI RtlInitializeExtendedContext(void*,ULONG,CONTEXT_EX**); -NTSYSAPI NTSTATUS WINAPI RtlInitializeExtendedContext2(void*,ULONG,CONTEXT_EX**,ULONG64); -NTSYSAPI ULONG64 WINAPI RtlGetEnabledExtendedFeatures(ULONG64); -NTSYSAPI NTSTATUS WINAPI RtlGetExtendedContextLength(ULONG,ULONG*); -NTSYSAPI NTSTATUS WINAPI RtlGetExtendedContextLength2(ULONG,ULONG*,ULONG64); -NTSYSAPI void * WINAPI RtlLocateLegacyContext(CONTEXT_EX*,ULONG*); -NTSYSAPI void * WINAPI RtlLocateExtendedFeature(CONTEXT_EX*,ULONG,ULONG*); -NTSYSAPI void * WINAPI RtlLocateExtendedFeature2(CONTEXT_EX*,ULONG,XSTATE_CONFIGURATION*,ULONG*); -NTSYSAPI ULONG64 WINAPI RtlGetExtendedFeaturesMask(CONTEXT_EX*); -NTSYSAPI void WINAPI RtlSetExtendedFeaturesMask(CONTEXT_EX*,ULONG64); -#endif - #ifndef __WINE_USE_MSVCRT NTSYSAPI int __cdecl _strnicmp(LPCSTR,LPCSTR,size_t); #endif