/*++ Copyright (c) 2000 Microsoft Corporation Module Name: ndisprot.h Abstract: Data structures, defines and function prototypes for NDISPROT. Environment: Kernel mode only. Revision History: --*/ #ifndef __NDISPROT__H #define __NDISPROT__H #define NT_DEVICE_NAME L"//Device//NdisProt" // Symbolic名称,供R3层打开时候用 #define DOS_DEVICE_NAME L"//DosDevices//NdisProt" // // Abstract types // // 在ndis.h中看到: // typedef struct _NDIS_EVENT // { // KEVENT Event; //} NDIS_EVENT, *PNDIS_EVENT // NDIS_EVENT就是KEVENT,KEVENT就是个长整型指针 typedef NDIS_EVENT NPROT_EVENT; // MAC地址长度是6个字节,比如 00-25-64-A7-25-B2 #define NPROT_MAC_ADDR_LEN 6 // Open Context代表打开我们的设备对象 // The Open Context represents an open of our device object. // 正在处理来自NDIS的BindAdapter时候分配这个Context对象 // We allocate this on processing a BindAdapter from NDIS, // 当引用计数为0时,释放这个Context对象 // and free it when all references (see below) to it are gone. // --------------------------------------------------------------------------- // 绑定/解除绑定到NDIS设备: // Binding/unbinding to an NDIS device: // 正在处理来自NDIS的BindAdapter时,我们绑定到指定的NDIS设备对象(miniport) // On processing a BindAdapter call from NDIS, we set up a binding // to the specified NDIS device (miniport). This binding is // 当NDIS通过调用我们设置的UnbindAdapter例程句柄,向我们寻味是否解除这个绑定 // torn down when NDIS asks us to Unbind by calling // our UnbindAdapter handler. // --------------------------------------------------------------------------- // 接收数据 // Receiving data: // 当一个NDIS绑定存在时候,读请求(read IRPs)是队列化在这个结构体 // While an NDIS binding exists, read IRPs are queued on this // 当包到达时候被处理 // structure, to be processed when packets are received. // 如果数据到达,但又不是挂起的读请求(read IRP),我们把它排队。 // If data arrives in the absense of a pended read IRP, we // 扩展一个packet,我们保存最后一个包的内容 // queue it, to the extent of one packet, i.e. we save the // contents of the latest packet received. We fail read IRPs // 正在解除绑定或者已经解除绑定,我们失败这个读请求(read IRPs) // received when no NDIS binding exists (or is in the process // of being torn down). // --------------------------------------------------------------------------- // 发送数据 // Sending data: // 写请求(Write IRPs)用来发送数据。每个写请求(Write IRPs)映射为一个单个的NDIS包 // Write IRPs are used to send data. Each write IRP maps to // 写请求(Write IRP)完成代表包发送完成 // a single NDIS packet. Packet send-completion is mapped to // 我们使用NDIS 5.1 CancelSend(取消发送请求)支持取消写请求(Write IRP) // write IRP completion. We use NDIS 5.1 CancelSend to support // write IRP cancellation. Write IRPs that arrive when we don't // 当我们没有一个活动的NDIS绑定时候写请求(write IRP)失败 // have an active NDIS binding are failed. // 引用计数 // Reference count: // 以下是长久的引用 // The following are long-lived references: // OPEN_DEVICE ioctl (goes away on processing a Close IRP) // Pended read IRPs // Queued received packets // Uncompleted write IRPs (outstanding sends) // Existence of NDIS binding // typedef struct _NDISPROT_OPEN_CONTEXT { LIST_ENTRY Link; // Link into global list ULONG Flags; // State information ULONG RefCount; NPROT_LOCK Lock; PFILE_OBJECT pFileObject; // Set on OPEN_DEVICE NDIS_HANDLE BindingHandle; NDIS_HANDLE SendPacketPool; NDIS_HANDLE SendBufferPool; NDIS_HANDLE RecvPacketPool; NDIS_HANDLE RecvBufferPool; ULONG MacOptions; ULONG MaxFrameSize; LIST_ENTRY PendedWrites; // pended Write IRPs ULONG PendedSendCount; LIST_ENTRY PendedReads; // pended Read IRPs ULONG PendedReadCount; LIST_ENTRY RecvPktQueue; // queued rcv packets ULONG RecvPktCount; NET_DEVICE_POWER_STATE PowerState; // D0 设备已经准备好了 NDIS_EVENT PoweredUpEvent; // signalled iff PowerState is D0 NDIS_STRING DeviceName; // used in NdisOpenAdapter NDIS_STRING DeviceDescr; // friendly name NDIS_STATUS BindStatus; // for Open/CloseAdapter NPROT_EVENT BindEvent; // for Open/CloseAdapter BOOLEAN bRunningOnWin9x;// TRUE if Win98/SE/ME, FALSE if NT ULONG oc_sig; // Signature for sanity UCHAR CurrentAddress[NPROT_MAC_ADDR_LEN]; PIRP StatusIndicationIrp; } NDISPROT_OPEN_CONTEXT, *PNDISPROT_OPEN_CONTEXT; #define oc_signature 'OiuN' // // Definitions for Flags above. // // 绑定的状态,有5种 #define NUIOO_BIND_IDLE 0x00000000 #define NUIOO_BIND_OPENING 0x00000001 #define NUIOO_BIND_FAILED 0x00000002 #define NUIOO_BIND_ACTIVE 0x00000004 #define NUIOO_BIND_CLOSING 0x00000008 #define NUIOO_BIND_FLAGS 0x0000000F // State of the binding // 打开的状态,有2种 #define NUIOO_OPEN_IDLE 0x00000000 #define NUIOO_OPEN_ACTIVE 0x00000010 #define NUIOO_OPEN_FLAGS 0x000000F0 // State of the I/O open // 复位的状态,有2种 #define NUIOO_RESET_IN_PROGRESS 0x00000100 #define NUIOO_NOT_RESETTING 0x00000000 #define NUIOO_RESET_FLAGS 0x00000100 // ? #define NUIOO_MEDIA_CONNECTED 0x00000000 #define NUIOO_MEDIA_DISCONNECTED 0x00000200 #define NUIOO_MEDIA_FLAGS 0x00000200 // 正在读 #define NUIOO_READ_SERVICING 0x00100000 // Is the read service // routine running? #define NUIOO_READ_FLAGS 0x00100000 // 收到解除绑定 #define NUIOO_UNBIND_RECEIVED 0x10000000 // Seen NDIS Unbind? #define NUIOO_UNBIND_FLAGS 0x10000000 // // Globals: // typedef struct _NDISPROT_GLOBALS { PDRIVER_OBJECT pDriverObject; PDEVICE_OBJECT ControlDeviceObject; NDIS_HANDLE NdisProtocolHandle; UCHAR PartialCancelId; // for cancelling sends ULONG LocalCancelId; LIST_ENTRY OpenList; // of OPEN_CONTEXT structures NPROT_LOCK GlobalLock; // to protect the above // 绑定完成标志 NPROT_EVENT BindsComplete; // have we seen NetEventBindsComplete? } NDISPROT_GLOBALS, *PNDISPROT_GLOBALS; // // NDIS Request context structure // typedef struct _NDISPROT_REQUEST { NDIS_REQUEST Request; NPROT_EVENT ReqEvent; ULONG Status; } NDISPROT_REQUEST, *PNDISPROT_REQUEST; // ? #define NUIOO_PACKET_FILTER (NDIS_PACKET_TYPE_DIRECTED| / NDIS_PACKET_TYPE_MULTICAST| / NDIS_PACKET_TYPE_BROADCAST) // // Send packet pool bounds // // 发送包的缓冲区的边界,最小20,最大400 #define MIN_SEND_PACKET_POOL_SIZE 20 #define MAX_SEND_PACKET_POOL_SIZE 400 // // ProtocolReserved in sent packets. We save a pointer to the IRP // that generated the send. // RefCount决定是否释放包(表明包池中该包已不再有效) // The RefCount is used to determine when to free the packet back // 它用来同步一个线程正在完成发送而另一个线程企图取消该发送的情况 // to its pool. It is used to synchronize between a thread completing // a send and a thread attempting to cancel a send. // typedef struct _NPROT_SEND_PACKET_RSVD { PIRP pIrp; ULONG RefCount; } NPROT_SEND_PACKET_RSVD, *PNPROT_SEND_PACKET_RSVD; // // Receive packet pool bounds // // 接收包的缓冲区的边界,最小4,最大20 #define MIN_RECV_PACKET_POOL_SIZE 4 #define MAX_RECV_PACKET_POOL_SIZE 20 // // Max receive packets we allow to be queued up // // 允许排队等候的最大接收包的数目 #define MAX_RECV_QUEUE_SIZE 4 // 把收到的包队列化等待读取,Read IRPs发生时会读取这些包。 // ProtocolReserved in received packets: we link these // packets up in a queue waiting for Read IRPs. // typedef struct _NPROT_RECV_PACKET_RSVD { LIST_ENTRY Link; PNDIS_BUFFER pOriginalBuffer; // used if we had to partial-map } NPROT_RECV_PACKET_RSVD, *PNPROT_RECV_PACKET_RSVD; #include <pshpack1.h> typedef struct _NDISPROT_ETH_HEADER { UCHAR DstAddr[NPROT_MAC_ADDR_LEN]; UCHAR SrcAddr[NPROT_MAC_ADDR_LEN]; USHORT EthType; } NDISPROT_ETH_HEADER; typedef struct _NDISPROT_ETH_HEADER UNALIGNED * PNDISPROT_ETH_HEADER; #include <poppack.h> extern NDISPROT_GLOBALS Globals; #define NPROT_ALLOC_TAG 'oiuN' #ifndef NdisGetPoolFromPacket #define NdisGetPoolFromPacket(_Pkt) (_Pkt->Private.Pool) #endif #ifndef NDIS_PACKET_FIRST_NDIS_BUFFER #define NDIS_PACKET_FIRST_NDIS_BUFFER(_Pkt) ((_Pkt)->Private.Head) #endif // 以下是一些常规的例程声明,省略 // // Prototypes. // DRIVER_INITIALIZE DriverEntry; NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath ); // ... // ... // 如果定义了EX_CALLBACK,就会使用ExCallbk.c中的例程 #ifdef EX_CALLBACK BOOLEAN ndisprotRegisterExCallBack(); VOID ndisprotUnregisterExCallBack(); VOID ndisprotCallback( PVOID CallBackContext, PVOID Source, PVOID NotifyPresenceCallback ); #else // 否则,只是做简单的定义,需要返回布尔值的定义为TRUE,没有返回值的定义为空 #define ndisprotRegisterExCallBack() TRUE #define ndisprotUnregisterExCallBack() #endif #endif // __NDISPROT__H