2.1.1 Registering as an NDIS Protocol Driver
A driver registers its ProtocolXxx functions with NDIS in the context of its DriverEntry function by calling NdisRegisterProtocol, defined as follows:
VOID
NdisRegisterProtocol(
OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE NdisProtocolHandle,
IN PNDIS_PROTOCOL_CHARACTERISTICS
ProtocolCharacteristics,
IN UINT CharacteristicsLength
);
The NdisProtocolHandle returned by this call is opaque to a protocol driver. The handle must be retained by the protocol driver and provided as an input parameter in future calls to NDIS, to open an adapter for example.
Before making this call, DriverEntry must do the following:
1.Zero-initialize a structure of type NDIS_PROTOCOL_CHARACTERISTICS, for instance with a call to NdisZeroMemory. This assures that unused members for optional entry points are set to NULL. If the structure is not zeroed, any unused members must be set to NULL before calling NdisRegisterProtocol.
2.Store the addresses of the mandatory ProtocolXxx functions, as well as any optional ProtocolXxx functions the driver exports, in the characteristics structure members, as follows:
BindAdapterHandler
This is an optional function in protocol drivers. A PnP-ready protocol driver specifies this entry point so it can be called by NDIS at the ProtocolBindAdapter function when an adapter is available. Specifying this entry point requires a V4.0 structure at ProtocolCharacteristics.
UnbindAdapterHandler
This is a required function if the protocol driver registered a ProtocolBindAdapter function. Specifying this entry point also requires a V4.0 structure at ProtocolCharacteristics.
OpenAdapterCompleteHandler
This is a required function. If a protocol driver’s call to NdisOpenAdapter returns NDIS_STATUS_PENDING, ProtocolOpenAdapterComplete is subsequently called to complete the binding operation.
CloseAdapterCompleteHandler
This is a required function. If a protocol driver’s call to NdisCloseAdapter returns NDIS_STATUS_PENDING, ProtocolCloseAdapterComplete is subsequently called to complete the unbinding operation.
ReceiveHandler
This is a required function. ProtocolReceive is called with a pointer to a lookahead buffer. If this buffer contains less than the full, received network packet, ProtocolReceive calls NdisTransferData with a protocol-allocated packet descriptor specifiying protocol-allocated buffer(s) to obtain the remainder of the received packet.
ReceiveCompleteHandler
This is a required function. ProtocolReceiveComplete is called to indicate that any received packets previously indicated to ProtocolReceive can now be postprocessed.
TransferCompleteHandler
This is a required function unless the protocol binds itself exclusively to underlying NIC driver(s) that indicate packets with NdisMIndicateReceivePacket. ProtocolTransferDataComplete is called when a previous call to NdisTransferData returned NDIS_STATUS_PENDING and the remaining data has been copied into the protocol-supplied buffers chained to a given packet descriptor.
ReceivePacketHandler
This is an optional function. A ProtocolReceivePacket function should be provided if the protocol driver might be bound to a NIC driver that indicates an array of one or more packets by calling NdisMIndicateReceivePacket. Specifying this entry point requires a V4.0 structure at ProtocolCharacteristics.
SendCompleteHandler
This is a required function. ProtocolSendComplete is called for each packet transmitted with a call to NdisSend that returned NDIS_STATUS_PENDING as the status of the send operation. If an array of packets is sent, ProtocolSendComplete is called once for each packet passed to NdisSendPackets, whether or not it returned pending.
ResetCompleteHandler
This is a required function. ProtocolResetComplete is called when a protocol-initiated reset operation, begun with a call to NdisReset that returned NDIS_STATUS_PENDING, is completed.
RequestCompleteHandler
This is a required function. ProtocolRequestComplete is called when a protocol-initiated query or set operation, begun with a call to NdisRequest that returned NDIS_STATUS_PENDING, is completed.
StatusHandler
This is a required function. ProtocolStatus is called to handle status changes indicated by the underlying NDIS driver.
StatusCompleteHandler
This is a required function. ProtocolStatusComplete is called by NDIS, along with ProtocolStatus, to report the start and end of an NDIS- or NIC-driver-initiated reset operation.
A protocol driver should set the ProtocolCharacteristics TranslateHandler and UnloadHandler members to NULL. The TranslateHandler member is reserved for future use. NDIS never calls an entry point specified in UnloadHandler on Windows NT platforms. Instead, the Windows NT I/O Manager calls the Unload routine that the protocol driver sets in the driver object passed in to the protocol's DriverEntry function.