MSDN系列 14 NDIS Protocol Driver 入门

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                日期: 2004-07-19 16:55
更新: 2004-08-17 16:23
链接: http://www.opencjk.org/~scz/windows/200408171624.txt

--------------------------------------------------------------------------
    ☆ NDIS Protocol Driver
    ☆ ntoskrnl.exe引出的一些运行时函数
    ☆ 一个完整的NDIS Protocol Driver框架
        a) NDIS协议驱动
            1) ndisprotocol.c
            2) sources
            3) makefile
            4) ndisprotocol.inf
        b) NDIS协议驱动的用户态测试程序
            1) ndisprotocoltest.c
            2) sources
            3) makefile
        c) NDIS组件配置程序
        d) 源代码目录结构
        e) 编译
        f) 安装
        g) 测试
        h) 卸载
        i) 一些遗留问题
    ☆ 参考资源

--------------------------------------------------------------------------

☆ NDIS Protocol Driver

[1]给了一张Windows网络架构图,有助于理解NDIS,推荐入门者先看看这张图。

[2]有一些关于Windows网络架构的讨论,这只是一种个人学术观点,仅供参考,不可
当成官方结论。

NDIS(Network Device Interface Specification)提供一个系统的、完整的Wrapper,
NDIS Miniport Driver、NDIS ProtocolDriver等等均属于"插入"这个Wrapper中的"
模块",这些驱动调用Wrapper提供的函数,同时也向Wrapper注册回调函数,整个运
作过程由Wrapper统一调度。Wrapper对应ndis.sys。

TDI Client Driver利用协议驱动上沿引出的TDI接口(Transport Data Interface)实
现命名管道、邮槽、Winsock等等。

下面这些注册表内容对应着Network Control Panel Applet (NCPA):

--------------------------------------------------------------------------
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E972-E325-11CE-BFC1-08002bE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E973-E325-11CE-BFC1-08002BE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E974-E325-11CE-BFC1-08002BE10318}
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Class/{4D36E975-E325-11CE-BFC1-08002BE10318}

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E972-E325-11CE-BFC1-08002BE10318}

    对应GUID_DEVCLASS_NET、Miniport Driver、Net。收到包后NDIS首先调用
    Miniport Driver进行处理。Miniport Driver负责控制网卡硬件特性,在协议驱
    动与网卡之间传递报文。

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E973-E325-11CE-BFC1-08002BE10318}

    对应GUID_DEVCLASS_NETCLIENT、Client Driver、NetClient。"Client for
    Microsoft Networks"即是此类型驱动。负责向用户态提供NetBIOS Client API。

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E974-E325-11CE-BFC1-08002BE10318}

    对应GUID_DEVCLASS_NETSERVICE、Service Driver、NetService。"File and
    Printer Sharing for Microsoft Networks"即是此类型驱动。

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}

    对应GUID_DEVCLASS_NETTRANS、Protocol Driver、NetTrans。负责实现各种网
    络协议,比如tcpip.sys实现了TCP/IP协议。协议驱动接收Miniport Driver上传
    的报文,也接收Client Driver、Service Driver、TDI Client Driver下传的报
    文。
--------------------------------------------------------------------------

中间层驱动(Intermediate Driver)是一种混合型驱动,位于Miniport Driver与协议
驱动之间,对下看起来像协议驱动,对上看起来像Miniport Driver。

在这些不同类型的驱动之间有一种操作叫作"绑定",其本质在于向NDIS Wrapper指明
报文(Packet)的传递路线。

☆ ntoskrnl.exe引出的一些运行时函数

> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find /I "printf"
       1397  574 00052BCB _snprintf
       1398  575 00052C22 _snwprintf
       1406  57D 00052D73 _vsnprintf
       1407  57E 00052DC9 _vsnwprintf
       1430  595 00053D4D sprintf
       1443  5A2 000543E0 swprintf
       1450  5A9 000544F4 vsprintf
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "_str"
       1399  576 00052C92 _stricmp
       1400  577 00052C97 _strlwr
       1401  578 00052CBA _strnicmp
       1402  579 00052CD0 _strnset
       1403  57A 00052D00 _strrev
       1404  57B 00052D30 _strset
       1405  57C 00052D50 _strupr
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find " str"
       1432  597 00053DC0 strcat
       1433  598 00053EB0 strchr
       1434  599 00053F70 strcmp
       1435  59A 00053DB0 strcpy
       1436  59B 00054000 strlen
       1437  59C 00054080 strncat
       1438  59D 000541B0 strncmp
       1439  59E 000541F0 strncpy
       1440  59F 000542F0 strrchr
       1441  5A0 00054320 strspn
       1442  5A1 00054360 strstr
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "wcs"
       1408  57F 00052E38 _wcsicmp
       1409  580 00052E83 _wcslwr
       1410  581 00052EAF _wcsnicmp
       1411  582 00052F08 _wcsnset
       1412  583 00052F31 _wcsrev
       1413  584 00052F63 _wcsupr
       1422  58D 000531DB mbstowcs
       1451  5AA 0005454B wcscat
       1452  5AB 00054591 wcschr
       1453  5AC 000545B3 wcscmp
       1454  5AD 00054575 wcscpy
       1455  5AE 000545E5 wcscspn
       1456  5AF 00054628 wcslen
       1457  5B0 0005463E wcsncat
       1458  5B1 0005467B wcsncmp
       1459  5B2 000546B0 wcsncpy
       1460  5B3 000546ED wcsrchr
       1461  5B4 0005471D wcsspn
       1462  5B5 00054763 wcsstr
       1463  5B6 000547C1 wcstombs
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "mem"
       1424  58F 00053290 memchr
       1425  590 00053340 memcpy
       1426  591 00053680 memmove
       1427  592 000539C0 memset
> dumpbin /exports %systemroot%/system32/ntoskrnl.exe | find "_ito"
       1393  570 00052B76 _itoa
       1394  571 00052BA0 _itow

☆ 一个完整的NDIS Protocol Driver框架

a) NDIS协议驱动

XP SP1 DDK自带了一个名为ndisuio的例子(NDIS User mode I/O Protocol),但我没
有找到NT4 DDK中名为packet的例子。参[3]、[4]、[5],这些都是完整的协议驱动源
代码。

ndisuio演示了"connection-less NDIS 5.0/5.1 protocol driver",用户态程序可
简单地通过ReadFile/WriteFile直接操作链路层数据(物理帧)。对于sniffer一类的
需求,这已经足够了。ndisuio没有在其上沿提供TDI接口。ndisuio做了很多限制,
使得我们无法随心所欲地操作链路层数据。假设有如下结构:

struct etherheader
{
    unsigned char           eth_dst[6]; /* destination eth addr */
    unsigned char           eth_src[6]; /* source ether addr    */
    unsigned short int      eth_type;   /* packet type ID field */
};

ndisuio在DispatchWrite()例程中对eth_src、eth_type进行检查,发送报文时不能
伪造源MAC,必须匹配事先指定的eth_type。

ndisuio允许用户态程序通过DeviceIoControl()指定eth_type,但其在
DispatchDeviceControl()例程中做了限制,不能任意指定eth_type。

ndisuio在ProtocolReceive()、ProtocolReceivePacket()例程中对eth_type进行检
查,只接收与事先指定的eth_type相匹配的报文。

ndisuio允许用户态程序通过DeviceIoControl()向Miniport Driver设置OID,但其在
DispatchDeviceControl()例程中做了限制,只允许设置部分OID。

从ndisuio例子所附用户态测试程序的代码来看,曾经有一个版本的ndisuio未做前述
限制,至少发送报文时可以伪造源MAC。现在我们要做的就是简单地注释掉相应代码,
使得可以随心所欲地操作链路层数据。

XP事实上缺省安装了ndisuio,可用"net start ndisuio"加载这个隐藏的协议驱动。
据tk讲,2000也缺省安装ndisuio,我不确认是某个Service Pack带进来的,还是最
初就有。由于存在前述限制,ndisuio对我们来讲没有多少意义。

下面是XP SP1中与ndisuio相关的注册表内容,NDI是"Network Device Installer"的
缩写。

--------------------------------------------------------------------------
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}]
"Characteristics"=dword:00000028
"InfPath"="ndisuio.inf"
"InfSection"="Install"
"Description"="NDIS Usermode I/O Protocol"
"ComponentId"="ms_ndisuio"

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}/Ndi]
"Service"="Ndisuio"
"HelpText"="A driver to support user-mode I/O on NDIS devices"

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Network/{4D36E975-E325-11CE-BFC1-08002BE10318}/{03130807-B5F2-47A1-81B0-B870D16F272B}/Ndi/Interfaces]
"UpperRange"="noupper"
"LowerRange"="ndis5,ndis4,ndis5_uio"
--------------------------------------------------------------------------
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO]
"NextInstance"=dword:00000001

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000]
"Service"="Ndisuio"
"Legacy"=dword:00000001
"ConfigFlags"=dword:00000000
"Class"="LegacyDriver"
"ClassGUID"="{8ECC055D-047F-11D1-A537-0000F8753ED1}"
"DeviceDesc"="NDIS Usermode I/O Protocol"
"Capabilities"=dword:00000000

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000/LogConf]

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/Root/LEGACY_NDISUIO/0000/Control]
"ActiveService"="Ndisuio"
--------------------------------------------------------------------------
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Ndisuio]
"Type"=dword:00000001
"Start"=dword:00000003
"ErrorControl"=dword:00000001
"Tag"=dword:0000000c
"ImagePath"=hex(2):53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,44,00,/
  52,00,49,00,56,00,45,00,52,00,53,00,5c,00,6e,00,64,00,69,00,73,00,75,00,69,/
  00,6f,00,2e,00,73,00,79,00,73,00,00,00
"DisplayName"="NDIS Usermode I/O Protocol"
"Group"="NDIS"
"Description"="NDIS Usermode I/O Protocol"

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Ndisuio/Linkage]
"Bind"=hex(7):5c,00,44,00,65,00,76,00,69,00,63,00,65,00,5c,00,7b,00,33,00,46,/
  00,32,00,46,00,37,00,46,00,35,00,33,00,2d,00,39,00,34,00,43,00,43,00,2d,00,/
  34,00,43,00,38,00,33,00,2d,00,42,00,36,00,38,00,33,00,2d,00,34,00,33,00,30,/
  00,38,00,43,00,35,00,37,00,33,00,37,00,31,00,32,00,44,00,7d,00,00,00,5c,00,/
  44,00,65,00,76,00,69,00,63,00,65,00,5c,00,7b,00,34,00,46,00,44,00,45,00,38,/
  00,42,00,37,00,42,00,2d,00,31,00,42,00,41,00,31,00,2d,00,34,00,42,00,30,00,/
  41,00,2d,00,39,00,30,00,32,00,39,00,2d,00,31,00,34,00,31,00,45,00,31,00,33,/
  00,35,00,35,00,39,00,45,00,36,00,39,00,7d,00,00,00,00,00
"Route"=hex(7):22,00,7b,00,33,00,46,00,32,00,46,00,37,00,46,00,35,00,33,00,2d,/
  00,39,00,34,00,43,00,43,00,2d,00,34,00,43,00,38,00,33,00,2d,00,42,00,36,00,/
  38,00,33,00,2d,00,34,00,33,00,30,00,38,00,43,00,35,00,37,00,33,00,37,00,31,/
  00,32,00,44,00,7d,00,22,00,00,00,22,00,7b,00,34,00,46,00,44,00,45,00,38,00,/
  42,00,37,00,42,00,2d,00,31,00,42,00,41,00,31,00,2d,00,34,00,42,00,30,00,41,/
  00,2d,00,39,00,30,00,32,00,39,00,2d,00,31,00,34,00,31,00,45,00,31,00,33,00,/
  35,00,35,00,39,00,45,00,36,00,39,00,7d,00,22,00,00,00,00,00
"Export"=hex(7):5c,00,44,00,65,00,76,00,69,00,63,00,65,00,5c,00,4e,00,64,00,69,/
  00,73,00,75,00,69,00,6f,00,5f,00,7b,00,33,00,46,00,32,00,46,00,37,00,46,00,/
  35,00,33,00,2d,00,39,00,34,00,43,00,43,00,2d,00,34,00,43,00,38,00,33,00,2d,/
  00,42,00,36,00,38,00,33,00,2d,00,34,00,33,00,30,00,38,00,43,00,35,00,37,00,/
  33,00,37,00,31,00,32,00,44,00,7d,00,00,00,5c,00,44,00,65,00,76,00,69,00,63,/
  00,65,00,5c,00,4e,00,64,00,69,00,73,00,75,00,69,00,6f,00,5f,00,7b,00,34,00,/
  46,00,44,00,45,00,38,00,42,00,37,00,42,00,2d,00,31,00,42,00,41,00,31,00,2d,/
  00,34,00,42,00,30,00,41,00,2d,00,39,00,30,00,32,00,39,00,2d,00,31,00,34,00,/
  31,00,45,00,31,00,33,00,35,00,35,00,39,00,45,00,36,00,39,00,7d,00,00,00,00,/
  00

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Ndisuio/Security]
"Security"=hex:01,00,14,80,90,00,00,00,9c,00,00,00,14,00,00,00,30,00,00,00,02,/
  00,1c,00,01,00,00,00,02,80,14,00,ff,01,0f,00,01,01,00,00,00,00,00,01,00,00,/
  00,00,02,00,60,00,04,00,00,00,00,00,14,00,fd,01,02,00,01,01,00,00,00,00,00,/
  05,12,00,00,00,00,00,18,00,ff,01,0f,00,01,02,00,00,00,00,00,05,20,00,00,00,/
  20,02,00,00,00,00,14,00,8d,01,02,00,01,01,00,00,00,00,00,05,0b,00,00,00,00,/
  00,18,00,fd,01,02,00,01,02,00,00,00,00,00,05,20,00,00,00,23,02,00,00,01,01,/
  00,00,00,00,00,05,12,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Ndisuio/Enum]
"0"="Root//LEGACY_NDISUIO//0000"
"Count"=dword:00000001
"NextInstance"=dword:00000001
--------------------------------------------------------------------------

名为"Characteristics"的键值对应INF文件中的Characteristics项,0x28表示逻辑
或NCF_HIDDEN(0x08)、NCF_NOT_USER_REMOVABLE(0x20),即NCPA中不可见、不可通过
NCPA或设备管理器删除。调试协议驱动时,应在INF文件中指定0x00,这样才便于删
除、重新增加并测试。

1) ndisprotocol.c

本文所给完整框架(安装/卸载、驱动、用户态测试程序)完全是DDK自带例子代码,我
可写不出这么大的框架代码来。如有疑问,请问微软。

--------------------------------------------------------------------------
/*
* For x86/EWindows XP SP1 & VC 7 & Windows DDK 2600.1106
*/

/************************************************************************
*                                                                      *
*                               Head File                              *
*                                                                      *
************************************************************************/

#include
#include
#include
#include
#include
#include

/************************************************************************
*                                                                      *
*                               Macro                                  *
*                                                                      *
************************************************************************/

#define INTERNALNAME                                L"//Device//NDISProtocolInternal"
#define EXTERNALNAME                                L"//??//NDISProtocolExternal"
#define PRIVATETAG                                  'OFSN'
#define NDISPROTOCOL_INDEX                          0x0800
#define IOCTL_NDISPROTOCOL_GET_PRIVATEFLAGS         CTL_CODE    /
(                                                               /
    FILE_DEVICE_NETWORK,                                        /
    NDISPROTOCOL_INDEX + 0,                                     /
    METHOD_BUFFERED,                                            /
    FILE_READ_ACCESS                                            /
)
#define IOCTL_NDISPROTOCOL_SET_PRIVATEFLAGS         CTL_CODE    /
(                                                               /
    FILE_DEVICE_NETWORK,                                        /
    NDISPROTOCOL_INDEX + 1,                                     /
    METHOD_BUFFERED,                                            /
    FILE_WRITE_ACCESS                                           /
)
#define IOCTL_NDISPROTOCOL_OPEN_DEVICE              CTL_CODE    /
(                                                               /
    FILE_DEVICE_NETWORK,                                        /
    NDISPROTOCOL_INDEX + 2,                                     /
    METHOD_BUFFERED,                                            /
    FILE_READ_ACCESS | FILE_WRITE_ACCESS                        /
)
#define IOCTL_NDISPROTOCOL_GET_OID_VALUE            CTL_CODE    /
(                                                               /
    FILE_DEVICE_NETWORK,                                        /
    NDISPROTOCOL_INDEX + 3,                                     /
    METHOD_BUFFERED,                                            /
    FILE_READ_ACCESS                                            /
)
#define IOCTL_NDISPROTOCOL_SET_OID_VALUE            CTL_CODE    /
(                                                               /
    FILE_DEVICE_NETWORK,                                        /
    NDISPROTOCOL_INDEX + 4,                                     /
    METHOD_BUFFERED,                                            /
    FILE_WRITE_ACCESS                                           /
)
#define IOCTL_NDISPROTOCOL_SET_ETHER_TYPE           CTL_CODE    /
(                                                               /
    FILE_DEVICE_NETWORK,                                        /
    NDISPROTOCOL_INDEX + 5,                                     /
    METHOD_BUFFERED,                                            /
    FILE_WRITE_ACCESS                                           /
)
#define IOCTL_NDISPROTOCOL_QUERY_BINDING            CTL_CODE    /
(                                                               /
    FILE_DEVICE_NETWORK,                                        /
    NDISPROTOCOL_INDEX + 6,                                     /
    METHOD_BUFFERED,                                            /
    FILE_READ_ACCESS                                            /
)
#define IOCTL_NDISPROTOCOL_BIND_WAIT                CTL_CODE    /
(                                                               /
    FILE_DEVICE_NETWORK,                                        /
    NDISPROTOCOL_INDEX + 7,                                     /
    METHOD_BUFFERED,                                            /
    FILE_READ_ACCESS | FILE_WRITE_ACCESS                        /
)

#define PRIVATEFLAGS_ETHERTYPE                      0x00000001
#define PRIVATEFLAGS_DEFAULT                        0x00000001

typedef struct _DEVICE_EXTENSION
{
    PDEVICE_OBJECT          DeviceObject;
    ULONG                   DeviceNumber;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

#define PRIVATEMIN(x,y)                             ((x)<(y)?(x):(y))
#define SET_FLAGS(_FlagsVar, _Mask, _BitsToSet)     (_FlagsVar) = ((_FlagsVar) & ~(_Mask)) | (_BitsToSet)
#define TEST_FLAGS(_FlagsVar, _Mask, _BitsToCheck)  (((_FlagsVar) & (_Mask)) == (_BitsToCheck))

#define PRIVATE_BIND_IDLE                           0x00000000
#define PRIVATE_BIND_OPENING                        0x00000001
#define PRIVATE_BIND_FAILED                         0x00000002
#define PRIVATE_BIND_ACTIVE                         0x00000004
#define PRIVATE_BIND_CLOSING                        0x00000008
#define PRIVATE_BIND_FLAGS                          0x0000000F

#define PRIVATE_OPEN_IDLE                           0x00000000
#define PRIVATE_OPEN_ACTIVE                         0x00000010
#define PRIVATE_OPEN_FLAGS                          0x000000F0

#define PRIVATE_RESET_IN_PROGRESS                   0x00000100
#define PRIVATE_NOT_RESETTING                       0x00000000
#define PRIVATE_RESET_FLAGS                         0x00000100

#define PRIVATE_MEDIA_CONNECTED                     0x00000000
#define PRIVATE_MEDIA_DISCONNECTED                  0x00000200
#define PRIVATE_MEDIA_FLAGS                         0x00000200

#define PRIVATE_READ_SERVICING                      0x00100000
#define PRIVATE_READ_FLAGS                          0x00100000

#define PRIVATE_UNBIND_RECEIVED                     0x10000000
#define PRIVATE_UNBIND_FLAGS                        0x10000000

#define DEFAULT_PACKET_FILTER                       (NDIS_PACKET_TYPE_DIRECTED|NDIS_PACKET_TYPE_MULTICAST|NDIS_PACKET_TYPE_BROADCAST)

typedef struct _ADAPTER_CONTEXT
{
    LIST_ENTRY              Link;
    NDIS_SPIN_LOCK          Lock;
    ULONG                   ReferenceCount;
    ULONG                   Flags;
    PFILE_OBJECT            FileObject;
    NDIS_STRING             DeviceName;
    NDIS_STRING             AdapterInstanceName;
    NDIS_STATUS             BindStatus;
    NDIS_EVENT              BindEvent;
    NDIS_HANDLE             SendPacketPool;
    NDIS_HANDLE             SendBufferPool;
    NDIS_HANDLE             RecvPacketPool;
    NDIS_HANDLE             RecvBufferPool;
    LIST_ENTRY              PendedWrites;
    ULONG                   PendedWriteCount;
    LIST_ENTRY              PendedReads;
    ULONG                   PendedReadCount;
    LIST_ENTRY              RecvPacketQueue;
    ULONG                   RecvPacketCount;
    NDIS_HANDLE             NdisBindingHandle;
    UCHAR                   CurrentAddress[6];
    ULONG                   MacOptions;
    ULONG                   MaximumFrameSize;
    NET_DEVICE_POWER_STATE  PowerState;
    NDIS_EVENT              PoweredUpEvent;
} ADAPTER_CONTEXT, *PADAPTER_CONTEXT;

typedef struct _BINDINGINFO
{
    ULONG                   BindingIndex;               // 0-based binding number
    ULONG                   DeviceNameOffset;           // from start of this struct
    ULONG                   DeviceNameLength;           // in bytes
    ULONG                   AdapterInstanceNameOffset;  // from start of this struct
    ULONG                   AdapterInstanceNameLength;  // in bytes
} BINDINGINFO, *PBINDINGINFO;

typedef struct _OIDVALUE
{
    NDIS_OID                Oid;
    UCHAR                   Value[sizeof(ULONG)];
} OIDVALUE, *POIDVALUE;

#define MIN_SEND_PACKET_NUM                         20
#define MAX_SEND_PACKET_NUM                         400

typedef struct _SEND_PACKET_PROTOCOLRESERVED
{
    PIRP                    Irp;
    ULONG                   ReferenceCount;

} SEND_PACKET_PROTOCOLRESERVED, *PSEND_PACKET_PROTOCOLRESERVED;

#define MIN_RECV_PACKET_NUM                         4
#define MAX_RECV_PACKET_NUM                         20
#define MAX_RECV_BUFFER_NUM                         20
#define MAX_RECV_QUEUE_NUM                          4

typedef struct _RECV_PACKET_PROTOCOLRESERVED
{
    LIST_ENTRY              Link;
    PNDIS_BUFFER            Buffer;
} RECV_PACKET_PROTOCOLRESERVED, *PRECV_PACKET_PROTOCOLRESERVED;

#define GETBUFFER(x)                                (((PRECV_PACKET_PROTOCOLRESERVED)(x)->ProtocolReserved)->Buffer)
#define GETLINK(x)                                  (&((PRECV_PACKET_PROTOCOLRESERVED)(x)->ProtocolReserved)->Link)
#define GETRECVPACKET(x)                            CONTAINING_RECORD(CONTAINING_RECORD(x, RECV_PACKET_PROTOCOLRESERVED, Link), NDIS_PACKET, ProtocolReserved)
#define GETREFERENCECOUNT(x)                        (((PSEND_PACKET_PROTOCOLRESERVED)(x)->ProtocolReserved)->ReferenceCount)
#define GETIRP(x)                                   (((PSEND_PACKET_PROTOCOLRESERVED)(x)->ProtocolReserved)->Irp)
#define GETCANCELID()                               (HighCancelId | (NdisInterlockedIncrement(&LowCancelId) & 0x00FFFFFF))

typedef struct _REQUEST_CONTEXT
{
    NDIS_REQUEST            NdisRequest;
    NDIS_EVENT              NdisRequestEvent;
    ULONG                   Status;
} REQUEST_CONTEXT, *PREQUEST_CONTEXT;

#pragma pack( push, 1 )

struct etherheader
{
    unsigned char           eth_dst[6]; /* destination eth addr */
    unsigned char           eth_src[6]; /* source ether addr    */
    unsigned short int      eth_type;   /* packet type ID field */
};

#pragma pack( pop )

#define swap_16(x)                                  ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
#define swap_32(x)                                  ((((x) >> 24) & 0xff) | (((x) & 0xff) << 24) | (((x) >> 8) & 0xff00) | (((x) & 0xff00) << 8))

#define ETH_P_IP                                    0x0800          /* Internet Protocol packet     */
#define ETH_P_ARP                                   0x0806          /* Address Resolution packet    */
#define ETH_P_RARP                                  0x8035          /* Reverse Addr Res packet      */
#define ETH_P_8021P                                 0x8100          /* 802.1p                       */
#define ETH_P_DEFAULT                               ETH_P_ARP

/************************************************************************
*                                                                      *
*                            Function Prototype                        *
*                        &nbs

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

你可能感兴趣的:(MSDN系列 14 NDIS Protocol Driver 入门)