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

📄 usb2com.utils.cpp

📁 这是一个关于USB转接串口的驱动程序开发
💻 CPP
字号:
//********************************************************************
//	created:	12:7:2008   1:51
//	file:		usb2com.utils.cpp
//	author:		tiamo
//	purpose:	utils
//********************************************************************

#include "stdafx.h"

//
// config usb device
//
NTSTATUS Usb2ComConfigUsbDevice(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	PURB Urb											= 0;
	PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc			= 0;
	ULONG DescLength									= 0x109;
	NTSTATUS Status										= STATUS_SUCCESS;

	__try
	{
		//
		// allocate urb buffer
		//
		Urb												= static_cast<PURB>(ExAllocatePoolWithTag(NonPagedPool,sizeof(_URB_CONTROL_GET_CONFIGURATION_REQUEST),'URB '));
		if(!Urb)
			try_leave(Status = STATUS_INSUFFICIENT_RESOURCES);

		//
		// allocate config desc buffer
		//
		ConfigDesc										= static_cast<PUSB_CONFIGURATION_DESCRIPTOR>(ExAllocatePoolWithTag(NonPagedPool,DescLength,'cDes'));
		if(!ConfigDesc)
			try_leave(Status = STATUS_INSUFFICIENT_RESOURCES);

		UsbBuildGetDescriptorRequest(Urb,sizeof(_URB_CONTROL_GET_CONFIGURATION_REQUEST),USB_CONFIGURATION_DESCRIPTOR_TYPE,0,0,ConfigDesc,0,DescLength,0);

		//
		// send it
		//
		Status											= Usb2ComSendUrbSync(DevExt,Urb);
		if(!NT_SUCCESS(Status))
		{
			//
			// get config descriptor failed,then reset port and try again
			//
			Usb2ComResetUsbPort(DevExt);

			//
			// clear endpoint feature
			//
			Usb2ComClearEndpointFeature(DevExt,0,0);

			//
			// resent the usb
			//
			UsbBuildGetDescriptorRequest(Urb,sizeof(_URB_CONTROL_GET_CONFIGURATION_REQUEST),USB_CONFIGURATION_DESCRIPTOR_TYPE,0,0,ConfigDesc,0,DescLength,0);

			Status										= Usb2ComSendUrbSync(DevExt,Urb);
			if(!NT_SUCCESS(Status))
				try_leave(NOTHING);
		}

		//
		// select configuration
		//
		Status											= Usb2ComSelectConfiguration(DevExt,ConfigDesc);
	}
	__finally
	{
		if(Urb)
			ExFreePool(Urb);

		if(ConfigDesc)
			ExFreePool(ConfigDesc);
	}

	return Status;
}

//
// disable usb device
//
NTSTATUS Usb2ComDisableUsbDevice(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	PURB Urb											= static_cast<PURB>(ExAllocatePoolWithTag(NonPagedPool,sizeof(_URB_SELECT_CONFIGURATION),'URB '));
	if(!Urb)
		return STATUS_INSUFFICIENT_RESOURCES;

	UsbBuildSelectConfigurationRequest(Urb,sizeof(_URB_SELECT_CONFIGURATION),0);

	NTSTATUS Status										= Usb2ComSendUrbSync(DevExt,Urb);

	ExFreePool(Urb);

	return Status;
}

//
// select configuration
//
NTSTATUS Usb2ComSelectConfiguration(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc)
{
	//
	// find the first interface descriptor from the configuration descriptor
	//
	PUSB_INTERFACE_DESCRIPTOR InterfaceDesc				= USBD_ParseConfigurationDescriptorEx(ConfigDesc,ConfigDesc,-1,-1,-1,-1,-1);
	if(!InterfaceDesc)
		return STATUS_INTERNAL_ERROR;

	USBD_INTERFACE_LIST_ENTRY InterfaceList[2];
	InterfaceList[0].Interface							= 0;
	InterfaceList[0].InterfaceDescriptor				= InterfaceDesc;
	InterfaceList[1].Interface							= 0;
	InterfaceList[1].InterfaceDescriptor				= 0;

	//
	// create a urb to select a configuration
	//
	PURB Urb											= USBD_CreateConfigurationRequestEx(ConfigDesc,InterfaceList);
	if(!Urb)
		return STATUS_INSUFFICIENT_RESOURCES;

	PUSBD_INTERFACE_INFORMATION UsbInterfaceInfo		= &Urb->UrbSelectConfiguration.Interface;
	ASSERT(UsbInterfaceInfo->NumberOfPipes == 3);

	for(ULONG i = 0; i < UsbInterfaceInfo->NumberOfPipes; i ++)
		UsbInterfaceInfo->Pipes[i].MaximumTransferSize	= 0x40;

	NTSTATUS Status										= Usb2ComSendUrbSync(DevExt,Urb);
	if(NT_SUCCESS(Status))
	{
		//
		// make a copy and save it into device extension
		//
		DevExt->UsbInterfaceInfo						= static_cast<PUSBD_INTERFACE_INFORMATION>(ExAllocatePoolWithTag(NonPagedPool,UsbInterfaceInfo->Length,'UsbI'));
		if(DevExt->UsbInterfaceInfo)
			RtlCopyMemory(DevExt->UsbInterfaceInfo,UsbInterfaceInfo,UsbInterfaceInfo->Length);
		else
			Status										= STATUS_INSUFFICIENT_RESOURCES;
	}

	ExFreePool(Urb);
	return Status;
}

//
// send usb sync
//
NTSTATUS Usb2ComSendUrbSync(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in PURB Urb)
{
	KEVENT Event;
	KeInitializeEvent(&Event,NotificationEvent,FALSE);

	IO_STATUS_BLOCK IoStatusBlock;
	PIRP Irp											= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,DevExt->LowerDeviceObject,
																						0,0,0,0,TRUE,&Event,&IoStatusBlock);

	PIO_STACK_LOCATION NextIrpSp						= IoGetNextIrpStackLocation(Irp);
	NextIrpSp->Parameters.Others.Argument1				= Urb;

	NTSTATUS Status										= IoCallDriver(DevExt->LowerDeviceObject,Irp);
	if(Status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,0);
		Status											= IoStatusBlock.Status;
	}

	return Status;
}

//
// reset port
//
NTSTATUS Usb2ComResetUsbPort(__in PUSB2COM_DEVICE_EXTENSION DevExt)
{
	KEVENT Event;
	KeInitializeEvent(&Event,NotificationEvent,FALSE);

	IO_STATUS_BLOCK IoStatusBlock;
	PIRP Irp											= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_RESET_PORT,DevExt->LowerDeviceObject,
																						0,0,0,0,TRUE,&Event,&IoStatusBlock);

	NTSTATUS Status										= IoCallDriver(DevExt->LowerDeviceObject,Irp);
	if(Status == STATUS_PENDING)
	{
		KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,0);
		Status											= IoStatusBlock.Status;
	}

	return Status;
}

//
// clear feature
//
NTSTATUS Usb2ComClearEndpointFeature(__in PUSB2COM_DEVICE_EXTENSION DevExt,__in USHORT Selector,__in USHORT Index)
{
	PURB Urb											= static_cast<PURB>(ExAllocatePoolWithTag(NonPagedPool,sizeof(_URB_CONTROL_FEATURE_REQUEST),'URB '));
	if(!Urb)
		return STATUS_INSUFFICIENT_RESOURCES;

	UsbBuildFeatureRequest(Urb,URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT,Selector,Index,0);

	NTSTATUS Status										= Usb2ComSendUrbSync(DevExt,Urb);

	ExFreePool(Urb);

	return Status;
}

⌨️ 快捷键说明

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