00001
#include "iop.h"
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
#if (( defined(_X86_) ) && ( FPO ))
00027
#pragma optimize( "y", off ) // disable FPO for consistent stack traces
00028
#endif
00029
00030
00031 #define IO_FREE_IRP_TYPE_INVALID 1
00032 #define IO_FREE_IRP_NOT_ASSOCIATED_WITH_THREAD 2
00033 #define IO_CALL_DRIVER_IRP_TYPE_INVALID 3
00034 #define IO_CALL_DRIVER_INVALID_DEVICE_OBJECT 4
00035 #define IO_CALL_DRIVER_IRQL_NOT_EQUAL 5
00036 #define IO_COMPLETE_REQUEST_INVALID_STATUS 6
00037 #define IO_COMPLETE_REQUEST_CANCEL_ROUTINE_SET 7
00038 #define IO_BUILD_FSD_REQUEST_EXCEPTION 8
00039 #define IO_BUILD_IOCTL_REQUEST_EXCEPTION 9
00040 #define IO_REINITIALIZING_TIMER_OBJECT 10
00041 #define IO_INVALID_HANDLE 11
00042 #define IO_INVALID_STACK_IOSB 12
00043 #define IO_INVALID_STACK_EVENT 13
00044 #define IO_COMPLETE_REQUEST_INVALID_IRQL 14
00045
00046
00047
00048
00049
00050 PVOID
00051
VerifierAllocatePoolWithQuotaTag(
00052 IN POOL_TYPE PoolType,
00053 IN SIZE_T NumberOfBytes,
00054 IN ULONG Tag
00055 );
00056
00057 #define IsKernelHandle(H,M) (((LONG_PTR)(H) < 0) && ((M) == KernelMode) && ((H) != NtCurrentThread()) && ((H) != NtCurrentProcess()))
00058
00059 BOOLEAN
00060
IovpValidateDeviceObject(
00061 IN
PDEVICE_OBJECT DeviceObject
00062 );
00063
VOID
00064
IovFreeIrpPrivate(
00065 IN
PIRP Irp
00066 );
00067
00068
#ifdef ALLOC_PRAGMA
00069
#pragma alloc_text(INIT, IoVerifierInit)
00070
#pragma alloc_text(PAGEVRFY,IovAllocateIrp)
00071
#pragma alloc_text(PAGEVRFY,IovFreeIrp)
00072
#pragma alloc_text(PAGEVRFY,IovCallDriver)
00073
#pragma alloc_text(PAGEVRFY,IovCompleteRequest)
00074
#pragma alloc_text(PAGEVRFY,IovCallDriver)
00075
#pragma alloc_text(PAGEVRFY,IovCompleteRequest)
00076
#pragma alloc_text(PAGEVRFY,IovpValidateDeviceObject)
00077
#pragma alloc_text(PAGEVRFY,IovSpecialIrpCallDriver)
00078
#pragma alloc_text(PAGEVRFY,IovSpecialIrpCompleteRequest)
00079
#pragma alloc_text(PAGEVRFY,IovFreeIrpPrivate)
00080
#endif
00081
00082 BOOLEAN
IopVerifierOn =
FALSE;
00083 ULONG
IovpEnforcementLevel = (ULONG) -1;
00084 ULONG
IovpVerifierLevel = (ULONG)0;
00085 BOOLEAN
IoVerifierOnByDefault =
TRUE;
00086 LONG
IovpInitCalled = 0;
00087 ULONG
IovpMaxSupportedVerifierLevel = 3;
00088 ULONG
IovpVerifierFlags = 0;
00089
00090
VOID
00091 IoVerifierInit(
00092 IN ULONG VerifierFlags,
00093 IN ULONG InitFlags
00094 )
00095 {
00096 PVOID sectionHeaderHandle;
00097 ULONG verifierLevel;
00098
00099
if (
IoVerifierOnByDefault) {
00100 VerifierFlags |= DRIVER_VERIFIER_IO_CHECKING;
00101 }
00102
00103
if (!VerifierFlags) {
00104
return;
00105 }
00106
pIoAllocateIrp =
IovAllocateIrp;
00107
00108
#ifndef NO_SPECIAL_IRP
00109
if (!(InitFlags &
IOVERIFIERINIT_PHASE0)) {
00110
00111
00112
00113
00114 sectionHeaderHandle = MmLockPagableCodeSection(
IopDriverCorrectnessTakeLock);
00115
00116
if (!sectionHeaderHandle) {
00117
00118
return;
00119 }
00120 }
00121
00122
00123
00124
00125
if (
IopDcControlOverride == (ULONG) -1) {
00126
00127
IopDcControlOverride = 0;
00128 }
00129
00130
if (
IopDcControlInitial == (ULONG) -1) {
00131
00132
IopDcControlInitial = 0;
00133
if (!(InitFlags &
IOVERIFIERINIT_VERIFIER_DRIVER_LIST)) {
00134
00135
IopDcControlInitial |=
DIAG_IGNORE_DRIVER_LIST;
00136 }
00137 }
00138
00139
KeInitializeSpinLock(&
IopDcControlLock) ;
00140
00141
#endif // NO_SPECIAL_IRP
00142
00143
if (!(VerifierFlags & DRIVER_VERIFIER_IO_CHECKING)) {
00144
00145
return;
00146 }
00147
00148
00149
00150
00151
00152
00153
#if !DBG
00154
if (
IovpVerifierLevel >
IovpMaxSupportedVerifierLevel) {
00155
IovpVerifierLevel =
IovpMaxSupportedVerifierLevel;
00156 }
00157
#endif
00158
00159 verifierLevel =
IovpVerifierLevel;
00160
00161
00162
00163
00164
IopVerifierOn =
TRUE;
00165
IovpInitCalled = 1;
00166
IovpVerifierFlags = VerifierFlags;
00167
00168
if (verifierLevel > 1) {
00169
00170
00171
00172
#ifndef NO_SPECIAL_IRP
00173
IovpInitIrpTracking(verifierLevel, InitFlags);
00174
#endif // NO_SPECIAL_IRP
00175
InterlockedExchangePointer((PVOID *)&
pIofCallDriver, (PVOID)
IovSpecialIrpCallDriver);
00176 InterlockedExchangePointer((PVOID *)&
pIofCompleteRequest, (PVOID)
IovSpecialIrpCompleteRequest);
00177 InterlockedExchangePointer((PVOID *)&
pIoFreeIrp, (PVOID)
IovFreeIrpPrivate);
00178 }
00179
ASSERT(KeGetCurrentIrql() <=
APC_LEVEL);
00180 }
00181
00182
00183 BOOLEAN
00184 IovpValidateDeviceObject(
00185 IN
PDEVICE_OBJECT DeviceObject
00186 )
00187 {
00188
if ((DeviceObject->Type !=
IO_TYPE_DEVICE) ||
00189 (DeviceObject->DriverObject ==
NULL) ||
00190 (DeviceObject->ReferenceCount < 0 )) {
00191
return FALSE;
00192 }
else {
00193
return TRUE;
00194 }
00195 }
00196
00197
VOID
00198 IovFreeIrp(
00199 IN
PIRP Irp
00200 )
00201 {
00202
IovFreeIrpPrivate(
Irp);
00203 }
00204
00205
VOID
00206 IovFreeIrpPrivate(
00207 IN
PIRP Irp
00208 )
00209 {
00210
00211
00212
#ifndef NO_SPECIAL_IRP
00213
BOOLEAN freeHandled ;
00214
#endif
00215
00216
00217
if (
IopVerifierOn) {
00218
if (
Irp->
Type !=
IO_TYPE_IRP) {
00219
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00220
IO_FREE_IRP_TYPE_INVALID,
00221 (ULONG_PTR)
Irp,
00222 0,
00223 0);
00224 }
00225
if (!IsListEmpty(&(
Irp)->ThreadListEntry)) {
00226
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00227
IO_FREE_IRP_NOT_ASSOCIATED_WITH_THREAD,
00228 (ULONG_PTR)
Irp,
00229 0,
00230 0);
00231 }
00232 }
00233
00234
#ifndef NO_SPECIAL_IRP
00235
SPECIALIRP_IO_FREE_IRP(
Irp, &freeHandled) ;
00236
00237
if (freeHandled) {
00238
00239
return ;
00240 }
00241
#endif
00242
00243
IopFreeIrp(
Irp);
00244 }
00245
00246
NTSTATUS
00247
FASTCALL
00248 IovCallDriver(
00249 IN
PDEVICE_OBJECT DeviceObject,
00250 IN OUT
PIRP Irp
00251 )
00252 {
00253 KIRQL saveIrql;
00254
NTSTATUS status;
00255
00256
00257
if (!
IopVerifierOn) {
00258 status =
IopfCallDriver(DeviceObject,
Irp);
00259
return status;
00260 }
00261
00262
if (
IovpVerifierLevel > 1) {
00263 status =
IovSpecialIrpCallDriver(DeviceObject,
Irp);
00264
return status;
00265 }
00266
if (
Irp->
Type !=
IO_TYPE_IRP) {
00267
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00268
IO_CALL_DRIVER_IRP_TYPE_INVALID,
00269 (ULONG_PTR)
Irp,
00270 0,
00271 0);
00272 }
00273
if (!
IovpValidateDeviceObject(DeviceObject)) {
00274
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00275
IO_CALL_DRIVER_INVALID_DEVICE_OBJECT,
00276 (ULONG_PTR)DeviceObject,
00277 0,
00278 0);
00279 }
00280
00281 saveIrql = KeGetCurrentIrql();
00282 status =
IopfCallDriver(DeviceObject,
Irp);
00283
if (saveIrql != KeGetCurrentIrql()) {
00284
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00285
IO_CALL_DRIVER_IRQL_NOT_EQUAL,
00286 (ULONG_PTR)DeviceObject,
00287 saveIrql,
00288 KeGetCurrentIrql());
00289
00290 }
00291
return status;
00292 }
00293
00294
00295
VOID
00296
FASTCALL
00297 IovCompleteRequest(
00298 IN
PIRP Irp,
00299 IN CCHAR PriorityBoost
00300 )
00301 {
00302
00303
if (!
IopVerifierOn) {
00304
IopfCompleteRequest(
Irp,
PriorityBoost);
00305
return;
00306 }
00307
00308
if (
IovpVerifierLevel > 1) {
00309
IovSpecialIrpCompleteRequest(
Irp,
PriorityBoost);
00310
return;
00311 }
00312
00313
if (
Irp->
CurrentLocation > (CCHAR) (
Irp->
StackCount + 1) ||
00314
Irp->
Type !=
IO_TYPE_IRP) {
00315
KeBugCheckEx( MULTIPLE_IRP_COMPLETE_REQUESTS,
00316 (ULONG_PTR)
Irp,
00317 __LINE__,
00318 0,
00319 0);
00320 }
00321
00322
if (
Irp->
CancelRoutine) {
00323
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00324
IO_COMPLETE_REQUEST_CANCEL_ROUTINE_SET,
00325 (ULONG_PTR)
Irp->
CancelRoutine,
00326 (ULONG_PTR)
Irp,
00327 0);
00328 }
00329
if (
Irp->
IoStatus.Status == STATUS_PENDING ||
Irp->
IoStatus.Status == 0xffffffff) {
00330
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00331
IO_COMPLETE_REQUEST_INVALID_STATUS,
00332
Irp->
IoStatus.Status,
00333 (ULONG_PTR)
Irp,
00334 0);
00335 }
00336
if (KeGetCurrentIrql() >
DISPATCH_LEVEL) {
00337
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00338
IO_COMPLETE_REQUEST_INVALID_IRQL,
00339 KeGetCurrentIrql(),
00340 (ULONG_PTR)
Irp,
00341 0);
00342
00343 }
00344
IopfCompleteRequest(
Irp,
PriorityBoost);
00345 }
00346
00347
00348
00349
00350
00351
00352
PIRP
00353 IovAllocateIrp(
00354 IN CCHAR StackSize,
00355 IN BOOLEAN ChargeQuota
00356 )
00357 {
00358
USHORT allocateSize;
00359 UCHAR fixedSize;
00360
PIRP irp;
00361 UCHAR mustSucceed;
00362
USHORT packetSize;
00363
00364
#ifndef NO_SPECIAL_IRP
00365
00366
00367
00368
00369
SPECIALIRP_IO_ALLOCATE_IRP_1(StackSize, ChargeQuota, &irp) ;
00370
00371
if (irp) {
00372
return irp ;
00373 }
00374
#endif
00375
00376
00377
00378
00379
00380
00381
if (!(
IovpVerifierFlags & DRIVER_VERIFIER_SPECIAL_POOLING )) {
00382 irp =
IopAllocateIrpPrivate(StackSize, ChargeQuota);
00383
return irp;
00384 }
00385
00386
00387 irp =
NULL;
00388 fixedSize = 0;
00389 mustSucceed = 0;
00390 packetSize =
IoSizeOfIrp(StackSize);
00391 allocateSize = packetSize;
00392
00393
00394
00395
00396
00397
00398
00399
00400
if (ChargeQuota) {
00401
try {
00402 irp =
ExAllocatePoolWithTagPriority(
00403
NonPagedPool,
00404 allocateSize,
00405 ' prI',
00406
HighPoolPrioritySpecialPoolOverrun);
00407 } except(
EXCEPTION_EXECUTE_HANDLER) {
00408 NOTHING;
00409 }
00410
00411 }
else {
00412
00413
00414
00415
00416
00417
00418
00419 irp =
ExAllocatePoolWithTagPriority(
00420
NonPagedPool,
00421 allocateSize,
00422 ' prI',
00423
HighPoolPrioritySpecialPoolOverrun);
00424
if (!irp) {
00425 mustSucceed =
IRP_ALLOCATED_MUST_SUCCEED;
00426
if (KeGetPreviousMode() ==
KernelMode ) {
00427 irp =
ExAllocatePoolWithTagPriority(
00428
NonPagedPoolMustSucceed,
00429 allocateSize,
00430 ' prI',
00431
HighPoolPrioritySpecialPoolOverrun);
00432 }
00433 }
00434 }
00435
00436
if (!irp) {
00437
return NULL;
00438 }
00439
00440
00441
00442
00443
00444
IopInitializeIrp(irp, packetSize, StackSize);
00445 irp->
AllocationFlags = mustSucceed;
00446
if (ChargeQuota) {
00447 irp->
AllocationFlags |=
IRP_QUOTA_CHARGED;
00448 }
00449
00450
SPECIALIRP_IO_ALLOCATE_IRP_2(irp) ;
00451
return irp;
00452 }
00453
00454
00455 PIRP
00456
IovBuildAsynchronousFsdRequest(
00457 IN ULONG MajorFunction,
00458 IN
PDEVICE_OBJECT DeviceObject,
00459 IN OUT PVOID Buffer OPTIONAL,
00460 IN ULONG Length OPTIONAL,
00461 IN PLARGE_INTEGER StartingOffset OPTIONAL,
00462 IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL
00463 )
00464 {
00465
PIRP Irp;
00466
00467
try {
00468
Irp =
IoBuildAsynchronousFsdRequest(
00469 MajorFunction,
00470 DeviceObject,
00471
Buffer,
00472 Length,
00473 StartingOffset,
00474 IoStatusBlock
00475 );
00476 } except(
EXCEPTION_EXECUTE_HANDLER) {
00477
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00478
IO_BUILD_FSD_REQUEST_EXCEPTION,
00479 (ULONG_PTR)DeviceObject,
00480 (ULONG_PTR)MajorFunction,
00481 GetExceptionCode());
00482 }
00483
return (
Irp);
00484 }
00485
00486 PIRP
00487
IovBuildDeviceIoControlRequest(
00488 IN ULONG IoControlCode,
00489 IN
PDEVICE_OBJECT DeviceObject,
00490 IN PVOID InputBuffer OPTIONAL,
00491 IN ULONG InputBufferLength,
00492 OUT PVOID OutputBuffer OPTIONAL,
00493 IN ULONG OutputBufferLength,
00494 IN BOOLEAN InternalDeviceIoControl,
00495 IN
PKEVENT Event,
00496 OUT PIO_STATUS_BLOCK IoStatusBlock
00497 )
00498 {
00499
PIRP Irp;
00500
00501
try {
00502
Irp =
IoBuildDeviceIoControlRequest(
00503 IoControlCode,
00504 DeviceObject,
00505 InputBuffer,
00506 InputBufferLength,
00507 OutputBuffer,
00508 OutputBufferLength,
00509 InternalDeviceIoControl,
00510
Event,
00511 IoStatusBlock
00512 );
00513 } except(
EXCEPTION_EXECUTE_HANDLER) {
00514
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00515
IO_BUILD_IOCTL_REQUEST_EXCEPTION,
00516 (ULONG_PTR)DeviceObject,
00517 (ULONG_PTR)IoControlCode,
00518 GetExceptionCode());
00519 }
00520
00521
return (
Irp);
00522 }
00523
00524 NTSTATUS
00525
IovInitializeTimer(
00526 IN
PDEVICE_OBJECT DeviceObject,
00527 IN PIO_TIMER_ROUTINE TimerRoutine,
00528 IN PVOID Context
00529 )
00530 {
00531
if (DeviceObject->Timer) {
00532
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00533
IO_REINITIALIZING_TIMER_OBJECT,
00534 (ULONG_PTR)DeviceObject,
00535 0,
00536 0);
00537 }
00538
return (
IoInitializeTimer(DeviceObject, TimerRoutine, Context));
00539 }
00540
00541
00542 VOID
00543
IovpCompleteRequest(
00544 IN
PKAPC Apc,
00545 IN PVOID *SystemArgument1,
00546 IN PVOID *SystemArgument2
00547 )
00548 {
00549
PIRP irp;
00550 PUCHAR addr;
00551 ULONG BestStackOffset;
00552
00553 irp = CONTAINING_RECORD( Apc,
IRP, Tail.Apc );
00554
00555
#if defined(_X86_)
00556
00557
00558 addr = (PUCHAR)irp->
UserIosb;
00559
if ((addr > (PUCHAR)
KeGetCurrentThread()->StackLimit) &&
00560 (addr <= (PUCHAR)&BestStackOffset)) {
00561
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00562
IO_INVALID_STACK_IOSB,
00563 (ULONG_PTR)addr,
00564 0,
00565 0);
00566
00567 }
00568
00569 addr = (PUCHAR)irp->
UserEvent;
00570
if ((addr > (PUCHAR)
KeGetCurrentThread()->StackLimit) &&
00571 (addr <= (PUCHAR)&BestStackOffset)) {
00572
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00573
IO_INVALID_STACK_EVENT,
00574 (ULONG_PTR)addr,
00575 0,
00576 0);
00577
00578 }
00579
#endif
00580
}
00581
00582
00583
00584
00585
VOID
00586 FASTCALL
00587
IovSpecialIrpCompleteRequest(
00588 IN
PIRP Irp,
00589 IN CCHAR PriorityBoost
00590 )
00591
00592
00593
00594
00595
00596
00597
00598
00599
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
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 #define
ZeroAndDopeIrpStackLocation( IrpSp ) { \
00656 (IrpSp)->MinorFunction = 0; \
00657 (IrpSp)->Flags = 0; \
00658 (IrpSp)->Control =
SL_NOTCOPIED; \
00659 (IrpSp)->Parameters.Others.Argument1 = 0; \
00660 (IrpSp)->Parameters.Others.Argument2 = 0; \
00661 (IrpSp)->Parameters.Others.Argument3 = 0; \
00662 (IrpSp)->Parameters.Others.Argument4 = 0; \
00663 (IrpSp)->FileObject = (
PFILE_OBJECT)
NULL; }
00664
00665 {
00666
PIRP masterIrp;
00667
NTSTATUS status;
00668
PIO_STACK_LOCATION stackPointer;
00669
PMDL mdl;
00670
PETHREAD thread;
00671
PFILE_OBJECT fileObject;
00672 KIRQL irql;
00673 PVOID saveAuxiliaryPointer =
NULL;
00674
00675
#ifndef NO_SPECIAL_IRP
00676
PVOID routine ;
00677
IOFCOMPLETEREQUEST_STACKDATA completionPacket;
00678
#endif
00679
00680
if (!
IopVerifierOn) {
00681
IopfCompleteRequest(Irp, PriorityBoost);
00682
return;
00683 }
00684
00685
#if DBG
00686
00687
if (
Irp->
CurrentLocation <= (CCHAR)
Irp->
StackCount) {
00688
00689 stackPointer =
IoGetCurrentIrpStackLocation(Irp);
00690
if (stackPointer->
MajorFunction ==
IRP_MJ_POWER) {
00691
PoPowerTrace(
00692 POWERTRACE_COMPLETE,
00693
IoGetCurrentIrpStackLocation(Irp)->DeviceObject,
00694 Irp,
00695
IoGetCurrentIrpStackLocation(Irp)
00696 );
00697 }
00698 }
00699
00700
#endif
00701
00702
SPECIALIRP_IOF_COMPLETE_1(Irp, PriorityBoost, &completionPacket);
00703
00704
00705
00706
00707
00708
00709
if (
Irp->
CurrentLocation > (CCHAR) (
Irp->
StackCount + 1) ||
00710
Irp->
Type !=
IO_TYPE_IRP) {
00711
KeBugCheckEx( MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR) Irp, __LINE__, 0, 0 );
00712 }
00713
00714
00715
00716
00717
00718
if (
Irp->
Type !=
IO_TYPE_IRP) {
00719
00720
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00721 IO_CALL_DRIVER_IRP_TYPE_INVALID,
00722 (ULONG_PTR)Irp,
00723 0,
00724 0);
00725 }
00726
00727
00728
00729
00730
00731
00732
if (
Irp->
CancelRoutine) {
00733
00734
ASSERT(
Irp->
CancelRoutine == NULL);
00735
00736
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00737 IO_COMPLETE_REQUEST_CANCEL_ROUTINE_SET,
00738 (ULONG_PTR)
Irp->
CancelRoutine,
00739 (ULONG_PTR)Irp,
00740 0);
00741 }
00742
00743
00744
00745
00746
00747
00748
00749
if (
Irp->
IoStatus.Status == STATUS_PENDING) {
00750
00751
00752
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00753 IO_COMPLETE_REQUEST_INVALID_STATUS,
00754
Irp->
IoStatus.Status,
00755 (ULONG_PTR)Irp,
00756 0);
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
if (
Irp->
IoStatus.Status == 0xffffffff) {
00766
00767
00768
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
00769 IO_COMPLETE_REQUEST_INVALID_STATUS,
00770
Irp->
IoStatus.Status,
00771 (ULONG_PTR)Irp,
00772 0);
00773 }
00774
00775
00776
00777
00778
00779
00780
ASSERT( !(
Irp->
Flags & IRP_PAGING_IO &&
Irp->
IoStatus.Status == STATUS_QUOTA_EXCEEDED ) );
00781
00782
#ifndef NO_SPECIAL_IRP
00783
00784
if (!
IovpTrackingFlags) {
00785
00786
IopfCompleteRequest(Irp, PriorityBoost);
00787
return;
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
for (stackPointer =
IoGetCurrentIrpStackLocation( Irp ),
00800
Irp->
CurrentLocation++,
00801
Irp->
Tail.Overlay.CurrentStackLocation++;
00802
Irp->
CurrentLocation <= (CCHAR) (
Irp->
StackCount + 1);
00803 stackPointer++,
00804
Irp->
CurrentLocation++,
00805
Irp->
Tail.Overlay.CurrentStackLocation++) {
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
Irp->
PendingReturned = stackPointer->
Control &
SL_PENDING_RETURNED;
00817
00818
SPECIALIRP_IOF_COMPLETE_2(Irp, &completionPacket);
00819
00820
if ( (
NT_SUCCESS(
Irp->
IoStatus.Status ) &&
00821 stackPointer->
Control &
SL_INVOKE_ON_SUCCESS) ||
00822 (!
NT_SUCCESS(
Irp->
IoStatus.Status ) &&
00823 stackPointer->
Control &
SL_INVOKE_ON_ERROR) ||
00824 (
Irp->
Cancel &&
00825 stackPointer->
Control &
SL_INVOKE_ON_CANCEL)
00826 ) {
00827
00828
00829
00830
00831
00832
00833
00834
ZeroAndDopeIrpStackLocation( stackPointer );
00835
00836
#ifndef NO_SPECIAL_IRP
00837
routine = stackPointer->
CompletionRoutine ;
00838
SPECIALIRP_IOF_COMPLETE_3(Irp, routine, &completionPacket);
00839
#endif
00840
00841
PERFINFO_DRIVER_COMPLETIONROUTINE_CALL(Irp, stackPointer);
00842
00843 status = stackPointer->
CompletionRoutine( (
PDEVICE_OBJECT) (
Irp->
CurrentLocation == (CCHAR) (
Irp->
StackCount + 1) ?
00844 (
PDEVICE_OBJECT) NULL :
00845
IoGetCurrentIrpStackLocation( Irp )->DeviceObject),
00846 Irp,
00847 stackPointer->
Context );
00848
00849
PERFINFO_DRIVER_COMPLETIONROUTINE_RETURN(Irp, stackPointer);
00850
00851
SPECIALIRP_IOF_COMPLETE_4(Irp, status, &completionPacket);
00852
00853
if (status == STATUS_MORE_PROCESSING_REQUIRED) {
00854
00855
00856
00857
00858
00859
00860
00861
00862
SPECIALIRP_IOF_COMPLETE_5(Irp, &completionPacket);
00863
return;
00864 }
00865
00866 }
else {
00867
if (
Irp->
PendingReturned &&
Irp->
CurrentLocation <=
Irp->
StackCount) {
00868
IoMarkIrpPending( Irp );
00869 }
00870
ZeroAndDopeIrpStackLocation( stackPointer );
00871 }
00872
00873
SPECIALIRP_IOF_COMPLETE_5(Irp, &completionPacket);
00874 }
00875
00876
00877
00878
00879
00880
00881
00882
if (
Irp->
Flags &
IRP_ASSOCIATED_IRP) {
00883 ULONG count;
00884 masterIrp =
Irp->
AssociatedIrp.MasterIrp;
00885 count =
ExInterlockedAddUlong( (PULONG) &masterIrp->
AssociatedIrp.IrpCount,
00886 0xffffffff,
00887 &IopDatabaseLock );
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
Irp->
Tail.Overlay.Thread = masterIrp->
Tail.Overlay.Thread;
00901
IopFreeIrpAndMdls( Irp );
00902
if (count == 1) {
00903
IoCompleteRequest( masterIrp, PriorityBoost );
00904 }
00905
return;
00906 }
00907
00908
00909
00910
00911
00912
00913
if ((
Irp->
IoStatus.Status == STATUS_REPARSE ) &&
00914 (
Irp->
IoStatus.Information > IO_REPARSE_TAG_RESERVED_RANGE)) {
00915
00916
if (
Irp->
IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT) {
00917
00918
00919
00920
00921
00922
00923
ASSERT(
Irp->
Tail.Overlay.AuxiliaryBuffer != NULL );
00924
00925 saveAuxiliaryPointer = (PVOID)
Irp->
Tail.Overlay.AuxiliaryBuffer;
00926
00927
00928
00929
00930
00931
00932
Irp->
Tail.Overlay.AuxiliaryBuffer =
NULL;
00933 }
else {
00934
00935
00936
00937
00938
00939
00940
Irp->
IoStatus.Status = STATUS_IO_REPARSE_TAG_NOT_HANDLED;
00941 }
00942 }
00943
00944
00945
00946
00947
00948
00949
00950
00951
if (
Irp->
Tail.Overlay.AuxiliaryBuffer) {
00952
ExFreePool(
Irp->
Tail.Overlay.AuxiliaryBuffer );
00953
Irp->
Tail.Overlay.AuxiliaryBuffer =
NULL;
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
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
if (
Irp->
Flags & (
IRP_PAGING_IO |
IRP_CLOSE_OPERATION)) {
01000
if (
Irp->
Flags & (
IRP_SYNCHRONOUS_PAGING_IO |
IRP_CLOSE_OPERATION)) {
01001 ULONG flags;
01002
01003 flags =
Irp->
Flags &
IRP_SYNCHRONOUS_PAGING_IO;
01004 *
Irp->
UserIosb =
Irp->
IoStatus;
01005 (
VOID)
KeSetEvent(
Irp->
UserEvent, PriorityBoost, FALSE );
01006
if (flags) {
01007
IoFreeIrp( Irp );
01008 }
01009 }
else {
01010 thread =
Irp->
Tail.Overlay.Thread;
01011
KeInitializeApc( &
Irp->
Tail.Apc,
01012 &thread->
Tcb,
01013
Irp->
ApcEnvironment,
01014 IopCompletePageWrite,
01015 (PKRUNDOWN_ROUTINE) NULL,
01016 (PKNORMAL_ROUTINE) NULL,
01017 KernelMode,
01018 (PVOID) NULL );
01019 (
VOID)
KeInsertQueueApc( &
Irp->
Tail.Apc,
01020 (PVOID) NULL,
01021 (PVOID) NULL,
01022 PriorityBoost );
01023 }
01024
return;
01025 }
01026
01027
01028
01029
01030
01031
if (
Irp->
MdlAddress !=
NULL) {
01032
01033
01034
01035
01036
01037 mdl =
Irp->
MdlAddress;
01038
while (mdl !=
NULL) {
01039
MmUnlockPages( mdl );
01040 mdl = mdl->
Next;
01041 }
01042 }
01043
01044
01045
01046
01047
01048
01049
01050
01051
if (
Irp->
Flags &
IRP_DEFER_IO_COMPLETION && !
Irp->
PendingReturned) {
01052
01053
if ((
Irp->
IoStatus.Status == STATUS_REPARSE ) &&
01054 (
Irp->
IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)) {
01055
01056
01057
01058
01059
01060
01061
Irp->
Tail.Overlay.AuxiliaryBuffer = saveAuxiliaryPointer;
01062 }
01063
01064
return;
01065 }
01066
01067
01068
01069
01070
01071
01072 thread =
Irp->
Tail.Overlay.Thread;
01073 fileObject =
Irp->
Tail.Overlay.OriginalFileObject;
01074
01075
if (!
Irp->
Cancel) {
01076
01077
KeInitializeApc( &
Irp->
Tail.Apc,
01078 &thread->
Tcb,
01079
Irp->
ApcEnvironment,
01080 IopCompleteRequest,
01081 IopAbortRequest,
01082 (PKNORMAL_ROUTINE) NULL,
01083 KernelMode,
01084 (PVOID) NULL );
01085
01086 (
VOID)
KeInsertQueueApc( &
Irp->
Tail.Apc,
01087 fileObject,
01088 (PVOID) saveAuxiliaryPointer,
01089 PriorityBoost );
01090 }
else {
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106 ExAcquireSpinLock( &IopCompletionLock, &irql );
01107
01108 thread =
Irp->
Tail.Overlay.Thread;
01109
01110
if (thread) {
01111
01112
KeInitializeApc( &
Irp->
Tail.Apc,
01113 &thread->
Tcb,
01114
Irp->
ApcEnvironment,
01115 IopCompleteRequest,
01116 IopAbortRequest,
01117 (PKNORMAL_ROUTINE) NULL,
01118 KernelMode,
01119 (PVOID) NULL );
01120
01121 (
VOID)
KeInsertQueueApc( &
Irp->
Tail.Apc,
01122 fileObject,
01123 (PVOID) saveAuxiliaryPointer,
01124 PriorityBoost );
01125
01126 ExReleaseSpinLock( &IopCompletionLock, irql );
01127
01128 }
else {
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138 ExReleaseSpinLock( &IopCompletionLock, irql );
01139
01140
ASSERT(
Irp->
Cancel );
01141
01142
01143
01144
01145
01146
IopDropIrp( Irp, fileObject );
01147
01148 }
01149 }
01150
#else
01151
01152
IopfCompleteRequest(Irp, PriorityBoost);
01153
return;
01154
01155
#endif
01156
}
01157
01158
NTSTATUS
01159 FASTCALL
01160
IovSpecialIrpCallDriver(
01161 IN
PDEVICE_OBJECT DeviceObject,
01162 IN OUT
PIRP Irp
01163 )
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184 {
01185
PIO_STACK_LOCATION irpSp;
01186
PDRIVER_OBJECT driverObject;
01187
NTSTATUS status;
01188 KIRQL saveIrql;
01189
PDRIVER_DISPATCH dispatchRoutine;
01190
IOFCALLDRIVER_STACKDATA iofCallDriverStackData ;
01191
01192
if (!
IopVerifierOn) {
01193 status =
IopfCallDriver(DeviceObject,
Irp);
01194
return status;
01195 }
01196
01197
01198
01199
01200
01201
if (
Irp->
Type !=
IO_TYPE_IRP) {
01202
01203
ASSERT(
Irp->
Type ==
IO_TYPE_IRP);
01204
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
01205
IO_CALL_DRIVER_IRP_TYPE_INVALID,
01206 (ULONG_PTR)
Irp,
01207 0,
01208 0);
01209 }
01210
01211
if (!
IovpValidateDeviceObject(DeviceObject)) {
01212
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
01213
IO_CALL_DRIVER_INVALID_DEVICE_OBJECT,
01214 (ULONG_PTR)DeviceObject,
01215 0,
01216 0);
01217 }
01218
01219
SPECIALIRP_IOF_CALL_1(&
Irp, DeviceObject, &iofCallDriverStackData) ;
01220
01221
01222
01223
01224
Irp->
CurrentLocation--;
01225
01226
if (
Irp->
CurrentLocation <= 0) {
01227
KeBugCheckEx( NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR)
Irp, 0, 0, 0 );
01228 }
01229
01230 irpSp =
IoGetNextIrpStackLocation(
Irp );
01231
Irp->
Tail.Overlay.CurrentStackLocation = irpSp;
01232
01233
01234
01235
01236
01237
01238 irpSp->
DeviceObject = DeviceObject;
01239
01240
01241
01242
01243
01244 driverObject = DeviceObject->DriverObject;
01245
01246 dispatchRoutine = driverObject->
MajorFunction[irpSp->
MajorFunction] ;
01247
01248 saveIrql = KeGetCurrentIrql();
01249
01250
PERFINFO_DRIVER_MAJORFUNCTION_CALL(
Irp, irpSp, driverObject);
01251
01252 status = dispatchRoutine( DeviceObject,
Irp );
01253
01254
PERFINFO_DRIVER_MAJORFUNCTION_RETURN(
Irp, irpSp, driverObject);
01255
01256
if (saveIrql != KeGetCurrentIrql()) {
01257
01258
DbgPrint(
"IO: IoCallDriver( Driver object: %p Device object: %p Irp: %p )\n",
01259 driverObject,
01260 DeviceObject,
01261
Irp
01262 );
01263
DbgPrint(
" Irql before: %x != After: %x\n", saveIrql, KeGetCurrentIrql() );
01264
01265
ASSERT(saveIrql == KeGetCurrentIrql());
01266
01267
KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION,
01268
IO_CALL_DRIVER_IRQL_NOT_EQUAL,
01269 saveIrql,
01270 KeGetCurrentIrql(),
01271 0);
01272 }
01273
01274
SPECIALIRP_IOF_CALL_2(
Irp, DeviceObject, dispatchRoutine, &status, &iofCallDriverStackData) ;
01275
01276
return status;
01277 }
01278
01279 VOID
01280
IovInitializeIrp(
01281
PIRP Irp,
01282 USHORT PacketSize,
01283 CCHAR StackSize
01284 )
01285 {
01286 BOOLEAN initializeHandled ;
01287
01288
if (
IovpVerifierLevel < 2) {
01289
return;
01290 }
01291
01292
SPECIALIRP_IO_INITIALIZE_IRP(
Irp, PacketSize, StackSize, &initializeHandled) ;
01293
01294 }
01295
01296 VOID
01297
IovAttachDeviceToDeviceStack(
01298
PDEVICE_OBJECT SourceDevice,
01299
PDEVICE_OBJECT TargetDevice
01300 )
01301 {
01302
if (
IovpVerifierLevel < 2) {
01303
return;
01304 }
01305
01306
SPECIALIRP_IO_ATTACH_DEVICE_TO_DEVICE_STACK(SourceDevice, TargetDevice);
01307 }
01308
01309 VOID
01310
IovDeleteDevice(
01311
PDEVICE_OBJECT DeleteDevice
01312 )
01313 {
01314
if (
IovpVerifierLevel < 2) {
01315
return;
01316 }
01317
01318
SPECIALIRP_IO_DELETE_DEVICE(DeleteDevice);
01319 }
01320
01321 VOID
01322
IovDetachDevice(
01323
PDEVICE_OBJECT TargetDevice
01324 )
01325 {
01326
if (
IovpVerifierLevel < 2) {
01327
return;
01328 }
01329
SPECIALIRP_IO_DETACH_DEVICE(TargetDevice);
01330 }
01331
01332 BOOLEAN
01333
IovCancelIrp(
01334
PIRP Irp,
01335 BOOLEAN *returnValue
01336 )
01337 {
01338
#ifndef NO_SPECIAL_IRP
01339
BOOLEAN cancelHandled ;
01340
01341
SPECIALIRP_IO_CANCEL_IRP(
Irp, &cancelHandled, returnValue) ;
01342
01343
if (cancelHandled) {
01344
01345
return TRUE ;
01346 }
01347
#endif
01348
return FALSE;
01349 }