📄 pnp.c
字号:
// pnp.c
//
// Generated by C DriverWizard 3.2.0 (Build 2485)
// Requires DDK Only
// File created on 3/11/2009
//
#include "pch.h"
#ifdef DRIVERA_WMI_TRACE
#include "pnp.tmh"
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////
// DriverAPnpDispatch
// 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 DriverAPnpDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDRIVERA_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;
DriverADebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);
DriverADumpIrp(Irp);
// Get our device extension from the device object
deviceExtension = (PDRIVERA_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// Get our current IRP stack location
irpStack = IoGetCurrentIrpStackLocation(Irp);
// Make sure we can accept IRPs
if (!DriverAAcquireRemoveLock(deviceExtension))
{
status = STATUS_NO_SUCH_DEVICE;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DriverADebugPrint(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 = DriverASubmitIrpSync(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 = DriverAGetDeviceCapabilities(deviceExtension);
if (!NT_SUCCESS(status))
{
DriverAFreeResources(deviceExtension);
break;
}
status = DriverAStartDevice(deviceExtension, Irp);
if (!NT_SUCCESS(status))
{
DriverAFreeResources(deviceExtension);
break;
}
// Update our PnP state
deviceExtension->PnpState = PnpStateStarted;
// restart any stalled queues
DriverARestartQueues(deviceExtension);
break;
case IRP_MN_QUERY_STOP_DEVICE:
if (DriverAIsStoppable(deviceExtension))
{
// Device is stoppable.
// pause io request processing
DriverAStallQueues(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
DriverAReleaseRemoveLock(deviceExtension);
DriverADebugPrint(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 = DriverASubmitIrpSync(deviceExtension->LowerDeviceObject,Irp);
if (NT_SUCCESS(status))
{
// restore previous pnp state
deviceExtension->PnpState = deviceExtension->PreviousPnpState;
// restart the queues
DriverARestartQueues(deviceExtension);
}
else
{
// Somebody below us failed the cancel
// this is a fatal error.
ASSERTMSG("Cancel stop failed!", FALSE);
DriverADebugPrint(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
DriverAFreeResources(deviceExtension);
// send the request down, and we are done
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
DriverAReleaseRemoveLock(deviceExtension);
DriverADebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
case IRP_MN_QUERY_REMOVE_DEVICE:
if (DriverAIsRemovable(deviceExtension))
{
// pause io request processing
DriverAStallQueues(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
DriverAReleaseRemoveLock(deviceExtension);
DriverADebugPrint(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 + -