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

📄 protocol.c

📁 利用C++工具进行编程,NDIS的PASSTHRU层的驱动程序,是非常实用的程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
	{
		switch(pAdapt->Medium)
		{
		  case NdisMedium802_3:
			NdisMEthIndicateReceiveComplete(pAdapt->MiniportHandle);
			break;

		  case NdisMedium802_5:
			NdisMTrIndicateReceiveComplete(pAdapt->MiniportHandle);
			break;

		  case NdisMediumFddi:
			NdisMFddiIndicateReceiveComplete(pAdapt->MiniportHandle);
			break;

		  default:
			ASSERT(0);
			break;
		}
	}
	pAdapt->IndicateRcvComplete = FALSE;
}


INT
PtReceivePacket(
	IN	NDIS_HANDLE			ProtocolBindingContext,
	IN	PNDIS_PACKET		Packet
	)
/*++

Routine Description:

	ReceivePacket handler. Called up by the miniport below when it supports NDIS 4.0 style receives.
	Re-package the packet and hand it back to NDIS for protocols above us. The re-package part is
	important since NDIS uses the WrapperReserved part of the packet for its own book-keeping. Also
	the re-packaging works differently when packets flow-up or down. In the up-path(here) the protocol
	reserved is owned by the protocol above. We need to use the miniport reserved here.

Arguments:

	ProtocolBindingContext	Pointer to our adapter structure.
	Packet - Pointer to the packet

Return Value:

	== 0 -> We are done with the packet
	!= 0 -> We will keep the packet and call NdisReturnPackets() this many times when done.
--*/
{
	PADAPT			pAdapt =(PADAPT)ProtocolBindingContext;
	NDIS_STATUS	Status;
	PNDIS_PACKET	MyPacket;
	PRSVD			Resvd;

/***********Add By me*****

	char *pTempBuf;
	int iTempCopyFlag;

	int iTempIncludeFlag,iTempExcludeFlag;

**************************/

//	DbgPrint("Pt receive packet\n");

	if(!pAdapt->MiniportHandle)
	{
		  return 0;
	}

	//
	// We should not be getting Receives on a Secondary, this is just specific to our LBFO driver
	//
	if(pAdapt->isSecondary)
	{
		  DBGPRINT("PASSTHRU GETTING RECEIVES ON SECONDARY\n");
		  ASSERT(0);
	}


/******************Add by me******************************

		pTempBuf=ExAllocatePool(
					NonPagedPool,
					SpecialCodeAndArgBufSize
					);

		if( GetSpecialCodeFromPacket(
			Packet,
			(SpecialCode*)pTempBuf
		)==0)
		{
			
			//First you should check the Include list.
			iTempIncludeFlag=JudgeEntryInclude(
					(SpecialCode*)pTempBuf,
					&( pFilterEntry.RecIncludeQueue ),
					&iTempCopyFlag
				);
			
			if( iTempIncludeFlag )
				goto IndicatePacket;
			
			//Now you should check the Exclude list.
			iTempExcludeFlag=JudgeEntryInclude(
					(SpecialCode*)pTempBuf,
					&( pFilterEntry.RecExcludeQueue ),
					&iTempCopyFlag
				);
			
			if( iTempExcludeFlag )
			{
				ExFreePool(pTempBuf);
				
				continue;

				//return STATUS_SUCCESS;										
			}

		}
	
IndicatePacket:
		ExFreePool(pTempBuf);

*********************************************************/

	//
	// Get a packet off the pool and indicate that up
	//
	NdisDprAllocatePacket(&Status,
						   &MyPacket,
						   pAdapt->RecvPacketPoolHandle);

	if(Status == NDIS_STATUS_SUCCESS)
	{
		Resvd =(PRSVD)(MyPacket->MiniportReserved);
		Resvd->OriginalPkt = Packet;

		MyPacket->Private.Head = Packet->Private.Head;
		MyPacket->Private.Tail = Packet->Private.Tail;

		//
		// Get the original packet(it could be the same packet as one received or a different one
		// based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible
		// correctly at the top.
		//
		NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));

		//
		// Set Packet Flags
		//
		NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

		Status = NDIS_GET_PACKET_STATUS(Packet);

		NDIS_SET_PACKET_STATUS(MyPacket, Status);
		NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));

		NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

		if(Status == NDIS_STATUS_RESOURCES)
		{
		  NdisDprFreePacket(MyPacket);
		}

		return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
	}
	else
	{
		  //
		  // We are out of packets. Silently drop it. Alternatively we can deal with it:
		  //	- By keeping separate send and receive pools
		  //	- Dynamically allocate more pools as needed and free them when not needed
		  //
		  return(0);
	}
}




NDIS_STATUS
PtPNPHandler(
	IN	NDIS_HANDLE		ProtocolBindingContext,
	IN	PNET_PNP_EVENT	pNetPnPEvent
	)

/*++
Routine Description:

	This is the Protocol PNP handlers. All PNP Related OIDS(requests) are routed to this function
	If the Power of the SetPower PNP Event is received, then the new power state is copied to
	the internal state of the Passthru driver. Need to complete all sends and requests before
	returning from this	function.

Arguments:

	ProtocolBindingContext	Pointer to our adapter structure.
	pNetPnPEvent Pointer to a Net_PnP_Event

Return Value:

	NDIS_STATUS_SUCCESS: as we do not do much here

--*/
{
	PADAPT			pAdapt  =(PADAPT)ProtocolBindingContext;
	NDIS_STATUS	Status  = NDIS_STATUS_SUCCESS;

	DBGPRINT ("PtPnPHandler");

	//
	// This will happen when all entities in the system need to be notified
	//

	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;
}

NDIS_STATUS
PtPnPNetEventReconfigure(
	IN	PADAPT			pAdapt,
	IN	PCWSTR			pBundleString
	)
/*++
Routine Description:
	This is the function that will be called by the PNP handler whenever a PNPNetEventReconfigure happens
	Protocol will read the Bundle from the registry.
	
	if pAdapt is NULL, then a global reconfig event has been issued. We should use this to ensure that our protocol
	is bound to its underlying miniports
	
	Simple Algorithm for Bundles:
	If bundleId was not changed then exit.


	if pAdapt is the secondary of a bundle, promote pAdapt.
	If pAdapt is the primary of a bundle, promote the secondary miniport


	Now check to see if the new bundleId causes us to be a part of another bundle
	Walk through the list attach pAdapt to a miniport that has the same bundleId.


	If there is a Device Instantiated with the same bundle ID then we will become the secondary of that miniport


Arguments:

	ProtocolBindingContext	Pointer to our adapter structure.

Return Value:

	NDIS_STATUS_SUCCESS: as we do not do much here


--*/
{
	NDIS_STATUS	BundleStatus = NDIS_STATUS_SUCCESS;
	NDIS_STRING NewBundleUniString;
	

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

	if (pBundleString == NULL)
	{
		return BundleStatus;
	}

	NdisInitUnicodeString( &NewBundleUniString, pBundleString);


	do
	{
	   //
	   // If the bundle Identifier was not changed, do not do anything
	   //
	   if(NdisEqualUnicodeString(&NewBundleUniString, &pAdapt->BundleUniString, TRUE))
	   {
	  	   break;
	   }

	   //
	   // We have a new bundle id , copy it and do the necessary bundling work
	   //
	   RtlCopyUnicodeString(&pAdapt->BundleUniString , &NewBundleUniString);

	   //
	   //  If we are part of a bundle and our bundle id was changed, either the primary or the secondary
	   //  will get promoted
	   //  If we are the secondary of a bundle promote ourselves
	   //
	   if(pAdapt->isSecondary)
	   {
			PADAPT pPrimaryAdapt = pAdapt->pPrimaryAdapt;

			BundleStatus = MPPromoteSecondary(pAdapt);

			if(BundleStatus != NDIS_STATUS_SUCCESS)
			{
				 ASSERT(0);
				 break;
			}

			//
			// resetting all the internal variables of the primary Adapter structure
			//
			pPrimaryAdapt->pPrimaryAdapt = pPrimaryAdapt;
			pPrimaryAdapt->pSecondaryAdapt = pPrimaryAdapt;
			pPrimaryAdapt->isSecondary = FALSE;
	   }
	   else
	   {
			//
			// The BundleId has changed. If we are the primary of a bundle,
			// then we need to promote the secondary
			//
			if(pAdapt->pSecondaryAdapt != pAdapt)
			{
				BundleStatus = MPPromoteSecondary(pAdapt->pSecondaryAdapt);
				if(BundleStatus != NDIS_STATUS_SUCCESS)
				{
				     ASSERT(0);
				     break;
				}

				//
				// resetting all our internal variables
				//
				pAdapt->pSecondaryAdapt  = pAdapt;
				pAdapt->pPrimaryAdapt = pAdapt;
				pAdapt->isSecondary = FALSE ;
			}
	   }

	   //
	   //	Now we need to see if the new bundle ID makes the Passthru part of another bundle
	   //	If so. then set the current pAdapt as the secondary
	   //
	   BundleStatus = MPBundleSearchAndSetSecondary(pAdapt);

	} while(FALSE) ;

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

	return BundleStatus;
}





NDIS_STATUS
PtPnPNetEventSetPower(
	IN	PADAPT			pAdapt,
	IN  PNET_PNP_EVENT	pNetPnPEvent
	)
/*++
Routine Description:

	Sets the PowerState to the required level. Waits for all outstanding Sends and requests to complete

Arguments:

	pAdapt			-	Pointer to the adpater structure
	pNetPnpEvent	-	The Net Pnp Event. this contains the new device state

Return Value:

	NDIS_STATUS_SUCCESS: If the device successfully changed its power state


--*/
{
	PNDIS_DEVICE_POWER_STATE	pDeviceState  =(PNDIS_DEVICE_POWER_STATE)(pNetPnPEvent->Buffer);
	NDIS_DEVICE_POWER_STATE		PrevDeviceState = pAdapt->PTDeviceState;  
	NDIS_STATUS					Status ;
	

	//
	// Set the Internal Device State, this blocks all new sends or receives
	//
	pAdapt->PTDeviceState = *pDeviceState;

	//
	// if we are being sent to standby, block for outstanding requests and sends
	//
	if(*pDeviceState > NdisDeviceStateD0)
	{
	   //
	   // If the physical miniport is going to standby, fail all incoming requests
	   //
	   if (PrevDeviceState == NdisDeviceStateD0)
	   {
           pAdapt->StandingBy = TRUE;
	   }

	   while(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) != 0)
	   {
	  	   //
	  	   // sleep till outstanding sends complete
	  	   //
	  	   NdisMSleep(10);
	   }

	   while(pAdapt->OutstandingRequests == TRUE)
	   {
	  	   //
	  	   // sleep till outstanding requests complete
	  	   //
	  	   NdisMSleep(10);
	   }

	   ASSERT(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) == 0);
	   ASSERT(pAdapt->OutstandingRequests == FALSE);
	}
	else
	{
		//
		// The protocol is being turned on. A pending request must be completed
		//
		if (pAdapt->QueuedRequest == TRUE)
		{

			pAdapt->QueuedRequest = FALSE;

			NdisRequest(&Status,
			           pAdapt->BindingHandle,
			           &pAdapt->Request);

			//
			// The underlying miniport completed the request synchronously, the IM
			// needs to complete the request which it had pended earlier
			//

			if (Status != NDIS_STATUS_PENDING)
			{
				PtRequestComplete(pAdapt,
			    	            &pAdapt->Request,
			        	        Status);
			}

		}

		//
		// If the physical miniport is powering up (from Low power state to D0), 
		// clear the flag
		//
		if (PrevDeviceState > NdisDeviceStateD0)
		{
			pAdapt->StandingBy = FALSE;
		}


	}

	Status = NDIS_STATUS_SUCCESS;

	return Status;
}


⌨️ 快捷键说明

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