📄 read.c
字号:
} else {
MappingFileObject = IrpSp->FileObject;
}
//
// Handle the non-cached read first.
//
if (NonCachedIo) {
//
// If we have an unaligned transfer then post this request if
// we can't wait. Unaligned means that the starting offset
// is not on a sector boundary or the read is not integral
// sectors.
//
ReadByteCount = SectorAlign( Vcb, ByteCount );
if (SectorOffset( Vcb, StartingOffset ) ||
(ReadByteCount > OriginalByteCount)) {
if (!Wait) {
UdfRaiseStatus( IrpContext, STATUS_CANT_WAIT );
}
//
// Make sure we don't overwrite the buffer.
//
ReadByteCount = ByteCount;
}
//
// Initialize the IoContext for the read.
// If there is a context pointer, we need to make sure it was
// allocated and not a stale stack pointer.
//
if (IrpContext->IoContext == NULL ||
!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) {
//
// If we can wait, use the context on the stack. Otherwise
// we need to allocate one.
//
if (Wait) {
IrpContext->IoContext = &LocalIoContext;
ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
} else {
IrpContext->IoContext = UdfAllocateIoContext();
SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
}
}
RtlZeroMemory( IrpContext->IoContext, sizeof( UDF_IO_CONTEXT ));
//
// Store whether we allocated this context structure in the structure
// itself.
//
IrpContext->IoContext->AllocatedContext =
BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO );
if (Wait) {
KeInitializeEvent( &IrpContext->IoContext->SyncEvent,
NotificationEvent,
FALSE );
} else {
IrpContext->IoContext->ResourceThreadId = ExGetCurrentResourceThread();
IrpContext->IoContext->Resource = Fcb->Resource;
IrpContext->IoContext->RequestedByteCount = ByteCount;
}
Irp->IoStatus.Information = ReadByteCount;
//
// Call the NonCacheIo routine to perform the actual read.
//
Status = UdfNonCachedRead( IrpContext, Fcb, StartingOffset, ReadByteCount );
//
// Don't complete this request now if STATUS_PENDING was returned.
//
if (Status == STATUS_PENDING) {
Irp = NULL;
ReleaseFile = FALSE;
//
// Test is we should zero part of the buffer or update the
// synchronous file position.
//
} else {
//
// Convert any unknown error code to IO_ERROR.
//
if (!NT_SUCCESS( Status )) {
//
// Set the information field to zero.
//
Irp->IoStatus.Information = 0;
//
// Raise if this is a user induced error.
//
if (IoIsErrorUserInduced( Status )) {
UdfRaiseStatus( IrpContext, Status );
}
Status = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR );
//
// Check if there is any portion of the user's buffer to zero.
//
} else if (ReadByteCount != ByteCount) {
UdfMapUserBuffer( IrpContext, &UserBuffer );
SafeZeroMemory( IrpContext,
Add2Ptr( UserBuffer,
ByteCount,
PVOID ),
ReadByteCount - ByteCount );
Irp->IoStatus.Information = ByteCount;
}
//
// Update the file position if this is a synchronous request.
//
if (SynchronousIo && !PagingIo && NT_SUCCESS( Status )) {
IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange;
}
}
try_leave( NOTHING );
}
//
// Handle the cached case. Start by initializing the private
// cache map.
//
if (MappingFileObject->PrivateCacheMap == NULL) {
//
// The metadata Fcb stream was fired up before any data read. We should never
// see it here.
//
ASSERT( MappingFileObject != Vcb->MetadataFcb->FileObject );
//
// Now initialize the cache map.
//
CcInitializeCacheMap( IrpSp->FileObject,
(PCC_FILE_SIZES) &Fcb->AllocationSize,
FALSE,
&UdfData.CacheManagerCallbacks,
Fcb );
CcSetReadAheadGranularity( IrpSp->FileObject, READ_AHEAD_GRANULARITY );
}
//
// Read from the cache if this is not an Mdl read.
//
if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) {
//
// If we are in the Fsp now because we had to wait earlier,
// we must map the user buffer, otherwise we can use the
// user's buffer directly.
//
UdfMapUserBuffer( IrpContext, &SystemBuffer);
//
// Now try to do the copy.
//
if (!CcCopyRead( MappingFileObject,
(PLARGE_INTEGER) &StartingOffset,
ByteCount,
Wait,
SystemBuffer,
&Irp->IoStatus )) {
try_leave( Status = STATUS_CANT_WAIT );
}
//
// If the call didn't succeed, raise the error status
//
if (!NT_SUCCESS( Irp->IoStatus.Status )) {
UdfNormalizeAndRaiseStatus( IrpContext, Irp->IoStatus.Status );
}
Status = Irp->IoStatus.Status;
//
// Otherwise perform the MdlRead operation.
//
} else {
CcMdlRead( MappingFileObject,
(PLARGE_INTEGER) &StartingOffset,
ByteCount,
&Irp->MdlAddress,
&Irp->IoStatus );
Status = Irp->IoStatus.Status;
}
//
// Update the current file position in the user file object.
//
if (SynchronousIo && !PagingIo && NT_SUCCESS( Status )) {
IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange;
}
} finally {
DebugUnwind( "UdfCommonRead" );
//
// Release the Fcb.
//
if (ReleaseFile) {
UdfReleaseFile( IrpContext, Fcb );
}
}
//
// Post the request if we got CANT_WAIT.
//
if (Status == STATUS_CANT_WAIT) {
Status = UdfFsdPostRequest( IrpContext, Irp );
//
// Otherwise complete the request.
//
} else {
UdfCompleteRequest( IrpContext, Irp, Status );
}
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -