114 lines
2.4 KiB
C
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;
|
|
}
|