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

📄 pnp.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
字号:
/*
 * COPYRIGHT:        GNU GENERAL PUBLIC LICENSE VERSION 2
 * PROJECT:          ReiserFs file system driver for Windows NT/2000/XP/Vista.
 * FILE:             pnp.c
 * PURPOSE:          
 * PROGRAMMER:       Mark Piper, Matt Wu, Bo Brant閚.
 * HOMEPAGE:         
 * UPDATE HISTORY: 
 */

#if (_WIN32_WINNT >= 0x0500)

/* INCLUDES *****************************************************************/

#include "rfsd.h"

/* GLOBALS ***************************************************************/

extern PRFSD_GLOBAL RfsdGlobal;

/* DEFINITIONS *************************************************************/

#define DBG_PNP DBG_USER

NTSTATUS
RfsdPnpCompletionRoutine (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp,
    IN PVOID          Contxt     );


#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, RfsdPnp)
#pragma alloc_text(PAGE, RfsdPnpQueryRemove)
#pragma alloc_text(PAGE, RfsdPnpRemove)
#pragma alloc_text(PAGE, RfsdPnpCancelRemove)
#pragma alloc_text(PAGE, RfsdPnpSurpriseRemove)
#endif


/* FUNCTIONS *************************************************************/

NTSTATUS
RfsdPnpCompletionRoutine (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Contxt
    )
{
    PKEVENT Event = (PKEVENT) Contxt;

    KeSetEvent( Event, 0, FALSE );

    return STATUS_MORE_PROCESSING_REQUIRED;

    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( Contxt );
}


NTSTATUS
RfsdPnp (IN PRFSD_IRP_CONTEXT IrpContext)
{
    NTSTATUS            Status = STATUS_INVALID_PARAMETER;

    PIRP                Irp;
    PIO_STACK_LOCATION  IrpSp;
    PRFSD_VCB           Vcb;
    PDEVICE_OBJECT      DeviceObject;

    __try {

        ASSERT(IrpContext);
        
        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
            (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;
    
        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);

        if ( !((Vcb->Identifier.Type == RFSDVCB) &&
               (Vcb->Identifier.Size == sizeof(RFSD_VCB)))) {
            __leave; // Status = STATUS_INVALID_PARAMETER
        }
        
        Irp = IrpContext->Irp;
        IrpSp = IoGetCurrentIrpStackLocation(Irp);

        SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
   
        switch ( IrpSp->MinorFunction ) {

            case IRP_MN_QUERY_REMOVE_DEVICE:

                RfsdPrint((DBG_PNP, "RfsdPnp: RfsdPnpQueryRemove...\n"));
                Status = RfsdPnpQueryRemove(IrpContext, Vcb);

                break;
        
            case IRP_MN_REMOVE_DEVICE:

                RfsdPrint((DBG_PNP, "RfsdPnp: RfsdPnpRemove...\n"));
                Status = RfsdPnpRemove(IrpContext, Vcb);
                break;

            case IRP_MN_CANCEL_REMOVE_DEVICE:
    
                RfsdPrint((DBG_PNP, "RfsdPnp: RfsdPnpCancelRemove...\n"));
                Status = RfsdPnpCancelRemove(IrpContext, Vcb);
                break;

            case IRP_MN_SURPRISE_REMOVAL:
        
                RfsdPrint((DBG_PNP, "RfsdPnp: RfsdPnpSupriseRemove...\n"));
                Status = RfsdPnpSurpriseRemove(IrpContext, Vcb);
                break;

            default:
                break;
        }

    } __finally {

        if (!IrpContext->ExceptionInProgress) {
            Irp = IrpContext->Irp;

            if (Irp) {

                //
                // Here we need pass the IRP to the disk driver.
                //

                IoSkipCurrentIrpStackLocation( Irp );
    
                Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);

                IrpContext->Irp = NULL;
            }

            RfsdCompleteIrpContext(IrpContext, Status);
        }
    }
        
    return Status;
}

   
NTSTATUS
RfsdPnpQueryRemove (
    PRFSD_IRP_CONTEXT IrpContext,
    PRFSD_VCB         Vcb
    )

{
    NTSTATUS Status;
    KEVENT   Event;
    BOOLEAN  bDeleted = FALSE;
    BOOLEAN  VcbAcquired = FALSE;

    __try {

        RfsdPrint((DBG_PNP, "RfsdPnpQueryRemove by RfsdPnp ...\n"));

        RfsdPrint((DBG_PNP, "RfsdPnpQueryRemove: RfsdFlushVolume ...\n"));

#if (_WIN32_WINNT >= 0x0500)
        CcWaitForCurrentLazyWriterActivity();
#endif

        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource, TRUE );
        VcbAcquired = TRUE;

        RfsdFlushFiles(Vcb, FALSE);

        RfsdFlushVolume(Vcb, FALSE);

        RfsdPrint((DBG_PNP, "RfsdPnpQueryRemove: RfsdLockVcb: Vcb=%xh FileObject=%xh ...\n",
                            Vcb, IrpContext->FileObject));
        Status = RfsdLockVcb(Vcb, IrpContext->FileObject);

        RfsdPrint((DBG_PNP, "RfsdPnpQueryRemove: RfsdPurgeVolume ...\n"));
        RfsdPurgeVolume(Vcb, TRUE);

        if (!NT_SUCCESS(Status)) {
            __leave;
        }

        ExReleaseResourceForThreadLite(
            &Vcb->MainResource,
            ExGetCurrentResourceThread() );
        VcbAcquired = FALSE;

        IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);

        KeInitializeEvent( &Event, NotificationEvent, FALSE );
        IoSetCompletionRoutine( IrpContext->Irp,
                                RfsdPnpCompletionRoutine,
                                &Event,
                                TRUE,
                                TRUE,
                                TRUE );

        RfsdPrint((DBG_PNP, "RfsdPnpQueryRemove: Call lower level driver...\n"));
        Status = IoCallDriver( Vcb->TargetDeviceObject, 
                                   IrpContext->Irp);

        if (Status == STATUS_PENDING) {

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

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

        if (NT_SUCCESS(Status)) {
            RfsdPrint((DBG_PNP, "RfsdPnpQueryRemove: RfsdCheckDismount ...\n"));
            bDeleted = RfsdCheckDismount(IrpContext, Vcb, TRUE);
            RfsdPrint((DBG_PNP, "RfsdPnpQueryRemove: RfsdFlushVolume bDelted=%xh ...\n", bDeleted));
        }

        ASSERT( !(NT_SUCCESS(Status) && !bDeleted));

    } __finally {

        if (VcbAcquired) {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread() );
        }

        RfsdCompleteRequest(
            IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)?
            IO_DISK_INCREMENT : IO_NO_INCREMENT) );

        IrpContext->Irp = NULL;
    }
    
    return Status;
}

NTSTATUS
RfsdPnpRemove (
    PRFSD_IRP_CONTEXT IrpContext,
    PRFSD_VCB         Vcb      )
{
    NTSTATUS Status;
    KEVENT   Event;
    BOOLEAN  bDeleted;

    __try {

        RfsdPrint((DBG_PNP, "RfsdPnpRemove by RfsdPnp ...\n"));
#if (_WIN32_WINNT >= 0x0500)
        CcWaitForCurrentLazyWriterActivity();
#endif
        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource,  TRUE );

        Status = RfsdLockVcb(Vcb, IrpContext->FileObject);

        ExReleaseResourceForThreadLite(
            &Vcb->MainResource,
            ExGetCurrentResourceThread());

        //
        // Setup the Irp. We'll send it to the lower disk driver.
        //

        IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);

        KeInitializeEvent( &Event, NotificationEvent, FALSE );
        IoSetCompletionRoutine( IrpContext->Irp,
                                RfsdPnpCompletionRoutine,
                                &Event,
                                TRUE,
                                TRUE,
                                TRUE );

        Status = IoCallDriver( Vcb->TargetDeviceObject, 
                               IrpContext->Irp);

       if (Status == STATUS_PENDING) {

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

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

        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource, TRUE );

        RfsdPurgeVolume(Vcb, FALSE);

        ExReleaseResourceForThreadLite(
            &Vcb->MainResource,
            ExGetCurrentResourceThread() );

        bDeleted = RfsdCheckDismount(IrpContext, Vcb, TRUE);

    } __finally {
        RfsdCompleteRequest(
            IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)?
            IO_DISK_INCREMENT : IO_NO_INCREMENT) );

        IrpContext->Irp = NULL;
    }

    return Status;
}


NTSTATUS
RfsdPnpSurpriseRemove (
    PRFSD_IRP_CONTEXT IrpContext,
    PRFSD_VCB         Vcb      )
{
    NTSTATUS Status;
    KEVENT   Event;
    BOOLEAN  bDeleted;

    __try {

        RfsdPrint((DBG_PNP, "RfsdPnpSupriseRemove by RfsdPnp ...\n"));
#if (_WIN32_WINNT >= 0x0500)
        CcWaitForCurrentLazyWriterActivity();
#endif
        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource,  TRUE );

        Status = RfsdLockVcb(Vcb, IrpContext->FileObject);

        ExReleaseResourceForThreadLite(
            &Vcb->MainResource,
            ExGetCurrentResourceThread());

        //
        // Setup the Irp. We'll send it to the lower disk driver.
        //

        IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);

        KeInitializeEvent( &Event, NotificationEvent, FALSE );
        IoSetCompletionRoutine( IrpContext->Irp,
                                RfsdPnpCompletionRoutine,
                                &Event,
                                TRUE,
                                TRUE,
                                TRUE );

        Status = IoCallDriver( Vcb->TargetDeviceObject, 
                               IrpContext->Irp);

       if (Status == STATUS_PENDING) {

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

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

        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource, TRUE );

        RfsdPurgeVolume(Vcb, FALSE);

        ExReleaseResourceForThreadLite(
            &Vcb->MainResource,
            ExGetCurrentResourceThread() );

        bDeleted = RfsdCheckDismount(IrpContext, Vcb, TRUE);

    } __finally {

        RfsdCompleteRequest(
            IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)?
            IO_DISK_INCREMENT : IO_NO_INCREMENT) );

        IrpContext->Irp = NULL;
    }

    return Status;
}


NTSTATUS
RfsdPnpCancelRemove (
    PRFSD_IRP_CONTEXT IrpContext,
    PRFSD_VCB         Vcb
    )
{
    NTSTATUS Status;

    RfsdPrint((DBG_PNP, "RfsdPnpCancelRemove by RfsdPnp ...\n"));

    ExAcquireResourceExclusiveLite(
        &Vcb->MainResource,  TRUE );

    Status = RfsdUnlockVcb(Vcb, IrpContext->FileObject);

    ExReleaseResourceForThreadLite(
        &Vcb->MainResource,
        ExGetCurrentResourceThread());

    IoSkipCurrentIrpStackLocation(IrpContext->Irp);

    Status = IoCallDriver(Vcb->TargetDeviceObject, IrpContext->Irp);

    IrpContext->Irp = NULL;

    return Status;
}


#endif //(_WIN32_WINNT >= 0x0500)

⌨️ 快捷键说明

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