TDI过滤程序框架

时间:2021-08-24 18:34:24
#include <ntddk.h>
#include <tdikrnl.h>
#include <ws2def.h>
#include <WDM.H>


//保存设备指针的全局变量

PDEVICE_OBJECT
g_tcpfltobj=NULL,
g_udpfltobj=NULL,
g_ipfltobj=NULL,
g_tcpoldobj=NULL,
g_udpoldobj=NULL,
g_ipoldobj=NULL;

//函数声明

NTSTATUS c_n_a_device(PDRIVER_OBJECT DriverObject,PDEVICE_OBJECT *fltobj,PDEVICE_OBJECT *oldobj,wchar_t *devname);
NTSTATUS DeviceDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP irp);
PDEVICE_OBJECT get_original_devobj(PDEVICE_OBJECT flt_devobj,int *proto);


//卸载函数

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
if(g_tcpoldobj!=NULL)IoDetachDevice(g_tcpoldobj); //解除 旧的
if(g_tcpfltobj!=NULL)IoDeleteDevice(g_tcpfltobj); //删除 新的
if(g_udpoldobj!=NULL)IoDetachDevice(g_udpfltobj);
if(g_udpfltobj!=NULL)IoDeleteDevice(g_udpfltobj);
if(g_ipoldobj!=NULL)IoDetachDevice(g_ipoldobj);
if(g_ipfltobj!=NULL)IoDeleteDevice(g_ipfltobj);

}

//驱动入口函数

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,IN PUNICODE_STRING theRegistryPath)
{
NTSTATUS status=STATUS_SUCCESS;
int i;

//设置分发函数
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
theDriverObject->MajorFunction[i]=DeviceDispatch;

//设置卸载函数
theDriverObject->DriverUnload=OnUnload;

//绑定TDI设备 \\Device\\Tcp
status=c_n_a_device(theDriverObject,&g_tcpfltobj,&g_tcpoldobj,L"\\Device\\Tcp");
if(status!=STATUS_SUCCESS)
{
KdPrint(("[tdi_fw] DriverEntry:c_n_a_device:0x%x\n",status)); //
goto done;
}
//绑定TDI设备 \\Device\\Udp
status=c_n_a_device(theDriverObject,&g_udpfltobj,&g_udpoldobj,L"\\Device\\Udp");
if(status!=STATUS_SUCCESS)
{
KdPrint(("[tdi_fw] DriverEntry:c_n_a_device:0x%x\n",status));
goto done;
}
//绑定TDI设备 \\Device\\RawIp
status=c_n_a_device(theDriverObject,&g_ipfltobj,&g_ipoldobj,L"\\Device\\RawIp");
if(status!=STATUS_SUCCESS)
{
KdPrint(("[tdi_fw] DriverEntry:c_n_a_device:0x%x\n",status));
goto done;
}
done:
//如果绑定失败了
if(status!=STATUS_UNSUCCESSFUL)
{

OnUnload(theDriverObject);
}

return status;
}



//绑定函数定义

NTSTATUS c_n_a_device(PDRIVER_OBJECT DriverObject,PDEVICE_OBJECT *fltobj,PDEVICE_OBJECT *oldobj,wchar_t *devname)
{
NTSTATUS status;
UNICODE_STRING str;
//生成自己的新设备
status=IoCreateDevice(DriverObject,0,NULL,FILE_DEVICE_UNKNOWN,0,TRUE,fltobj);
if(status!=STATUS_SUCCESS)
{
KdPrint(("IoCreateDevice failed"));
return status;
}
//设置设备IO方式为直接IO 读写不经过缓存
(*fltobj)->Flags|=DO_DIRECT_IO;
//将要绑定的设备名初始化为一个Unicode字符串
RtlInitUnicodeString(&str,devname);
//绑定这个设备
status=IoAttachDevice(*fltobj,&str,oldobj); //此函数注意下 找到了真实设备指针
if(status!=STATUS_SUCCESS)
{

KdPrint(("IoAttachDevice failed"));
return status;
}
KdPrint(("[tdi_fw] DriverEntry:%S fileObj:0x%x\n",devname,*fltobj));
return STATUS_SUCCESS;

}

//分发函数定义

NTSTATUS DeviceDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP irp)
{
NTSTATUS status;
PDEVICE_OBJECT old_devobj=get_original_devobj(DeviceObject,NULL); //找到真实设备指针函数 供I噢CallDriver函数调用
if(old_devobj!=NULL)
{
//如果能找到原设备,就发送到原设备
IoSkipCurrentIrpStackLocation(irp);
status=IoCallDriver(old_devobj,irp);
}
else
{
//如果找不到原设备,就返回失败
status=irp->IoStatus.Status=STATUS_INVALID_PARAMETER;
IoCompleteRequest(irp,IO_NO_INCREMENT);
}
return status;
}

//取得对应的真实设备

PDEVICE_OBJECT get_original_devobj(PDEVICE_OBJECT flt_devobj,int *proto)
{
PDEVICE_OBJECT result;
int ipproto;
if(flt_devobj==g_tcpfltobj)
{
result=g_tcpoldobj; //注意下 此处对应到了真实的设备
ipproto=IPPROTO_TCP;
}else if (flt_devobj==g_udpfltobj)
{
result=g_ipoldobj;
ipproto=IPPROTO_IP;
}else
{
KdPrint(("[tdi_fw] get_original_devobj:Unknown DeviceObject 0x%x!\n",flt_devobj));
ipproto=IPPROTO_IP;
result=NULL;
}
if(result!=NULL&&proto!=NULL)
*proto=ipproto;
return result;
}