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

📄 prothook.c

📁 ndis 中间层截获后转发的例子,通过修改IP 地址和MAC地址转发.
💻 C
📖 第 1 页 / 共 2 页
字号:
	pAdapt->Status	= Status;
	NdisSetEvent(&pAdapt->Event);
	DBGPRINT("<== Passthru Protocol PtCloseAdapterComplete\n");
}

/*——————————————————————————————————————
	复位操作完成后的处理函数,由于Passthru不需要复位,所以这里什么都没有做。
*/
VOID
PtResetComplete(
	IN  NDIS_HANDLE			ProtocolBindingContext,
	IN  NDIS_STATUS			Status
	)
{
	PADAPT	pAdapt =(PADAPT)ProtocolBindingContext;
	ASSERT(0);
	DBGPRINT("<== Passthru Protocol PtResetComplete\n");
}

/*——————————————————————————————————————
	完成请求的操作函数,所有的OID被完整的发送到同一个请求的miniport设备
	如果Oid == OID_PNP_QUERY_POWER那么数据结构都需要以 entries = 
	NdisDeviceStateUnspecified的形式返回
*/
VOID
PtRequestComplete(
	IN  NDIS_HANDLE			ProtocolBindingContext,
	IN  PNDIS_REQUEST		NdisRequest,
	IN  NDIS_STATUS			Status
)
{
	PADAPT		pAdapt	= (PADAPT)ProtocolBindingContext;
	NDIS_OID	Oid		= pAdapt->Request.DATA.SET_INFORMATION.Oid ;

	//————————————————————————————————————
	// 根据请求来源改变pAdapt
	//
	if(MPIsSendOID(Oid))
	  pAdapt = pAdapt->pPrimaryAdapt;

	//————————————————————————————————————
	// 设置我们的请求不再紧急
	//
	pAdapt->OutstandingRequests = FALSE;

	//————————————————————————————————————
	// 如果需要,完成设置或者查询,并且为OID_PNP_CAPABILITIES缓冲区填充
	//
	switch(NdisRequest->RequestType)
	{
		case NdisRequestQueryInformation:
			ASSERT(Oid != OID_PNP_QUERY_POWER);
		
			//————————————————————————————————
			// 如果oid == OID_PNP_CAPABILITIES并且查询成功便填充必须的数值
			//
			if(Oid == OID_PNP_CAPABILITIES && Status == NDIS_STATUS_SUCCESS)
				MPQueryPNPCapbilities(pAdapt,&Status);

			*pAdapt->BytesReadOrWritten 
				= NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
			*pAdapt->BytesNeeded 
				= NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
			NdisMQueryInformationComplete(pAdapt->MiniportHandle, Status);
			break;

		case NdisRequestSetInformation:
			ASSERT( Oid != OID_PNP_SET_POWER);
			*pAdapt->BytesReadOrWritten 
				= NdisRequest->DATA.SET_INFORMATION.BytesRead;
			*pAdapt->BytesNeeded 
				= NdisRequest->DATA.SET_INFORMATION.BytesNeeded;
			NdisMSetInformationComplete(pAdapt->MiniportHandle, Status);
			break;

		default:
			ASSERT(0);
			break;
	}
	DBGPRINT("<== Passthru Protocol PtRequestComplete\n");
}

/*——————————————————————————————————————
	调用NdisMIndicateStatus完成状态标识的传递
*/
VOID
PtStatus(
	IN  NDIS_HANDLE			ProtocolBindingContext,
	IN  NDIS_STATUS			GeneralStatus,
	IN  PVOID				StatusBuffer,
	IN  UINT				StatusBufferSize
)
{
	PADAPT	  pAdapt =(PADAPT)ProtocolBindingContext;

	//————————————————————————————————————
	// 在miniport初始化前得到的状态指示需要跳过,如果passthru没有设置为ON,
	// 我们不传递状态标识
	//
	if(pAdapt->MiniportHandle != NULL  &&
	  pAdapt->MPDeviceState == NdisDeviceStateD0 &&
	  pAdapt->PTDeviceState == NdisDeviceStateD0 )	
	{
		  NdisMIndicateStatus(pAdapt->MiniportHandle
			  , GeneralStatus, StatusBuffer, StatusBufferSize);
	}

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

/*——————————————————————————————————————
	状态标识传递完成后的处理函数
*/
VOID
PtStatusComplete(
	IN	NDIS_HANDLE			ProtocolBindingContext
)
{
	PADAPT	  pAdapt =(PADAPT)ProtocolBindingContext;

	//————————————————————————————————————
	// 在miniport初始化前得到的状态指示需要跳过
	//
	if(pAdapt->MiniportHandle != NULL  &&
	  pAdapt->MPDeviceState == NdisDeviceStateD0 &&
	  pAdapt->PTDeviceState == NdisDeviceStateD0 )	
	{
		  NdisMIndicateStatusComplete(pAdapt->MiniportHandle);
	}
	DBGPRINT("<== Passthru Protocol PtStatusComplete\n");
}

/*——————————————————————————————————————
	这是一个Protocol PNP操作函数。所有PNP相关的OID请求被送到这个函数进行处理
*/
NDIS_STATUS
PtPNPHandler(
	IN	NDIS_HANDLE		ProtocolBindingContext,
	IN	PNET_PNP_EVENT	pNetPnPEvent
)
{
	PADAPT		pAdapt  =(PADAPT)ProtocolBindingContext;
	NDIS_STATUS	Status  = NDIS_STATUS_SUCCESS;

	DBGPRINT("==> Passthru Protocol PtPNPHandler\n");

	//————————————————————————————————————
	// 用当在系统中所有的实体需要改变时这里将执行
	//

	switch(pNetPnPEvent->NetEvent)
	{
	 case  NetEventSetPower :
	    Status = PtPnPNetEventSetPower(pAdapt, pNetPnPEvent);
	    break;

	 case NetEventReconfigure :
	    Status  = PtPnPNetEventReconfigure(pAdapt, (PCWSTR)pNetPnPEvent->Buffer);
	    break;

	 default :
	    Status  = NDIS_STATUS_SUCCESS;
	    break;
	}

	return Status;
}

/*——————————————————————————————————————
	只要PNPNetEventReconfigure被触发,这个函数将被调用。这里protocol将从注
	册表读取绑定信息。
*/
NDIS_STATUS
PtPnPNetEventReconfigure(
	IN	PADAPT			pAdapt,
	IN	PCWSTR			pBundleString
)
{
	NDIS_STATUS	BundleStatus = NDIS_STATUS_SUCCESS;
	NDIS_STRING NewBundleUniString;
	
	DBGPRINT("==> Passthru Protocol PtPnPNetEventReconfigure\n");

	if(pAdapt == NULL)
	{
		NdisReEnumerateProtocolBindings (ProtHandle);		
		return BundleStatus;
	}
	if (pBundleString == NULL)
		return BundleStatus;

	NdisInitUnicodeString( &NewBundleUniString, pBundleString);

	do
	{
		//——————————————————————————————————
		// 如果绑定标识没有改变,不需要做任何处理。
		//
	    if(NdisEqualUnicodeString(
			&NewBundleUniString, &pAdapt->BundleUniString, TRUE))
	  	   break;

		//——————————————————————————————————
		// 有一个新的绑定ID,复制它并作一些需要的绑定工作。
		//
	    RtlCopyUnicodeString(&pAdapt->BundleUniString , &NewBundleUniString);

	    if(pAdapt->isSecondary)
		{
			PADAPT pPrimaryAdapt = pAdapt->pPrimaryAdapt;
			BundleStatus = MPPromoteSecondary(pAdapt);
			if(BundleStatus != NDIS_STATUS_SUCCESS)
			{
				 ASSERT(0);
				 break;
			}

			//————————————————————————————————
			// 重新设置主设备所有的成员变量。
			//
			pPrimaryAdapt->pPrimaryAdapt	= pPrimaryAdapt;
			pPrimaryAdapt->pSecondaryAdapt	= pPrimaryAdapt;
			pPrimaryAdapt->isSecondary		= FALSE;
		}
	    else
		{
			//————————————————————————————————
			// 绑定ID已经改变,如果我们绑定主设备,那吗我们需要设置第二个
			// 设备为主设备。
			//
			if(pAdapt->pSecondaryAdapt != pAdapt)
			{
				BundleStatus = MPPromoteSecondary(pAdapt->pSecondaryAdapt);
				if(BundleStatus != NDIS_STATUS_SUCCESS)
				{
				     ASSERT(0);
				     break;
				}
				pAdapt->pSecondaryAdapt = pAdapt;
				pAdapt->pPrimaryAdapt	= pAdapt;
				pAdapt->isSecondary		= FALSE ;
			}
		}

		//——————————————————————————————————
		// 如果做了一个新的绑定,需要设置当前设备为第二个设备
		//
	    BundleStatus = MPBundleSearchAndSetSecondary(pAdapt);

	} while(FALSE) ;

	DBGPRINT("<==PtPNPNetEventReconfigure\n");

	return BundleStatus;
}

/*——————————————————————————————————————
	设置电源状态到需要的级别,等待所有的发送和请求完成。
*/
NDIS_STATUS
PtPnPNetEventSetPower(
	IN	PADAPT			pAdapt,
	IN  PNET_PNP_EVENT	pNetPnPEvent
)
{
	PNDIS_DEVICE_POWER_STATE	pDeviceState; 
	NDIS_DEVICE_POWER_STATE		PrevDeviceState = pAdapt->PTDeviceState;  
	NDIS_STATUS					Status ;
	pDeviceState = (PNDIS_DEVICE_POWER_STATE)(pNetPnPEvent->Buffer);
	
	DBGPRINT("==> Passthru Protocol PtPnPNetEventSetPower\n");

	//————————————————————————————————————
	// 设置设备状态,这将阻断所有新的发送和接收请求
	//
	pAdapt->PTDeviceState = *pDeviceState;

	if(*pDeviceState > NdisDeviceStateD0)
	{
		//——————————————————————————————————
		// 如果物理miniport变成待命,所有进入的请求失败。
		//
	    if (PrevDeviceState == NdisDeviceStateD0)
           pAdapt->StandingBy = TRUE;

		//——————————————————————————————————
		// 等待直到发送完成。
		//
	    while(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) != 0)
	  	   NdisMSleep(10);

		//——————————————————————————————————
		// 等待直到请求完成。
		//
	    while(pAdapt->OutstandingRequests == TRUE)
	  	   NdisMSleep(10);

		ASSERT(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) == 0);
		ASSERT(pAdapt->OutstandingRequests == FALSE);
	}
	else
	{
		//——————————————————————————————————
		// protocol设备已经打开,一个挂起的请求必须完成。
		//
		if (pAdapt->QueuedRequest == TRUE)
		{
			pAdapt->QueuedRequest = FALSE;
			NdisRequest(&Status, pAdapt->BindingHandle, &pAdapt->Request);

			//————————————————————————————————
			// 下层的miniport同步的完成请求,passthru需要完成挂起的请求。
			//
			if (Status != NDIS_STATUS_PENDING)
				PtRequestComplete(pAdapt, &pAdapt->Request, Status);
		}

		//——————————————————————————————————
		// 如果物理miniport的状态为D0,清除标记
		//
		if (PrevDeviceState > NdisDeviceStateD0)
			pAdapt->StandingBy = FALSE;
	}

	Status = NDIS_STATUS_SUCCESS;

	return Status;
}

⌨️ 快捷键说明

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