#ifndef _NTPSAPI_H
//
// Threads
//
#if (PHNT_MODE != PHNT_MODE_KERNEL)
#if (PHNT_VERSION >= PHNT_WIN7)
/**
* Queues an APC (Asynchronous Procedure Call) to a thread.
*
* @param ThreadHandle Handle to the thread to which the APC is to be queued.
* @param ReserveHandle Optional handle to a reserve object. This can be QUEUE_USER_APC_SPECIAL_USER_APC or a handle returned by NtAllocateReserveObject.
* @param ApcRoutine A pointer to the RtlDispatchAPC function or custom APC routine to be executed.
* @param ApcArgument1 Optional first argument to be passed to the APC routine.
* @param ApcArgument2 Optional second argument to be passed to the APC routine.
* @param ApcArgument3 Optional third argument to be passed to the APC routine.
* @return NTSTATUS Successful or errant status.
* @remarks The APC will be executed in the context of the specified thread after the thread enters an alertable wait state or immediately
* when QUEUE_USER_APC_SPECIAL_USER_APC is used or NtTestAlert, NtAlertThread, NtAlertResumeThread or NtAlertThreadByThreadId are called.
*/
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueueApcThreadEx(
_In_ HANDLE ThreadHandle,
_In_opt_ HANDLE ReserveHandle, // NtAllocateReserveObject // QUEUE_USER_APC_SPECIAL_USER_APC
_In_ PPS_APC_ROUTINE ApcRoutine, // RtlDispatchAPC
_In_opt_ PVOID ApcArgument1,
_In_opt_ PVOID ApcArgument2,
_In_opt_ PVOID ApcArgument3
);
View code on GitHub
#ifndef _NTZWAPI_H
NTSYSCALLAPI
NTSTATUS
NTAPI
ZwQueueApcThreadEx(
_In_ HANDLE ThreadHandle,
_In_opt_ HANDLE ReserveHandle, // NtAllocateReserveObject // QUEUE_USER_APC_SPECIAL_USER_APC
_In_ PPS_APC_ROUTINE ApcRoutine, // RtlDispatchAPC
_In_opt_ PVOID ApcArgument1,
_In_opt_ PVOID ApcArgument2,
_In_opt_ PVOID ApcArgument3
);
View code on GitHub
Queues a user-mode Asynchronous Procedure Call (APC) on the specified thread.
ThreadHandle
- a handle the the thread granting the THREAD_SET_CONTEXT
access.ReserveHandle
- an optional handle to the reserve object (see NtAllocateReserveObject
) or a QUEUE_USER_APC_SPECIAL_USER_APC
constant.ApcRoutine
- the address of the function to invoke.ApcArgument1
- the first argument to pass to the APC routine.ApcArgument2
- the second argument to pass to the APC routine.ApcArgument3
- the third argument to pass to the APC routine.This function has three modes of operation:
ReserveHandle
is NULL
, the function behaves identically to NtQueueApcThread
. To execute the APC, the thread must first enter an alertable wait via NtDelayExecution
(or a similar function) or call NtTestAlert
.ReserveHandle
is a handle to the reserve object, the function uses this object to avoid additional memory allocations. Otherwise, the behavior is identical to option 1.ReserveHandle
is the QUEUE_USER_APC_SPECIAL_USER_APC
value, the function queues a special user-mode APC that does not require the thread to enter an alertable state. The APC will be executed on the next thread's transition to user mode. This flag is supported on Windows 10 RS5 (1809) and above. Because execution of special APCs is not synchronized with the target thread (which might happen to acquire locks), it is crucial to keep the amount and complexity of the code invoked by the special APC routine to a minimum.To queue a WoW64 APC, encode the ApcRoutine
parameter using the Wow64EncodeApcRoutine
macro or use RtlQueueApcWow64Thread
.
Note that user APCs on the Native API level have three parameters in contrast with the Win32 APCs that only have one.