#if (PHNT_MODE != PHNT_MODE_KERNEL)
#if (PHNT_VERSION >= PHNT_WIN7)
_In_ HANDLE ThreadHandle,
_In_opt_ HANDLE ReserveHandle, // NtAllocateReserveObject // SPECIAL_USER_APC
_In_ PPS_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcArgument1,
_In_opt_ PVOID ApcArgument2,
_In_opt_ PVOID ApcArgument3
Queues a user-mode Asynchronous Procedure Call (APC) on the specified thread.
ThreadHandle - a handle the the thread granting the
ReserveHandle - an optional handle to the reserve object (see
NtAllocateReserveObject) or a
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:
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
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.
Note that user APCs on the Native API level have three parameters in contrast with the Win32 APCs that only have one.