Like all NT objects, a driver object is opaque: only the defining NT component (here, the I/O Manager) "knows" an object type's internal structure and can access all the data an object contains directly. The defining NT component usually exports support routines that NT drivers and other NT components can call to manipulate that component's objects. For example, the NT Kernel exports support routines that the I/O Manager calls to initialize and connect interrupt objects when a lowest-level NT driver registers its interrupt service routine (ISR), shown in Figure 2.4 as DDInterruptService.
To maintain driver portability, consider this implementation guideline concerning NT objects
NT drivers must use the system-supplied support routines to manipulate NT objects. The defining NT component can change the internal structure of its object types at any time.
However, the I/O Manager exports no support routines to manipulate driver objects. Driver objects are used only by the I/O Manager to keep track of currently loaded NT drivers. Some fields within a driver object are opaque: "known" only to the I/O Manager and used only by the I/O Manager. Others are partially opaque: NT driver writers must know certain field names to define Dispatch, StartIo, and Unload entry points and to use the registry. Nevertheless, NT driver writers should neither attempt to use unpublished fields within a driver object nor make assumptions about the locations of any driver object fields that are named in this documentation. Otherwise, NT driver writers cannot maintain the portability of their drivers from one Windows NT platform to another.
Unlike most NT objects, which are wholly opaque outside the defining NT component, the driver object is partially opaque to NT drivers because each driver becomes part of the NT I/O system when the driver is loaded.