Commit 81a08cea authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

kernel32: Implement CopyContext().

parent 85a33ff7
@ stub RtlCopyExtendedContext
@ stdcall RtlCopyExtendedContext(ptr long ptr) ntdll.RtlCopyExtendedContext
@ stdcall RtlGetEnabledExtendedFeatures(int64) ntdll.RtlGetEnabledExtendedFeatures
@ stdcall RtlGetExtendedContextLength(long ptr) ntdll.RtlGetExtendedContextLength
@ stdcall -ret64 RtlGetExtendedFeaturesMask(ptr) ntdll.RtlGetExtendedFeaturesMask
......
@ stub CopyContext
@ stdcall -arch=i386,x86_64 CopyContext(ptr long ptr) kernel32.CopyContext
@ stdcall -ret64 -arch=i386,x86_64 GetEnabledXStateFeatures() kernel32.GetEnabledXStateFeatures
@ stdcall -arch=i386,x86_64 GetXStateFeaturesMask(ptr ptr) kernel32.GetXStateFeaturesMask
@ stdcall -arch=i386,x86_64 InitializeContext(ptr long ptr ptr) kernel32.InitializeContext
......
......@@ -256,7 +256,7 @@
@ stdcall -import ConvertThreadToFiber(ptr)
@ stdcall -import ConvertThreadToFiberEx(ptr long)
@ stdcall ConvertToGlobalHandle(long)
# @ stub CopyContext
@ stdcall -import -arch=i386,x86_64 CopyContext(ptr long ptr)
@ stdcall CopyFileA(str str long)
@ stdcall CopyFileExA (str str ptr ptr ptr long)
@ stdcall -import CopyFileExW(wstr wstr ptr ptr ptr long)
......
......@@ -165,7 +165,7 @@
@ stdcall ConvertThreadToFiber(ptr)
@ stdcall ConvertThreadToFiberEx(ptr long)
@ stdcall ConvertToAutoInheritPrivateObjectSecurity(ptr ptr ptr ptr long ptr)
# @ stub CopyContext
@ stdcall -arch=i386,x86_64 CopyContext(ptr long ptr)
# @ stub CopyFile2
@ stdcall CopyFileExW(wstr wstr ptr ptr ptr long)
@ stdcall CopyFileW(wstr wstr long)
......
......@@ -1233,6 +1233,62 @@ BOOL WINAPI InitializeContext( void *buffer, DWORD context_flags, CONTEXT **cont
{
return InitializeContext2( buffer, context_flags, context, length, ~(ULONG64)0 );
}
/***********************************************************************
* CopyContext (kernelbase.@)
*/
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;
}
#endif
......
......@@ -666,6 +666,24 @@ ULONG64 WINAPI RtlGetEnabledExtendedFeatures(ULONG64 feature_mask)
return user_shared_data->XState.EnabledFeatures & feature_mask;
}
struct context_copy_range
{
ULONG start;
ULONG flag;
};
static const struct context_copy_range copy_ranges_amd64[] =
{
{0x38, 0x1}, {0x3a, 0x4}, { 0x42, 0x1}, { 0x48, 0x10}, { 0x78, 0x2}, { 0x98, 0x1},
{0xa0, 0x2}, {0xf8, 0x1}, {0x100, 0x8}, {0x2a0, 0}, {0x4b0, 0x10}, {0x4d0, 0}
};
static const struct context_copy_range copy_ranges_x86[] =
{
{ 0x4, 0x10}, {0x1c, 0x8}, {0x8c, 0x4}, {0x9c, 0x2}, {0xb4, 0x1}, {0xcc, 0x20}, {0x1ec, 0},
{0x2cc, 0},
};
static const struct context_parameters
{
ULONG arch_flag;
......@@ -676,11 +694,12 @@ static const struct context_parameters
ULONG alignment; /* Used when computing size of context. */
ULONG true_alignment; /* Used for actual alignment. */
ULONG flags_offset;
const struct context_copy_range *copy_ranges;
}
arch_context_paramaters[] =
{
{0x00100000, 0xd810005f, 0x4d0, 0x4d0, 0x20, 7, 0xf, 0x30},
{0x00010000, 0xd801007f, 0x2cc, 0xcc, 0x18, 3, 0x3, 0},
{0x00100000, 0xd810005f, 0x4d0, 0x4d0, 0x20, 7, 0xf, 0x30, copy_ranges_amd64},
{0x00010000, 0xd801007f, 0x2cc, 0xcc, 0x18, 3, 0x3, 0, copy_ranges_x86},
};
static const struct context_parameters *context_get_parameters( ULONG context_flags )
......@@ -882,3 +901,65 @@ ULONG64 WINAPI RtlGetExtendedFeaturesMask( CONTEXT_EX *context_ex )
return xs->Mask & ~(ULONG64)3;
}
/**********************************************************************
* RtlCopyExtendedContext (NTDLL.@)
*/
NTSTATUS WINAPI RtlCopyExtendedContext( CONTEXT_EX *dst, ULONG context_flags, CONTEXT_EX *src )
{
const struct context_copy_range *range;
const struct context_parameters *p;
XSTATE *dst_xs, *src_xs;
ULONG64 feature_mask;
unsigned int start;
BYTE *d, *s;
TRACE( "dst %p, context_flags %#x, src %p.\n", dst, context_flags, src );
if (!(p = context_get_parameters( context_flags )))
return STATUS_INVALID_PARAMETER;
if (!(feature_mask = RtlGetEnabledExtendedFeatures( ~(ULONG64)0 )) && context_flags & 0x40)
return STATUS_NOT_SUPPORTED;
d = RtlLocateLegacyContext( dst, NULL );
s = RtlLocateLegacyContext( src, NULL );
*((ULONG *)(d + p->flags_offset)) |= context_flags;
start = 0;
range = p->copy_ranges;
do
{
if (range->flag & context_flags)
{
if (!start)
start = range->start;
}
else if (start)
{
memcpy( d + start, s + start, range->start - start );
start = 0;
}
}
while (range++->start != p->context_size);
if (!(context_flags & 0x40))
return STATUS_SUCCESS;
if (dst->XState.Length < offsetof(XSTATE, YmmContext))
return STATUS_BUFFER_OVERFLOW;
dst_xs = (XSTATE *)((BYTE *)dst + dst->XState.Offset);
src_xs = (XSTATE *)((BYTE *)src + src->XState.Offset);
memset(dst_xs, 0, offsetof(XSTATE, YmmContext));
dst_xs->Mask = (src_xs->Mask & ~(ULONG64)3) & feature_mask;
dst_xs->CompactionMask = user_shared_data->XState.CompactionEnabled
? ((ULONG64)1 << 63) | (src_xs->CompactionMask & feature_mask) : 0;
if (dst_xs->Mask & 4 && src->XState.Length >= sizeof(XSTATE) && dst->XState.Length >= sizeof(XSTATE))
memcpy( &dst_xs->YmmContext, &src_xs->YmmContext, sizeof(dst_xs->YmmContext) );
return STATUS_SUCCESS;
}
......@@ -525,6 +525,7 @@
@ stub RtlConvertUiListToApiList
@ stdcall -arch=win32 -ret64 RtlConvertUlongToLargeInteger(long)
# @ stub RtlConvertVariantToProperty
@ stdcall RtlCopyExtendedContext(ptr long ptr)
@ stdcall RtlCopyLuid(ptr ptr)
@ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr)
@ stdcall -arch=x86_64 RtlCopyMemory(ptr ptr long)
......
......@@ -1010,6 +1010,7 @@
@ stdcall -arch=win32 -ret64 RtlConvertLongToLargeInteger(long)
@ stdcall RtlConvertSidToUnicodeString(ptr ptr long)
@ stdcall -arch=win32 -ret64 RtlConvertUlongToLargeInteger(long)
@ stdcall RtlCopyExtendedContext(ptr long ptr)
@ stdcall RtlCopyLuid(ptr ptr)
@ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr)
@ stdcall -arch=x86_64 RtlCopyMemory(ptr ptr long)
......
......@@ -1837,6 +1837,7 @@ BOOLEAN WINAPI PsGetVersion(ULONG*,ULONG*,ULONG*,UNICODE_STRING*);
NTSTATUS WINAPI PsTerminateSystemThread(NTSTATUS);
#if defined(__x86_64__) || defined(__i386__)
NTSTATUS WINAPI RtlCopyExtendedContext(CONTEXT_EX*,ULONG,CONTEXT_EX*);
NTSTATUS WINAPI RtlInitializeExtendedContext(void*,ULONG,CONTEXT_EX**);
NTSTATUS WINAPI RtlInitializeExtendedContext2(void*,ULONG,CONTEXT_EX**,ULONG64);
ULONG64 WINAPI RtlGetEnabledExtendedFeatures(ULONG64);
......
......@@ -1827,6 +1827,7 @@ WINBASEAPI BOOL WINAPI CommConfigDialogW(LPCWSTR,HWND,LPCOMMCONFIG);
WINBASEAPI BOOL WINAPI ConnectNamedPipe(HANDLE,LPOVERLAPPED);
WINBASEAPI BOOL WINAPI ContinueDebugEvent(DWORD,DWORD,DWORD);
WINBASEAPI HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc);
WINBASEAPI BOOL WINAPI CopyContext(CONTEXT*, DWORD, CONTEXT*);
WINBASEAPI BOOL WINAPI CopyFileA(LPCSTR,LPCSTR,BOOL);
WINBASEAPI BOOL WINAPI CopyFileW(LPCWSTR,LPCWSTR,BOOL);
#define CopyFile WINELIB_NAME_AW(CopyFile)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment