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
00041
00042
00043
00044
00045
00046
00047
00048
#include "iop.h"
00049
00050
#if (( defined(_X86_) ) && ( FPO ))
00051
#pragma optimize( "y", off ) // disable FPO for consistent stack traces
00052
#endif
00053
00054 #define POOL_TAG_DEFERRED_CONTEXT 'dprI'
00055
00056 #define HACKHACK_FOR_MUP
00057 #define HACKHACK_FOR_SCSIPORT
00058 #define HACKHACK_FOR_ACPI
00059 #define HACKHACK_FOR_BOGUSIRPS
00060
00061
00062
00063
00064
#ifndef NO_SPECIAL_IRP
00065
00066
00067
00068
00069
#ifdef ALLOC_PRAGMA
00070
00071
#pragma alloc_text(PAGE, IovpInitIrpTracking)
00072
#pragma alloc_text(PAGE, IovpReexamineAllStacks)
00073
#pragma alloc_text(PAGEVRFY, IovpCallDriver1)
00074
#pragma alloc_text(PAGEVRFY, IovpCallDriver2)
00075
#pragma alloc_text(PAGEVRFY, IovpCompleteRequest1)
00076
#pragma alloc_text(PAGEVRFY, IovpCompleteRequest2)
00077
#pragma alloc_text(PAGEVRFY, IovpCompleteRequest3)
00078
#pragma alloc_text(PAGEVRFY, IovpCompleteRequest4)
00079
#pragma alloc_text(PAGEVRFY, IovpCompleteRequest5)
00080
#pragma alloc_text(PAGEVRFY, IovpCompleteRequest)
00081
#pragma alloc_text(PAGEVRFY, IovpCancelIrp)
00082
#pragma alloc_text(PAGEVRFY, IovpFreeIrp)
00083
#pragma alloc_text(PAGEVRFY, IovpAllocateIrp1)
00084
#pragma alloc_text(PAGEVRFY, IovpAllocateIrp2)
00085
#pragma alloc_text(PAGEVRFY, IovpInitializeIrp)
00086
#pragma alloc_text(PAGEVRFY, IovpAttachDeviceToDeviceStack)
00087
#pragma alloc_text(PAGEVRFY, IovpDetachDevice)
00088
#pragma alloc_text(PAGEVRFY, IovpDeleteDevice)
00089
#pragma alloc_text(PAGEVRFY, IovpInternalCompletionTrap)
00090
#pragma alloc_text(PAGEVRFY, IovpSwapSurrogateIrp)
00091
#pragma alloc_text(PAGEVRFY, IovpProtectedIrpAllocate)
00092
#pragma alloc_text(PAGEVRFY, IovpProtectedIrpMakeTouchable)
00093
#pragma alloc_text(PAGEVRFY, IovpProtectedIrpMakeUntouchable)
00094
#pragma alloc_text(PAGEVRFY, IovpProtectedIrpFree)
00095
#pragma alloc_text(PAGEVRFY, IovpExamineDevObjForwarding)
00096
#pragma alloc_text(PAGEVRFY, IovpExamineIrpStackForwarding)
00097
#pragma alloc_text(PAGEVRFY, IovpGetDeviceAttachedTo)
00098
#pragma alloc_text(PAGEVRFY, IovpGetLowestDevice)
00099
#pragma alloc_text(PAGEVRFY, IovpAssertNonLegacyDevice)
00100
#pragma alloc_text(PAGEVRFY, IovpIsInFdoStack)
00101
#pragma alloc_text(PAGEVRFY, IovpSeedStack)
00102
#pragma alloc_text(PAGEVRFY, IovpSeedOnePage)
00103
#pragma alloc_text(PAGEVRFY, IovpSeedTwoPages)
00104
#pragma alloc_text(PAGEVRFY, IovpSeedThreePages)
00105
#pragma alloc_text(PAGEVRFY, IovpInternalDeferredCompletion)
00106
#pragma alloc_text(PAGEVRFY, IovpInternalCompleteAfterWait)
00107
#pragma alloc_text(PAGEVRFY, IovpInternalCompleteAtDPC)
00108
#pragma alloc_text(PAGEVRFY, IovpAdvanceStackDownwards)
00109
#pragma alloc_text(PAGEVRFY, IovpEnumDevObjCallback)
00110
#pragma alloc_text(PAGEVRFY, IovpIsInterestingStack)
00111
#pragma alloc_text(PAGEVRFY, IovpIsInterestingDriver)
00112
#endif
00113
00114
00115
00116
00117
00118
00119
00120
00121 ULONG
IovpTrackingFlags = 0;
00122 ULONG
IovpHackFlags = (ULONG) -1;
00123
00124
00125
00126
00127
00128
00129
00130 BOOLEAN
IovpIrpTrackingEnabled =
FALSE;
00131
00132
00133
00134
00135 ULONG
IovpInitFlags = 0;
00136
00137
00138
00139
00140 ULONG
IovpCancelCount = 0;
00141
00142
00143
00144
00145
00146
00147 LONG
IovpIrpDeferralTime = 10 * 300;
00148
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
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
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
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
00251
00252
00253
00254
00255 BOOLEAN
00256
FASTCALL
00257 IovpInitIrpTracking(
00258 IN ULONG Level,
00259 IN ULONG Flags
00260 )
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 {
00286 PVOID sectionHeaderHandle;
00287 ULONG newTrackingFlags;
00288
00289
PAGED_CODE();
00290
00291
if (
IovpIrpTrackingEnabled) {
00292
00293
IovpInitFlags = (Flags | (
IovpInitFlags&
IOVERIFIERINIT_EVERYTHING_TRACKED));
00294
00295 }
else {
00296
00297
IovpTrackingDataInit();
00298
00299
IovpInitFlags = Flags;
00300
IovpIrpTrackingEnabled =
TRUE;
00301 }
00302
00303 newTrackingFlags = 0;
00304
switch(Level) {
00305
00306
default:
00307
case 7:
00308
IovpHackFlags = 0;
00309
00310
case 6:
00311 newTrackingFlags |=
ASSERTFLAG_FORCEPENDING |
00312
ASSERTFLAG_DEFERCOMPLETION;
00313
00314
00315
00316
00317
case 5:
00318 newTrackingFlags |=
ASSERTFLAG_COMPLETEATDPC;
00319
00320
00321
00322
00323
case 4:
00324 newTrackingFlags |=
ASSERTFLAG_SURROGATE |
00325
ASSERTFLAG_SMASH_SRBS |
00326
ASSERTFLAG_CONSUME_ALWAYS |
00327
ASSERTFLAG_ROTATE_STATUS |
00328
ASSERTFLAG_SEEDSTACK;
00329
00330
00331
00332
00333
case 3:
00334 newTrackingFlags |=
ASSERTFLAG_MONITORMAJORS;
00335
00336
00337
00338
00339
case 2:
00340 newTrackingFlags |=
ASSERTFLAG_POLICEIRPS;
00341
00342
00343
00344
00345
case 1:
00346 newTrackingFlags |=
ASSERTFLAG_TRACKIRPS |
00347
ASSERTFLAG_MONITOR_ALLOCS;
00348
00349
00350
00351
00352
case 0:
00353
break;
00354 }
00355
00356
if ((Level == 0) && (Flags&
IOVERIFIERINIT_NO_REINIT)) {
00357
00358
00359
00360
00361 newTrackingFlags =
IovpTrackingFlags;
00362 }
00363
00364
if (
IovpHackFlags == (ULONG) -1) {
00365
00366
IovpHackFlags =
00367
#ifdef HACKHACKS_ENABLED
00368
#ifdef HACKHACK_FOR_MUP
00369
HACKFLAG_FOR_MUP |
00370
#endif
00371
#ifdef HACKHACK_FOR_SCSIPORT
00372
HACKFLAG_FOR_SCSIPORT |
00373
#endif
00374
#ifdef HACKHACK_FOR_ACPI
00375
HACKFLAG_FOR_ACPI |
00376
#endif
00377
#ifdef HACKHACK_FOR_BOGUSIRPS
00378
HACKFLAG_FOR_BOGUSIRPS |
00379
#endif
00380
#endif // HACKHACKS_ENABLED
00381
0;
00382 }
00383
00384
if (!(
IovpInitFlags &
IOVERIFIERINIT_EVERYTHING_TRACKED)) {
00385
00386
00387
00388
00389
00390 newTrackingFlags &=~ (
00391
ASSERTFLAG_MONITORMAJORS |
00392
ASSERTFLAG_SURROGATE |
00393
ASSERTFLAG_SMASH_SRBS |
00394
ASSERTFLAG_CONSUME_ALWAYS
00395 );
00396 }
00397
00398
IovpTrackingFlags = newTrackingFlags;
00399
return TRUE;
00400 }
00401
00402 BOOLEAN
00403
FASTCALL
00404 IovpDoAssertIrps(
00405 VOID
00406 )
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 {
00423
ASSERT(
IovpTrackingFlags);
00424
ASSERT(KeGetCurrentIrql() <=
DISPATCH_LEVEL) ;
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
if (!
IovpIrpTrackingEnabled) {
00437
00438
#if 0
00439
IoVerifierInit(
00440 DRIVER_VERIFIER_IO_CHECKING,
00441
IOVERIFIERINIT_EVERYTHING_TRACKED |
00442
IOVERIFIERINIT_ASYNCHRONOUSINIT |
00443
IOVERIFIERINIT_NO_REINIT
00444 );
00445
#endif
00446
}
00447
00448
00449
00450
00451
return IovpIrpTrackingEnabled;
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 #define FAIL_CALLER_OF_IOFCALLDRIVER(msg, irpSp) \
00486
WDM_FAIL_CALLER(msg, 3+2*((irpSp)->MajorFunction == IRP_MJ_POWER))
00487
00488 #define FAIL_CALLER_OF_IOFCALLDRIVER2(msg, irpSp) \
00489
WDM_FAIL_CALLER(msg, 4+2*((irpSp)->MajorFunction == IRP_MJ_POWER))
00490
00491
VOID
00492
FASTCALL
00493 IovpCallDriver1(
00494 IN OUT
PIRP *IrpPointer,
00495 IN
PDEVICE_OBJECT DeviceObject,
00496 IN OUT
PIOFCALLDRIVER_STACKDATA IofCallDriverStackData
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
00523
00524
00525
00526 {
00527
PIOV_REQUEST_PACKET iovPacket;
00528
PIOV_SESSION_DATA iovSessionData;
00529
PIOV_STACK_LOCATION iovCurrentStackLocation;
00530
PIRP irp, replacementIrp;
00531
PIO_STACK_LOCATION irpSp, irpLastSp;
00532 BOOLEAN isNewSession, isNewRequest, previouslyInUse, surrogateSpawned;
00533 ULONG isSameStack;
00534 ULONG locationsAdvanced, completeStyle;
00535
PDEVICE_OBJECT pdo, lowerDeviceObject;
00536
PDRIVER_OBJECT driverObject;
00537 PVOID dispatchRoutine;
00538
00539 irp = *IrpPointer;
00540 irpSp =
IoGetNextIrpStackLocation( irp );
00541
00542
00543
00544
00545 RtlZeroMemory(IofCallDriverStackData,
sizeof(
IOFCALLDRIVER_STACKDATA));
00546
00547
00548
00549
00550
if (DeviceObject ==
NULL) {
00551
00552
FAIL_CALLER_OF_IOFCALLDRIVER(
00553 (
DCERROR_NULL_DEVOBJ_FORWARDED,
DCPARAM_IRP, irp),
00554 irpSp
00555 );
00556 }
00557
00558
00559
00560
00561
00562
00563
switch(irp->
Flags&
IRPFLAG_EXAMINE_MASK) {
00564
00565
case IRPFLAG_EXAMINE_NOT_TRACKED:
00566
00567
00568
00569
00570 iovPacket =
NULL;
00571
break;
00572
00573
case IRPFLAG_EXAMINE_TRACKED:
00574
00575
00576
00577
00578 iovPacket =
IovpTrackingDataFindAndLock(irp);
00579
ASSERT(iovPacket !=
NULL);
00580
break;
00581
00582
case IRPFLAG_EXAMINE_UNMARKED:
00583
00584 iovPacket =
IovpTrackingDataFindAndLock(irp);
00585
if (iovPacket) {
00586
00587
00588
00589
00590 irp->
Flags |=
IRPFLAG_EXAMINE_TRACKED;
00591
00592 }
else if (
IovpTrackingFlags&
ASSERTFLAG_TRACKIRPS) {
00593
00594
00595
00596
00597 iovPacket =
IovpTrackingDataCreateAndLock(irp);
00598
if (iovPacket) {
00599
00600
00601
00602
00603 irp->
Flags |=
IRPFLAG_EXAMINE_TRACKED;
00604 }
else {
00605
00606
00607
00608
00609 irp->
Flags |=
IRPFLAG_EXAMINE_NOT_TRACKED;
00610 }
00611 }
else {
00612
00613
00614
00615
00616 irp->
Flags |=
IRPFLAG_EXAMINE_NOT_TRACKED;
00617 }
00618
break;
00619
00620
default:
00621
ASSERT(0);
00622
break;
00623 }
00624
00625
if (iovPacket ==
NULL) {
00626
00627
00628
00629
00630
return;
00631 }
00632
00633
00634
00635
00636
00637 iovSessionData =
IovpTrackingDataGetCurrentSessionData(iovPacket);
00638
00639
if (iovSessionData) {
00640
00641
ASSERT(iovPacket->
Flags&
TRACKFLAG_ACTIVE);
00642 isNewSession =
FALSE;
00643
00644
IovpSessionDataAdvance(
00645 DeviceObject,
00646 iovSessionData,
00647 &iovPacket,
00648 &surrogateSpawned
00649 );
00650
00651 }
else if (!(iovPacket->
Flags&
TRACKFLAG_ACTIVE)){
00652
00653 iovPacket->
Flags |=
TRACKFLAG_ACTIVE;
00654 isNewSession =
TRUE;
00655
00656 iovSessionData =
IovpSessionDataCreate(
00657 DeviceObject,
00658 &iovPacket,
00659 &surrogateSpawned
00660 );
00661
00662 }
else {
00663
00664
00665
00666
00667
00668 }
00669
00670
00671
00672
00673 IofCallDriverStackData->IovSessionData = iovSessionData;
00674
00675
if (iovSessionData ==
NULL) {
00676
00677
IovpTrackingDataReleaseLock(iovPacket) ;
00678
return;
00679 }
00680
00681
if (surrogateSpawned) {
00682
00683
00684
00685
00686
00687 irp = iovPacket->
TrackedIrp;
00688 irpSp =
IoGetNextIrpStackLocation(irp);
00689 *IrpPointer = irp;
00690 }
00691
00692
if (isNewSession) {
00693
00694
IovpTrackingDataReference(iovPacket,
IOVREFTYPE_POINTER);
00695
IovpSessionDataReference(iovSessionData);
00696 }
00697
00698
if (iovPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS) {
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
if (irp->
CancelRoutine) {
00709
00710
FAIL_CALLER_OF_IOFCALLDRIVER(
00711 (
DCERROR_CANCELROUTINE_FORWARDED,
DCPARAM_IRP, irp),
00712 irpSp
00713 );
00714
00715 irp->
CancelRoutine =
NULL;
00716 }
00717 }
00718
00719
00720
00721
00722
if (iovPacket->
Flags&
TRACKFLAG_QUEUED_INTERNALLY) {
00723
00724
00725
00726
00727
00728
00729
00730
00731
FAIL_CALLER_OF_IOFCALLDRIVER(
00732 (
DCERROR_QUEUED_IRP_FORWARDED,
DCPARAM_IRP, irp),
00733 irpSp
00734 );
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
IovpExamineDevObjForwarding(
00748 DeviceObject,
00749 iovSessionData->
DeviceLastCalled,
00750 &iovSessionData->
ForwardMethod
00751 ) ;
00752
00753
IovpExamineIrpStackForwarding(
00754 iovPacket,
00755 isNewSession,
00756 iovSessionData->
ForwardMethod,
00757 DeviceObject,
00758 irp,
00759 &irpSp,
00760 &irpLastSp,
00761 &locationsAdvanced
00762 );
00763
00764
TRACKIRP_DBGPRINT((
00765
" CD1: Current, Last = (%x, %x)\n",
00766 irp->
CurrentLocation,
00767 iovPacket->
LastLocation
00768 ), 3) ;
00769
00770
00771
00772
00773
00774 isNewRequest =
IovpAssertIsNewRequest(irpLastSp, irpSp);
00775
00776
00777
00778
00779
00780 previouslyInUse =
IovpAdvanceStackDownwards(
00781 iovSessionData->
StackData,
00782 irp->
CurrentLocation,
00783 irpSp,
00784 irpLastSp,
00785 locationsAdvanced,
00786 isNewRequest,
00787
TRUE,
00788 &iovCurrentStackLocation
00789 );
00790
00791
ASSERT(iovCurrentStackLocation);
00792
00793
if (previouslyInUse) {
00794
00795
ASSERT(!isNewRequest);
00796
ASSERT(!isNewSession);
00797
KeQuerySystemTime(&iovCurrentStackLocation->
PerfDispatchStart) ;
00798
00799 }
else {
00800
00801 IofCallDriverStackData->Flags =
CALLFLAG_TOPMOST_IN_SLOT ;
00802 InitializeListHead(&IofCallDriverStackData->SharedLocationList) ;
00803
00804
KeQuerySystemTime(&iovCurrentStackLocation->
PerfDispatchStart) ;
00805
KeQuerySystemTime(&iovCurrentStackLocation->
PerfStackLocationStart) ;
00806
00807
00808
00809
00810 iovCurrentStackLocation->
ThreadDispatchedTo =
PsGetCurrentThread();
00811
if (isNewRequest) {
00812
00813 iovCurrentStackLocation->
InitialStatusBlock = irp->
IoStatus;
00814 iovCurrentStackLocation->
LastStatusBlock = irp->
IoStatus;
00815
if (isNewSession) {
00816
00817 iovCurrentStackLocation->
Flags |=
STACKFLAG_FIRST_REQUEST;
00818 }
00819 }
00820 }
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 lowerDeviceObject =
IovpGetDeviceAttachedTo(DeviceObject) ;
00831
if (lowerDeviceObject) {
00832
ObDereferenceObject(lowerDeviceObject) ;
00833 }
else {
00834 iovCurrentStackLocation->
Flags |=
STACKFLAG_REACHED_PDO ;
00835 }
00836
00837
00838
00839
00840
00841
00842 driverObject = DeviceObject->DriverObject ;
00843 dispatchRoutine = driverObject->
MajorFunction[irpSp->
MajorFunction] ;
00844 iovCurrentStackLocation->
LastDispatch = dispatchRoutine ;
00845
00846
00847
00848
00849 iovCurrentStackLocation->
Flags &=~ STACKFLAG_REQUEST_COMPLETED ;
00850
00851
00852
00853
00854
00855
00856 InsertHeadList(
00857 &iovCurrentStackLocation->
CallStackData,
00858 &IofCallDriverStackData->SharedLocationList
00859 ) ;
00860
00861
00862
00863
00864 IofCallDriverStackData->IovStackLocation = iovCurrentStackLocation ;
00865
00866
00867
if ((irpSp->
MajorFunction ==
IRP_MJ_PNP)&&
00868 (irpSp->
MinorFunction ==
IRP_MN_REMOVE_DEVICE)) {
00869
00870 IofCallDriverStackData->
Flags |=
CALLFLAG_IS_REMOVE_IRP ;
00871
00872 pdo =
IovpGetLowestDevice(DeviceObject) ;
00873
ASSERT(pdo) ;
00874 IofCallDriverStackData->RemovePdo = pdo ;
00875
ObDereferenceObject(pdo) ;
00876
if (
IovpIsInFdoStack(DeviceObject) &&
00877 (!(DeviceObject->DeviceObjectExtension->ExtensionFlags&
DOE_RAW_FDO))) {
00878 IofCallDriverStackData->Flags |=
CALLFLAG_REMOVING_FDO_STACK_DO ;
00879 }
00880 }
00881
00882
if ((iovPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS) &&
00883 (iovPacket->
AssertFlags&
ASSERTFLAG_MONITORMAJORS)) {
00884
00885
00886
00887
00888
if (isNewSession) {
00889
00890
IovpAssertNewIrps(iovPacket, irpSp, iovCurrentStackLocation) ;
00891 }
00892
00893
if (isNewRequest) {
00894
00895
IovpAssertNewRequest(iovPacket, DeviceObject, irpLastSp, irpSp, iovCurrentStackLocation) ;
00896 }
00897
00898
IovpAssertIrpStackDownward(iovPacket, DeviceObject, irpLastSp, irpSp, iovCurrentStackLocation) ;
00899 }
00900
00901
00902
00903
00904 iovSessionData->
DeviceLastCalled = DeviceObject ;
00905 iovPacket->
LastLocation = irp->
CurrentLocation ;
00906 iovCurrentStackLocation->
RequestsFirstStackLocation->
LastStatusBlock = irp->
IoStatus;
00907
00908
00909
00910
00911
00912
if (irp->
CurrentLocation>1) {
00913
IoSetNextIrpStackLocation( irp ) ;
00914 irpSp =
IoGetNextIrpStackLocation( irp );
00915 irpSp->
Control |=
SL_NOTCOPIED ;
00916
IoSkipCurrentIrpStackLocation( irp ) ;
00917 }
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
if ((
IovpInitFlags &
IOVERIFIERINIT_RANDOMLY_CANCEL_IRPS) &&
00929 (!(irp->
Flags &
IRP_PAGING_IO))) {
00930
00931
if (((++
IovpCancelCount) % 4000) == 0) {
00932
00933 irp->
Cancel =
TRUE;
00934 }
00935 }
00936
00937
00938
00939
00940
ASSERT(iovSessionData->
StackData[iovPacket->
LastLocation-1].InUse) ;
00941
00942
IovpSessionDataReference(iovSessionData);
00943
IovpTrackingDataReleaseLock(iovPacket) ;
00944 }
00945
00946
VOID
00947
FASTCALL
00948 IovpCallDriver2(
00949 IN
PIRP Irp,
00950 IN
PDEVICE_OBJECT DeviceObject,
00951 IN PVOID DispatchRoutine,
00952 IN OUT NTSTATUS *FinalStatus,
00953 IN
PIOFCALLDRIVER_STACKDATA IofCallDriverStackData
00954 )
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 {
00983
NTSTATUS status, lastStatus;
00984
PIOV_REQUEST_PACKET iovPacket;
00985
PIOV_SESSION_DATA iovSessionData;
00986 ULONG refCount;
00987
PIOV_STACK_LOCATION iovCurrentStackLocation;
00988 BOOLEAN mustDetachAndDelete;
00989
PDEVICE_NODE devNode;
00990
PDEVICE_OBJECT lowerDevObj;
00991
00992 iovSessionData = IofCallDriverStackData->IovSessionData;
00993
if (iovSessionData ==
NULL) {
00994
00995
return;
00996 }
00997
00998 iovPacket = iovSessionData->
IovRequestPacket;
00999
ASSERT(iovPacket);
01000
IovpTrackingDataAcquireLock(iovPacket);
01001
01002
01003
01004
01005
01006
01007
#if 0
01008
if (iovSessionData->
AssertFlags&
ASSERTFLAG_POLICEIRPS) {
01009
01010
if (IofCallDriverStackData->Flags&
CALLFLAG_IS_REMOVE_IRP) {
01011
01012
if ((*FinalStatus != STATUS_PENDING) &&
01013 (iovCurrentStackLocation->
ThreadDispatchedTo ==
PsGetCurrentThread())) {
01014
01015 lowerDevObj =
IovpGetDeviceAttachedTo(DeviceObject) ;
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
if (IofCallDriverStackData->Flags&
CALLFLAG_REMOVING_FDO_STACK_DO) {
01026
01027
01028
01029
01030
01031 mustDetachAndDelete =
TRUE ;
01032
01033 }
else {
01034
01035 devNode = IofCallDriverStackData->RemovePdo->DeviceObjectExtension->DeviceNode ;
01036
ASSERT(devNode) ;
01037
01038
if (devNode->
Flags &
DNF_DEVICE_GONE) {
01039
01040
01041
01042
01043 mustDetachAndDelete =
TRUE ;
01044
01045 }
else {
01046
01047
01048
01049
01050 mustDetachAndDelete =
FALSE ;
01051 }
01052 }
01053
01054
if (mustDetachAndDelete) {
01055
01056
01057
01058
01059
01060
if (lowerDevObj) {
01061
01062
WDM_FAIL_ROUTINE((
01063
DCERROR_SHOULDVE_DETACHED,
01064
DCPARAM_IRP +
DCPARAM_ROUTINE +
DCPARAM_DEVOBJ,
01065 iovSessionData->
BestVisibleIrp,
01066 DispatchRoutine,
01067 DeviceObject
01068 ));
01069 }
01070
01071
01072
01073
01074
if (!(DeviceObject->DeviceObjectExtension->ExtensionFlags&
DOE_DELETE_PENDING)) {
01075
01076
WDM_FAIL_ROUTINE((
01077
DCERROR_SHOULDVE_DELETED,
01078
DCPARAM_IRP +
DCPARAM_ROUTINE +
DCPARAM_DEVOBJ,
01079 iovSessionData->
BestVisibleIrp,
01080 DispatchRoutine,
01081 DeviceObject
01082 ));
01083 }
01084
01085 }
else {
01086
01087
01088
01089
01090
01091
ASSERT(!(IofCallDriverStackData->Flags&
CALLFLAG_REMOVING_FDO_STACK_DO)) ;
01092
01093
if (DeviceObject == IofCallDriverStackData->RemovePdo) {
01094
01095
01096
01097
01098
if (DeviceObject->DeviceObjectExtension->ExtensionFlags&
DOE_DELETE_PENDING) {
01099
01100
WDM_FAIL_ROUTINE((
01101
DCERROR_DELETED_PRESENT_PDO,
01102
DCPARAM_IRP +
DCPARAM_ROUTINE +
DCPARAM_DEVOBJ,
01103 iovSessionData->
BestVisibleIrp,
01104 DispatchRoutine,
01105 DeviceObject
01106 ));
01107 }
01108
01109 }
else if (!(IofCallDriverStackData->RemovePdo->DeviceObjectExtension->ExtensionFlags&
DOE_DELETE_PENDING)) {
01110
01111
01112
01113
01114
01115
if (lowerDevObj ==
NULL) {
01116
01117
01118
01119
01120
WDM_FAIL_ROUTINE((
01121
DCERROR_BUS_FILTER_ERRONEOUSLY_DETACHED,
01122
DCPARAM_IRP +
DCPARAM_ROUTINE +
DCPARAM_DEVOBJ,
01123 iovSessionData->
BestVisibleIrp,
01124 DispatchRoutine,
01125 DeviceObject
01126 ));
01127 }
01128
01129
if (DeviceObject->DeviceObjectExtension->ExtensionFlags&
DOE_DELETE_PENDING) {
01130
01131
01132
01133
01134
WDM_FAIL_ROUTINE((
01135
DCERROR_BUS_FILTER_ERRONEOUSLY_DELETED,
01136
DCPARAM_IRP +
DCPARAM_ROUTINE +
DCPARAM_DEVOBJ,
01137 iovSessionData->
BestVisibleIrp,
01138 DispatchRoutine,
01139 DeviceObject
01140 ));
01141 }
01142 }
01143 }
01144
01145
if (lowerDevObj) {
01146
01147
ObDereferenceObject(lowerDevObj) ;
01148 }
01149 }
01150 }
01151 }
01152
#endif
01153
if (IofCallDriverStackData->Flags&
CALLFLAG_COMPLETED) {
01154
01155
TRACKIRP_DBGPRINT((
01156
" Verifying status in CD2\n"
01157 ),2) ;
01158
01159
if ((*FinalStatus != IofCallDriverStackData->ExpectedStatus)&&
01160 (*FinalStatus != STATUS_PENDING)) {
01161
01162
if ((iovSessionData->
AssertFlags&
ASSERTFLAG_POLICEIRPS) &&
01163 (!(iovSessionData->
SessionFlags&
SESSIONFLAG_UNWOUND_INCONSISTANT))) {
01164
01165
01166
01167
01168
01169
WDM_FAIL_ROUTINE((
01170
DCERROR_INCONSISTANT_STATUS,
01171
DCPARAM_IRP +
DCPARAM_ROUTINE +
DCPARAM_STATUS*2,
01172 iovSessionData->
BestVisibleIrp,
01173 DispatchRoutine,
01174 IofCallDriverStackData->ExpectedStatus,
01175 *FinalStatus
01176 ));
01177 }
01178
01179 iovSessionData->
SessionFlags |=
SESSIONFLAG_UNWOUND_INCONSISTANT;
01180
01181 }
else if (*FinalStatus == 0xFFFFFFFF) {
01182
01183
if (iovSessionData->
AssertFlags&
ASSERTFLAG_POLICEIRPS) {
01184
01185
01186
01187
01188
01189
01190
WDM_FAIL_ROUTINE((
01191
DCERROR_UNINITIALIZED_STATUS,
01192
DCPARAM_IRP +
DCPARAM_ROUTINE,
01193 iovSessionData->
BestVisibleIrp,
01194 DispatchRoutine
01195 ));
01196 }
01197 }
01198
01199
01200
01201
01202
01203
01204 }
else {
01205
01206
01207
01208
01209
01210
TRACKIRP_DBGPRINT((
01211
" Verifying status is STATUS_PENDING in CR2\n"
01212 ), 2) ;
01213
01214
if (*FinalStatus != STATUS_PENDING) {
01215
01216
if ((iovSessionData->
AssertFlags&
ASSERTFLAG_POLICEIRPS) &&
01217 (!(iovPacket->
Flags&
TRACKFLAG_UNWOUND_BADLY))) {
01218
01219
01220
01221
01222
01223
01224
WDM_FAIL_ROUTINE((
01225
DCERROR_IRP_RETURNED_WITHOUT_COMPLETION,
01226
DCPARAM_IRP +
DCPARAM_ROUTINE,
01227 iovSessionData->
BestVisibleIrp,
01228 DispatchRoutine
01229 ));
01230 }
01231
01232 iovPacket->
Flags |=
TRACKFLAG_UNWOUND_BADLY;
01233 }
01234
01235 iovCurrentStackLocation = (
PIOV_STACK_LOCATION)(IofCallDriverStackData->IovStackLocation) ;
01236
ASSERT(iovCurrentStackLocation->
InUse) ;
01237
ASSERT(!IsListEmpty(&iovCurrentStackLocation->
CallStackData)) ;
01238
01239
01240
01241
01242 RemoveEntryList(&IofCallDriverStackData->SharedLocationList) ;
01243 }
01244
01245
if ((IofCallDriverStackData->Flags&
CALLFLAG_OVERRIDE_STATUS)&&
01246 (*FinalStatus != STATUS_PENDING)) {
01247
01248 *FinalStatus = IofCallDriverStackData->NewStatus ;
01249 }
01250
01251
if ((iovSessionData->
AssertFlags&
ASSERTFLAG_FORCEPENDING) &&
01252 (!(IofCallDriverStackData->Flags&
CALLFLAG_IS_REMOVE_IRP))) {
01253
01254
01255
01256
01257
01258 *FinalStatus = STATUS_PENDING ;
01259 }
01260
01261
IovpSessionDataDereference(iovSessionData);
01262
IovpTrackingDataReleaseLock(iovPacket);
01263 }
01264
01265
VOID
01266
FASTCALL
01267 IovpCompleteRequest1(
01268 IN
PIRP Irp,
01269 IN CCHAR
PriorityBoost,
01270 IN OUT
PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket
01271 )
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 {
01297
PIOV_REQUEST_PACKET iovPacket;
01298
PIOV_SESSION_DATA iovSessionData;
01299 BOOLEAN slotIsInUse;
01300
PIOV_STACK_LOCATION iovCurrentStackLocation;
01301 ULONG locationsAdvanced;
01302
PIO_STACK_LOCATION irpSp;
01303
PDEVICE_OBJECT lowerDevobj;
01304
01305 iovPacket =
IovpTrackingDataFindAndLock(
Irp);
01306
01307 CompletionPacket->RaisedCount = 0;
01308
01309
if (iovPacket ==
NULL) {
01310
01311 CompletionPacket->IovSessionData =
NULL;
01312
return;
01313 }
01314
01315 iovSessionData =
IovpTrackingDataGetCurrentSessionData(iovPacket);
01316
01317 CompletionPacket->IovSessionData = iovSessionData;
01318 CompletionPacket->
IovRequestPacket = iovPacket;
01319
01320
if (iovSessionData ==
NULL) {
01321
01322
01323
01324
01325
01326
01327
IovpTrackingDataReleaseLock(iovPacket);
01328
return;
01329 }
01330
01331
TRACKIRP_DBGPRINT((
01332
" CR1: Current, Last = (%x, %x)\n",
01333
Irp->
CurrentLocation, iovPacket->
LastLocation
01334 ), 3);
01335
01336 irpSp =
IoGetCurrentIrpStackLocation(
Irp);
01337
01338
if (iovPacket->
Flags&
TRACKFLAG_QUEUED_INTERNALLY) {
01339
01340
01341
01342
01343
WDM_FAIL_CALLER3((
DCERROR_QUEUED_IRP_COMPLETED,
DCPARAM_IRP,
Irp));
01344 }
01345
01346
01347
01348
01349
01350
ASSERT(!(
Irp->
Flags&
IRP_DIAG_HAS_SURROGATE));
01351
01352
01353
01354
01355
01356
if (
Irp->
CurrentLocation == ((CCHAR)
Irp->
StackCount + 1)) {
01357
01358
WDM_CHASTISE_CALLER3((
DCERROR_UNFORWARDED_IRP_COMPLETED,
DCPARAM_IRP,
Irp));
01359 }
01360
01361
01362
01363
01364 iovPacket->
PriorityBoost =
PriorityBoost;
01365
01366
01367
01368
01369
01370
01371
01372
if (iovSessionData->
AssertFlags&
ASSERTFLAG_FORCEPENDING) {
01373
01374
IoMarkIrpPending(
Irp);
01375 }
01376
01377
01378
01379
01380
01381 iovSessionData->
DeviceLastCalled =
NULL;
01382
01383 locationsAdvanced = iovPacket->
LastLocation -
Irp->
CurrentLocation;
01384
01385
01386
01387
01388
01389 CompletionPacket->LocationsAdvanced = locationsAdvanced;
01390
01391
01392
01393
01394
ASSERT(locationsAdvanced);
01395
01396
01397
01398
01399
01400 slotIsInUse =
IovpAdvanceStackDownwards(
01401 iovSessionData->
StackData,
01402
Irp->
CurrentLocation,
01403 irpSp,
01404 irpSp + locationsAdvanced,
01405 locationsAdvanced,
01406
FALSE,
01407
FALSE,
01408 &iovCurrentStackLocation
01409 );
01410
01411
IovpTrackingDataReleaseLock(iovPacket);
01412 }
01413
01414
VOID
01415
FASTCALL
01416 IovpCompleteRequest2(
01417 IN
PIRP Irp,
01418 IN OUT
PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket
01419 )
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441 {
01442
PIOV_REQUEST_PACKET iovPacket;
01443
PIOV_SESSION_DATA iovSessionData;
01444 BOOLEAN raiseToDPC, newlyCompleted, requestFinalized ;
01445 KIRQL oldIrql ;
01446
PIOV_STACK_LOCATION iovCurrentStackLocation, requestsFirstStackLocation ;
01447
NTSTATUS status, entranceStatus ;
01448
PIOFCALLDRIVER_STACKDATA IofCallDriverStackData ;
01449
PIO_STACK_LOCATION irpSp ;
01450 ULONG refAction ;
01451 PLIST_ENTRY listEntry ;
01452
01453 iovSessionData = CompletionPacket->IovSessionData;
01454
if (iovSessionData ==
NULL) {
01455
01456
return;
01457 }
01458
01459 iovPacket = CompletionPacket->IovRequestPacket;
01460
ASSERT(iovPacket);
01461
IovpTrackingDataAcquireLock(iovPacket);
01462
01463
ASSERT(iovSessionData ==
IovpTrackingDataGetCurrentSessionData(iovPacket));
01464
01465
ASSERT(!
Irp->
CancelRoutine) ;
01466
01467 status =
Irp->
IoStatus.Status ;
01468
01469
TRACKIRP_DBGPRINT((
01470
" CR2: Current, Last = (%x, %x)\n",
01471
Irp->
CurrentLocation, iovPacket->LastLocation
01472 ), 3) ;
01473
01474 iovCurrentStackLocation = iovSessionData->
StackData +
Irp->
CurrentLocation -1 ;
01475
TRACKIRP_DBGPRINT((
01476
" Smacking %lx in CR2\n",
01477 iovCurrentStackLocation-iovSessionData->
StackData
01478 ), 2) ;
01479
01480
if (
Irp->
CurrentLocation <= iovPacket->TopStackLocation) {
01481
01482
01483
01484
01485
01486
ASSERT(iovCurrentStackLocation->
InUse) ;
01487
01488
01489
01490
01491
01492
01493
01494
01495 requestsFirstStackLocation = iovCurrentStackLocation->
RequestsFirstStackLocation ;
01496
TRACKIRP_DBGPRINT((
01497
" CR2: original request for %lx is %lx\n",
01498 iovCurrentStackLocation-iovSessionData->
StackData,
01499 requestsFirstStackLocation-iovSessionData->
StackData
01500 ), 3) ;
01501
01502
ASSERT(requestsFirstStackLocation) ;
01503
if (requestsFirstStackLocation->
Flags&
STACKFLAG_REQUEST_COMPLETED) {
01504 newlyCompleted =
FALSE ;
01505 }
else {
01506 requestsFirstStackLocation->
Flags|=
STACKFLAG_REQUEST_COMPLETED ;
01507 newlyCompleted =
TRUE ;
01508
TRACKIRP_DBGPRINT((
01509
" CR2: Request %lx newly completed by %lx\n",
01510 requestsFirstStackLocation-iovSessionData->
StackData,
01511 iovCurrentStackLocation-iovSessionData->
StackData
01512 ), 3) ;
01513 }
01514 requestFinalized = (iovCurrentStackLocation == requestsFirstStackLocation) ;
01515
if (requestFinalized) {
01516
01517
TRACKIRP_DBGPRINT((
01518
" CR2: Request %lx finalized\n",
01519 iovCurrentStackLocation-iovSessionData->
StackData
01520 ), 3) ;
01521 }
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538 irpSp =
IoGetNextIrpStackLocation(
Irp) ;
01539
01540
if ((iovPacket->AssertFlags&
ASSERTFLAG_POLICEIRPS) &&
01541 (iovPacket->AssertFlags&
ASSERTFLAG_MONITORMAJORS)) {
01542
01543
IovpAssertIrpStackUpward(
01544 iovPacket,
01545 irpSp,
01546 iovCurrentStackLocation,
01547 newlyCompleted,
01548 requestFinalized
01549 );
01550 }
01551
01552 entranceStatus = status ;
01553
01554
while(!IsListEmpty(&iovCurrentStackLocation->CallStackData)) {
01555
01556
01557
01558
01559 listEntry = RemoveHeadList(&iovCurrentStackLocation->CallStackData) ;
01560 IofCallDriverStackData = CONTAINING_RECORD(
01561 listEntry,
01562
IOFCALLDRIVER_STACKDATA,
01563 SharedLocationList) ;
01564
01565
ASSERT(!(IofCallDriverStackData->
Flags&
CALLFLAG_COMPLETED)) ;
01566
01567 IofCallDriverStackData->
Flags |=
CALLFLAG_COMPLETED ;
01568 IofCallDriverStackData->
ExpectedStatus = status ;
01569
01570
if ((iovSessionData->
AssertFlags&
ASSERTFLAG_ROTATE_STATUS)&&
01571
IovpAssertDoAdvanceStatus(irpSp, entranceStatus, &status)) {
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582 IofCallDriverStackData->
Flags |=
CALLFLAG_OVERRIDE_STATUS ;
01583 IofCallDriverStackData->
NewStatus = status ;
01584 }
01585 }
01586
Irp->
IoStatus.Status = status ;
01587
01588
01589
01590
01591 RtlZeroMemory(iovCurrentStackLocation,
sizeof(
IOV_STACK_LOCATION)) ;
01592 InitializeListHead(&iovCurrentStackLocation->CallStackData) ;
01593 }
else {
01594
01595
ASSERT(0) ;
01596 }
01597
01598
01599
01600
01601
01602 raiseToDPC =
FALSE ;
01603
01604
if (iovSessionData->
AssertFlags&
ASSERTFLAG_COMPLETEATDPC) {
01605
01606
if (!CompletionPacket->RaisedCount) {
01607
01608
01609
01610
01611 CompletionPacket->PreviousIrql = iovPacket->CallerIrql;
01612 raiseToDPC =
TRUE ;
01613 }
01614 CompletionPacket->RaisedCount++ ;
01615 }
01616
01617 iovPacket->LastLocation =
Irp->
CurrentLocation+1 ;
01618
01619
if (iovPacket->TopStackLocation ==
Irp->
CurrentLocation) {
01620
01621 CompletionPacket->IovSessionData =
NULL;
01622
01623
if (iovPacket->Flags&
TRACKFLAG_SURROGATE) {
01624
01625
01626
01627
01628 irpSp =
IoGetNextIrpStackLocation(
Irp) ;
01629 iovPacket->RealIrpCompletionRoutine = irpSp->
CompletionRoutine ;
01630 iovPacket->RealIrpControl = irpSp->
Control ;
01631 iovPacket->RealIrpContext = irpSp->
Context ;
01632
01633
01634
01635
01636
01637
01638
IoSetCompletionRoutine(
01639
Irp,
01640
IovpSwapSurrogateIrp,
01641
Irp,
01642
TRUE,
01643
TRUE,
01644
TRUE
01645 ) ;
01646
01647 }
else {
01648
01649
01650
01651
01652
01653
01654 irpSp =
IoGetNextIrpStackLocation(
Irp) ;
01655
if (iovPacket->AssertFlags&
ASSERTFLAG_POLICEIRPS) {
01656
01657
IovpAssertFinalIrpStack(iovPacket, irpSp) ;
01658 }
01659
01660
ASSERT(iovPacket->TopStackLocation ==
Irp->
CurrentLocation);
01661
IovpSessionDataClose(iovSessionData);
01662
IovpSessionDataDereference(iovSessionData);
01663
IovpTrackingDataDereference(iovPacket,
IOVREFTYPE_POINTER);
01664 }
01665
01666 }
else {
01667
01668
01669
01670
01671
IovpSessionDataReference(iovSessionData);
01672 }
01673
01674
01675
01676
01677
if (iovPacket->LastLocation < iovPacket->TopStackLocation) {
01678
01679
ASSERT(iovSessionData->
StackData[iovPacket->LastLocation-1].
InUse) ;
01680 }
01681
01682
IovpTrackingDataReleaseLock(iovPacket);
01683
01684
if (raiseToDPC) {
01685
KeRaiseIrql(
DISPATCH_LEVEL, &oldIrql);
01686 }
01687
01688 CompletionPacket->LocationsAdvanced --;
01689 }
01690
01691
VOID
01692
FASTCALL
01693 IovpCompleteRequest3(
01694 IN
PIRP Irp,
01695 IN PVOID Routine,
01696 IN OUT
PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket
01697 )
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719 {
01720
PIOV_REQUEST_PACKET iovPacket;
01721
PIOV_SESSION_DATA iovSessionData;
01722
PIO_STACK_LOCATION irpSpCur, irpSpNext ;
01723
PDEFERRAL_CONTEXT deferralContext ;
01724
01725 iovSessionData = CompletionPacket->IovSessionData;
01726
if (iovSessionData ==
NULL) {
01727
01728
return;
01729 }
01730
01731 iovPacket = iovSessionData->
IovRequestPacket;
01732
ASSERT(iovPacket);
01733
IovpTrackingDataAcquireLock(iovPacket);
01734
01735
01736
01737
01738
01739
01740
if (iovSessionData->
AssertFlags&
ASSERTFLAG_POLICEIRPS) {
01741
01742
if ((CompletionPacket->LocationsAdvanced <= 0) &&
01743 (
MmIsSystemAddressLocked(Routine) ==
FALSE)) {
01744
01745
DbgPrint(
01746
"Verifier Notes: LocationsAdvanced %d\n",
01747 CompletionPacket->LocationsAdvanced
01748 );
01749
01750
WDM_FAIL_ROUTINE((
01751
DCERROR_COMPLETION_ROUTINE_PAGABLE,
01752
DCPARAM_IRP +
DCPARAM_ROUTINE,
01753
Irp,
01754 Routine
01755 ));
01756 }
01757 }
01758
01759
01760
01761
01762
01763 irpSpCur =
IoGetCurrentIrpStackLocation(
Irp) ;
01764 CompletionPacket->IsRemoveIrp =
01765 ((
Irp->
CurrentLocation <= (CCHAR)
Irp->
StackCount) &&
01766 (irpSpCur->
MajorFunction ==
IRP_MJ_PNP) &&
01767 (irpSpCur->
MinorFunction ==
IRP_MN_REMOVE_DEVICE)) ;
01768
01769 CompletionPacket->CompletionRoutine = Routine ;
01770
01771
01772
01773
01774
01775
01776
if ((!CompletionPacket->IsRemoveIrp)&&
01777 ((iovSessionData->
AssertFlags&
ASSERTFLAG_DEFERCOMPLETION)||
01778 (iovSessionData->
AssertFlags&
ASSERTFLAG_COMPLETEATPASSIVE))) {
01779
01780
ASSERT(iovSessionData->
AssertFlags&
ASSERTFLAG_FORCEPENDING) ;
01781
01782 irpSpNext =
IoGetNextIrpStackLocation(
Irp) ;
01783
01784 deferralContext =
ExAllocatePoolWithTag(
01785
NonPagedPool,
01786
sizeof(
DEFERRAL_CONTEXT),
01787
POOL_TAG_DEFERRED_CONTEXT
01788 ) ;
01789
01790
if (deferralContext) {
01791
01792
01793
01794
01795 deferralContext->
IovRequestPacket = iovPacket;
01796 deferralContext->
IrpSpNext = irpSpNext;
01797 deferralContext->
OriginalCompletionRoutine = irpSpNext->
CompletionRoutine;
01798 deferralContext->
OriginalContext = irpSpNext->
Context;
01799 deferralContext->
OriginalIrp =
Irp;
01800 deferralContext->
OriginalPriorityBoost = iovPacket->
PriorityBoost;
01801
01802 irpSpNext->
CompletionRoutine =
IovpInternalDeferredCompletion;
01803 irpSpNext->
Context = deferralContext;
01804
IovpTrackingDataReference(iovPacket,
IOVREFTYPE_POINTER);
01805 }
01806 }
01807
01808
IovpTrackingDataReleaseLock(iovPacket) ;
01809 }
01810
01811
VOID
01812
FASTCALL
01813 IovpCompleteRequest4(
01814 IN
PIRP Irp,
01815 IN NTSTATUS ReturnedStatus,
01816 IN OUT
PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket
01817 )
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841 {
01842
PIOV_REQUEST_PACKET iovPacket;
01843
PIOV_SESSION_DATA iovSessionData;
01844
PIO_STACK_LOCATION irpSp;
01845 PVOID routine;
01846
01847 routine = CompletionPacket->CompletionRoutine;
01848 iovSessionData = CompletionPacket->IovSessionData;
01849
01850
if (iovSessionData ==
NULL) {
01851
01852
return;
01853 }
01854
01855 iovPacket = iovSessionData->
IovRequestPacket;
01856
ASSERT(iovPacket);
01857
IovpTrackingDataAcquireLock(iovPacket);
01858
01859
01860
01861
01862
01863
if (iovSessionData->
AssertFlags&
ASSERTFLAG_FORCEPENDING) {
01864
01865
01866
01867
01868
01869
if ((ReturnedStatus != STATUS_MORE_PROCESSING_REQUIRED)&&
01870 (iovPacket->
pIovSessionData == iovSessionData)) {
01871
01872
01873
01874
01875
01876
01877
01878 irpSp =
IoGetCurrentIrpStackLocation(
Irp) ;
01879
if (!(irpSp->
Control &
SL_PENDING_RETURNED )) {
01880
01881
WDM_FAIL_ROUTINE((
01882
DCERROR_PENDING_BIT_NOT_MIGRATED,
01883
DCPARAM_IRP +
DCPARAM_ROUTINE,
01884
Irp,
01885 routine
01886 ));
01887
01888
01889
01890
01891
01892
IoMarkIrpPending(
Irp);
01893 }
01894 }
01895 }
01896
IovpTrackingDataReleaseLock(iovPacket);
01897 }
01898
01899
VOID
01900
FASTCALL
01901 IovpCompleteRequest5(
01902 IN
PIRP Irp,
01903 IN OUT
PIOFCOMPLETEREQUEST_STACKDATA CompletionPacket
01904 )
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926 {
01927
PIOV_REQUEST_PACKET iovPacket;
01928
PIOV_SESSION_DATA iovSessionData;
01929
PIOV_STACK_LOCATION iovCurrentStackLocation ;
01930
NTSTATUS status ;
01931
01932 iovSessionData = CompletionPacket->IovSessionData;
01933
01934
if (iovSessionData) {
01935
01936 iovPacket = iovSessionData->
IovRequestPacket;
01937
ASSERT(iovPacket);
01938
IovpTrackingDataAcquireLock(iovPacket);
01939
01940
ASSERT((!CompletionPacket->RaisedCount) ||
01941 (iovSessionData->
AssertFlags&
ASSERTFLAG_COMPLETEATDPC)) ;
01942
01943
IovpSessionDataDereference(iovSessionData);
01944
IovpTrackingDataReleaseLock(iovPacket);
01945 }
01946
01947
01948
01949
01950
01951
if (CompletionPacket->RaisedCount) {
01952
01953
if (!(--CompletionPacket->RaisedCount)) {
01954
01955
01956
01957
01958
KeLowerIrql(CompletionPacket->PreviousIrql);
01959 }
01960 }
01961 }
01962
01963
VOID
01964
FASTCALL
01965 IovpCompleteRequestApc(
01966 IN
PIRP Irp,
01967 IN PVOID BestStackOffset
01968 )
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989 {
01990
#if DBG
01991
#if defined(_X86_)
01992
PUCHAR addr;
01993
PIOV_REQUEST_PACKET iovPacket;
01994
01995 addr = (PUCHAR)
Irp->
UserIosb;
01996
if ((addr > (PUCHAR)
KeGetCurrentThread()->StackLimit) &&
01997 (addr <= (PUCHAR)BestStackOffset)) {
01998
01999 iovPacket =
IovpTrackingDataFindAndLock(
Irp) ;
02000
02001
RtlAssert(
"UserIosb below stack pointer", __FILE__, (ULONG) iovPacket,
02002
"Call AdriaO");
02003
02004
IovpTrackingDataReleaseLock(iovPacket) ;
02005 }
02006
02007 addr = (PUCHAR)
Irp->
UserEvent;
02008
if ((addr > (PUCHAR)
KeGetCurrentThread()->StackLimit) &&
02009 (addr <= (PUCHAR)BestStackOffset)) {
02010
02011 iovPacket =
IovpTrackingDataFindAndLock(
Irp) ;
02012
02013
RtlAssert(
"UserEvent below stack pointer", __FILE__, (ULONG) iovPacket,
02014
"Call AdriaO");
02015
02016
IovpTrackingDataReleaseLock(iovPacket) ;
02017 }
02018
#endif
02019
#endif
02020
}
02021
02022 BOOLEAN
02023 IovpAdvanceStackDownwards(
02024 IN
PIOV_STACK_LOCATION StackDataArray,
02025 IN CCHAR CurrentLocation,
02026 IN
PIO_STACK_LOCATION IrpSp,
02027 IN
PIO_STACK_LOCATION IrpLastSp OPTIONAL,
02028 IN ULONG LocationsAdvanced,
02029 IN BOOLEAN IsNewRequest,
02030 IN BOOLEAN MarkAsTaken,
02031 OUT
PIOV_STACK_LOCATION *StackLocationInfo
02032 )
02033 {
02034
PIOV_STACK_LOCATION iovCurrentStackLocation, advancedLocationData, requestOriginalSLD;
02035
PIO_STACK_LOCATION irpSpTemp;
02036 PLARGE_INTEGER dispatchTime, stackTime;
02037 BOOLEAN isNewSession, wasInUse;
02038 PVOID dispatchRoutine;
02039
02040 isNewSession = (IrpLastSp ==
NULL);
02041
ASSERT((!isNewSession) || (LocationsAdvanced == 1));
02042
ASSERT(isNewSession || ((ULONG) (IrpLastSp - IrpSp) == LocationsAdvanced));
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052 iovCurrentStackLocation = StackDataArray + CurrentLocation -1;
02053
02054
TRACKIRP_DBGPRINT((
02055
" Smacking %lx (%lx) to valid in SD\n",
02056 CurrentLocation -1, iovCurrentStackLocation
02057 ), 2);
02058
02059
02060
02061
02062
if (iovCurrentStackLocation->
InUse) {
02063
02064
02065
02066
02067
ASSERT(!LocationsAdvanced);
02068
ASSERT(IrpSp == iovCurrentStackLocation->
IrpSp);
02069
02070 }
else if (MarkAsTaken) {
02071
02072
02073
02074
02075
02076
02077
ASSERT(LocationsAdvanced);
02078 RtlZeroMemory(iovCurrentStackLocation,
sizeof(
IOV_STACK_LOCATION));
02079 InitializeListHead(&iovCurrentStackLocation->
CallStackData);
02080 iovCurrentStackLocation->
IrpSp = IrpSp;
02081 }
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
if (isNewSession) {
02092
02093
02094
02095
02096
02097 dispatchRoutine =
NULL;
02098 requestOriginalSLD =
NULL;
02099 stackTime =
NULL;
02100 dispatchTime =
NULL;
02101
02102 }
else if (LocationsAdvanced) {
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113 dispatchTime = &iovCurrentStackLocation[LocationsAdvanced].
PerfDispatchStart;
02114 stackTime = &iovCurrentStackLocation[LocationsAdvanced].PerfStackLocationStart;
02115 dispatchRoutine = iovCurrentStackLocation[LocationsAdvanced].LastDispatch;
02116 requestOriginalSLD = iovCurrentStackLocation[LocationsAdvanced].
RequestsFirstStackLocation;
02117
02118
ASSERT(dispatchRoutine);
02119
ASSERT(iovCurrentStackLocation[LocationsAdvanced].InUse);
02120
ASSERT(requestOriginalSLD->
RequestsFirstStackLocation == requestOriginalSLD);
02121 iovCurrentStackLocation->RequestsFirstStackLocation = requestOriginalSLD;
02122
02123 }
else {
02124
02125
02126
02127
02128 dispatchRoutine =
NULL;
02129 dispatchTime =
NULL;
02130 stackTime =
NULL;
02131 requestOriginalSLD = iovCurrentStackLocation->
RequestsFirstStackLocation;
02132
ASSERT(requestOriginalSLD);
02133
ASSERT(requestOriginalSLD->
RequestsFirstStackLocation == requestOriginalSLD);
02134 }
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144 advancedLocationData = iovCurrentStackLocation;
02145 irpSpTemp = IrpSp;
02146
while(LocationsAdvanced>1) {
02147 advancedLocationData++ ;
02148 LocationsAdvanced-- ;
02149 irpSpTemp++ ;
02150
TRACKIRP_DBGPRINT((
02151
" Late smacking %lx to valid in CD1\n",
02152 advancedLocationData - StackDataArray
02153 ), 3) ;
02154
02155
ASSERT(!advancedLocationData->
InUse) ;
02156 RtlZeroMemory(advancedLocationData,
sizeof(
IOV_STACK_LOCATION)) ;
02157 InitializeListHead(&advancedLocationData->
CallStackData) ;
02158 advancedLocationData->
InUse =
TRUE ;
02159 advancedLocationData->
IrpSp = irpSpTemp ;
02160
02161 advancedLocationData->
RequestsFirstStackLocation = requestOriginalSLD ;
02162 advancedLocationData->
PerfDispatchStart = *dispatchTime;
02163 advancedLocationData->
PerfStackLocationStart = *stackTime;
02164 advancedLocationData->
LastDispatch = dispatchRoutine ;
02165 }
02166
02167
02168
02169
02170
if (LocationsAdvanced) {
02171 irpSpTemp++ ;
02172 }
02173
ASSERT((irpSpTemp == IrpLastSp)||(IrpLastSp ==
NULL)) ;
02174
02175
02176
02177
02178 *StackLocationInfo = iovCurrentStackLocation;
02179
02180
if (!MarkAsTaken) {
02181
return iovCurrentStackLocation->InUse;
02182 }
02183
02184
02185
02186
02187
02188
if (IsNewRequest) {
02189
02190
TRACKIRP_DBGPRINT((
02191
" CD1: %lx is a new request\n",
02192 advancedLocationData-StackDataArray
02193 ), 3) ;
02194
02195
ASSERT(LocationsAdvanced == 1) ;
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205 iovCurrentStackLocation->RequestsFirstStackLocation = iovCurrentStackLocation;
02206
02207 }
else if (LocationsAdvanced) {
02208
02209
ASSERT(!isNewSession) ;
02210
02211
02212
02213
02214
02215
TRACKIRP_DBGPRINT((
02216
" CD1: %lx is a request for %lx\n",
02217 advancedLocationData-StackDataArray,
02218 requestOriginalSLD-StackDataArray
02219 ), 3) ;
02220
02221 }
else {
02222
02223
02224
02225
02226
02227
02228
02229
ASSERT(!isNewSession) ;
02230
ASSERT(advancedLocationData->
RequestsFirstStackLocation == requestOriginalSLD) ;
02231 }
02232
02233 wasInUse = iovCurrentStackLocation->InUse;
02234 iovCurrentStackLocation->InUse =
TRUE;
02235
return wasInUse;
02236 }
02237
02238
VOID
02239 IovpExamineIrpStackForwarding(
02240 IN OUT
PIOV_REQUEST_PACKET IovPacket,
02241 IN BOOLEAN IsNewSession,
02242 IN ULONG ForwardMethod,
02243 IN
PDEVICE_OBJECT DeviceObject,
02244 IN
PIRP Irp,
02245 IN OUT
PIO_STACK_LOCATION *IoCurrentStackLocation,
02246 OUT
PIO_STACK_LOCATION *IoLastStackLocation,
02247 OUT ULONG *StackLocationsAdvanced
02248 )
02249 {
02250
PIRP irp;
02251
PIO_STACK_LOCATION irpSp, irpLastSp;
02252 BOOLEAN isSameStack;
02253 ULONG locationsAdvanced;
02254
02255 irpSp = *IoCurrentStackLocation;
02256
02257
if (!IsNewSession) {
02258
02259
02260
02261
02262
02263 locationsAdvanced = IovPacket->LastLocation-
Irp->
CurrentLocation ;
02264 irpLastSp =
Irp->
Tail.Overlay.CurrentStackLocation+(locationsAdvanced-1) ;
02265
02266 }
else {
02267
02268
02269
02270
02271 locationsAdvanced = 1 ;
02272 irpLastSp =
NULL ;
02273 }
02274
02275
if ((!IsNewSession) && (IovPacket->AssertFlags&
ASSERTFLAG_POLICEIRPS)) {
02276
02277
02278
02279
02280
02281
02282
02283
02284
if ((irpSp->
Control&
SL_NOTCOPIED)&&
02285 IovPacket->LastLocation !=
Irp->
CurrentLocation) {
02286
02287
#if 0
02288
FAIL_CALLER_OF_IOFCALLDRIVER2(
02289 (
DCERROR_NEXTIRPSP_DIRTY,
DCPARAM_IRP,
Irp),
02290 irpSp
02291 );
02292
#endif
02293
}
02294
02295
02296
02297
02298
02299
if (locationsAdvanced) {
02300
02301
02302
02303
02304
02305 isSameStack = RtlEqualMemory(irpSp, irpLastSp,
02306 FIELD_OFFSET(
IO_STACK_LOCATION, Control)) ;
02307
02308 isSameStack &= RtlEqualMemory(&irpSp->
Parameters, &irpLastSp->
Parameters,
02309 FIELD_OFFSET(
IO_STACK_LOCATION, DeviceObject)-
02310 FIELD_OFFSET(
IO_STACK_LOCATION, Parameters)) ;
02311
02312 isSameStack &= (irpSp->
FileObject == irpLastSp->
FileObject) ;
02313
02314
02315
02316
02317
02318
ASSERT(irpSp->
CompletionRoutine !=
IovpSwapSurrogateIrp) ;
02319
02320
if (isSameStack) {
02321
02322
02323
02324
02325
02326
02327
if ((irpSp->
CompletionRoutine == irpLastSp->
CompletionRoutine)&&
02328 (irpSp->
Context == irpLastSp->
Context) &&
02329 (irpSp->
Control == irpLastSp->
Control) &&
02330 (irpSp->
CompletionRoutine !=
NULL) &&
02331 (DeviceObject->DriverObject != irpLastSp->
DeviceObject->
DriverObject)
02332 ) {
02333
02334
02335
02336
02337
02338
02339
FAIL_CALLER_OF_IOFCALLDRIVER2(
02340 (
DCERROR_IRPSP_COPIED,
DCPARAM_IRP,
Irp),
02341 irpSp
02342 ) ;
02343
02344
02345
02346
02347 irpSp->
CompletionRoutine =
NULL ;
02348 irpSp->
Control = 0 ;
02349
02350 }
else if (!irpSp->
CompletionRoutine) {
02351
02352
if (!(irpSp->
Control&
SL_NOTCOPIED)
02353
#ifdef HACKHACKS_ENABLED
02354
&& (!(
IovpHackFlags&
HACKFLAG_FOR_SCSIPORT))
02355
#endif
02356
) {
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
if (irpSp->
MajorFunction ==
IRP_MJ_POWER) {
02369
02370
02371
02372
02373
WDM_CHASTISE_CALLER5(
02374 (
DCERROR_UNNECCESSARY_COPY,
DCPARAM_IRP,
Irp)
02375 );
02376
02377 }
else {
02378
02379
WDM_CHASTISE_CALLER3(
02380 (
DCERROR_UNNECCESSARY_COPY,
DCPARAM_IRP,
Irp)
02381 );
02382 }
02383 }
02384
02385
IoSetCompletionRoutine(
02386
Irp,
02387
IovpInternalCompletionTrap,
02388
IoGetCurrentIrpStackLocation(
Irp ),
02389
TRUE,
02390
TRUE,
02391
TRUE
02392 ) ;
02393 }
02394 }
02395
02396 }
else if (IovPacket->AssertFlags&
ASSERTFLAG_CONSUME_ALWAYS) {
02397
02398
if (ForwardMethod ==
FORWARDED_TO_NEXT_DO) {
02399
02400
if (
Irp->
CurrentLocation<2) {
02401
02402
FAIL_CALLER_OF_IOFCALLDRIVER2(
02403 (
DCERROR_INSUFFICIENT_STACK_LOCATIONS,
DCPARAM_IRP,
Irp),
02404 irpSp
02405 ) ;
02406
02407 }
else {
02408
02409
02410
02411
02412
02413
02414
02415
IoSetNextIrpStackLocation(
Irp ) ;
02416
02417
02418
02419
02420
IoCopyCurrentIrpStackLocationToNext(
Irp ) ;
02421
IoSetCompletionRoutine(
02422
Irp,
02423
IovpInternalCompletionTrap,
02424
IoGetCurrentIrpStackLocation(
Irp ),
02425
TRUE,
02426
TRUE,
02427
TRUE
02428 ) ;
02429
02430
02431
02432
02433 locationsAdvanced = 1 ;
02434 irpSp =
IoGetNextIrpStackLocation(
Irp );
02435 }
02436 }
02437 }
02438 }
02439
02440 *IoCurrentStackLocation = irpSp;
02441 *IoLastStackLocation = irpLastSp;
02442 *StackLocationsAdvanced = locationsAdvanced;
02443 }
02444
02445
NTSTATUS
02446 IovpInternalCompletionTrap(
02447 IN
PDEVICE_OBJECT DeviceObject,
02448 IN
PIRP Irp,
02449 IN PVOID Context
02450 )
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473 {
02474
PIO_STACK_LOCATION irpSp ;
02475
02476
if (
Irp->
PendingReturned) {
02477
02478
IoMarkIrpPending(
Irp ) ;
02479 }
02480 irpSp =
IoGetCurrentIrpStackLocation(
Irp ) ;
02481
02482
ASSERT((PVOID) irpSp == Context) ;
02483
02484
return STATUS_SUCCESS ;
02485 }
02486
02487
VOID
02488 IovpInternalCompleteAtDPC(
02489 IN
PKDPC Dpc,
02490 IN PVOID DeferredContext,
02491 IN PVOID SystemArgument1,
02492 IN PVOID SystemArgument2
02493 )
02494 {
02495
IovpInternalCompleteAfterWait(DeferredContext) ;
02496 }
02497
02498
VOID
02499 IovpInternalCompleteAfterWait(
02500 IN PVOID Context
02501 )
02502 {
02503
PDEFERRAL_CONTEXT deferralContext = (
PDEFERRAL_CONTEXT) Context ;
02504
PIO_STACK_LOCATION irpSpNext ;
02505
NTSTATUS status ;
02506
02507
if (deferralContext->
DeferAction ==
DEFERACTION_QUEUE_PASSIVE_TIMER) {
02508
02509
02510
02511
02512
ASSERT(KeGetCurrentIrql()==
PASSIVE_LEVEL) ;
02513
KeWaitForSingleObject(
02514 &deferralContext->
DeferralTimer,
02515
Executive,
02516
KernelMode,
02517
FALSE,
02518
NULL
02519 ) ;
02520 }
02521
02522
IovpTrackingDataAcquireLock(deferralContext->
IovRequestPacket) ;
02523
02524
IovpProtectedIrpMakeTouchable(
02525 deferralContext->
OriginalIrp,
02526 &deferralContext->
IovRequestPacket->
RestoreHandle
02527 );
02528
02529 irpSpNext =
IoGetNextIrpStackLocation( deferralContext->
OriginalIrp ) ;
02530
02531
ASSERT(irpSpNext == deferralContext->
IrpSpNext) ;
02532
ASSERT(irpSpNext->
CompletionRoutine == deferralContext->
OriginalCompletionRoutine) ;
02533
ASSERT(irpSpNext->
Context == deferralContext->
OriginalContext) ;
02534
02535
ASSERT(deferralContext->
IovRequestPacket->
Flags &
TRACKFLAG_QUEUED_INTERNALLY) ;
02536 deferralContext->
IovRequestPacket->
Flags &=~ TRACKFLAG_QUEUED_INTERNALLY ;
02537
02538
IovpTrackingDataDereference(deferralContext->
IovRequestPacket,
IOVREFTYPE_POINTER) ;
02539
IovpTrackingDataReleaseLock(deferralContext->
IovRequestPacket) ;
02540
02541 status = irpSpNext->
CompletionRoutine(
02542 deferralContext->
DeviceObject,
02543 deferralContext->
OriginalIrp,
02544 irpSpNext->
Context
02545 ) ;
02546
02547
if (status!=STATUS_MORE_PROCESSING_REQUIRED) {
02548
02549
IoCompleteRequest(deferralContext->
OriginalIrp, deferralContext->
OriginalPriorityBoost) ;
02550 }
02551
ExFreePool(deferralContext) ;
02552 }
02553
02554
NTSTATUS
02555 IovpInternalDeferredCompletion(
02556 IN
PDEVICE_OBJECT DeviceObject,
02557 IN
PIRP Irp,
02558 IN PVOID Context
02559 )
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582 {
02583
PDEFERRAL_CONTEXT deferralContext = (
PDEFERRAL_CONTEXT) Context;
02584
PIO_STACK_LOCATION irpSpNext;
02585 BOOLEAN passiveCompletionOK;
02586
DEFER_ACTION deferAction;
02587 ULONG refAction;
02588 ULONG trackingFlags;
02589 LARGE_INTEGER deltaTime;
02590
02591
02592
02593
02594 deltaTime.QuadPart = -
IovpIrpDeferralTime ;
02595
02596
02597
02598
02599
02600 irpSpNext =
IoGetNextIrpStackLocation(
Irp ) ;
02601
02602
ASSERT((PVOID) irpSpNext->
CompletionRoutine ==
IovpInternalDeferredCompletion) ;
02603
02604
02605
02606
02607 irpSpNext->
CompletionRoutine = deferralContext->
OriginalCompletionRoutine ;
02608 irpSpNext->
Context = deferralContext->
OriginalContext ;
02609
02610
02611
02612
02613
02614
02615 passiveCompletionOK = (KeGetCurrentIrql()==
PASSIVE_LEVEL) ;
02616
02617
IovpTrackingDataAcquireLock(deferralContext->
IovRequestPacket) ;
02618
02619
02620
02621
02622
if (deferralContext->
IovRequestPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS) {
02623
02624
if (
MmIsSystemAddressLocked(irpSpNext->
CompletionRoutine) ==
FALSE) {
02625
02626
WDM_FAIL_ROUTINE((
02627
DCERROR_COMPLETION_ROUTINE_PAGABLE,
02628
DCPARAM_IRP +
DCPARAM_ROUTINE,
02629
Irp,
02630 irpSpNext->
CompletionRoutine
02631 )) ;
02632 }
02633 }
02634
02635 trackingFlags = deferralContext->
IovRequestPacket->
AssertFlags;
02636
02637
ASSERT(trackingFlags&
ASSERTFLAG_FORCEPENDING) ;
02638
02639
switch(trackingFlags&(
ASSERTFLAG_DEFERCOMPLETION|
02640
ASSERTFLAG_COMPLETEATPASSIVE|
02641
ASSERTFLAG_COMPLETEATDPC)) {
02642
02643
case ASSERTFLAG_COMPLETEATPASSIVE:
02644 deferAction = passiveCompletionOK ?
DEFERACTION_QUEUE_WORKITEM :
02645
DEFERACTION_NORMAL ;
02646
break;
02647
02648
case ASSERTFLAG_DEFERCOMPLETION |
ASSERTFLAG_COMPLETEATPASSIVE:
02649 deferAction = passiveCompletionOK ?
DEFERACTION_QUEUE_PASSIVE_TIMER :
02650
DEFERACTION_NORMAL ;
02651
break;
02652
02653
case ASSERTFLAG_DEFERCOMPLETION |
ASSERTFLAG_COMPLETEATDPC:
02654 deferAction =
DEFERACTION_QUEUE_DISPATCH_TIMER ;
02655
break;
02656
02657
case ASSERTFLAG_DEFERCOMPLETION:
02658 deferAction = (KeGetCurrentIrql()==
DISPATCH_LEVEL) ?
02659
DEFERACTION_QUEUE_DISPATCH_TIMER :
02660
DEFERACTION_QUEUE_PASSIVE_TIMER ;
02661
break;
02662
02663
default:
02664 deferAction =
DEFERACTION_NORMAL ;
02665
KDASSERT(0) ;
02666 }
02667
02668
if (deferAction !=
DEFERACTION_NORMAL) {
02669
02670
02671
02672
02673
02674
ASSERT(!(trackingFlags&
TRACKFLAG_QUEUED_INTERNALLY)) ;
02675 deferralContext->
IovRequestPacket->
Flags |=
TRACKFLAG_QUEUED_INTERNALLY ;
02676 deferralContext->
DeviceObject = DeviceObject ;
02677
02678 deferralContext->
IovRequestPacket->
RestoreHandle =
02679
IovpProtectedIrpMakeUntouchable(
02680
Irp,
02681
FALSE
02682 ) ;
02683 }
else {
02684
02685
IovpTrackingDataDereference(deferralContext->
IovRequestPacket,
IOVREFTYPE_POINTER);
02686 }
02687
02688
IovpTrackingDataReleaseLock(deferralContext->
IovRequestPacket) ;
02689
02690 deferralContext->
DeferAction = deferAction ;
02691
02692
switch(deferAction) {
02693
02694
case DEFERACTION_QUEUE_PASSIVE_TIMER:
02695
KeInitializeTimerEx(&deferralContext->
DeferralTimer, SynchronizationTimer) ;
02696
KeSetTimerEx(
02697 &deferralContext->
DeferralTimer,
02698 deltaTime,
02699 0,
02700
NULL
02701 ) ;
02702
02703
02704
02705
02706
02707
case DEFERACTION_QUEUE_WORKITEM:
02708
02709
02710
02711
02712
ExInitializeWorkItem(
02713 (
PWORK_QUEUE_ITEM)&deferralContext->
WorkQueueItem,
02714
IovpInternalCompleteAfterWait,
02715 deferralContext
02716 );
02717
02718
ExQueueWorkItem(
02719 (
PWORK_QUEUE_ITEM)&deferralContext->
WorkQueueItem,
02720
DelayedWorkQueue
02721 );
02722
02723
return STATUS_MORE_PROCESSING_REQUIRED ;
02724
02725
case DEFERACTION_QUEUE_DISPATCH_TIMER:
02726
02727
KeInitializeDpc(
02728 &deferralContext->
DpcItem,
02729
IovpInternalCompleteAtDPC,
02730 deferralContext
02731 );
02732
02733
KeInitializeTimerEx(&deferralContext->
DeferralTimer, SynchronizationTimer) ;
02734
KeSetTimerEx(
02735 &deferralContext->
DeferralTimer,
02736 deltaTime,
02737 0,
02738 &deferralContext->
DpcItem
02739 ) ;
02740
return STATUS_MORE_PROCESSING_REQUIRED ;
02741
02742
case DEFERACTION_NORMAL:
02743
default:
02744
02745
ExFreePool(deferralContext) ;
02746
return irpSpNext->
CompletionRoutine(DeviceObject,
Irp, irpSpNext->
Context) ;
02747 }
02748 }
02749
02750
NTSTATUS
02751 IovpSwapSurrogateIrp(
02752 IN
PDEVICE_OBJECT DeviceObject,
02753 IN
PIRP Irp,
02754 IN PVOID Context
02755 )
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778 {
02779
PIOV_REQUEST_PACKET iovPacket, iovPrevPacket;
02780
PIOV_SESSION_DATA iovSessionData;
02781 ULONG irpSize ;
02782
PIRP realIrp ;
02783 BOOLEAN freeTrackingData ;
02784
NTSTATUS status, lockedStatus ;
02785 CCHAR priorityBoost ;
02786 PVOID completionRoutine ;
02787
PIO_STACK_LOCATION irpSp ;
02788 BOOLEAN locked ;
02789
02790
02791
02792
02793
02794
02795
ASSERT(
Irp == Context) ;
02796
02797 iovPacket =
IovpTrackingDataFindAndLock(
Irp) ;
02798
ASSERT(iovPacket) ;
02799
02800
if (iovPacket ==
NULL) {
02801
02802
return STATUS_SUCCESS ;
02803 }
02804
02805
ASSERT(iovPacket->
TopStackLocation ==
Irp->
CurrentLocation) ;
02806
02807 iovSessionData =
IovpTrackingDataGetCurrentSessionData(iovPacket);
02808
ASSERT(iovSessionData);
02809
02810
02811
02812
02813
ASSERT(iovPacket->
HeadPacket != iovPacket);
02814
02815 iovPrevPacket = CONTAINING_RECORD(
02816 iovPacket->
SurrogateLink.Blink,
02817
IOV_REQUEST_PACKET,
02818 SurrogateLink
02819 );
02820
02821 realIrp = iovPrevPacket->
TrackedIrp ;
02822 irpSize =
IoSizeOfIrp(
Irp->
StackCount ) ;
02823
02824
02825
02826
02827
02828
IoSetNextIrpStackLocation(
Irp);
02829
IoSetNextIrpStackLocation(realIrp);
02830
02831 irpSp =
IoGetCurrentIrpStackLocation(
Irp) ;
02832 irpSp->
CompletionRoutine = iovPacket->
RealIrpCompletionRoutine ;
02833 irpSp->
Control = iovPacket->
RealIrpControl ;
02834 irpSp->
Context = iovPacket->
RealIrpContext ;
02835
02836
02837
02838
02839
02840 irpSp =
IoGetNextIrpStackLocation(
Irp) ;
02841
if (iovPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS) {
02842
02843
IovpAssertFinalIrpStack(iovPacket, irpSp) ;
02844 }
02845
02846 priorityBoost = iovPacket->
PriorityBoost ;
02847
IovpTrackingDataDereference(iovPacket,
IOVREFTYPE_POINTER);
02848
IovpSessionDataFinalizeSurrogate(iovSessionData, iovPacket,
Irp);
02849
IovpSessionDataClose(iovSessionData);
02850
IovpSessionDataDereference(iovSessionData);
02851
02852
TRACKIRP_DBGPRINT((
02853
" Swapping surrogate IRP %lx back to %lx (Tracking data %lx)\n",
02854
Irp,
02855 realIrp,
02856 iovPacket
02857 ), 1) ;
02858
02859 iovPacket->
Flags |=
TRACKFLAG_SWAPPED_BACK ;
02860
IovpTrackingDataReleaseLock(iovPacket) ;
02861
02862
02863
02864
02865
IoCompleteRequest(realIrp, priorityBoost) ;
02866
02867
return STATUS_MORE_PROCESSING_REQUIRED ;
02868 }
02869
02870
VOID
02871
FASTCALL
02872 IovpCancelIrp(
02873 IN
PIRP Irp,
02874 OUT PBOOLEAN CancelHandled,
02875 OUT PBOOLEAN ReturnValue
02876 )
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906 {
02907
PIOV_REQUEST_PACKET iovPacket, iovNextPacket;
02908
PIRP irpToCancel;
02909 KIRQL irql ;
02910
02911 *CancelHandled =
FALSE ;
02912
02913 iovPacket =
IovpTrackingDataFindAndLock(
Irp) ;
02914
if (!iovPacket) {
02915
02916
return ;
02917 }
02918
02919
02920
02921
02922
02923
02924
02925
if (iovPacket->
Flags&
TRACKFLAG_QUEUED_INTERNALLY) {
02926
02927
IovpProtectedIrpMakeTouchable(
02928
Irp,
02929 &iovPacket->
RestoreHandle
02930 );
02931
02932 iovPacket->
RestoreHandle =
NULL ;
02933 }
02934
02935
if (!(iovPacket->
Flags&
TRACKFLAG_ACTIVE)) {
02936
02937
02938
02939
02940
02941
02942
IovpTrackingDataReleaseLock(iovPacket);
02943
return;
02944 }
02945
02946
if (!(iovPacket->
Flags&
TRACKFLAG_HAS_SURROGATE)) {
02947
02948
02949
02950
02951
02952
IovpTrackingDataReleaseLock(iovPacket);
02953
return;
02954 }
02955
02956
if (iovPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS) {
02957
02958
if (
Irp->
CancelRoutine) {
02959
02960
WDM_FAIL_ROUTINE((
02961
DCERROR_CANCELROUTINE_ON_FORWARDED_IRP,
02962
DCPARAM_IRP +
DCPARAM_ROUTINE,
02963
Irp,
02964
Irp->
CancelRoutine
02965 ));
02966
02967
02968
02969
02970 }
02971 }
02972
02973 iovNextPacket = CONTAINING_RECORD(
02974 iovPacket->
SurrogateLink.Flink,
02975
IOV_REQUEST_PACKET,
02976 SurrogateLink
02977 );
02978
02979
Irp->
Cancel =
TRUE;
02980 *CancelHandled =
TRUE ;
02981 irpToCancel = iovNextPacket->
TrackedIrp ;
02982
IovpTrackingDataReleaseLock(iovPacket) ;
02983 *ReturnValue =
IoCancelIrp(irpToCancel) ;
02984
02985
return ;
02986 }
02987
02988
VOID
02989
FASTCALL
02990 IovpFreeIrp(
02991 IN
PIRP Irp,
02992 IN OUT PBOOLEAN FreeHandled
02993 )
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018 {
03019
PIOV_REQUEST_PACKET iovPacket;
03020 PVOID restoreHandle ;
03021
03022 iovPacket =
IovpTrackingDataFindAndLock(
Irp);
03023
03024
if (iovPacket ==
NULL) {
03025
03026
03027
03028
03029
03030
ASSERT(!(
Irp->
AllocationFlags&
IRP_ALLOCATION_MONITORED));
03031 *FreeHandled =
FALSE ;
03032
return;
03033 }
03034
03035
if (!IsListEmpty(&
Irp->
ThreadListEntry)) {
03036
03037
if (iovPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS) {
03038
03039
WDM_FAIL_CALLER2(
03040 (
DCERROR_FREE_OF_THREADED_IRP,
DCPARAM_IRP,
Irp)
03041 );
03042 }
03043
03044
03045
03046
03047
03048 *FreeHandled =
TRUE ;
03049
return ;
03050 }
03051
03052
if (
IovpTrackingDataGetCurrentSessionData(iovPacket)) {
03053
03054
03055
03056
03057
03058
03059
03060
if ((iovPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS) &&
03061 (!(iovPacket->
Flags&
TRACKFLAG_UNWOUND_BADLY))) {
03062
03063
WDM_FAIL_CALLER2(
03064 (
DCERROR_FREE_OF_INUSE_IRP,
DCPARAM_IRP,
Irp)
03065 );
03066 }
03067
03068
03069
03070
03071
03072
IovpTrackingDataReleaseLock(iovPacket) ;
03073 *FreeHandled =
TRUE ;
03074
return ;
03075 }
03076
03077
if (!(iovPacket->
Flags&
TRACKFLAG_IO_ALLOCATED)) {
03078
03079
03080
03081
03082
03083
03084
ASSERT(0);
03085
IovpTrackingDataReleaseLock(iovPacket) ;
03086 *FreeHandled =
FALSE ;
03087
return;
03088 }
03089
03090
03091
03092
03093
03094
03095
03096
03097
if (!(iovPacket->
Flags&
TRACKFLAG_PROTECTEDIRP)) {
03098
03099
03100
03101
03102
IovpTrackingDataDereference(iovPacket,
IOVREFTYPE_POINTER);
03103
IovpTrackingDataReleaseLock(iovPacket);
03104 *FreeHandled =
FALSE;
03105
return;
03106 }
03107
03108
03109
03110
03111
03112
03113
Irp->
Type = 0;
03114
03115
ASSERT(iovPacket) ;
03116
ASSERT(iovPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS);
03117
IovpTrackingDataDereference(iovPacket,
IOVREFTYPE_POINTER);
03118
ASSERT(iovPacket->
PointerCount == 0);
03119
IovpTrackingDataReleaseLock(iovPacket) ;
03120 restoreHandle =
IovpProtectedIrpMakeUntouchable(
Irp,
TRUE) ;
03121
IovpProtectedIrpFree(
Irp, &restoreHandle) ;
03122
03123
03124
03125
03126
03127 *FreeHandled =
TRUE ;
03128 }
03129
03130
VOID
03131
FASTCALL
03132 IovpAllocateIrp1(
03133 IN CCHAR StackSize,
03134 IN BOOLEAN ChargeQuota,
03135 IN OUT
PIRP *IrpPointer
03136 )
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163 {
03164
PIOV_REQUEST_PACKET iovPacket;
03165 PVOID returnAddress[1];
03166 ULONG stackHash;
03167
PIRP irp;
03168
03169 *IrpPointer =
NULL ;
03170
if (!(
IovpTrackingFlags&
ASSERTFLAG_MONITOR_ALLOCS)) {
03171
03172
return ;
03173 }
03174
03175
if (!(
IovpTrackingFlags&
ASSERTFLAG_POLICEIRPS)) {
03176
03177
return ;
03178 }
03179
03180 irp =
IovpProtectedIrpAllocate(
03181 StackSize,
03182 ChargeQuota,
03183
PsGetCurrentThread()
03184 ) ;
03185
03186
if (irp ==
NULL) {
03187
03188
return;
03189 }
03190
03191
IopInitializeIrp(irp,
IoSizeOfIrp(StackSize), StackSize);
03192 *IrpPointer = irp;
03193
03194 iovPacket =
IovpTrackingDataCreateAndLock(irp);
03195
03196
if (iovPacket ==
NULL) {
03197
03198
return;
03199 }
03200
03201
IovpTrackingDataReference(iovPacket,
IOVREFTYPE_POINTER);
03202 iovPacket->
Flags |=
TRACKFLAG_PROTECTEDIRP |
TRACKFLAG_IO_ALLOCATED;
03203 irp->AllocationFlags |=
IRP_ALLOCATION_MONITORED ;
03204 irp->Flags |=
IRPFLAG_EXAMINE_TRACKED;
03205
03206
03207
03208
03209
RtlCaptureStackBackTrace(3,
IRP_ALLOC_COUNT, iovPacket->
AllocatorStack, &stackHash) ;
03210
03211
IovpTrackingDataReleaseLock(iovPacket) ;
03212 }
03213
03214
VOID
03215
FASTCALL
03216 IovpAllocateIrp2(
03217 IN
PIRP Irp
03218 )
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235 {
03236
PIOV_REQUEST_PACKET iovPacket;
03237 PVOID returnAddress[1];
03238 ULONG stackHash;
03239
03240
if (!(
IovpTrackingFlags&
ASSERTFLAG_MONITOR_ALLOCS)) {
03241
03242
return;
03243 }
03244
03245
03246
03247 iovPacket =
IovpTrackingDataCreateAndLock(
Irp);
03248
if (iovPacket ==
NULL) {
03249
03250
return;
03251 }
03252
03253
IovpTrackingDataReference(iovPacket,
IOVREFTYPE_POINTER);
03254 iovPacket->
Flags |=
TRACKFLAG_IO_ALLOCATED;
03255
Irp->
AllocationFlags |=
IRP_ALLOCATION_MONITORED;
03256
Irp->
Flags |=
IRPFLAG_EXAMINE_TRACKED;
03257
03258
03259
03260
03261
RtlCaptureStackBackTrace(2,
IRP_ALLOC_COUNT, iovPacket->
AllocatorStack, &stackHash) ;
03262
03263
IovpTrackingDataReleaseLock(iovPacket) ;
03264 }
03265
03266
VOID
03267
FASTCALL
03268 IovpInitializeIrp(
03269 IN OUT
PIRP Irp,
03270 IN USHORT PacketSize,
03271 IN CCHAR StackSize,
03272 IN OUT PBOOLEAN InitializeHandled
03273 )
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302 {
03303
PIOV_REQUEST_PACKET iovPacket ;
03304
03305 iovPacket =
IovpTrackingDataFindAndLock(
Irp);
03306
if (iovPacket ==
NULL) {
03307
03308 *InitializeHandled =
FALSE ;
03309
return;
03310 }
03311
03312
if ((iovPacket->
AssertFlags&
ASSERTFLAG_POLICEIRPS) &&
03313 (iovPacket->
Flags&
TRACKFLAG_IO_ALLOCATED)) {
03314
03315
if (
Irp->
AllocationFlags&
IRP_QUOTA_CHARGED) {
03316
03317
03318
03319
03320
WDM_FAIL_CALLER2(
03321 (
DCERROR_REINIT_OF_ALLOCATED_IRP_WITH_QUOTA,
DCPARAM_IRP,
Irp)
03322 );
03323
03324 }
else {
03325
03326
03327
03328
03329
03330
03331
03332 }
03333 }
03334
03335 *InitializeHandled =
FALSE ;
03336
IovpTrackingDataReleaseLock(iovPacket) ;
03337 }
03338
03339
03340
03341
03342
03343
03344
03345
VOID
03346 IovpAttachDeviceToDeviceStack(
03347 IN
PDEVICE_OBJECT NewDevice,
03348 IN
PDEVICE_OBJECT ExistingDevice
03349 )
03350 {
03351 }
03352
03353
VOID
03354 IovpDetachDevice(
03355 IN
PDEVICE_OBJECT LowerDevice
03356 )
03357 {
03358
PDEVOBJ_EXTENSION deviceExtension;
03359
03360
if (LowerDevice->AttachedDevice ==
NULL) {
03361
03362
WDM_FAIL_CALLER2((
DCERROR_DETACH_NOT_ATTACHED,
DCPARAM_DEVOBJ, LowerDevice));
03363 }
else {
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373 deviceExtension = LowerDevice->AttachedDevice->DeviceObjectExtension;
03374 deviceExtension->
ExtensionFlags &=~ (
DOE_EXAMINED |
DOE_TRACKED);
03375 }
03376 }
03377
03378
VOID
03379 IovpDeleteDevice(
03380 IN
PDEVICE_OBJECT DeviceObject
03381 )
03382 {
03383
PDEVICE_OBJECT deviceBelow;
03384
03385
03386
03387
03388
03389
03390 deviceBelow =
IovpGetDeviceAttachedTo(DeviceObject);
03391
if (deviceBelow) {
03392
03393
WDM_FAIL_CALLER1((
DCERROR_DELETE_WHILE_ATTACHED, 0));
03394
ObDereferenceObject(deviceBelow);
03395 }
03396 }
03397
03398
VOID
03399 IovpReexamineAllStacks(
03400 VOID
03401 )
03402 {
03403
PAGED_CODE();
03404
03405
ObEnumerateObjectsByType(
03406
IoDeviceObjectType,
03407
IovpEnumDevObjCallback,
03408
NULL
03409 );
03410 }
03411
03412 BOOLEAN
03413 IovpEnumDevObjCallback(
03414 IN PVOID Object,
03415 IN PUNICODE_STRING ObjectName,
03416 IN ULONG HandleCount,
03417 IN ULONG PointerCount,
03418 IN PVOID Context
03419 )
03420 {
03421
PDEVICE_OBJECT deviceObject;
03422
PDEVOBJ_EXTENSION deviceExtension;
03423
03424 deviceObject = (
PDEVICE_OBJECT) Object;
03425 deviceExtension = deviceObject->
DeviceObjectExtension;
03426
03427
if (PointerCount || HandleCount) {
03428
03429 deviceExtension->
ExtensionFlags &=~ (
DOE_EXAMINED |
DOE_TRACKED);
03430 }
03431
03432
return TRUE;
03433 }
03434
03435 BOOLEAN
03436 IovpIsInterestingStack(
03437 IN
PDEVICE_OBJECT DeviceObject
03438 )
03439 {
03440
PDEVOBJ_EXTENSION deviceExtension;
03441
PDEVICE_OBJECT currentDevObj, deviceAttachedTo;
03442 BOOLEAN stackIsInteresting;
03443 KIRQL irql;
03444
03445
03446
03447
03448 ExAcquireFastLock( &
IopDatabaseLock, &irql );
03449
03450
03451
03452
03453
if (DeviceObject->DeviceObjectExtension->ExtensionFlags &
DOE_EXAMINED) {
03454
03455 stackIsInteresting =
03456 ((DeviceObject->DeviceObjectExtension->ExtensionFlags &
DOE_TRACKED) != 0);
03457
03458 ExReleaseFastLock( &
IopDatabaseLock, irql );
03459
return stackIsInteresting;
03460 }
03461
03462
03463
03464
03465
03466
03467 stackIsInteresting =
FALSE;
03468 deviceAttachedTo = DeviceObject;
03469
do {
03470 currentDevObj = deviceAttachedTo;
03471 deviceExtension = currentDevObj->
DeviceObjectExtension;
03472 deviceAttachedTo = deviceExtension->
AttachedTo;
03473
03474
03475
03476
03477
if (
IovpIsInterestingDriver(currentDevObj->
DriverObject)) {
03478
03479 stackIsInteresting =
TRUE;
03480 }
03481
03482 }
while (deviceAttachedTo &&
03483 (deviceAttachedTo->
DeviceObjectExtension->
ExtensionFlags &
DOE_EXAMINED)
03484 );
03485
03486
if (deviceAttachedTo &&
03487 (deviceAttachedTo->
DeviceObjectExtension->
ExtensionFlags &
DOE_TRACKED)) {
03488
03489
03490
03491
03492
03493 stackIsInteresting =
TRUE;
03494 }
03495
03496
03497
03498
03499
do {
03500 deviceExtension = currentDevObj->
DeviceObjectExtension;
03501
03502
if (stackIsInteresting) {
03503
03504 deviceExtension->
ExtensionFlags |=
DOE_TRACKED;
03505 }
else {
03506
03507 deviceExtension->
ExtensionFlags &=~ DOE_TRACKED;
03508 }
03509
03510 deviceExtension->
ExtensionFlags |=
DOE_EXAMINED;
03511
03512 currentDevObj = currentDevObj->
AttachedDevice;
03513
03514 }
while (currentDevObj);
03515
03516 ExReleaseFastLock( &
IopDatabaseLock, irql );
03517
return stackIsInteresting;
03518 }
03519
03520 BOOLEAN
03521 IovpIsInterestingDriver(
03522 IN
PDRIVER_OBJECT DriverObject
03523 )
03524 {
03525
if (
IovpInitFlags&
IOVERIFIERINIT_VERIFIER_DRIVER_LIST) {
03526
03527
return (BOOLEAN)
MmIsDriverVerifying(DriverObject);
03528
03529 }
else {
03530
03531
return TRUE;
03532 }
03533 }
03534
03535
VOID
03536
FASTCALL
03537 IovpExamineDevObjForwarding(
03538 IN
PDEVICE_OBJECT DeviceBeingCalled,
03539 IN
PDEVICE_OBJECT DeviceLastCalled,
03540 OUT PULONG ForwardTechnique
03541 )
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555 {
03556
PDEVICE_OBJECT upperDevobj, lowerObject ;
03557 ULONG result ;
03558 KIRQL irql;
03559
03560 lowerObject =
IovpGetDeviceAttachedTo(DeviceLastCalled) ;
03561
03562 ExAcquireFastLock( &
IopDatabaseLock, &irql );
03563
03564
03565
03566
03567
03568
03569 upperDevobj = DeviceBeingCalled->
AttachedDevice ;
03570
while(upperDevobj && (upperDevobj != DeviceLastCalled)) {
03571
03572 upperDevobj = upperDevobj->
AttachedDevice ;
03573 }
03574
03575
if (DeviceLastCalled ==
NULL) {
03576
03577
03578
03579
03580
03581 result = (DeviceBeingCalled->AttachedDevice) ?
STARTED_INSIDE_STACK :
03582
STARTED_TOP_OF_STACK ;
03583
03584 }
else if (upperDevobj ==
NULL) {
03585
03586
03587
03588
03589 result = (lowerObject) ?
CHANGED_STACKS_MID_STACK :
03590
CHANGED_STACKS_AT_BOTTOM ;
03591
03592 }
else if (DeviceBeingCalled->AttachedDevice == upperDevobj) {
03593
03594 result =
FORWARDED_TO_NEXT_DO ;
03595
03596
03597
03598
03599
03600
ASSERT(lowerObject == DeviceBeingCalled) ;
03601
03602 }
else {
03603
03604
03605
03606
03607
03608 result =
SKIPPED_A_DO ;
03609 }
03610
03611 ExReleaseFastLock( &
IopDatabaseLock, irql );
03612
if (lowerObject) {
03613
ObDereferenceObject(lowerObject) ;
03614 }
03615 *ForwardTechnique = result ;
03616 }
03617
03618
PDEVICE_OBJECT
03619
FASTCALL
03620 IovpGetDeviceAttachedTo(
03621 IN
PDEVICE_OBJECT DeviceObject
03622 )
03623 {
03624
PDEVOBJ_EXTENSION deviceExtension;
03625
PDEVICE_OBJECT deviceAttachedTo ;
03626 KIRQL irql ;
03627
03628
if (DeviceObject ==
NULL) {
03629
03630
return NULL ;
03631 }
03632
03633 ExAcquireFastLock( &
IopDatabaseLock, &irql );
03634
03635 deviceExtension = DeviceObject->DeviceObjectExtension;
03636 deviceAttachedTo = deviceExtension->
AttachedTo ;
03637
03638
if (deviceAttachedTo) {
03639
ObReferenceObject(deviceAttachedTo) ;
03640 }
03641
03642 ExReleaseFastLock( &
IopDatabaseLock, irql );
03643
return deviceAttachedTo ;
03644 }
03645
03646
PDEVICE_OBJECT
03647
FASTCALL
03648 IovpGetLowestDevice(
03649 IN
PDEVICE_OBJECT DeviceObject
03650 )
03651
03652
03653
03654
03655
03656 {
03657
PDEVOBJ_EXTENSION deviceExtension;
03658
PDEVICE_OBJECT lowerDevobj, deviceAttachedTo ;
03659 KIRQL irql ;
03660
03661 deviceAttachedTo = DeviceObject ;
03662
03663 ExAcquireFastLock( &
IopDatabaseLock, &irql );
03664
03665
do {
03666 lowerDevobj = deviceAttachedTo ;
03667 deviceExtension = lowerDevobj->
DeviceObjectExtension;
03668 deviceAttachedTo = deviceExtension->
AttachedTo ;
03669
03670 }
while ( deviceAttachedTo );
03671
03672
ObReferenceObject(lowerDevobj) ;
03673
03674 ExReleaseFastLock( &
IopDatabaseLock, irql );
03675
return lowerDevobj ;
03676 }
03677
03678
VOID
03679
FASTCALL
03680 IovpAssertNonLegacyDevice(
03681 IN
PDEVICE_OBJECT DeviceObject,
03682 IN ULONG StackFramesToSkip,
03683 IN PUCHAR FailureTxt
03684 )
03685
03686
03687
03688 {
03689
PDEVICE_OBJECT pdoDeviceObject ;
03690
PDEVICE_NODE pDevNode ;
03691
03692 pdoDeviceObject =
IovpGetLowestDevice(DeviceObject) ;
03693
03694
if (pdoDeviceObject) {
03695
03696 pDevNode = pdoDeviceObject->
DeviceObjectExtension->
DeviceNode ;
03697
if (pDevNode&&(!(pDevNode->
Flags&
DNF_LEGACY_DRIVER))) {
03698
03699
03700
03701
03702
ASSERT(0);
03703
03704
03705
03706
03707
03708
03709
03710 }
03711
ObDereferenceObject(pdoDeviceObject) ;
03712 }
03713 }
03714
03715 BOOLEAN
03716
FASTCALL
03717 IovpIsInFdoStack(
03718 IN
PDEVICE_OBJECT DeviceObject
03719 )
03720 {
03721
PDEVOBJ_EXTENSION deviceExtension;
03722
PDEVICE_OBJECT deviceAttachedTo, lowerDevobj ;
03723 KIRQL irql ;
03724
03725 deviceAttachedTo = DeviceObject ;
03726
03727 ExAcquireFastLock( &
IopDatabaseLock, &irql );
03728
03729
do {
03730
if (deviceAttachedTo->
DeviceObjectExtension->
ExtensionFlags&
DOE_BOTTOM_OF_FDO_STACK) {
03731
break;
03732 }
03733 deviceAttachedTo = deviceAttachedTo->
DeviceObjectExtension->
AttachedTo ;
03734
03735 }
while ( deviceAttachedTo );
03736
03737 ExReleaseFastLock( &
IopDatabaseLock, irql );
03738
return (deviceAttachedTo !=
NULL) ;
03739 }
03740
03741
VOID
03742
FASTCALL
03743 IovpSeedOnePage(
03744 VOID
03745 )
03746 {
03747 ULONG StackSeed[(
PAGE_SIZE/
sizeof(ULONG))] ;
03748 ULONG
register i ;
03749
03750
03751
03752
03753
03754
03755
for(i=0; i<(
PAGE_SIZE/
sizeof(ULONG)); i++) StackSeed[i]=0xFFFFFFFF ;
03756 }
03757
03758
VOID
03759
FASTCALL
03760 IovpSeedTwoPages(
03761 VOID
03762 )
03763 {
03764 ULONG StackSeed[(
PAGE_SIZE*2/
sizeof(ULONG))] ;
03765 ULONG
register i ;
03766
03767
for(i=0; i<(
PAGE_SIZE*2/
sizeof(ULONG)); i++) StackSeed[i]=0xFFFFFFFF ;
03768 }
03769
03770
VOID
03771
FASTCALL
03772 IovpSeedThreePages(
03773 VOID
03774 )
03775 {
03776 ULONG
register i ;
03777 ULONG StackSeed[(
PAGE_SIZE*3/
sizeof(ULONG))] ;
03778
03779
for(i=0; i<(
PAGE_SIZE*3/
sizeof(ULONG)); i++) StackSeed[i]=0xFFFFFFFF ;
03780 }
03781
03782
VOID
03783
FASTCALL
03784 IovpSeedStack(
03785 VOID
03786 )
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806 {
03807
int i, interruptReservedOverhead ;
03808
03809
if (!(
IovpTrackingFlags&
ASSERTFLAG_SEEDSTACK)) {
03810
return ;
03811 }
03812
03813
03814
03815
03816
03817 interruptReservedOverhead =
PAGE_SIZE/2 ;
03818
03819
03820
03821
03822
for(i=0; i<4; i++) {
03823
if (!
MmIsAddressValid(((PUCHAR)&i)-i*
PAGE_SIZE-interruptReservedOverhead)) {
03824
break;
03825 }
03826 }
03827
03828
switch(i) {
03829
case 4:
IovpSeedThreePages() ;
break ;
03830
case 3:
IovpSeedTwoPages() ;
break ;
03831
case 2:
IovpSeedOnePage() ;
break ;
03832
case 1:
break ;
03833
case 0:
break ;
03834
default:
break ;
03835 }
03836 }
03837
03838
#endif // NO_SPECIAL_IRP
03839
03840
03841