2.3.2 Driver Object Entry Points

Except for video and SCSI miniport drivers, as explained later in Section 2.4, each NT driver must define the following entry points in its driver object:

While an NT device driver is not required to define a StartIo entry point if it is designed to set up and manage its own queue(s) of IRPs, most NT device drivers define a StartIo entry point in their driver objects and rely on the I/O Manager to queue IRPs bound for their StartIo routines. In fact, few lowest-level system-supplied drivers are designed without a StartIo routine, even when they set up and maintain their own supplemental queues for IRPs.

Higher-level NT drivers can have a StartIo routine but, for better performance, seldom do. Instead, most NT file system drivers set up and maintain internal queues of IRPs. Other higher-level NT drivers either have internal queues for IRPs or simply pass IRPs on to lower drivers from their Dispatch routines after setting up the I/O stack location for the next-lower driver in each IRP, and, possibly, setting up the higher-level driver’s IoCompletion routine for a given IRP.

When an NT driver’s DriverEntry routine is called, it sets Dispatch, StartIo (if any), and Unload (if any) entry points directly in the driver object as follows:
DriverObject->MajorFunction[IRP_MJ_xxx] = DDDispatchXxx; 
              :    : 
DriverObject->MajorFunction[IRP_MJ_yyy] = DDDispatchYyy; 
              :    : 
DriverObject->DriverStartIo = DDStartIo; 
DriverObject->DriverUnload = DDUnload; 
              :    : 
 

An NT driver can define several Dispatch entry points, but it can define only one StartIo entry point and one Unload entry point in its driver object. At the driver writer’s discretion, an NT driver writer can implement one or more Dispatch routines and define corresponding entry points in the driver object as any one of the following: