📄 pnp.c
字号:
// 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 + -