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

📄 prothook.c

📁 ndis 中间层截获后转发的例子,通过修改IP 地址和MAC地址转发.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*——————————————————————————————————————
	文件:protocol.c
	工程:xpassthru
	概述:演示NDIS中间驱动程序输出封包结构信息
	版权所有(c) 2001-2002 X 工作室
	http://www.xfilt.com
	xstudio@xfilt.com
*/

#include "prexsim.h"
#pragma hdrstop

#define MAX_PACKET_POOL_SIZE 0x0000FFFF
#define MIN_PACKET_POOL_SIZE 0x000000FF

NDIS_STATUS
PtRegisterAsProtocol(
	IN	PDRIVER_OBJECT		DriverObject,
	IN	PUNICODE_STRING		RegistryPath
)
{
	NDIS_STATUS						Status;
	NDIS_PROTOCOL_CHARACTERISTICS	ProtocolStruct;
	NDIS_STRING						Name;

	NdisZeroMemory(&ProtocolStruct, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
	ProtocolStruct.MajorNdisVersion = 4;
	ProtocolStruct.MinorNdisVersion = 0;
	NdisInitUnicodeString(&Name, L"xfilter");	// Protocol名称
	ProtocolStruct.Name				= Name;
	ProtocolStruct.OpenAdapterCompleteHandler	= PtOpenAdapterComplete;
	ProtocolStruct.CloseAdapterCompleteHandler	= PtCloseAdapterComplete;
	ProtocolStruct.SendCompleteHandler			= PtSendComplete;
	ProtocolStruct.TransferDataCompleteHandler	= PtTransferDataComplete;
	ProtocolStruct.ResetCompleteHandler			= PtResetComplete;
	ProtocolStruct.RequestCompleteHandler		= PtRequestComplete;
	ProtocolStruct.ReceiveHandler				= PtReceive;
	ProtocolStruct.ReceiveCompleteHandler		= PtReceiveComplete;
	ProtocolStruct.StatusHandler				= PtStatus;
	ProtocolStruct.StatusCompleteHandler		= PtStatusComplete;
	ProtocolStruct.BindAdapterHandler			= PtBindAdapter;
	ProtocolStruct.UnbindAdapterHandler			= PtUnbindAdapter;
	ProtocolStruct.UnloadHandler				= NULL;
	ProtocolStruct.ReceivePacketHandler			= PtReceivePacket;
	ProtocolStruct.PnPEventHandler				= PtPNPHandler;

	NdisRegisterProtocol(&Status, &ProtHandle
		, &ProtocolStruct, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

	DBGPRINT("<== NdisRegisterProtocol.\n");
	return Status;
}

/*——————————————————————————————————————
	被NDIS调用将Protocol驱动绑定到下层的miniport设备。详情请参阅DDK文档关于
	ProtocolBindAdapter函数的解释。
*/
VOID
PtBindAdapter(
	OUT PNDIS_STATUS			Status,
	IN  NDIS_HANDLE				BindContext,
	IN  PNDIS_STRING			DeviceName,
	IN  PVOID					SystemSpecific1,
	IN  PVOID					SystemSpecific2
)
{
	NDIS_HANDLE			ConfigHandle = NULL;
	PNDIS_CONFIGURATION_PARAMETER	Param;
	NDIS_STRING			DeviceStr	= NDIS_STRING_CONST("UpperBindings");
	PADAPT				pAdapt		= NULL;
	NDIS_STATUS			Sts;
	UINT				MediumIndex;

	PNDIS_CONFIGURATION_PARAMETER	BundleParam;
	NDIS_STRING		BundleStr = NDIS_STRING_CONST("BundleId");
	NDIS_STATUS		BundleStatus;
	
	DBGPRINT("==> Passthru Protocol Initialize PtBindAdapter\n");

	do
	{
		//——————————————————————————————————
		// 打开Protocol配置得到句柄ConfigHandle
		//
		NdisOpenProtocolConfiguration(Status, &ConfigHandle, SystemSpecific1);
		if (*Status != NDIS_STATUS_SUCCESS)	break;

		//——————————————————————————————————
		// 利用句柄ConfigHandle读出配置参数到Param结构
		//
		NdisReadConfiguration(Status, &Param
			, ConfigHandle, &DeviceStr, NdisParameterString);
		if (*Status != NDIS_STATUS_SUCCESS)	break;

		//——————————————————————————————————
		// 为Adapter结构分配内存
		//
		NdisAllocateMemoryWithTag(&pAdapt, sizeof(ADAPT), TAG);
		if (pAdapt == NULL)
		{
			*Status = NDIS_STATUS_RESOURCES;
		  	break;
		}

		//——————————————————————————————————
		// 初始化Adapter结构数据为0
		//
		NdisZeroMemory(pAdapt, sizeof(ADAPT));

		//——————————————————————————————————
		// 初始化pAdapt->BundleUniString.Buffer,这个缓冲区将用来保存从注册
		// 表读出来的数据。
		//
		NdisAllocateMemoryWithTag( 
			&(pAdapt->BundleUniString.Buffer), MAX_BUNDLEID_LENGTH ,TAG);
		if (pAdapt->BundleUniString.Buffer == NULL)
		{
		  	*Status = NDIS_STATUS_RESOURCES;
		  	break;
		}

		pAdapt->BundleUniString.MaximumLength = MAX_BUNDLEID_LENGTH ;

		NdisReadConfiguration(&BundleStatus
			, &BundleParam, ConfigHandle, &BundleStr, NdisParameterString);

		if (BundleStatus == NDIS_STATUS_SUCCESS)
		{
			//————————————————————————————————
			// 复制绑定标识到自己初始化的缓冲区pAdapt->BundleUniString
			//
		  	ASSERT(pAdapt->BundleUniString.MaximumLength  
				>= BundleParam->ParameterData.StringData.Length);

		  	pAdapt->BundleUniString.Length 
				= BundleParam->ParameterData.StringData.Length;

		  	RtlCopyUnicodeString(
				&pAdapt->BundleUniString, &BundleParam->ParameterData.StringData);
		}
		else 
		{
			//————————————————————————————————
			// 没有在注册表里找到绑定ID,设定BundleUniString为"<no-bundle>"
			//
			NDIS_STRING NoBundle = NDIS_STRING_CONST ("<no-bundle>");
			RtlCopyUnicodeString(&pAdapt->BundleUniString, &NoBundle);
		}

		//——————————————————————————————————
		// 初始化Event并加同步锁
		//
		NdisInitializeEvent(&pAdapt->Event);
		KeInitializeSpinLock(&pAdapt->SpinLock);

		//——————————————————————————————————
		// 为发送封包分配内存缓冲池
		//
		NdisAllocatePacketPoolEx(Status,
		  	 &pAdapt->SendPacketPoolHandle,
		  	 MIN_PACKET_POOL_SIZE,
		  	 MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
		  	 sizeof(RSVD));
		if (*Status != NDIS_STATUS_SUCCESS)	break;

		//——————————————————————————————————
		// 为接收封包分配内存缓冲池
		//
		NdisAllocatePacketPoolEx(Status,
		  	 &pAdapt->RecvPacketPoolHandle,
		  	 MIN_PACKET_POOL_SIZE,
		  	 MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
		  	 sizeof(RSVD));
		if (*Status != NDIS_STATUS_SUCCESS)	break;

		//——————————————————————————————————
		// 打开底层adapter设备并且完成初始化
		//
		NdisOpenAdapter(Status,	&Sts, &pAdapt->BindingHandle, &MediumIndex,
		  	MediumArray, sizeof(MediumArray)/sizeof(NDIS_MEDIUM), ProtHandle,
		  	pAdapt,	DeviceName,	0, NULL);
		if(*Status == NDIS_STATUS_PENDING)
		{
		  	NdisWaitEvent(&pAdapt->Event, 0);
		  	*Status = pAdapt->Status;
		}
		if(*Status != NDIS_STATUS_SUCCESS) break;
		pAdapt->Medium = MediumArray[MediumIndex];

		//——————————————————————————————————
		// 告诉NDIS初始化我们的miniport设备
		//
		NdisIMInitializeDeviceInstanceEx(
			DriverHandle, &Param->ParameterData.StringData, pAdapt);

	} while(FALSE);

	if (ConfigHandle != NULL)
		NdisCloseConfiguration(ConfigHandle);

	if (*Status != NDIS_STATUS_SUCCESS)
	{
		if (pAdapt != NULL)
		{
			if (pAdapt->SendPacketPoolHandle != NULL)
				 NdisFreePacketPool(pAdapt->SendPacketPoolHandle);

			if (pAdapt->RecvPacketPoolHandle != NULL)
				 NdisFreePacketPool(pAdapt->RecvPacketPoolHandle);

			NdisFreeMemory(pAdapt, sizeof(ADAPT), 0);
		}
	}

	DBGPRINT("<== Passthru Protocol Initialize\n");
}

/*——————————————————————————————————————
	在PtBindAdapter里调用NdisOpenAdapter完成绑定后执行,用来解除阻塞状态。
	详情请参阅DDK文档关于ProtocolOpenAdapterComplete函数的解释。
*/
VOID
PtOpenAdapterComplete(
	IN  NDIS_HANDLE			 ProtocolBindingContext,
	IN  NDIS_STATUS			 Status,
	IN  NDIS_STATUS			 OpenErrorStatus
)
{
	PADAPT pAdapt	=(PADAPT)ProtocolBindingContext;
	pAdapt->Status	= Status;
	DBGPRINT("==> Passthru PtOpenAdapterComplete\n");
	NdisSetEvent(&pAdapt->Event);
}

/*——————————————————————————————————————
	当我需要解除与底层adapter设备的绑定时由NDIS调用,这个函数使用miniport的
	HaltHandler共享功能函数,这段代码应该保证NdisCloseAdapter和NdisFreeMemory
	这两个函数只能被调用一次。
*/
VOID
PtUnbindAdapter(
	OUT PNDIS_STATUS		Status,
	IN  NDIS_HANDLE			ProtocolBindingContext,
	IN  NDIS_HANDLE			UnbindContext
	)
{
	PADAPT		pAdapt			= (PADAPT)ProtocolBindingContext;
	NDIS_HANDLE BindingHandle	= pAdapt->BindingHandle;

	DBGPRINT("==> Passthru PtUnbindAdapter\n");

	if (pAdapt->QueuedRequest == TRUE)
	{
		pAdapt->QueuedRequest = FALSE;
		PtRequestComplete (pAdapt, &pAdapt->Request, NDIS_STATUS_FAILURE );
	}
	
	//————————————————————————————————————
	// 调用NDIS移除设备句柄,通常我们需要在HaltHandler做许多工作。
	//
	// 如果passthru的miniport的halt handler已经被调用或者如果中间设备根本没有
	// 初始化,这个句柄将为NULL。
	//
	if(pAdapt->MiniportHandle != NULL)
	{
		*Status = NdisIMDeInitializeDeviceInstance(pAdapt->MiniportHandle);
		if(*Status != NDIS_STATUS_SUCCESS) *Status = NDIS_STATUS_FAILURE;
	}
	else
	{
		//——————————————————————————————————
		// 关闭底层绑定并且释放内存
		//
		if(pAdapt->BindingHandle != NULL)
		{
			NdisResetEvent(&pAdapt->Event);
			NdisCloseAdapter(Status, pAdapt->BindingHandle);

			//————————————————————————————————
			// 等待结束
			//
			if(*Status == NDIS_STATUS_PENDING)
			{
				 NdisWaitEvent(&pAdapt->Event, 0);
				 *Status = pAdapt->Status;
			}
		}
		else
		{
			//————————————————————————————————
			// Miniport句柄和绑定句柄不应该为NULL,为NULL则设置错误状态。
			//
			*Status = NDIS_STATUS_FAILURE;
			ASSERT(0);
		}

		//——————————————————————————————————
		// 在这里释放内存
		//
		NdisFreeMemory(pAdapt, sizeof(ADAPT), 0);
	}

	DBGPRINT("<==Passthru UnbindAdapter\n");
}

/*——————————————————————————————————————
	这是一个可选函数,在这里调用NdisDeregisterProtocol释放执行
	NdisRegisterProtocol注册protocol时使用的资源.
*/
VOID
PtUnload(
	IN	PDRIVER_OBJECT		DriverObject
	)
{
	NDIS_STATUS Status;
	NdisDeregisterProtocol(&Status, ProtHandle);
	DBGPRINT("<== Passthru Protocol PtUnload\n");
}

/*——————————————————————————————————————
	关闭adapter完成后的处理函数
*/
VOID
PtCloseAdapterComplete(
	IN	NDIS_HANDLE			ProtocolBindingContext,
	IN	NDIS_STATUS			Status
	)
{
	PADAPT pAdapt	= (PADAPT)ProtocolBindingContext;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -