⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read.c

📁 windows 2000中的UDF文件系统的驱动程序.只有读的功能,不支持未关闭的盘片.只支持UDF2.0以下版本,不支持VAT格式的UDF.
💻 C
📖 第 1 页 / 共 2 页
字号:
        } 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 + -