00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "ki.h"
00028
00029
VOID
00030 KiDeliverApc (
00031 IN KPROCESSOR_MODE PreviousMode,
00032 IN PKEXCEPTION_FRAME ExceptionFrame,
00033 IN PKTRAP_FRAME TrapFrame
00034 )
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 {
00066
00067
PKAPC Apc;
00068
PKKERNEL_ROUTINE KernelRoutine;
00069 PLIST_ENTRY NextEntry;
00070 PVOID NormalContext;
00071
PKNORMAL_ROUTINE NormalRoutine;
00072 KIRQL OldIrql;
00073 PVOID SystemArgument1;
00074 PVOID SystemArgument2;
00075
PKTHREAD Thread;
00076
00077
00078
00079
00080
00081 Thread =
KeGetCurrentThread();
00082
KiLockApcQueue(Thread, &OldIrql);
00083
00084
00085
00086
00087
00088
00089 Thread->
ApcState.
KernelApcPending =
FALSE;
00090
while (IsListEmpty(&Thread->
ApcState.
ApcListHead[
KernelMode]) ==
FALSE) {
00091 NextEntry = Thread->
ApcState.
ApcListHead[
KernelMode].Flink;
00092 Apc = CONTAINING_RECORD(NextEntry,
KAPC, ApcListEntry);
00093 KernelRoutine = Apc->
KernelRoutine;
00094 NormalRoutine = Apc->
NormalRoutine;
00095 NormalContext = Apc->
NormalContext;
00096 SystemArgument1 = Apc->
SystemArgument1;
00097 SystemArgument2 = Apc->
SystemArgument2;
00098
if (NormalRoutine == (
PKNORMAL_ROUTINE)
NULL) {
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 RemoveEntryList(NextEntry);
00109 Apc->
Inserted =
FALSE;
00110
KiUnlockApcQueue(Thread, OldIrql);
00111 (KernelRoutine)(Apc, &NormalRoutine, &NormalContext,
00112 &SystemArgument1, &SystemArgument2);
00113
00114
#if DBG
00115
00116
if (KeGetCurrentIrql() != OldIrql) {
00117
KeBugCheckEx(IRQL_UNEXPECTED_VALUE,
00118 KeGetCurrentIrql() << 16 | OldIrql << 8,
00119 (ULONG_PTR)KernelRoutine,
00120 (ULONG_PTR)Apc,
00121 (ULONG_PTR)NormalRoutine);
00122 }
00123
00124
#endif
00125
00126
KiLockApcQueue(Thread, &OldIrql);
00127
00128 }
else {
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
if ((Thread->
ApcState.
KernelApcInProgress ==
FALSE) &&
00142 (Thread->
KernelApcDisable == 0)) {
00143 RemoveEntryList(NextEntry);
00144 Apc->
Inserted =
FALSE;
00145
KiUnlockApcQueue(Thread, OldIrql);
00146 (KernelRoutine)(Apc, &NormalRoutine, &NormalContext,
00147 &SystemArgument1, &SystemArgument2);
00148
00149
#if DBG
00150
00151
if (KeGetCurrentIrql() != OldIrql) {
00152
KeBugCheckEx(IRQL_UNEXPECTED_VALUE,
00153 KeGetCurrentIrql() << 16 | OldIrql << 8 | 1,
00154 (ULONG_PTR)KernelRoutine,
00155 (ULONG_PTR)Apc,
00156 (ULONG_PTR)NormalRoutine);
00157 }
00158
00159
#endif
00160
00161
if (NormalRoutine != (
PKNORMAL_ROUTINE)
NULL) {
00162 Thread->
ApcState.
KernelApcInProgress =
TRUE;
00163
KeLowerIrql(0);
00164 (NormalRoutine)(NormalContext, SystemArgument1,
00165 SystemArgument2);
00166
KeRaiseIrql(
APC_LEVEL, &OldIrql);
00167 }
00168
00169
KiLockApcQueue(Thread, &OldIrql);
00170 Thread->
ApcState.
KernelApcInProgress =
FALSE;
00171
00172 }
else {
00173
KiUnlockApcQueue(Thread, OldIrql);
00174
return;
00175 }
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
if ((IsListEmpty(&Thread->
ApcState.
ApcListHead[
UserMode]) ==
FALSE) &&
00191 (PreviousMode ==
UserMode) && (Thread->
ApcState.
UserApcPending ==
TRUE)) {
00192 Thread->
ApcState.
UserApcPending =
FALSE;
00193 NextEntry = Thread->
ApcState.
ApcListHead[
UserMode].Flink;
00194 Apc = CONTAINING_RECORD(NextEntry,
KAPC, ApcListEntry);
00195 KernelRoutine = Apc->
KernelRoutine;
00196 NormalRoutine = Apc->
NormalRoutine;
00197 NormalContext = Apc->
NormalContext;
00198 SystemArgument1 = Apc->
SystemArgument1;
00199 SystemArgument2 = Apc->
SystemArgument2;
00200 RemoveEntryList(NextEntry);
00201 Apc->
Inserted =
FALSE;
00202
KiUnlockApcQueue(Thread, OldIrql);
00203 (KernelRoutine)(Apc, &NormalRoutine, &NormalContext,
00204 &SystemArgument1, &SystemArgument2);
00205
00206
if (NormalRoutine == (
PKNORMAL_ROUTINE)
NULL) {
00207
KeTestAlertThread(
UserMode);
00208
00209 }
else {
00210
KiInitializeUserApc(ExceptionFrame, TrapFrame, NormalRoutine,
00211 NormalContext, SystemArgument1, SystemArgument2);
00212 }
00213
00214 }
else {
00215
KiUnlockApcQueue(Thread, OldIrql);
00216 }
00217
00218
return;
00219 }
00220
00221 BOOLEAN
00222
FASTCALL
00223 KiInsertQueueApc (
00224 IN
PKAPC Apc,
00225 IN KPRIORITY Increment
00226 )
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 {
00255
00256
KPROCESSOR_MODE ApcMode;
00257
PKAPC ApcEntry;
00258
PKAPC_STATE ApcState;
00259 BOOLEAN Inserted;
00260 PLIST_ENTRY ListEntry;
00261
PKTHREAD Thread;
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 Thread = Apc->Thread;
00277 KiAcquireSpinLock(&Thread->
ApcQueueLock);
00278
if (Apc->Inserted) {
00279 Inserted =
FALSE;
00280
00281 }
else {
00282 ApcState = Thread->
ApcStatePointer[Apc->ApcStateIndex];
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 ApcMode = Apc->ApcMode;
00294
if (Apc->NormalRoutine !=
NULL) {
00295
if ((ApcMode !=
KernelMode) && (Apc->KernelRoutine ==
PsExitSpecialApc)) {
00296 Thread->
ApcState.
UserApcPending =
TRUE;
00297 InsertHeadList(&ApcState->
ApcListHead[ApcMode],
00298 &Apc->ApcListEntry);
00299
00300 }
else {
00301 InsertTailList(&ApcState->
ApcListHead[ApcMode],
00302 &Apc->ApcListEntry);
00303 }
00304
00305 }
else {
00306 ListEntry = ApcState->
ApcListHead[ApcMode].Flink;
00307
while (ListEntry != &ApcState->
ApcListHead[ApcMode]) {
00308 ApcEntry = CONTAINING_RECORD(ListEntry,
KAPC, ApcListEntry);
00309
if (ApcEntry->
NormalRoutine !=
NULL) {
00310
break;
00311 }
00312
00313 ListEntry = ListEntry->Flink;
00314 }
00315
00316 ListEntry = ListEntry->Blink;
00317 InsertHeadList(ListEntry, &Apc->ApcListEntry);
00318 }
00319
00320 Apc->Inserted =
TRUE;
00321
00322
00323
00324
00325
00326
00327
00328
if (Apc->ApcStateIndex == Thread->
ApcStateIndex) {
00329
00330
00331
00332
00333
00334
00335
00336
00337
if (ApcMode ==
KernelMode) {
00338 Thread->
ApcState.
KernelApcPending =
TRUE;
00339
if (Thread->
State ==
Running) {
00340
KiRequestApcInterrupt(Thread->
NextProcessor);
00341
00342 }
else if ((Thread->
State ==
Waiting) &&
00343 (Thread->
WaitIrql == 0) &&
00344 ((Apc->NormalRoutine ==
NULL) ||
00345 ((Thread->
KernelApcDisable == 0) &&
00346 (Thread->
ApcState.
KernelApcInProgress ==
FALSE)))) {
00347
KiUnwaitThread(Thread, STATUS_KERNEL_APC,
Increment);
00348 }
00349
00350 }
else if ((Thread->
State ==
Waiting) &&
00351 (Thread->
WaitMode ==
UserMode) &&
00352 (Thread->
Alertable)) {
00353 Thread->
ApcState.
UserApcPending =
TRUE;
00354
KiUnwaitThread(Thread, STATUS_USER_APC,
Increment);
00355 }
00356 }
00357
00358 Inserted =
TRUE;
00359 }
00360
00361
00362
00363
00364
00365
00366 KiReleaseSpinLock(&Thread->
ApcQueueLock);
00367
return Inserted;
00368 }