Every DriverEntry routine is run in the context of a system thread at IRQL PASSIVE_LEVEL.
In general, a DriverEntry routine is responsible for exporting the driver’s other entry points, for initializing the NT objects the driver uses, and for setting up any other system resources that the driver uses. For more information about NT objects, see Chapter 3.
A DriverEntry routine can use the Windows NT® registry to get some of the information it needs to initialize the driver or its device(s). The DriverEntry routine must set information in the registry for other NT drivers and/or protected subsystems to use. For more information about using the registry, see Chapter 16.
See Chapter 2 for how to do this. For more information about Dispatch, StartIo, and Unload routines, see Chapters 6, 7, and 15, respectively.
See Chapter 3 for how to set up a device object.
See Chapter 16 for more information about using the registry and setting up symbolic links.
For routine-specific requirements, see Chapters 7-9, 11, and 14.
Because it executes in a system-thread context, the DriverEntry routine itself can wait for a nonzero interval on a dispatcher object, which must be initialized before the wait begins. For example, class drivers that call down to a corresponding port driver during initialization usually wait on an event object they associate with an IRP, which they allocate with IoBuildSynchronousFsdRequest and pass with IoCallDriver to the port driver for the physical device.
See Chapter 3 for more information about waiting on dispatcher objects.
See Chapter 16 for guidelines on how to use spin locks, and Chapter 8 for more information about whether a device driver must supply storage for an interrupt spin lock.
As shown by its declaration, a DriverEntry routine returns an NTSTATUS-type value. The DriverEntry routine should postpone any call to IoRegisterDriverReinitialization until just before it returns STATUS_SUCCESS. It must not make this call unless it will return STATUS_SUCCESS.
If a DriverEntry routine returns something other than STATUS_SUCCESS to indicate that it can successfully process I/O requests for at least one named device object that it created, that driver does not remain loaded.
A DriverEntry routine that will fail initialization must free any NT objects, system resources, and registry resources it has already set up before it returns control. It should reset the driver’s Dispatch entry points in the driver object for IRP_MJ_FLUSH_BUFFERS and/or IRP_MJ_SHUTDOWN to NULL if the driver supports these requests. If it already called IoRegisterShutdownNotification, the DriverEntry routine must call IoUnregisterShutdownNotification before it fails initialization.
If a driver will fail initialization, the DriverEntry routine also should log an error or have IoReportResourceUsage log a hardware resource conflict error on a device driver’s behalf before DriverEntry returns control. For more information about logging I/O and resource-conflict errors, see Chapter 16.