/*++ Copyright (c) 1989 Microsoft Corporation Module Name: psctx.c Abstract: This procedure implements Get/Set Context Thread Author: Mark Lucovsky (markl) 25-May-1989 Revision History: --*/ #include "psp.h" VOID PspQueueApcSpecialApc( IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2 ) { PAGED_CODE(); ExFreePool(Apc); } NTSYSAPI NTSTATUS NTAPI NtQueueApcThread( IN HANDLE ThreadHandle, IN PPS_APC_ROUTINE ApcRoutine, IN PVOID ApcArgument1, IN PVOID ApcArgument2, IN PVOID ApcArgument3 ) /*++ Routine Description: This function is used to queue a user-mode APC to the specified thread. The APC will fire when the specified thread does an alertable wait Arguments: ThreadHandle - Supplies a handle to a thread object. The caller must have THREAD_SET_CONTEXT access to the thread. ApcRoutine - Supplies the address of the APC routine to execute when the APC fires. ApcArgument1 - Supplies the first PVOID passed to the APC ApcArgument2 - Supplies the second PVOID passed to the APC ApcArgument3 - Supplies the third PVOID passed to the APC Return Value: Returns an NT Status code indicating success or failure of the API --*/ { PETHREAD Thread; NTSTATUS Status; PKAPC Apc; PAGED_CODE(); Status = ObReferenceObjectByHandle(ThreadHandle, &PsThreadObjectType, (PVOID *)&Thread); if (NT_SUCCESS(Status)) { Apc = ExAllocatePoolWithTag(sizeof(*Apc), 'pasP'); if (Apc != NULL) { KeInitializeApc(Apc, &Thread->Tcb, PspQueueApcSpecialApc, NULL, (PKNORMAL_ROUTINE)ApcRoutine, UserMode, ApcArgument1); if (!KeInsertQueueApc(Apc, ApcArgument2, ApcArgument3, 0)) { ExFreePool(Apc); Status = STATUS_UNSUCCESSFUL; } } else { Status = STATUS_NO_MEMORY; } ObDereferenceObject(Thread); } return Status; }