📄 ndisprot.cpp
字号:
///////////////////////////////////////////////////
// ndisprot.cpp文件
// NT入口点,派遣例程
#define NDIS50 1 // 说明要使用NDIS 5.0
extern "C"
{
#include <ndis.h>
#include <ntddk.h>
#include <stdio.h>
}
#include "nuiouser.h"
#include "ndisprot.h"
#pragma comment(lib, "ndis")
GLOBAL g_data;
// 初始化协议驱动
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT pDeviceObj = NULL;
NDIS_STRING protoName = NDIS_STRING_CONST("Packet");
// 给用户使用的符号连接名称
UNICODE_STRING ustrSymbolicLink;
BOOLEAN bSymbolicLink = FALSE;
DbgPrint(" ProtoDrv: DriverEntry... \n");
// 保存驱动对象指针。这里,g_data是GLOBAL类型的全局变量
g_data.pDriverObj = pDriverObj;
do
{
// 为此驱动创建一个控制设备对象。用户程序向这个设备发送IOCTL代码,
// 以便获取绑定的适配器信息
UNICODE_STRING ustrDevName;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj,
0,
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDeviceObj);
if(!NT_SUCCESS(status))
{
DbgPrint(" ProtoDrv: CreateDevice failed \n");
break;
}
// 为上面的设备创建符号连接
RtlInitUnicodeString(&ustrSymbolicLink, LINK_NAME);
status = IoCreateSymbolicLink(&ustrSymbolicLink, &ustrDevName);
if(!NT_SUCCESS(status))
{
DbgPrint(" ProtoDrv: CreateSymbolicLink failed \n");
break;
}
bSymbolicLink = TRUE;
// 设置为缓冲区I/O方式
pDeviceObj->Flags |= DO_BUFFERED_IO;
// 初始化全局变量
g_data.pControlDevice = pDeviceObj;
InitializeListHead(&g_data.AdapterList);
KeInitializeSpinLock(&g_data.GlobalLock);
// 初始化协议特征结构
NDIS_PROTOCOL_CHARACTERISTICS protocolChar;
NdisZeroMemory(&protocolChar, sizeof(protocolChar));
protocolChar.Ndis40Chars.Ndis30Chars.MajorNdisVersion = 5;
protocolChar.Ndis40Chars.Ndis30Chars.MinorNdisVersion = 0;
protocolChar.Ndis40Chars.Ndis30Chars.Name = protoName;
protocolChar.Ndis40Chars.BindAdapterHandler = ProtocolBindAdapter;
protocolChar.Ndis40Chars.UnbindAdapterHandler = ProtocolUnbindAdapter;
protocolChar.Ndis40Chars.Ndis30Chars.OpenAdapterCompleteHandler = ProtocolOpenAdapterComplete;
protocolChar.Ndis40Chars.Ndis30Chars.CloseAdapterCompleteHandler = ProtocolCloseAdapterComplete;
protocolChar.Ndis40Chars.Ndis30Chars.ReceiveHandler = ProtocolReceive;
// protocolChar.Ndis40Chars.ReceivePacketHandler = ProtocolReceivePacket;
protocolChar.Ndis40Chars.Ndis30Chars.TransferDataCompleteHandler = ProtocolTransferDataComplete;
protocolChar.Ndis40Chars.Ndis30Chars.SendCompleteHandler = ProtocolSendComplete;
protocolChar.Ndis40Chars.Ndis30Chars.ResetCompleteHandler = ProtocolResetComplete;
protocolChar.Ndis40Chars.Ndis30Chars.RequestCompleteHandler = ProtocolRequestComplete;
protocolChar.Ndis40Chars.Ndis30Chars.ReceiveCompleteHandler = ProtocolReceiveComplete;
protocolChar.Ndis40Chars.Ndis30Chars.StatusHandler = ProtocolStatus;
protocolChar.Ndis40Chars.Ndis30Chars.StatusCompleteHandler = ProtocolStatusComplete;
protocolChar.Ndis40Chars.PnPEventHandler = ProtocolPNPHandler;
// 注册为协议驱动
NdisRegisterProtocol((PNDIS_STATUS)&status,
&g_data.hNdisProtocol, &protocolChar, sizeof(protocolChar));
if(status != NDIS_STATUS_SUCCESS)
{
status = STATUS_UNSUCCESSFUL;
break;
}
DbgPrint(" ProtoDrv: NdisRegisterProtocol success \n");
// 现在,设置我们要处理的派遣例程
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->MajorFunction[IRP_MJ_READ] = DispatchRead;
pDriverObj->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
pDriverObj->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
status = STATUS_SUCCESS;
}while(FALSE);
if(!NT_SUCCESS(status)) // 错误处理
{
if(pDeviceObj != NULL)
{
// 删除设备对象
IoDeleteDevice(pDeviceObj);
g_data.pControlDevice = NULL;
}
if(bSymbolicLink)
{
// 删除符号连接
IoDeleteSymbolicLink(&ustrSymbolicLink);
}
}
return status;
}
// 卸载
void DriverUnload(PDRIVER_OBJECT pDriverObj)
{
// 删除控制设备对象和对应的符号连接
UNICODE_STRING ustrLink;
RtlInitUnicodeString(&ustrLink, LINK_NAME);
IoDeleteSymbolicLink(&ustrLink);
if(g_data.pControlDevice != NULL)
IoDeleteDevice(g_data.pControlDevice);
// 解除所有绑定
NDIS_STATUS status;
while(pDriverObj->DeviceObject != NULL) // 这里除了控制设备对象之外,其它全是NIC设备对象
{
ProtocolUnbindAdapter(&status, pDriverObj->DeviceObject->DeviceExtension, NULL);
}
// 取消协议驱动的注册
NdisDeregisterProtocol(&status, g_data.hNdisProtocol);
}
// 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
DbgPrint(" ProtoDrv: DispatchClose \n");
NTSTATUS status = STATUS_SUCCESS;
if(pDevObj == g_data.pControlDevice)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
POPEN_INSTANCE pOpen = (POPEN_INSTANCE)pDevObj->DeviceExtension;
IoIncrement(pOpen);
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
IoDecrement(pOpen);
return status;
}
// 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
DbgPrint(" ProtoDrv: DispatchCreate \n");
NTSTATUS status = STATUS_SUCCESS;
if(pDevObj == g_data.pControlDevice)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
POPEN_INSTANCE pOpen = (POPEN_INSTANCE)pDevObj->DeviceExtension;
IoIncrement(pOpen);
if(!pOpen->bBound)
{
status = STATUS_DEVICE_NOT_READY;
}
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
IoDecrement(pOpen);
return status;
}
// I/O控制派遣例程
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
// 假设失败
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
// 取得此IRP(pIrp)的I/O堆栈指针
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// 取得I/O控制代码
ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
// 取得I/O缓冲区指针和它的长度
PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
if(uIoControlCode == IOCTL_ENUM_ADAPTERS)
{
ULONG nDataLen = 0;
if(pDevObj != g_data.pControlDevice)
status = STATUS_INVALID_DEVICE_REQUEST;
else
{
status = GetAdapterList(pIoBuffer, uOutSize, &nDataLen);
if(status != STATUS_SUCCESS)
DbgPrint("GetAdapterList error ");
}
pIrp->IoStatus.Information = nDataLen;
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
OPEN_INSTANCE *pOpen = (OPEN_INSTANCE *)pDevObj->DeviceExtension;
if(pOpen == NULL || !pOpen->bBound)
{
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
IoIncrement(pOpen);
IoMarkIrpPending(pIrp);
if(uIoControlCode == IOCTL_PROTOCOL_RESET)
{
// 插入此IRP到重置IRP列表
ExInterlockedInsertTailList(
&pOpen->ResetIrpList,
&pIrp->Tail.Overlay.ListEntry,
&pOpen->ResetQueueLock);
// 发出重置请求
NdisReset(
&status,
pOpen->hAdapter
);
if(status != NDIS_STATUS_PENDING)
{
ProtocolResetComplete(
pOpen,
status);
}
}
// 获取或者设置OID信息
else if(uIoControlCode == IOCTL_PROTOCOL_SET_OID
|| uIoControlCode == IOCTL_PROTOCOL_QUERY_OID) // 输入参数是一个自定义的PROTOCOL_OID_DATA结构
{
PPROTOCOL_OID_DATA pOidData = (PPROTOCOL_OID_DATA)pIoBuffer;
// 申请一个INTERNAL_REQUEST结构
PINTERNAL_REQUEST pInterRequest =
(PINTERNAL_REQUEST)ExAllocatePool(NonPagedPool, sizeof(INTERNAL_REQUEST));
if(pInterRequest == NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -