📄 pnp.c
字号:
// pnp.c
//
// Generated by C DriverWizard 3.1.0 (Build 1722)
// Requires DDK Only
// File created on 1/23/2009
//
#include "pch.h"
#ifdef CHARSAMPLE_WMI_TRACE
#include "pnp.tmh"
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSamplePnpDispatch
// 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 CharSamplePnpDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PCHARSAMPLE_DEVICE_EXTENSION deviceExtension;
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
PDEVICE_CAPABILITIES deviceCapabilities;
ULONG requestCount;
ULONG index;
PPNP_DEVICE_STATE deviceState;
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);
CharSampleDumpIrp(Irp);
// Get our device extension from the device object
deviceExtension = (PCHARSAMPLE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// Get our current IRP stack location
irpStack = IoGetCurrentIrpStackLocation(Irp);
// Make sure we can accept IRPs
if (!CharSampleAcquireRemoveLock(deviceExtension))
{
status = STATUS_NO_SUCH_DEVICE;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
CharSampleDebugPrint(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 = CharSampleSubmitIrpSync(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.
status = CharSampleStartDevice(deviceExtension, Irp);
if (!NT_SUCCESS(status))
{
CharSampleFreeResources(deviceExtension);
break;
}
// Enable the device interface.
status = IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, TRUE);
if (!NT_SUCCESS(status))
{
CharSampleFreeResources(deviceExtension);
break;
}
// Update our PnP state
deviceExtension->PnpState = PnpStateStarted;
// restart any stalled queues
CharSampleRestartQueues(deviceExtension);
break;
case IRP_MN_QUERY_STOP_DEVICE:
if (CharSampleIsStoppable(deviceExtension))
{
// Device is stoppable.
// pause io request processing
CharSampleStallQueues(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
CharSampleReleaseRemoveLock(deviceExtension);
CharSampleDebugPrint(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 = CharSampleSubmitIrpSync(deviceExtension->LowerDeviceObject,Irp);
if (NT_SUCCESS(status))
{
// restore previous pnp state
deviceExtension->PnpState = deviceExtension->PreviousPnpState;
// restart the queues
CharSampleRestartQueues(deviceExtension);
}
else
{
// Somebody below us failed the cancel
// this is a fatal error.
ASSERTMSG("Cancel stop failed!", FALSE);
CharSampleDebugPrint(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
CharSampleFreeResources(deviceExtension);
// send the request down, and we are done
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
CharSampleReleaseRemoveLock(deviceExtension);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
case IRP_MN_QUERY_REMOVE_DEVICE:
if (CharSampleIsRemovable(deviceExtension))
{
// pause io request processing
CharSampleStallQueues(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
CharSampleReleaseRemoveLock(deviceExtension);
CharSampleDebugPrint(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
// remove request. It could happen that we did not if
// someone above us failed a query remove and passed down the
// subsequent cancel remove request.
if (PnpStateRemovePending == deviceExtension->PnpState)
{
status = CharSampleSubmitIrpSync(deviceExtension->LowerDeviceObject, Irp);
if (NT_SUCCESS(status))
{
// restore pnp state, since remove was canceled
deviceExtension->PnpState = deviceExtension->PreviousPnpState;
// restart the queues
CharSampleRestartQueues(deviceExtension);
}
else
{
// Nobody can fail this IRP. This is a fatal error.
ASSERTMSG("IRP_MN_CANCEL_REMOVE_DEVICE failed. Fatal error!", FALSE);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
}
}
else
{
// Spurious cancel remove request so we just complete it
status = STATUS_SUCCESS;
}
break;
case IRP_MN_SURPRISE_REMOVAL:
// The device has been unexpectedly removed from the machine
// and is no longer available for I/O.
// We must return device and memory resources,
// disable interfaces. We will defer failing any outstanding
// request to IRP_MN_REMOVE.
// stall all the queues
CharSampleStallQueues(deviceExtension);
// flush pending io list
CharSampleInvalidateIo(&deviceExtension->IoLock, STATUS_NO_SUCH_DEVICE);
// update pnp state
deviceExtension->PnpState = PnpStateSurpriseRemoved;
// disable our interface
IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, FALSE);
// Return any resources acquired during device startup.
CharSampleFreeResources(deviceExtension);
// 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);
// Adjust the active I/O count
CharSampleReleaseRemoveLock(deviceExtension);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
case IRP_MN_REMOVE_DEVICE:
// The Plug & Play system has dictated the removal of this device. We
// have no choice but to detach and delete the device object.
if (deviceExtension->PnpState != PnpStateSurpriseRemoved)
{
// flush pending io list
CharSampleInvalidateIo(&deviceExtension->IoLock, STATUS_NO_SUCH_DEVICE);
IoSetDeviceInterfaceState(&deviceExtension->InterfaceName, FALSE);
CharSampleFreeResources(deviceExtension);
}
// Update our PnP state
deviceExtension->PnpState = PnpStateRemoved;
CharSampleReleaseRemoveLock(deviceExtension);
CharSampleWaitForSafeRemove(deviceExtension);
// Send the remove IRP down the stack.
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver (deviceExtension->LowerDeviceObject, Irp);
// Detach our device object from the device stack
IoDetachDevice(deviceExtension->LowerDeviceObject);
// free InterfaceName memory
RtlFreeUnicodeString(&deviceExtension->InterfaceName);
// attempt to delete our device object
IoDeleteDevice(deviceExtension->DeviceObject);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
case IRP_MN_QUERY_CAPABILITIES:
// Check the device capabilities struct
deviceCapabilities =
irpStack->Parameters.DeviceCapabilities.Capabilities;
if (deviceCapabilities->Version != 1 ||
deviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES))
{
// We don't support this version. Fail the request
break;
}
// Pass the IRP down
status = CharSampleSubmitIrpSync(deviceExtension->LowerDeviceObject, Irp);
// Lower drivers have finished their operation, so now
// we can finish ours.
if (NT_SUCCESS(status))
{
//*****************************************************************
//*****************************************************************
// TODO: Override the device capabilities
// set by the underlying drivers here.
//*****************************************************************
//*****************************************************************
}
break;
default:
// Pass down any unknown requests.
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);
// Adjust our active I/O count
CharSampleReleaseRemoveLock(deviceExtension);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
}
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
// Adjust the active I/O count
CharSampleReleaseRemoveLock(deviceExtension);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -