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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
#include "exp.h"
00041
#pragma hdrstop
00042
#include "nturtl.h"
00043
00044
00045
00046
00047
00048 #define IsExclusiveWaiting(a) ((a)->NumberOfExclusiveWaiters != 0)
00049 #define IsSharedWaiting(a) ((a)->NumberOfSharedWaiters != 0)
00050 #define IsOwnedExclusive(a) (((a)->Flag & ResourceOwnedExclusive) != 0)
00051 #define IsBoostAllowed(a) (((a)->Flag & DisablePriorityBoost) == 0)
00052
00053
00054
00055
00056
00057 #define DisablePriorityBoost 0x08
00058
00059
00060
00061
00062
00063
#if DBG
00064
00065
VOID
00066 ExpAssertResource(
00067 IN
PERESOURCE Resource
00068 );
00069
00070
#define ASSERT_RESOURCE(_Resource) ExpAssertResource(_Resource)
00071
00072
#else
00073
00074 #define ASSERT_RESOURCE(_Resource)
00075
00076
#endif
00077
00078
00079
00080
00081
00082
00083
00084
VOID
00085
FASTCALL
00086
ExpWaitForResource (
00087 IN
PERESOURCE Resource,
00088 IN PVOID Object
00089 );
00090
00091
POWNER_ENTRY
00092
FASTCALL
00093
ExpFindCurrentThread(
00094 IN
PERESOURCE Resource,
00095 IN ERESOURCE_THREAD CurrentThread
00096 );
00097
00098
00099
00100
00101
00102 LARGE_INTEGER
ExpTimeout;
00103
00104
00105
00106
00107
00108 ULONG
ExpResourceTimeoutCount = 648000;
00109
00110
00111
00112
00113
00114 KSPIN_LOCK
ExpResourceSpinLock;
00115
00116
00117
00118
00119
00120 LIST_ENTRY
ExpSystemResourcesList;
00121
00122
00123
00124
00125
00126
#if defined(_COLLECT_RESOURCE_DATA_)
00127
00128
#define ExpIncrementCounter(Member) ExpResourcePerformanceData.Member += 1
00129
00130
RESOURCE_PERFORMANCE_DATA ExpResourcePerformanceData;
00131
00132
#else
00133
00134 #define ExpIncrementCounter(Member)
00135
00136
#endif
00137
00138
00139
00140
00141
00142
#ifdef ALLOC_PRAGMA
00143
00144
#pragma alloc_text(INIT, ExpResourceInitialization)
00145
#pragma alloc_text(PAGELK, ExQuerySystemLockInformation)
00146
00147
#endif
00148
00149 BOOLEAN
00150 ExpResourceInitialization(
00151 VOID
00152 )
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 {
00171
00172 ULONG
Index;
00173
00174
00175
00176
00177
00178
00179
ExpTimeout.QuadPart = Int32x32To64(4 * 1000, -10000);
00180 InitializeListHead(&
ExpSystemResourcesList);
00181
KeInitializeSpinLock(&
ExpResourceSpinLock);
00182
00183
00184
00185
00186
00187
#if defined(_COLLECT_RESOURCE_DATA_)
00188
00189 ExpResourcePerformanceData.
ActiveResourceCount = 0;
00190 ExpResourcePerformanceData.
TotalResourceCount = 0;
00191 ExpResourcePerformanceData.
ExclusiveAcquire = 0;
00192 ExpResourcePerformanceData.
SharedFirstLevel = 0;
00193 ExpResourcePerformanceData.
SharedSecondLevel = 0;
00194 ExpResourcePerformanceData.
StarveFirstLevel = 0;
00195 ExpResourcePerformanceData.
StarveSecondLevel = 0;
00196 ExpResourcePerformanceData.
WaitForExclusive = 0;
00197 ExpResourcePerformanceData.
OwnerTableExpands = 0;
00198 ExpResourcePerformanceData.
MaximumTableExpand = 0;
00199
for (
Index = 0;
Index <
RESOURCE_HASH_TABLE_SIZE;
Index += 1) {
00200 InitializeListHead(&ExpResourcePerformanceData.
HashTable[
Index]);
00201 }
00202
00203
#endif
00204
00205
return TRUE;
00206 }
00207
00208
NTSTATUS
00209 ExInitializeResourceLite(
00210 IN
PERESOURCE Resource
00211 )
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 {
00230
00231 PVOID CallersCaller;
00232
00233
ASSERT(
MmDeterminePoolType(
Resource) ==
NonPagedPool);
00234
00235
00236
00237
00238
00239
00240
00241
00242 RtlZeroMemory(
Resource,
sizeof(
ERESOURCE));
00243
KeInitializeSpinLock(&
Resource->
SpinLock);
00244
00245
#if i386 && !FPO
00246
if (
NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {
00247
Resource->
CreatorBackTraceIndex = RtlLogStackBackTrace();
00248 }
00249
else {
00250
Resource->
CreatorBackTraceIndex = 0;
00251 }
00252
#endif // i386 && !FPO
00253
ExInterlockedInsertTailList(&
ExpSystemResourcesList,
00254 &
Resource->
SystemResourcesList,
00255 &
ExpResourceSpinLock);
00256
00257
00258
00259
00260
00261
#if defined(_COLLECT_RESOURCE_DATA_)
00262
00263
RtlGetCallersAddress(&
Resource->
Address, &CallersCaller);
00264 ExpResourcePerformanceData.
TotalResourceCount += 1;
00265 ExpResourcePerformanceData.
ActiveResourceCount += 1;
00266
00267
#endif
00268
00269
return STATUS_SUCCESS;
00270 }
00271
00272
NTSTATUS
00273 ExReinitializeResourceLite(
00274 IN
PERESOURCE Resource
00275 )
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 {
00294
00295
PKEVENT Event;
00296 ULONG
Index;
00297
POWNER_ENTRY OwnerTable;
00298
PKSEMAPHORE Semaphore;
00299 ULONG TableSize;
00300
00301
ASSERT(
MmDeterminePoolType(
Resource) ==
NonPagedPool);
00302
00303
00304
00305
00306
00307 OwnerTable =
Resource->
OwnerTable;
00308
if (OwnerTable !=
NULL) {
00309 TableSize = OwnerTable->
TableSize;
00310
for (
Index = 1;
Index < TableSize;
Index += 1) {
00311 OwnerTable[
Index].
OwnerThread = 0;
00312 OwnerTable[
Index].
OwnerCount = 0;
00313 }
00314 }
00315
00316
00317
00318
00319
00320
Resource->
ActiveCount = 0;
00321
Resource->
Flag = 0;
00322
00323
00324
00325
00326
00327
00328 Semaphore =
Resource->
SharedWaiters;
00329
if (Semaphore !=
NULL) {
00330
KeInitializeSemaphore(Semaphore, 0, MAXLONG);
00331 }
00332
00333
00334
00335
00336
00337
00338
Event =
Resource->
ExclusiveWaiters;
00339
if (
Event !=
NULL) {
00340
KeInitializeEvent(
Event, SynchronizationEvent,
FALSE);
00341 }
00342
00343
00344
00345
00346
00347
Resource->
OwnerThreads[0].
OwnerThread = 0;
00348
Resource->
OwnerThreads[0].
OwnerCount = 0;
00349
Resource->
OwnerThreads[1].
OwnerThread = 0;
00350
Resource->
OwnerThreads[1].
OwnerCount = 0;
00351
00352
00353
00354
00355
00356
00357
Resource->
ContentionCount = 0;
00358
Resource->
NumberOfSharedWaiters = 0;
00359
Resource->
NumberOfExclusiveWaiters = 0;
00360
00361
00362
00363
00364
00365
KeInitializeSpinLock(&
Resource->
SpinLock);
00366
return STATUS_SUCCESS;
00367 }
00368
00369
VOID
00370 ExDisableResourceBoostLite(
00371 IN
PERESOURCE Resource
00372 )
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 {
00393
00394 KIRQL OldIrql;
00395
00396
00397
00398
00399
00400 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
00401
00402
ASSERT_RESOURCE(
Resource);
00403
00404
Resource->
Flag |=
DisablePriorityBoost;
00405 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00406 }
00407
00408 BOOLEAN
00409
FASTCALL
00410 ExpAcquireResourceExclusiveLite(
00411 IN
PERESOURCE Resource,
00412 IN KIRQL OldIrql
00413 )
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 {
00440
00441
PKEVENT Event;
00442
00443
00444
00445
00446
00447
00448
if (
Resource->
ExclusiveWaiters ==
NULL) {
00449
00450
00451
00452
00453
00454
00455
00456
00457 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00458 ExAcquireSpinLock(&
Resource->
SpinLock, &OldIrql);
00459
if (
Resource->
ExclusiveWaiters ==
NULL) {
00460
Event =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
00461
sizeof(
KEVENT),
00462 'vEeR');
00463
00464
KeInitializeEvent(
Event, SynchronizationEvent,
FALSE);
00465
Resource->
ExclusiveWaiters =
Event;
00466 }
00467
00468 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
00469
return ExAcquireResourceExclusiveLite(
Resource,
TRUE);
00470 }
00471
00472
00473
00474
00475
00476
00477
Resource->
NumberOfExclusiveWaiters += 1;
00478 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00479
ExpWaitForResource(
Resource,
Resource->
ExclusiveWaiters);
00480
00481
00482
00483
00484
00485
00486
00487
Resource->
OwnerThreads[0].
OwnerThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
00488
return TRUE;
00489 }
00490
00491 BOOLEAN
00492 ExAcquireResourceExclusiveLite(
00493 IN
PERESOURCE Resource,
00494 IN BOOLEAN Wait
00495 )
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 {
00521
00522
ERESOURCE_THREAD CurrentThread;
00523
PKEVENT Event;
00524 KIRQL OldIrql = 0;
00525 BOOLEAN Result;
00526
00527
ASSERT((
Resource->
Flag &
ResourceNeverExclusive) == 0);
00528
00529
00530
00531
00532
00533 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
00534 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
00535
00536
ASSERT(KeIsExecutingDpc() ==
FALSE);
00537
ASSERT_RESOURCE(
Resource);
00538
00539
00540
00541
00542
00543
00544
00545
00546
ExpIncrementCounter(ExclusiveAcquire);
00547
if (
Resource->
ActiveCount != 0) {
00548
00549
00550
00551
00552
00553
00554
00555
00556
if (
IsOwnedExclusive(
Resource) &&
00557 (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread)) {
00558
Resource->
OwnerThreads[0].
OwnerCount += 1;
00559 Result =
TRUE;
00560
00561 }
else {
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
if (Wait ==
FALSE) {
00573 Result =
FALSE;
00574
00575 }
else {
00576
return ExpAcquireResourceExclusiveLite(
Resource, OldIrql);
00577 }
00578 }
00579
00580 }
else {
00581
00582
00583
00584
00585
00586
Resource->
Flag |=
ResourceOwnedExclusive;
00587
Resource->
OwnerThreads[0].
OwnerThread = CurrentThread;
00588
Resource->
OwnerThreads[0].
OwnerCount = 1;
00589
Resource->
ActiveCount = 1;
00590 Result =
TRUE;
00591 }
00592
00593 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00594
return Result;
00595 }
00596
00597 BOOLEAN
00598 ExTryToAcquireResourceExclusiveLite(
00599 IN
PERESOURCE Resource
00600 )
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 {
00623
00624
ERESOURCE_THREAD CurrentThread;
00625 KIRQL OldIrql;
00626 BOOLEAN Result;
00627
00628
ASSERT((
Resource->
Flag &
ResourceNeverExclusive) == 0);
00629
00630
00631
00632
00633
00634 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
00635 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
00636
00637
ASSERT(KeIsExecutingDpc() ==
FALSE);
00638
ASSERT_RESOURCE(
Resource);
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 Result =
FALSE;
00649
if (
Resource->
ActiveCount == 0) {
00650
ExpIncrementCounter(ExclusiveAcquire);
00651
Resource->
Flag |=
ResourceOwnedExclusive;
00652
Resource->
OwnerThreads[0].
OwnerThread = CurrentThread;
00653
Resource->
OwnerThreads[0].
OwnerCount = 1;
00654
Resource->
ActiveCount = 1;
00655 Result =
TRUE;
00656
00657 }
else if (
IsOwnedExclusive(
Resource) &&
00658 (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread)) {
00659
ExpIncrementCounter(ExclusiveAcquire);
00660
Resource->
OwnerThreads[0].
OwnerCount += 1;
00661 Result =
TRUE;
00662 }
00663
00664 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00665
return Result;
00666 }
00667
00668
#if defined(NT_UP) && !DBG
00669
00670 BOOLEAN
00671 ExpAcquireResourceSharedLite(
00672 IN
PERESOURCE Resource,
00673 IN BOOLEAN Wait
00674 );
00675
00676 BOOLEAN
00677
ExAcquireResourceSharedLite(
00678 IN
PERESOURCE Resource,
00679 IN BOOLEAN Wait
00680 )
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705 {
00706
00707
ERESOURCE_THREAD CurrentThread;
00708 KIRQL OldIrql;
00709
00710
00711
00712
00713
00714 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
00715 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
00716
00717
00718
00719
00720
00721
00722
00723
if (
Resource->
ActiveCount == 0) {
00724
Resource->
OwnerThreads[1].
OwnerThread = CurrentThread;
00725
Resource->
OwnerThreads[1].
OwnerCount = 1;
00726
Resource->
ActiveCount = 1;
00727
ExpIncrementCounter(SharedFirstLevel);
00728 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00729
return TRUE;
00730 }
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
if (
IsOwnedExclusive(Resource) &&
00741 (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread)) {
00742
Resource->
OwnerThreads[0].
OwnerCount += 1;
00743
ExpIncrementCounter(SharedFirstLevel);
00744 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00745
return TRUE;
00746 }
00747
00748
00749
00750
00751
00752
00753 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00754
return ExpAcquireResourceSharedLite(Resource, Wait);
00755 }
00756
00757
#define ExAcquireResourceSharedLite ExpAcquireResourceSharedLite
00758
00759
#endif
00760
00761 BOOLEAN
00762 ExAcquireResourceSharedLite(
00763 IN
PERESOURCE Resource,
00764 IN BOOLEAN Wait
00765 )
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 {
00789
00790
ERESOURCE_THREAD CurrentThread;
00791 KIRQL OldIrql;
00792
POWNER_ENTRY OwnerEntry;
00793
PKSEMAPHORE Semaphore;
00794
00795
00796
00797
00798
00799 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
00800 ExAcquireSpinLock(&
Resource->
SpinLock, &OldIrql);
00801
00802
ASSERT(KeIsExecutingDpc() ==
FALSE);
00803
ASSERT_RESOURCE(
Resource);
00804
00805
ExpIncrementCounter(SharedSecondLevel);
00806
00807
00808
00809
00810
00811
00812
00813
if (
Resource->
ActiveCount == 0) {
00814
Resource->
OwnerThreads[1].
OwnerThread = CurrentThread;
00815
Resource->
OwnerThreads[1].
OwnerCount = 1;
00816
Resource->
ActiveCount = 1;
00817 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
00818
return TRUE;
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
if (
IsOwnedExclusive(
Resource)) {
00830
if (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread) {
00831
Resource->
OwnerThreads[0].
OwnerCount += 1;
00832 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
00833
return TRUE;
00834 }
00835
00836
00837
00838
00839
00840 OwnerEntry =
ExpFindCurrentThread(
Resource, 0);
00841
00842 }
else {
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 OwnerEntry =
ExpFindCurrentThread(
Resource, CurrentThread);
00853
if (OwnerEntry->
OwnerThread == CurrentThread) {
00854 OwnerEntry->
OwnerCount += 1;
00855
00856
ASSERT(OwnerEntry->
OwnerCount != 0);
00857
00858 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
00859
return TRUE;
00860 }
00861
00862
00863
00864
00865
00866
00867
00868
if (
IsExclusiveWaiting(
Resource) ==
FALSE) {
00869 OwnerEntry->
OwnerThread = CurrentThread;
00870 OwnerEntry->
OwnerCount = 1;
00871
Resource->
ActiveCount += 1;
00872 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
00873
return TRUE;
00874 }
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
if (Wait ==
FALSE) {
00888 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
00889
return FALSE;
00890 }
00891
00892
00893
00894
00895
00896
00897
if (
Resource->
SharedWaiters ==
NULL) {
00898 Semaphore =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
00899
sizeof(
KSEMAPHORE),
00900 'eSeR');
00901
00902
KeInitializeSemaphore(Semaphore, 0, MAXLONG);
00903
Resource->
SharedWaiters = Semaphore;
00904 }
00905
00906
00907
00908
00909
00910
00911 OwnerEntry->
OwnerThread = CurrentThread;
00912 OwnerEntry->
OwnerCount = 1;
00913
Resource->
NumberOfSharedWaiters += 1;
00914 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
00915
ExpWaitForResource(
Resource,
Resource->
SharedWaiters);
00916
return TRUE;
00917 }
00918
00919
#if defined(NT_UP) && !DBG
00920
00921 BOOLEAN
00922 ExpAcquireSharedStarveExclusive(
00923 IN
PERESOURCE Resource,
00924 IN BOOLEAN Wait
00925 );
00926
00927 BOOLEAN
00928
ExAcquireSharedStarveExclusive(
00929 IN
PERESOURCE Resource,
00930 IN BOOLEAN Wait
00931 )
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957 {
00958
00959
ERESOURCE_THREAD CurrentThread;
00960 KIRQL OldIrql;
00961
00962
00963
00964
00965
00966 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
00967 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
00968
00969
00970
00971
00972
00973
00974
00975
if (
Resource->
ActiveCount == 0) {
00976
Resource->
OwnerThreads[1].
OwnerThread = CurrentThread;
00977
Resource->
OwnerThreads[1].
OwnerCount = 1;
00978
Resource->
ActiveCount = 1;
00979
ExpIncrementCounter(StarveFirstLevel);
00980 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00981
return TRUE;
00982 }
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
if (
IsOwnedExclusive(Resource) &&
00993 (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread)) {
00994
Resource->
OwnerThreads[0].
OwnerCount += 1;
00995
ExpIncrementCounter(StarveFirstLevel);
00996 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
00997
return TRUE;
00998 }
00999
01000
01001
01002
01003
01004
01005 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01006
return ExpAcquireSharedStarveExclusive(Resource, Wait);
01007 }
01008
01009
#define ExAcquireSharedStarveExclusive ExpAcquireSharedStarveExclusive
01010
01011
#endif
01012
01013 BOOLEAN
01014 ExAcquireSharedStarveExclusive(
01015 IN
PERESOURCE Resource,
01016 IN BOOLEAN Wait
01017 )
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040 {
01041
01042
ERESOURCE_THREAD CurrentThread;
01043 KIRQL OldIrql;
01044
POWNER_ENTRY OwnerEntry;
01045
PKSEMAPHORE Semaphore;
01046
01047
01048
01049
01050
01051 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
01052 ExAcquireSpinLock(&
Resource->
SpinLock, &OldIrql);
01053
01054
ASSERT(KeIsExecutingDpc() ==
FALSE);
01055
ASSERT_RESOURCE(
Resource);
01056
01057
ExpIncrementCounter(StarveSecondLevel);
01058
01059
01060
01061
01062
01063
01064
01065
if (
Resource->
ActiveCount == 0) {
01066
Resource->
OwnerThreads[1].
OwnerThread = CurrentThread;
01067
Resource->
OwnerThreads[1].
OwnerCount = 1;
01068
Resource->
ActiveCount = 1;
01069 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01070
return TRUE;
01071 }
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
if (
IsOwnedExclusive(
Resource)) {
01082
if (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread) {
01083
Resource->
OwnerThreads[0].
OwnerCount += 1;
01084 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01085
return TRUE;
01086 }
01087
01088
01089
01090
01091
01092 OwnerEntry =
ExpFindCurrentThread(
Resource, 0);
01093
01094 }
else {
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104 OwnerEntry =
ExpFindCurrentThread(
Resource, CurrentThread);
01105
if (OwnerEntry->
OwnerThread == CurrentThread) {
01106 OwnerEntry->
OwnerCount += 1;
01107
01108
ASSERT(OwnerEntry->
OwnerCount != 0);
01109
01110 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01111
return TRUE;
01112 }
01113
01114
01115
01116
01117
01118 OwnerEntry->
OwnerThread = CurrentThread;
01119 OwnerEntry->
OwnerCount = 1;
01120
Resource->
ActiveCount += 1;
01121 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01122
return TRUE;
01123 }
01124
01125
01126
01127
01128
01129
01130
01131
01132
if (Wait ==
FALSE) {
01133 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01134
return FALSE;
01135 }
01136
01137
01138
01139
01140
01141
01142
if (
Resource->
SharedWaiters ==
NULL) {
01143 Semaphore =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
01144
sizeof(
KSEMAPHORE),
01145 'eSeR');
01146
01147
KeInitializeSemaphore(Semaphore, 0, MAXLONG);
01148
Resource->
SharedWaiters = Semaphore;
01149 }
01150
01151
01152
01153
01154
01155
01156 OwnerEntry->
OwnerThread = CurrentThread;
01157 OwnerEntry->
OwnerCount = 1;
01158
Resource->
NumberOfSharedWaiters += 1;
01159 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01160
ExpWaitForResource(
Resource,
Resource->
SharedWaiters);
01161
return TRUE;
01162 }
01163
01164 BOOLEAN
01165 ExAcquireSharedWaitForExclusive(
01166 IN
PERESOURCE Resource,
01167 IN BOOLEAN Wait
01168 )
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191 {
01192
01193
ERESOURCE_THREAD CurrentThread;
01194 KIRQL OldIrql;
01195
POWNER_ENTRY OwnerEntry;
01196
PKSEMAPHORE Semaphore;
01197
01198
01199
01200
01201
01202 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
01203 ExAcquireSpinLock(&
Resource->
SpinLock, &OldIrql);
01204
01205
ASSERT(KeIsExecutingDpc() ==
FALSE);
01206
ASSERT_RESOURCE(
Resource);
01207
01208
ExpIncrementCounter(WaitForExclusive);
01209
01210
01211
01212
01213
01214
01215
01216
if (
Resource->
ActiveCount == 0) {
01217
Resource->
OwnerThreads[1].
OwnerThread = CurrentThread;
01218
Resource->
OwnerThreads[1].
OwnerCount = 1;
01219
Resource->
ActiveCount = 1;
01220 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01221
return TRUE;
01222 }
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
if (
IsOwnedExclusive(
Resource)) {
01233
if (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread) {
01234
Resource->
OwnerThreads[0].
OwnerCount += 1;
01235 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01236
return TRUE;
01237 }
01238
01239
01240
01241
01242
01243 OwnerEntry =
ExpFindCurrentThread(
Resource, 0);
01244
01245 }
else {
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
if (
IsExclusiveWaiting(
Resource)) {
01259
01260
01261
01262
01263
01264
01265
01266
01267
if (Wait ==
FALSE) {
01268 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01269
return FALSE;
01270 }
01271
01272
01273
01274
01275
01276
01277
if (
Resource->
SharedWaiters ==
NULL) {
01278 Semaphore =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
01279
sizeof(
KSEMAPHORE),
01280 'eSeR');
01281
01282
KeInitializeSemaphore(Semaphore, 0, MAXLONG);
01283
Resource->
SharedWaiters = Semaphore;
01284 }
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
Resource->
NumberOfSharedWaiters += 1;
01302 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01303
ExpWaitForResource(
Resource,
Resource->
SharedWaiters);
01304
01305
01306
01307
01308
01309
01310
01311 ExAcquireSpinLock(&
Resource->
SpinLock, &OldIrql);
01312
01313
ASSERT(
IsOwnedExclusive(
Resource) ==
FALSE);
01314
ASSERT(
Resource->
ActiveCount > 0);
01315
01316 OwnerEntry =
ExpFindCurrentThread(
Resource, CurrentThread);
01317
01318
ASSERT(OwnerEntry->
OwnerThread != CurrentThread);
01319
01320 OwnerEntry->
OwnerThread = CurrentThread;
01321 OwnerEntry->
OwnerCount = 1;
01322 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01323
return TRUE;
01324
01325 }
else {
01326 OwnerEntry =
ExpFindCurrentThread(
Resource, CurrentThread);
01327
if (OwnerEntry->
OwnerThread == CurrentThread) {
01328 OwnerEntry->
OwnerCount += 1;
01329
01330
ASSERT(OwnerEntry->
OwnerCount != 0);
01331
01332 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01333
return TRUE;
01334 }
01335
01336
01337
01338
01339
01340 OwnerEntry->
OwnerThread = CurrentThread;
01341 OwnerEntry->
OwnerCount = 1;
01342
Resource->
ActiveCount += 1;
01343 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01344
return TRUE;
01345 }
01346 }
01347
01348
01349
01350
01351
01352
01353
01354
01355
if (Wait ==
FALSE) {
01356 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01357
return FALSE;
01358 }
01359
01360
01361
01362
01363
01364
01365
if (
Resource->
SharedWaiters ==
NULL) {
01366 Semaphore =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
01367
sizeof(
KSEMAPHORE),
01368 'eSeR');
01369
01370
KeInitializeSemaphore(Semaphore, 0, MAXLONG);
01371
Resource->
SharedWaiters = Semaphore;
01372 }
01373
01374
01375
01376
01377
01378
01379 OwnerEntry->
OwnerThread = CurrentThread;
01380 OwnerEntry->
OwnerCount = 1;
01381
Resource->
NumberOfSharedWaiters += 1;
01382 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
01383
ExpWaitForResource(
Resource,
Resource->
SharedWaiters);
01384
return TRUE;
01385 }
01386
01387
VOID
01388
FASTCALL
01389 ExReleaseResourceLite(
01390 IN
PERESOURCE Resource
01391 )
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413 {
01414
01415
ERESOURCE_THREAD CurrentThread;
01416 ULONG
Index;
01417 ULONG Number;
01418 KIRQL OldIrql;
01419
POWNER_ENTRY OwnerEntry, OwnerEnd;
01420
01421 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
01422
01423
01424
01425
01426
01427 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
01428
01429
ASSERT_RESOURCE(
Resource);
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
if (
IsOwnedExclusive(
Resource)) {
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
ASSERT(
Resource->
OwnerThreads[0].
OwnerCount > 0);
01455
01456
if (--
Resource->
OwnerThreads[0].
OwnerCount != 0) {
01457 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01458
return;
01459 }
01460
01461
01462
01463
01464
01465
Resource->
OwnerThreads[0].
OwnerThread = 0;
01466
01467
01468
01469
01470
01471
01472
01473
01474
ASSERT(
Resource->
ActiveCount > 0);
01475
01476
if (--
Resource->
ActiveCount == 0) {
01477
01478
01479
01480
01481
01482
01483
01484
if (
IsSharedWaiting(
Resource)) {
01485
Resource->
Flag &= ~
ResourceOwnedExclusive;
01486 Number =
Resource->
NumberOfSharedWaiters;
01487
Resource->
ActiveCount = (
SHORT)Number;
01488
Resource->
NumberOfSharedWaiters = 0;
01489 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01490
KeReleaseSemaphore(
Resource->
SharedWaiters, 0, Number,
FALSE);
01491
return;
01492
01493 }
else if (
IsExclusiveWaiting(
Resource)) {
01494
Resource->
OwnerThreads[0].
OwnerThread = 1;
01495
Resource->
OwnerThreads[0].
OwnerCount = 1;
01496
Resource->
ActiveCount = 1;
01497
Resource->
NumberOfExclusiveWaiters -= 1;
01498 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01499
KeSetEventBoostPriority(
Resource->
ExclusiveWaiters,
01500 (
PRKTHREAD *)&
Resource->
OwnerThreads[0].
OwnerThread);
01501
return;
01502 }
01503
01504
Resource->
Flag &= ~
ResourceOwnedExclusive;
01505 }
01506
01507 }
else {
01508
if (
Resource->
OwnerThreads[1].
OwnerThread == CurrentThread) {
01509 OwnerEntry = &
Resource->
OwnerThreads[1];
01510
01511 }
else if (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread) {
01512 OwnerEntry = &
Resource->
OwnerThreads[0];
01513
01514 }
else {
01515
Index = ((
PKTHREAD)(CurrentThread))->ResourceIndex;
01516 OwnerEntry =
Resource->
OwnerTable;
01517
01518
if (OwnerEntry ==
NULL) {
01519
KeBugCheckEx(RESOURCE_NOT_OWNED,
01520 (ULONG_PTR)
Resource,
01521 (ULONG_PTR)CurrentThread,
01522 (ULONG_PTR)
Resource->
OwnerTable,
01523 0x2);
01524 }
01525
01526
01527
01528
01529
01530
01531
01532
if ((
Index >= OwnerEntry->
TableSize) ||
01533 (OwnerEntry[
Index].
OwnerThread != CurrentThread)) {
01534 OwnerEnd = &OwnerEntry[OwnerEntry->TableSize];
01535
while (1) {
01536 OwnerEntry += 1;
01537
if (OwnerEntry >= OwnerEnd) {
01538
KeBugCheckEx(RESOURCE_NOT_OWNED,
01539 (ULONG_PTR)
Resource,
01540 (ULONG_PTR)CurrentThread,
01541 (ULONG_PTR)
Resource->
OwnerTable,
01542 0x3);
01543 }
01544
if (OwnerEntry->OwnerThread == CurrentThread) {
01545
break;
01546 }
01547 };
01548 }
else {
01549 OwnerEntry = &OwnerEntry[
Index];
01550 }
01551 }
01552
01553
01554
01555
01556
01557
01558
ASSERT(OwnerEntry->
OwnerThread == CurrentThread);
01559
ASSERT(OwnerEntry->
OwnerCount > 0);
01560
01561
if (--OwnerEntry->
OwnerCount != 0) {
01562 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01563
return;
01564 }
01565
01566
01567
01568
01569
01570 OwnerEntry->
OwnerThread = 0;
01571
01572
01573
01574
01575
01576
01577
01578
01579
ASSERT(
Resource->
ActiveCount > 0);
01580
01581
if (--
Resource->
ActiveCount == 0) {
01582
01583
01584
01585
01586
01587
01588
if (
IsExclusiveWaiting(
Resource)) {
01589
Resource->
Flag |=
ResourceOwnedExclusive;
01590
Resource->
OwnerThreads[0].
OwnerThread = 1;
01591
Resource->
OwnerThreads[0].
OwnerCount = 1;
01592
Resource->
ActiveCount = 1;
01593
Resource->
NumberOfExclusiveWaiters -= 1;
01594 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01595
KeSetEventBoostPriority(
Resource->
ExclusiveWaiters,
01596 (
PRKTHREAD *)&
Resource->
OwnerThreads[0].
OwnerThread);
01597
return;
01598 }
01599 }
01600 }
01601
01602 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01603
return;
01604 }
01605
01606
VOID
01607 ExReleaseResourceForThreadLite(
01608 IN
PERESOURCE Resource,
01609 IN ERESOURCE_THREAD CurrentThread
01610 )
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 {
01635
01636 ULONG
Index;
01637 ULONG Number;
01638 KIRQL OldIrql;
01639
POWNER_ENTRY OwnerEntry;
01640
01641
ASSERT(CurrentThread != 0);
01642
01643
01644
01645
01646
01647 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
01648
01649
ASSERT_RESOURCE(
Resource);
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
if (
IsOwnedExclusive(
Resource)) {
01660
01661
ASSERT(
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread);
01662
01663
01664
01665
01666
01667
01668
ASSERT(
Resource->
OwnerThreads[0].
OwnerCount > 0);
01669
01670
if (--
Resource->
OwnerThreads[0].
OwnerCount != 0) {
01671 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01672
return;
01673 }
01674
01675
01676
01677
01678
01679
Resource->
OwnerThreads[0].
OwnerThread = 0;
01680
01681
01682
01683
01684
01685
01686
01687
01688
ASSERT(
Resource->
ActiveCount > 0);
01689
01690
if (--
Resource->
ActiveCount == 0) {
01691
01692
01693
01694
01695
01696
01697
01698
if (
IsSharedWaiting(
Resource)) {
01699
Resource->
Flag &= ~
ResourceOwnedExclusive;
01700 Number =
Resource->
NumberOfSharedWaiters;
01701
Resource->
ActiveCount = (
SHORT)Number;
01702
Resource->
NumberOfSharedWaiters = 0;
01703 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01704
KeReleaseSemaphore(
Resource->
SharedWaiters, 0, Number,
FALSE);
01705
return;
01706
01707 }
else if (
IsExclusiveWaiting(
Resource)) {
01708
Resource->
OwnerThreads[0].
OwnerThread = 1;
01709
Resource->
OwnerThreads[0].
OwnerCount = 1;
01710
Resource->
ActiveCount = 1;
01711
Resource->
NumberOfExclusiveWaiters -= 1;
01712 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01713
KeSetEventBoostPriority(
Resource->
ExclusiveWaiters,
01714 (
PRKTHREAD *)&
Resource->
OwnerThreads[0].
OwnerThread);
01715
return;
01716 }
01717
01718
Resource->
Flag &= ~
ResourceOwnedExclusive;
01719 }
01720
01721 }
else {
01722
if (
Resource->
OwnerThreads[1].
OwnerThread == CurrentThread) {
01723 OwnerEntry = &
Resource->
OwnerThreads[1];
01724
01725 }
else if (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread) {
01726 OwnerEntry = &
Resource->
OwnerThreads[0];
01727
01728 }
else {
01729
01730
01731
01732
01733
01734
01735
01736
Index = 1;
01737
if (((ULONG)CurrentThread & 3) == 0) {
01738
Index = ((
PKTHREAD)(CurrentThread))->ResourceIndex;
01739 }
01740
01741 OwnerEntry =
Resource->
OwnerTable;
01742
01743
ASSERT(OwnerEntry !=
NULL);
01744
01745
01746
01747
01748
01749
01750
01751
if ((
Index >= OwnerEntry->
TableSize) ||
01752 (OwnerEntry[
Index].
OwnerThread != CurrentThread)) {
01753
do {
01754 OwnerEntry += 1;
01755
if (OwnerEntry->
OwnerThread == CurrentThread) {
01756
break;
01757 }
01758
01759 }
while (
TRUE);
01760
01761 }
else {
01762 OwnerEntry = &OwnerEntry[
Index];
01763 }
01764 }
01765
01766
01767
01768
01769
01770
01771
ASSERT(OwnerEntry->
OwnerThread == CurrentThread);
01772
ASSERT(OwnerEntry->
OwnerCount > 0);
01773
01774
if (--OwnerEntry->
OwnerCount != 0) {
01775 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01776
return;
01777 }
01778
01779
01780
01781
01782
01783 OwnerEntry->
OwnerThread = 0;
01784
01785
01786
01787
01788
01789
01790
01791
01792
ASSERT(
Resource->
ActiveCount > 0);
01793
01794
if (--
Resource->
ActiveCount == 0) {
01795
01796
01797
01798
01799
01800
01801
if (
IsExclusiveWaiting(
Resource)) {
01802
Resource->
Flag |=
ResourceOwnedExclusive;
01803
Resource->
OwnerThreads[0].
OwnerThread = 1;
01804
Resource->
OwnerThreads[0].
OwnerCount = 1;
01805
Resource->
ActiveCount = 1;
01806
Resource->
NumberOfExclusiveWaiters -= 1;
01807 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01808
KeSetEventBoostPriority(
Resource->
ExclusiveWaiters,
01809 (
PRKTHREAD *)&
Resource->
OwnerThreads[0].
OwnerThread);
01810
return;
01811 }
01812 }
01813 }
01814
01815 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01816
return;
01817 }
01818
01819
VOID
01820 ExSetResourceOwnerPointer(
01821 IN
PERESOURCE Resource,
01822 IN PVOID OwnerPointer
01823 )
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860 {
01861
01862
ERESOURCE_THREAD CurrentThread;
01863 ULONG
Index;
01864 KIRQL OldIrql;
01865
POWNER_ENTRY OwnerEntry;
01866
01867
ASSERT((OwnerPointer != 0) && (((ULONG_PTR)OwnerPointer & 3) == 3));
01868
01869 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
01870
01871
01872
01873
01874
01875 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
01876
01877
ASSERT_RESOURCE(
Resource);
01878
01879
01880
01881
01882
01883
if (
IsOwnedExclusive(
Resource)) {
01884
01885
ASSERT(
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread);
01886
01887
01888
01889
01890
01891
ASSERT(
Resource->
OwnerThreads[0].
OwnerCount > 0);
01892
01893
Resource->
OwnerThreads[0].
OwnerThread = (ULONG_PTR)OwnerPointer;
01894
01895
01896
01897
01898
01899
01900 }
else {
01901
if (
Resource->
OwnerThreads[1].
OwnerThread == CurrentThread) {
01902
Resource->
OwnerThreads[1].
OwnerThread = (ULONG_PTR)OwnerPointer;
01903
01904 }
else if (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread) {
01905
Resource->
OwnerThreads[0].
OwnerThread = (ULONG_PTR)OwnerPointer;
01906
01907 }
else {
01908
Index = ((
PKTHREAD)(CurrentThread))->ResourceIndex;
01909 OwnerEntry =
Resource->
OwnerTable;
01910
01911
ASSERT(OwnerEntry !=
NULL);
01912
01913
01914
01915
01916
01917
01918
01919
if ((
Index >= OwnerEntry->
TableSize) ||
01920 (OwnerEntry[
Index].
OwnerThread != CurrentThread)) {
01921
do {
01922 OwnerEntry += 1;
01923
if (OwnerEntry->
OwnerThread == CurrentThread) {
01924
break;
01925 }
01926
01927 }
while (
TRUE);
01928
01929 }
else {
01930 OwnerEntry = &OwnerEntry[
Index];
01931 }
01932
01933 OwnerEntry->
OwnerThread = (ULONG_PTR)OwnerPointer;
01934 }
01935 }
01936
01937 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01938
return;
01939 }
01940
01941
VOID
01942 ExConvertExclusiveToSharedLite(
01943 IN
PERESOURCE Resource
01944 )
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965 {
01966
01967 ULONG Number;
01968 KIRQL OldIrql;
01969
01970
01971
01972
01973
01974 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
01975
01976
ASSERT(KeIsExecutingDpc() ==
FALSE);
01977
ASSERT_RESOURCE(
Resource);
01978
ASSERT(
IsOwnedExclusive(
Resource));
01979
ASSERT(
Resource->
OwnerThreads[0].
OwnerThread == (
ERESOURCE_THREAD)
PsGetCurrentThread());
01980
01981
01982
01983
01984
01985
Resource->
Flag &= ~
ResourceOwnedExclusive;
01986
01987
01988
01989
01990
01991
if (
IsSharedWaiting(
Resource)) {
01992 Number =
Resource->
NumberOfSharedWaiters;
01993
Resource->
ActiveCount += (
SHORT)Number;
01994
Resource->
NumberOfSharedWaiters = 0;
01995 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
01996
KeReleaseSemaphore(
Resource->
SharedWaiters, 0, Number,
FALSE);
01997
return;
01998 }
01999
02000 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
02001
return;
02002 }
02003
02004
NTSTATUS
02005 ExDeleteResourceLite(
02006 IN
PERESOURCE Resource
02007 )
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028 {
02029
02030
PRESOURCE_HASH_ENTRY HashEntry;
02031 ULONG Hash;
02032
PRESOURCE_HASH_ENTRY MatchEntry;
02033 PLIST_ENTRY NextEntry;
02034 KIRQL OldIrql;
02035
02036
ASSERT(
IsSharedWaiting(
Resource) ==
FALSE);
02037
ASSERT(
IsExclusiveWaiting(
Resource) ==
FALSE);
02038
02039
02040
02041
02042
02043
02044 ExAcquireSpinLock(&
ExpResourceSpinLock, &OldIrql);
02045
02046
ASSERT(KeIsExecutingDpc() ==
FALSE);
02047
ASSERT_RESOURCE(
Resource);
02048
02049 RemoveEntryList(&
Resource->
SystemResourcesList);
02050
02051
#if defined(_COLLECT_RESOURCE_DATA_)
02052
02053
02054
02055
02056
02057
02058 Hash = (ULONG)
Resource->
Address;
02059 Hash = ((Hash > 24) ^ (Hash > 16) ^ (Hash > 8) ^ (Hash)) & (
RESOURCE_HASH_TABLE_SIZE - 1);
02060 MatchEntry =
NULL;
02061 NextEntry = ExpResourcePerformanceData.
HashTable[Hash].Flink;
02062
while (NextEntry != &ExpResourcePerformanceData.
HashTable[Hash]) {
02063 HashEntry = CONTAINING_RECORD(NextEntry,
02064
RESOURCE_HASH_ENTRY,
02065 ListEntry);
02066
02067
if (HashEntry->
Address ==
Resource->
Address) {
02068 MatchEntry = HashEntry;
02069
break;
02070 }
02071
02072 NextEntry = NextEntry->Flink;
02073 }
02074
02075
02076
02077
02078
02079
02080
02081
if (MatchEntry !=
NULL) {
02082 MatchEntry->
ContentionCount +=
Resource->
ContentionCount;
02083 MatchEntry->
Number += 1;
02084
02085 }
else {
02086 MatchEntry =
ExAllocatePoolWithTag(
NonPagedPool,
02087
sizeof(
RESOURCE_HASH_ENTRY),
02088 'vEpR');
02089
02090
if (MatchEntry !=
NULL) {
02091 MatchEntry->
Address =
Resource->
Address;
02092 MatchEntry->
ContentionCount =
Resource->
ContentionCount;
02093 MatchEntry->
Number = 1;
02094 InsertTailList(&ExpResourcePerformanceData.
HashTable[Hash],
02095 &MatchEntry->
ListEntry);
02096 }
02097 }
02098
02099 ExpResourcePerformanceData.
ActiveResourceCount -= 1;
02100
02101
#endif
02102
02103 ExReleaseSpinLock(&
ExpResourceSpinLock, OldIrql);
02104
02105
02106
02107
02108
02109
if (
Resource->
OwnerTable !=
NULL) {
02110
ExFreePool(
Resource->
OwnerTable);
02111 }
02112
02113
02114
02115
02116
02117
if (
Resource->
SharedWaiters) {
02118
ExFreePool(
Resource->
SharedWaiters);
02119 }
02120
02121
02122
02123
02124
02125
if (
Resource->
ExclusiveWaiters) {
02126
ExFreePool(
Resource->
ExclusiveWaiters);
02127 }
02128
02129
return STATUS_SUCCESS;
02130 }
02131
02132 ULONG
02133 ExGetExclusiveWaiterCount(
02134 IN
PERESOURCE Resource
02135 )
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155 {
02156
return Resource->
NumberOfExclusiveWaiters;
02157 }
02158
02159 ULONG
02160 ExGetSharedWaiterCount(
02161 IN
PERESOURCE Resource
02162 )
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 {
02183
return Resource->
NumberOfSharedWaiters;
02184 }
02185
02186 BOOLEAN
02187 ExIsResourceAcquiredExclusiveLite(
02188 IN
PERESOURCE Resource
02189 )
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209 {
02210
02211
ERESOURCE_THREAD CurrentThread;
02212 KIRQL OldIrql;
02213 BOOLEAN Result;
02214
02215
02216
02217
02218
02219 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
02220 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
02221
02222
ASSERT_RESOURCE(
Resource);
02223
02224
02225
02226
02227
02228
02229
02230 Result =
FALSE;
02231
if ((
IsOwnedExclusive(
Resource)) &&
02232 (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread)) {
02233 Result =
TRUE;
02234 }
02235
02236
02237
02238
02239
02240 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
02241
return Result;
02242 }
02243
02244 ULONG
02245 ExIsResourceAcquiredSharedLite(
02246 IN
PERESOURCE Resource
02247 )
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267 {
02268
02269
ERESOURCE_THREAD CurrentThread;
02270 ULONG
Index;
02271 ULONG Number;
02272 KIRQL OldIrql;
02273
POWNER_ENTRY OwnerEntry;
02274 ULONG Result;
02275
02276
02277
02278
02279
02280 CurrentThread = (
ERESOURCE_THREAD)
PsGetCurrentThread();
02281 ExAcquireFastLock(&
Resource->
SpinLock, &OldIrql);
02282
02283
ASSERT_RESOURCE(
Resource);
02284
02285
02286
02287
02288
02289
02290
02291
if (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread) {
02292 Result =
Resource->
OwnerThreads[0].
OwnerCount;
02293
02294 }
else if (
Resource->
OwnerThreads[1].
OwnerThread == CurrentThread) {
02295 Result =
Resource->
OwnerThreads[1].
OwnerCount;
02296
02297 }
else {
02298
02299
02300
02301
02302
02303
02304
02305 OwnerEntry =
Resource->
OwnerTable;
02306 Result = 0;
02307
if (OwnerEntry !=
NULL) {
02308
Index = ((
PKTHREAD)(CurrentThread))->ResourceIndex;
02309 Number = OwnerEntry->
TableSize;
02310
if ((
Index >= Number) ||
02311 (OwnerEntry[
Index].
OwnerThread != CurrentThread)) {
02312
for (
Index = 1;
Index < Number;
Index += 1) {
02313 OwnerEntry += 1;
02314
if (OwnerEntry->
OwnerThread == CurrentThread) {
02315 Result = OwnerEntry->
OwnerCount;
02316
break;
02317 }
02318 }
02319
02320 }
else {
02321 Result = OwnerEntry[
Index].
OwnerCount;
02322 }
02323 }
02324 }
02325
02326
02327
02328
02329
02330 ExReleaseFastLock(&
Resource->
SpinLock, OldIrql);
02331
return Result;
02332 }
02333
02334
NTSTATUS
02335 ExQuerySystemLockInformation(
02336 OUT PRTL_PROCESS_LOCKS LockInformation,
02337 IN ULONG LockInformationLength,
02338 OUT PULONG ReturnLength OPTIONAL
02339 )
02340
02341 {
02342
02343
NTSTATUS Status;
02344 KIRQL OldIrql;
02345 ULONG RequiredLength;
02346 PLIST_ENTRY Head, Next;
02347 PRTL_PROCESS_LOCK_INFORMATION LockInfo;
02348
PERESOURCE Resource;
02349
PNTDDK_ERESOURCE NtDdkResource;
02350
PETHREAD OwningThread;
02351
02352 RequiredLength = FIELD_OFFSET(RTL_PROCESS_LOCKS, Locks);
02353
if (LockInformationLength < RequiredLength) {
02354
Status = STATUS_INFO_LENGTH_MISMATCH;
02355
02356 }
else {
02357
Status = STATUS_SUCCESS;
02358 ExAcquireSpinLock(&
ExpResourceSpinLock, &OldIrql);
02359
try {
02360 LockInformation->NumberOfLocks = 0;
02361 LockInfo = &LockInformation->Locks[0];
02362 Head = &
ExpSystemResourcesList;
02363 Next = Head->Flink;
02364
while (Next != Head) {
02365
Resource = CONTAINING_RECORD(Next,
02366
ERESOURCE,
02367 SystemResourcesList);
02368
02369 LockInformation->NumberOfLocks += 1;
02370 RequiredLength +=
sizeof(RTL_PROCESS_LOCK_INFORMATION);
02371
02372
02373
02374
02375
02376
02377 NtDdkResource = (
PNTDDK_ERESOURCE)
Resource;
02378
if (NtDdkResource->
OwnerThreads != &NtDdkResource->
InitialOwnerThreads[0]) {
02379 NtDdkResource =
NULL;
02380 }
02381
02382
if (LockInformationLength < RequiredLength) {
02383
Status = STATUS_INFO_LENGTH_MISMATCH;
02384
02385 }
else {
02386 LockInfo->Address =
Resource;
02387 LockInfo->Type = RTL_RESOURCE_TYPE;
02388 LockInfo->
CreatorBackTraceIndex = 0;
02389
#if i386 && !FPO
02390
if (NtDdkResource) {
02391 LockInfo->CreatorBackTraceIndex = (
USHORT)NtDdkResource->
CreatorBackTraceIndex;
02392 }
else {
02393 LockInfo->CreatorBackTraceIndex = (
USHORT)
Resource->
CreatorBackTraceIndex;
02394 }
02395
#endif // i386 && !FPO
02396
02397
if (NtDdkResource) {
02398
if ((NtDdkResource->
OwnerThreads[0] != 0) &&
02399 ((NtDdkResource->
OwnerThreads[0] & 3) == 0)) {
02400 OwningThread = (
PETHREAD)(NtDdkResource->
OwnerThreads[0]);
02401 LockInfo->OwningThread = OwningThread->
Cid.UniqueThread;
02402
02403 }
else {
02404 LockInfo->OwningThread = 0;
02405 }
02406
02407 LockInfo->LockCount = NtDdkResource->
ActiveCount;
02408 LockInfo->ContentionCount = NtDdkResource->
ContentionCount;
02409 LockInfo->NumberOfWaitingShared = NtDdkResource->
NumberOfSharedWaiters;
02410 LockInfo->NumberOfWaitingExclusive = NtDdkResource->
NumberOfExclusiveWaiters;
02411
02412 }
else {
02413
if ((
Resource->
OwnerThreads[0].
OwnerThread != 0) &&
02414 ((
Resource->
OwnerThreads[0].
OwnerThread & 3) == 0)) {
02415 OwningThread = (
PETHREAD)(
Resource->
OwnerThreads[0].
OwnerThread);
02416 LockInfo->OwningThread = OwningThread->
Cid.UniqueThread;
02417
02418 }
else {
02419 LockInfo->OwningThread = 0;
02420 }
02421
02422 LockInfo->LockCount =
Resource->
ActiveCount;
02423 LockInfo->ContentionCount =
Resource->
ContentionCount;
02424 LockInfo->NumberOfWaitingShared =
Resource->
NumberOfSharedWaiters;
02425 LockInfo->NumberOfWaitingExclusive =
Resource->
NumberOfExclusiveWaiters;
02426 }
02427
02428 LockInfo += 1;
02429 }
02430
02431
if (Next == Next->Flink) {
02432 Next = Head;
02433
02434 }
else {
02435 Next = Next->Flink;
02436 }
02437 }
02438
02439 } finally {
02440 ExReleaseSpinLock(&
ExpResourceSpinLock, OldIrql);
02441 }
02442 }
02443
02444
if (ARGUMENT_PRESENT(ReturnLength)) {
02445 *ReturnLength = RequiredLength;
02446 }
02447
02448
return Status;
02449 }
02450
02451
VOID
02452
FASTCALL
02453 ExpBoostOwnerThread (
02454 IN
PKTHREAD CurrentThread,
02455 IN
PKTHREAD OwnerThread
02456 )
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479 {
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
if (((ULONG_PTR)OwnerThread & 0x3) == 0) {
02492
if ((OwnerThread->Priority < CurrentThread->Priority) &&
02493 (OwnerThread->Priority < 14)) {
02494 OwnerThread->PriorityDecrement += 14 - OwnerThread->Priority;
02495 OwnerThread->DecrementCount =
ROUND_TRIP_DECREMENT_COUNT;
02496
KiSetPriorityThread(OwnerThread, 14);
02497 OwnerThread->Quantum = OwnerThread->ApcState.Process->ThreadQuantum;
02498 }
02499 }
02500
02501
return;
02502 }
02503
02504
VOID
02505
FASTCALL
02506 ExpWaitForResource (
02507 IN
PERESOURCE Resource,
02508 IN PVOID Object
02509 )
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531 {
02532
02533 ULONG
Index;
02534 ULONG Limit;
02535 ULONG Number;
02536 KIRQL OldIrql;
02537
POWNER_ENTRY OwnerEntry;
02538
PKTHREAD OwnerThread;
02539
NTSTATUS Status;
02540
PKTHREAD CurrentThread;
02541 LARGE_INTEGER Timeout;
02542
02543
02544
02545
02546
02547
02548
02549 Limit = 0;
02550
Resource->
ContentionCount += 1;
02551 Timeout.QuadPart = 500 * -10000;
02552
do {
02553
Status =
KeWaitForSingleObject (
02554 Object,
02555
Executive,
02556
KernelMode,
02557
FALSE,
02558 &Timeout );
02559
02560
if (
Status != STATUS_TIMEOUT) {
02561
break;
02562 }
02563
02564
02565
02566
02567
02568 Limit += 1;
02569 Timeout =
ExpTimeout;
02570
if (Limit >
ExpResourceTimeoutCount) {
02571 Limit = 0;
02572
02573
02574
02575
02576
02577 ExAcquireSpinLock(&
Resource->
SpinLock, &OldIrql);
02578
DbgPrint(
"Resource @ %lx\n",
Resource);
02579
DbgPrint(
" ActiveCount = %04lx Flags = %s%s%s\n",
02580
Resource->
ActiveCount,
02581
IsOwnedExclusive(
Resource) ?
"IsOwnedExclusive " :
"",
02582
IsSharedWaiting(
Resource) ?
"SharedWaiter " :
"",
02583
IsExclusiveWaiting(
Resource) ?
"ExclusiveWaiter " :
"");
02584
02585
DbgPrint(
" NumberOfExclusiveWaiters = %04lx\n",
Resource->
NumberOfExclusiveWaiters);
02586
02587
DbgPrint(
" Thread = %08lx, Count = %02x\n",
02588
Resource->
OwnerThreads[0].
OwnerThread,
02589
Resource->
OwnerThreads[0].
OwnerCount);
02590
02591
DbgPrint(
" Thread = %08lx, Count = %02x\n",
02592
Resource->
OwnerThreads[1].
OwnerThread,
02593
Resource->
OwnerThreads[1].
OwnerCount);
02594
02595 OwnerEntry =
Resource->
OwnerTable;
02596
if (OwnerEntry !=
NULL) {
02597 Number = OwnerEntry->
TableSize;
02598
for(
Index = 1;
Index < Number;
Index += 1) {
02599 OwnerEntry += 1;
02600
DbgPrint(
" Thread = %08lx, Count = %02x\n",
02601 OwnerEntry->
OwnerThread,
02602 OwnerEntry->
OwnerCount);
02603 }
02604 }
02605
02606 DbgBreakPoint();
02607
DbgPrint(
"EX - Rewaiting\n");
02608 ExReleaseSpinLock(&
Resource->
SpinLock, OldIrql);
02609 }
02610
02611
02612
02613
02614
02615
02616
if (
IsBoostAllowed(
Resource)) {
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637 CurrentThread =
KeGetCurrentThread();
02638
02639
KiLockDispatcherDatabase(&CurrentThread->
WaitIrql);
02640 CurrentThread->
WaitNext =
TRUE;
02641
02642
02643
02644
02645
02646 OwnerThread = (
PKTHREAD)
Resource->
OwnerThreads[0].
OwnerThread;
02647
if (OwnerThread !=
NULL) {
02648
ExpBoostOwnerThread(CurrentThread, OwnerThread);
02649 }
02650
02651
02652
02653
02654
02655
02656
if (!
IsOwnedExclusive(
Resource)) {
02657 OwnerThread = (
PKTHREAD)
Resource->
OwnerThreads[1].
OwnerThread;
02658
if (OwnerThread !=
NULL) {
02659
ExpBoostOwnerThread(CurrentThread, OwnerThread);
02660 }
02661
02662 OwnerEntry =
Resource->
OwnerTable;
02663
if (OwnerEntry !=
NULL) {
02664 Number = OwnerEntry->
TableSize;
02665
for(
Index = 1;
Index < Number;
Index += 1) {
02666 OwnerEntry += 1;
02667 OwnerThread = (
PKTHREAD)OwnerEntry->
OwnerThread;
02668
if (OwnerThread !=
NULL) {
02669
ExpBoostOwnerThread(CurrentThread, OwnerThread);
02670 }
02671 }
02672 }
02673 }
02674 }
02675
02676 }
while (
TRUE);
02677
02678
return;
02679 }
02680
02681
POWNER_ENTRY
02682
FASTCALL
02683 ExpFindCurrentThread(
02684 IN
PERESOURCE Resource,
02685 IN ERESOURCE_THREAD CurrentThread
02686 )
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711 {
02712
02713
POWNER_ENTRY FreeEntry;
02714 ULONG NewSize;
02715 ULONG OldSize;
02716
POWNER_ENTRY OwnerEntry;
02717
POWNER_ENTRY OwnerBound;
02718
POWNER_ENTRY OwnerTable, OldTable;
02719 KIRQL OldIrql;
02720
02721
02722
02723
02724
02725
02726
02727
if (
Resource->
OwnerThreads[0].
OwnerThread == CurrentThread) {
02728
return &
Resource->
OwnerThreads[0];
02729
02730 }
else if (
Resource->
OwnerThreads[1].
OwnerThread == CurrentThread) {
02731
return &
Resource->
OwnerThreads[1];
02732
02733 }
else {
02734 FreeEntry =
NULL;
02735
if (
Resource->
OwnerThreads[1].
OwnerThread == 0) {
02736 FreeEntry = &
Resource->
OwnerThreads[1];
02737 }
02738
02739 OwnerEntry =
Resource->
OwnerTable;
02740
if (OwnerEntry ==
NULL) {
02741 OldSize = 0;
02742
02743 }
else {
02744 OldSize = OwnerEntry->
TableSize;
02745 OwnerBound = &OwnerEntry[OldSize];
02746 OwnerEntry += 1;
02747
do {
02748
if (OwnerEntry->OwnerThread == CurrentThread) {
02749
KeGetCurrentThread()->ResourceIndex = (UCHAR)(OwnerEntry -
Resource->
OwnerTable);
02750
return OwnerEntry;
02751 }
02752
02753
if ((FreeEntry ==
NULL) &&
02754 (OwnerEntry->OwnerThread == 0)) {
02755 FreeEntry = OwnerEntry;
02756 }
02757
02758 OwnerEntry += 1;
02759 }
while (OwnerEntry != OwnerBound);
02760 }
02761 }
02762
02763
02764
02765
02766
02767
02768
if (FreeEntry !=
NULL) {
02769
KeGetCurrentThread()->ResourceIndex = (UCHAR)(FreeEntry -
Resource->
OwnerTable);
02770
return FreeEntry;
02771 }
02772
02773
02774
02775
02776
02777
ExpIncrementCounter(OwnerTableExpands);
02778
if (OldSize == 0 ) {
02779 NewSize = 3;
02780
02781 }
else {
02782 NewSize = OldSize + 4;
02783 }
02784
02785
if (NewSize *
sizeof(
OWNER_ENTRY) <=
PAGE_SIZE) {
02786
02787 OwnerTable = (
POWNER_ENTRY)
ExAllocatePoolWithTag(
02788
NonPagedPoolMustSucceed,
02789 NewSize *
sizeof(
OWNER_ENTRY),
02790 'aTeR');
02791 }
02792
else {
02793
02794
02795
02796
02797
02798
02799
02800
02801 OwnerTable = (
POWNER_ENTRY)
ExAllocatePoolWithTag(
02802
NonPagedPool,
02803 NewSize *
sizeof(
OWNER_ENTRY),
02804 'aTeR');
02805
02806
if (OwnerTable ==
NULL) {
02807
02808
KeBugCheck (MUST_SUCCEED_POOL_EMPTY);
02809 }
02810
02811 }
02812
02813
02814
02815
02816
02817
02818 RtlZeroMemory((PVOID)(OwnerTable + OldSize),
02819 (NewSize - OldSize) *
sizeof(
OWNER_ENTRY));
02820
02821 RtlCopyMemory((PVOID)OwnerTable,
02822
Resource->
OwnerTable,
02823 OldSize *
sizeof(
OWNER_ENTRY));
02824
02825
02826
02827
02828 OldTable =
Resource->
OwnerTable;
02829
02830
02831
02832
02833
02834
02835
KiLockDispatcherDatabase(&OldIrql);
02836 OwnerTable->TableSize = NewSize;
02837
Resource->
OwnerTable = OwnerTable;
02838
KiUnlockDispatcherDatabase(OldIrql);
02839
02840
if (OldTable !=
NULL) {
02841
ExFreePool(OldTable);
02842 }
02843
02844
ASSERT_RESOURCE(
Resource);
02845
02846
#if defined(_COLLECT_RESOURCE_DATA_)
02847
02848
if (NewSize > ExpResourcePerformanceData.
MaximumTableExpand) {
02849 ExpResourcePerformanceData.
MaximumTableExpand = NewSize;
02850 }
02851
02852
#endif
02853
02854
if (OldSize == 0) {
02855 OldSize = 1;
02856 }
02857
02858
KeGetCurrentThread()->ResourceIndex = (CCHAR)OldSize;
02859
return &OwnerTable[OldSize];
02860 }
02861
02862
#if DBG
02863
02864
VOID
02865 ExpAssertResource (
02866 IN
PERESOURCE Resource
02867 )
02868
02869 {
02870 ULONG
Index;
02871
POWNER_ENTRY OwnerEntry;
02872
02873
02874
02875
02876
02877
02878
02879
ASSERT(!
Resource->
SharedWaiters ||
02880
Resource->
SharedWaiters->
Header.
Type == SemaphoreObject);
02881
02882
ASSERT(!
Resource->
SharedWaiters ||
02883
Resource->
SharedWaiters->
Header.
Size == (
sizeof(
KSEMAPHORE) /
sizeof(ULONG)));
02884
02885
ASSERT(!
Resource->
ExclusiveWaiters ||
02886
Resource->
ExclusiveWaiters->
Header.
Type == SynchronizationEvent);
02887
02888
ASSERT(!
Resource->
ExclusiveWaiters ||
02889
Resource->
ExclusiveWaiters->
Header.
Size == (
sizeof(
KEVENT) /
sizeof(ULONG)));
02890 }
02891
#endif // dbg
02892
02893 PVOID
02894 ExpCheckForResource(
02895 IN PVOID p,
02896 IN ULONG Size
02897 )
02898
02899 {
02900
02901 KIRQL OldIrql;
02902 PLIST_ENTRY Head, Next;
02903
PERESOURCE Resource;
02904 PCHAR BeginBlock;
02905 PCHAR EndBlock;
02906
02907
02908
02909
02910
02911
if (
KeNumberProcessors > 1) {
02912
return NULL;
02913 }
02914
02915 BeginBlock = (PCHAR)p;
02916 EndBlock = (PCHAR)p +
Size;
02917
02918 ExAcquireSpinLock( &
ExpResourceSpinLock, &OldIrql );
02919 Head = &
ExpSystemResourcesList;
02920 Next = Head->Flink;
02921
while (Next != Head) {
02922
Resource = CONTAINING_RECORD( Next,
02923
ERESOURCE,
02924 SystemResourcesList
02925 );
02926
02927
if ((PCHAR)
Resource >= BeginBlock && (PCHAR)
Resource < EndBlock) {
02928
DbgPrint(
"EX: ExFreePool( %lx, %lx ) contains an ERESOURCE structure that has not been ExDeleteResourced\n",
02929 p,
Size
02930 );
02931 DbgBreakPoint();
02932 ExReleaseSpinLock( &
ExpResourceSpinLock, OldIrql );
02933
return (PVOID)
Resource;
02934 }
02935
02936 Next = Next->Flink;
02937 }
02938
02939 ExReleaseSpinLock( &
ExpResourceSpinLock, OldIrql );
02940
return NULL;
02941 }