2020-09-30 17:17:25 +02:00

114 lines
2.4 KiB
C

/*++
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;
}