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

📄 pnp.c

📁 USB 过滤驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1996  Microsoft Corporation

Module Name:

    pnp.c

Abstract: NULL filter driver -- boilerplate code

Author:

    ervinp

Environment:

    Kernel mode

Revision History:


--*/

#include <WDM.H>

#include "filter.h"


#ifdef ALLOC_PRAGMA
        #pragma alloc_text(PAGE, VA_PnP)
        #pragma alloc_text(PAGE, GetDeviceCapabilities)
        #ifdef HANDLE_DEVICE_USAGE
            #pragma alloc_text(PAGE, VA_DeviceUsageNotification)
        #endif // HANDLE_DEVICE_USAGE
#endif


NTSTATUS VA_PnP(struct DEVICE_EXTENSION *devExt, PIRP irp)
/*++

Routine Description:

    Dispatch routine for PnP IRPs (MajorFunction == IRP_MJ_PNP)

Arguments:

    devExt - device extension for the targetted device object
    irp - IO Request Packet

Return Value:

    NT status code

--*/
{
    PIO_STACK_LOCATION irpSp;
    NTSTATUS status = STATUS_SUCCESS;
    BOOLEAN completeIrpHere = FALSE;
    BOOLEAN justReturnStatus = FALSE;

    PAGED_CODE();

    irpSp = IoGetCurrentIrpStackLocation(irp);

    DBGOUT(("VA_PnP, minorFunc = %d ", (ULONG)irpSp->MinorFunction));

    switch (irpSp->MinorFunction){

    case IRP_MN_START_DEVICE:
        DBGOUT(("START_DEVICE"));

        devExt->state = STATE_STARTING;

        /*
         *  First, send the START_DEVICE irp down the stack
         *  synchronously to start the lower stack.
         *  We cannot do anything with our device object
         *  before propagating the START_DEVICE this way.
         */
        IoCopyCurrentIrpStackLocationToNext(irp);
        status = CallNextDriverSync(devExt, irp);

        if (NT_SUCCESS(status)){
            /*
             *  Now that the lower stack is started,
             *  do any initialization required by this device object.
             */
            status = GetDeviceCapabilities(devExt);
            if (NT_SUCCESS(status)){
                devExt->state = STATE_STARTED;
            }
            else {
                devExt->state = STATE_START_FAILED;
            }
        }
        else {
            devExt->state = STATE_START_FAILED;
        }
        completeIrpHere = TRUE;
        break;

    case IRP_MN_QUERY_STOP_DEVICE:
    case IRP_MN_QUERY_REMOVE_DEVICE:
#ifdef HANDLE_DEVICE_USAGE
        //
        // Need to fail these IRPs if a paging, hibernation, or crashdump
        // file is currently open on this device
        //
        if(    devExt->pagingFileCount      != 0
            || devExt->hibernationFileCount != 0
            || devExt->crashdumpFileCount   != 0 )
        {
            // Fail the IRP
            DBGOUT(( "Failing QUERY_(STOP,REMOVE)_DEVICE request b/c "
                     "paging, hiber, or crashdump file is present on device." ));
            status = STATUS_UNSUCCESSFUL;
            completeIrpHere = TRUE;
        }
        else
        {
            // We'll just pass this IRP down the driver stack.  But
            // first, must change the IRP's status to STATUS_SUCCESS
            // (default is STATUS_NOT_SUPPORTED)
            irp->IoStatus.Status = STATUS_SUCCESS;
        }
#else
        /*
         *  We will pass this IRP down the driver stack.
         *  However, we need to change the default status
         *  from STATUS_NOT_SUPPORTED to STATUS_SUCCESS.
         */
        irp->IoStatus.Status = STATUS_SUCCESS;
#endif

        break;

    case IRP_MN_STOP_DEVICE:
        if (devExt->state == STATE_SUSPENDED){
            status = STATUS_DEVICE_POWER_FAILURE;
            completeIrpHere = TRUE;
        }
        else {
            /*
             *  Only set state to STOPPED if the device was
             *  previously started successfully.
             */
            if (devExt->state == STATE_STARTED){
                devExt->state = STATE_STOPPED;
            }
        }
        break;


    case IRP_MN_SURPRISE_REMOVAL:
        DBGOUT(("SURPRISE_REMOVAL"));

        /*
         *  We will pass this IRP down the driver stack.
         *  However, we need to change the default status
         *  from STATUS_NOT_SUPPORTED to STATUS_SUCCESS.
         */
        irp->IoStatus.Status = STATUS_SUCCESS;

        /*
         *  For now just set the STATE_REMOVING state so that
         *  we don't do any more IO.  We are guaranteed to get
         *  IRP_MN_REMOVE_DEVICE soon; we'll do the rest of
         *  the remove processing there.
         */
        devExt->state = STATE_REMOVING;

        break;

    case IRP_MN_REMOVE_DEVICE:
        /*
         *  Check the current state to guard against multiple
         *  REMOVE_DEVICE IRPs.
         */
        DBGOUT(("REMOVE_DEVICE"));
        if (devExt->state != STATE_REMOVED){

            devExt->state = STATE_REMOVED;

            /*
             *  Send the REMOVE IRP down the stack asynchronously.
             *  Do not synchronize sending down the REMOVE_DEVICE
             *  IRP, because the REMOVE_DEVICE IRP must be sent
             *  down and completed all the way back up to the sender
             *  before we continue.
             */
            IoCopyCurrentIrpStackLocationToNext(irp);
            status = IoCallDriver(devExt->topDevObj, irp);
            justReturnStatus = TRUE;

            DBGOUT(("REMOVE_DEVICE - waiting for %d irps to complete...",
                    devExt->pendingActionCount));

            /*
             *  We must for all outstanding IO to complete before
             *  completing the REMOVE_DEVICE IRP.
             *
             *  First do an extra decrement on the pendingActionCount.
             *  This will cause pendingActionCount to eventually
             *  go to -1 once all asynchronous actions on this
             *  device object are complete.
             *  Then wait on the event that gets set when the
             *  pendingActionCount actually reaches -1.
             */
            DecrementPendingActionCount(devExt);
            KeWaitForSingleObject(  &devExt->removeEvent,
                                    Executive,      // wait reason
                                    KernelMode,
                                    FALSE,          // not alertable
                                    NULL );         // no timeout

            DBGOUT(("REMOVE_DEVICE - ... DONE waiting. "));

#ifdef HANDLE_DEVICE_USAGE
            /*
             *  If we locked-down certain paged code sections earlier
             *  because of this device, then need to unlock them now
             *  (before calling IoDeleteDevice)
             */
            if( NULL != devExt->pagingPathUnlockHandle )
            {
                DBGOUT(( "UNLOCKing some driver code (non-pageable) (b/c paging path)" ));
                MmUnlockPagableImageSection( devExt->pagingPathUnlockHandle );
                devExt->pagingPathUnlockHandle = NULL;
            }

            if( NULL != devExt->initUnlockHandle )
            {
                DBGOUT(( "UNLOCKing some driver code (non-pageable) (b/c init conditions)" ));
                MmUnlockPagableImageSection( devExt->initUnlockHandle );
                devExt->initUnlockHandle = NULL;
            }
#endif // HANDLE_DEVICE_USAGE

            /*
             *  Detach our device object from the lower
             *  device object stack.
             */
            IoDetachDevice(devExt->topDevObj);

            /*
             *  Delete our device object.
             *  This will also delete the associated device extension.
             */
            IoDeleteDevice(devExt->filterDevObj);
        }
        break;

#ifdef HANDLE_DEVICE_USAGE
    case IRP_MN_DEVICE_USAGE_NOTIFICATION:


        //
        // Make sure the Type of this UsageNotification is one that we handle
        //
        if(    irpSp->Parameters.UsageNotification.Type != DeviceUsageTypePaging
            && irpSp->Parameters.UsageNotification.Type != DeviceUsageTypeHibernation
            && irpSp->Parameters.UsageNotification.Type != DeviceUsageTypeDumpFile )
        {
            break; // out of the big switch statement (and just forward this IRP)
        }

        status = VA_DeviceUsageNotification(devExt, irp);
        justReturnStatus = TRUE;
        break;
#endif // HANDLE_DEVICE_USAGE

#ifdef HANDLE_DEVICE_USAGE
    case IRP_MN_QUERY_PNP_DEVICE_STATE:
        //
        // If a paging, hibernation, or crashdump file is currently open
        // on this device, must set NOT_DISABLEABLE flag in DeviceState
        //
        if(    devExt->pagingFileCount      != 0
            || devExt->hibernationFileCount != 0
            || devExt->crashdumpFileCount   != 0  )
        {
            // Mark the device as not disableable
            PPNP_DEVICE_STATE pDeviceState;
            pDeviceState = (PPNP_DEVICE_STATE) &irp->IoStatus.Information;
            *pDeviceState |= PNP_DEVICE_NOT_DISABLEABLE;
        }

        //
        // We _did_ handle this IRP (as best we could), so set IRP's

⌨️ 快捷键说明

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