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
00030
00031
00032
00033
00034 #define ASSERT_DEVICE_QUEUE(E) { \
00035
ASSERT((E)->Type == DeviceQueueObject); \
00036
}
00037
00038
00039
VOID
00040 KeInitializeDeviceQueue (
00041 IN
PKDEVICE_QUEUE DeviceQueue
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
00068
00069 DeviceQueue->Type =
DeviceQueueObject;
00070 DeviceQueue->Size =
sizeof(
KDEVICE_QUEUE);
00071
00072
00073
00074
00075
00076 InitializeListHead(&DeviceQueue->DeviceListHead);
00077
KeInitializeSpinLock(&DeviceQueue->Lock);
00078 DeviceQueue->Busy =
FALSE;
00079
return;
00080 }
00081
00082 BOOLEAN
00083 KeInsertDeviceQueue (
00084 IN
PKDEVICE_QUEUE DeviceQueue,
00085 IN
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
00086 )
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 {
00113
00114 BOOLEAN Inserted;
00115
00116
ASSERT_DEVICE_QUEUE(DeviceQueue);
00117
ASSERT(KeGetCurrentIrql() ==
DISPATCH_LEVEL);
00118
00119
00120
00121
00122
00123 KiAcquireSpinLock(&DeviceQueue->Lock);
00124
00125
00126
00127
00128
00129
00130
00131
if (DeviceQueue->Busy ==
TRUE) {
00132 Inserted =
TRUE;
00133 InsertTailList(&DeviceQueue->DeviceListHead,
00134 &DeviceQueueEntry->DeviceListEntry);
00135 }
else {
00136 DeviceQueue->Busy =
TRUE;
00137 Inserted =
FALSE;
00138 }
00139 DeviceQueueEntry->Inserted = Inserted;
00140 KiReleaseSpinLock(&DeviceQueue->Lock);
00141
return Inserted;
00142 }
00143
00144 BOOLEAN
00145 KeInsertByKeyDeviceQueue (
00146 IN
PKDEVICE_QUEUE DeviceQueue,
00147 IN
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
00148 IN ULONG SortKey
00149 )
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 {
00181
00182 BOOLEAN Inserted;
00183 PLIST_ENTRY NextEntry;
00184
PKDEVICE_QUEUE_ENTRY QueueEntry;
00185
00186
ASSERT_DEVICE_QUEUE(DeviceQueue);
00187
ASSERT(KeGetCurrentIrql() ==
DISPATCH_LEVEL);
00188
00189
00190
00191
00192
00193 KiAcquireSpinLock(&DeviceQueue->Lock);
00194
00195
00196
00197
00198
00199
00200
00201
00202 DeviceQueueEntry->SortKey = SortKey;
00203
if (DeviceQueue->Busy ==
TRUE) {
00204 Inserted =
TRUE;
00205 NextEntry = DeviceQueue->DeviceListHead.Flink;
00206
while (NextEntry != &DeviceQueue->DeviceListHead) {
00207 QueueEntry = CONTAINING_RECORD(NextEntry,
KDEVICE_QUEUE_ENTRY,
00208 DeviceListEntry);
00209
if (SortKey < QueueEntry->
SortKey) {
00210
break;
00211 }
00212 NextEntry = NextEntry->Flink;
00213 }
00214 NextEntry = NextEntry->Blink;
00215 InsertHeadList(NextEntry, &DeviceQueueEntry->DeviceListEntry);
00216 }
else {
00217 DeviceQueue->Busy =
TRUE;
00218 Inserted =
FALSE;
00219 }
00220 DeviceQueueEntry->Inserted = Inserted;
00221 KiReleaseSpinLock(&DeviceQueue->Lock);
00222
return Inserted;
00223 }
00224
00225
PKDEVICE_QUEUE_ENTRY
00226 KeRemoveDeviceQueue (
00227 IN
PKDEVICE_QUEUE DeviceQueue
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
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry;
00256 PLIST_ENTRY NextEntry;
00257
00258
ASSERT_DEVICE_QUEUE(DeviceQueue);
00259
ASSERT(KeGetCurrentIrql() ==
DISPATCH_LEVEL);
00260
00261
00262
00263
00264
00265 KiAcquireSpinLock(&DeviceQueue->Lock);
00266
00267
ASSERT(DeviceQueue->Busy ==
TRUE);
00268
00269
00270
00271
00272
00273
00274
if (IsListEmpty(&DeviceQueue->DeviceListHead) ==
TRUE) {
00275 DeviceQueue->Busy =
FALSE;
00276 DeviceQueueEntry = (
PKDEVICE_QUEUE_ENTRY)
NULL;
00277 }
else {
00278 NextEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
00279 DeviceQueueEntry = CONTAINING_RECORD(NextEntry,
KDEVICE_QUEUE_ENTRY,
00280 DeviceListEntry);
00281 DeviceQueueEntry->
Inserted =
FALSE;
00282 }
00283
00284
00285
00286
00287
00288
00289 KiReleaseSpinLock(&DeviceQueue->Lock);
00290
return DeviceQueueEntry;
00291 }
00292
00293
PKDEVICE_QUEUE_ENTRY
00294 KeRemoveByKeyDeviceQueue (
00295 IN
PKDEVICE_QUEUE DeviceQueue,
00296 IN ULONG SortKey
00297 )
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 {
00328
00329
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry;
00330 PLIST_ENTRY NextEntry;
00331
00332
ASSERT_DEVICE_QUEUE(DeviceQueue);
00333
ASSERT(KeGetCurrentIrql() ==
DISPATCH_LEVEL);
00334
00335
00336
00337
00338
00339 KiAcquireSpinLock(&DeviceQueue->Lock);
00340
00341
ASSERT(DeviceQueue->Busy ==
TRUE);
00342
00343
00344
00345
00346
00347
00348
if (IsListEmpty(&DeviceQueue->DeviceListHead) ==
TRUE) {
00349 DeviceQueue->Busy =
FALSE;
00350 DeviceQueueEntry = (
PKDEVICE_QUEUE_ENTRY)
NULL;
00351 }
else {
00352 NextEntry = DeviceQueue->DeviceListHead.Flink;
00353
while (NextEntry != &DeviceQueue->DeviceListHead) {
00354 DeviceQueueEntry = CONTAINING_RECORD(NextEntry,
KDEVICE_QUEUE_ENTRY,
00355 DeviceListEntry);
00356
if (SortKey <= DeviceQueueEntry->
SortKey) {
00357
break;
00358 }
00359 NextEntry = NextEntry->Flink;
00360 }
00361
00362
if (NextEntry != &DeviceQueue->DeviceListHead) {
00363 RemoveEntryList(&DeviceQueueEntry->
DeviceListEntry);
00364
00365 }
else {
00366 NextEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
00367 DeviceQueueEntry = CONTAINING_RECORD(NextEntry,
KDEVICE_QUEUE_ENTRY,
00368 DeviceListEntry);
00369 }
00370
00371 DeviceQueueEntry->
Inserted =
FALSE;
00372 }
00373
00374
00375
00376
00377
00378
00379 KiReleaseSpinLock(&DeviceQueue->Lock);
00380
return DeviceQueueEntry;
00381 }
00382
00383 BOOLEAN
00384 KeRemoveEntryDeviceQueue (
00385 IN
PKDEVICE_QUEUE DeviceQueue,
00386 IN
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
00387 )
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 {
00413
00414 KIRQL OldIrql;
00415 BOOLEAN Removed;
00416
00417
ASSERT_DEVICE_QUEUE(DeviceQueue);
00418
ASSERT(KeGetCurrentIrql() <=
DISPATCH_LEVEL);
00419
00420
00421
00422
00423
00424 ExAcquireSpinLock(&DeviceQueue->Lock, &OldIrql);
00425
00426
00427
00428
00429
00430
00431
00432 Removed = DeviceQueueEntry->Inserted;
00433
if (Removed ==
TRUE) {
00434 DeviceQueueEntry->Inserted =
FALSE;
00435 RemoveEntryList(&DeviceQueueEntry->DeviceListEntry);
00436 }
00437
00438
00439
00440
00441
00442
00443 ExReleaseSpinLock(&DeviceQueue->Lock, OldIrql);
00444
return Removed;
00445 }