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

📄 usbnicadap.cpp

📁 driver studio 中的例子usbnic.rar
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		// Allocate and initialize the context block:
		IRP_CONTEXT* Context = new (&m_ContextHeap) IRP_CONTEXT (this, NULL);
		// Validate the new context
		if(Context == NULL)
		{
			// Return failure so that send can queue the packet
			return NDIS_STATUS_RESOURCES;
		}

		// Pass the URB to the bus driver at DISPATCH level
		PURB pUrb = m_BusDevice.BuildVendorRequest(
							NULL,
							0,
							0,
							USBNIC_COMMAND_SET_PACKET_FILTER,
							receive_filters,
							USBD_TRANSFER_DIRECTION_OUT,
							FALSE,
							NULL,
							0,
							URB_FUNCTION_VENDOR_DEVICE,
							NULL
							);

		// Validate the URB
		if (pUrb==NULL)
		{
			delete Context;
			return NDIS_STATUS_RESOURCES;
		}

		// Store the URB and allocate a Control Irp from the pool
		Context->m_pUrb = pUrb;
		KIrp I=m_CntrlIrpPool.Allocate();

		// Validate the Irp
		if (I.IsNull())
		{
			delete pUrb;
			delete Context;
			return NDIS_STATUS_RESOURCES;
		}

		// NOTES:To be fixed
		// Store the adapter "this" pointer in the m_pClass param
		// of the Context for the DriverWorks MEMBER_COMPLETEIRPWITHCONTEXT
		// macro to work
		Context->m_pClass = this;

		// send the URB to the device
		status = m_BusDevice.SubmitUrb(
										I,
										pUrb,
										LinkTo(CompletionCntrlRoutine),
										(void*)Context,
										100
										);
		if(status == STATUS_PENDING)
			status = STATUS_SUCCESS;
	}

	return status;
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::ActivateDevice()
//
//		This routine is used to select the proper configuration of
//	the USB device
//
// Parameters: None
//
// IRQL:
//		PASSIVE_LEVEL
//
// Return Mode:
//		SYNCHRONOUS
//
AC_STATUS USBNICAdapter::ActivateDevice()
{
	AC_STATUS		acStatus;
	acStatus = m_BusDevice.ActivateConfiguration(1);	// Configuration value 1

	switch (acStatus)
	{
		case AC_SUCCESS:
			TRACE("USB Configuration OK\n");
			//GetStringDescriptors();
			break;

		case AC_COULD_NOT_LOCATE_INTERFACE:
			TRACE("Could not locate the interface in the config descriptor\n");
			//Check that the Interface Number and Alternate Setting
			//for the KUsbInterface object initialized in the constructor match
			//an interface descriptor reported by the hardware.
			break;

		case AC_COULD_NOT_PRECONFIGURE_INTERFACE:
			TRACE("Could not get configuration descriptor\n");
			break;

		case AC_CONFIGURATION_REQUEST_FAILED:
			TRACE("Board did not accept configuration URB\n");
			break;

		case AC_FAILED_TO_INITIALIZE_INTERFACE_OBJECT:
			TRACE("Failed to initialize interface object\n");
			break;

		case AC_FAILED_TO_LOCATE_ENDPOINT_ADDRESS:
			TRACE("Failed to locate endpoint address for pipe\n");
			break;

		case AC_FAILED_TO_OPEN_PIPE_OBJECT:
			//NOTE: this may or may not be fatal.  It could mean that
			//the device has an endpoint for which a KUsbPipe object has
			//not been instanced.  If the intention is to not use this pipe,
			//then it's ok.  Otherwise, there is a failure.  Clients can
			//iterate through the pipe array  in KUsbLowerDevice to check
			//which pipes are open/closed.
			TRACE("Failed to open pipe object \n");
			break;

		default:
			TRACE("Unexpected error activating USB configuration\n");
			// Possibly the device is disconnected
			break;
	}

	return acStatus;
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::ConfigureAndProbeDevice()
//
//	This is the main routine used to configure the USB NIC device.
//	It downloads the firmware and configures the cards settings.
//
// Parameters: None
// IRQL:
//		PASSIVE_LEVEL
//
// Return Mode:
//		SYNCHRONOUS
//
NTSTATUS USBNICAdapter::ConfigureAndProbeDevice()
{
	NTSTATUS status = STATUS_SUCCESS;
	AC_STATUS		acStatus;

	status = DownLoadFirmware(new_code, new_code_size,0,0);
	if (status!=NDIS_STATUS_SUCCESS)
		return status;

	TriggerFirmware();
	if (status!=NDIS_STATUS_SUCCESS)
		return status;

	SetURBSize(BUF_SIZE);
	if (status!=NDIS_STATUS_SUCCESS)
		return status;

	SetSOFSWait(SOFS_TO_WAIT);
	if (status!=NDIS_STATUS_SUCCESS)
		return status;

	acStatus = ActivateDevice();
	if (acStatus != AC_SUCCESS)
		return STATUS_UNSUCCESSFUL;

	NdisStallExecution(100000);
	status = ReadConfiguration(&EthConfig);
	if (status!=NDIS_STATUS_SUCCESS)
		return status;

	// Cache the MAC address
	memcpy(&m_CurrentAddress.m_bytes[0], &EthConfig.MAC_Address.EthNodeAddress[0], 6);
	memcpy(&m_PermanentAddress.m_bytes[0], &EthConfig.MAC_Address.EthNodeAddress[0], 6);

	NdisStallExecution(100000);
	m_uPacketFilter = NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST |
					  NDIS_PACKET_TYPE_BROADCAST;

	SetReceiveFilter(m_uPacketFilter);

	return status;
}

////////////////////////////////////////////////////////////////////
// USBNICAdapter::ControlCommand()
//
//	This routine is used to submit all the SYNCHRONOUS URBS to the
//	device.
//
// Parameters:
//			Request - Device specific command request code
//			Direction - IN/OUT
//			Value - USB URB Value
//			Index - USB URB Index
//			Data - pointer to data that will be submitted
//			Size - size of buffer pointed to by Data
//			Timeout - unused
//
// IRQL:
//		PASSIVE_LEVEL
// Return Mode:
//		SYNCHRONOUS
NTSTATUS USBNICAdapter::ControlCommand (
						  UCHAR Request,
						  UCHAR Direction,
						  USHORT Value,
						  USHORT Index,
						  PUCHAR Data,
						  short Size,
						  short Timeout )
{
	NTSTATUS status = STATUS_SUCCESS;

	PURB pUrb = m_BusDevice.BuildVendorRequest(
												Data,
												Size,
												0,
												Request,
												Value,
												Direction,
												FALSE,
												NULL,
												Index,
												URB_FUNCTION_VENDOR_DEVICE,
												NULL
												);

	status = m_BusDevice.SubmitUrb(pUrb);

	delete pUrb;

	return status;
}

///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DescriptorInitialize
//
// Parameters:
//  pWdmDesc			- The descriptor to initialize
//	pPhysAddr			- Physycal Address Pointer
// IRQL:
//				<= DISPATCH_LEVEL
// Returns:
// 	NONE
// Comments:
//	Called by KNdisSystemReceiveArea to initialize each descriptor.
//	This routine is called for each descriptor.
//
VOID USBNICAdapter::DescriptorInitialize(
	PWDM_RFD pWdmDesc,
	PNDIS_PHYSICAL_ADDRESS pPhysAddr
	)
{
	TRACE("USBNICAdapter::DescriptorInitialize\n");

	// Get an available IRP from the Rx Irp pool
	KIrp I = m_RxIrpPool.Allocate();
	// Validate the Irp
	if (I.IsNull())
	{
		TRACE("USBNICAdapter::DescriptorInitialize() Irp allocation error\n");
		ASSERT(!"Irp allocation error\n");
		return;
	}

	pWdmDesc->m_Irp = I;
	pWdmDesc->m_pAdapter = this;

	// Create an BULK URB
	pWdmDesc->m_pUrb = m_ReceivePipe.BuildBulkTransfer(
											pWdmDesc->m_RfdBuffer,
											BUF_SIZE,
											TRUE,
											NULL,
											TRUE
											);
	// Validate the URB
	if (pWdmDesc->m_pUrb == NULL)
	{
		TRACE("USBNICAdapter::DescriptorInitialize() Urb creation error\n");
		m_RxIrpPool.Free(pWdmDesc->m_Irp);
		ASSERT(!"Urb creation error\n");
		return;
	}

	pWdmDesc->m_RfdActualCount= 0;
	pWdmDesc->m_RfdSize = BUF_SIZE;

	// Pass down the URB to the bus driver
	NTSTATUS status = m_ReceivePipe.SubmitUrb (
												pWdmDesc->m_Irp,
												pWdmDesc->m_pUrb,
												WdmCompletionRxRoutine(this),
												pWdmDesc
												);
	// update the Rx Irp count
	++m_RxIrpsOutstanding;
	TRACE("IRP RX Outstanding Count++= %08X\n",(ULONG)m_RxIrpsOutstanding);

	// Add the IRP to the RxIrp list
	m_RxIrpList.InsertTail(pWdmDesc);
	DumpWdmRfd(pWdmDesc);

}

///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DescriptorInvalidate
//
// Parameters:
//  pWdmDesc			- The descriptor to invalidate
// IRQL:
//				<= DISPATCH_LEVEL
// Returns:
// 	NONE
// Comments:
// 	Called by KNdisSystemReceiveArea to undo any initializations done
//	during the Initialize step. The look aside list is flushed.
//	This routine is called for each descriptor.
//
VOID USBNICAdapter::DescriptorInvalidate(
	PWDM_RFD pWdmDesc
	)
{
	TRACE("USBNICAdapter::DescriptorInvalidate\n");
	m_RxIrpPool.Free(pWdmDesc->m_Irp);
	delete pWdmDesc->m_pUrb;
}

///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DescriptorComplete
//
// Parameters:
//  pWdmDesc			- The descriptor to complete
//	pPhysAddr			- Physycal Address Pointer
// IRQL:
//				<= DISPATCH_LEVEL
// Returns:
// 	NONE
// Comments:
//
VOID USBNICAdapter::DescriptorComplete(
	PWDM_RFD pWdmDesc,
	PNDIS_PHYSICAL_ADDRESS pPhysAddr
	)
{
	//TRACE("USBNICAdapter::DescriptorComplete\n");
	DumpWdmRfd(pWdmDesc);
}

///////////////////////////////////////////////////////////////////////
// USBNICAdapter::ReSubmitRfd
//
//	This member is used to pass the IRP and URB pair back to the
//	bus driver.
//
// Parameters:
//  pWdmDesc			- The descriptor to reclaim
// IRQL:
//				<= DISPATCH_LEVEL
// Returns:
// 	NONE
// Comments:
//			Resubmit the URB to the bus driver for reuse
//
void USBNICAdapter::ReSubmitRfd(PWDM_RFD pWdmDesc)
{
	//TRACE("USBNICAdapter::ReSubmitRfd\n");

	KIrp Irp(pWdmDesc->m_Irp);
	ASSERT(!Irp.IsNull());
	ASSERT(pWdmDesc->m_pUrb);
	Irp.Reuse();
	*((short *)pWdmDesc->m_RfdBuffer) = 0;

	// Reuse the existing URB. Notice that the 6th parameter is
	// the pointer to the URB that was reclaimed. This call reinitializes
	// the URB for reuse.
	m_ReceivePipe.BuildBulkTransfer(
									pWdmDesc->m_RfdBuffer,
									BUF_SIZE,
									TRUE,
									NULL,
									TRUE,
									pWdmDesc->m_pUrb
									);

	// Pass down the URB to the bus driver
	m_ReceivePipe.SubmitUrb (
							pWdmDesc->m_Irp,
							pWdmDesc->m_pUrb,
							WdmCompletionRxRoutine(this),
							pWdmDesc
							);
}

///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DescriptorReclaim
//
//	Once a descriptor is reclaimed, then we create a new IRP and URB
//	and submit it to the bus driver.
//
// Parameters:
//  pWdmDesc			- The descriptor to reclaim
//	pPhysAddr			- Physycal Address Pointer
// IRQL:
//				<= DISPATCH_LEVEL
// Returns:
// 	NONE
// Comments:
//	The packet descriptor returns to the "free list" in the Rx area.
//	This routine is called for each descriptor.
//
VOID USBNICAdapter::DescriptorReclaim(
	PWDM_RFD pWdmDesc,
	PNDIS_PHYSICAL_ADDRESS pPhysAddr
	)
{
	//TRACE("USBNICAdapter::DescriptorReclaim\n");
	ReSubmitRfd(pWdmDesc);
	DumpWdmRfd(pWdmDesc);
}

///////////////////////////////////////////////////////////////////////
// USBNICAdapter::DumpWdmRfd
//
// Parameters:
//  pWdmDesc			- The descriptor to display
// IRQL:
//				<= DISPATCH_LEVEL
// Returns:
// 	NONE
// Comments:
//	Display some descriptor data in the softice window.
//
VOID USBNICAdapter::DumpWdmRfd(PWDM_RFD p)
{
	//TRACE("USBNICAdapter::DumpWdmRfd\n");
	//TRACE("   RFD_STRUC* p =%lx\n", p);
}

NTSTATUS KNdisWrapper<USBNICAdapter>::WdmCompletionRxRoutine(PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID context)
{
	UNREFERENCED_PARAMETER(pDevObj);
	USBNICAdapter::PWDM_RFD pWdmRfd = (USBNICAdapter::PWDM_RFD) context;
	USBNICAdapter* a = pWdmRfd->m_pAdapter;	// maps irp => owner
	ASSERT(a);										// assert context had been alloc correctly
	return a->CompletionRxRoutine(pIrp, reinterpret_cast<USBNICAdapter::IRP_CONTEXT*>(context));
}

// end of file

⌨️ 快捷键说明

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