2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ke/apc.c
5 * PURPOSE: Possible implementation of APCs
6 * PROGRAMMER: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
15 #include <internal/string.h>
16 #include <internal/i386/segment.h>
17 #include <internal/ps.h>
20 #include <internal/debug.h>
22 extern VOID
KeApcProlog(VOID
);
24 /* FUNCTIONS *****************************************************************/
26 VOID
KeApcProlog2(PKAPC Apc
)
28 Apc
->KernelRoutine(Apc
,
31 &Apc
->SystemArgument2
,
32 &Apc
->SystemArgument2
);
33 PsSuspendThread(CONTAINING_RECORD(Apc
->Thread
,ETHREAD
,Tcb
));
36 VOID
KeDeliverKernelApc(PKAPC Apc
)
38 * FUNCTION: Simulates an interrupt on the target thread which will transfer
39 * control to a kernel mode routine
42 PKTHREAD TargetThread
;
45 TargetThread
= Apc
->Thread
;
47 if (TargetThread
== KeGetCurrentThread())
49 Apc
->KernelRoutine(Apc
,
52 &Apc
->SystemArgument2
,
53 &Apc
->SystemArgument2
);
57 if (TargetThread
->Context
.cs
== KERNEL_CS
)
59 TargetThread
->Context
.esp
= TargetThread
->Context
.esp
- 16;
60 Stack
= (PULONG
)TargetThread
->Context
.esp
;
61 Stack
[0] = TargetThread
->Context
.eax
;
62 Stack
[1] = TargetThread
->Context
.eip
;
63 Stack
[2] = TargetThread
->Context
.cs
;
64 Stack
[3] = TargetThread
->Context
.eflags
;
65 TargetThread
->Context
.eip
= (ULONG
)KeApcProlog
;
66 TargetThread
->Context
.eax
= (ULONG
)Apc
;
70 TargetThread
->Context
.esp
= TargetThread
->Context
.esp
- 40;
71 Stack
= (PULONG
)TargetThread
->Context
.esp
;
72 Stack
[9] = TargetThread
->Context
.ss
;
73 Stack
[8] = TargetThread
->Context
.esp
;
74 Stack
[7] = TargetThread
->Context
.gs
;
75 Stack
[6] = TargetThread
->Context
.fs
;
76 Stack
[5] = TargetThread
->Context
.ds
;
77 Stack
[4] = TargetThread
->Context
.es
;
78 Stack
[3] = TargetThread
->Context
.eflags
;
79 Stack
[2] = TargetThread
->Context
.cs
;
80 Stack
[1] = TargetThread
->Context
.eip
;
81 Stack
[0] = TargetThread
->Context
.eax
;
82 TargetThread
->Context
.eip
= (ULONG
)KeApcProlog
;
83 TargetThread
->Context
.eax
= (ULONG
)Apc
;
86 PsResumeThread(CONTAINING_RECORD(TargetThread
,ETHREAD
,Tcb
));
89 void KeInsertQueueApc(struct _KAPC
*Apc
, PVOID SystemArgument1
,
90 PVOID SystemArgument2
, UCHAR Mode
)
94 DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
95 "SystemArgument2 %x, Mode %d)\n",Apc
,SystemArgument1
,
96 SystemArgument2
,Mode
);
98 KeRaiseIrql(DISPATCH_LEVEL
,&oldlvl
);
100 if (Apc
->KernelRoutine
!= NULL
)
102 KeDeliverKernelApc(Apc
);
107 VOID
KeInitializeApc(PKAPC Apc
,
110 PKKERNEL_ROUTINE KernelRoutine
,
111 PKRUNDOWN_ROUTINE RundownRoutine
,
112 PKNORMAL_ROUTINE NormalRoutine
,
116 memset(Apc
,0,sizeof(KAPC
));
117 Apc
->Thread
= Thread
;
118 Apc
->ApcListEntry
.Flink
=NULL
;
119 Apc
->ApcListEntry
.Blink
=NULL
;
120 Apc
->KernelRoutine
=KernelRoutine
;
121 Apc
->RundownRoutine
=RundownRoutine
;
122 Apc
->NormalRoutine
=NormalRoutine
;
123 Apc
->NormalContext
=Context
;
125 Apc
->ApcStateIndex
=StateIndex
;
130 NTSTATUS STDCALL
NtQueueApcThread(HANDLE ThreadHandle
,
131 PKNORMAL_ROUTINE ApcRoutine
,
133 PVOID SystemArgument1
,
134 PVOID SystemArgument2
)
136 return(ZwQueueApcThread(ThreadHandle
,
143 NTSTATUS STDCALL
ZwQueueApcThread(HANDLE ThreadHandle
,
144 PKNORMAL_ROUTINE ApcRoutine
,
146 PVOID SystemArgument1
,
147 PVOID SystemArgument2
)
152 NTSTATUS STDCALL
NtTestAlert(VOID
)
154 return(ZwTestAlert());
157 NTSTATUS STDCALL
ZwTestAlert(VOID
)