The following table summarizes the IRQL and thread context requirements for file system filter driver dispatch routines.
DriverEntry routines are called in the context of a system thread at IRQL = PASSIVE_LEVEL.
Most drivers' dispatch routines are called in an arbitrary thread context at IRQL = PASSIVE_LEVEL, with the following exceptions:
- Any highest-level driver's dispatch routines
are called in the context of the thread that originated the I/O
request, which is commonly a user-mode application thread.
In other words, the dispatch routines of file system drivers and other highest-level drivers are called in a nonarbitrary thread context at IRQL = PASSIVE_LEVEL.
- The DispatchRead
, DispatchWrite
, and DispatchDeviceControl
routines of lowest-level device drivers, and of intermediate drivers
layered above them in the system paging path, can be called at IRQL =
APC_LEVEL and in an arbitrary thread context.
The DispatchRead and/or DispatchWrite routines, and any other routine that also processes read and/or write requests in such a lowest-level device or intermediate driver, must be resident at all times . These driver routines can neither be pageable nor be part of a driver's pageable-image section; they must not access any pageable memory . Furthermore, they should not be dependent on any blocking calls (such as KeWaitForSingleObject with a nonzero time-out).
- The DispatchPower routine of drivers in the hibernation and/or paging paths can be called at IRQL = DISPATCH_LEVEL. The DispatchPnP routines of such drivers must be prepared to handle PnP IRP_MN_DEVICE_USAGE_NOTIFICATION requests.
- The DispatchPower routine of drivers that require inrush power at start-up can be called at IRQL = DISPATCH_LEVEL.
Dispatch Routine | Caller's IRQL: | Caller's Thread Context: |
---|---|---|
Cleanup | PASSIVE_LEVEL | Nonarbitrary |
Close | APC_LEVEL | Arbitrary |
Create | PASSIVE_LEVEL | Nonarbitrary |
DeviceControl (except paging I/O) | PASSIVE_LEVEL | Nonarbitrary |
DeviceControl (paging I/O path) | APC_LEVEL | Arbitrary |
DirectoryControl | APC_LEVEL | Arbitrary |
FlushBuffers | PASSIVE_LEVEL | Nonarbitrary |
FsControl (except paging I/O) | PASSIVE_LEVEL | Nonarbitrary |
FsControl (paging I/O path) | APC_LEVEL | Arbitrary |
LockControl | PASSIVE_LEVEL | Nonarbitrary |
PnP | PASSIVE_LEVEL | Arbitrary |
QueryEa | PASSIVE_LEVEL | Nonarbitrary |
QueryInformation | PASSIVE_LEVEL | Nonarbitrary |
QueryQuota | PASSIVE_LEVEL | Nonarbitrary |
QuerySecurity | PASSIVE_LEVEL | Nonarbitrary |
QueryVolumeInfo | PASSIVE_LEVEL | Nonarbitrary |
Read (except paging I/O) | PASSIVE_LEVEL | Nonarbitrary |
Read (paging I/O path) | APC_LEVEL | Arbitrary |
SetEa | PASSIVE_LEVEL | Nonarbitrary |
SetInformation | PASSIVE_LEVEL | Nonarbitrary |
SetQuota | PASSIVE_LEVEL | Nonarbitrary |
SetSecurity | PASSIVE_LEVEL | Nonarbitrary |
SetVolumeInfo | PASSIVE_LEVEL | Nonarbitrary |
Shutdown | APC_LEVEL | Arbitrary |
Write (except paging I/O) | PASSIVE_LEVEL | Nonarbitrary |
Write (paging I/O path) | APC_LEVEL | Arbitrary |