册的派发函数地址,而是调用NDIS_OPEN_BLOCK里的派发函数。
struct _NDIS_OPEN_BLOCK
{
PNDIS_MAC_BLOCK MacHandle; // pointer to our MAC
NDIS_HANDLE MacBindingHandle; // context when calling MacXX funcs
PNDIS_ADAPTER_BLOCK AdapterHandle; // pointer to our adapter
PNDIS_PROTOCOL_BLOCK ProtocolHandle; // pointer to our protocol
NDIS_HANDLE ProtocolBindingContext;// context when calling ProtXX funcs
PNDIS_OPEN_BLOCK AdapterNextOpen; // used by adapter''s OpenQueue
PNDIS_OPEN_BLOCK ProtocolNextOpen; // used by protocol''s OpenQueue
PFILE_OBJECT FileObject; // created by operating system
BOOLEAN Closing; // TRUE when removing this struct
BOOLEAN Unloading; // TRUE when processing unload
BOOLEAN NoProtRsvdOnRcvPkt; // Reflect the protocol_options
NDIS_HANDLE CloseRequestHandle; // 0 indicates an internal close
KSPIN_LOCK SpinLock; // guards Closing
PNDIS_OPEN_BLOCK NextGlobalOpen;
//
// These are optimizations for getting to MAC routines. They are not
// necessary, but are here to save a dereference through the MAC block.
//
SEND_HANDLER SendHandler;
TRANSFER_DATA_HANDLER TransferDataHandler;
//
// These are optimizations for getting to PROTOCOL routines. They are not
// necessary, but are here to save a dereference through the PROTOCOL block.
//
SEND_COMPLETE_HANDLER SendCompleteHandler;
TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;
RECEIVE_HANDLER ReceiveHandler;
RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler;
//
// Extentions to the OPEN_BLOCK since Product 1.
//
RECEIVE_HANDLER PostNt31ReceiveHandler;
RECEIVE_COMPLETE_HANDLER PostNt31ReceiveCompleteHandler;
//
// NDIS 4.0 extensions
//
RECEIVE_PACKET_HANDLER ReceivePacketHandler;
SEND_PACKETS_HANDLER SendPacketsHandler;
//
// More NDIS 3.0 Cached Handlers
//
RESET_HANDLER ResetHandler;
REQUEST_HANDLER RequestHandler;
//
// Needed for PnP
//
UNICODE_STRING AdapterName; // Upcased name of the adapter we are bound to
};
这张表是一个单向链接表,并且存放了和PNDIS_OPEN_BLOCK->ProtocolCharacteristic
s
一样的数据收发派发函数,当第N块网卡发送数据包到第N个协议时,就会调用第N个协议
与第N个网卡之间建立的
NDIS_OPEN_BLOCK表里的SendHandler或SendPacketHandler。所以我们还需要对这张表里
的派发函数进行处理(勾挂)。
值得注意的是,在Windows9x/Me/NT的DDK中,NDIS_PROTOCOL_BLOCK的定义是很明确的,
而在Windows 2000/xp的DDK中,并没有该结构的详细定义,也就是说该结构在Windows2
000/xp下是非公开的,因此开发人员需要利用各种调试工具来发掘该结构的详细定义。
也正是因为如此,这种方法对平台的依赖性比较大,需要在程序中判断不同的操作系统
版本而使用不同的结构定义。可以用NdisOpenProtocolConfiguration打开协议配置,用
NdisReadConfiguration查询NDIS版本。
下面的函数注册fake protocol并将PNDIS_PROTOCOL_BLOCK结构存在ProtHandle中NDIS_
HANDLE GetProtocolBlock()
{
NDIS_PROTOCOL_CHARACTERISTICS PChars;
NDIS_STRING Name;
NDIS_HANDLE ProtHandle;
NDIS_STATUS Status;
NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
PChars.MajorNdisVersion = 5;
PChars.MinorNdisVersion = 0;
NdisInitUnicodeString(&Name, L"WssFW"); // Protocol name
PChars.Name = Name;
PChars.OpenAdapterCompleteHandler = NULL;
PChars.CloseAdapterCompleteHandler = NULL;
PChars.SendCompleteHandler = NULL;
PChars.TransferDataCompleteHandler = NULL;
PChars.ResetCompleteHandler = NULL;
PChars.RequestCompleteHandler = NULL;
PChars.ReceiveHandler = NULL;
PChars.ReceiveCompleteHandler = NULL;
PChars.StatusHandler = NULL;
PChars.StatusCompleteHandler = NULL;
PChars.BindAdapterHandler = NULL;
PChars.UnbindAdapterHandler = NULL;
PChars.UnloadHandler = NULL;
PChars.ReceivePacketHandler = NULL;
PChars.PnPEventHandler= NULL;
NdisRegisterProtocol(&Status,
&ProtHandle,
&PChars,
sizeof(NDIS_PROTOCOL_CHARACTERIS
TICS));
ASSERT(Status == NDIS_STATUS_SUCCESS);
if(Status == NDIS_STATUS_SUCCESS)
return ProtHandle;
else
return NULL;
}
下