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

📄 deviosup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
                                    IrpContext->Irp,
                                    Fcb,
                                    UserBuffer,
                                    UserBufferOffset,
                                    CurrentOffset,
                                    RemainingByteCount,
                                    IoRuns,
                                    &CleanupRunCount,
                                    &ThisByteCount );
            }
            
            //
            //  Perform multiple Io to read in the data.  Note that
            //  there may be no Io to do if we were able to use an
            //  existing buffer from the Vcb.
            //

            if (CleanupRunCount != 0) {

                RunCount = CleanupRunCount;

                CdMultipleXAAsync( IrpContext,
                                   RunCount,
                                   IoRuns,
                                   RawReads,
                                   TrackMode );
                //
                //  Wait for the request to complete.
                //

                CdWaitSync( IrpContext );

                Status = IrpContext->Irp->IoStatus.Status;

                //
                //  Exit this loop if there is an error.
                //

                if (!NT_SUCCESS( Status )) {

                    if (!TryingYellowbookMode2 && 
                        FlagOn( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE )) {

                        //
                        //  There are wacky cases where someone has mastered as CD-XA
                        //  but the sectors they claim are Mode2Form2 are really, according
                        //  to ATAPI devices, Yellowbook Mode2. We will try once more
                        //  with these. Kodak PHOTO-CD has been observed to do this.
                        //

                        TryingYellowbookMode2 = TRUE;
                        TrackMode = YellowMode2;
                        
                        //
                        //  Clear our 'cumulative' error status value
                        //
                        
                        IrpContext->IoContext->Status = STATUS_SUCCESS;

                        continue;
                    }

                    try_return( NOTHING );
                }
                
                CleanupRunCount = 0;
                
                if (TryingYellowbookMode2) {

                    //
                    //  We succesfully got data when we tried switching the trackmode,
                    //  so change the state of the FCB to remember that.
                    //

                    SetFlag( Fcb->FcbState, FCB_STATE_MODE2_FILE );
                    ClearFlag( Fcb->FcbState, FCB_STATE_MODE2FORM2_FILE );

                    TryingYellowbookMode2 = FALSE;
                }

                //
                //  Perform post read operations on the IoRuns if
                //  necessary.
                //

                CdFinishBuffers( IrpContext, IoRuns, RunCount, FALSE, TRUE );
            }

            //
            //  Adjust our loop variants.
            //

            RemainingByteCount -= ThisByteCount;
            CurrentOffset += ThisByteCount;
            UserBuffer = Add2Ptr( UserBuffer, ThisByteCount, PVOID );
            UserBufferOffset += ThisByteCount;
        }

        //
        //  Always flush the hardware cache.
        //

        KeFlushIoBuffers( IrpContext->Irp->MdlAddress, TRUE, FALSE );

    try_exit:  NOTHING;
    } finally {

        //
        //  Perform final cleanup on the IoRuns if necessary.
        //

        if (CleanupRunCount != 0) {

            CdFinishBuffers( IrpContext, IoRuns, CleanupRunCount, TRUE, FALSE );
        }
    }

    return Status;
}


BOOLEAN
CdReadSectors (
    IN PIRP_CONTEXT IrpContext,
    IN LONGLONG StartingOffset,
    IN ULONG ByteCount,
    IN BOOLEAN ReturnError,
    IN OUT PVOID Buffer,
    IN PDEVICE_OBJECT TargetDeviceObject
    )

/*++

Routine Description:

    This routine is called to transfer sectors from the disk to a
    specified buffer.  It is used for mount and volume verify operations.

    This routine is synchronous, it will not return until the operation
    is complete or until the operation fails.

    The routine allocates an IRP and then passes this IRP to a lower
    level driver.  Errors may occur in the allocation of this IRP or
    in the operation of the lower driver.

Arguments:

    StartingOffset - Logical offset on the disk to start the read.  This
        must be on a sector boundary, no check is made here.

    ByteCount - Number of bytes to read.  This is an integral number of
        2K sectors, no check is made here to confirm this.

    ReturnError - Indicates whether we should return TRUE or FALSE
        to indicate an error or raise an error condition.  This only applies
        to the result of the IO.  Any other error may cause a raise.

    Buffer - Buffer to transfer the disk data into.

    TargetDeviceObject - The device object for the volume to be read.

Return Value:

    BOOLEAN - Depending on 'RaiseOnError' flag above.  TRUE if operation
              succeeded, FALSE otherwise.

--*/

{
    NTSTATUS Status;
    KEVENT  Event;
    PIRP Irp;

    PAGED_CODE();

    //
    //  Initialize the event.
    //

    KeInitializeEvent( &Event, NotificationEvent, FALSE );

    //
    //  Attempt to allocate the IRP.  If unsuccessful, raise
    //  STATUS_INSUFFICIENT_RESOURCES.
    //

    Irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ,
                                        TargetDeviceObject,
                                        Buffer,
                                        ByteCount,
                                        (PLARGE_INTEGER) &StartingOffset,
                                        &Event,
                                        &IrpContext->Irp->IoStatus );

    if (Irp == NULL) {

        CdRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES );
    }

    //
    //  Ignore the change line (verify) for mount and verify requests
    //

    SetFlag( IoGetNextIrpStackLocation( Irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME );

    //
    //  Send the request down to the driver.  If an error occurs return
    //  it to the caller.
    //

    Status = IoCallDriver( TargetDeviceObject, Irp );

    //
    //  If the status was STATUS_PENDING then wait on the event.
    //

    if (Status == STATUS_PENDING) {

        Status = KeWaitForSingleObject( &Event,
                                        Executive,
                                        KernelMode,
                                        FALSE,
                                        NULL );

        //
        //  On a successful wait pull the status out of the IoStatus block.
        //

        if (NT_SUCCESS( Status )) {

            Status = IrpContext->Irp->IoStatus.Status;
        }
    }

    //
    //  Check whether we should raise in the error case.
    //

    if (!NT_SUCCESS( Status )) {

        if (!ReturnError) {

            CdNormalizeAndRaiseStatus( IrpContext, Status );
        }

        //
        //  We don't raise, but return FALSE to indicate an error.
        //

        return FALSE;

    //
    //  The operation completed successfully.
    //

    } else {

        return TRUE;
    }
}


NTSTATUS
CdCreateUserMdl (
    IN PIRP_CONTEXT IrpContext,
    IN ULONG BufferLength,
    IN BOOLEAN RaiseOnError
    )

/*++

Routine Description:

    This routine locks the specified buffer for read access (we only write into
    the buffer).  The file system requires this routine since it does not
    ask the I/O system to lock its buffers for direct I/O.  This routine
    may only be called from the Fsd while still in the user context.

    This routine is only called if there is not already an Mdl.

Arguments:

    BufferLength - Length of user buffer.

    RaiseOnError - Indicates if our caller wants this routine to raise on
        an error condition.

Return Value:

    NTSTATUS - Status from this routine.  Error status only returned if
        RaiseOnError is FALSE.

--*/

{
    NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
    PMDL Mdl;

    PAGED_CODE();

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_IRP( IrpContext->Irp );
    ASSERT( IrpContext->Irp->MdlAddress == NULL );

    //
    // Allocate the Mdl, and Raise if we fail.
    //

    Mdl = IoAllocateMdl( IrpContext->Irp->UserBuffer,
                         BufferLength,
                         FALSE,
                         FALSE,
                         IrpContext->Irp );

    if (Mdl != NULL) {

        //
        //  Now probe the buffer described by the Irp.  If we get an exception,
        //  deallocate the Mdl and return the appropriate "expected" status.
        //

        try {

            MmProbeAndLockPages( Mdl, IrpContext->Irp->RequestorMode, IoWriteAccess );

            Status = STATUS_SUCCESS;

        } except(EXCEPTION_EXECUTE_HANDLER) {

            Status = GetExceptionCode();

            IoFreeMdl( Mdl );
            IrpContext->Irp->MdlAddress = NULL;

            if (!FsRtlIsNtstatusExpected( Status )) {

                Status = STATUS_INVALID_USER_BUFFER;
            }
        }
    }

    //
    //  Check if we are to raise or return
    //

    if (Status != STATUS_SUCCESS) {

        if (RaiseOnError) {

            CdRaiseStatus( IrpContext, Status );
        }
    }

    //
    //  Return the status code.
    //

    return Status;
}


NTSTATUS
CdPerformDevIoCtrlEx (
    IN PIRP_CONTEXT IrpContext,
    IN ULONG IoControlCode,
    IN PDEVICE_OBJECT Device,
    IN OPTIONAL PVOID InputBuffer,
    IN ULONG InputBufferLength,
    OUT OPTIONAL PVOID OutputBuffer,
    IN ULONG OutputBufferLength,
    IN BOOLEAN InternalDeviceIoControl,
    IN BOOLEAN OverrideVerify,
    OUT OPTIONAL PIO_STATUS_BLOCK Iosb
    )

/*++

Routine Description:

    This routine is called to perform DevIoCtrl functions internally within
    the filesystem.  We take the status from the driver and return it to our
    caller.

Arguments:

    IoControlCode - Code to send to driver.

    Device - This is the device to send the request to.

    OutPutBuffer - Pointer to output buffer.

    OutputBufferLength - Length of output buffer above.

    InternalDeviceIoControl - Indicates if this is an internal or external
        Io control code.

    OverrideVerify - Indicates if we should tell the driver not to return
        STATUS_VERIFY_REQUIRED for mount and verify.

    Iosb - If specified, we return the results of the operation here.

Return Value:

    NTSTATUS - Status returned by next lower driver.

--*/

{
    NTSTATUS Status;
    PIRP Irp;
    KEVENT Event;
    IO_STATUS_BLOCK LocalIosb;
    PIO_STATUS_BLOCK IosbToUse = &LocalIosb;

    PAGED_CODE();

    //
    //  Check if the user gave us an Iosb.
    //

    if (ARGUMENT_PRESENT( Iosb )) {

        IosbToUse = Iosb;
    }

    IosbToUse->Status = 0;
    IosbToUse->Information = 0;

    KeInitializeEvent( &Event, NotificationEvent, FALSE );

    Irp = IoBuildDeviceIoControlRequest( IoControlCode,
                                         Device,
                                         InputBuffer,
                                         InputBufferLength,
                                         OutputBuffer,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -