Initializing an Intermediate Driver
An NDIS intermediate driver registers its MiniportXxx functions and its ProtocolXxx functions in the context of its DriverEntry routine. To register its MiniportXxx functions, an intermediate driver must call the NdisMRegisterMiniportDriver function with the NDIS_INTERMEDIATE_DRIVER flag set. This flag is in the NDIS_MINIPORT_DRIVER_CHARACTERISTICS structure that the driver passes at MiniportDriverCharacteristics. To register its ProtocolXxx functions, an intermediate driver must call the NdisRegisterProtocolDriver function.
DriverEntry returns STATUS_SUCCESS, or its equivalent NDIS_STATUS_SUCCESS, if the driver registered as an NDIS intermediate driver successfully. If DriverEntry fails initialization by propagating an error status that was returned by an NdisXxx function or by a kernel-mode support routine, the driver will not remain loaded. DriverEntry must execute synchronously; that is, it cannot return STATUS_PENDING or its equivalent NDIS_STATUS_PENDING.
To register the intermediate driver with NDIS, the DriverEntry routine must, at a minimum:
- Call the NdisMRegisterMiniportDriver function with the NDIS_INTERMEDIATE_DRIVER flag set to register the driver's MiniportXxx functions.
- Call the NdisRegisterProtocolDriver function to register the driver's ProtocolXxx functions if the driver subsequently binds itself to an underlying NDIS driver.
- Call the NdisIMAssociateMiniport function to inform NDIS about the association between the driver's miniport upper edge and protocol lower edge.
If an error occurs in DriverEntry after NdisMRegisterMiniportDriver returns successfully, the driver must call the NdisMDeregisterMiniportDriver function before DriverEntry returns. If DriverEntry succeeds, the driver must call NdisMDeregisterMiniportDriver from its MiniportDriverUnload function.
Intermediate drivers share most of the DriverEntry requirements of protocol drivers and miniport drivers.
The initialization of an intermediate driver's virtual miniport occurs when the driver calls the NdisIMInitializeDeviceInstanceEx function from its ProtocolBindAdapterEx function.
NDIS calls the ProtocolBindAdapterEx function after all underlying miniport drivers have initialized.
In effect, the DriverEntry function of an NDIS intermediate driver can ignore the RegistryPath pointer after passing it to NdisMRegisterMiniportDriver. Such a driver can also ignore the DriverObject pointer after passing it to NdisMRegisterMiniportDriver. However, the driver should save the miniport driver handle value that is returned by NdisMRegisterMiniportDriver at NdisMiniportDriverHandle and the protocol handle value that is returned by NdisRegisterProtocolDriver at NdisProtocolHandle for subsequent calls to NdisXxx functions. The intermediate driver's ProtocolBindAdapterEx function binds the driver to each underlying miniport driver before its MiniportInitializeEx function is called to initialize the intermediate driver's virtual miniport. Still higher level protocol drivers subsequently bind themselves to the virtual miniport that it creates. This strategy enables an NDIS intermediate driver to allocate resources at the creation of the virtual miniport according to the features of the underlying miniport driver to which it is bound.