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

📄 usbnicadap.cpp

📁 driver studio 中的例子usbnic.rar
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		// Copy partial packet buffer to Transfer buffer
		memcpy(Context->Buffer+count,Buffer,Size);
		count += Size;

		buf = buf.GetNext();
	}
	// Store the packet size in the Frame at the first word
	*((short *)Context->Buffer) = (short)count-2;

	pUrb = m_SendPipe.BuildBulkTransfer(
											Context->Buffer,
											count,
											FALSE,
											NULL,
											TRUE
											);

	if (pUrb == NULL)
	{
		delete Context;
		m_TxIrpPool.Free(I);
		return NDIS_STATUS_RESOURCES;
	}
	else
	{
		Context->m_pUrb = pUrb;
	}

	// Pass down the URB to the bus driver
	status = m_SendPipe.SubmitUrb (
									I,
									pUrb,
									WdmCompletionTxRoutine(this),
									Context
									);

	return status;
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::ReturnPacket
//
// This method is called when NDIS returns a packet previuosly
// indicated by IndicateReceive() back to the miniport
//
// Parameters:
//		Packet
//			Points to a packet descriptor specifying the packet
// IRQL:
//		DISPATCH_LEVEL
// Return Mode:
//		n/a
// NOTE:
//		The packet returns to the "free list" in the Rx area.
//		Reclaim() does the necessary reset of the chained buffer
//		and OOB data if any.
VOID USBNICAdapter::ReturnPacket(IN PNDIS_PACKET Packet)
{
	//TRACE("USBNICAdapter::ReturnPacket() Entered Packet=%p\n", Packet);

	// declare for convenience
	m_pRxArea->Reclaim(Packet);
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::CheckForHang
//		Optional function that reports the state of the NIC or monitors
//		 the responsiveness of an underlying device driver.
// Parameters:
//		none
// IRQL:
//		IRQL DISPATCH_LEVEL
// Return Mode:
//		Synchronous
// NOTE:
//		By default, the NDIS library calls MiniportCheckForHang
//		approximately every two seconds. If MiniportCheckForHang returns
//		TRUE, NDIS then calls the driver's MiniportReset function.
BOOLEAN USBNICAdapter::CheckForHang()
{
	return FALSE;
}

///////////////////////////////////////////////////////////////////////
// USBNICAdapter::CompletionRxRoutine
//
// Parameters:
// 	pIrp                 - irp being completed
// 	Context              - context passed when the irp had been submitted
// IRQL:
//		IRQL DISPATCH_LEVEL
// Returns:
// 	Usually, STATUS_MORE_PROCESSING_REQUIRED
// Comments:
// 	Processes asynchronous "receive" IRP completions: this is a "HandleInterrupt()"
//  thing for NDIS WDM drivers. So, the logic is similar to HandleInterrupt():
//  If a new received packet arrived indicate it to NDIS. Handle status indications, too.
//  The important point is that if the the irps are be recycled back to the pools they
//  came from, STATUS_MORE_PROCESSING_REQUIRED should be returned to the system.
// NOTE: Under Win9X, NDIS packet and status indications must NOT be made from
//       the completion routine context. Instead, the NDIS WDM driver should use the
//		 KNdisWdm9XIndication class which is used to schedule the indication on
//		 a timer.
NTSTATUS USBNICAdapter::CompletionRxRoutine(PIRP pIrp, IRP_CONTEXT *Context)
{
	PWDM_RFD pContext = (PWDM_RFD)Context;
	KIrp I(pIrp);
	NTSTATUS status = I.Status();
	//TRACE("USBNICAdapter::CompletionRxRoutine() Entered\n");
	if(status)
		TRACE("IRP RX completion status = %08X\n",ULONG(I.Status()));

	if (m_HaltFlag)
	{
		--m_RxIrpsOutstanding;
		TRACE("IRP RX Outstanding Count--= %08X\n",(ULONG)m_RxIrpsOutstanding);
		if (!m_RxIrpsOutstanding)
		{
			TRACE("IRP RX Idle Event being set!");
			m_RxIdleEvent.Set();
		}
		return STATUS_MORE_PROCESSING_REQUIRED;
	}

	if (status != NDIS_STATUS_SUCCESS)
	{
		if ((status == STATUS_DEVICE_DATA_ERROR) ||
			(status == STATUS_CANCELLED) ||
			(status == STATUS_DEVICE_NOT_CONNECTED))
		{
			// This error usually occurs when the device is malfunctioning
			// or it has been disconnected. Halt() cancels all outstanding Irps
			// Note: The OutStanding Rx Irp count must be decrimented because we got
			// here prior to the m_HaltFlag being set
			// TODO: add code to handle you case
			--m_RxIrpsOutstanding;
			TRACE("IRP RX Outstanding Count--= %08X\n",(ULONG)m_RxIrpsOutstanding);
			if (!m_RxIrpsOutstanding)
			{
				TRACE("IRP RX Idle Event being set!");
				m_RxIdleEvent.Set();
			}
			return STATUS_MORE_PROCESSING_REQUIRED;
		}
		else
		{
			//TODO: Handle the case were the Irp did not complete successfully
			//		In this example we simply are resending the URB back to the
			//		bus driver.
			ReSubmitRfd(pContext);
			return STATUS_MORE_PROCESSING_REQUIRED;
		}
	}

	// Retrieve the Packet descriptor that matches this HwRfd
	KNdisPacket Packet(m_pRxArea->GetPacket(pContext));
	ASSERT( Packet.IsValid() );

	// Extract the first available buffer
	KNdisBuffer buf = Packet.QueryFirstBuffer();
	ASSERT( buf.IsValid() );

	// Copy the Rx Packet data to the Packet
	short ActualSize = *((short *)pContext->m_RfdBuffer);
	if(0 == ActualSize)
	{
		ReSubmitRfd(pContext);
		return STATUS_MORE_PROCESSING_REQUIRED;
	}

	// Remove the Packet from the Rfd list
	m_pRxArea->Complete(pContext);

	// Make sure that the Packet to be indicated has the correct length
	buf.AdjustLength(ActualSize);
	Packet.STATUS(NDIS_STATUS_SUCCESS);

#if BINARY_COMPATIBLE
	m_PacketIndicate.ScheduleReceiveIndicate(Packet);
#else
	// Indicate the Packet to NDIS
	IndicateReceive(Packet);
#endif

	// Update the transmit stats
	m_GenStats->rcv_ok++;

	return STATUS_MORE_PROCESSING_REQUIRED;
}

#if BINARY_COMPATIBLE
///////////////////////////////////////////////////////////////////////
// USBNIC::ProcessReceiveIndicate
//
// Parameters:
//  Packet			- Packet to indicate
//  Context			- Anything you wish to carry forward that is not 
//					  resident in the packet.
// IRQL: 
//				= DISPATCH_LEVEL
// Returns:
// 	None
// Comments:
// 	This routine is used to perform the actual indication when the timer
// has expired.
//  
VOID USBNICAdapter::ProcessReceiveIndicate(PNDIS_PACKET Packet)
{
	// Indicate the Packet to NDIS
	IndicateReceive(Packet);
}
#endif

////////////////////////////////////////////////////////////////////
// USBNICAdapter::CompletionCntrlRoutine()
//
//
// Parameters:
//				Irp - IRP to be completed
//				Context - Associated context for the Irp
// IRQL:
//		IRQL DISPATCH_LEVEL
//
// Return Mode:
//
NTSTATUS USBNICAdapter::CompletionCntrlRoutine(KIrp Irp, IRP_CONTEXT* Context)
{
	TRACE("USBNICAdapter::CompletionCntrlRoutineLINK() Entered\n");
	TRACE("IRP Control completion status = %08X\n",ULONG(Irp->IoStatus.Information));

	// Free the associated Irp
	Context->Adapter->m_CntrlIrpPool.Free(Irp);

	// Destroy the associated Urb
	delete Context->m_pUrb;

	// Destroy the Context
	delete Context;

	return STATUS_MORE_PROCESSING_REQUIRED;
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::ReadConfiguration()
//
//		When this routine returns success, then it is
//	accepted that the device configuration was successfull.
//
// Parameters:
//				pEthConfig - pointer to a Ethernet_Configuration
//
// IRQL:
//		PASSIVE_LEVEL
//
// Return Mode:
//
NTSTATUS USBNICAdapter::ReadConfiguration(Ethernet_Configuration	*pEthConfig)
{
	NTSTATUS status = STATUS_SUCCESS;

	status = ControlCommand (
								USBNIC_COMMAND_GET_ETHERNET_DESC,
								USBD_TRANSFER_DIRECTION_IN,
								0,
								0,
								(PUCHAR)pEthConfig,
								sizeof(Ethernet_Configuration),
								TIMEOUT);
	return status;
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::DownLoadFirmware()
//
//		This routine is used to supply the Firmware Buffers to
//	the device.
//
// Parameters:
//
//			data - data to be downloaded
//			length - length of data buffer
//			interrupt - firmware specific params
//			type - firmware specific params
//
// IRQL:
//		PASSIVE_LEVEL
//
// Return Mode:
//				SYNCHRONOUS
NTSTATUS USBNICAdapter::DownLoadFirmware(PUCHAR data, USHORT length, UCHAR interrupt, UCHAR type)
{
	NTSTATUS status = STATUS_SUCCESS;

	if (length > BUF_SIZE)
		status = STATUS_UNSUCCESSFUL;
	else
	{
		memcpy((PUCHAR)FirmwareBuffer, data,length);
		status = ControlCommand (
								USBNIC_COMMAND_SCAN,
								USBD_TRANSFER_DIRECTION_OUT,
								type,
								interrupt,
								(PUCHAR)FirmwareBuffer,
								length,
								TIMEOUT);
	}

	return status;
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::TriggerFirmware()
//
//		This routine fires off the hardware to that it starts
//	performing as a NIC.
//
// Parameters:
//				None
// IRQL:
//		PASSIVE_LEVEL
//
// Return Mode:
//				SYNCHRONOUS
NTSTATUS USBNICAdapter::TriggerFirmware()
{
	NTSTATUS status = STATUS_SUCCESS;

	status = ControlCommand (
							USBNIC_COMMAND_SCAN,
							USBD_TRANSFER_DIRECTION_OUT,
							0,
							0,
							(PUCHAR)trigger_code,
							trigger_code_size,
							TIMEOUT);
	return status;
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::SetURBSize()
//
//		This routine is used to set the size of the URBs that the
//	adapter will accept. These URBs will contains bothe packet data
//	and configuration parameters.
//
// Parameters:
//				urb_size - size for the URB to be accepted by the
//							hardware.
//
// IRQL:
//		PASSIVE_LEVEL
//
// Return Mode:
//				SYNCHRONOUS
NTSTATUS USBNICAdapter::SetURBSize(short urb_size)
{
	NTSTATUS status = STATUS_SUCCESS;

	status = ControlCommand (
								USBNIC_COMMAND_SET_URB_SIZE,
								USBD_TRANSFER_DIRECTION_OUT,
								urb_size,
								0,
								NULL,
								0,
								TIMEOUT);
	return status;

}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::SetSOFSWait()
//
//		This routine sets the SOFS for the device.
//
// Parameters:
//				sofs_wait - specific value to the SOFS
// IRQL:
//		PASSIVE_LEVEL
//
// Return Mode:
//				SYNCHRONOUS
NTSTATUS USBNICAdapter::SetSOFSWait(short sofs_wait)
{
	NTSTATUS status = STATUS_SUCCESS;

	status = ControlCommand (
							USBNIC_COMMAND_SET_SOFS_WAIT,
							USBD_TRANSFER_DIRECTION_OUT,
							sofs_wait,
							0,
							NULL,
							0,
							TIMEOUT);
	return status;
}


////////////////////////////////////////////////////////////////////
// USBNICAdapter::SetReceiveFilter()
//
//		This routine converts the NDIS Rx filter values to the
//	device specific values.
//
// Parameters:
//				Rxfilters - NDIS Rx Filter values
//
// IRQL:
//		PASSIVE_LEVEL or DISPATCH_LEVEL
//
// Return Mode:
//			SYNCHRONOUS(for PASSIVE) or ASYNCHRONOUS(for DISPATCH)
// Comments:
//	During the setOID_GEN_CURRENT_PACKET_FILTER this routine runs
//	at DISPATCH_LEVEL. During device configuration this routine runs
//	at PASSIVE_LEVEL.
//
NTSTATUS USBNICAdapter::SetReceiveFilter(ULONG Rxfilters)
{
	KIRQL kIrql;
	NTSTATUS status = STATUS_SUCCESS;

	short receive_filters = 0;

	if (Rxfilters & NDIS_PACKET_TYPE_FUNCTIONAL)
		receive_filters =	USBNIC_PACKET_FILTER_DIRECTED |
							USBNIC_PACKET_FILTER_BROADCAST |
							USBNIC_PACKET_FILTER_MULTICAST |
							USBNIC_PACKET_FILTER_PROMISCUOUS |
							USBNIC_PACKET_FILTER_ALL_MULTICAST
							;

	else
	{
		receive_filters |= Rxfilters & NDIS_PACKET_TYPE_DIRECTED ? USBNIC_PACKET_FILTER_DIRECTED : 0;
		receive_filters |= Rxfilters & NDIS_PACKET_TYPE_BROADCAST  ? USBNIC_PACKET_FILTER_BROADCAST : 0;
		receive_filters |= Rxfilters & NDIS_PACKET_TYPE_MULTICAST ? USBNIC_PACKET_FILTER_MULTICAST : 0;
		receive_filters |= Rxfilters & NDIS_PACKET_TYPE_PROMISCUOUS  ? USBNIC_PACKET_FILTER_PROMISCUOUS : 0;
		receive_filters |= Rxfilters & NDIS_PACKET_TYPE_ALL_MULTICAST  ? USBNIC_PACKET_FILTER_ALL_MULTICAST : 0;
	}

	kIrql = KeGetCurrentIrql();
	if (kIrql < DISPATCH_LEVEL)
	{
		// Pass the URB to the bus driver at PASSIVE level
		status = ControlCommand (
									USBNIC_COMMAND_SET_PACKET_FILTER,
									USBD_TRANSFER_DIRECTION_OUT,
									receive_filters,
									0,
									NULL,
									0,
									TIMEOUT);
	}
	else
	{

⌨️ 快捷键说明

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