设为首页 加入收藏

TOP

驱动开发:内核封装TDI网络通信接口(一)
2023-07-23 13:33:46 】 浏览:128
Tags:封装 TDI 通信接

在上一篇文章《驱动开发:内核封装WSK网络通信接口》中,LyShark已经带大家看过了如何通过WSK接口实现套接字通信,但WSK实现的通信是内核与内核模块之间的,而如果需要内核与应用层之间通信则使用TDK会更好一些因为它更接近应用层,本章将使用TDK实现,TDI全称传输驱动接口,其主要负责连接Socket和协议驱动,用于实现访问传输层的功能,该接口比NDIS更接近于应用层,在早期Win系统中常用于实现过滤防火墙,同样经过封装后也可实现通信功能,本章将运用TDI接口实现驱动与应用层之间传输字符串,结构体,多线程收发等技术。

  • TDI传输字符串
  • TDI多线程收发
  • TDI传数结构实现认证

SDK库提取,将其命名为MyTDI.hpp放入到代码同级目录下。

拷贝SDK代码
#include <ntifs.h>
#include <tdikrnl.h>
#include <ntstatus.h>

// TCP驱动设备名称
#define COMM_TCP_DEV_NAME L"\\Device\\Tcp"

// 地址转换的宏
#define INETADDR(a, b, c, d) (a + (b<<8) + (c<<16) + (d<<24))
#define HTONL(a) (((a & 0xFF)<<24) + ((a & 0xFF00)<<8) + ((a & 0xFF0000)>>8) + (a&0xFF000000)>>24)
#define HTONS(a) (((a & 0xFF)<<8) + ((a & 0xFF00)>>8))

// 完成回调函数
NTSTATUS TdiCompletionRoutine(PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID pContext)
{
  if (NULL != pContext)
  {
    KeSetEvent((PKEVENT)pContext, IO_NO_INCREMENT, FALSE);
  }
  return STATUS_MORE_PROCESSING_REQUIRED;
}

// TDI初始化设置
NTSTATUS TdiOpen(PDEVICE_OBJECT *ppTdiAddressDevObj, PFILE_OBJECT *ppTdiEndPointFileObject, HANDLE *phTdiAddress, HANDLE *phTdiEndPoint)
{
  NTSTATUS status = STATUS_UNSUCCESSFUL;
  PFILE_FULL_EA_INFORMATION pAddressEaBuffer = NULL;
  ULONG ulAddressEaBufferLength = 0;
  PTA_IP_ADDRESS pTaIpAddr = NULL;
  UNICODE_STRING ustrTDIDevName;
  OBJECT_ATTRIBUTES ObjectAttributes = { 0 };
  IO_STATUS_BLOCK iosb = { 0 };
  HANDLE hTdiAddress = NULL;
  PFILE_OBJECT pTdiAddressFileObject = NULL;
  PDEVICE_OBJECT pTdiAddressDevObj = NULL;
  PFILE_FULL_EA_INFORMATION pContextEaBuffer = NULL;
  ULONG ulContextEaBufferLength = 0;
  HANDLE hTdiEndPoint = NULL;
  PFILE_OBJECT pTdiEndPointFileObject = NULL;
  KEVENT irpCompleteEvent = { 0 };
  PIRP pIrp = NULL;

  do
  {
    // 为本地地址拓展属性结构申请内存及初始化
    ulAddressEaBufferLength = sizeof(FILE_FULL_EA_INFORMATION) + TDI_TRANSPORT_ADDRESS_LENGTH + sizeof(TA_IP_ADDRESS);
    pAddressEaBuffer = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, ulAddressEaBufferLength);
    if (NULL == pAddressEaBuffer)
    {
      break;
    }
    RtlZeroMemory(pAddressEaBuffer, ulAddressEaBufferLength);
    RtlCopyMemory(pAddressEaBuffer->EaName, TdiTransportAddress, (1 + TDI_TRANSPORT_ADDRESS_LENGTH));
    pAddressEaBuffer->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
    pAddressEaBuffer->EaValueLength = sizeof(TA_IP_ADDRESS);

    // 初始化本机IP地址与端口
    pTaIpAddr = (PTA_IP_ADDRESS)((PUCHAR)pAddressEaBuffer->EaName + pAddressEaBuffer->EaNameLength + 1);
    pTaIpAddr->TAAddressCount = 1;
    pTaIpAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
    pTaIpAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
    pTaIpAddr->Address[0].Address[0].sin_port = 0;     // 0表示本机任意随机端口
    pTaIpAddr->Address[0].Address[0].in_addr = 0;      // 0表示本机本地IP地址
    RtlZeroMemory(pTaIpAddr->Address[0].Address[0].sin_zero, sizeof(pTaIpAddr->Address[0].Address[0].sin_zero));

    // 创建TDI驱动设备字符串与初始化设备对象
    RtlInitUnicodeString(&ustrTDIDevName, COMM_TCP_DEV_NAME);
    InitializeObjectAttributes(&ObjectAttributes, &ustrTDIDevName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

    // 根据本地地址拓展属性结构创建本地地址对象
    status = ZwCreateFile(&hTdiAddress, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
      &ObjectA
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇<五>关于类的各类成员 下一篇AtCoder Beginner Contest 276

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目