From 8e01e8763bc45d1ecb71a56a38f93187d1a4daa6 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 25 May 2021 13:15:16 +0200 Subject: [PATCH] ntdll: Implement NtTestAlert(). Signed-off-by: Alexandre Julliard --- dlls/kernel32/tests/sync.c | 20 ++++++++++++++++++++ dlls/ntdll/ntdll.spec | 4 ++-- dlls/ntdll/unix/server.c | 14 ++++++++++++++ dlls/ntdll/unix/signal_x86_64.c | 2 +- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c index bde3e15fe26..827f4c53aa0 100644 --- a/dlls/kernel32/tests/sync.c +++ b/dlls/kernel32/tests/sync.c @@ -64,6 +64,7 @@ static PSLIST_ENTRY (__fastcall *pRtlInterlockedPushListSList)(PSLIST_HEADER lis static PSLIST_ENTRY (WINAPI *pRtlInterlockedPushListSListEx)(PSLIST_HEADER list, PSLIST_ENTRY first, PSLIST_ENTRY last, ULONG count); static NTSTATUS (WINAPI *pNtQueueApcThread)(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR); +static NTSTATUS (WINAPI *pNtTestAlert)(void); #ifdef __i386__ @@ -2712,8 +2713,11 @@ static DWORD WINAPI thread_proc(LPVOID unused) return 0; } +static int apc_count; + static void CALLBACK user_apc(ULONG_PTR unused) { + apc_count++; } static void CALLBACK call_user_apc(ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3) @@ -2726,6 +2730,7 @@ static void test_QueueUserAPC(void) { HANDLE thread; DWORD tid, ret; + NTSTATUS status; thread = CreateThread(NULL, 0, thread_proc, NULL, CREATE_SUSPENDED, &tid); ok(thread != NULL, "CreateThread error %u\n", GetLastError()); @@ -2748,15 +2753,29 @@ static void test_QueueUserAPC(void) CloseHandle(thread); + apc_count = 0; ret = QueueUserAPC(user_apc, GetCurrentThread(), 0); ok(ret, "QueueUserAPC failed err %u\n", GetLastError()); + ok(!apc_count, "APC count %u\n", apc_count); ret = SleepEx( 100, TRUE ); ok( ret == WAIT_IO_COMPLETION, "SleepEx returned %u\n", ret); + ok(apc_count == 1, "APC count %u\n", apc_count); ret = pNtQueueApcThread( GetCurrentThread(), NULL, 0, 0, 0 ); ok( !ret, "got %#x\n", ret); ret = SleepEx( 100, TRUE ); ok( ret == WAIT_OBJECT_0, "SleepEx returned %u\n", ret); + + apc_count = 0; + ret = QueueUserAPC(user_apc, GetCurrentThread(), 0); + ok(ret, "QueueUserAPC failed err %u\n", GetLastError()); + ok(!apc_count, "APC count %u\n", apc_count); + status = pNtTestAlert(); + ok(!status, "got %x\n", status); + ok(apc_count == 1, "APC count %u\n", apc_count); + status = pNtTestAlert(); + ok(!status, "got %x\n", status); + ok(apc_count == 1, "APC count %u\n", apc_count); } START_TEST(sync) @@ -2790,6 +2809,7 @@ START_TEST(sync) pRtlInterlockedPushListSList = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSList"); pRtlInterlockedPushListSListEx = (void *)GetProcAddress(hntdll, "RtlInterlockedPushListSListEx"); pNtQueueApcThread = (void *)GetProcAddress(hntdll, "NtQueueApcThread"); + pNtTestAlert = (void *)GetProcAddress(hntdll, "NtTestAlert"); argc = winetest_get_mainargs( &argv ); if (argc >= 3) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 4eb7aec1aa5..c092e7a9d78 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -412,7 +412,7 @@ @ stdcall -syscall NtTerminateJobObject(long long) @ stdcall -syscall NtTerminateProcess(long long) @ stdcall -syscall NtTerminateThread(long long) -@ stub NtTestAlert +@ stdcall -syscall NtTestAlert() # @ stub NtTraceEvent # @ stub NtTranslateFilePath @ stdcall -syscall NtUnloadDriver(ptr) @@ -1425,7 +1425,7 @@ @ stdcall -private -syscall ZwTerminateJobObject(long long) NtTerminateJobObject @ stdcall -private -syscall ZwTerminateProcess(long long) NtTerminateProcess @ stdcall -private -syscall ZwTerminateThread(long long) NtTerminateThread -@ stub ZwTestAlert +@ stdcall -private -syscall ZwTestAlert() NtTestAlert # @ stub ZwTraceEvent # @ stub ZwTranslateFilePath @ stdcall -private -syscall ZwUnloadDriver(ptr) NtUnloadDriver diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index e30f2dd683d..c0cf13b3cb4 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -720,6 +720,20 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable ) } +/*********************************************************************** + * NtTestAlert (NTDLL.@) + */ +NTSTATUS WINAPI NtTestAlert(void) +{ + user_apc_t apc; + NTSTATUS status; + + status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, NULL, &apc ); + if (status == STATUS_USER_APC) invoke_user_apc( NULL, &apc, STATUS_SUCCESS ); + return STATUS_SUCCESS; +} + + /*********************************************************************** * server_queue_process_apc */ diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 5897e793b3e..0b7dde1b931 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1973,7 +1973,7 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec ) */ struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *context, struct apc_stack_layout *stack, - NSTATUS status ) + NTSTATUS status ) { CONTEXT c;