⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndisprot.cpp

📁 有关WDM驱动程序编程的几个源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////
// 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 + -