1.
//
// Initialize DevicePowerState to PowerDeviceD3. PowerDeviceD3 is the lowest// power state for hardware. ToasterAddDevice initializes DevicePowerState to
// the lowest power state instead of the working power state because the
// hardware instance cannot be working until ToasterDispatchPnP processes
// IRP_MN_START_DEVICE.
//
fdoData->DevicePowerState = PowerDeviceD3;
//
// Initialize SystemPowerState to PowerSystemWorking. PowerSystemWorking is the
// highest power state for the system. ToasterAddDevice initializes
// SystemPowerState to the highest power state because the system only executes
// code, such as drivers, when the system is working.
//
fdoData->SystemPowerState = PowerSystemWorking;
//
// Notify the power manager of the initial power state of the hardware instance.
//
powerState.DeviceState = PowerDeviceD3;
PoSetPowerState ( deviceObject, DevicePowerState, powerState );
对设备与系统电源状态的初始化
2.
The system dispatches IRP_MJ_CLEANUP IRPs to ToasterCleanup. ToasterCleanup
cancels all IRPs from the driver-managed IRP queue whose file object matches
the file object of the incoming IRP.
IRP_MJ_CLEANUP and IRP_MJ_CLOSE are related but not identical, and are often
confused. The system sends IRP_MJ_CLOSE to the function driver to close a
handle returned earlier by the function driver's IRP_MJ_CREATE dispatch
routine. ToasterCreate is the function drivers IRP_MJ_CREATE dispatch routine.
However, ToasterClose only closes the file object handle. It does not cancel
any IRPs in the driver-managed IRP queue that are associated with the handle.
Thus, the system sends IRP_MJ_CLEANUP to the function driver, so that the
driver can remove any IRPs in the driver-managed IRP queue that belonged to
the handle that is now closed.
ToasterCleanup processes each queued IRP in the driver-managed IRP queue and,
if the queued IRP's file object matches that of the cleanup IRP, then the
queued IRP is removed from the driver-managed IRP queue and added to a
temporary IRP queue.
After every IRP in the driver-managed IRP queue has been processed, the
temporary IRP queue is processed. Each IRP in the temporary IRP queue is
removed and completed with STATUS_CANCELLED.
Note that ToasterCleanup does not call the PAGED_CODE macro because the routine
uses a spin lock.
1) CleanUp例程的作用
2)CleanUp与Close的差别
3)CleanUp中不能使用PAGED_CODE宏的原因(spin lock)
3.
// If the device interface is from an unrelated device we must register a
// PnP notification for device removal to dereference and stop using the interface.
不明其意
4.
// Clear the IRP's cancel routine to NULL. Then determine if the system
// has already called the IRP's cancel routine. If IoSetCancelRoutine
// returns NULL, then the system has already called ToasterCancelQueued.
// If IoSetCancelRoutine does not return NULL, then the system will not
// call ToasterCancelQueued, because ToasterCancelQueued clears the IRP's
// cancel routine to NULL.
Cancel Routine的使用方法
Cancel Routine一直是Windows驱动编程中的难点.
5.
//
// The system has already called ToasterCancelQueued. However,
// ToasterCancelQueued must be waiting to acquire QueueLock because
// QueueLock was acquired before the for-loop began to process the
// driver-managed IRP queue.
//
// The thread that executes ToasterCancelQueued will resume when
// QueueLock is released outside of the for loop. ToasterCancelQueued
// will then proceed to remove the IRP from the driver-managed IRP
// queue, thus ToasterCleanup must not add the IRP to the temporary
// IRP queue. Otherwise, when the temporary queue is processed at the
// end of ToasterCleanup the same IRP would be completed twice,
// causing a system crash because an IRP must only be completed once.
//
// Initialize NewRequestsQueue's list head to prevent
// ToasterCancelQueued from causing a system crash when it attempts
// to remove the IRP which has already been removed from the
// driver-managed IRP queue earlier.
//
InitializeListHead(thisEntry);
CancelRoutine与CleanUp间对于driver-managed IRP queue的同步,由Spin lock来负责
如果CancelRoutine已经被系统调用, 则最后的IRP完成处理由CanceRoutine完成(STATUS_CANCELLED), 目前spin lock由CleanUp占有, 一旦CleanUp释放, CancelRoutine将得到调用
// The system has not already called ToasterCancelQueued, nor
// will it call ToasterCancelQueued because the IRP's cancel
// routine has been cleared to NULL.
//
// Add the de-queued IRP to the temporary IRP queue to be completed
// at the end of ToasterCleanup.
如果CancelRoutine未被系统调用, 则该IRP将从driver-managed IRP queue移除, 放入临时性的cleanupList, 在CleanUp最后阶段, 将该IRP完成(STATUS_CANCELLED)
6.
The IRP might need to be canceled if the application that originated the IRP
has been closed, but the IRP remains in the driver-managed IRP queue. The
system then calls ToasterCancelQueued to remove the IRP from the
driver-managed IRP queue.
A driver that implements its own driver-managed IRP queue must supply a cancel
routine to the system when the IRP is added to the driver-managed IRP queue
because only the driver can correctly remove the IRP from its own
driver-managed IRP queue.
CancelRoutine与driver-managed IRP queue的关系
CancelRoutine被系统调用的时机
这一篇主要列出一系列Windows驱动中IRP CancelRoutine的相关知识点
具体内容请参考
featured1