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
#include "FsRtlP.h"
00026
00027
00028
00029
00030
00031 KQUEUE FsRtlWorkerQueues[2];
00032
00033
00034
00035
00036
00037
#undef MODULE_POOL_TAG
00038 #define MODULE_POOL_TAG ('srSF')
00039
00040
00041
00042
00043
00044
00045
VOID
00046
FsRtlStackOverflowRead (
00047 IN PVOID Context
00048 );
00049
00050
VOID
00051
FsRtlpPostStackOverflow (
00052 IN PVOID Context,
00053 IN
PKEVENT Event,
00054 IN
PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine,
00055 IN BOOLEAN PagingFile
00056 );
00057
00058
00059
00060
00061
00062
VOID
00063
FsRtlWorkerThread(
00064 IN PVOID StartContext
00065 );
00066
00067
00068
00069
00070
00071 typedef struct _STACK_OVERFLOW_ITEM {
00072
00073 WORK_QUEUE_ITEM Item;
00074
00075
00076
00077
00078
00079 PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine;
00080
00081
00082
00083
00084
00085 PVOID
Context;
00086 PKEVENT Event;
00087
00088 }
STACK_OVERFLOW_ITEM;
00089 typedef STACK_OVERFLOW_ITEM *
PSTACK_OVERFLOW_ITEM;
00090
00091
00092
#ifdef ALLOC_PRAGMA
00093
#pragma alloc_text(INIT, FsRtlInitializeWorkerThread)
00094
#endif
00095
00096
00097
00098
NTSTATUS
00099 FsRtlInitializeWorkerThread (
00100 VOID
00101 )
00102 {
00103 OBJECT_ATTRIBUTES
ObjectAttributes;
00104 HANDLE Thread;
00105 ULONG i;
00106
00107
00108
00109
00110
00111 InitializeObjectAttributes(&
ObjectAttributes,
NULL, 0,
NULL,
NULL);
00112
00113
for (i=0; i < 2; i++) {
00114
00115
00116
00117
00118
00119
KeInitializeQueue(&
FsRtlWorkerQueues[i], 0);
00120
00121
if (!
NT_SUCCESS(
PsCreateSystemThread(&Thread,
00122 THREAD_ALL_ACCESS,
00123 &
ObjectAttributes,
00124 0
L,
00125
NULL,
00126
FsRtlWorkerThread,
00127 ULongToPtr( i )))) {
00128
00129
return FALSE;
00130 }
00131 }
00132
00133 ZwClose( Thread );
00134
00135
return TRUE;
00136 }
00137
00138
VOID
00139 FsRtlPostStackOverflow (
00140 IN PVOID Context,
00141 IN
PKEVENT Event,
00142 IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine
00143 )
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 {
00171
FsRtlpPostStackOverflow( Context,
Event, StackOverflowRoutine,
FALSE );
00172
return;
00173 }
00174
00175
00176
VOID
00177 FsRtlPostPagingFileStackOverflow (
00178 IN PVOID Context,
00179 IN
PKEVENT Event,
00180 IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine
00181 )
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 {
00209
FsRtlpPostStackOverflow( Context,
Event, StackOverflowRoutine,
TRUE );
00210
return;
00211 }
00212
00213
00214
VOID
00215 FsRtlpPostStackOverflow (
00216 IN PVOID Context,
00217 IN
PKEVENT Event,
00218 IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine,
00219 IN BOOLEAN PagingFile
00220 )
00221
00222
00223
00224
00225
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
PSTACK_OVERFLOW_ITEM StackOverflowItem;
00251
00252
00253
00254
00255
00256
00257 StackOverflowItem =
FsRtlpAllocatePool( PagingFile ?
00258
NonPagedPoolMustSucceed :
00259
NonPagedPool,
00260
sizeof(
STACK_OVERFLOW_ITEM) );
00261
00262
00263
00264
00265
00266 StackOverflowItem->
Context = Context;
00267 StackOverflowItem->
Event =
Event;
00268 StackOverflowItem->
StackOverflowRoutine = StackOverflowRoutine;
00269
00270
ExInitializeWorkItem( &StackOverflowItem->
Item,
00271 &
FsRtlStackOverflowRead,
00272 StackOverflowItem );
00273
00274
00275
00276
00277
00278
KeInsertQueue( &
FsRtlWorkerQueues[PagingFile],
00279 &StackOverflowItem->
Item.
List );
00280
00281
00282
00283
00284
00285
return;
00286 }
00287
00288
00289
00290
00291
00292
00293
VOID
00294 FsRtlStackOverflowRead (
00295 IN PVOID Context
00296 )
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 {
00314
PSTACK_OVERFLOW_ITEM StackOverflowItem;
00315
00316
00317
00318
00319
00320
00321
00322
PsGetCurrentThread()->TopLevelIrp =
FSRTL_FSP_TOP_LEVEL_IRP;
00323
00324
00325
00326
00327
00328
00329 StackOverflowItem = (
PSTACK_OVERFLOW_ITEM)Context;
00330
00331 (StackOverflowItem->
StackOverflowRoutine)(StackOverflowItem->
Context,
00332 StackOverflowItem->
Event);
00333
00334
00335
00336
00337
00338
00339
ExFreePool( StackOverflowItem );
00340
00341
PsGetCurrentThread()->TopLevelIrp = (ULONG_PTR)
NULL;
00342 }
00343
00344
VOID
00345 FsRtlWorkerThread(
00346 IN PVOID StartContext
00347 )
00348
00349 {
00350 PLIST_ENTRY Entry;
00351
PWORK_QUEUE_ITEM WorkItem;
00352 ULONG PagingFile = (ULONG)(ULONG_PTR)StartContext;
00353
00354
00355
00356
00357
00358 (
VOID)
KeSetPriorityThread( &
PsGetCurrentThread()->Tcb,
00359 LOW_REALTIME_PRIORITY + PagingFile );
00360
00361
00362
00363
00364
00365
00366
do {
00367
00368
00369
00370
00371
00372
00373
00374
00375 Entry =
KeRemoveQueue(&
FsRtlWorkerQueues[PagingFile],
KernelMode,
NULL);
00376 WorkItem = CONTAINING_RECORD(Entry,
WORK_QUEUE_ITEM,
List);
00377
00378
00379
00380
00381
00382 (WorkItem->
WorkerRoutine)(WorkItem->
Parameter);
00383
if (KeGetCurrentIrql() != 0) {
00384
KeBugCheckEx(
00385
IRQL_NOT_LESS_OR_EQUAL,
00386 (ULONG_PTR)WorkItem->
WorkerRoutine,
00387 (ULONG_PTR)KeGetCurrentIrql(),
00388 (ULONG_PTR)WorkItem->
WorkerRoutine,
00389 (ULONG_PTR)WorkItem
00390 );
00391 }
00392
00393 }
while(
TRUE);
00394 }