diff options
Diffstat (limited to 'filesys/fastfat/deviosup.c')
| -rw-r--r-- | filesys/fastfat/deviosup.c | 119 |
1 files changed, 110 insertions, 9 deletions
diff --git a/filesys/fastfat/deviosup.c b/filesys/fastfat/deviosup.c index ee46c016..5802722d 100644 --- a/filesys/fastfat/deviosup.c +++ b/filesys/fastfat/deviosup.c @@ -1042,7 +1042,7 @@ Return Value: // that this will be only a single page. // - if (MmGetSystemAddressForMdlSafe( Mdl, NormalPagePriority ) == NULL) { + if (MmGetSystemAddressForMdlSafe( Mdl, NormalPagePriority | MdlMappingNoExecute ) == NULL) { FatRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); } @@ -1874,6 +1874,12 @@ Return Value: } // + // Back up a copy of the IrpContext flags for later use in async completion. + // + + Context->IrpContextFlags = IrpContext->Flags; + + // // Now that all the dangerous work is done, issue the read requests // @@ -2095,6 +2101,12 @@ Return Value: } // + // Back up a copy of the IrpContext flags for later use in async completion. + // + + IrpContext->FatIoContext->IrpContextFlags = IrpContext->Flags; + + // // Issue the read request // @@ -2419,7 +2431,11 @@ Return Value: if (!NT_SUCCESS( Irp->IoStatus.Status )) { - NT_ASSERT( NT_SUCCESS( FatAssertNotStatus ) || Irp->IoStatus.Status != FatAssertNotStatus ); +#if DBG + if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) { + DbgBreakPoint(); + } +#endif #ifdef SYSCACHE_COMPILE DbgPrint( "FAT SYSCACHE: MultiSync (IRP %08x for Master %08x) -> %08x\n", Irp, MasterIrp, Irp->IoStatus ); @@ -2503,9 +2519,10 @@ Return Value: --*/ { - + NTSTATUS Status = STATUS_SUCCESS; PFAT_IO_CONTEXT Context = Contxt; PIRP MasterIrp = Context->MasterIrp; + BOOLEAN PostRequest = FALSE; DebugTrace(+1, Dbg, "FatMultiAsyncCompletionRoutine, Context = %p\n", Context ); @@ -2515,7 +2532,11 @@ Return Value: if (!NT_SUCCESS( Irp->IoStatus.Status )) { - NT_ASSERT( NT_SUCCESS( FatAssertNotStatus ) || Irp->IoStatus.Status != FatAssertNotStatus ); +#if DBG + if (!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) { + DbgBreakPoint(); + } +#endif #ifdef SYSCACHE_COMPILE DbgPrint( "FAT SYSCACHE: MultiAsync (IRP %08x for Master %08x) -> %08x\n", Irp, MasterIrp, Irp->IoStatus ); @@ -2548,6 +2569,19 @@ Return Value: IoGetCurrentIrpStackLocation(MasterIrp)->MajorFunction == IRP_MJ_READ ? FO_FILE_FAST_IO_READ : FO_FILE_MODIFIED ); } + + } else { + + // + // Post STATUS_VERIFY_REQUIRED failures. Only post top level IRPs, because recursive I/Os + // cannot process volume verification. + // + + if (!FlagOn(Context->IrpContextFlags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) && + (MasterIrp->IoStatus.Status == STATUS_VERIFY_REQUIRED)) { + PostRequest = TRUE; + } + } // @@ -2594,13 +2628,35 @@ Return Value: // ExFreePool( Context ); + + if (PostRequest) { + + PIRP_CONTEXT IrpContext = NULL; + + try { + + IrpContext = FatCreateIrpContext(Irp, TRUE ); + ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL); + FatFsdPostRequest( IrpContext, Irp ); + Status = STATUS_MORE_PROCESSING_REQUIRED; + + } except( FatExceptionFilter(NULL, GetExceptionInformation()) ) { + + // + // If we failed to post the IRP, we just have to return the failure + // to the user. :( + // + + NOTHING; + } + } } DebugTrace(-1, Dbg, "FatMultiAsyncCompletionRoutine -> SUCCESS\n", 0 ); UNREFERENCED_PARAMETER( DeviceObject ); - return STATUS_SUCCESS; + return Status; } @@ -2984,7 +3040,12 @@ Return Value: if (!NT_SUCCESS( Irp->IoStatus.Status )) { - NT_ASSERT( NT_SUCCESS( FatAssertNotStatus ) || Irp->IoStatus.Status != FatAssertNotStatus ); +#if DBG + if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) { + DbgBreakPoint(); + } +#endif + } NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 )); @@ -3042,7 +3103,10 @@ Return Value: --*/ { + NTSTATUS Status = STATUS_SUCCESS; + PFAT_IO_CONTEXT Context = Contxt; + BOOLEAN PostRequest = FALSE; DebugTrace(+1, Dbg, "FatSingleAsyncCompletionRoutine, Context = %p\n", Context ); @@ -3071,12 +3135,26 @@ Return Value: } else { - NT_ASSERT( NT_SUCCESS( FatAssertNotStatus ) || Irp->IoStatus.Status != FatAssertNotStatus ); +#if DBG + if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) { + DbgBreakPoint(); + } +#endif #ifdef SYSCACHE_COMPILE DbgPrint( "FAT SYSCACHE: SingleAsync (IRP %08x) -> %08x\n", Irp, Irp->IoStatus ); #endif + // + // Post STATUS_VERIFY_REQUIRED failures. Only post top level IRPs, because recursive I/Os + // cannot process volume verification. + // + + if (!FlagOn(Context->IrpContextFlags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) && + (Irp->IoStatus.Status == STATUS_VERIFY_REQUIRED)) { + PostRequest = TRUE; + } + } // @@ -3125,11 +3203,34 @@ Return Value: ExFreePool( Context ); + if (PostRequest) { + + PIRP_CONTEXT IrpContext = NULL; + + try { + + IrpContext = FatCreateIrpContext(Irp, TRUE ); + ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL); + FatFsdPostRequest( IrpContext, Irp ); + Status = STATUS_MORE_PROCESSING_REQUIRED; + + } except( FatExceptionFilter(NULL, GetExceptionInformation()) ) { + + // + // If we failed to post the IRP, we just have to return the failure + // to the user. :( + // + + NOTHING; + } + } + + DebugTrace(-1, Dbg, "FatSingleAsyncCompletionRoutine -> STATUS_MORE_PROCESSING_REQUIRED\n", 0 ); UNREFERENCED_PARAMETER( DeviceObject ); - return STATUS_SUCCESS; + return Status; } @@ -3256,7 +3357,7 @@ Return Value: } else { - PVOID Address = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority ); + PVOID Address = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute ); if (Address == NULL) { |
