struct _NDIS_PROTOCOL_BLOCK
{
PNDIS_OPEN_BLOCK OpenQueue; // queue of opens for this protocol
REFERENCE Ref; // contains spinlock for OpenQueue
UINT Length; // of this NDIS_PROTOCOL_BLOCK struct
NDIS50_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics;// handler addresses
struct _NDIS_PROTOCOL_BLOCK * NextProtocol; // Link to next
ULONG MaxPatternSize;
#if defined(NDIS_WRAPPER)
//
// Protocol filters
//
struct _NDIS_PROTOCOL_FILTER * ProtocolFilter[NdisMediumMax+1];
WORK_QUEUE_ITEM WorkItem; // Used during NdisRegisterProtocol to
// notify protocols of existing drivers.
KMUTEX Mutex; // For serialization of Bind/Unbind requests
PKEVENT DeregEvent; // Used by NdisDeregisterProtocol
#endif
};
typedef struct _NDIS_PROTOCOL_BLOCK NDIS_PROTOCOL_BLOCK, *PNDIS_PROTOCOL_BLOCK;
EXPORT
VOID
NdisRegisterProtocol(
OUT PNDIS_STATUS Status,
OUT PNDIS_PROTOCOL_BLOCK NdisProtocolHandle, /*注意NDIS_HANDLE所指向的就是PNDIS_PROTOCOL_BLOCK的结构,不要有什么怀疑。*/
IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics,
IN UINT CharacteristicsLength
);
有人会问这样就行了吗?真的拦截下来了吗?如果有那位仁兄心急现在就写程序的话,
准会失望的,因为他会发现结果什么东西都没拦截到或偶而会拦截到一些数据包。为什么?
因为NDIS网卡驱动和协议驱动在发送和接收到数居时并不是调用PNDIS_OPEN_BLOCK->ProtocolCharacteristics
里的派发函数。怎么办?
有必要先介绍一下NDIS网卡驱动和协议驱动之间是如何BINDING 的吧,
NdisRegisterProtocol在注册完一个协议后,不久NDIS会通过调用表中
BindAdapterHandler派发函数,通知协议对每一个网卡进行BINDING。或者当系统通PNP找到一块新的网卡时
也会调用BindAdapterHandler对协议进行BINDING。协议在BINDING 调用里,会根据自己的需要使用NdisOpenAdapter
将自身绑定到适合的网卡。并返回NdisBindingHandle.NdisBindingHandle是什么?NdisBindingHandl其实是
指向NDIS_OPEN_BLOCK表的一根指针,那么NDIS_OPEN_BLOCK表有什么用呢?当协议顺利的绑定后,每个绑定的网卡
和每一个协议之间建立了数据传输的通道,而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;
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
VOID
PacketUnload(
IN PDRIVER_OBJECT DriverObject
);
NTSTATUS
PacketDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
PacketCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
NTSTATUS
TCPFilter_Attach(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
TCPFilter_InitDeviceExtension(
IN PTDIH_DeviceExtension pTDIH_DeviceExtension,
IN PDEVICE_OBJECT pFilterDeviceObject,
IN PDEVICE_OBJECT pTargetDeviceObject,
IN PFILE_OBJECT pTargetFileObject,
IN PDEVICE_OBJECT pLowerDeviceObject
);
VOID
TCPFilter_Detach(
IN PDEVICE_OBJECT pDeviceObject
);
status = IoGetDeviceObjectPointer(
IN &uniNtNameString,
IN FILE_READ_ATTRIBUTES,
OUT &pTargetFileObject,
OUT &pTargetDeviceObject
);
if( !NT_SUCCESS(status) )
{
DBGPRINT((\"TCPFilter_Attach: Couldn\'t get the TCP Device Object\\n\"));
pTargetFileObject = NULL;
pTargetDeviceObject = NULL;
return( status );
}
status = IoCreateDevice(
IN DriverObject,
IN sizeof( TDIH_DeviceExtension ),
IN &uniNtNameString,
IN pTargetDeviceObject->DeviceType,
IN pTargetDeviceObject->Characteristics,
IN FALSE,
OUT &pFilterDeviceObject
);
if( !NT_SUCCESS(status) )
{
DBGPRINT((\"TCPFilter_Attach: Couldn\'t create the TCP Filter Device Object\\n\"));
ObDereferenceObject( pTargetFileObject );
pTargetFileObject = NULL;
pTargetDeviceObject = NULL;
return( status );
}
pTDIH_DeviceExtension
= (PTDIH_DeviceExtension )( pFilterDeviceObject->DeviceExtension );
TCPFilter_InitDeviceExtension(
IN pTDIH_DeviceExtension,
IN pFilterDeviceObject,
IN pTargetDeviceObject,
IN pTargetFileObject,
IN pLowerDeviceObject
);