00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "psp.h"
00022
00023
#ifdef ALLOC_PRAGMA
00024
#pragma alloc_text(PAGE, NtSuspendThread)
00025
#pragma alloc_text(PAGE, NtResumeThread)
00026
#pragma alloc_text(PAGE, NtAlertThread)
00027
#pragma alloc_text(PAGE, NtAlertResumeThread)
00028
#pragma alloc_text(PAGE, NtTestAlert)
00029
#endif
00030
00031
00032
NTSTATUS
00033 NtSuspendThread(
00034 IN HANDLE ThreadHandle,
00035 OUT PULONG PreviousSuspendCount OPTIONAL
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
PETHREAD Thread;
00062
NTSTATUS st;
00063 ULONG LocalPreviousSuspendCount;
00064
KPROCESSOR_MODE Mode;
00065
00066
PAGED_CODE();
00067
00068
try {
00069
00070 Mode = KeGetPreviousMode();
00071
00072
if ( Mode !=
KernelMode ) {
00073
if (ARGUMENT_PRESENT(PreviousSuspendCount)) {
00074
ProbeForWriteUlong(PreviousSuspendCount);
00075 }
00076 }
00077 } except (
EXCEPTION_EXECUTE_HANDLER) {
00078
00079
return GetExceptionCode();
00080 }
00081
00082 st =
ObReferenceObjectByHandle(
00083
ThreadHandle,
00084 THREAD_SUSPEND_RESUME,
00085
PsThreadType,
00086 Mode,
00087 (PVOID *)&Thread,
00088
NULL
00089 );
00090
00091
if ( !
NT_SUCCESS(st) ) {
00092
return st;
00093 }
00094
00095
try {
00096
00097
if ( Thread !=
PsGetCurrentThread() ) {
00098
if ( Thread->HasTerminated ) {
00099
ObDereferenceObject(Thread);
00100
return STATUS_THREAD_IS_TERMINATING;
00101 }
00102
00103 LocalPreviousSuspendCount = (ULONG)
KeSuspendThread(&Thread->Tcb);
00104
00105 }
else {
00106 LocalPreviousSuspendCount = (ULONG)
KeSuspendThread(&Thread->Tcb);
00107 }
00108
00109
ObDereferenceObject(Thread);
00110
00111
if (ARGUMENT_PRESENT(PreviousSuspendCount))
00112 *PreviousSuspendCount = LocalPreviousSuspendCount;
00113
00114 } except (
EXCEPTION_EXECUTE_HANDLER) {
00115
00116 st = GetExceptionCode();
00117
00118
00119
00120
00121
00122
00123
00124
if ( st == STATUS_SUSPEND_COUNT_EXCEEDED ) {
00125
ObDereferenceObject(Thread);
00126 }
else {
00127 st = STATUS_SUCCESS;
00128 }
00129
00130
return st;
00131 }
00132
00133
return STATUS_SUCCESS;
00134
00135 }
00136
00137
NTSTATUS
00138 NtResumeThread(
00139 IN HANDLE ThreadHandle,
00140 OUT PULONG PreviousSuspendCount OPTIONAL
00141 )
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 {
00163
PETHREAD Thread;
00164
NTSTATUS st;
00165 ULONG LocalPreviousSuspendCount;
00166
KPROCESSOR_MODE Mode;
00167
00168
PAGED_CODE();
00169
00170
try {
00171
00172 Mode = KeGetPreviousMode();
00173
00174
if ( Mode !=
KernelMode ) {
00175
if (ARGUMENT_PRESENT(PreviousSuspendCount))
00176
ProbeForWriteUlong(PreviousSuspendCount);
00177 }
00178 } except (
EXCEPTION_EXECUTE_HANDLER) {
00179
00180
return GetExceptionCode();
00181 }
00182
00183 st =
ObReferenceObjectByHandle(
00184
ThreadHandle,
00185 THREAD_SUSPEND_RESUME,
00186
PsThreadType,
00187 Mode,
00188 (PVOID *)&Thread,
00189
NULL
00190 );
00191
00192
if ( !
NT_SUCCESS(st) ) {
00193
return st;
00194 }
00195
00196 LocalPreviousSuspendCount = (ULONG)
KeResumeThread(&Thread->Tcb);
00197
00198
ObDereferenceObject(Thread);
00199
00200
try {
00201
if (ARGUMENT_PRESENT(PreviousSuspendCount))
00202 *PreviousSuspendCount = LocalPreviousSuspendCount;
00203
00204 } except (
EXCEPTION_EXECUTE_HANDLER) {
00205
00206
return STATUS_SUCCESS;
00207 }
00208
00209
return STATUS_SUCCESS;
00210
00211 }
00212
00213
NTSTATUS
00214 NtAlertThread(
00215 IN HANDLE ThreadHandle
00216 )
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 {
00236
PETHREAD Thread;
00237
NTSTATUS st;
00238
KPROCESSOR_MODE Mode;
00239
00240
PAGED_CODE();
00241
00242 Mode = KeGetPreviousMode();
00243
00244 st =
ObReferenceObjectByHandle(
00245
ThreadHandle,
00246 THREAD_ALERT,
00247
PsThreadType,
00248 Mode,
00249 (PVOID *)&Thread,
00250
NULL
00251 );
00252
00253
if ( !
NT_SUCCESS(st) ) {
00254
return st;
00255 }
00256
00257 (
VOID)
KeAlertThread(&Thread->Tcb,Mode);
00258
00259
ObDereferenceObject(Thread);
00260
00261
return STATUS_SUCCESS;
00262
00263 }
00264
00265
00266
NTSTATUS
00267 NtAlertResumeThread(
00268 IN HANDLE ThreadHandle,
00269 OUT PULONG PreviousSuspendCount OPTIONAL
00270 )
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 {
00292
PETHREAD Thread;
00293
NTSTATUS st;
00294 ULONG LocalPreviousSuspendCount;
00295
KPROCESSOR_MODE Mode;
00296
00297
PAGED_CODE();
00298
00299
try {
00300
00301 Mode = KeGetPreviousMode();
00302
00303
if ( Mode !=
KernelMode ) {
00304
if (ARGUMENT_PRESENT(PreviousSuspendCount)) {
00305
ProbeForWriteUlong(PreviousSuspendCount);
00306 }
00307 }
00308 } except (
EXCEPTION_EXECUTE_HANDLER) {
00309
00310
return GetExceptionCode();
00311 }
00312
00313 st =
ObReferenceObjectByHandle(
00314
ThreadHandle,
00315 THREAD_SUSPEND_RESUME,
00316
PsThreadType,
00317 Mode,
00318 (PVOID *)&Thread,
00319
NULL
00320 );
00321
00322
if ( !
NT_SUCCESS(st) ) {
00323
return st;
00324 }
00325
00326 LocalPreviousSuspendCount = (ULONG)
KeAlertResumeThread(&Thread->Tcb);
00327
00328
ObDereferenceObject(Thread);
00329
00330
try {
00331
00332
if (ARGUMENT_PRESENT(PreviousSuspendCount))
00333 *PreviousSuspendCount = LocalPreviousSuspendCount;
00334
00335 } except (
EXCEPTION_EXECUTE_HANDLER) {
00336
00337
return STATUS_SUCCESS;
00338 }
00339
00340
return STATUS_SUCCESS;
00341 }
00342
00343
00344
NTSTATUS
00345 NtTestAlert(
00346 VOID
00347 )
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 {
00371
00372
PAGED_CODE();
00373
00374
if (
KeTestAlertThread(KeGetPreviousMode()) ) {
00375
return STATUS_ALERTED;
00376 }
else {
00377
return STATUS_SUCCESS;
00378 }
00379 }