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

📄 pnp.c

📁 基于DDK的驱动间同步调用测试示例程序,DriverA是目标驱动,DriverB是主驱动,test是MFC测试示例
💻 C
📖 第 1 页 / 共 2 页
字号:
// pnp.c
//
// Generated by C DriverWizard 3.2.0 (Build 2485)
// Requires DDK Only
// File created on 3/12/2009
//

#include "pch.h"
#ifdef DRIVERB_SYN_WMI_TRACE
#include "pnp.tmh"
#endif

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverB_SynPnpDispatch
//      Dispatch routine to handle PnP requests
//
//  Arguments:
//      IN  DeviceObject
//              pointer to our device object
//
//      IN  Irp
//              pointer to the PnP IRP
//
//  Return Value:
//      NT status code
//
NTSTATUS DriverB_SynPnpDispatch(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp
    )
{
    PDRIVERB_SYN_DEVICE_EXTENSION    deviceExtension;
    PIO_STACK_LOCATION              irpStack;
    NTSTATUS                        status;
    PDEVICE_CAPABILITIES            deviceCapabilities;
    ULONG                           requestCount;
    ULONG                           index;
    PPNP_DEVICE_STATE               deviceState;
    UNICODE_STRING                  win32Name;
    POWER_STATE                     powerState;

    DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    DriverB_SynDumpIrp(Irp);

    // Get our device extension from the device object
    deviceExtension = (PDRIVERB_SYN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    // Get our current IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Make sure we can accept IRPs
    if (!DriverB_SynAcquireRemoveLock(deviceExtension))
    {
        status = STATUS_NO_SUCH_DEVICE;

        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        DriverB_SynDebugPrint(DBG_PNP, DBG_WARN, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;
    }

    switch (irpStack->MinorFunction) 
    {
    case IRP_MN_START_DEVICE:

        // The device stack must be started from the bottom up.  
        // So, we send the IRP down the stack and wait so that 
        // all devices below ours have started before we process 
        // this IRP and start ourselves.
        status = DriverB_SynSubmitIrpSync(deviceExtension->LowerDeviceObject, Irp);
        if (!NT_SUCCESS(status))
        {
            // Someone below us failed to start, so just complete with error
            break;
        }

        // Lower drivers have finished their start operation, so now
        // we process ours.

        // Start is an implicit power-up so 
        // we set our device power state accordingly 
        deviceExtension->DevicePowerState = PowerDeviceD0;
        powerState.DeviceState = deviceExtension->DevicePowerState;

        PoSetPowerState(deviceExtension->DeviceObject, DevicePowerState, powerState);

        status = DriverB_SynGetDeviceCapabilities(deviceExtension);
        if (!NT_SUCCESS(status))
        {
            DriverB_SynFreeResources(deviceExtension);
            break;
        }

        status = DriverB_SynStartDevice(deviceExtension, Irp);
        if (!NT_SUCCESS(status))
        {
            DriverB_SynFreeResources(deviceExtension);
            break;
        }

        // Update our PnP state
        deviceExtension->PnpState = PnpStateStarted;

        // restart any stalled queues
        DriverB_SynRestartQueues(deviceExtension);
        break;

    case IRP_MN_QUERY_STOP_DEVICE:

        if (DriverB_SynIsStoppable(deviceExtension)) 
        {
            // Device is stoppable.

            // pause io request processing
            DriverB_SynStallQueues(deviceExtension);

            // Update our PnP state
            deviceExtension->PreviousPnpState = deviceExtension->PnpState;
            deviceExtension->PnpState = PnpStateStopPending;

            // We must set Irp->IoStatus.Status to STATUS_SUCCESS before
            // passing it down.
            Irp->IoStatus.Status = STATUS_SUCCESS;
            IoSkipCurrentIrpStackLocation (Irp);
            status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);

            // Decrement the active I/O count
            DriverB_SynReleaseRemoveLock(deviceExtension);

            DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

            return status;
        }
        else
        {
            // device is not currently stoppable, fail the request
            status = STATUS_UNSUCCESSFUL;
        }

        break;

   case IRP_MN_CANCEL_STOP_DEVICE:

        // Send this IRP down and wait for it to come back,
        // restart our stall fifo,
        // and process all the previously queued up IRPs.

        // First check to see whether we received a query before this
        // cancel. This could happen if someone above us failed a query
        // and passed down the subsequent cancel.
        if (deviceExtension->PnpState == PnpStateStopPending) 
        {
            status = DriverB_SynSubmitIrpSync(deviceExtension->LowerDeviceObject,Irp);
            if (NT_SUCCESS(status))
            {
                // restore previous pnp state
                deviceExtension->PnpState = deviceExtension->PreviousPnpState;

                // restart the queues
                DriverB_SynRestartQueues(deviceExtension);
            } 
            else 
            {
                // Somebody below us failed the cancel
                // this is a fatal error.
                ASSERTMSG("Cancel stop failed!", FALSE);
                DriverB_SynDebugPrint(DBG_PNP, DBG_ERR, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
            }
        } 
        else 
        {
            // Spurious cancel so we just complete the request.
            status = STATUS_SUCCESS;
        }

        break;

    case IRP_MN_STOP_DEVICE:
        // Mark the device as stopped.
        deviceExtension->PnpState = PnpStateStopped;

        // release our resources
        DriverB_SynFreeResources(deviceExtension);

        // send the request down, and we are done
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation (Irp);
        status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);

        DriverB_SynReleaseRemoveLock(deviceExtension);

        DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;

    case IRP_MN_QUERY_REMOVE_DEVICE:

        if (DriverB_SynIsRemovable(deviceExtension)) 
        {
            // pause io request processing
            DriverB_SynStallQueues(deviceExtension);

            // Update our PnP state
            deviceExtension->PreviousPnpState = deviceExtension->PnpState;
            deviceExtension->PnpState = PnpStateRemovePending;

            // Now just send the request down and we are done
            Irp->IoStatus.Status = STATUS_SUCCESS;
            IoSkipCurrentIrpStackLocation (Irp);

            status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);

            // decrement the I/O count
            DriverB_SynReleaseRemoveLock(deviceExtension);

            DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

            return status;
        }
        else
        {
            // Our device is not removable, just fail the request
            status = STATUS_UNSUCCESSFUL;
        }

        break;

    case IRP_MN_CANCEL_REMOVE_DEVICE:

        // First check to see whether we have received a prior query

⌨️ 快捷键说明

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