[PATCH v2 0/4] MR4761: ntdll: Implement NtContinueEx()
This MR implements `NtContinueEx(PCONTEXT, PCONTINUE_OPTIONS)` which was added in Windows 10 20H1. Also added basic test reusing existing `test_continue()` (included from !4720) League of Legends game hooks `NtContinue()` and `NtContinueEx()` by putting `jmp` instruction in front of it. Note that LoL doesn't actually use `NtContinueEx()` itself and game will work fine without it but if game doesn't find `NtContinueEx()` it will permanently ban your account due to detecting "scripting program" -- v2: ntdll/tests: Add basic test for NtContinueEx() ntdll: NtContinueEx() handle few error cases ntdll: Implement NtContinueEx() https://gitlab.winehq.org/wine/wine/-/merge_requests/4761
From: Dāvis Mosāns <davispuh(a)gmail.com> --- dlls/ntdll/tests/exception.c | 163 +++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index bac571b2733..c9223c6108e 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -4413,6 +4413,168 @@ static void test_thread_context(void) #undef COMPARE } +static void test_continue(void) +{ + struct context_pair { + CONTEXT before; + CONTEXT after; + } contexts; + NTSTATUS (*func_ptr)( struct context_pair *, BOOL alertable, void *continue_func, void *capture_func ) = code_mem; + + static const BYTE call_func[] = + { + /* ret at 8*9(rsp) */ + + /* need to preserve these */ + 0x53, /* push %rbx; 8*8(rsp) */ + 0x55, /* push %rbp; 8*7(rsp) */ + 0x56, /* push %rsi; 8*6(rsp) */ + 0x57, /* push %rdi; 8*5(rsp) */ + 0x41, 0x54, /* push %r12; 8*4(rsp) */ + 0x41, 0x55, /* push %r13; 8*3(rsp) */ + 0x41, 0x56, /* push %r14; 8*2(rsp) */ + 0x41, 0x57, /* push %r15; 8*1(rsp) */ + + 0x48, 0x83, 0xec, 0x08, /* sub $0x8, %rsp; reserve space for rsp */ + 0x48, 0x89, 0x24, 0x24, /* %rsp, (%rsp); for stack validation */ + + /* save args */ + 0x48, 0x89, 0x4c, 0x24, 0x50, /* mov %rcx, 8*10(%rsp) */ + 0x48, 0x89, 0x54, 0x24, 0x58, /* mov %rdx, 8*11(%rsp) */ + 0x4c, 0x89, 0x44, 0x24, 0x60, /* mov %r8, 8*12(%rsp) */ + 0x4c, 0x89, 0x4c, 0x24, 0x68, /* mov %r9, 8*13(%rsp) */ + + /* invoke capture context */ + 0x41, 0xff, 0xd1, /* call *%r9 */ + + /* overwrite general registers */ + 0x48, 0xb8, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, /* movabs $0xdeadbeefdeadbeef, %rax */ + 0x48, 0x89, 0xc1, /* mov %rax, %rcx */ + 0x48, 0x89, 0xc2, /* mov %rax, %rdx */ + 0x48, 0x89, 0xc3, /* mov %rax, %rbx */ + 0x48, 0x89, 0xc5, /* mov %rax, %rbp */ + 0x48, 0x89, 0xc6, /* mov %rax, %rsi */ + 0x48, 0x89, 0xc7, /* mov %rax, %rdi */ + 0x49, 0x89, 0xc0, /* mov %rax, %r8 */ + 0x49, 0x89, 0xc1, /* mov %rax, %r9 */ + 0x49, 0x89, 0xc2, /* mov %rax, %r10 */ + 0x49, 0x89, 0xc3, /* mov %rax, %r11 */ + 0x49, 0x89, 0xc4, /* mov %rax, %r12 */ + 0x49, 0x89, 0xc5, /* mov %rax, %r13 */ + 0x49, 0x89, 0xc6, /* mov %rax, %r14 */ + 0x49, 0x89, 0xc7, /* mov %rax, %r15 */ + + /* overwrite SSE registers */ + 0x66, 0x48, 0x0f, 0x6e, 0xc0, /* movq %rax, %xmm0 */ + 0x66, 0x0f, 0x6c, 0xc0, /* punpcklqdq %xmm0, %xmm0; extend to high quadword */ + 0x0f, 0x28, 0xc8, /* movaps %xmm0, %xmm1 */ + 0x0f, 0x28, 0xd0, /* movaps %xmm0, %xmm2 */ + 0x0f, 0x28, 0xd8, /* movaps %xmm0, %xmm3 */ + 0x0f, 0x28, 0xe0, /* movaps %xmm0, %xmm4 */ + 0x0f, 0x28, 0xe8, /* movaps %xmm0, %xmm5 */ + 0x0f, 0x28, 0xf0, /* movaps %xmm0, %xmm6 */ + 0x0f, 0x28, 0xf8, /* movaps %xmm0, %xmm7 */ + 0x44, 0x0f, 0x28, 0xc0, /* movaps %xmm0, %xmm8 */ + 0x44, 0x0f, 0x28, 0xc8, /* movaps %xmm0, %xmm9 */ + 0x44, 0x0f, 0x28, 0xd0, /* movaps %xmm0, %xmm10 */ + 0x44, 0x0f, 0x28, 0xd8, /* movaps %xmm0, %xmm11 */ + 0x44, 0x0f, 0x28, 0xe0, /* movaps %xmm0, %xmm12 */ + 0x44, 0x0f, 0x28, 0xe8, /* movaps %xmm0, %xmm13 */ + 0x44, 0x0f, 0x28, 0xf0, /* movaps %xmm0, %xmm14 */ + 0x44, 0x0f, 0x28, 0xf8, /* movaps %xmm0, %xmm15 */ + + /* FIXME: overwrite debug, x87 FPU and AVX registers to test those */ + + /* load args */ + 0x48, 0x8b, 0x4c, 0x24, 0x50, /* mov 8*10(%rsp), %rcx; context */ + 0x48, 0x8b, 0x54, 0x24, 0x58, /* mov 8*11(%rsp), %rdx; alertable */ + 0x48, 0x83, 0xec, 0x70, /* sub $0x70, %rsp; change stack */ + + /* setup context to return to label 1 */ + 0x48, 0x8d, 0x05, 0x18, 0x00, 0x00, 0x00, /* lea 0x18(%rip) */ + 0x48, 0x89, 0x81, 0xf8, 0x00, 0x00, 0x00, /* mov %rax, 0xf8(%rcx); context.Rip */ + + /* flip some EFLAGS */ + 0x9c, /* pushf */ + /* + 0x0001 Carry flag + 0x0004 Parity flag + 0x0010 Auxiliary Carry flag + 0x0040 Zero flag + 0x0080 Sign flag + FIXME: 0x0400 Direction flag - not changing as it breaks Wine + 0x0800 Overflow flag + ~0x4000~ Nested task flag - not changing - breaks Wine + = 0x8d5 + */ + 0x48, 0x81, 0x34, 0x24, 0xd5, 0x08, 0x00, 0x00, /* xorq $0x8d5, (%rsp) */ + 0x9d, /* popf */ + + /* invoke NtContinue... */ + 0xff, 0x94, 0x24, 0xd0, 0x00, 0x00, 0x00, /* call *8*12+0x70(%rsp) */ + + /* validate stack pointer */ + 0x48, 0x8b, 0x0c, 0x24, /* 1: (%rsp), %rcx */ + 0x48, 0x39, 0xe1, /* cmp %rsp, %rcx */ + 0x74, 0x02, /* je 2; jump over ud2 */ + 0x0f, 0x0b, /* ud2; stack pointer invalid, let's crash */ + + /* invoke capture context */ + 0x48, 0x8b, 0x4c, 0x24, 0x50, /* 2: mov 8*10(%rsp), %rcx; context */ + 0x48, 0x81, 0xc1, 0xd0, 0x04, 0x00, 0x00, /* $0x4d0, %rcx; +sizeof(CONTEXT) to get context->after */ + 0xff, 0x54, 0x24, 0x68, /* call *8*13(%rsp) */ + + /* free stack */ + 0x48, 0x83, 0xc4, 0x08, /* $0x8, %rsp */ + + /* restore back */ + 0x41, 0x5f, /* pop %r15 */ + 0x41, 0x5e, /* pop %r14 */ + 0x41, 0x5d, /* pop %r13 */ + 0x41, 0x5c, /* pop %r12 */ + 0x5f, /* pop %rdi */ + 0x5e, /* pop %rsi */ + 0x5d, /* pop %rbp */ + 0x5b, /* pop %rbx */ + 0xc3 /* ret */ + }; + + if (!pRtlCaptureContext) + { + win_skip("RtlCaptureContext is not available.\n"); + return; + } + + memcpy( func_ptr, call_func, sizeof(call_func) ); + FlushInstructionCache( GetCurrentProcess(), func_ptr, sizeof(call_func) ); + + func_ptr( &contexts, FALSE, NtContinue, pRtlCaptureContext ); + +#define COMPARE(reg) \ + ok( contexts.before.reg == contexts.after.reg, "wrong " #reg " %p/%p\n", (void *)(ULONG64)contexts.before.reg, (void *)(ULONG64)contexts.after.reg ) + + COMPARE( Rax ); + COMPARE( Rdx ); + COMPARE( Rbx ); + COMPARE( Rbp ); + COMPARE( Rsi ); + COMPARE( Rdi ); + COMPARE( R8 ); + COMPARE( R9 ); + COMPARE( R10 ); + COMPARE( R11 ); + COMPARE( R12 ); + COMPARE( R13 ); + COMPARE( R14 ); + COMPARE( R15 ); + + ok(memcmp(&contexts.before.Xmm0, &contexts.after.Xmm0, &contexts.before.Xmm15 - &contexts.before.Xmm0) == 0, + "wrong some SSE register, Xmm0 %lld/%lld Xmm15 %lld/%lld", contexts.before.Xmm0.Low, contexts.after.Xmm0.Low, + contexts.before.Xmm15.High, contexts.after.Xmm15.High); + +#undef COMPARE +} + static void test_wow64_context(void) { const char appname[] = "C:\\windows\\syswow64\\cmd.exe"; @@ -12456,6 +12618,7 @@ START_TEST(exception) test_debug_registers_wow64(); test_debug_service(1); test_simd_exceptions(); + test_continue(); test_virtual_unwind(); test___C_specific_handler(); test_restore_context(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4761
From: Dāvis Mosāns <davispuh(a)gmail.com> Implement NtContinueEx(PCONTEXT, PCONTINUE_OPTIONS) which was added in Windows 10 20H1 Co-authored-by: Etaash Mathamsetty <etaash.mathamsetty(a)gmail.com> --- dlls/ntdll/ntdll.spec | 2 + dlls/ntdll/ntsyscalls.h | 840 ++++++++++++++++++++------------------- dlls/ntdll/unix/server.c | 27 ++ dlls/wow64/syscall.c | 14 +- include/winternl.h | 21 + 5 files changed, 483 insertions(+), 421 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 1908a089d44..fa4e18f3566 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -166,6 +166,7 @@ # @ stub NtCompressKey @ stdcall -syscall NtConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall -syscall NtContinue(ptr long) +@ stdcall -syscall NtContinueEx(ptr ptr) @ stdcall -syscall NtCreateDebugObject(ptr long ptr long) @ stdcall -syscall NtCreateDirectoryObject(ptr long ptr) @ stdcall -syscall NtCreateEvent(ptr long ptr long long) @@ -1216,6 +1217,7 @@ # @ stub ZwCompressKey @ stdcall -private -syscall ZwConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr) NtConnectPort @ stdcall -private -syscall ZwContinue(ptr long) NtContinue +@ stdcall -private -syscall ZwContinueEx(ptr ptr) NtContinueEx # @ stub ZwCreateDebugObject @ stdcall -private -syscall ZwCreateDirectoryObject(ptr long ptr) NtCreateDirectoryObject @ stdcall -private -syscall ZwCreateEvent(ptr long ptr long long) NtCreateEvent diff --git a/dlls/ntdll/ntsyscalls.h b/dlls/ntdll/ntsyscalls.h index 7ae20b31159..92b492ba685 100644 --- a/dlls/ntdll/ntsyscalls.h +++ b/dlls/ntdll/ntsyscalls.h @@ -28,218 +28,219 @@ SYSCALL_ENTRY( 0x0018, NtCompleteConnectPort, 4 ) \ SYSCALL_ENTRY( 0x0019, NtConnectPort, 32 ) \ SYSCALL_ENTRY( 0x001a, NtContinue, 8 ) \ - SYSCALL_ENTRY( 0x001b, NtCreateDebugObject, 16 ) \ - SYSCALL_ENTRY( 0x001c, NtCreateDirectoryObject, 12 ) \ - SYSCALL_ENTRY( 0x001d, NtCreateEvent, 20 ) \ - SYSCALL_ENTRY( 0x001e, NtCreateFile, 44 ) \ - SYSCALL_ENTRY( 0x001f, NtCreateIoCompletion, 16 ) \ - SYSCALL_ENTRY( 0x0020, NtCreateJobObject, 12 ) \ - SYSCALL_ENTRY( 0x0021, NtCreateKey, 28 ) \ - SYSCALL_ENTRY( 0x0022, NtCreateKeyTransacted, 32 ) \ - SYSCALL_ENTRY( 0x0023, NtCreateKeyedEvent, 16 ) \ - SYSCALL_ENTRY( 0x0024, NtCreateLowBoxToken, 36 ) \ - SYSCALL_ENTRY( 0x0025, NtCreateMailslotFile, 32 ) \ - SYSCALL_ENTRY( 0x0026, NtCreateMutant, 16 ) \ - SYSCALL_ENTRY( 0x0027, NtCreateNamedPipeFile, 56 ) \ - SYSCALL_ENTRY( 0x0028, NtCreatePagingFile, 16 ) \ - SYSCALL_ENTRY( 0x0029, NtCreatePort, 20 ) \ - SYSCALL_ENTRY( 0x002a, NtCreateSection, 28 ) \ - SYSCALL_ENTRY( 0x002b, NtCreateSemaphore, 20 ) \ - SYSCALL_ENTRY( 0x002c, NtCreateSymbolicLinkObject, 16 ) \ - SYSCALL_ENTRY( 0x002d, NtCreateThread, 32 ) \ - SYSCALL_ENTRY( 0x002e, NtCreateThreadEx, 44 ) \ - SYSCALL_ENTRY( 0x002f, NtCreateTimer, 16 ) \ - SYSCALL_ENTRY( 0x0030, NtCreateToken, 52 ) \ - SYSCALL_ENTRY( 0x0031, NtCreateTransaction, 40 ) \ - SYSCALL_ENTRY( 0x0032, NtCreateUserProcess, 44 ) \ - SYSCALL_ENTRY( 0x0033, NtDebugActiveProcess, 8 ) \ - SYSCALL_ENTRY( 0x0034, NtDebugContinue, 12 ) \ - SYSCALL_ENTRY( 0x0035, NtDelayExecution, 8 ) \ - SYSCALL_ENTRY( 0x0036, NtDeleteAtom, 4 ) \ - SYSCALL_ENTRY( 0x0037, NtDeleteFile, 4 ) \ - SYSCALL_ENTRY( 0x0038, NtDeleteKey, 4 ) \ - SYSCALL_ENTRY( 0x0039, NtDeleteValueKey, 8 ) \ - SYSCALL_ENTRY( 0x003a, NtDeviceIoControlFile, 40 ) \ - SYSCALL_ENTRY( 0x003b, NtDisplayString, 4 ) \ - SYSCALL_ENTRY( 0x003c, NtDuplicateObject, 28 ) \ - SYSCALL_ENTRY( 0x003d, NtDuplicateToken, 24 ) \ - SYSCALL_ENTRY( 0x003e, NtEnumerateKey, 24 ) \ - SYSCALL_ENTRY( 0x003f, NtEnumerateValueKey, 24 ) \ - SYSCALL_ENTRY( 0x0040, NtFilterToken, 24 ) \ - SYSCALL_ENTRY( 0x0041, NtFindAtom, 12 ) \ - SYSCALL_ENTRY( 0x0042, NtFlushBuffersFile, 8 ) \ - SYSCALL_ENTRY( 0x0043, NtFlushInstructionCache, 12 ) \ - SYSCALL_ENTRY( 0x0044, NtFlushKey, 4 ) \ - SYSCALL_ENTRY( 0x0045, NtFlushProcessWriteBuffers, 0 ) \ - SYSCALL_ENTRY( 0x0046, NtFlushVirtualMemory, 16 ) \ - SYSCALL_ENTRY( 0x0047, NtFreeVirtualMemory, 16 ) \ - SYSCALL_ENTRY( 0x0048, NtFsControlFile, 40 ) \ - SYSCALL_ENTRY( 0x0049, NtGetContextThread, 8 ) \ - SYSCALL_ENTRY( 0x004a, NtGetCurrentProcessorNumber, 0 ) \ - SYSCALL_ENTRY( 0x004b, NtGetNextThread, 24 ) \ - SYSCALL_ENTRY( 0x004c, NtGetNlsSectionPtr, 20 ) \ - SYSCALL_ENTRY( 0x004d, NtGetWriteWatch, 28 ) \ - SYSCALL_ENTRY( 0x004e, NtImpersonateAnonymousToken, 4 ) \ - SYSCALL_ENTRY( 0x004f, NtInitializeNlsFiles, 12 ) \ - SYSCALL_ENTRY( 0x0050, NtInitiatePowerAction, 16 ) \ - SYSCALL_ENTRY( 0x0051, NtIsProcessInJob, 8 ) \ - SYSCALL_ENTRY( 0x0052, NtListenPort, 8 ) \ - SYSCALL_ENTRY( 0x0053, NtLoadDriver, 4 ) \ - SYSCALL_ENTRY( 0x0054, NtLoadKey, 8 ) \ - SYSCALL_ENTRY( 0x0055, NtLoadKey2, 12 ) \ - SYSCALL_ENTRY( 0x0056, NtLoadKeyEx, 32 ) \ - SYSCALL_ENTRY( 0x0057, NtLockFile, 40 ) \ - SYSCALL_ENTRY( 0x0058, NtLockVirtualMemory, 16 ) \ - SYSCALL_ENTRY( 0x0059, NtMakeTemporaryObject, 4 ) \ - SYSCALL_ENTRY( 0x005a, NtMapViewOfSection, 40 ) \ - SYSCALL_ENTRY( 0x005b, NtMapViewOfSectionEx, 36 ) \ - SYSCALL_ENTRY( 0x005c, NtNotifyChangeDirectoryFile, 36 ) \ - SYSCALL_ENTRY( 0x005d, NtNotifyChangeKey, 40 ) \ - SYSCALL_ENTRY( 0x005e, NtNotifyChangeMultipleKeys, 48 ) \ - SYSCALL_ENTRY( 0x005f, NtOpenDirectoryObject, 12 ) \ - SYSCALL_ENTRY( 0x0060, NtOpenEvent, 12 ) \ - SYSCALL_ENTRY( 0x0061, NtOpenFile, 24 ) \ - SYSCALL_ENTRY( 0x0062, NtOpenIoCompletion, 12 ) \ - SYSCALL_ENTRY( 0x0063, NtOpenJobObject, 12 ) \ - SYSCALL_ENTRY( 0x0064, NtOpenKey, 12 ) \ - SYSCALL_ENTRY( 0x0065, NtOpenKeyEx, 16 ) \ - SYSCALL_ENTRY( 0x0066, NtOpenKeyTransacted, 16 ) \ - SYSCALL_ENTRY( 0x0067, NtOpenKeyTransactedEx, 20 ) \ - SYSCALL_ENTRY( 0x0068, NtOpenKeyedEvent, 12 ) \ - SYSCALL_ENTRY( 0x0069, NtOpenMutant, 12 ) \ - SYSCALL_ENTRY( 0x006a, NtOpenProcess, 16 ) \ - SYSCALL_ENTRY( 0x006b, NtOpenProcessToken, 12 ) \ - SYSCALL_ENTRY( 0x006c, NtOpenProcessTokenEx, 16 ) \ - SYSCALL_ENTRY( 0x006d, NtOpenSection, 12 ) \ - SYSCALL_ENTRY( 0x006e, NtOpenSemaphore, 12 ) \ - SYSCALL_ENTRY( 0x006f, NtOpenSymbolicLinkObject, 12 ) \ - SYSCALL_ENTRY( 0x0070, NtOpenThread, 16 ) \ - SYSCALL_ENTRY( 0x0071, NtOpenThreadToken, 16 ) \ - SYSCALL_ENTRY( 0x0072, NtOpenThreadTokenEx, 20 ) \ - SYSCALL_ENTRY( 0x0073, NtOpenTimer, 12 ) \ - SYSCALL_ENTRY( 0x0074, NtPowerInformation, 20 ) \ - SYSCALL_ENTRY( 0x0075, NtPrivilegeCheck, 12 ) \ - SYSCALL_ENTRY( 0x0076, NtProtectVirtualMemory, 20 ) \ - SYSCALL_ENTRY( 0x0077, NtPulseEvent, 8 ) \ - SYSCALL_ENTRY( 0x0078, NtQueryAttributesFile, 8 ) \ - SYSCALL_ENTRY( 0x0079, NtQueryDefaultLocale, 8 ) \ - SYSCALL_ENTRY( 0x007a, NtQueryDefaultUILanguage, 4 ) \ - SYSCALL_ENTRY( 0x007b, NtQueryDirectoryFile, 44 ) \ - SYSCALL_ENTRY( 0x007c, NtQueryDirectoryObject, 28 ) \ - SYSCALL_ENTRY( 0x007d, NtQueryEaFile, 36 ) \ - SYSCALL_ENTRY( 0x007e, NtQueryEvent, 20 ) \ - SYSCALL_ENTRY( 0x007f, NtQueryFullAttributesFile, 8 ) \ - SYSCALL_ENTRY( 0x0080, NtQueryInformationAtom, 20 ) \ - SYSCALL_ENTRY( 0x0081, NtQueryInformationFile, 20 ) \ - SYSCALL_ENTRY( 0x0082, NtQueryInformationJobObject, 20 ) \ - SYSCALL_ENTRY( 0x0083, NtQueryInformationProcess, 20 ) \ - SYSCALL_ENTRY( 0x0084, NtQueryInformationThread, 20 ) \ - SYSCALL_ENTRY( 0x0085, NtQueryInformationToken, 20 ) \ - SYSCALL_ENTRY( 0x0086, NtQueryInstallUILanguage, 4 ) \ - SYSCALL_ENTRY( 0x0087, NtQueryIoCompletion, 20 ) \ - SYSCALL_ENTRY( 0x0088, NtQueryKey, 20 ) \ - SYSCALL_ENTRY( 0x0089, NtQueryLicenseValue, 20 ) \ - SYSCALL_ENTRY( 0x008a, NtQueryMultipleValueKey, 24 ) \ - SYSCALL_ENTRY( 0x008b, NtQueryMutant, 20 ) \ - SYSCALL_ENTRY( 0x008c, NtQueryObject, 20 ) \ - SYSCALL_ENTRY( 0x008d, NtQueryPerformanceCounter, 8 ) \ - SYSCALL_ENTRY( 0x008e, NtQuerySection, 20 ) \ - SYSCALL_ENTRY( 0x008f, NtQuerySecurityObject, 20 ) \ - SYSCALL_ENTRY( 0x0090, NtQuerySemaphore, 20 ) \ - SYSCALL_ENTRY( 0x0091, NtQuerySymbolicLinkObject, 12 ) \ - SYSCALL_ENTRY( 0x0092, NtQuerySystemEnvironmentValue, 16 ) \ - SYSCALL_ENTRY( 0x0093, NtQuerySystemEnvironmentValueEx, 20 ) \ - SYSCALL_ENTRY( 0x0094, NtQuerySystemInformation, 16 ) \ - SYSCALL_ENTRY( 0x0095, NtQuerySystemInformationEx, 24 ) \ - SYSCALL_ENTRY( 0x0096, NtQuerySystemTime, 4 ) \ - SYSCALL_ENTRY( 0x0097, NtQueryTimer, 20 ) \ - SYSCALL_ENTRY( 0x0098, NtQueryTimerResolution, 12 ) \ - SYSCALL_ENTRY( 0x0099, NtQueryValueKey, 24 ) \ - SYSCALL_ENTRY( 0x009a, NtQueryVirtualMemory, 24 ) \ - SYSCALL_ENTRY( 0x009b, NtQueryVolumeInformationFile, 20 ) \ - SYSCALL_ENTRY( 0x009c, NtQueueApcThread, 20 ) \ - SYSCALL_ENTRY( 0x009d, NtRaiseException, 12 ) \ - SYSCALL_ENTRY( 0x009e, NtRaiseHardError, 24 ) \ - SYSCALL_ENTRY( 0x009f, NtReadFile, 36 ) \ - SYSCALL_ENTRY( 0x00a0, NtReadFileScatter, 36 ) \ - SYSCALL_ENTRY( 0x00a1, NtReadVirtualMemory, 20 ) \ - SYSCALL_ENTRY( 0x00a2, NtRegisterThreadTerminatePort, 4 ) \ - SYSCALL_ENTRY( 0x00a3, NtReleaseKeyedEvent, 16 ) \ - SYSCALL_ENTRY( 0x00a4, NtReleaseMutant, 8 ) \ - SYSCALL_ENTRY( 0x00a5, NtReleaseSemaphore, 12 ) \ - SYSCALL_ENTRY( 0x00a6, NtRemoveIoCompletion, 20 ) \ - SYSCALL_ENTRY( 0x00a7, NtRemoveIoCompletionEx, 24 ) \ - SYSCALL_ENTRY( 0x00a8, NtRemoveProcessDebug, 8 ) \ - SYSCALL_ENTRY( 0x00a9, NtRenameKey, 8 ) \ - SYSCALL_ENTRY( 0x00aa, NtReplaceKey, 12 ) \ - SYSCALL_ENTRY( 0x00ab, NtReplyWaitReceivePort, 16 ) \ - SYSCALL_ENTRY( 0x00ac, NtRequestWaitReplyPort, 12 ) \ - SYSCALL_ENTRY( 0x00ad, NtResetEvent, 8 ) \ - SYSCALL_ENTRY( 0x00ae, NtResetWriteWatch, 12 ) \ - SYSCALL_ENTRY( 0x00af, NtRestoreKey, 12 ) \ - SYSCALL_ENTRY( 0x00b0, NtResumeProcess, 4 ) \ - SYSCALL_ENTRY( 0x00b1, NtResumeThread, 8 ) \ - SYSCALL_ENTRY( 0x00b2, NtRollbackTransaction, 8 ) \ - SYSCALL_ENTRY( 0x00b3, NtSaveKey, 8 ) \ - SYSCALL_ENTRY( 0x00b4, NtSecureConnectPort, 36 ) \ - SYSCALL_ENTRY( 0x00b5, NtSetContextThread, 8 ) \ - SYSCALL_ENTRY( 0x00b6, NtSetDebugFilterState, 12 ) \ - SYSCALL_ENTRY( 0x00b7, NtSetDefaultLocale, 8 ) \ - SYSCALL_ENTRY( 0x00b8, NtSetDefaultUILanguage, 4 ) \ - SYSCALL_ENTRY( 0x00b9, NtSetEaFile, 16 ) \ - SYSCALL_ENTRY( 0x00ba, NtSetEvent, 8 ) \ - SYSCALL_ENTRY( 0x00bb, NtSetInformationDebugObject, 20 ) \ - SYSCALL_ENTRY( 0x00bc, NtSetInformationFile, 20 ) \ - SYSCALL_ENTRY( 0x00bd, NtSetInformationJobObject, 16 ) \ - SYSCALL_ENTRY( 0x00be, NtSetInformationKey, 16 ) \ - SYSCALL_ENTRY( 0x00bf, NtSetInformationObject, 16 ) \ - SYSCALL_ENTRY( 0x00c0, NtSetInformationProcess, 16 ) \ - SYSCALL_ENTRY( 0x00c1, NtSetInformationThread, 16 ) \ - SYSCALL_ENTRY( 0x00c2, NtSetInformationToken, 16 ) \ - SYSCALL_ENTRY( 0x00c3, NtSetInformationVirtualMemory, 24 ) \ - SYSCALL_ENTRY( 0x00c4, NtSetIntervalProfile, 8 ) \ - SYSCALL_ENTRY( 0x00c5, NtSetIoCompletion, 20 ) \ - SYSCALL_ENTRY( 0x00c6, NtSetLdtEntries, 24 ) \ - SYSCALL_ENTRY( 0x00c7, NtSetSecurityObject, 12 ) \ - SYSCALL_ENTRY( 0x00c8, NtSetSystemInformation, 12 ) \ - SYSCALL_ENTRY( 0x00c9, NtSetSystemTime, 8 ) \ - SYSCALL_ENTRY( 0x00ca, NtSetThreadExecutionState, 8 ) \ - SYSCALL_ENTRY( 0x00cb, NtSetTimer, 28 ) \ - SYSCALL_ENTRY( 0x00cc, NtSetTimerResolution, 12 ) \ - SYSCALL_ENTRY( 0x00cd, NtSetValueKey, 24 ) \ - SYSCALL_ENTRY( 0x00ce, NtSetVolumeInformationFile, 20 ) \ - SYSCALL_ENTRY( 0x00cf, NtShutdownSystem, 4 ) \ - SYSCALL_ENTRY( 0x00d0, NtSignalAndWaitForSingleObject, 16 ) \ - SYSCALL_ENTRY( 0x00d1, NtSuspendProcess, 4 ) \ - SYSCALL_ENTRY( 0x00d2, NtSuspendThread, 8 ) \ - SYSCALL_ENTRY( 0x00d3, NtSystemDebugControl, 24 ) \ - SYSCALL_ENTRY( 0x00d4, NtTerminateJobObject, 8 ) \ - SYSCALL_ENTRY( 0x00d5, NtTerminateProcess, 8 ) \ - SYSCALL_ENTRY( 0x00d6, NtTerminateThread, 8 ) \ - SYSCALL_ENTRY( 0x00d7, NtTestAlert, 0 ) \ - SYSCALL_ENTRY( 0x00d8, NtTraceControl, 24 ) \ - SYSCALL_ENTRY( 0x00d9, NtUnloadDriver, 4 ) \ - SYSCALL_ENTRY( 0x00da, NtUnloadKey, 4 ) \ - SYSCALL_ENTRY( 0x00db, NtUnlockFile, 20 ) \ - SYSCALL_ENTRY( 0x00dc, NtUnlockVirtualMemory, 16 ) \ - SYSCALL_ENTRY( 0x00dd, NtUnmapViewOfSection, 8 ) \ - SYSCALL_ENTRY( 0x00de, NtUnmapViewOfSectionEx, 12 ) \ - SYSCALL_ENTRY( 0x00df, NtWaitForAlertByThreadId, 8 ) \ - SYSCALL_ENTRY( 0x00e0, NtWaitForDebugEvent, 16 ) \ - SYSCALL_ENTRY( 0x00e1, NtWaitForKeyedEvent, 16 ) \ - SYSCALL_ENTRY( 0x00e2, NtWaitForMultipleObjects, 20 ) \ - SYSCALL_ENTRY( 0x00e3, NtWaitForSingleObject, 12 ) \ - SYSCALL_ENTRY( 0x00e4, NtWow64AllocateVirtualMemory64, 28 ) \ - SYSCALL_ENTRY( 0x00e5, NtWow64GetNativeSystemInformation, 16 ) \ - SYSCALL_ENTRY( 0x00e6, NtWow64IsProcessorFeaturePresent, 4 ) \ - SYSCALL_ENTRY( 0x00e7, NtWow64ReadVirtualMemory64, 28 ) \ - SYSCALL_ENTRY( 0x00e8, NtWow64WriteVirtualMemory64, 28 ) \ - SYSCALL_ENTRY( 0x00e9, NtWriteFile, 36 ) \ - SYSCALL_ENTRY( 0x00ea, NtWriteFileGather, 36 ) \ - SYSCALL_ENTRY( 0x00eb, NtWriteVirtualMemory, 20 ) \ - SYSCALL_ENTRY( 0x00ec, NtYieldExecution, 0 ) \ - SYSCALL_ENTRY( 0x00ed, wine_nt_to_unix_file_name, 16 ) \ - SYSCALL_ENTRY( 0x00ee, wine_unix_to_nt_file_name, 12 ) + SYSCALL_ENTRY( 0x001b, NtContinueEx, 8 ) \ + SYSCALL_ENTRY( 0x001c, NtCreateDebugObject, 16 ) \ + SYSCALL_ENTRY( 0x001d, NtCreateDirectoryObject, 12 ) \ + SYSCALL_ENTRY( 0x001e, NtCreateEvent, 20 ) \ + SYSCALL_ENTRY( 0x001f, NtCreateFile, 44 ) \ + SYSCALL_ENTRY( 0x0020, NtCreateIoCompletion, 16 ) \ + SYSCALL_ENTRY( 0x0021, NtCreateJobObject, 12 ) \ + SYSCALL_ENTRY( 0x0022, NtCreateKey, 28 ) \ + SYSCALL_ENTRY( 0x0023, NtCreateKeyTransacted, 32 ) \ + SYSCALL_ENTRY( 0x0024, NtCreateKeyedEvent, 16 ) \ + SYSCALL_ENTRY( 0x0025, NtCreateLowBoxToken, 36 ) \ + SYSCALL_ENTRY( 0x0026, NtCreateMailslotFile, 32 ) \ + SYSCALL_ENTRY( 0x0027, NtCreateMutant, 16 ) \ + SYSCALL_ENTRY( 0x0028, NtCreateNamedPipeFile, 56 ) \ + SYSCALL_ENTRY( 0x0029, NtCreatePagingFile, 16 ) \ + SYSCALL_ENTRY( 0x002a, NtCreatePort, 20 ) \ + SYSCALL_ENTRY( 0x002b, NtCreateSection, 28 ) \ + SYSCALL_ENTRY( 0x002c, NtCreateSemaphore, 20 ) \ + SYSCALL_ENTRY( 0x002d, NtCreateSymbolicLinkObject, 16 ) \ + SYSCALL_ENTRY( 0x002e, NtCreateThread, 32 ) \ + SYSCALL_ENTRY( 0x002f, NtCreateThreadEx, 44 ) \ + SYSCALL_ENTRY( 0x0030, NtCreateTimer, 16 ) \ + SYSCALL_ENTRY( 0x0031, NtCreateToken, 52 ) \ + SYSCALL_ENTRY( 0x0032, NtCreateTransaction, 40 ) \ + SYSCALL_ENTRY( 0x0033, NtCreateUserProcess, 44 ) \ + SYSCALL_ENTRY( 0x0034, NtDebugActiveProcess, 8 ) \ + SYSCALL_ENTRY( 0x0035, NtDebugContinue, 12 ) \ + SYSCALL_ENTRY( 0x0036, NtDelayExecution, 8 ) \ + SYSCALL_ENTRY( 0x0037, NtDeleteAtom, 4 ) \ + SYSCALL_ENTRY( 0x0038, NtDeleteFile, 4 ) \ + SYSCALL_ENTRY( 0x0039, NtDeleteKey, 4 ) \ + SYSCALL_ENTRY( 0x003a, NtDeleteValueKey, 8 ) \ + SYSCALL_ENTRY( 0x003b, NtDeviceIoControlFile, 40 ) \ + SYSCALL_ENTRY( 0x003c, NtDisplayString, 4 ) \ + SYSCALL_ENTRY( 0x003d, NtDuplicateObject, 28 ) \ + SYSCALL_ENTRY( 0x003e, NtDuplicateToken, 24 ) \ + SYSCALL_ENTRY( 0x003f, NtEnumerateKey, 24 ) \ + SYSCALL_ENTRY( 0x0040, NtEnumerateValueKey, 24 ) \ + SYSCALL_ENTRY( 0x0041, NtFilterToken, 24 ) \ + SYSCALL_ENTRY( 0x0042, NtFindAtom, 12 ) \ + SYSCALL_ENTRY( 0x0043, NtFlushBuffersFile, 8 ) \ + SYSCALL_ENTRY( 0x0044, NtFlushInstructionCache, 12 ) \ + SYSCALL_ENTRY( 0x0045, NtFlushKey, 4 ) \ + SYSCALL_ENTRY( 0x0046, NtFlushProcessWriteBuffers, 0 ) \ + SYSCALL_ENTRY( 0x0047, NtFlushVirtualMemory, 16 ) \ + SYSCALL_ENTRY( 0x0048, NtFreeVirtualMemory, 16 ) \ + SYSCALL_ENTRY( 0x0049, NtFsControlFile, 40 ) \ + SYSCALL_ENTRY( 0x004a, NtGetContextThread, 8 ) \ + SYSCALL_ENTRY( 0x004b, NtGetCurrentProcessorNumber, 0 ) \ + SYSCALL_ENTRY( 0x004c, NtGetNextThread, 24 ) \ + SYSCALL_ENTRY( 0x004d, NtGetNlsSectionPtr, 20 ) \ + SYSCALL_ENTRY( 0x004e, NtGetWriteWatch, 28 ) \ + SYSCALL_ENTRY( 0x004f, NtImpersonateAnonymousToken, 4 ) \ + SYSCALL_ENTRY( 0x0050, NtInitializeNlsFiles, 12 ) \ + SYSCALL_ENTRY( 0x0051, NtInitiatePowerAction, 16 ) \ + SYSCALL_ENTRY( 0x0052, NtIsProcessInJob, 8 ) \ + SYSCALL_ENTRY( 0x0053, NtListenPort, 8 ) \ + SYSCALL_ENTRY( 0x0054, NtLoadDriver, 4 ) \ + SYSCALL_ENTRY( 0x0055, NtLoadKey, 8 ) \ + SYSCALL_ENTRY( 0x0056, NtLoadKey2, 12 ) \ + SYSCALL_ENTRY( 0x0057, NtLoadKeyEx, 32 ) \ + SYSCALL_ENTRY( 0x0058, NtLockFile, 40 ) \ + SYSCALL_ENTRY( 0x0059, NtLockVirtualMemory, 16 ) \ + SYSCALL_ENTRY( 0x005a, NtMakeTemporaryObject, 4 ) \ + SYSCALL_ENTRY( 0x005b, NtMapViewOfSection, 40 ) \ + SYSCALL_ENTRY( 0x005c, NtMapViewOfSectionEx, 36 ) \ + SYSCALL_ENTRY( 0x005d, NtNotifyChangeDirectoryFile, 36 ) \ + SYSCALL_ENTRY( 0x005e, NtNotifyChangeKey, 40 ) \ + SYSCALL_ENTRY( 0x005f, NtNotifyChangeMultipleKeys, 48 ) \ + SYSCALL_ENTRY( 0x0060, NtOpenDirectoryObject, 12 ) \ + SYSCALL_ENTRY( 0x0061, NtOpenEvent, 12 ) \ + SYSCALL_ENTRY( 0x0062, NtOpenFile, 24 ) \ + SYSCALL_ENTRY( 0x0063, NtOpenIoCompletion, 12 ) \ + SYSCALL_ENTRY( 0x0064, NtOpenJobObject, 12 ) \ + SYSCALL_ENTRY( 0x0065, NtOpenKey, 12 ) \ + SYSCALL_ENTRY( 0x0066, NtOpenKeyEx, 16 ) \ + SYSCALL_ENTRY( 0x0067, NtOpenKeyTransacted, 16 ) \ + SYSCALL_ENTRY( 0x0068, NtOpenKeyTransactedEx, 20 ) \ + SYSCALL_ENTRY( 0x0069, NtOpenKeyedEvent, 12 ) \ + SYSCALL_ENTRY( 0x006a, NtOpenMutant, 12 ) \ + SYSCALL_ENTRY( 0x006b, NtOpenProcess, 16 ) \ + SYSCALL_ENTRY( 0x006c, NtOpenProcessToken, 12 ) \ + SYSCALL_ENTRY( 0x006d, NtOpenProcessTokenEx, 16 ) \ + SYSCALL_ENTRY( 0x006e, NtOpenSection, 12 ) \ + SYSCALL_ENTRY( 0x006f, NtOpenSemaphore, 12 ) \ + SYSCALL_ENTRY( 0x0070, NtOpenSymbolicLinkObject, 12 ) \ + SYSCALL_ENTRY( 0x0071, NtOpenThread, 16 ) \ + SYSCALL_ENTRY( 0x0072, NtOpenThreadToken, 16 ) \ + SYSCALL_ENTRY( 0x0073, NtOpenThreadTokenEx, 20 ) \ + SYSCALL_ENTRY( 0x0074, NtOpenTimer, 12 ) \ + SYSCALL_ENTRY( 0x0075, NtPowerInformation, 20 ) \ + SYSCALL_ENTRY( 0x0076, NtPrivilegeCheck, 12 ) \ + SYSCALL_ENTRY( 0x0077, NtProtectVirtualMemory, 20 ) \ + SYSCALL_ENTRY( 0x0078, NtPulseEvent, 8 ) \ + SYSCALL_ENTRY( 0x0079, NtQueryAttributesFile, 8 ) \ + SYSCALL_ENTRY( 0x007a, NtQueryDefaultLocale, 8 ) \ + SYSCALL_ENTRY( 0x007b, NtQueryDefaultUILanguage, 4 ) \ + SYSCALL_ENTRY( 0x007c, NtQueryDirectoryFile, 44 ) \ + SYSCALL_ENTRY( 0x007d, NtQueryDirectoryObject, 28 ) \ + SYSCALL_ENTRY( 0x007e, NtQueryEaFile, 36 ) \ + SYSCALL_ENTRY( 0x007f, NtQueryEvent, 20 ) \ + SYSCALL_ENTRY( 0x0080, NtQueryFullAttributesFile, 8 ) \ + SYSCALL_ENTRY( 0x0081, NtQueryInformationAtom, 20 ) \ + SYSCALL_ENTRY( 0x0082, NtQueryInformationFile, 20 ) \ + SYSCALL_ENTRY( 0x0083, NtQueryInformationJobObject, 20 ) \ + SYSCALL_ENTRY( 0x0084, NtQueryInformationProcess, 20 ) \ + SYSCALL_ENTRY( 0x0085, NtQueryInformationThread, 20 ) \ + SYSCALL_ENTRY( 0x0086, NtQueryInformationToken, 20 ) \ + SYSCALL_ENTRY( 0x0087, NtQueryInstallUILanguage, 4 ) \ + SYSCALL_ENTRY( 0x0088, NtQueryIoCompletion, 20 ) \ + SYSCALL_ENTRY( 0x0089, NtQueryKey, 20 ) \ + SYSCALL_ENTRY( 0x008a, NtQueryLicenseValue, 20 ) \ + SYSCALL_ENTRY( 0x008b, NtQueryMultipleValueKey, 24 ) \ + SYSCALL_ENTRY( 0x008c, NtQueryMutant, 20 ) \ + SYSCALL_ENTRY( 0x008d, NtQueryObject, 20 ) \ + SYSCALL_ENTRY( 0x008e, NtQueryPerformanceCounter, 8 ) \ + SYSCALL_ENTRY( 0x008f, NtQuerySection, 20 ) \ + SYSCALL_ENTRY( 0x0090, NtQuerySecurityObject, 20 ) \ + SYSCALL_ENTRY( 0x0091, NtQuerySemaphore, 20 ) \ + SYSCALL_ENTRY( 0x0092, NtQuerySymbolicLinkObject, 12 ) \ + SYSCALL_ENTRY( 0x0093, NtQuerySystemEnvironmentValue, 16 ) \ + SYSCALL_ENTRY( 0x0094, NtQuerySystemEnvironmentValueEx, 20 ) \ + SYSCALL_ENTRY( 0x0095, NtQuerySystemInformation, 16 ) \ + SYSCALL_ENTRY( 0x0096, NtQuerySystemInformationEx, 24 ) \ + SYSCALL_ENTRY( 0x0097, NtQuerySystemTime, 4 ) \ + SYSCALL_ENTRY( 0x0098, NtQueryTimer, 20 ) \ + SYSCALL_ENTRY( 0x0099, NtQueryTimerResolution, 12 ) \ + SYSCALL_ENTRY( 0x009a, NtQueryValueKey, 24 ) \ + SYSCALL_ENTRY( 0x009b, NtQueryVirtualMemory, 24 ) \ + SYSCALL_ENTRY( 0x009c, NtQueryVolumeInformationFile, 20 ) \ + SYSCALL_ENTRY( 0x009d, NtQueueApcThread, 20 ) \ + SYSCALL_ENTRY( 0x009e, NtRaiseException, 12 ) \ + SYSCALL_ENTRY( 0x009f, NtRaiseHardError, 24 ) \ + SYSCALL_ENTRY( 0x00a0, NtReadFile, 36 ) \ + SYSCALL_ENTRY( 0x00a1, NtReadFileScatter, 36 ) \ + SYSCALL_ENTRY( 0x00a2, NtReadVirtualMemory, 20 ) \ + SYSCALL_ENTRY( 0x00a3, NtRegisterThreadTerminatePort, 4 ) \ + SYSCALL_ENTRY( 0x00a4, NtReleaseKeyedEvent, 16 ) \ + SYSCALL_ENTRY( 0x00a5, NtReleaseMutant, 8 ) \ + SYSCALL_ENTRY( 0x00a6, NtReleaseSemaphore, 12 ) \ + SYSCALL_ENTRY( 0x00a7, NtRemoveIoCompletion, 20 ) \ + SYSCALL_ENTRY( 0x00a8, NtRemoveIoCompletionEx, 24 ) \ + SYSCALL_ENTRY( 0x00a9, NtRemoveProcessDebug, 8 ) \ + SYSCALL_ENTRY( 0x00aa, NtRenameKey, 8 ) \ + SYSCALL_ENTRY( 0x00ab, NtReplaceKey, 12 ) \ + SYSCALL_ENTRY( 0x00ac, NtReplyWaitReceivePort, 16 ) \ + SYSCALL_ENTRY( 0x00ad, NtRequestWaitReplyPort, 12 ) \ + SYSCALL_ENTRY( 0x00ae, NtResetEvent, 8 ) \ + SYSCALL_ENTRY( 0x00af, NtResetWriteWatch, 12 ) \ + SYSCALL_ENTRY( 0x00b0, NtRestoreKey, 12 ) \ + SYSCALL_ENTRY( 0x00b1, NtResumeProcess, 4 ) \ + SYSCALL_ENTRY( 0x00b2, NtResumeThread, 8 ) \ + SYSCALL_ENTRY( 0x00b3, NtRollbackTransaction, 8 ) \ + SYSCALL_ENTRY( 0x00b4, NtSaveKey, 8 ) \ + SYSCALL_ENTRY( 0x00b5, NtSecureConnectPort, 36 ) \ + SYSCALL_ENTRY( 0x00b6, NtSetContextThread, 8 ) \ + SYSCALL_ENTRY( 0x00b7, NtSetDebugFilterState, 12 ) \ + SYSCALL_ENTRY( 0x00b8, NtSetDefaultLocale, 8 ) \ + SYSCALL_ENTRY( 0x00b9, NtSetDefaultUILanguage, 4 ) \ + SYSCALL_ENTRY( 0x00ba, NtSetEaFile, 16 ) \ + SYSCALL_ENTRY( 0x00bb, NtSetEvent, 8 ) \ + SYSCALL_ENTRY( 0x00bc, NtSetInformationDebugObject, 20 ) \ + SYSCALL_ENTRY( 0x00bd, NtSetInformationFile, 20 ) \ + SYSCALL_ENTRY( 0x00be, NtSetInformationJobObject, 16 ) \ + SYSCALL_ENTRY( 0x00bf, NtSetInformationKey, 16 ) \ + SYSCALL_ENTRY( 0x00c0, NtSetInformationObject, 16 ) \ + SYSCALL_ENTRY( 0x00c1, NtSetInformationProcess, 16 ) \ + SYSCALL_ENTRY( 0x00c2, NtSetInformationThread, 16 ) \ + SYSCALL_ENTRY( 0x00c3, NtSetInformationToken, 16 ) \ + SYSCALL_ENTRY( 0x00c4, NtSetInformationVirtualMemory, 24 ) \ + SYSCALL_ENTRY( 0x00c5, NtSetIntervalProfile, 8 ) \ + SYSCALL_ENTRY( 0x00c6, NtSetIoCompletion, 20 ) \ + SYSCALL_ENTRY( 0x00c7, NtSetLdtEntries, 24 ) \ + SYSCALL_ENTRY( 0x00c8, NtSetSecurityObject, 12 ) \ + SYSCALL_ENTRY( 0x00c9, NtSetSystemInformation, 12 ) \ + SYSCALL_ENTRY( 0x00ca, NtSetSystemTime, 8 ) \ + SYSCALL_ENTRY( 0x00cb, NtSetThreadExecutionState, 8 ) \ + SYSCALL_ENTRY( 0x00cc, NtSetTimer, 28 ) \ + SYSCALL_ENTRY( 0x00cd, NtSetTimerResolution, 12 ) \ + SYSCALL_ENTRY( 0x00ce, NtSetValueKey, 24 ) \ + SYSCALL_ENTRY( 0x00cf, NtSetVolumeInformationFile, 20 ) \ + SYSCALL_ENTRY( 0x00d0, NtShutdownSystem, 4 ) \ + SYSCALL_ENTRY( 0x00d1, NtSignalAndWaitForSingleObject, 16 ) \ + SYSCALL_ENTRY( 0x00d2, NtSuspendProcess, 4 ) \ + SYSCALL_ENTRY( 0x00d3, NtSuspendThread, 8 ) \ + SYSCALL_ENTRY( 0x00d4, NtSystemDebugControl, 24 ) \ + SYSCALL_ENTRY( 0x00d5, NtTerminateJobObject, 8 ) \ + SYSCALL_ENTRY( 0x00d6, NtTerminateProcess, 8 ) \ + SYSCALL_ENTRY( 0x00d7, NtTerminateThread, 8 ) \ + SYSCALL_ENTRY( 0x00d8, NtTestAlert, 0 ) \ + SYSCALL_ENTRY( 0x00d9, NtTraceControl, 24 ) \ + SYSCALL_ENTRY( 0x00da, NtUnloadDriver, 4 ) \ + SYSCALL_ENTRY( 0x00db, NtUnloadKey, 4 ) \ + SYSCALL_ENTRY( 0x00dc, NtUnlockFile, 20 ) \ + SYSCALL_ENTRY( 0x00dd, NtUnlockVirtualMemory, 16 ) \ + SYSCALL_ENTRY( 0x00de, NtUnmapViewOfSection, 8 ) \ + SYSCALL_ENTRY( 0x00df, NtUnmapViewOfSectionEx, 12 ) \ + SYSCALL_ENTRY( 0x00e0, NtWaitForAlertByThreadId, 8 ) \ + SYSCALL_ENTRY( 0x00e1, NtWaitForDebugEvent, 16 ) \ + SYSCALL_ENTRY( 0x00e2, NtWaitForKeyedEvent, 16 ) \ + SYSCALL_ENTRY( 0x00e3, NtWaitForMultipleObjects, 20 ) \ + SYSCALL_ENTRY( 0x00e4, NtWaitForSingleObject, 12 ) \ + SYSCALL_ENTRY( 0x00e5, NtWow64AllocateVirtualMemory64, 28 ) \ + SYSCALL_ENTRY( 0x00e6, NtWow64GetNativeSystemInformation, 16 ) \ + SYSCALL_ENTRY( 0x00e7, NtWow64IsProcessorFeaturePresent, 4 ) \ + SYSCALL_ENTRY( 0x00e8, NtWow64ReadVirtualMemory64, 28 ) \ + SYSCALL_ENTRY( 0x00e9, NtWow64WriteVirtualMemory64, 28 ) \ + SYSCALL_ENTRY( 0x00ea, NtWriteFile, 36 ) \ + SYSCALL_ENTRY( 0x00eb, NtWriteFileGather, 36 ) \ + SYSCALL_ENTRY( 0x00ec, NtWriteVirtualMemory, 20 ) \ + SYSCALL_ENTRY( 0x00ed, NtYieldExecution, 0 ) \ + SYSCALL_ENTRY( 0x00ee, wine_nt_to_unix_file_name, 16 ) \ + SYSCALL_ENTRY( 0x00ef, wine_unix_to_nt_file_name, 12 ) #define ALL_SYSCALLS64 \ SYSCALL_ENTRY( 0x0000, NtAcceptConnectPort, 48 ) \ @@ -269,210 +270,211 @@ SYSCALL_ENTRY( 0x0018, NtCompleteConnectPort, 8 ) \ SYSCALL_ENTRY( 0x0019, NtConnectPort, 64 ) \ SYSCALL_ENTRY( 0x001a, NtContinue, 16 ) \ - SYSCALL_ENTRY( 0x001b, NtCreateDebugObject, 32 ) \ - SYSCALL_ENTRY( 0x001c, NtCreateDirectoryObject, 24 ) \ - SYSCALL_ENTRY( 0x001d, NtCreateEvent, 40 ) \ - SYSCALL_ENTRY( 0x001e, NtCreateFile, 88 ) \ - SYSCALL_ENTRY( 0x001f, NtCreateIoCompletion, 32 ) \ - SYSCALL_ENTRY( 0x0020, NtCreateJobObject, 24 ) \ - SYSCALL_ENTRY( 0x0021, NtCreateKey, 56 ) \ - SYSCALL_ENTRY( 0x0022, NtCreateKeyTransacted, 64 ) \ - SYSCALL_ENTRY( 0x0023, NtCreateKeyedEvent, 32 ) \ - SYSCALL_ENTRY( 0x0024, NtCreateLowBoxToken, 72 ) \ - SYSCALL_ENTRY( 0x0025, NtCreateMailslotFile, 64 ) \ - SYSCALL_ENTRY( 0x0026, NtCreateMutant, 32 ) \ - SYSCALL_ENTRY( 0x0027, NtCreateNamedPipeFile, 112 ) \ - SYSCALL_ENTRY( 0x0028, NtCreatePagingFile, 32 ) \ - SYSCALL_ENTRY( 0x0029, NtCreatePort, 40 ) \ - SYSCALL_ENTRY( 0x002a, NtCreateSection, 56 ) \ - SYSCALL_ENTRY( 0x002b, NtCreateSemaphore, 40 ) \ - SYSCALL_ENTRY( 0x002c, NtCreateSymbolicLinkObject, 32 ) \ - SYSCALL_ENTRY( 0x002d, NtCreateThread, 64 ) \ - SYSCALL_ENTRY( 0x002e, NtCreateThreadEx, 88 ) \ - SYSCALL_ENTRY( 0x002f, NtCreateTimer, 32 ) \ - SYSCALL_ENTRY( 0x0030, NtCreateToken, 104 ) \ - SYSCALL_ENTRY( 0x0031, NtCreateTransaction, 80 ) \ - SYSCALL_ENTRY( 0x0032, NtCreateUserProcess, 88 ) \ - SYSCALL_ENTRY( 0x0033, NtDebugActiveProcess, 16 ) \ - SYSCALL_ENTRY( 0x0034, NtDebugContinue, 24 ) \ - SYSCALL_ENTRY( 0x0035, NtDelayExecution, 16 ) \ - SYSCALL_ENTRY( 0x0036, NtDeleteAtom, 8 ) \ - SYSCALL_ENTRY( 0x0037, NtDeleteFile, 8 ) \ - SYSCALL_ENTRY( 0x0038, NtDeleteKey, 8 ) \ - SYSCALL_ENTRY( 0x0039, NtDeleteValueKey, 16 ) \ - SYSCALL_ENTRY( 0x003a, NtDeviceIoControlFile, 80 ) \ - SYSCALL_ENTRY( 0x003b, NtDisplayString, 8 ) \ - SYSCALL_ENTRY( 0x003c, NtDuplicateObject, 56 ) \ - SYSCALL_ENTRY( 0x003d, NtDuplicateToken, 48 ) \ - SYSCALL_ENTRY( 0x003e, NtEnumerateKey, 48 ) \ - SYSCALL_ENTRY( 0x003f, NtEnumerateValueKey, 48 ) \ - SYSCALL_ENTRY( 0x0040, NtFilterToken, 48 ) \ - SYSCALL_ENTRY( 0x0041, NtFindAtom, 24 ) \ - SYSCALL_ENTRY( 0x0042, NtFlushBuffersFile, 16 ) \ - SYSCALL_ENTRY( 0x0043, NtFlushInstructionCache, 24 ) \ - SYSCALL_ENTRY( 0x0044, NtFlushKey, 8 ) \ - SYSCALL_ENTRY( 0x0045, NtFlushProcessWriteBuffers, 0 ) \ - SYSCALL_ENTRY( 0x0046, NtFlushVirtualMemory, 32 ) \ - SYSCALL_ENTRY( 0x0047, NtFreeVirtualMemory, 32 ) \ - SYSCALL_ENTRY( 0x0048, NtFsControlFile, 80 ) \ - SYSCALL_ENTRY( 0x0049, NtGetContextThread, 16 ) \ - SYSCALL_ENTRY( 0x004a, NtGetCurrentProcessorNumber, 0 ) \ - SYSCALL_ENTRY( 0x004b, NtGetNextThread, 48 ) \ - SYSCALL_ENTRY( 0x004c, NtGetNlsSectionPtr, 40 ) \ - SYSCALL_ENTRY( 0x004d, NtGetWriteWatch, 56 ) \ - SYSCALL_ENTRY( 0x004e, NtImpersonateAnonymousToken, 8 ) \ - SYSCALL_ENTRY( 0x004f, NtInitializeNlsFiles, 24 ) \ - SYSCALL_ENTRY( 0x0050, NtInitiatePowerAction, 32 ) \ - SYSCALL_ENTRY( 0x0051, NtIsProcessInJob, 16 ) \ - SYSCALL_ENTRY( 0x0052, NtListenPort, 16 ) \ - SYSCALL_ENTRY( 0x0053, NtLoadDriver, 8 ) \ - SYSCALL_ENTRY( 0x0054, NtLoadKey, 16 ) \ - SYSCALL_ENTRY( 0x0055, NtLoadKey2, 24 ) \ - SYSCALL_ENTRY( 0x0056, NtLoadKeyEx, 64 ) \ - SYSCALL_ENTRY( 0x0057, NtLockFile, 80 ) \ - SYSCALL_ENTRY( 0x0058, NtLockVirtualMemory, 32 ) \ - SYSCALL_ENTRY( 0x0059, NtMakeTemporaryObject, 8 ) \ - SYSCALL_ENTRY( 0x005a, NtMapViewOfSection, 80 ) \ - SYSCALL_ENTRY( 0x005b, NtMapViewOfSectionEx, 72 ) \ - SYSCALL_ENTRY( 0x005c, NtNotifyChangeDirectoryFile, 72 ) \ - SYSCALL_ENTRY( 0x005d, NtNotifyChangeKey, 80 ) \ - SYSCALL_ENTRY( 0x005e, NtNotifyChangeMultipleKeys, 96 ) \ - SYSCALL_ENTRY( 0x005f, NtOpenDirectoryObject, 24 ) \ - SYSCALL_ENTRY( 0x0060, NtOpenEvent, 24 ) \ - SYSCALL_ENTRY( 0x0061, NtOpenFile, 48 ) \ - SYSCALL_ENTRY( 0x0062, NtOpenIoCompletion, 24 ) \ - SYSCALL_ENTRY( 0x0063, NtOpenJobObject, 24 ) \ - SYSCALL_ENTRY( 0x0064, NtOpenKey, 24 ) \ - SYSCALL_ENTRY( 0x0065, NtOpenKeyEx, 32 ) \ - SYSCALL_ENTRY( 0x0066, NtOpenKeyTransacted, 32 ) \ - SYSCALL_ENTRY( 0x0067, NtOpenKeyTransactedEx, 40 ) \ - SYSCALL_ENTRY( 0x0068, NtOpenKeyedEvent, 24 ) \ - SYSCALL_ENTRY( 0x0069, NtOpenMutant, 24 ) \ - SYSCALL_ENTRY( 0x006a, NtOpenProcess, 32 ) \ - SYSCALL_ENTRY( 0x006b, NtOpenProcessToken, 24 ) \ - SYSCALL_ENTRY( 0x006c, NtOpenProcessTokenEx, 32 ) \ - SYSCALL_ENTRY( 0x006d, NtOpenSection, 24 ) \ - SYSCALL_ENTRY( 0x006e, NtOpenSemaphore, 24 ) \ - SYSCALL_ENTRY( 0x006f, NtOpenSymbolicLinkObject, 24 ) \ - SYSCALL_ENTRY( 0x0070, NtOpenThread, 32 ) \ - SYSCALL_ENTRY( 0x0071, NtOpenThreadToken, 32 ) \ - SYSCALL_ENTRY( 0x0072, NtOpenThreadTokenEx, 40 ) \ - SYSCALL_ENTRY( 0x0073, NtOpenTimer, 24 ) \ - SYSCALL_ENTRY( 0x0074, NtPowerInformation, 40 ) \ - SYSCALL_ENTRY( 0x0075, NtPrivilegeCheck, 24 ) \ - SYSCALL_ENTRY( 0x0076, NtProtectVirtualMemory, 40 ) \ - SYSCALL_ENTRY( 0x0077, NtPulseEvent, 16 ) \ - SYSCALL_ENTRY( 0x0078, NtQueryAttributesFile, 16 ) \ - SYSCALL_ENTRY( 0x0079, NtQueryDefaultLocale, 16 ) \ - SYSCALL_ENTRY( 0x007a, NtQueryDefaultUILanguage, 8 ) \ - SYSCALL_ENTRY( 0x007b, NtQueryDirectoryFile, 88 ) \ - SYSCALL_ENTRY( 0x007c, NtQueryDirectoryObject, 56 ) \ - SYSCALL_ENTRY( 0x007d, NtQueryEaFile, 72 ) \ - SYSCALL_ENTRY( 0x007e, NtQueryEvent, 40 ) \ - SYSCALL_ENTRY( 0x007f, NtQueryFullAttributesFile, 16 ) \ - SYSCALL_ENTRY( 0x0080, NtQueryInformationAtom, 40 ) \ - SYSCALL_ENTRY( 0x0081, NtQueryInformationFile, 40 ) \ - SYSCALL_ENTRY( 0x0082, NtQueryInformationJobObject, 40 ) \ - SYSCALL_ENTRY( 0x0083, NtQueryInformationProcess, 40 ) \ - SYSCALL_ENTRY( 0x0084, NtQueryInformationThread, 40 ) \ - SYSCALL_ENTRY( 0x0085, NtQueryInformationToken, 40 ) \ - SYSCALL_ENTRY( 0x0086, NtQueryInstallUILanguage, 8 ) \ - SYSCALL_ENTRY( 0x0087, NtQueryIoCompletion, 40 ) \ - SYSCALL_ENTRY( 0x0088, NtQueryKey, 40 ) \ - SYSCALL_ENTRY( 0x0089, NtQueryLicenseValue, 40 ) \ - SYSCALL_ENTRY( 0x008a, NtQueryMultipleValueKey, 48 ) \ - SYSCALL_ENTRY( 0x008b, NtQueryMutant, 40 ) \ - SYSCALL_ENTRY( 0x008c, NtQueryObject, 40 ) \ - SYSCALL_ENTRY( 0x008d, NtQueryPerformanceCounter, 16 ) \ - SYSCALL_ENTRY( 0x008e, NtQuerySection, 40 ) \ - SYSCALL_ENTRY( 0x008f, NtQuerySecurityObject, 40 ) \ - SYSCALL_ENTRY( 0x0090, NtQuerySemaphore, 40 ) \ - SYSCALL_ENTRY( 0x0091, NtQuerySymbolicLinkObject, 24 ) \ - SYSCALL_ENTRY( 0x0092, NtQuerySystemEnvironmentValue, 32 ) \ - SYSCALL_ENTRY( 0x0093, NtQuerySystemEnvironmentValueEx, 40 ) \ - SYSCALL_ENTRY( 0x0094, NtQuerySystemInformation, 32 ) \ - SYSCALL_ENTRY( 0x0095, NtQuerySystemInformationEx, 48 ) \ - SYSCALL_ENTRY( 0x0096, NtQuerySystemTime, 8 ) \ - SYSCALL_ENTRY( 0x0097, NtQueryTimer, 40 ) \ - SYSCALL_ENTRY( 0x0098, NtQueryTimerResolution, 24 ) \ - SYSCALL_ENTRY( 0x0099, NtQueryValueKey, 48 ) \ - SYSCALL_ENTRY( 0x009a, NtQueryVirtualMemory, 48 ) \ - SYSCALL_ENTRY( 0x009b, NtQueryVolumeInformationFile, 40 ) \ - SYSCALL_ENTRY( 0x009c, NtQueueApcThread, 40 ) \ - SYSCALL_ENTRY( 0x009d, NtRaiseException, 24 ) \ - SYSCALL_ENTRY( 0x009e, NtRaiseHardError, 48 ) \ - SYSCALL_ENTRY( 0x009f, NtReadFile, 72 ) \ - SYSCALL_ENTRY( 0x00a0, NtReadFileScatter, 72 ) \ - SYSCALL_ENTRY( 0x00a1, NtReadVirtualMemory, 40 ) \ - SYSCALL_ENTRY( 0x00a2, NtRegisterThreadTerminatePort, 8 ) \ - SYSCALL_ENTRY( 0x00a3, NtReleaseKeyedEvent, 32 ) \ - SYSCALL_ENTRY( 0x00a4, NtReleaseMutant, 16 ) \ - SYSCALL_ENTRY( 0x00a5, NtReleaseSemaphore, 24 ) \ - SYSCALL_ENTRY( 0x00a6, NtRemoveIoCompletion, 40 ) \ - SYSCALL_ENTRY( 0x00a7, NtRemoveIoCompletionEx, 48 ) \ - SYSCALL_ENTRY( 0x00a8, NtRemoveProcessDebug, 16 ) \ - SYSCALL_ENTRY( 0x00a9, NtRenameKey, 16 ) \ - SYSCALL_ENTRY( 0x00aa, NtReplaceKey, 24 ) \ - SYSCALL_ENTRY( 0x00ab, NtReplyWaitReceivePort, 32 ) \ - SYSCALL_ENTRY( 0x00ac, NtRequestWaitReplyPort, 24 ) \ - SYSCALL_ENTRY( 0x00ad, NtResetEvent, 16 ) \ - SYSCALL_ENTRY( 0x00ae, NtResetWriteWatch, 24 ) \ - SYSCALL_ENTRY( 0x00af, NtRestoreKey, 24 ) \ - SYSCALL_ENTRY( 0x00b0, NtResumeProcess, 8 ) \ - SYSCALL_ENTRY( 0x00b1, NtResumeThread, 16 ) \ - SYSCALL_ENTRY( 0x00b2, NtRollbackTransaction, 16 ) \ - SYSCALL_ENTRY( 0x00b3, NtSaveKey, 16 ) \ - SYSCALL_ENTRY( 0x00b4, NtSecureConnectPort, 72 ) \ - SYSCALL_ENTRY( 0x00b5, NtSetContextThread, 16 ) \ - SYSCALL_ENTRY( 0x00b6, NtSetDebugFilterState, 24 ) \ - SYSCALL_ENTRY( 0x00b7, NtSetDefaultLocale, 16 ) \ - SYSCALL_ENTRY( 0x00b8, NtSetDefaultUILanguage, 8 ) \ - SYSCALL_ENTRY( 0x00b9, NtSetEaFile, 32 ) \ - SYSCALL_ENTRY( 0x00ba, NtSetEvent, 16 ) \ - SYSCALL_ENTRY( 0x00bb, NtSetInformationDebugObject, 40 ) \ - SYSCALL_ENTRY( 0x00bc, NtSetInformationFile, 40 ) \ - SYSCALL_ENTRY( 0x00bd, NtSetInformationJobObject, 32 ) \ - SYSCALL_ENTRY( 0x00be, NtSetInformationKey, 32 ) \ - SYSCALL_ENTRY( 0x00bf, NtSetInformationObject, 32 ) \ - SYSCALL_ENTRY( 0x00c0, NtSetInformationProcess, 32 ) \ - SYSCALL_ENTRY( 0x00c1, NtSetInformationThread, 32 ) \ - SYSCALL_ENTRY( 0x00c2, NtSetInformationToken, 32 ) \ - SYSCALL_ENTRY( 0x00c3, NtSetInformationVirtualMemory, 48 ) \ - SYSCALL_ENTRY( 0x00c4, NtSetIntervalProfile, 16 ) \ - SYSCALL_ENTRY( 0x00c5, NtSetIoCompletion, 40 ) \ - SYSCALL_ENTRY( 0x00c6, NtSetLdtEntries, 32 ) \ - SYSCALL_ENTRY( 0x00c7, NtSetSecurityObject, 24 ) \ - SYSCALL_ENTRY( 0x00c8, NtSetSystemInformation, 24 ) \ - SYSCALL_ENTRY( 0x00c9, NtSetSystemTime, 16 ) \ - SYSCALL_ENTRY( 0x00ca, NtSetThreadExecutionState, 16 ) \ - SYSCALL_ENTRY( 0x00cb, NtSetTimer, 56 ) \ - SYSCALL_ENTRY( 0x00cc, NtSetTimerResolution, 24 ) \ - SYSCALL_ENTRY( 0x00cd, NtSetValueKey, 48 ) \ - SYSCALL_ENTRY( 0x00ce, NtSetVolumeInformationFile, 40 ) \ - SYSCALL_ENTRY( 0x00cf, NtShutdownSystem, 8 ) \ - SYSCALL_ENTRY( 0x00d0, NtSignalAndWaitForSingleObject, 32 ) \ - SYSCALL_ENTRY( 0x00d1, NtSuspendProcess, 8 ) \ - SYSCALL_ENTRY( 0x00d2, NtSuspendThread, 16 ) \ - SYSCALL_ENTRY( 0x00d3, NtSystemDebugControl, 48 ) \ - SYSCALL_ENTRY( 0x00d4, NtTerminateJobObject, 16 ) \ - SYSCALL_ENTRY( 0x00d5, NtTerminateProcess, 16 ) \ - SYSCALL_ENTRY( 0x00d6, NtTerminateThread, 16 ) \ - SYSCALL_ENTRY( 0x00d7, NtTestAlert, 0 ) \ - SYSCALL_ENTRY( 0x00d8, NtTraceControl, 48 ) \ - SYSCALL_ENTRY( 0x00d9, NtUnloadDriver, 8 ) \ - SYSCALL_ENTRY( 0x00da, NtUnloadKey, 8 ) \ - SYSCALL_ENTRY( 0x00db, NtUnlockFile, 40 ) \ - SYSCALL_ENTRY( 0x00dc, NtUnlockVirtualMemory, 32 ) \ - SYSCALL_ENTRY( 0x00dd, NtUnmapViewOfSection, 16 ) \ - SYSCALL_ENTRY( 0x00de, NtUnmapViewOfSectionEx, 24 ) \ - SYSCALL_ENTRY( 0x00df, NtWaitForAlertByThreadId, 16 ) \ - SYSCALL_ENTRY( 0x00e0, NtWaitForDebugEvent, 32 ) \ - SYSCALL_ENTRY( 0x00e1, NtWaitForKeyedEvent, 32 ) \ - SYSCALL_ENTRY( 0x00e2, NtWaitForMultipleObjects, 40 ) \ - SYSCALL_ENTRY( 0x00e3, NtWaitForSingleObject, 24 ) \ - SYSCALL_ENTRY( 0x00e4, NtWriteFile, 72 ) \ - SYSCALL_ENTRY( 0x00e5, NtWriteFileGather, 72 ) \ - SYSCALL_ENTRY( 0x00e6, NtWriteVirtualMemory, 40 ) \ - SYSCALL_ENTRY( 0x00e7, NtYieldExecution, 0 ) \ - SYSCALL_ENTRY( 0x00e8, wine_nt_to_unix_file_name, 32 ) \ - SYSCALL_ENTRY( 0x00e9, wine_unix_to_nt_file_name, 24 ) + SYSCALL_ENTRY( 0x001b, NtContinueEx, 16 ) \ + SYSCALL_ENTRY( 0x001c, NtCreateDebugObject, 32 ) \ + SYSCALL_ENTRY( 0x001d, NtCreateDirectoryObject, 24 ) \ + SYSCALL_ENTRY( 0x001e, NtCreateEvent, 40 ) \ + SYSCALL_ENTRY( 0x001f, NtCreateFile, 88 ) \ + SYSCALL_ENTRY( 0x0020, NtCreateIoCompletion, 32 ) \ + SYSCALL_ENTRY( 0x0021, NtCreateJobObject, 24 ) \ + SYSCALL_ENTRY( 0x0022, NtCreateKey, 56 ) \ + SYSCALL_ENTRY( 0x0023, NtCreateKeyTransacted, 64 ) \ + SYSCALL_ENTRY( 0x0024, NtCreateKeyedEvent, 32 ) \ + SYSCALL_ENTRY( 0x0025, NtCreateLowBoxToken, 72 ) \ + SYSCALL_ENTRY( 0x0026, NtCreateMailslotFile, 64 ) \ + SYSCALL_ENTRY( 0x0027, NtCreateMutant, 32 ) \ + SYSCALL_ENTRY( 0x0028, NtCreateNamedPipeFile, 112 ) \ + SYSCALL_ENTRY( 0x0029, NtCreatePagingFile, 32 ) \ + SYSCALL_ENTRY( 0x002a, NtCreatePort, 40 ) \ + SYSCALL_ENTRY( 0x002b, NtCreateSection, 56 ) \ + SYSCALL_ENTRY( 0x002c, NtCreateSemaphore, 40 ) \ + SYSCALL_ENTRY( 0x002d, NtCreateSymbolicLinkObject, 32 ) \ + SYSCALL_ENTRY( 0x002e, NtCreateThread, 64 ) \ + SYSCALL_ENTRY( 0x002f, NtCreateThreadEx, 88 ) \ + SYSCALL_ENTRY( 0x0030, NtCreateTimer, 32 ) \ + SYSCALL_ENTRY( 0x0031, NtCreateToken, 104 ) \ + SYSCALL_ENTRY( 0x0032, NtCreateTransaction, 80 ) \ + SYSCALL_ENTRY( 0x0033, NtCreateUserProcess, 88 ) \ + SYSCALL_ENTRY( 0x0034, NtDebugActiveProcess, 16 ) \ + SYSCALL_ENTRY( 0x0035, NtDebugContinue, 24 ) \ + SYSCALL_ENTRY( 0x0036, NtDelayExecution, 16 ) \ + SYSCALL_ENTRY( 0x0037, NtDeleteAtom, 8 ) \ + SYSCALL_ENTRY( 0x0038, NtDeleteFile, 8 ) \ + SYSCALL_ENTRY( 0x0039, NtDeleteKey, 8 ) \ + SYSCALL_ENTRY( 0x003a, NtDeleteValueKey, 16 ) \ + SYSCALL_ENTRY( 0x003b, NtDeviceIoControlFile, 80 ) \ + SYSCALL_ENTRY( 0x003c, NtDisplayString, 8 ) \ + SYSCALL_ENTRY( 0x003d, NtDuplicateObject, 56 ) \ + SYSCALL_ENTRY( 0x003e, NtDuplicateToken, 48 ) \ + SYSCALL_ENTRY( 0x003f, NtEnumerateKey, 48 ) \ + SYSCALL_ENTRY( 0x0040, NtEnumerateValueKey, 48 ) \ + SYSCALL_ENTRY( 0x0041, NtFilterToken, 48 ) \ + SYSCALL_ENTRY( 0x0042, NtFindAtom, 24 ) \ + SYSCALL_ENTRY( 0x0043, NtFlushBuffersFile, 16 ) \ + SYSCALL_ENTRY( 0x0044, NtFlushInstructionCache, 24 ) \ + SYSCALL_ENTRY( 0x0045, NtFlushKey, 8 ) \ + SYSCALL_ENTRY( 0x0046, NtFlushProcessWriteBuffers, 0 ) \ + SYSCALL_ENTRY( 0x0047, NtFlushVirtualMemory, 32 ) \ + SYSCALL_ENTRY( 0x0048, NtFreeVirtualMemory, 32 ) \ + SYSCALL_ENTRY( 0x0049, NtFsControlFile, 80 ) \ + SYSCALL_ENTRY( 0x004a, NtGetContextThread, 16 ) \ + SYSCALL_ENTRY( 0x004b, NtGetCurrentProcessorNumber, 0 ) \ + SYSCALL_ENTRY( 0x004c, NtGetNextThread, 48 ) \ + SYSCALL_ENTRY( 0x004d, NtGetNlsSectionPtr, 40 ) \ + SYSCALL_ENTRY( 0x004e, NtGetWriteWatch, 56 ) \ + SYSCALL_ENTRY( 0x004f, NtImpersonateAnonymousToken, 8 ) \ + SYSCALL_ENTRY( 0x0050, NtInitializeNlsFiles, 24 ) \ + SYSCALL_ENTRY( 0x0051, NtInitiatePowerAction, 32 ) \ + SYSCALL_ENTRY( 0x0052, NtIsProcessInJob, 16 ) \ + SYSCALL_ENTRY( 0x0053, NtListenPort, 16 ) \ + SYSCALL_ENTRY( 0x0054, NtLoadDriver, 8 ) \ + SYSCALL_ENTRY( 0x0055, NtLoadKey, 16 ) \ + SYSCALL_ENTRY( 0x0056, NtLoadKey2, 24 ) \ + SYSCALL_ENTRY( 0x0057, NtLoadKeyEx, 64 ) \ + SYSCALL_ENTRY( 0x0058, NtLockFile, 80 ) \ + SYSCALL_ENTRY( 0x0059, NtLockVirtualMemory, 32 ) \ + SYSCALL_ENTRY( 0x005a, NtMakeTemporaryObject, 8 ) \ + SYSCALL_ENTRY( 0x005b, NtMapViewOfSection, 80 ) \ + SYSCALL_ENTRY( 0x005c, NtMapViewOfSectionEx, 72 ) \ + SYSCALL_ENTRY( 0x005d, NtNotifyChangeDirectoryFile, 72 ) \ + SYSCALL_ENTRY( 0x005e, NtNotifyChangeKey, 80 ) \ + SYSCALL_ENTRY( 0x005f, NtNotifyChangeMultipleKeys, 96 ) \ + SYSCALL_ENTRY( 0x0060, NtOpenDirectoryObject, 24 ) \ + SYSCALL_ENTRY( 0x0061, NtOpenEvent, 24 ) \ + SYSCALL_ENTRY( 0x0062, NtOpenFile, 48 ) \ + SYSCALL_ENTRY( 0x0063, NtOpenIoCompletion, 24 ) \ + SYSCALL_ENTRY( 0x0064, NtOpenJobObject, 24 ) \ + SYSCALL_ENTRY( 0x0065, NtOpenKey, 24 ) \ + SYSCALL_ENTRY( 0x0066, NtOpenKeyEx, 32 ) \ + SYSCALL_ENTRY( 0x0067, NtOpenKeyTransacted, 32 ) \ + SYSCALL_ENTRY( 0x0068, NtOpenKeyTransactedEx, 40 ) \ + SYSCALL_ENTRY( 0x0069, NtOpenKeyedEvent, 24 ) \ + SYSCALL_ENTRY( 0x006a, NtOpenMutant, 24 ) \ + SYSCALL_ENTRY( 0x006b, NtOpenProcess, 32 ) \ + SYSCALL_ENTRY( 0x006c, NtOpenProcessToken, 24 ) \ + SYSCALL_ENTRY( 0x006d, NtOpenProcessTokenEx, 32 ) \ + SYSCALL_ENTRY( 0x006e, NtOpenSection, 24 ) \ + SYSCALL_ENTRY( 0x006f, NtOpenSemaphore, 24 ) \ + SYSCALL_ENTRY( 0x0070, NtOpenSymbolicLinkObject, 24 ) \ + SYSCALL_ENTRY( 0x0071, NtOpenThread, 32 ) \ + SYSCALL_ENTRY( 0x0072, NtOpenThreadToken, 32 ) \ + SYSCALL_ENTRY( 0x0073, NtOpenThreadTokenEx, 40 ) \ + SYSCALL_ENTRY( 0x0074, NtOpenTimer, 24 ) \ + SYSCALL_ENTRY( 0x0075, NtPowerInformation, 40 ) \ + SYSCALL_ENTRY( 0x0076, NtPrivilegeCheck, 24 ) \ + SYSCALL_ENTRY( 0x0077, NtProtectVirtualMemory, 40 ) \ + SYSCALL_ENTRY( 0x0078, NtPulseEvent, 16 ) \ + SYSCALL_ENTRY( 0x0079, NtQueryAttributesFile, 16 ) \ + SYSCALL_ENTRY( 0x007a, NtQueryDefaultLocale, 16 ) \ + SYSCALL_ENTRY( 0x007b, NtQueryDefaultUILanguage, 8 ) \ + SYSCALL_ENTRY( 0x007c, NtQueryDirectoryFile, 88 ) \ + SYSCALL_ENTRY( 0x007d, NtQueryDirectoryObject, 56 ) \ + SYSCALL_ENTRY( 0x007e, NtQueryEaFile, 72 ) \ + SYSCALL_ENTRY( 0x007f, NtQueryEvent, 40 ) \ + SYSCALL_ENTRY( 0x0080, NtQueryFullAttributesFile, 16 ) \ + SYSCALL_ENTRY( 0x0081, NtQueryInformationAtom, 40 ) \ + SYSCALL_ENTRY( 0x0082, NtQueryInformationFile, 40 ) \ + SYSCALL_ENTRY( 0x0083, NtQueryInformationJobObject, 40 ) \ + SYSCALL_ENTRY( 0x0084, NtQueryInformationProcess, 40 ) \ + SYSCALL_ENTRY( 0x0085, NtQueryInformationThread, 40 ) \ + SYSCALL_ENTRY( 0x0086, NtQueryInformationToken, 40 ) \ + SYSCALL_ENTRY( 0x0087, NtQueryInstallUILanguage, 8 ) \ + SYSCALL_ENTRY( 0x0088, NtQueryIoCompletion, 40 ) \ + SYSCALL_ENTRY( 0x0089, NtQueryKey, 40 ) \ + SYSCALL_ENTRY( 0x008a, NtQueryLicenseValue, 40 ) \ + SYSCALL_ENTRY( 0x008b, NtQueryMultipleValueKey, 48 ) \ + SYSCALL_ENTRY( 0x008c, NtQueryMutant, 40 ) \ + SYSCALL_ENTRY( 0x008d, NtQueryObject, 40 ) \ + SYSCALL_ENTRY( 0x008e, NtQueryPerformanceCounter, 16 ) \ + SYSCALL_ENTRY( 0x008f, NtQuerySection, 40 ) \ + SYSCALL_ENTRY( 0x0090, NtQuerySecurityObject, 40 ) \ + SYSCALL_ENTRY( 0x0091, NtQuerySemaphore, 40 ) \ + SYSCALL_ENTRY( 0x0092, NtQuerySymbolicLinkObject, 24 ) \ + SYSCALL_ENTRY( 0x0093, NtQuerySystemEnvironmentValue, 32 ) \ + SYSCALL_ENTRY( 0x0094, NtQuerySystemEnvironmentValueEx, 40 ) \ + SYSCALL_ENTRY( 0x0095, NtQuerySystemInformation, 32 ) \ + SYSCALL_ENTRY( 0x0096, NtQuerySystemInformationEx, 48 ) \ + SYSCALL_ENTRY( 0x0097, NtQuerySystemTime, 8 ) \ + SYSCALL_ENTRY( 0x0098, NtQueryTimer, 40 ) \ + SYSCALL_ENTRY( 0x0099, NtQueryTimerResolution, 24 ) \ + SYSCALL_ENTRY( 0x009a, NtQueryValueKey, 48 ) \ + SYSCALL_ENTRY( 0x009b, NtQueryVirtualMemory, 48 ) \ + SYSCALL_ENTRY( 0x009c, NtQueryVolumeInformationFile, 40 ) \ + SYSCALL_ENTRY( 0x009d, NtQueueApcThread, 40 ) \ + SYSCALL_ENTRY( 0x009e, NtRaiseException, 24 ) \ + SYSCALL_ENTRY( 0x009f, NtRaiseHardError, 48 ) \ + SYSCALL_ENTRY( 0x00a0, NtReadFile, 72 ) \ + SYSCALL_ENTRY( 0x00a1, NtReadFileScatter, 72 ) \ + SYSCALL_ENTRY( 0x00a2, NtReadVirtualMemory, 40 ) \ + SYSCALL_ENTRY( 0x00a3, NtRegisterThreadTerminatePort, 8 ) \ + SYSCALL_ENTRY( 0x00a4, NtReleaseKeyedEvent, 32 ) \ + SYSCALL_ENTRY( 0x00a5, NtReleaseMutant, 16 ) \ + SYSCALL_ENTRY( 0x00a6, NtReleaseSemaphore, 24 ) \ + SYSCALL_ENTRY( 0x00a7, NtRemoveIoCompletion, 40 ) \ + SYSCALL_ENTRY( 0x00a8, NtRemoveIoCompletionEx, 48 ) \ + SYSCALL_ENTRY( 0x00a9, NtRemoveProcessDebug, 16 ) \ + SYSCALL_ENTRY( 0x00aa, NtRenameKey, 16 ) \ + SYSCALL_ENTRY( 0x00ab, NtReplaceKey, 24 ) \ + SYSCALL_ENTRY( 0x00ac, NtReplyWaitReceivePort, 32 ) \ + SYSCALL_ENTRY( 0x00ad, NtRequestWaitReplyPort, 24 ) \ + SYSCALL_ENTRY( 0x00ae, NtResetEvent, 16 ) \ + SYSCALL_ENTRY( 0x00af, NtResetWriteWatch, 24 ) \ + SYSCALL_ENTRY( 0x00b0, NtRestoreKey, 24 ) \ + SYSCALL_ENTRY( 0x00b1, NtResumeProcess, 8 ) \ + SYSCALL_ENTRY( 0x00b2, NtResumeThread, 16 ) \ + SYSCALL_ENTRY( 0x00b3, NtRollbackTransaction, 16 ) \ + SYSCALL_ENTRY( 0x00b4, NtSaveKey, 16 ) \ + SYSCALL_ENTRY( 0x00b5, NtSecureConnectPort, 72 ) \ + SYSCALL_ENTRY( 0x00b6, NtSetContextThread, 16 ) \ + SYSCALL_ENTRY( 0x00b7, NtSetDebugFilterState, 24 ) \ + SYSCALL_ENTRY( 0x00b8, NtSetDefaultLocale, 16 ) \ + SYSCALL_ENTRY( 0x00b9, NtSetDefaultUILanguage, 8 ) \ + SYSCALL_ENTRY( 0x00ba, NtSetEaFile, 32 ) \ + SYSCALL_ENTRY( 0x00bb, NtSetEvent, 16 ) \ + SYSCALL_ENTRY( 0x00bc, NtSetInformationDebugObject, 40 ) \ + SYSCALL_ENTRY( 0x00bd, NtSetInformationFile, 40 ) \ + SYSCALL_ENTRY( 0x00be, NtSetInformationJobObject, 32 ) \ + SYSCALL_ENTRY( 0x00bf, NtSetInformationKey, 32 ) \ + SYSCALL_ENTRY( 0x00c0, NtSetInformationObject, 32 ) \ + SYSCALL_ENTRY( 0x00c1, NtSetInformationProcess, 32 ) \ + SYSCALL_ENTRY( 0x00c2, NtSetInformationThread, 32 ) \ + SYSCALL_ENTRY( 0x00c3, NtSetInformationToken, 32 ) \ + SYSCALL_ENTRY( 0x00c4, NtSetInformationVirtualMemory, 48 ) \ + SYSCALL_ENTRY( 0x00c5, NtSetIntervalProfile, 16 ) \ + SYSCALL_ENTRY( 0x00c6, NtSetIoCompletion, 40 ) \ + SYSCALL_ENTRY( 0x00c7, NtSetLdtEntries, 32 ) \ + SYSCALL_ENTRY( 0x00c8, NtSetSecurityObject, 24 ) \ + SYSCALL_ENTRY( 0x00c9, NtSetSystemInformation, 24 ) \ + SYSCALL_ENTRY( 0x00ca, NtSetSystemTime, 16 ) \ + SYSCALL_ENTRY( 0x00cb, NtSetThreadExecutionState, 16 ) \ + SYSCALL_ENTRY( 0x00cc, NtSetTimer, 56 ) \ + SYSCALL_ENTRY( 0x00cd, NtSetTimerResolution, 24 ) \ + SYSCALL_ENTRY( 0x00ce, NtSetValueKey, 48 ) \ + SYSCALL_ENTRY( 0x00cf, NtSetVolumeInformationFile, 40 ) \ + SYSCALL_ENTRY( 0x00d0, NtShutdownSystem, 8 ) \ + SYSCALL_ENTRY( 0x00d1, NtSignalAndWaitForSingleObject, 32 ) \ + SYSCALL_ENTRY( 0x00d2, NtSuspendProcess, 8 ) \ + SYSCALL_ENTRY( 0x00d3, NtSuspendThread, 16 ) \ + SYSCALL_ENTRY( 0x00d4, NtSystemDebugControl, 48 ) \ + SYSCALL_ENTRY( 0x00d5, NtTerminateJobObject, 16 ) \ + SYSCALL_ENTRY( 0x00d6, NtTerminateProcess, 16 ) \ + SYSCALL_ENTRY( 0x00d7, NtTerminateThread, 16 ) \ + SYSCALL_ENTRY( 0x00d8, NtTestAlert, 0 ) \ + SYSCALL_ENTRY( 0x00d9, NtTraceControl, 48 ) \ + SYSCALL_ENTRY( 0x00da, NtUnloadDriver, 8 ) \ + SYSCALL_ENTRY( 0x00db, NtUnloadKey, 8 ) \ + SYSCALL_ENTRY( 0x00dc, NtUnlockFile, 40 ) \ + SYSCALL_ENTRY( 0x00dd, NtUnlockVirtualMemory, 32 ) \ + SYSCALL_ENTRY( 0x00de, NtUnmapViewOfSection, 16 ) \ + SYSCALL_ENTRY( 0x00df, NtUnmapViewOfSectionEx, 24 ) \ + SYSCALL_ENTRY( 0x00e0, NtWaitForAlertByThreadId, 16 ) \ + SYSCALL_ENTRY( 0x00e1, NtWaitForDebugEvent, 32 ) \ + SYSCALL_ENTRY( 0x00e2, NtWaitForKeyedEvent, 32 ) \ + SYSCALL_ENTRY( 0x00e3, NtWaitForMultipleObjects, 40 ) \ + SYSCALL_ENTRY( 0x00e4, NtWaitForSingleObject, 24 ) \ + SYSCALL_ENTRY( 0x00e5, NtWriteFile, 72 ) \ + SYSCALL_ENTRY( 0x00e6, NtWriteFileGather, 72 ) \ + SYSCALL_ENTRY( 0x00e7, NtWriteVirtualMemory, 40 ) \ + SYSCALL_ENTRY( 0x00e8, NtYieldExecution, 0 ) \ + SYSCALL_ENTRY( 0x00e9, wine_nt_to_unix_file_name, 32 ) \ + SYSCALL_ENTRY( 0x00ea, wine_unix_to_nt_file_name, 24 ) diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 53fcc61ccf3..af5fb210346 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -789,9 +789,36 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f * NtContinue (NTDLL.@) */ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable ) +{ + /* NtContinueEx accepts both */ + return NtContinueEx(context, (CONTINUE_OPTIONS *)(intptr_t)alertable); +} + + +/*********************************************************************** + * NtContinueEx (NTDLL.@) + */ +NTSTATUS WINAPI NtContinueEx( CONTEXT *context, CONTINUE_OPTIONS *options ) { user_apc_t apc; NTSTATUS status; + BOOLEAN alertable; + + if (options <= (CONTINUE_OPTIONS *)0xff) + { + alertable = (BOOLEAN)(intptr_t)options; + } else + { + alertable = !!(options->ContinueFlags & CONTINUE_FLAG_TEST_ALERT); + + /* FIXME: no idea how to handle rest of CONTINUE_OPTIONS stuff */ + if (options->ContinueType != CONTINUE_UNWIND || + options->ContinueFlags > CONTINUE_FLAG_TEST_ALERT || + options->Reserved[0] > 0 || options->Reserved[1] > 0) + { + FIXME("(PCONTEXT, PCONTINUE_OPTIONS) is not implemented!\n"); + } + } if (alertable) { diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c index db51948057f..9954c214222 100644 --- a/dlls/wow64/syscall.c +++ b/dlls/wow64/syscall.c @@ -441,9 +441,19 @@ NTSTATUS WINAPI wow64_NtClose( UINT *args ) * wow64_NtContinue */ NTSTATUS WINAPI wow64_NtContinue( UINT *args ) +{ + return wow64_NtContinueEx( args ); +} + + +/********************************************************************** + * wow64_NtContinueEx + */ +NTSTATUS WINAPI wow64_NtContinueEx( UINT *args ) { void *context = get_ptr( &args ); - BOOLEAN alertable = get_ulong( &args ); + CONTINUE_OPTIONS *options = get_ptr( &args ); + BOOL alertable = options > (CONTINUE_OPTIONS *)0xFF ? options->ContinueFlags & CONTINUE_FLAG_TEST_ALERT : !!options; NTSTATUS status = get_context_return_value( context ); struct user_apc_frame *frame = NtCurrentTeb()->TlsSlots[WOW64_TLS_APCLIST]; @@ -452,7 +462,7 @@ NTSTATUS WINAPI wow64_NtContinue( UINT *args ) while (frame && frame->wow_context != context) frame = frame->prev_frame; NtCurrentTeb()->TlsSlots[WOW64_TLS_APCLIST] = frame ? frame->prev_frame : NULL; - if (frame) NtContinue( frame->context, alertable ); + if (frame) NtContinueEx( frame->context, options ); if (alertable) NtTestAlert(); return status; diff --git a/include/winternl.h b/include/winternl.h index ff8756211a1..a3325f5c398 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4283,6 +4283,26 @@ typedef struct _API_SET_VALUE_ENTRY ULONG ValueLength; } API_SET_VALUE_ENTRY; +typedef enum _CONTINUE_TYPE +{ + CONTINUE_UNWIND, + CONTINUE_RESUME, + CONTINUE_LONGJUMP, + CONTINUE_SET, + CONTINUE_LAST, +} CONTINUE_TYPE; + +typedef struct _CONTINUE_OPTIONS +{ + CONTINUE_TYPE ContinueType; + ULONG ContinueFlags; + ULONGLONG Reserved[2]; +} CONTINUE_OPTIONS, *PCONTINUE_OPTIONS; + +#define CONTINUE_FLAG_TEST_ALERT 0x00000001 +#define CONTINUE_FLAG_DELIVER_APC 0x00000002 + + /*********************************************************************** * Function declarations */ @@ -4358,6 +4378,7 @@ NTSYSAPI NTSTATUS WINAPI NtCompareObjects(HANDLE,HANDLE); NTSYSAPI NTSTATUS WINAPI NtCompleteConnectPort(HANDLE); NTSYSAPI NTSTATUS WINAPI NtConnectPort(PHANDLE,PUNICODE_STRING,PSECURITY_QUALITY_OF_SERVICE,PLPC_SECTION_WRITE,PLPC_SECTION_READ,PULONG,PVOID,PULONG); NTSYSAPI NTSTATUS WINAPI NtContinue(PCONTEXT,BOOLEAN); +NTSYSAPI NTSTATUS WINAPI NtContinueEx(PCONTEXT,PCONTINUE_OPTIONS); /* PCONTINUE_OPTIONS can also be BOOLEAN */ NTSYSAPI NTSTATUS WINAPI NtCreateDebugObject(HANDLE*,ACCESS_MASK,OBJECT_ATTRIBUTES*,ULONG); NTSYSAPI NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES); NTSYSAPI NTSTATUS WINAPI NtCreateEvent(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES *,EVENT_TYPE,BOOLEAN); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4761
From: Dāvis Mosāns <davispuh(a)gmail.com> context and options must be aligned --- dlls/ntdll/unix/server.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index af5fb210346..6f7514d6d0c 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -803,12 +803,28 @@ NTSTATUS WINAPI NtContinueEx( CONTEXT *context, CONTINUE_OPTIONS *options ) user_apc_t apc; NTSTATUS status; BOOLEAN alertable; + const intptr_t alignment_bits = 16 - 1; /* (16-bytes on amd64) */ + + if (!context) + { + return STATUS_ACCESS_VIOLATION; + } + + /* context must be aligned */ + if ((intptr_t)context & alignment_bits) + { + return STATUS_DATATYPE_MISALIGNMENT; + } if (options <= (CONTINUE_OPTIONS *)0xff) { alertable = (BOOLEAN)(intptr_t)options; } else { + if ((intptr_t)options & alignment_bits) + { + return STATUS_DATATYPE_MISALIGNMENT; + } alertable = !!(options->ContinueFlags & CONTINUE_FLAG_TEST_ALERT); /* FIXME: no idea how to handle rest of CONTINUE_OPTIONS stuff */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4761
From: Dāvis Mosāns <davispuh(a)gmail.com> --- dlls/ntdll/tests/exception.c | 38 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index c9223c6108e..54505d56731 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -4413,13 +4413,13 @@ static void test_thread_context(void) #undef COMPARE } -static void test_continue(void) +static void test_continue(BOOL testContinueEx) { struct context_pair { CONTEXT before; CONTEXT after; } contexts; - NTSTATUS (*func_ptr)( struct context_pair *, BOOL alertable, void *continue_func, void *capture_func ) = code_mem; + NTSTATUS (*func_ptr)( struct context_pair *, void *arg2, void *continue_func, void *capture_func ) = code_mem; static const BYTE call_func[] = { @@ -4487,7 +4487,7 @@ static void test_continue(void) /* load args */ 0x48, 0x8b, 0x4c, 0x24, 0x50, /* mov 8*10(%rsp), %rcx; context */ - 0x48, 0x8b, 0x54, 0x24, 0x58, /* mov 8*11(%rsp), %rdx; alertable */ + 0x48, 0x8b, 0x54, 0x24, 0x58, /* mov 8*11(%rsp), %rdx; arg2 */ 0x48, 0x83, 0xec, 0x70, /* sub $0x70, %rsp; change stack */ /* setup context to return to label 1 */ @@ -4548,7 +4548,16 @@ static void test_continue(void) memcpy( func_ptr, call_func, sizeof(call_func) ); FlushInstructionCache( GetCurrentProcess(), func_ptr, sizeof(call_func) ); - func_ptr( &contexts, FALSE, NtContinue, pRtlCaptureContext ); + if (testContinueEx) + { + CONTINUE_OPTIONS opts = { 0 }; + opts.ContinueType = CONTINUE_UNWIND; /* Nothing else is implemented */ + opts.ContinueFlags = 0; /* Disable test alert */ + func_ptr( &contexts, &opts, NtContinueEx, pRtlCaptureContext ); + } else + { + func_ptr( &contexts, FALSE, NtContinue, pRtlCaptureContext ); + } #define COMPARE(reg) \ ok( contexts.before.reg == contexts.after.reg, "wrong " #reg " %p/%p\n", (void *)(ULONG64)contexts.before.reg, (void *)(ULONG64)contexts.after.reg ) @@ -9032,14 +9041,14 @@ static void test_debug_service(DWORD numexc) /* not supported */ } -static void test_continue(void) +static void test_continue(BOOL testContinueEx) { struct context_pair { CONTEXT before; CONTEXT after; } contexts; unsigned int i; - NTSTATUS (*func_ptr)( struct context_pair *, BOOL alertable, void *continue_func, void *capture_func ) = code_mem; + NTSTATUS (*func_ptr)( struct context_pair *, void *arg2, void *continue_func, void *capture_func ) = code_mem; static const DWORD call_func[] = { @@ -9139,7 +9148,16 @@ static void test_continue(void) #define COMPARE_INDEXED(reg) \ ok( contexts.before.reg == contexts.after.reg, "wrong " #reg " i: %u, %p/%p\n", i, (void *)(ULONG64)contexts.before.reg, (void *)(ULONG64)contexts.after.reg ) - func_ptr( &contexts, FALSE, NtContinue, pRtlCaptureContext ); + if (testContinueEx) + { + CONTINUE_OPTIONS opts = { 0 }; + opts.ContinueType = CONTINUE_UNWIND; /* Nothing else is implemented */ + opts.ContinueFlags = 0; /* Disable test alert */ + func_ptr( &contexts, &opts, NtContinueEx, pRtlCaptureContext ); + } else + { + func_ptr( &contexts, FALSE, NtContinue, pRtlCaptureContext ); + } for (i = 1; i < 29; i++) COMPARE_INDEXED( X[i] ); @@ -12618,7 +12636,8 @@ START_TEST(exception) test_debug_registers_wow64(); test_debug_service(1); test_simd_exceptions(); - test_continue(); + test_continue(FALSE /* NtContinue */); + test_continue(TRUE /* NtContinueEx */); test_virtual_unwind(); test___C_specific_handler(); test_restore_context(); @@ -12641,7 +12660,8 @@ START_TEST(exception) #elif defined(__aarch64__) - test_continue(); + test_continue(FALSE /* NtContinue */); + test_continue(TRUE /* NtContinueEx */); test_virtual_unwind(); #elif defined(__arm__) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4761
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=141518 Your paranoid android. === debian11 (build log) === Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report === debian11b (build log) === Task: Could not create the wow32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the wow32 report
On Mon Jan 1 12:20:35 2024 +0000, Dāvis Mosāns (davispuh) wrote:
I don't understand this, why we need `NtTestAlert()` when `NtContinue()` should already do that... You're correct that `NtContinue()` indeed already tests for the alerts.
There's something you've missed, though: `NtContinue` is only called when there is a pending [APC][], which is usually not the case if you're calling it directly outside of an APC. In fact, the heavy lifting here is done by `pBTCpuSetContext` alone. You're looking at an "emulator," called WoW64[^fname]. WoW64 works by switching[^hg] between 32bit mode and 64bit mode in the [user space][]. The 32bit guest app uses `I386_CONTEXT`, while the host process uses `AMD64_CONTEXT`. This means two things: 1. `NtContinue` here will accept host `CONTEXT`, which is synonymous with `AMD64_CONTEXT`. Therefore, this cannot be used to restore 32bit guest context. 2. `pBTCpuSetContext` is actually responsible for setting the 32bit guest context. After this context is set, the next 64bit-to-32bit transition[^hg] will restore this guest context. Note that `frame == NULL` in the usual case (no APC pending), which means that `NtTestAlert` is still needed. If `frame != NULL`, then `NtContinue` (which is a "noreturn" function) will continue executing from the context, which means the `NtTestAlert()` below is not executed at all. [^fname]: This is evident in the filename, `dlls/wow64/syscall.c`. [^hg]: This is made possible by x86 far jump which can switch from 64-bit code segment to a 32-bit code segment, and vice versa. This technique is also known as "Heaven's Gate." [APC]: <https://en.wikipedia.org/wiki/Asynchronous_procedure_call> [user space]: <https://en.wikipedia.org/wiki/User_space_and_kernel_space> -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4761#note_56520
On Mon Jan 1 12:36:54 2024 +0000, Jinoh Kang wrote:
You're correct that `NtContinue()` indeed already tests for the alerts. There's something you've missed, though: `NtContinue` is only called when there is a pending [APC][], which is usually not the case if you're calling it directly outside of an APC. In fact, the heavy lifting here is done by `pBTCpuSetContext` alone. You're looking at an "emulator," called WoW64[^fname]. WoW64 works by switching[^hg] between 32bit mode and 64bit mode in the [user space][]. The 32bit guest app uses `I386_CONTEXT`, while the host process uses `AMD64_CONTEXT`. This means two things: 1. `NtContinue` here will accept host `CONTEXT`, which is synonymous with `AMD64_CONTEXT`. Therefore, this cannot be used to restore 32bit guest context. 2. `pBTCpuSetContext` is actually responsible for setting the 32bit guest context. After this context is set, the next 64bit-to-32bit transition[^hg] will restore this guest context. Note that `frame == NULL` in the usual case (no APC pending), which means that `NtTestAlert` is still needed[^null]. If `frame != NULL`, then `NtContinue` (which is almost a "noreturn" function) will continue executing from the context, which means the `NtTestAlert()` below won't be executed at all. [^fname]: This is evident in the filename, `dlls/wow64/syscall.c`. [^hg]: This is made possible by x86 far jump which can switch from 64-bit code segment to a 32-bit code segment, and vice versa. This technique is also known as "Heaven's Gate." [^null]: If `frame == NULL`, then the condition in `if (frame) NtContinue( frame->context, alertable );` is false. Therefore, the if body won't be executed. Then, the execution continues to `if (alertable) NtTestAlert();` [APC]: <https://en.wikipedia.org/wiki/Asynchronous_procedure_call> [user space]: <https://en.wikipedia.org/wiki/User_space_and_kernel_space> Notice that you could have spot this: `if (frame)` is conditional, so `NtContinue` won't always be executed and the control will transfer to `NtTestAlert()` in this case.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/4761#note_56522
participants (3)
-
Dāvis Mosāns -
Jinoh Kang (@iamahuman) -
Marvin