00001
#include "iop.h"
00002
#include "srb.h"
00003
00004
00005
00006
00007
#ifndef NO_SPECIAL_IRP
00008
00009
00010
00011
00012
#ifdef ALLOC_PRAGMA
00013
#pragma alloc_text(PAGEVRFY, IovpSessionDataCreate)
00014
#pragma alloc_text(PAGEVRFY, IovpSessionDataAdvance)
00015
#pragma alloc_text(PAGEVRFY, IovpSessionDataReference)
00016
#pragma alloc_text(PAGEVRFY, IovpSessionDataDereference)
00017
#pragma alloc_text(PAGEVRFY, IovpSessionDataClose)
00018
#pragma alloc_text(PAGEVRFY, IovpSessionDataDeterminePolicy)
00019
#pragma alloc_text(PAGEVRFY, IovpSessionDataAttachSurrogate)
00020
#pragma alloc_text(PAGEVRFY, IovpSessionDataFinalizeSurrogate)
00021
#endif
00022
00023 #define POOL_TAG_SESSION_DATA 'sprI'
00024
00025
PIOV_SESSION_DATA
00026
FASTCALL
00027 IovpSessionDataCreate(
00028 IN
PDEVICE_OBJECT DeviceObject,
00029 IN OUT
PIOV_REQUEST_PACKET *IovPacketPointer,
00030 OUT PBOOLEAN SurrogateSpawned
00031 )
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 {
00049
PIRP irp, surrogateIrp;
00050
PIOV_SESSION_DATA iovSessionData;
00051
PIOV_REQUEST_PACKET headPacket;
00052 ULONG sessionDataSize;
00053 BOOLEAN trackable, useSurrogateIrp;
00054
00055 *SurrogateSpawned =
FALSE;
00056
00057 headPacket = (*IovPacketPointer)->
HeadPacket;
00058
ASSERT(headPacket == (*IovPacketPointer));
00059 irp = headPacket->
TrackedIrp;
00060
00061
00062
00063
00064
IovpSessionDataDeterminePolicy(
00065 headPacket,
00066 DeviceObject,
00067 &trackable,
00068 &useSurrogateIrp
00069 );
00070
00071
if (!trackable) {
00072
00073
return NULL;
00074 }
00075
00076
00077
00078
00079
00080 sessionDataSize =
00081
sizeof(
IOV_SESSION_DATA)+
00082 irp->
StackCount*
sizeof(
IOV_STACK_LOCATION);
00083
00084 iovSessionData =
ExAllocatePoolWithTag(
00085
NonPagedPool,
00086 sessionDataSize,
00087
POOL_TAG_SESSION_DATA
00088 );
00089
00090
if (iovSessionData ==
NULL) {
00091
00092
return NULL;
00093 }
00094
00095 RtlZeroMemory(iovSessionData, sessionDataSize);
00096
00097 iovSessionData->
AssertFlags =
IovpTrackingFlags;
00098 iovSessionData->
IovRequestPacket = headPacket;
00099 InsertHeadList(&headPacket->
SessionHead, &iovSessionData->
SessionLink);
00100
00101
if ((iovSessionData->
AssertFlags&
ASSERTFLAG_COMPLETEATPASSIVE) ||
00102 (iovSessionData->
AssertFlags&
ASSERTFLAG_DEFERCOMPLETION)) {
00103
00104 iovSessionData->
AssertFlags |=
ASSERTFLAG_FORCEPENDING;
00105 }
00106
00107 headPacket->
pIovSessionData = iovSessionData;
00108 headPacket->
TopStackLocation = irp->
CurrentLocation;
00109 headPacket->
Flags |=
TRACKFLAG_ACTIVE;
00110 headPacket->
Flags &=~ (
00111
TRACKFLAG_QUEUED_INTERNALLY|
00112
TRACKFLAG_RELEASED|
00113
TRACKFLAG_SRB_MUNGED|
00114
TRACKFLAG_SWAPPED_BACK|
00115
TRACKFLAG_PASSED_FAILURE
00116 );
00117
00118 iovSessionData->
BestVisibleIrp = irp;
00119
if (useSurrogateIrp) {
00120
00121
00122
00123
00124 *SurrogateSpawned =
IovpSessionDataAttachSurrogate(
00125 IovPacketPointer,
00126 iovSessionData
00127 );
00128 }
00129
00130
TRACKIRP_DBGPRINT((
00131
" SSN CREATE(%x)->%x\n",
00132 headPacket,
00133 iovSessionData
00134 ), 3) ;
00135
return iovSessionData;
00136 }
00137
00138
VOID
00139
FASTCALL
00140 IovpSessionDataAdvance(
00141 IN
PDEVICE_OBJECT DeviceObject,
00142 IN
PIOV_SESSION_DATA IovSessionData,
00143 IN OUT
PIOV_REQUEST_PACKET *IovPacketPointer,
00144 OUT PBOOLEAN SurrogateSpawned
00145 )
00146 {
00147 *SurrogateSpawned =
FALSE;
00148 }
00149
00150
VOID
00151
FASTCALL
00152 IovpSessionDataDereference(
00153 IN
PIOV_SESSION_DATA IovSessionData
00154 )
00155 {
00156
PIOV_REQUEST_PACKET iovPacket, headPacket;
00157
00158 iovPacket = IovSessionData->IovRequestPacket;
00159 headPacket = iovPacket->
HeadPacket;
00160
00161
ASSERT_SPINLOCK_HELD(&headPacket->
IrpLock);
00162
ASSERT_SPINLOCK_HELD(&iovPacket->
IrpLock);
00163
ASSERT(IovSessionData->SessionRefCount > 0);
00164
ASSERT(headPacket->
ReferenceCount > 0);
00165
ASSERT(iovPacket->
ReferenceCount >= 0);
00166
00167
TRACKIRP_DBGPRINT((
00168
" SSN DEREF(%x) %x--\n",
00169 IovSessionData,
00170 IovSessionData->SessionRefCount
00171 ), 3) ;
00172
00173 IovSessionData->SessionRefCount--;
00174
if (!IovSessionData->SessionRefCount) {
00175
00176
ASSERT(headPacket->
pIovSessionData != IovSessionData);
00177
ASSERT(iovPacket->
ReferenceCount > iovPacket->
PointerCount);
00178
00179 RemoveEntryList(&IovSessionData->SessionLink);
00180 InitializeListHead(&IovSessionData->SessionLink);
00181
00182
IovpTrackingDataDereference(iovPacket,
IOVREFTYPE_PACKET);
00183
00184
ExFreePool(IovSessionData);
00185 }
00186 }
00187
00188
VOID
00189
FASTCALL
00190 IovpSessionDataReference(
00191 IN
PIOV_SESSION_DATA IovSessionData
00192 )
00193 {
00194
PIOV_REQUEST_PACKET iovPacket, headPacket;
00195
00196 iovPacket = IovSessionData->IovRequestPacket;
00197 headPacket = iovPacket->
HeadPacket;
00198
00199
ASSERT_SPINLOCK_HELD(&headPacket->
IrpLock);
00200
ASSERT_SPINLOCK_HELD(&iovPacket->
IrpLock);
00201
ASSERT(IovSessionData->SessionRefCount >= 0);
00202
ASSERT(headPacket->
ReferenceCount >= 0);
00203
ASSERT(iovPacket->
ReferenceCount >= 0);
00204
00205
TRACKIRP_DBGPRINT((
00206
" SSN REF(%x) %x++\n",
00207 IovSessionData,
00208 IovSessionData->SessionRefCount
00209 ), 3) ;
00210
00211
if (!IovSessionData->SessionRefCount) {
00212
00213
IovpTrackingDataReference(iovPacket,
IOVREFTYPE_PACKET);
00214 }
00215 IovSessionData->SessionRefCount++;
00216 }
00217
00218
VOID
00219
FASTCALL
00220 IovpSessionDataClose(
00221 IN
PIOV_SESSION_DATA IovSessionData
00222 )
00223 {
00224
PIOV_REQUEST_PACKET iovPacket = IovSessionData->IovRequestPacket;
00225
00226
ASSERT_SPINLOCK_HELD(&iovPacket->
IrpLock);
00227
00228
ASSERT(iovPacket == iovPacket->
HeadPacket);
00229
ASSERT(iovPacket->
pIovSessionData == IovSessionData);
00230
00231
TRACKIRP_DBGPRINT((
00232
" SSN CLOSE(%x)\n"
00233 ), 3) ;
00234
00235 iovPacket->
Flags &=~ TRACKFLAG_ACTIVE;
00236 iovPacket->
pIovSessionData =
NULL;
00237 }
00238
00239
VOID
00240 IovpSessionDataDeterminePolicy(
00241 IN
PIOV_REQUEST_PACKET IovRequestPacket,
00242 IN
PDEVICE_OBJECT DeviceObject,
00243 OUT PBOOLEAN Trackable,
00244 OUT PBOOLEAN UseSurrogateIrp
00245 )
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 {
00263
PIO_STACK_LOCATION irpSp;
00264
PIRP irp;
00265
00266 irp = IovRequestPacket->TrackedIrp;
00267
00268
if (!(
IovpTrackingFlags&
ASSERTFLAG_TRACKIRPS)) {
00269
00270
00271
00272
00273 *Trackable =
FALSE;
00274
return;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 *Trackable =
IovpIsInterestingStack(DeviceObject);
00286
00287 irpSp =
IoGetNextIrpStackLocation( irp );
00288
00289
if (
IovpTrackingFlags&
ASSERTFLAG_POLICEIRPS) {
00290
00291 *UseSurrogateIrp = ((
IovpTrackingFlags&
ASSERTFLAG_SURROGATE)!=0) ;
00292 *UseSurrogateIrp &= ((irpSp->
MajorFunction !=
IRP_MJ_SCSI) ||
00293 ((
IovpTrackingFlags&
ASSERTFLAG_SMASH_SRBS)!=0)) ;
00294
00295
#ifdef HACKHACKS_ENABLED
00296
00297
00298
00299
00300
00301
00302
if (
IovpHackFlags&
HACKFLAG_FOR_MUP) {
00303 *UseSurrogateIrp &= (irpSp->
MajorFunction !=
IRP_MJ_CREATE) ;
00304 }
00305
#endif
00306
}
else {
00307
00308 *UseSurrogateIrp =
FALSE;
00309 }
00310 }
00311
00312 BOOLEAN
00313
FASTCALL
00314 IovpSessionDataAttachSurrogate(
00315 IN OUT
PIOV_REQUEST_PACKET *IovPacketPointer,
00316 IN
PIOV_SESSION_DATA IovSessionData
00317 )
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 {
00339
00340
PIOV_REQUEST_PACKET iovSurrogatePacket, iovPacket, headPacket;
00341
PIRP surrogateIrp, irp;
00342
PIO_STACK_LOCATION irpSp;
00343 PSCSI_REQUEST_BLOCK srb;
00344 PVOID restoreHandle;
00345 CCHAR activeSize;
00346
00347 iovPacket = *IovPacketPointer;
00348
ASSERT_SPINLOCK_HELD(&iovPacket->
IrpLock);
00349
ASSERT(!(CONTAINING_RECORD(
00350 iovPacket->
SurrogateLink.Flink,
00351
IOV_REQUEST_PACKET,
00352 SurrogateLink)->Flags&
TRACKFLAG_SURROGATE
00353 ));
00354
00355
ASSERT(iovPacket->
Flags &
TRACKFLAG_ACTIVE);
00356
00357 irp = iovPacket->
TrackedIrp;
00358 activeSize = (irp->
CurrentLocation-1);
00359
ASSERT(activeSize);
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 surrogateIrp =
IovpProtectedIrpAllocate(
00374 irp->
StackCount,
00375 (BOOLEAN) ((irp->
AllocationFlags&
IRP_QUOTA_CHARGED) ?
TRUE :
FALSE),
00376
NULL
00377 );
00378
00379
if (surrogateIrp ==
NULL) {
00380
00381
return FALSE;
00382 }
00383
00384
00385
00386
00387
00388 RtlCopyMemory(surrogateIrp, irp,
sizeof(
IRP));
00389
00390
00391
00392
00393 surrogateIrp->
StackCount = irp->
StackCount;
00394 surrogateIrp->
Tail.Overlay.CurrentStackLocation =
00395 ((
PIO_STACK_LOCATION) (surrogateIrp+1))+activeSize;
00396
00397
00398
00399
00400
00401
00402 InitializeListHead(&surrogateIrp->
ThreadListEntry);
00403
00404
00405
00406
00407 surrogateIrp->
UserEvent =
NULL;
00408 surrogateIrp->
UserIosb =
NULL;
00409
00410
00411
00412
00413
00414
00415 irpSp = (
IoGetCurrentIrpStackLocation(irp)-activeSize);
00416 RtlCopyMemory(surrogateIrp+1, irpSp,
sizeof(
IO_STACK_LOCATION)*activeSize);
00417
00418
00419
00420
00421
00422 RtlZeroMemory(
00423 ((
PIO_STACK_LOCATION) (surrogateIrp+1))+activeSize,
00424
sizeof(
IO_STACK_LOCATION)*(surrogateIrp->StackCount - activeSize)
00425 );
00426
00427
00428
00429
00430 iovSurrogatePacket =
IovpTrackingDataCreateAndLock(surrogateIrp);
00431
if (iovSurrogatePacket ==
NULL) {
00432
00433
00434
00435
00436 restoreHandle =
IovpProtectedIrpMakeUntouchable(surrogateIrp,
TRUE);
00437
IovpProtectedIrpFree(surrogateIrp, restoreHandle);
00438
return FALSE;
00439 }
00440
00441 headPacket = iovPacket->
HeadPacket;
00442
00443
ASSERT(iovSurrogatePacket->
CallerIrql ==
DISPATCH_LEVEL);
00444 irpSp =
IoGetNextIrpStackLocation(irp);
00445
00446
00447
00448
00449 irp->
CancelRoutine =
NULL;
00450
00451
00452
00453
00454
00455
00456 irp->
IoStatus.Information = (ULONG_PTR) iovPacket;
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
if (irpSp->
MajorFunction ==
IRP_MJ_SCSI) {
00467 srb = irpSp->
Parameters.Others.Argument1 ;
00468
if (
IopIsMemoryRangeReadable(srb, SCSI_REQUEST_BLOCK_SIZE)) {
00469
if ((srb->Length == SCSI_REQUEST_BLOCK_SIZE)&&(srb->OriginalRequest == irp)) {
00470 srb->OriginalRequest = surrogateIrp ;
00471 headPacket->
Flags |=
TRACKFLAG_SRB_MUNGED ;
00472 }
00473 }
00474 }
00475
00476
00477
00478
00479
00480 surrogateIrp->UserIosb = (PIO_STATUS_BLOCK) iovPacket ;
00481
00482
00483
00484
00485
00486
00487
IovpTrackingDataReference(iovPacket,
IOVREFTYPE_POINTER);
00488
00489
00490
00491
00492 surrogateIrp->
Flags |=
IRP_DIAG_IS_SURROGATE;
00493 irp->
Flags |=
IRP_DIAG_HAS_SURROGATE;
00494
00495
00496
00497
00498 iovSurrogatePacket->
Flags |=
TRACKFLAG_SURROGATE |
TRACKFLAG_ACTIVE;
00499 iovSurrogatePacket->
pIovSessionData = iovPacket->
pIovSessionData;
00500 iovSurrogatePacket->
AssertFlags = iovPacket->
AssertFlags;
00501 iovSurrogatePacket->
HeadPacket = iovPacket->
HeadPacket;
00502 iovSurrogatePacket->
LastLocation = iovPacket->
LastLocation;
00503 iovSurrogatePacket->
TopStackLocation = irp->
CurrentLocation;
00504
00505 iovPacket->
Flags |=
TRACKFLAG_HAS_SURROGATE;
00506
00507
00508
00509
00510 iovSurrogatePacket->
CallerIrql = iovPacket->
CallerIrql;
00511 iovPacket->
CallerIrql =
DISPATCH_LEVEL;
00512 InsertTailList(
00513 &iovPacket->
HeadPacket->
SurrogateLink,
00514 &iovSurrogatePacket->
SurrogateLink
00515 );
00516
00517 *IovPacketPointer = iovSurrogatePacket;
00518
return TRUE;
00519 }
00520
00521
VOID
00522
FASTCALL
00523 IovpSessionDataFinalizeSurrogate(
00524 IN
PIOV_SESSION_DATA IovSessionData,
00525 IN OUT
PIOV_REQUEST_PACKET IovPacket,
00526 IN
PIRP SurrogateIrp
00527 )
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 {
00545
PIOV_REQUEST_PACKET iovPrevPacket;
00546
NTSTATUS status, lockedStatus;
00547 ULONG nonInterestingFlags;
00548
PIO_STACK_LOCATION irpSp;
00549 PVOID restoreHandle;
00550
PIRP irp;
00551
00552
ASSERT(IovPacket->Flags&
TRACKFLAG_SURROGATE);
00553
00554
ASSERT(
IovpTrackingDataGetCurrentSessionData(IovPacket) == IovSessionData);
00555
00556
00557
00558
00559
ASSERT(IovPacket->TopStackLocation == SurrogateIrp->CurrentLocation+1) ;
00560
00561 iovPrevPacket = CONTAINING_RECORD(
00562 IovPacket->SurrogateLink.Blink,
00563
IOV_REQUEST_PACKET,
00564 SurrogateLink
00565 );
00566
00567 irp = iovPrevPacket->
TrackedIrp;
00568
00569
00570
00571
00572
if (SurrogateIrp->PendingReturned) {
00573
IoMarkIrpPending(irp);
00574 }
00575
00576 nonInterestingFlags = (
00577
IRPFLAG_EXAMINE_MASK |
00578
IRP_DIAG_IS_SURROGATE|
00579
IRP_DIAG_HAS_SURROGATE
00580 );
00581
00582
00583
00584
00585 SurrogateIrp->Flags &=~ IRP_DIAG_IS_SURROGATE;
00586 irp->
Flags &=~ IRP_DIAG_HAS_SURROGATE;
00587
00588
00589
00590
00591
ASSERT(irp->
StackCount == SurrogateIrp->StackCount);
00592
00593
ASSERT(irp->
Type == SurrogateIrp->Type);
00594
ASSERT(irp->
RequestorMode == SurrogateIrp->RequestorMode);
00595
ASSERT(irp->
ApcEnvironment == SurrogateIrp->ApcEnvironment);
00596
ASSERT(irp->
AllocationFlags == SurrogateIrp->AllocationFlags);
00597
ASSERT(irp->
UserBuffer == SurrogateIrp->UserBuffer);
00598
ASSERT(irp->
Tail.Overlay.Thread == SurrogateIrp->Tail.Overlay.Thread);
00599
00600
ASSERT(
00601 irp->
Overlay.AsynchronousParameters.UserApcRoutine ==
00602 SurrogateIrp->Overlay.AsynchronousParameters.UserApcRoutine
00603 );
00604
00605
ASSERT(
00606 irp->
Overlay.AsynchronousParameters.UserApcContext ==
00607 SurrogateIrp->Overlay.AsynchronousParameters.UserApcContext
00608 );
00609
00610
ASSERT(
00611 irp->
Tail.Overlay.OriginalFileObject ==
00612 SurrogateIrp->Tail.Overlay.OriginalFileObject
00613 );
00614
00615
ASSERT(
00616 irp->
Tail.Overlay.AuxiliaryBuffer ==
00617 SurrogateIrp->Tail.Overlay.AuxiliaryBuffer
00618 );
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 irp->
Flags |= SurrogateIrp->Flags;
00638 irp->
MdlAddress = SurrogateIrp->MdlAddress;
00639 irp->
AssociatedIrp.SystemBuffer = SurrogateIrp->AssociatedIrp.SystemBuffer;
00640
00641
if ((irp->
Flags&
IRP_DEALLOCATE_BUFFER)&&
00642 (irp->
AssociatedIrp.SystemBuffer ==
NULL)) {
00643
00644 irp->
Flags &=~ IRP_DEALLOCATE_BUFFER;
00645 }
00646
00647
00648
00649
00650
00651 irp->
IoStatus = SurrogateIrp->IoStatus;
00652 irp->
PendingReturned = SurrogateIrp->PendingReturned;
00653 irp->
Cancel = SurrogateIrp->Cancel;
00654
00655 iovPrevPacket->
Flags &=~ TRACKFLAG_HAS_SURROGATE;
00656
00657
00658
00659
00660
00661 IovSessionData->BestVisibleIrp = irp;
00662
00663
IovpTrackingDataDereference(iovPrevPacket,
IOVREFTYPE_POINTER);
00664
00665
ASSERT(IovPacket->PointerCount == 0);
00666
00667 restoreHandle =
IovpProtectedIrpMakeUntouchable(SurrogateIrp,
TRUE);
00668
IovpProtectedIrpFree(SurrogateIrp, &restoreHandle);
00669 }
00670
#endif // NO_SPECIAL_IRP
00671