Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ioverifier.c File Reference

#include "iop.h"

Go to the source code of this file.

Defines

#define IO_FREE_IRP_TYPE_INVALID   1
#define IO_FREE_IRP_NOT_ASSOCIATED_WITH_THREAD   2
#define IO_CALL_DRIVER_IRP_TYPE_INVALID   3
#define IO_CALL_DRIVER_INVALID_DEVICE_OBJECT   4
#define IO_CALL_DRIVER_IRQL_NOT_EQUAL   5
#define IO_COMPLETE_REQUEST_INVALID_STATUS   6
#define IO_COMPLETE_REQUEST_CANCEL_ROUTINE_SET   7
#define IO_BUILD_FSD_REQUEST_EXCEPTION   8
#define IO_BUILD_IOCTL_REQUEST_EXCEPTION   9
#define IO_REINITIALIZING_TIMER_OBJECT   10
#define IO_INVALID_HANDLE   11
#define IO_INVALID_STACK_IOSB   12
#define IO_INVALID_STACK_EVENT   13
#define IO_COMPLETE_REQUEST_INVALID_IRQL   14
#define IsKernelHandle(H, M)   (((LONG_PTR)(H) < 0) && ((M) == KernelMode) && ((H) != NtCurrentThread()) && ((H) != NtCurrentProcess()))
#define ZeroAndDopeIrpStackLocation(IrpSp)

Functions

PVOID VerifierAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
BOOLEAN IovpValidateDeviceObject (IN PDEVICE_OBJECT DeviceObject)
VOID IovFreeIrpPrivate (IN PIRP Irp)
VOID IoVerifierInit (IN ULONG VerifierFlags, IN ULONG InitFlags)
VOID IovFreeIrp (IN PIRP Irp)
NTSTATUS FASTCALL IovCallDriver (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
VOID FASTCALL IovCompleteRequest (IN PIRP Irp, IN CCHAR PriorityBoost)
PIRP IovAllocateIrp (IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
PIRP IovBuildAsynchronousFsdRequest (IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN OUT PVOID Buffer OPTIONAL, IN ULONG Length OPTIONAL, IN PLARGE_INTEGER StartingOffset OPTIONAL, IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL)
PIRP IovBuildDeviceIoControlRequest (IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, OUT PIO_STATUS_BLOCK IoStatusBlock)
NTSTATUS IovInitializeTimer (IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context)
VOID IovpCompleteRequest (IN PKAPC Apc, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
VOID FASTCALL IovSpecialIrpCompleteRequest (IN PIRP Irp, IN CCHAR PriorityBoost)
NTSTATUS FASTCALL IovSpecialIrpCallDriver (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
VOID IovInitializeIrp (PIRP Irp, USHORT PacketSize, CCHAR StackSize)
VOID IovAttachDeviceToDeviceStack (PDEVICE_OBJECT SourceDevice, PDEVICE_OBJECT TargetDevice)
VOID IovDeleteDevice (PDEVICE_OBJECT DeleteDevice)
VOID IovDetachDevice (PDEVICE_OBJECT TargetDevice)
BOOLEAN IovCancelIrp (PIRP Irp, BOOLEAN *returnValue)

Variables

BOOLEAN IopVerifierOn = FALSE
ULONG IovpEnforcementLevel = (ULONG) -1
ULONG IovpVerifierLevel = (ULONG)0
BOOLEAN IoVerifierOnByDefault = TRUE
LONG IovpInitCalled = 0
ULONG IovpMaxSupportedVerifierLevel = 3
ULONG IovpVerifierFlags = 0


Define Documentation

#define IO_BUILD_FSD_REQUEST_EXCEPTION   8
 

Definition at line 38 of file ioverifier.c.

Referenced by IovBuildAsynchronousFsdRequest().

#define IO_BUILD_IOCTL_REQUEST_EXCEPTION   9
 

Definition at line 39 of file ioverifier.c.

Referenced by IovBuildDeviceIoControlRequest().

#define IO_CALL_DRIVER_INVALID_DEVICE_OBJECT   4
 

Definition at line 34 of file ioverifier.c.

Referenced by IovCallDriver(), and IovSpecialIrpCallDriver().

#define IO_CALL_DRIVER_IRP_TYPE_INVALID   3
 

Definition at line 33 of file ioverifier.c.

Referenced by IovCallDriver(), and IovSpecialIrpCallDriver().

#define IO_CALL_DRIVER_IRQL_NOT_EQUAL   5
 

Definition at line 35 of file ioverifier.c.

Referenced by IovCallDriver(), and IovSpecialIrpCallDriver().

#define IO_COMPLETE_REQUEST_CANCEL_ROUTINE_SET   7
 

Definition at line 37 of file ioverifier.c.

Referenced by IovCompleteRequest().

#define IO_COMPLETE_REQUEST_INVALID_IRQL   14
 

Definition at line 44 of file ioverifier.c.

Referenced by IovCompleteRequest().

#define IO_COMPLETE_REQUEST_INVALID_STATUS   6
 

Definition at line 36 of file ioverifier.c.

Referenced by IovCompleteRequest().

#define IO_FREE_IRP_NOT_ASSOCIATED_WITH_THREAD   2
 

Definition at line 32 of file ioverifier.c.

Referenced by IovFreeIrpPrivate().

#define IO_FREE_IRP_TYPE_INVALID   1
 

Definition at line 31 of file ioverifier.c.

Referenced by IovFreeIrpPrivate().

#define IO_INVALID_HANDLE   11
 

Definition at line 41 of file ioverifier.c.

#define IO_INVALID_STACK_EVENT   13
 

Definition at line 43 of file ioverifier.c.

Referenced by IovpCompleteRequest().

#define IO_INVALID_STACK_IOSB   12
 

Definition at line 42 of file ioverifier.c.

Referenced by IovpCompleteRequest().

#define IO_REINITIALIZING_TIMER_OBJECT   10
 

Definition at line 40 of file ioverifier.c.

Referenced by IovInitializeTimer().

#define IsKernelHandle H,
 )     (((LONG_PTR)(H) < 0) && ((M) == KernelMode) && ((H) != NtCurrentThread()) && ((H) != NtCurrentProcess()))
 

Definition at line 57 of file ioverifier.c.

Referenced by NtClose(), NtSetInformationObject(), NtWaitForMultipleObjects(), and ObReferenceObjectByHandle().

#define ZeroAndDopeIrpStackLocation IrpSp   ) 
 

Value:

{ \ (IrpSp)->MinorFunction = 0; \ (IrpSp)->Flags = 0; \ (IrpSp)->Control = SL_NOTCOPIED; \ (IrpSp)->Parameters.Others.Argument1 = 0; \ (IrpSp)->Parameters.Others.Argument2 = 0; \ (IrpSp)->Parameters.Others.Argument3 = 0; \ (IrpSp)->Parameters.Others.Argument4 = 0; \ (IrpSp)->FileObject = (PFILE_OBJECT) NULL; }

Referenced by IovSpecialIrpCompleteRequest().


Function Documentation

PIRP IovAllocateIrp IN CCHAR  StackSize,
IN BOOLEAN  ChargeQuota
 

Definition at line 353 of file ioverifier.c.

References _IRP::AllocationFlags, ExAllocatePoolWithTagPriority(), EXCEPTION_EXECUTE_HANDLER, HighPoolPrioritySpecialPoolOverrun, IopAllocateIrpPrivate(), IopInitializeIrp, IoSizeOfIrp, IovpVerifierFlags, IRP_ALLOCATED_MUST_SUCCEED, IRP_QUOTA_CHARGED, KernelMode, NonPagedPool, NonPagedPoolMustSucceed, NULL, SPECIALIRP_IO_ALLOCATE_IRP_1, SPECIALIRP_IO_ALLOCATE_IRP_2, and USHORT.

Referenced by IoVerifierInit().

00357 { 00358 USHORT allocateSize; 00359 UCHAR fixedSize; 00360 PIRP irp; 00361 UCHAR mustSucceed; 00362 USHORT packetSize; 00363 00364 #ifndef NO_SPECIAL_IRP 00365 // 00366 // Should we override normal lookaside caching so that we may catch 00367 // more bugs? 00368 // 00369 SPECIALIRP_IO_ALLOCATE_IRP_1(StackSize, ChargeQuota, &irp) ; 00370 00371 if (irp) { 00372 return irp ; 00373 } 00374 #endif 00375 00376 // 00377 // If special pool is not turned on lets just call the standard 00378 // irp allocator. 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 // There are no free packets on the lookaside list, or the packet is 00395 // too large to be allocated from one of the lists, so it must be 00396 // allocated from nonpaged pool. If quota is to be charged, charge it 00397 // against the current process. Otherwise, allocate the pool normally. 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 // Attempt to allocate the pool from non-paged pool. If this 00415 // fails, and the caller's previous mode was kernel then allocate 00416 // the pool as must succeed. 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 // Initialize the packet. 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 }

VOID IovAttachDeviceToDeviceStack PDEVICE_OBJECT  SourceDevice,
PDEVICE_OBJECT  TargetDevice
 

Definition at line 1296 of file ioverifier.c.

References IovpVerifierLevel, SPECIALIRP_IO_ATTACH_DEVICE_TO_DEVICE_STACK, and VOID().

01300 { 01301 if (IovpVerifierLevel < 2) { 01302 return; 01303 } 01304 01305 SPECIALIRP_IO_ATTACH_DEVICE_TO_DEVICE_STACK(SourceDevice, TargetDevice); 01306 }

PIRP IovBuildAsynchronousFsdRequest IN ULONG  MajorFunction,
IN PDEVICE_OBJECT  DeviceObject,
IN OUT PVOID Buffer  OPTIONAL,
IN ULONG Length  OPTIONAL,
IN PLARGE_INTEGER StartingOffset  OPTIONAL,
IN PIO_STATUS_BLOCK IoStatusBlock  OPTIONAL
 

Definition at line 455 of file ioverifier.c.

References Buffer, EXCEPTION_EXECUTE_HANDLER, IO_BUILD_FSD_REQUEST_EXCEPTION, IoBuildAsynchronousFsdRequest(), Irp, and KeBugCheckEx().

00463 { 00464 PIRP Irp; 00465 00466 try { 00467 Irp = IoBuildAsynchronousFsdRequest( 00468 MajorFunction, 00469 DeviceObject, 00470 Buffer, 00471 Length, 00472 StartingOffset, 00473 IoStatusBlock 00474 ); 00475 } except(EXCEPTION_EXECUTE_HANDLER) { 00476 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00477 IO_BUILD_FSD_REQUEST_EXCEPTION, 00478 (ULONG_PTR)DeviceObject, 00479 (ULONG_PTR)MajorFunction, 00480 GetExceptionCode()); 00481 } 00482 return (Irp); 00483 }

PIRP IovBuildDeviceIoControlRequest IN ULONG  IoControlCode,
IN PDEVICE_OBJECT  DeviceObject,
IN PVOID InputBuffer  OPTIONAL,
IN ULONG  InputBufferLength,
OUT PVOID OutputBuffer  OPTIONAL,
IN ULONG  OutputBufferLength,
IN BOOLEAN  InternalDeviceIoControl,
IN PKEVENT  Event,
OUT PIO_STATUS_BLOCK  IoStatusBlock
 

Definition at line 486 of file ioverifier.c.

References Event(), EXCEPTION_EXECUTE_HANDLER, IO_BUILD_IOCTL_REQUEST_EXCEPTION, IoBuildDeviceIoControlRequest(), Irp, and KeBugCheckEx().

00497 { 00498 PIRP Irp; 00499 00500 try { 00501 Irp = IoBuildDeviceIoControlRequest( 00502 IoControlCode, 00503 DeviceObject, 00504 InputBuffer, 00505 InputBufferLength, 00506 OutputBuffer, 00507 OutputBufferLength, 00508 InternalDeviceIoControl, 00509 Event, 00510 IoStatusBlock 00511 ); 00512 } except(EXCEPTION_EXECUTE_HANDLER) { 00513 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00514 IO_BUILD_IOCTL_REQUEST_EXCEPTION, 00515 (ULONG_PTR)DeviceObject, 00516 (ULONG_PTR)IoControlCode, 00517 GetExceptionCode()); 00518 } 00519 00520 return (Irp); 00521 }

NTSTATUS FASTCALL IovCallDriver IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp
 

Definition at line 248 of file ioverifier.c.

References IO_CALL_DRIVER_INVALID_DEVICE_OBJECT, IO_CALL_DRIVER_IRP_TYPE_INVALID, IO_CALL_DRIVER_IRQL_NOT_EQUAL, IO_TYPE_IRP, IopfCallDriver(), IopVerifierOn, IovpValidateDeviceObject(), IovpVerifierLevel, IovSpecialIrpCallDriver(), Irp, KeBugCheckEx(), NTSTATUS(), and _IRP::Type.

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 }

BOOLEAN IovCancelIrp PIRP  Irp,
BOOLEAN *  returnValue
 

Definition at line 1332 of file ioverifier.c.

References FALSE, Irp, SPECIALIRP_IO_CANCEL_IRP, and TRUE.

01336 { 01337 #ifndef NO_SPECIAL_IRP 01338 BOOLEAN cancelHandled ; 01339 01340 SPECIALIRP_IO_CANCEL_IRP(Irp, &cancelHandled, returnValue) ; 01341 01342 if (cancelHandled) { 01343 01344 return TRUE ; 01345 } 01346 #endif 01347 return FALSE; 01348 }

VOID FASTCALL IovCompleteRequest IN PIRP  Irp,
IN CCHAR  PriorityBoost
 

Definition at line 297 of file ioverifier.c.

References _IRP::CancelRoutine, _IRP::CurrentLocation, DISPATCH_LEVEL, IO_COMPLETE_REQUEST_CANCEL_ROUTINE_SET, IO_COMPLETE_REQUEST_INVALID_IRQL, IO_COMPLETE_REQUEST_INVALID_STATUS, IO_TYPE_IRP, IopfCompleteRequest(), IopVerifierOn, _IRP::IoStatus, IovpVerifierLevel, IovSpecialIrpCompleteRequest(), Irp, KeBugCheckEx(), PriorityBoost, _IRP::StackCount, and _IRP::Type.

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 }

VOID IovDeleteDevice PDEVICE_OBJECT  DeleteDevice  ) 
 

Definition at line 1309 of file ioverifier.c.

References IovpVerifierLevel, SPECIALIRP_IO_DELETE_DEVICE, and VOID().

01312 { 01313 if (IovpVerifierLevel < 2) { 01314 return; 01315 } 01316 01317 SPECIALIRP_IO_DELETE_DEVICE(DeleteDevice); 01318 }

VOID IovDetachDevice PDEVICE_OBJECT  TargetDevice  ) 
 

Definition at line 1321 of file ioverifier.c.

References IovpVerifierLevel, SPECIALIRP_IO_DETACH_DEVICE, and VOID().

01324 { 01325 if (IovpVerifierLevel < 2) { 01326 return; 01327 } 01328 SPECIALIRP_IO_DETACH_DEVICE(TargetDevice); 01329 }

VOID IoVerifierInit IN ULONG  VerifierFlags,
IN ULONG  InitFlags
 

Definition at line 91 of file ioverifier.c.

References APC_LEVEL, ASSERT, DIAG_IGNORE_DRIVER_LIST, IopDcControlInitial, IopDcControlLock, IopDcControlOverride, IopDriverCorrectnessTakeLock(), IopVerifierOn, IovAllocateIrp(), IOVERIFIERINIT_PHASE0, IOVERIFIERINIT_VERIFIER_DRIVER_LIST, IoVerifierOnByDefault, IovFreeIrpPrivate(), IovpInitCalled, IovpInitIrpTracking(), IovpMaxSupportedVerifierLevel, IovpVerifierFlags, IovpVerifierLevel, IovSpecialIrpCallDriver(), IovSpecialIrpCompleteRequest(), KeInitializeSpinLock(), pIoAllocateIrp, pIofCallDriver, pIofCompleteRequest, pIoFreeIrp, and TRUE.

Referenced by IovpDoAssertIrps(), and MiInitializeDriverVerifierList().

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 // Lock it down. 00113 // 00114 sectionHeaderHandle = MmLockPagableCodeSection(IopDriverCorrectnessTakeLock); 00115 00116 if (!sectionHeaderHandle) { 00117 00118 return; 00119 } 00120 } 00121 00122 // 00123 // Various initialization 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 // Determine the level of verification. Later we will modify the driver 00150 // verifier applet to pass in a level directly. 00151 // 00152 00153 #if !DBG 00154 if (IovpVerifierLevel > IovpMaxSupportedVerifierLevel) { 00155 IovpVerifierLevel = IovpMaxSupportedVerifierLevel; 00156 } 00157 #endif 00158 00159 verifierLevel = IovpVerifierLevel; 00160 00161 // 00162 // Enable and hook in the verifier. 00163 // 00164 IopVerifierOn = TRUE; 00165 IovpInitCalled = 1; 00166 IovpVerifierFlags = VerifierFlags; 00167 00168 if (verifierLevel > 1) { 00169 // 00170 // Initialize the special IRP code as appropriate. 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 }

VOID IovFreeIrp IN PIRP  Irp  ) 
 

Definition at line 198 of file ioverifier.c.

References IovFreeIrpPrivate(), and Irp.

00201 { 00202 IovFreeIrpPrivate(Irp); 00203 }

VOID IovFreeIrpPrivate IN PIRP  Irp  ) 
 

Definition at line 206 of file ioverifier.c.

References IO_FREE_IRP_NOT_ASSOCIATED_WITH_THREAD, IO_FREE_IRP_TYPE_INVALID, IO_TYPE_IRP, IopFreeIrp(), IopVerifierOn, Irp, KeBugCheckEx(), SPECIALIRP_IO_FREE_IRP, and _IRP::Type.

Referenced by IoVerifierInit(), and IovFreeIrp().

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 }

VOID IovInitializeIrp PIRP  Irp,
USHORT  PacketSize,
CCHAR  StackSize
 

Definition at line 1279 of file ioverifier.c.

References IovpVerifierLevel, Irp, SPECIALIRP_IO_INITIALIZE_IRP, and VOID().

01284 { 01285 BOOLEAN initializeHandled ; 01286 01287 if (IovpVerifierLevel < 2) { 01288 return; 01289 } 01290 01291 SPECIALIRP_IO_INITIALIZE_IRP(Irp, PacketSize, StackSize, &initializeHandled) ; 01292 01293 }

NTSTATUS IovInitializeTimer IN PDEVICE_OBJECT  DeviceObject,
IN PIO_TIMER_ROUTINE  TimerRoutine,
IN PVOID  Context
 

Definition at line 524 of file ioverifier.c.

References IO_REINITIALIZING_TIMER_OBJECT, IoInitializeTimer(), KeBugCheckEx(), and NTSTATUS().

00529 { 00530 if (DeviceObject->Timer) { 00531 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00532 IO_REINITIALIZING_TIMER_OBJECT, 00533 (ULONG_PTR)DeviceObject, 00534 0, 00535 0); 00536 } 00537 return (IoInitializeTimer(DeviceObject, TimerRoutine, Context)); 00538 }

VOID IovpCompleteRequest IN PKAPC  Apc,
IN PVOID *  SystemArgument1,
IN PVOID *  SystemArgument2
 

Definition at line 542 of file ioverifier.c.

References IO_INVALID_STACK_EVENT, IO_INVALID_STACK_IOSB, KeBugCheckEx(), KeGetCurrentThread, _IRP::UserEvent, _IRP::UserIosb, and VOID().

00547 { 00548 PIRP irp; 00549 PUCHAR addr; 00550 ULONG BestStackOffset; 00551 00552 irp = CONTAINING_RECORD( Apc, IRP, Tail.Apc ); 00553 00554 #if defined(_X86_) 00555 00556 00557 addr = (PUCHAR)irp->UserIosb; 00558 if ((addr > (PUCHAR)KeGetCurrentThread()->StackLimit) && 00559 (addr <= (PUCHAR)&BestStackOffset)) { 00560 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00561 IO_INVALID_STACK_IOSB, 00562 (ULONG_PTR)addr, 00563 0, 00564 0); 00565 00566 } 00567 00568 addr = (PUCHAR)irp->UserEvent; 00569 if ((addr > (PUCHAR)KeGetCurrentThread()->StackLimit) && 00570 (addr <= (PUCHAR)&BestStackOffset)) { 00571 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00572 IO_INVALID_STACK_EVENT, 00573 (ULONG_PTR)addr, 00574 0, 00575 0); 00576 00577 } 00578 #endif 00579 }

BOOLEAN IovpValidateDeviceObject IN PDEVICE_OBJECT  DeviceObject  ) 
 

Definition at line 184 of file ioverifier.c.

References FALSE, IO_TYPE_DEVICE, NULL, and TRUE.

Referenced by IovCallDriver(), and IovSpecialIrpCallDriver().

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 }

NTSTATUS FASTCALL IovSpecialIrpCallDriver IN PDEVICE_OBJECT  DeviceObject,
IN OUT PIRP  Irp
 

Definition at line 1159 of file ioverifier.c.

References ASSERT, _IRP::CurrentLocation, DbgPrint, _IO_STACK_LOCATION::DeviceObject, FASTCALL, IO_CALL_DRIVER_INVALID_DEVICE_OBJECT, IO_CALL_DRIVER_IRP_TYPE_INVALID, IO_CALL_DRIVER_IRQL_NOT_EQUAL, IO_TYPE_IRP, IOFCALLDRIVER_STACKDATA, IoGetNextIrpStackLocation, IopfCallDriver(), IopVerifierOn, IovpValidateDeviceObject(), Irp, KeBugCheckEx(), _DRIVER_OBJECT::MajorFunction, _IO_STACK_LOCATION::MajorFunction, NTSTATUS(), PDRIVER_DISPATCH, PERFINFO_DRIVER_MAJORFUNCTION_CALL, PERFINFO_DRIVER_MAJORFUNCTION_RETURN, SPECIALIRP_IOF_CALL_1, SPECIALIRP_IOF_CALL_2, _IRP::Tail, and _IRP::Type.

Referenced by IovCallDriver(), and IoVerifierInit().

01165 : 01166 01167 This routine is invoked to pass an I/O Request Packet (IRP) to another 01168 driver at its dispatch routine. This routine is called only for IRP tracking 01169 It duplicates the code in iosubs.c. 01170 01171 Arguments: 01172 01173 DeviceObject - Pointer to device object to which the IRP should be passed. 01174 01175 Irp - Pointer to IRP for request. 01176 01177 Return Value: 01178 01179 Return status from driver's dispatch routine. 01180 01181 --*/ 01182 01183 { 01184 PIO_STACK_LOCATION irpSp; 01185 PDRIVER_OBJECT driverObject; 01186 NTSTATUS status; 01187 KIRQL saveIrql; 01188 PDRIVER_DISPATCH dispatchRoutine; 01189 IOFCALLDRIVER_STACKDATA iofCallDriverStackData ; 01190 01191 if (!IopVerifierOn) { 01192 status = IopfCallDriver(DeviceObject, Irp); 01193 return status; 01194 } 01195 01196 // 01197 // Ensure that this is really an I/O Request Packet. 01198 // 01199 01200 if (Irp->Type != IO_TYPE_IRP) { 01201 01202 ASSERT(Irp->Type == IO_TYPE_IRP); 01203 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 01204 IO_CALL_DRIVER_IRP_TYPE_INVALID, 01205 (ULONG_PTR)Irp, 01206 0, 01207 0); 01208 } 01209 01210 if (!IovpValidateDeviceObject(DeviceObject)) { 01211 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 01212 IO_CALL_DRIVER_INVALID_DEVICE_OBJECT, 01213 (ULONG_PTR)DeviceObject, 01214 0, 01215 0); 01216 } 01217 01218 SPECIALIRP_IOF_CALL_1(&Irp, DeviceObject, &iofCallDriverStackData) ; 01219 01220 // 01221 // Update the IRP stack to point to the next location. 01222 // 01223 Irp->CurrentLocation--; 01224 01225 if (Irp->CurrentLocation <= 0) { 01226 KeBugCheckEx( NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR) Irp, 0, 0, 0 ); 01227 } 01228 01229 irpSp = IoGetNextIrpStackLocation( Irp ); 01230 Irp->Tail.Overlay.CurrentStackLocation = irpSp; 01231 01232 // 01233 // Save a pointer to the device object for this request so that it can 01234 // be used later in completion. 01235 // 01236 01237 irpSp->DeviceObject = DeviceObject; 01238 01239 // 01240 // Invoke the driver at its dispatch routine entry point. 01241 // 01242 01243 driverObject = DeviceObject->DriverObject; 01244 01245 dispatchRoutine = driverObject->MajorFunction[irpSp->MajorFunction] ; 01246 01247 saveIrql = KeGetCurrentIrql(); 01248 01249 PERFINFO_DRIVER_MAJORFUNCTION_CALL(Irp, irpSp, driverObject); 01250 01251 status = dispatchRoutine( DeviceObject, Irp ); 01252 01253 PERFINFO_DRIVER_MAJORFUNCTION_RETURN(Irp, irpSp, driverObject); 01254 01255 if (saveIrql != KeGetCurrentIrql()) { 01256 01257 DbgPrint( "IO: IoCallDriver( Driver object: %p Device object: %p Irp: %p )\n", 01258 driverObject, 01259 DeviceObject, 01260 Irp 01261 ); 01262 DbgPrint( " Irql before: %x != After: %x\n", saveIrql, KeGetCurrentIrql() ); 01263 01264 ASSERT(saveIrql == KeGetCurrentIrql()); 01265 01266 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 01267 IO_CALL_DRIVER_IRQL_NOT_EQUAL, 01268 saveIrql, 01269 KeGetCurrentIrql(), 01270 0); 01271 } 01272 01273 SPECIALIRP_IOF_CALL_2(Irp, DeviceObject, dispatchRoutine, &status, &iofCallDriverStackData) ; 01274 01275 return status; 01276 }

VOID FASTCALL IovSpecialIrpCompleteRequest IN PIRP  Irp,
IN CCHAR  PriorityBoost
 

Definition at line 586 of file ioverifier.c.

References FASTCALL, NULL, SL_NOTCOPIED, and ZeroAndDopeIrpStackLocation.

Referenced by IovCompleteRequest(), and IoVerifierInit().

00592 : 00593 00594 The following code is called only when doing IRP tracking. It duplicates code 00595 in iosubs.c. 00596 This routine is invoked to complete an I/O request. It is invoked by the 00597 driver in its DPC routine to perform the final completion of the IRP. The 00598 functions performed by this routine are as follows. 00599 00600 1. A check is made to determine whether the packet's stack locations 00601 have been exhausted. If not, then the stack location pointer is set 00602 to the next location and if there is a routine to be invoked, then 00603 it will be invoked. This continues until there are either no more 00604 routines which are interested or the packet runs out of stack. 00605 00606 If a routine is invoked to complete the packet for a specific driver 00607 which needs to perform work a lot of work or the work needs to be 00608 performed in the context of another process, then the routine will 00609 return an alternate success code of STATUS_MORE_PROCESSING_REQUIRED. 00610 This indicates that this completion routine should simply return to 00611 its caller because the operation will be "completed" by this routine 00612 again sometime in the future. 00613 00614 2. A check is made to determine whether this IRP is an associated IRP. 00615 If it is, then the count on the master IRP is decremented. If the 00616 count for the master becomes zero, then the master IRP will be 00617 completed according to the steps below taken for a normal IRP being 00618 completed. If the count is still non-zero, then this IRP (the one 00619 being completed) will simply be deallocated. 00620 00621 3. If this is paging I/O or a close operation, then simply write the 00622 I/O status block and set the event to the signaled state, and 00623 dereference the event. If this is paging I/O, deallocate the IRP 00624 as well. 00625 00626 4. Unlock the pages, if any, specified by the MDL by calling 00627 MmUnlockPages. 00628 00629 5. A check is made to determine whether or not completion of the 00630 request can be deferred until later. If it can be, then this 00631 routine simply exits and leaves it up to the originator of the 00632 request to fully complete the IRP. By not initializing and queueing 00633 the special kernel APC to the calling thread (which is the current 00634 thread by definition), a lot of interrupt and queueing processing 00635 can be avoided. 00636 00637 00638 6. The final rundown routine is invoked to queue the request packet to 00639 the target (requesting) thread as a special kernel mode APC. 00640 00641 Arguments: 00642 00643 Irp - Pointer to the I/O Request Packet to complete. 00644 00645 PriorityBoost - Supplies the amount of priority boost that is to be given 00646 to the target thread when the special kernel APC is queued. 00647 00648 Return Value: 00649 00650 None. 00651 00652 --*/ 00653 00654 #define ZeroAndDopeIrpStackLocation( IrpSp ) { \ 00655 (IrpSp)->MinorFunction = 0; \ 00656 (IrpSp)->Flags = 0; \ 00657 (IrpSp)->Control = SL_NOTCOPIED; \ 00658 (IrpSp)->Parameters.Others.Argument1 = 0; \ 00659 (IrpSp)->Parameters.Others.Argument2 = 0; \ 00660 (IrpSp)->Parameters.Others.Argument3 = 0; \ 00661 (IrpSp)->Parameters.Others.Argument4 = 0; \ 00662 (IrpSp)->FileObject = (PFILE_OBJECT) NULL; } 00663 00664 { 00665 PIRP masterIrp; 00666 NTSTATUS status; 00667 PIO_STACK_LOCATION stackPointer; 00668 PMDL mdl; 00669 PETHREAD thread; 00670 PFILE_OBJECT fileObject; 00671 KIRQL irql; 00672 PVOID saveAuxiliaryPointer = NULL; 00673 00674 #ifndef NO_SPECIAL_IRP 00675 PVOID routine ; 00676 IOFCOMPLETEREQUEST_STACKDATA completionPacket; 00677 #endif 00678 00679 if (!IopVerifierOn) { 00680 IopfCompleteRequest(Irp, PriorityBoost); 00681 return; 00682 } 00683 00684 #if DBG 00685 00686 if (Irp->CurrentLocation <= (CCHAR) Irp->StackCount) { 00687 00688 stackPointer = IoGetCurrentIrpStackLocation(Irp); 00689 if (stackPointer->MajorFunction == IRP_MJ_POWER) { 00690 PoPowerTrace( 00691 POWERTRACE_COMPLETE, 00692 IoGetCurrentIrpStackLocation(Irp)->DeviceObject, 00693 Irp, 00694 IoGetCurrentIrpStackLocation(Irp) 00695 ); 00696 } 00697 } 00698 00699 #endif 00700 00701 SPECIALIRP_IOF_COMPLETE_1(Irp, PriorityBoost, &completionPacket); 00702 00703 // 00704 // Begin by ensuring that this packet has not already been completed 00705 // by someone. 00706 // 00707 00708 if (Irp->CurrentLocation > (CCHAR) (Irp->StackCount + 1) || 00709 Irp->Type != IO_TYPE_IRP) { 00710 KeBugCheckEx( MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR) Irp, __LINE__, 0, 0 ); 00711 } 00712 00713 // 00714 // Ensure that the packet being completed really is still an IRP. 00715 // 00716 00717 if (Irp->Type != IO_TYPE_IRP) { 00718 00719 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00720 IO_CALL_DRIVER_IRP_TYPE_INVALID, 00721 (ULONG_PTR)Irp, 00722 0, 00723 0); 00724 } 00725 00726 // 00727 // Ensure that no one believes that this request is still in a cancellable 00728 // state. 00729 // 00730 00731 if (Irp->CancelRoutine) { 00732 00733 ASSERT(Irp->CancelRoutine == NULL); 00734 00735 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00736 IO_COMPLETE_REQUEST_CANCEL_ROUTINE_SET, 00737 (ULONG_PTR)Irp->CancelRoutine, 00738 (ULONG_PTR)Irp, 00739 0); 00740 } 00741 00742 // 00743 // Ensure that the packet is not being completed with a thoroughly 00744 // confusing status code. Actually completing a packet with a pending 00745 // status probably means that someone forgot to set the real status in 00746 // the packet. 00747 00748 if (Irp->IoStatus.Status == STATUS_PENDING) { 00749 00750 00751 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00752 IO_COMPLETE_REQUEST_INVALID_STATUS, 00753 Irp->IoStatus.Status, 00754 (ULONG_PTR)Irp, 00755 0); 00756 } 00757 00758 // 00759 // Ensure that the packet is not being completed with a minus one. This is 00760 // apparently a common problem in some drivers, and has no meaning as a 00761 // status code. 00762 // 00763 00764 if (Irp->IoStatus.Status == 0xffffffff) { 00765 00766 00767 KeBugCheckEx(DRIVER_VERIFIER_IOMANAGER_VIOLATION, 00768 IO_COMPLETE_REQUEST_INVALID_STATUS, 00769 Irp->IoStatus.Status, 00770 (ULONG_PTR)Irp, 00771 0); 00772 } 00773 00774 // 00775 // Ensure that if this is a paging I/O operation, and it failed, that the 00776 // reason for the failure isn't because quota was exceeded. 00777 // 00778 00779 ASSERT( !(Irp->Flags & IRP_PAGING_IO && Irp->IoStatus.Status == STATUS_QUOTA_EXCEEDED ) ); 00780 00781 #ifndef NO_SPECIAL_IRP 00782 00783 if (!IovpTrackingFlags) { 00784 00785 IopfCompleteRequest(Irp, PriorityBoost); 00786 return; 00787 } 00788 00789 // 00790 // Now check to see whether this is the last driver that needs to be 00791 // invoked for this packet. If not, then bump the stack and check to 00792 // see whether the driver wishes to see the completion. As each stack 00793 // location is examined, invoke any routine which needs to be invoked. 00794 // If the routine returns STATUS_MORE_PROCESSING_REQUIRED, then stop the 00795 // processing of this packet. 00796 // 00797 00798 for (stackPointer = IoGetCurrentIrpStackLocation( Irp ), 00799 Irp->CurrentLocation++, 00800 Irp->Tail.Overlay.CurrentStackLocation++; 00801 Irp->CurrentLocation <= (CCHAR) (Irp->StackCount + 1); 00802 stackPointer++, 00803 Irp->CurrentLocation++, 00804 Irp->Tail.Overlay.CurrentStackLocation++) { 00805 00806 // 00807 // A stack location was located. Check to see whether or not it 00808 // has a completion routine and if so, whether or not it should be 00809 // invoked. 00810 // 00811 // Begin by saving the pending returned flag in the current stack 00812 // location in the fixed part of the IRP. 00813 // 00814 00815 Irp->PendingReturned = stackPointer->Control & SL_PENDING_RETURNED; 00816 00817 SPECIALIRP_IOF_COMPLETE_2(Irp, &completionPacket); 00818 00819 if ( (NT_SUCCESS( Irp->IoStatus.Status ) && 00820 stackPointer->Control & SL_INVOKE_ON_SUCCESS) || 00821 (!NT_SUCCESS( Irp->IoStatus.Status ) && 00822 stackPointer->Control & SL_INVOKE_ON_ERROR) || 00823 (Irp->Cancel && 00824 stackPointer->Control & SL_INVOKE_ON_CANCEL) 00825 ) { 00826 00827 // 00828 // This driver has specified a completion routine. Invoke the 00829 // routine passing it a pointer to its device object and the 00830 // IRP that is being completed. 00831 // 00832 00833 ZeroAndDopeIrpStackLocation( stackPointer ); 00834 00835 #ifndef NO_SPECIAL_IRP 00836 routine = stackPointer->CompletionRoutine ; 00837 SPECIALIRP_IOF_COMPLETE_3(Irp, routine, &completionPacket); 00838 #endif 00839 00840 PERFINFO_DRIVER_COMPLETIONROUTINE_CALL(Irp, stackPointer); 00841 00842 status = stackPointer->CompletionRoutine( (PDEVICE_OBJECT) (Irp->CurrentLocation == (CCHAR) (Irp->StackCount + 1) ? 00843 (PDEVICE_OBJECT) NULL : 00844 IoGetCurrentIrpStackLocation( Irp )->DeviceObject), 00845 Irp, 00846 stackPointer->Context ); 00847 00848 PERFINFO_DRIVER_COMPLETIONROUTINE_RETURN(Irp, stackPointer); 00849 00850 SPECIALIRP_IOF_COMPLETE_4(Irp, status, &completionPacket); 00851 00852 if (status == STATUS_MORE_PROCESSING_REQUIRED) { 00853 00854 // 00855 // Note: Notice that if the driver has returned the above 00856 // status value, it may have already DEALLOCATED the 00857 // packet! Therefore, do NOT touch any part of the 00858 // IRP in the following code. 00859 // 00860 00861 SPECIALIRP_IOF_COMPLETE_5(Irp, &completionPacket); 00862 return; 00863 } 00864 00865 } else { 00866 if (Irp->PendingReturned && Irp->CurrentLocation <= Irp->StackCount) { 00867 IoMarkIrpPending( Irp ); 00868 } 00869 ZeroAndDopeIrpStackLocation( stackPointer ); 00870 } 00871 00872 SPECIALIRP_IOF_COMPLETE_5(Irp, &completionPacket); 00873 } 00874 00875 // 00876 // Check to see whether this is an associated IRP. If so, then decrement 00877 // the count in the master IRP. If the count is decremented to zero, 00878 // then complete the master packet as well. 00879 // 00880 00881 if (Irp->Flags & IRP_ASSOCIATED_IRP) { 00882 ULONG count; 00883 masterIrp = Irp->AssociatedIrp.MasterIrp; 00884 count = ExInterlockedAddUlong( (PULONG) &masterIrp->AssociatedIrp.IrpCount, 00885 0xffffffff, 00886 &IopDatabaseLock ); 00887 00888 // 00889 // Deallocate this packet and any MDLs that are associated with it 00890 // by either doing direct deallocations if they were allocated from 00891 // a zone or by queueing the packet to a thread to perform the 00892 // deallocation. 00893 // 00894 // Also, check the count of the master IRP to determine whether or not 00895 // the count has gone to zero. If not, then simply get out of here. 00896 // Otherwise, complete the master packet. 00897 // 00898 00899 Irp->Tail.Overlay.Thread = masterIrp->Tail.Overlay.Thread; 00900 IopFreeIrpAndMdls( Irp ); 00901 if (count == 1) { 00902 IoCompleteRequest( masterIrp, PriorityBoost ); 00903 } 00904 return; 00905 } 00906 00907 // 00908 // Check to see if we have a name junction. If so set the stage to 00909 // transmogrify the reparse point data in IopCompleteRequest. 00910 // 00911 00912 if ((Irp->IoStatus.Status == STATUS_REPARSE ) && 00913 (Irp->IoStatus.Information > IO_REPARSE_TAG_RESERVED_RANGE)) { 00914 00915 if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT) { 00916 00917 // 00918 // For name junctions, we save the pointer to the auxiliary 00919 // buffer and use it below. 00920 // 00921 00922 ASSERT( Irp->Tail.Overlay.AuxiliaryBuffer != NULL ); 00923 00924 saveAuxiliaryPointer = (PVOID) Irp->Tail.Overlay.AuxiliaryBuffer; 00925 00926 // 00927 // We NULL the entry to avoid its de-allocation at this time. 00928 // This buffer get deallocated in IopDoNameTransmogrify 00929 // 00930 00931 Irp->Tail.Overlay.AuxiliaryBuffer = NULL; 00932 } else { 00933 00934 // 00935 // Fail the request. A driver needed to act on this IRP prior 00936 // to getting to this point. 00937 // 00938 00939 Irp->IoStatus.Status = STATUS_IO_REPARSE_TAG_NOT_HANDLED; 00940 } 00941 } 00942 00943 // 00944 // Check the auxiliary buffer pointer in the packet and if a buffer was 00945 // allocated, deallocate it now. Note that this buffer must be freed 00946 // here since the pointer is overlayed with the APC that will be used 00947 // to get to the requesting thread's context. 00948 // 00949 00950 if (Irp->Tail.Overlay.AuxiliaryBuffer) { 00951 ExFreePool( Irp->Tail.Overlay.AuxiliaryBuffer ); 00952 Irp->Tail.Overlay.AuxiliaryBuffer = NULL; 00953 } 00954 00955 // 00956 // Check to see if this is paging I/O or a close operation. If either, 00957 // then special processing must be performed. The reasons that special 00958 // processing must be performed is different based on the type of 00959 // operation being performed. The biggest reasons for special processing 00960 // on paging operations are that using a special kernel APC for an in- 00961 // page operation cannot work since the special kernel APC can incur 00962 // another pagefault. Likewise, all paging I/O uses MDLs that belong 00963 // to the memory manager, not the I/O system. 00964 // 00965 // Close operations are special because the close may have been invoked 00966 // because of a special kernel APC (some IRP was completed which caused 00967 // the reference count on the object to become zero while in the I/O 00968 // system's special kernel APC routine). Therefore, a special kernel APC 00969 // cannot be used since it cannot execute until the close APC finishes. 00970 // 00971 // The special steps are as follows for a synchronous paging operation 00972 // and close are: 00973 // 00974 // 1. Copy the I/O status block (it is in SVAS, nonpaged). 00975 // 2. Signal the event 00976 // 3. If paging I/O, deallocate the IRP 00977 // 00978 // The special steps taken for asynchronous paging operations (out-pages) 00979 // are as follows: 00980 // 00981 // 1. Initialize a special kernel APC just for page writes. 00982 // 1. Queue the special kernel APC. 00983 // 00984 // It should also be noted that the logic for completing a Mount request 00985 // operation is exactly the same as a Page Read. No assumptions should be 00986 // made here about this being a Page Read operation w/o carefully checking 00987 // to ensure that they are also true for a Mount. That is: 00988 // 00989 // IRP_PAGING_IO and IRP_MOUNT_COMPLETION 00990 // 00991 // are the same flag in the IRP. 00992 // 00993 // Also note that the last time the IRP is touched for a close operation 00994 // must be just before the event is set to the signaled state. Once this 00995 // occurs, the IRP can be deallocated by the thread waiting for the event. 00996 // 00997 00998 if (Irp->Flags & (IRP_PAGING_IO | IRP_CLOSE_OPERATION)) { 00999 if (Irp->Flags & (IRP_SYNCHRONOUS_PAGING_IO | IRP_CLOSE_OPERATION)) { 01000 ULONG flags; 01001 01002 flags = Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO; 01003 *Irp->UserIosb = Irp->IoStatus; 01004 (VOID) KeSetEvent( Irp->UserEvent, PriorityBoost, FALSE ); 01005 if (flags) { 01006 IoFreeIrp( Irp ); 01007 } 01008 } else { 01009 thread = Irp->Tail.Overlay.Thread; 01010 KeInitializeApc( &Irp->Tail.Apc, 01011 &thread->Tcb, 01012 Irp->ApcEnvironment, 01013 IopCompletePageWrite, 01014 (PKRUNDOWN_ROUTINE) NULL, 01015 (PKNORMAL_ROUTINE) NULL, 01016 KernelMode, 01017 (PVOID) NULL ); 01018 (VOID) KeInsertQueueApc( &Irp->Tail.Apc, 01019 (PVOID) NULL, 01020 (PVOID) NULL, 01021 PriorityBoost ); 01022 } 01023 return; 01024 } 01025 01026 // 01027 // Check to see whether any pages need to be unlocked. 01028 // 01029 01030 if (Irp->MdlAddress != NULL) { 01031 01032 // 01033 // Unlock any pages that may be described by MDLs. 01034 // 01035 01036 mdl = Irp->MdlAddress; 01037 while (mdl != NULL) { 01038 MmUnlockPages( mdl ); 01039 mdl = mdl->Next; 01040 } 01041 } 01042 01043 // 01044 // Make a final check here to determine whether or not this is a 01045 // synchronous I/O operation that is being completed in the context 01046 // of the original requestor. If so, then an optimal path through 01047 // I/O completion can be taken. 01048 // 01049 01050 if (Irp->Flags & IRP_DEFER_IO_COMPLETION && !Irp->PendingReturned) { 01051 01052 if ((Irp->IoStatus.Status == STATUS_REPARSE ) && 01053 (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)) { 01054 01055 // 01056 // For name junctions we reinstate the address of the appropriate 01057 // buffer. It is freed in parse.c 01058 // 01059 01060 Irp->Tail.Overlay.AuxiliaryBuffer = saveAuxiliaryPointer; 01061 } 01062 01063 return; 01064 } 01065 01066 // 01067 // Finally, initialize the IRP as an APC structure and queue the special 01068 // kernel APC to the target thread. 01069 // 01070 01071 thread = Irp->Tail.Overlay.Thread; 01072 fileObject = Irp->Tail.Overlay.OriginalFileObject; 01073 01074 if (!Irp->Cancel) { 01075 01076 KeInitializeApc( &Irp->Tail.Apc, 01077 &thread->Tcb, 01078 Irp->ApcEnvironment, 01079 IopCompleteRequest, 01080 IopAbortRequest, 01081 (PKNORMAL_ROUTINE) NULL, 01082 KernelMode, 01083 (PVOID) NULL ); 01084 01085 (VOID) KeInsertQueueApc( &Irp->Tail.Apc, 01086 fileObject, 01087 (PVOID) saveAuxiliaryPointer, 01088 PriorityBoost ); 01089 } else { 01090 01091 // 01092 // This request has been cancelled. Ensure that access to the thread 01093 // is synchronized, otherwise it may go away while attempting to get 01094 // through the remainder of completion for this request. This happens 01095 // when the thread times out waiting for the request to be completed 01096 // once it has been cancelled. 01097 // 01098 // Note that it is safe to capture the thread pointer above, w/o having 01099 // the lock because the cancel flag was not set at that point, and 01100 // the code that disassociates IRPs must set the flag before looking to 01101 // see whether or not the packet has been completed, and this packet 01102 // will appear to be completed because it no longer belongs to a driver. 01103 // 01104 01105 ExAcquireSpinLock( &IopCompletionLock, &irql ); 01106 01107 thread = Irp->Tail.Overlay.Thread; 01108 01109 if (thread) { 01110 01111 KeInitializeApc( &Irp->Tail.Apc, 01112 &thread->Tcb, 01113 Irp->ApcEnvironment, 01114 IopCompleteRequest, 01115 IopAbortRequest, 01116 (PKNORMAL_ROUTINE) NULL, 01117 KernelMode, 01118 (PVOID) NULL ); 01119 01120 (VOID) KeInsertQueueApc( &Irp->Tail.Apc, 01121 fileObject, 01122 (PVOID) saveAuxiliaryPointer, 01123 PriorityBoost ); 01124 01125 ExReleaseSpinLock( &IopCompletionLock, irql ); 01126 01127 } else { 01128 01129 // 01130 // This request has been aborted from completing in the caller's 01131 // thread. This can only occur if the packet was cancelled, and 01132 // the driver did not complete the request, so it was timed out. 01133 // Attempt to drop things on the floor, since the originating thread 01134 // has probably exited at this point. 01135 // 01136 01137 ExReleaseSpinLock( &IopCompletionLock, irql ); 01138 01139 ASSERT( Irp->Cancel ); 01140 01141 // 01142 // Drop the IRP on the floor. 01143 // 01144 01145 IopDropIrp( Irp, fileObject ); 01146 01147 } 01148 } 01149 #else 01150 01151 IopfCompleteRequest(Irp, PriorityBoost); 01152 return; 01153 01154 #endif 01155 }

THUNKED_API PVOID VerifierAllocatePoolWithQuotaTag IN POOL_TYPE  PoolType,
IN SIZE_T  NumberOfBytes,
IN ULONG  Tag
 

Definition at line 1059 of file verifier.c.

References ExAllocatePoolWithQuotaTag, ExRaiseStatus(), FALSE, _MI_VERIFIER_DRIVER_ENTRY::Flags, HighPoolPriority, KernelVerifier, NULL, POOL_DRIVER_MASK, POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, RtlGetCallersAddress(), TRUE, VeAllocatePoolWithTagPriority(), VI_VERIFYING_DIRECTLY, and ViLocateVerifierEntry().

01064 { 01065 PVOID Va; 01066 LOGICAL RaiseOnQuotaFailure; 01067 PVOID CallingAddress; 01068 PVOID CallersCaller; 01069 PMI_VERIFIER_DRIVER_ENTRY Verifier; 01070 01071 #if defined (_X86_) 01072 RtlGetCallersAddress(&CallingAddress, &CallersCaller); 01073 #else 01074 CallingAddress = (PVOID)_ReturnAddress(); 01075 #endif 01076 01077 if (KernelVerifier == TRUE) { 01078 Verifier = ViLocateVerifierEntry (CallingAddress); 01079 01080 if ((Verifier == NULL) || 01081 ((Verifier->Flags & VI_VERIFYING_DIRECTLY) == 0)) { 01082 01083 return ExAllocatePoolWithQuotaTag (PoolType | POOL_DRIVER_MASK, 01084 NumberOfBytes, 01085 Tag); 01086 } 01087 PoolType |= POOL_DRIVER_MASK; 01088 } 01089 01090 if (PoolType & POOL_QUOTA_FAIL_INSTEAD_OF_RAISE) { 01091 RaiseOnQuotaFailure = FALSE; 01092 PoolType &= ~POOL_QUOTA_FAIL_INSTEAD_OF_RAISE; 01093 } 01094 else { 01095 RaiseOnQuotaFailure = TRUE; 01096 } 01097 01098 Va = VeAllocatePoolWithTagPriority (PoolType, 01099 NumberOfBytes, 01100 Tag, 01101 HighPoolPriority, 01102 CallingAddress); 01103 01104 if (Va == NULL) { 01105 if (RaiseOnQuotaFailure == TRUE) { 01106 ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES); 01107 } 01108 } 01109 01110 return Va; 01111 }


Variable Documentation

BOOLEAN IopVerifierOn = FALSE
 

Definition at line 82 of file ioverifier.c.

Referenced by IoCancelIrp(), IovCallDriver(), IovCompleteRequest(), IoVerifierInit(), IovFreeIrpPrivate(), and IovSpecialIrpCallDriver().

BOOLEAN IoVerifierOnByDefault = TRUE
 

Definition at line 85 of file ioverifier.c.

Referenced by IoVerifierInit().

ULONG IovpEnforcementLevel = (ULONG) -1
 

Definition at line 83 of file ioverifier.c.

LONG IovpInitCalled = 0
 

Definition at line 86 of file ioverifier.c.

Referenced by IopDriverCorrectnessTakeLock(), and IoVerifierInit().

ULONG IovpMaxSupportedVerifierLevel = 3
 

Definition at line 87 of file ioverifier.c.

Referenced by IoVerifierInit().

ULONG IovpVerifierFlags = 0
 

Definition at line 88 of file ioverifier.c.

Referenced by IovAllocateIrp(), and IoVerifierInit().

ULONG IovpVerifierLevel = (ULONG)0
 

Definition at line 84 of file ioverifier.c.


Generated on Sat May 15 19:44:23 2004 for test by doxygen 1.3.7