00001
#include "iop.h"
00002
00003
00004
00005
00006
#ifndef NO_SPECIAL_IRP
00007
00008
00009
00010
00011
#ifdef ALLOC_PRAGMA
00012
#pragma alloc_text(PAGE, IovpTrackingDataInit)
00013
#pragma alloc_text(PAGEVRFY, IovpTrackingDataFindPointer)
00014
#pragma alloc_text(PAGEVRFY, IovpTrackingDataFindAndLock)
00015
#pragma alloc_text(PAGEVRFY, IovpTrackingDataCreateAndLock)
00016
#pragma alloc_text(PAGEVRFY, IovpTrackingDataGetCurrentSessionData)
00017
#pragma alloc_text(PAGEVRFY, IovpTrackingDataFree)
00018
#pragma alloc_text(PAGEVRFY, IovpTrackingDataAcquireLock)
00019
#pragma alloc_text(PAGEVRFY, IovpTrackingDataReleaseLock)
00020
#pragma alloc_text(PAGEVRFY, IovpTrackingDataReference)
00021
#pragma alloc_text(PAGEVRFY, IovpTrackingDataDereference)
00022
#pragma alloc_text(PAGEVRFY, IovpWatermarkIrp)
00023
#endif
00024
00025 #define POOL_TAG_TRACKING_DATA 'tprI'
00026 #define POOL_TAG_PROTECTED_IRP '+prI'
00027
00028
00029
00030
00031 ULONG
IovpIrpTrackingSpewLevel = 0 ;
00032
00033
00034
00035
00036
00037 LIST_ENTRY
IovpIrpTrackingTable[
IRP_TRACKING_HASH_SIZE];
00038 KSPIN_LOCK
IovpIrpHashLock;
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
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
VOID
00088
FASTCALL
00089 IovpTrackingDataInit(
00090 VOID
00091 )
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 {
00109 ULONG i;
00110
00111
PAGED_CODE();
00112
00113
KeInitializeSpinLock( &
IovpIrpHashLock );
00114
for(i=0; i<
IRP_TRACKING_HASH_SIZE; i++) {
00115
00116 InitializeListHead(
IovpIrpTrackingTable+i);
00117 }
00118 }
00119
00120
PIOV_REQUEST_PACKET
00121
FASTCALL
00122 IovpTrackingDataCreateAndLock(
00123 IN
PIRP Irp
00124 )
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 {
00143 KIRQL oldIrql;
00144
PIOV_REQUEST_PACKET iovPacket;
00145 PLIST_ENTRY hashHead;
00146 ULONG trackingDataSize;
00147 LONG newCount;
00148
00149 ExAcquireSpinLock( &
IovpIrpHashLock, &oldIrql );
00150
00151 iovPacket =
IovpTrackingDataFindPointer(
Irp, &hashHead) ;
00152
00153
ASSERT(!iovPacket) ;
00154
00155
00156
00157
00158
00159 trackingDataSize =
sizeof(
IOV_REQUEST_PACKET)+
Irp->
StackCount*
sizeof(
IOV_STACK_LOCATION) ;
00160
00161 iovPacket =
ExAllocatePoolWithTag(
00162
NonPagedPool,
00163 trackingDataSize,
00164
POOL_TAG_TRACKING_DATA
00165 );
00166
00167
if (!iovPacket) {
00168
00169 ExReleaseSpinLock( &
IovpIrpHashLock, oldIrql );
00170
return iovPacket;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 iovPacket->
TrackedIrp =
Irp;
00183
KeInitializeSpinLock( &iovPacket->
IrpLock );
00184 iovPacket->
ReferenceCount = 1;
00185 iovPacket->
PointerCount = 0;
00186 iovPacket->
Flags = 0;
00187 InitializeListHead(&iovPacket->
HashLink);
00188 InitializeListHead(&iovPacket->
SurrogateLink);
00189 InitializeListHead(&iovPacket->
SessionHead);
00190 iovPacket->
HeadPacket = iovPacket;
00191 iovPacket->
StackCount =
Irp->
StackCount;
00192 iovPacket->
AssertFlags =
IovpTrackingFlags;
00193 iovPacket->
RealIrpCompletionRoutine =
NULL;
00194 iovPacket->
RealIrpControl = 0;
00195 iovPacket->
RealIrpContext =
NULL;
00196 iovPacket->
TopStackLocation = 0;
00197 iovPacket->
PriorityBoost = 0;
00198 iovPacket->
LastLocation = 0;
00199 iovPacket->
RefTrackingCount =0;
00200 iovPacket->
RestoreHandle =
NULL;
00201 iovPacket->
pIovSessionData =
NULL;
00202
00203
00204
00205
00206 InsertHeadList(hashHead, &iovPacket->
HashLink);
00207
00208 ExReleaseSpinLock( &
IovpIrpHashLock, oldIrql );
00209
00210 ExAcquireSpinLock( &iovPacket->
IrpLock, &iovPacket->
CallerIrql );
00211
00212 newCount = InterlockedDecrement(&iovPacket->
ReferenceCount);
00213
00214
00215
00216
00217
00218
00219
00220
00221
TRACKIRP_DBGPRINT((
00222
" VRP CREATE(%x)->%x\n",
00223
Irp,
00224 iovPacket
00225 ), 3) ;
00226
00227
return iovPacket ;
00228 }
00229
00230
VOID
00231
FASTCALL
00232 IovpTrackingDataFree(
00233 IN
PIOV_REQUEST_PACKET IovPacket
00234 )
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 {
00253
00254
00255
00256
00257 IovPacket->Flags|=
TRACKFLAG_REMOVED_FROM_TABLE ;
00258
ASSERT(IsListEmpty(&IovPacket->HashLink)) ;
00259
00260
00261
00262
00263
ASSERT(!IovPacket->ReferenceCount) ;
00264
ASSERT(!IovPacket->PointerCount) ;
00265
00266
TRACKIRP_DBGPRINT((
00267
" VRP FREE(%x)x\n",
00268 IovPacket
00269 ), 3) ;
00270
00271
ExFreePool(IovPacket) ;
00272 }
00273
00274
PIOV_REQUEST_PACKET
00275
FASTCALL
00276 IovpTrackingDataFindAndLock(
00277 IN
PIRP Irp
00278 )
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 {
00297 KIRQL oldIrql ;
00298
PIOV_REQUEST_PACKET iovPacket ;
00299 PLIST_ENTRY listHead;
00300
00301
ASSERT(
Irp) ;
00302 ExAcquireSpinLock( &
IovpIrpHashLock, &oldIrql );
00303
00304 iovPacket =
IovpTrackingDataFindPointer(
Irp, &listHead) ;
00305
00306
if (!iovPacket) {
00307
00308 ExReleaseSpinLock( &
IovpIrpHashLock, oldIrql );
00309
return NULL;
00310 }
00311
00312 InterlockedIncrement(&iovPacket->
ReferenceCount);
00313
00314 ExReleaseSpinLock( &
IovpIrpHashLock, oldIrql );
00315
00316
IovpTrackingDataAcquireLock(iovPacket) ;
00317 iovPacket->
CallerIrql = oldIrql;
00318
00319 InterlockedDecrement(&iovPacket->
ReferenceCount);
00320
00321
if (iovPacket->
TrackedIrp ==
NULL) {
00322
00323
ASSERT(0);
00324
00325
00326
00327
00328
00329
00330
IovpTrackingDataReleaseLock(iovPacket);
00331
return NULL;
00332 }
00333
00334
TRACKIRP_DBGPRINT((
00335
" VRP FIND(%x)->%x\n",
00336
Irp,
00337 iovPacket
00338 ), 3) ;
00339
00340
return iovPacket;
00341 }
00342
00343
PIOV_REQUEST_PACKET
00344
FASTCALL
00345 IovpTrackingDataFindPointer(
00346 IN
PIRP Irp,
00347 OUT PLIST_ENTRY *HashHead
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 KIRQL oldIrql ;
00373
PIOV_REQUEST_PACKET iovPacket ;
00374 PLIST_ENTRY listEntry, listHead;
00375 UINT_PTR hash ;
00376
00377
ASSERT_SPINLOCK_HELD(&
IovpIrpHashLock) ;
00378
00379 hash = (((UINT_PTR)
Irp)/
PAGE_SIZE)*
IRP_TRACKING_HASH_PRIME ;
00380 hash %=
IRP_TRACKING_HASH_SIZE ;
00381
00382 *HashHead = listHead =
IovpIrpTrackingTable + hash ;
00383
00384
for(listEntry = listHead;
00385 listEntry->Flink != listHead;
00386 listEntry = listEntry->Flink) {
00387
00388 iovPacket = CONTAINING_RECORD(listEntry->Flink,
IOV_REQUEST_PACKET, HashLink);
00389
00390
if (iovPacket->
TrackedIrp ==
Irp) {
00391
00392
return iovPacket;
00393 }
00394 }
00395
00396
return NULL ;
00397 }
00398
00399
VOID
00400
FASTCALL
00401 IovpTrackingDataAcquireLock(
00402 IN
PIOV_REQUEST_PACKET IovPacket OPTIONAL
00403 )
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 {
00424 KIRQL oldIrql ;
00425
PIOV_REQUEST_PACKET iovCurPacket;
00426
00427
if (!IovPacket) {
00428
00429
return ;
00430 }
00431
00432 iovCurPacket = IovPacket;
00433
ASSERT(iovCurPacket->
ReferenceCount != 0);
00434
while(1) {
00435
00436 ExAcquireSpinLock( &iovCurPacket->
IrpLock, &oldIrql );
00437 iovCurPacket->
CallerIrql = oldIrql ;
00438
00439
if (iovCurPacket == IovPacket->
HeadPacket) {
00440
00441
break;
00442 }
00443
00444 iovCurPacket = CONTAINING_RECORD(
00445 iovCurPacket->
SurrogateLink.Blink,
00446
IOV_REQUEST_PACKET,
00447 SurrogateLink
00448 );
00449 }
00450 }
00451
00452
VOID
00453
FASTCALL
00454 IovpTrackingDataReleaseLock(
00455 IN
PIOV_REQUEST_PACKET IovPacket
00456 )
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 {
00475 BOOLEAN freeTrackingData;
00476
PIOV_REQUEST_PACKET iovCurPacket, iovHeadPacket, iovNextPacket;
00477 KIRQL oldIrql;
00478
00479
00480
00481
00482
00483 iovCurPacket = iovHeadPacket = IovPacket->
HeadPacket;
00484
while(1) {
00485
00486
ASSERT_SPINLOCK_HELD(&iovCurPacket->
IrpLock);
00487
00488 iovNextPacket = CONTAINING_RECORD(
00489 iovCurPacket->
SurrogateLink.Flink,
00490
IOV_REQUEST_PACKET,
00491 SurrogateLink
00492 );
00493
00494
00495
00496
00497
if (iovCurPacket->
PointerCount == 0) {
00498
00499 ExAcquireSpinLock( &
IovpIrpHashLock, &oldIrql );
00500
00501
00502
00503
00504
if (iovCurPacket->
TrackedIrp) {
00505
00506 iovCurPacket->
TrackedIrp->
Flags &=~ IRPFLAG_EXAMINE_MASK;
00507 iovCurPacket->
TrackedIrp =
NULL;
00508 }
00509
00510 ExReleaseSpinLock( &
IovpIrpHashLock, oldIrql );
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
if (iovCurPacket->
ReferenceCount == 0) {
00523
00524 ExAcquireSpinLock( &
IovpIrpHashLock, &oldIrql );
00525
00526
if (iovCurPacket->
ReferenceCount ==0) {
00527
00528
ASSERT(iovCurPacket->
PointerCount == 0);
00529
ASSERT((iovCurPacket->
pIovSessionData ==
NULL) ||
00530 (iovCurPacket != iovHeadPacket));
00531
ASSERT((iovNextPacket->
ReferenceCount == 0) ||
00532 (iovNextPacket == iovHeadPacket));
00533
00534 RemoveEntryList(&iovCurPacket->
HashLink);
00535
00536 InitializeListHead(&iovCurPacket->
HashLink);
00537 }
00538 ExReleaseSpinLock( &
IovpIrpHashLock, oldIrql );
00539 }
00540
00541
if (iovCurPacket == IovPacket) {
00542
00543
break;
00544 }
00545
00546 iovCurPacket = iovNextPacket;
00547 }
00548
00549
00550
00551
00552 iovCurPacket = iovHeadPacket;
00553
while(1) {
00554
00555 freeTrackingData = IsListEmpty(&iovCurPacket->
HashLink);
00556
00557 iovNextPacket = CONTAINING_RECORD(
00558 iovCurPacket->
SurrogateLink.Flink,
00559
IOV_REQUEST_PACKET,
00560 SurrogateLink
00561 );
00562
00563 ExReleaseSpinLock(&iovCurPacket->
IrpLock, iovCurPacket->
CallerIrql) ;
00564
00565
if (freeTrackingData) {
00566
00567 RemoveEntryList(&iovCurPacket->
SurrogateLink);
00568 InitializeListHead(&iovCurPacket->
SurrogateLink);
00569
00570
IovpTrackingDataFree(iovCurPacket) ;
00571 }
00572
00573
if (iovCurPacket == IovPacket) {
00574
00575
break;
00576 }
00577
00578 iovCurPacket = iovNextPacket;
00579 }
00580 }
00581
00582
VOID
00583
FASTCALL
00584 IovpTrackingDataReference(
00585 IN
PIOV_REQUEST_PACKET IovPacket,
00586 IN
IOV_REFERENCE_TYPE IovRefType
00587 )
00588 {
00589
ASSERT_SPINLOCK_HELD(&IovPacket->IrpLock);
00590
00591
TRACKIRP_DBGPRINT((
00592
" VRP REF(%x) %x++\n",
00593 IovPacket,
00594 IovPacket->ReferenceCount
00595 ), 3) ;
00596
00597 InterlockedIncrement(&IovPacket->ReferenceCount);
00598
if (IovRefType ==
IOVREFTYPE_POINTER) {
00599
00600
TRACKIRP_DBGPRINT((
00601
" VRP REF2(%x) %x++\n",
00602 IovPacket,
00603 IovPacket->PointerCount
00604 ), 3) ;
00605
00606 IovPacket->PointerCount++;
00607 }
00608 }
00609
00610
VOID
00611
FASTCALL
00612 IovpTrackingDataDereference(
00613 IN
PIOV_REQUEST_PACKET IovPacket,
00614 IN IOV_REFERENCE_TYPE IovRefType
00615 )
00616 {
00617 KIRQL oldIrql;
00618
00619
ASSERT_SPINLOCK_HELD(&IovPacket->IrpLock);
00620
ASSERT(IovPacket->ReferenceCount > 0);
00621
00622
TRACKIRP_DBGPRINT((
00623
" VRP DEREF(%x) %x--\n",
00624 IovPacket,
00625 IovPacket->ReferenceCount
00626 ), 3) ;
00627
00628
if (IovRefType ==
IOVREFTYPE_POINTER) {
00629
00630
ASSERT(IovPacket->PointerCount > 0);
00631
00632
TRACKIRP_DBGPRINT((
00633
" VRP DEREF2(%x) %x--\n",
00634 IovPacket,
00635 IovPacket->PointerCount
00636 ), 3) ;
00637
00638 IovPacket->PointerCount--;
00639
00640
if (IovPacket->PointerCount == 0) {
00641
00642 ExAcquireSpinLock( &
IovpIrpHashLock, &oldIrql );
00643
00644 IovPacket->TrackedIrp->Flags &=~ IRPFLAG_EXAMINE_MASK;
00645 IovPacket->TrackedIrp =
NULL;
00646
00647 ExReleaseSpinLock( &
IovpIrpHashLock, oldIrql );
00648 }
00649 }
00650 InterlockedDecrement(&IovPacket->ReferenceCount);
00651
00652
ASSERT(IovPacket->ReferenceCount >= IovPacket->PointerCount);
00653 }
00654
00655
PIOV_SESSION_DATA
00656
FASTCALL
00657 IovpTrackingDataGetCurrentSessionData(
00658 IN
PIOV_REQUEST_PACKET IovPacket
00659 )
00660 {
00661
ASSERT_SPINLOCK_HELD(&IovPacket->IrpLock);
00662
ASSERT_SPINLOCK_HELD(&IovPacket->HeadPacket->IrpLock);
00663
ASSERT((IovPacket->HeadPacket->pIovSessionData ==
NULL)||
00664 (IovPacket->Flags&
TRACKFLAG_ACTIVE)) ;
00665
00666
return IovPacket->HeadPacket->pIovSessionData;
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
PIRP
00685
FASTCALL
00686 IovpProtectedIrpAllocate(
00687 IN CCHAR StackSize,
00688 IN BOOLEAN ChargeQuota,
00689 IN
PETHREAD QuotaThread OPTIONAL
00690 )
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 {
00712
PIRP pSurrogateIrp;
00713 ULONG_PTR irpPtr;
00714 SIZE_T sizeOfAllocation;
00715
00716
00717
00718
00719
00720
00721
00722 sizeOfAllocation =
IoSizeOfIrp(StackSize);
00723
00724
ASSERT((sizeOfAllocation % (
sizeof(ULONG))) == 0);
00725
00726
00727
00728
00729
00730 irpPtr = (ULONG_PTR)
ExAllocatePoolWithTagPriority(
00731
NonPagedPool,
00732 sizeOfAllocation,
00733
POOL_TAG_PROTECTED_IRP,
00734
HighPoolPrioritySpecialPoolOverrun
00735 );
00736
00737 pSurrogateIrp = (
PIRP) (irpPtr);
00738
00739
return pSurrogateIrp;
00740 }
00741
00742 PVOID
00743
FASTCALL
00744 IovpProtectedIrpMakeUntouchable(
00745 IN
PIRP Irp OPTIONAL,
00746 IN BOOLEAN Permanent
00747 )
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 {
00767 ULONG howModified;
00768
00769
if (!
Irp) {
00770
return NULL ;
00771 }
00772
00773
if (Permanent) {
00774
ExFreePool(
Irp) ;
00775
return NULL;
00776 }
00777
00778 howModified = (ULONG)
MmProtectSpecialPool(
Irp, PAGE_NOACCESS);
00779
00780
switch(howModified) {
00781
00782
case (ULONG) -1:
00783
00784
00785
00786
00787
return NULL;
00788
00789
case 0:
00790
00791
00792
00793
00794
return NULL;
00795
00796
default:
00797
00798
00799
00800
00801
return (PVOID)
Irp;
00802 }
00803 }
00804
00805
VOID
00806
FASTCALL
00807 IovpProtectedIrpMakeTouchable(
00808 IN
PIRP Irp,
00809 IN PVOID *RestoreHandle
00810 )
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827 {
00828
if (*RestoreHandle) {
00829
00830
ASSERT(*RestoreHandle ==
Irp);
00831
MmProtectSpecialPool(
Irp, PAGE_READWRITE) ;
00832 *RestoreHandle =
NULL ;
00833 }
00834 }
00835
00836
VOID
00837
FASTCALL
00838 IovpProtectedIrpFree(
00839 IN
PIRP Irp OPTIONAL,
00840 IN PVOID *RestoreHandle
00841 )
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859 {
00860
ASSERT((*RestoreHandle) ==
NULL);
00861 }
00862
00863
VOID
00864
FASTCALL
00865 IovpWatermarkIrp(
00866 IN
PIRP Irp,
00867 IN ULONG Flags
00868 )
00869 {
00870
PIOV_REQUEST_PACKET iovPacket;
00871
00872 iovPacket =
IovpTrackingDataFindAndLock(
Irp);
00873
00874
if (iovPacket ==
NULL) {
00875
00876
return;
00877 }
00878
00879
if (Flags &
IRP_SYSTEM_RESTRICTED) {
00880
00881
00882
00883
00884
00885
00886
00887 iovPacket->
Flags |=
TRACKFLAG_WATERMARKED;
00888 }
00889
00890
if (Flags &
IRP_BOGUS) {
00891
00892 iovPacket->
Flags |=
TRACKFLAG_BOGUS;
00893 }
00894
00895
IovpTrackingDataReleaseLock(iovPacket);
00896 }
00897
00898
#endif // NO_SPECIAL_IRP
00899
00900
00901