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

📄 minihook.c

📁 ndis 中间层截获后转发的例子,通过修改IP 地址和MAC地址转发.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*——————————————————————————————————————
	设置pAdapt的StandingBy数值,来决定阻断或者允许引入的请求。
*/
VOID
MPProcessSetPowerOid(
	IN OUT PNDIS_STATUS     pNdisStatus,
	IN  PADAPT				pAdapt,
	IN	PVOID				InformationBuffer,
	IN	ULONG				InformationBufferLength,
	OUT PULONG				BytesRead,
	OUT PULONG				BytesNeeded
)
{
	NDIS_DEVICE_POWER_STATE NewDeviceState;

	DBGPRINT ("==>MPProcessSetPowerOid"); 
	ASSERT (InformationBuffer != NULL);
	NewDeviceState	= (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);
	*pNdisStatus	= NDIS_STATUS_FAILURE;

	do 
	{
		//——————————————————————————————————
		// 检查是否是无效的长度
		//
		if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
		{
			*pNdisStatus = NDIS_STATUS_INVALID_LENGTH;
			break;
		}

		//——————————————————————————————————
		// 检查是否是无效的设备状态
		//
		if ((pAdapt->MPDeviceState > NdisDeviceStateD0) 
			&& (NewDeviceState != NdisDeviceStateD0))
		{
			ASSERT (!(pAdapt->MPDeviceState > NdisDeviceStateD0) 
				&& (NewDeviceState != NdisDeviceStateD0));

			*pNdisStatus = NDIS_STATUS_FAILURE;
			break;
		}	

		//——————————————————————————————————
		// 如果miniport从On(D0)状态转换成Low Power状态(>D0),设置StandingBy
		// 为TRUE,阻挡所有引入的请求。
		//
		if (pAdapt->MPDeviceState == NdisDeviceStateD0 
			&& NewDeviceState > NdisDeviceStateD0)
			pAdapt->StandingBy = TRUE;

		//——————————————————————————————————
		// 如果miniport从Low Power状态(>D0)转换成On(D0)状态,设置StandingBy
		// 为FALSE,所有引入的请求将挂起,直到物理Miniport打开(turns ON)。
		//
		if (pAdapt->MPDeviceState > NdisDeviceStateD0 
			&&  NewDeviceState == NdisDeviceStateD0)
			pAdapt->StandingBy = FALSE;
		
		//——————————————————————————————————
		// 更新pAdapt结构中的状态成员变量值
		//
		pAdapt->MPDeviceState = NewDeviceState;
		
		*pNdisStatus = NDIS_STATUS_SUCCESS;
	

	} while (FALSE);	
		
	if (*pNdisStatus == NDIS_STATUS_SUCCESS)
	{
		*BytesRead	= sizeof(NDIS_DEVICE_POWER_STATE);
		*BytesNeeded = 0;
	}
	else
	{
		*BytesRead = 0;
		*BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
	}

	DBGPRINT ("<==MPProcessSetPowerOid"); 
}


/*——————————————————————————————————————
	Miniport必需的函数,当设备停止时释放相应的资源。详情请参阅DDK文档关于
	MiniportHalt函数的解释。
*/
VOID
MPHalt(
	IN	NDIS_HANDLE	MiniportAdapterContext
)
{
	PADAPT			pAdapt = (PADAPT)MiniportAdapterContext;
	NDIS_STATUS		Status;
	PADAPT			pCursor, *ppCursor;
	PADAPT			pPromoteAdapt = NULL;
	KIRQL			OldIrql;

	DBGPRINT("==>Passthru Miniport MPHalt\n");
	
	//————————————————————————————————————
	// 从全局列表中移除pAdapt。
	//
	// 在操作全局列表时必须保持多进程间同步
	//
	KeAcquireSpinLock (&pAdapt->SpinLock, &OldIrql);

	//————————————————————————————————————
	// 从列表中移除pAdapt。
	//
	for (ppCursor = &pAdaptList; *ppCursor != NULL; ppCursor = &(*ppCursor)->Next)
	{
		if (*ppCursor == pAdapt)
		{
			*ppCursor = pAdapt->Next;
			break;
		}
	}

	//————————————————————————————————————
	// 从列表里移除所有指向pAdapt的指针。
	//
	for (pCursor = pAdaptList; pCursor != NULL; pCursor = pCursor->Next)
	{
		//——————————————————————————————————
		// 在全局列表里的指针或许无效,首先对Primary进行检查
		//
		if (pCursor->pPrimaryAdapt == pAdapt)
		{
			ASSERT (pCursor->isSecondary == TRUE);
			pPromoteAdapt = pCursor;
		}

		//——————————————————————————————————
		// 检查下一个
		//
		if (pCursor->pSecondaryAdapt == pAdapt)
		{
			ASSERT(pCursor->isSecondary == FALSE); 
			pCursor->pSecondaryAdapt = pCursor;
		}
	}
	KeReleaseSpinLock (&pAdapt->SpinLock, OldIrql);

	//————————————————————————————————————
	// 如果miniport需要保留pPromoteAdapt调用自定义函数MPPromoteSecondary
	// 保留实例。
	//
	if (pPromoteAdapt != NULL)
		MPPromoteSecondary(pPromoteAdapt);

	//————————————————————————————————————
	// 如果有一个无效的绑定,关闭miniport下面的protocol。
	//
	if (pAdapt->BindingHandle != NULL)
	{
		//——————————————————————————————————
		// 关闭miniport下面的protocol并等待结束。
		//
		NdisResetEvent(&pAdapt->Event);
		NdisCloseAdapter(&Status, pAdapt->BindingHandle);
		if (Status == NDIS_STATUS_PENDING)
		{
			NdisWaitEvent(&pAdapt->Event, 0);
			Status = pAdapt->Status;
		}
		ASSERT (Status == NDIS_STATUS_SUCCESS);
		pAdapt->BindingHandle = NULL;
	}

	//————————————————————————————————————
	// 释放资源
	//
	NdisFreePacketPool(pAdapt->SendPacketPoolHandle);
	NdisFreePacketPool(pAdapt->RecvPacketPoolHandle);
	NdisFreeMemory(pAdapt->BundleUniString.Buffer, MAX_BUNDLEID_LENGTH,0);
	NdisFreeMemory(pAdapt, sizeof(ADAPT), 0);

	DBGPRINT("<==Passthru Minport Halt\n");
}

/*——————————————————————————————————————
	Miniport必需的函数,复位操作,这里我们什么都不需要做。详情请参阅DDK
	文档关于MiniportReset的说明。
*/
NDIS_STATUS
MPReset(
	OUT PBOOLEAN				AddressingReset,
	IN	NDIS_HANDLE				MiniportAdapterContext
)
{
	PADAPT	pAdapt = (PADAPT)MiniportAdapterContext;
	DBGPRINT("==>Passthru Miniport MPReset\n");
	*AddressingReset = FALSE;
	return(NDIS_STATUS_SUCCESS);
}

/*——————————————————————————————————————
	遍历全局列表查找并设置第二个设备的绑定
*/
NDIS_STATUS
MPBundleSearchAndSetSecondary(
	IN	PADAPT			pAdapt
)
{
	NDIS_STATUS		Status		= NDIS_STATUS_FAILURE;
	NDIS_STRING		NoBundle	= NDIS_STRING_CONST ("<no-bundle>");
	PADAPT			pCursor		= NULL;
	PADAPT			pPrimary	= NULL;
	KIRQL			OldIrql;

	DBGPRINT("==>Passthru Miniport MPBundleSearchAndSetSecondary\n");
	
	do
	{
		//——————————————————————————————————
		// 如果bundle == '<bundle id>'那么这个miniport将不是任何绑定的一部分
		//
		if (NdisEqualUnicodeString(&NoBundle, &pAdapt->BundleUniString, TRUE))
		{
			Status = NDIS_STATUS_SUCCESS;
			break;
		}

		//——————————————————————————————————
		// 如果绑定标识为空字符串,这个miniport不是任何绑定的一部分。
		//
		if (pAdapt->BundleUniString.Length == 0)
		{
			Status = NDIS_STATUS_SUCCESS;
			break;
		}

		//——————————————————————————————————
		// 加同步锁。
		//
		KeAcquireSpinLock (&pAdapt->SpinLock, &OldIrql);

		//——————————————————————————————————
		// 查找全局链表中具有相同绑定ID的设备。
		//
		for (pCursor = pAdaptList; pCursor != NULL; pCursor = pCursor->Next)
		{
			if (pCursor == pAdapt)
			{
				//——————————————————————————————
				// 如果指向自己跳过。
				//
				continue;
			}

			//————————————————————————————————
			// 如果匹配将第二个设置为当前的pAdapt。
			//
			if (NdisEqualUnicodeString(
				&pCursor->BundleUniString, &pAdapt->BundleUniString, TRUE))
			{
				//——————————————————————————————
				// 确认这是一个绑定的主设备。
				//
				ASSERT (pCursor->pSecondaryAdapt 
					== pCursor && pCursor->isSecondary == FALSE);
				pPrimary = pCursor;
				break;
			}
		}

		//——————————————————————————————————
		// 解同步锁。
		//
		KeReleaseSpinLock (&pAdapt->SpinLock, OldIrql);

		//——————————————————————————————————
		// 调用自定义函数MPSetMiniportSecondary进行设置。
		//
		if (pPrimary != NULL)
		{
			Status = MPSetMiniportSecondary (pAdapt, pPrimary);
			ASSERT (Status == NDIS_STATUS_SUCCESS);
		}

		//——————————————————————————————————
		// 成功的搜索了列表尽管没有找到绑定仍然返回成功。
		//
		Status = NDIS_STATUS_SUCCESS;

	} while (FALSE) ;

	return Status;
}

/*——————————————————————————————————————
	调用NdisMSetMiniportSecondary设置绑定并且改变成员变量的状态值
*/
NDIS_STATUS
MPSetMiniportSecondary (
	IN	PADAPT		Secondary,
	IN	PADAPT		Primary
	)
{
	NDIS_STATUS	Status = NDIS_STATUS_SUCCESS;
	DBGPRINT("==>Passthru Miniport MPSetMiniportSecondary\n");
	
	//————————————————————————————————————
	// 保证主设备不是其它绑定的一部分
	//
	ASSERT (Primary != Secondary);
	ASSERT (Primary->isSecondary == 0);
	ASSERT (Primary->pSecondaryAdapt == Primary);

	DBGPRINT ("Calling NdisMSetSecondary API on the two handles\n");
	Status = NdisMSetMiniportSecondary(Secondary->MiniportHandle,
									   Primary->MiniportHandle);
	ASSERT (Status == NDIS_STATUS_SUCCESS);

	if (Status == NDIS_STATUS_SUCCESS)
	{
		//——————————————————————————————————
		// 初始化LBFO变量来记录当前状态
		//
		Secondary->isSecondary		= TRUE;
		Secondary->pPrimaryAdapt	= Primary;
		Primary->pSecondaryAdapt	= Secondary;

		//——————————————————————————————————
		// 保证其它一些状态变量也由正确的状态值
		//
		Secondary->pSecondaryAdapt	= Secondary;
		Primary->pPrimaryAdapt		= Primary;
		Primary->isSecondary		= FALSE;
	}

	return Status;
}

/*——————————————————————————————————————
	从第二个设备升迁为主设备,保留升迁设备的实例
*/
NDIS_STATUS
MPPromoteSecondary(
	IN	PADAPT		pAdapt
)
{
	NDIS_STATUS Status = NdisMPromoteMiniport(pAdapt->MiniportHandle);
	ASSERT (Status == NDIS_STATUS_SUCCESS);
	if (Status == NDIS_STATUS_SUCCESS)
	{
		pAdapt->isSecondary		= FALSE;
		pAdapt->pPrimaryAdapt	= pAdapt;
		pAdapt->pSecondaryAdapt = pAdapt;
	}
	DBGPRINT ("<== MPPromoteMiniport\n");
	return Status;
}

/*——————————————————————————————————————
	根据OID判断是发送还是接收
*/
BOOLEAN
MPIsSendOID (
	IN	NDIS_OID	Oid
)
{
	BOOLEAN fIsSend = FALSE;	// 默认是一个接收OID
	DBGPRINT("==>Passthru Miniport MPIsSendOID\n");
	
	switch (Oid)
	{
		//——————————————————————————————————
		// 如果需要发送OID,设置fIsSend为TRUE;
		//
		case OID_GEN_TRANSMIT_BUFFER_SPACE :
		case OID_GEN_TRANSMIT_BLOCK_SIZE :
		case OID_GEN_MAXIMUM_TOTAL_SIZE :
		case OID_GEN_XMIT_OK :
		case OID_GEN_XMIT_ERROR :
		case OID_GEN_DIRECTED_BYTES_XMIT :
		case OID_GEN_DIRECTED_FRAMES_XMIT :
		case OID_GEN_MULTICAST_BYTES_XMIT :
		case OID_GEN_MULTICAST_FRAMES_XMIT :
		case OID_GEN_BROADCAST_BYTES_XMIT :
		case OID_GEN_BROADCAST_FRAMES_XMIT :
		case OID_GEN_TRANSMIT_QUEUE_LENGTH :
			fIsSend = TRUE;
			break;

		default:
			fIsSend = FALSE;
			break;
	}

	return fIsSend;
}

⌨️ 快捷键说明

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