tdi防火墙驱动,这个构架是tdifw这个开源网站率先提出的。微软也发扬他一贯的作风,在win7里面全面封杀这种防火墙驱动的写法。对于微软,技术的霸道和垄断不用质疑。可是tdi防火墙驱动依照他良好的架构,和简易的编程一举囊获了从win2000-win vista的这些个版本,至于之后出来的这个怪胎,现在国人对于他的态度是直接启用ndsi驱动,有种你微软把这个也封杀掉,我看你pppoe咋做,我看你tcp咋做,我看你虚拟网卡咋做。
  所以将来可能防火墙都有两个以上的内核,一个是nt-vista的,另外一个是win7以后的,听说微软已经开始招募win8开发人员了。看来微软是被这win7的销售高潮冲晕了。要知道现在多数客户还在死守xp,要知道还有很多程序员没转vista,要知道你的win7现在还没有引来良性发展。嗨~~~~~~中国啥时候能出一个操作系统啊,甚至是黑屏cmd,甚至是没有命令,咱都支持,我**个肺微软。
tdi驱动模式本着是irp过滤型驱动的模型做的,也就是标准的attach模型。
1.创建设备
2.attach上自己想要attach的设备
3.重新定向自己想要定向的所有irp
4.建立irp完成机制,对于一些不能等待的irp请求,做完成等待处理
(所谓完成等待,这就是微软这些*人想出来的鳖招,我们不能叫一个Irp等待,因为这样我们的io控制器负担会很大,非常大,所以你必须先把irp直接传递下去,或者作短暂处理,不要做线程切换这样负担极大的处理,否则我就蓝给你看,等系统驱动处理完成,你要真的想要等待一下,好,我微软可以容忍,你只能在你自己的进程里面等,随你等多久,只要不甘我事就行,所以,你在完成回调函数里面想等多久等多久,压力分摊给各个进程,之后就美其名曰的掏出一堆的中断级别,什么dispatch或者是passlevel,看吧,我微软够专业吧?我**个肥佬~~~~~~

代码重点如下:
1.变量声明
#define kprintf DbgPrint
//每个设备所独有的空间扩展
typedef struct _DEVICE_EXTENSION
{
  ULONG  StateVariable;
  PDEVICE_OBJECT OrgNetDevice;//原始设备指针
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
#define DEVICE_EXT(a) (PDEVICE_EXTENSION)a->DeviceExtension//获取扩展的宏
extern PDEVICE_OBJECT TcpFilterDevice;//过滤层设备指针,针对工程的全局对象
extern PDEVICE_OBJECT UdpFilterDevice;
extern PDEVICE_OBJECT RawIpFilterDevice;
enum PROTOL_TYPES//协议类型
{
  TCP_TYPE,//tcp类型
  UDP_TYPE,
  RAW_IP,
};

2.DriverEntry里面产生设备
  //产生tcp过滤器
  ntStatus=CreateATdiDevice(DriverObject,TCP_FILTER_DEVICE_NAME,&TcpFilterDevice);
  if(!NT_SUCCESS(ntStatus))
    return ntStatus;

  //产生udp过滤器
  ntStatus=CreateATdiDevice(DriverObject,UDP_FILTER_DEVICE_NAME,&UdpFilterDevice);
  if(!NT_SUCCESS(ntStatus))
  {
    IoDeleteDevice(TcpFilterDevice);
    return ntStatus;
  }

  //产生原始ip过滤器
  ntStatus=CreateATdiDevice(DriverObject,RAWIP_FILTER_DEVICE_NAME,&RawIpFilterDevice);
  if(!NT_SUCCESS(ntStatus))
  {
    IoDeleteDevice(TcpFilterDevice);
    IoDeleteDevice(RawIpFilterDevice);
    return ntStatus;
  }
其中CreateATdiDevice函数如下:
/*********************************************************************
函数作用:产生以及tdi设备
参数:基础驱动,设备驱动
返回值:状态返回
**********************************************************************/
NTSTATUS CreateATdiDevice(
      IN PDRIVER_OBJECT pDriver,//驱动指针
      IN PWCHAR pDeviceName,//设备名称
      OUT PDEVICE_OBJECT *pDevice//设备指针(返回)
      )
{
  NTSTATUS ntStatus;
  UNICODE_STRING ntDeviceName,dosDeviceName;
  PDEVICE_EXTENSION DeviceExtension;

  RtlInitUnicodeString(&ntDeviceName, pDeviceName);
  ntStatus = IoCreateDevice(
    pDriver,
    sizeof(DEVICE_EXTENSION), // DeviceExtensionSize
    &ntDeviceName, // DeviceName
    FILE_DEVICE_UNKNOWN, // DeviceType
    0,// DeviceCharacteristics
    TRUE,// Exclusive
    pDevice// [OUT]
  );
  if(!NT_SUCCESS(ntStatus))
    {
    DbgPrint("[CreateATdiDevice]IoCreateDevice=0x%x\n", ntStatus);
    return ntStatus;
  }
  (*pDevice)->Flags|=DO_DIRECT_IO;//直接io缓冲类型
  return ntStatus;
}

3.DriverEntry里面Attach驱动
  PDEVICE_EXTENSION pExt=DEVICE_EXT(TcpFilterDevice);
  //绑定tcp
  ntStatus=AttachDevice(NT_TCP_DEVICE_NAME,TcpFilterDevice,
    &pExt->OrgNetDevice);
  if(!NT_SUCCESS(ntStatus))
  {
    return ntStatus;
  }
  DbgPrint("[DriverEntry]tcp org net device %08x\r\n",pExt->OrgNetDevice);

  pExt=DEVICE_EXT(UdpFilterDevice);
  //绑定udp
  ntStatus=AttachDevice(NT_UDP_DEVICE_NAME,UdpFilterDevice,
    &pExt->OrgNetDevice);
  if(!NT_SUCCESS(ntStatus))
  {
    return ntStatus;
  }

  DbgPrint("[DriverEntry]udp org net device %08x\r\n",pExt->OrgNetDevice);
  pExt=DEVICE_EXT(RawIpFilterDevice);
  //绑定rawip
  ntStatus=AttachDevice(NT_RAWIP_DEVICE_NAME,RawIpFilterDevice,
    &pExt->OrgNetDevice);
  if(!NT_SUCCESS(ntStatus))
  {
    return ntStatus;
  }
  DbgPrint("[DriverEntry]rawip org net device %08x\r\n",pExt->OrgNetDevice);
其中
#define TCP_FILTER_DEVICE_NAME  L"\\Device\\TcpFilterTrans"
#define UDP_FILTER_DEVICE_NAME  L"\\Device\\UdpFilterTrans"
#define RAWIP_FILTER_DEVICE_NAME  L"\\Device\\RowIpFilterTrans"

#define NT_TCP_DEVICE_NAME  L"\\Device\\Tcp"
#define NT_UDP_DEVICE_NAME  L"\\Device\\Udp"
#define NT_RAWIP_DEVICE_NAME  L"\\Device\\RawIp"

AttachDevice函数:
/*********************************************************************
函数作用:绑定指定设备
参数:需要绑定的设备名称,想帮到目标上的设备指针,绑定后获取到的老顶层设备指针
返回值:
**********************************************************************/
NTSTATUS AttachDevice(
      IN PWCHAR pDeviceName,//需要绑定的设备名称
      IN PDEVICE_OBJECT pAttachingDevice,//想帮到目标上的设备指针
      OUT PDEVICE_OBJECT *oldDevice//绑定后获取到的老顶层设备指针
    )
{
  NTSTATUS ntStatus;
  UNICODE_STRING AttachDeviceName;
  RtlInitUnicodeString(&AttachDeviceName,pDeviceName);

  ntStatus=IoAttachDevice(pAttachingDevice,&AttachDeviceName,oldDevice);
  if (!NT_SUCCESS(ntStatus))
  {
    DbgPrint("[AttachDevice]IoAttachDevice=0x%x\n", ntStatus);
    return ntStatus;
  }
  return ntStatus;
}

4.DriverEntry勾走所有的irp处理
  for(int i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
    DriverObject->MajorFunction[i]=TditransDispatch;
    DriverObject->DriverUnload=TditransUnload;

5.我们跳过所有的处理,只稍微判断下他们的类型
NTSTATUS TditransDispatch(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp
  )
{
  NTSTATUS ntStatus;

  switch ((unsigned int)WhichProtol(DeviceObject))
  {
    case PROTOL_TYPES::TCP_TYPE:
      DbgPrint("[TditransDispatch]Tcp action\r\n");
      break;
    case PROTOL_TYPES::UDP_TYPE:
      DbgPrint("[TditransDispatch]Udp action\r\n");
      break;
    case PROTOL_TYPES::RAW_IP:
      DbgPrint("[TditransDispatch]Rawip action\r\n");
      break;
  }

  PDEVICE_EXTENSION pExt=DEVICE_EXT(DeviceObject);
  PDEVICE_OBJECT pOrgDev=pExt->OrgNetDevice;
  DbgPrint("[TditransDispatch]org net device %08x\r\n",pExt->OrgNetDevice);
  if(pOrgDev!=NULL)
    {
    IoSkipCurrentIrpStackLocation(Irp);
    ntStatus=IoCallDriver(pOrgDev,Irp);
  }
  return ntStatus;
}
其中WhichProtol
/*********************************************************************
函数作用:判断协议属于类型
参数:被选中通讯的设备指针
返回值:协议类型
**********************************************************************/
int WhichProtol(PDEVICE_OBJECT pSelDevice)
{
  if(TcpFilterDevice==pSelDevice)
    return (int)PROTOL_TYPES::TCP_TYPE;
  if(UdpFilterDevice==pSelDevice)
    return (int)PROTOL_TYPES::UDP_TYPE;
  if(RawIpFilterDevice==pSelDevice)
    return (int)PROTOL_TYPES::RAW_IP;
  return 0;
}

6.Unload里面啥也别做,否则系统蓝给你看!(这一点不要怀疑,所有通过attach+完成事例来做过滤的驱动最好都不要做这个卸载,否则后果很严重,微软会在卸载里面判断你这个驱动是不是符合wdm即插即用标准,如果但凡你不支持pnp和power管理标准,你就去蓝屏那里买单吧,我顶~~~)
//啥也不要做,做了会蓝屏
VOID TditransUnload(
  IN PDRIVER_OBJECT DriverObject
  )
{
    DbgPrint("[TDITrans] unloaded\n");
}

总结:并非一个sys对应一个设备,也并非一个irp回调过程对一个sys只会给一个设备指针,这就是这个文章的技巧真谛,拥有它,你就想申请多少个设备申请多少个吧。