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

📄 whusb20usb.c

📁 linux 下的驱动程序 欢迎下载
💻 C
📖 第 1 页 / 共 3 页
字号:
	PURB urb ;
	NTSTATUS status;
	
	urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize);
	if( urb==NULL)
	{
//		DebugPrintMsg("No URB memory");
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Build URB to send Class interface control request on Default pipe
	UsbBuildVendorRequest(urb,
		URB_FUNCTION_CLASS_INTERFACE, UrbSize,
		USBD_TRANSFER_DIRECTION_OUT,	// Direction out
		0,			// Reserved bits
		SET_REPORT,	// Request
		0x0200,		// Output report type, Report id zero
		0,			// interface index
		&OutputData, NULL, 1,	// Output data
		NULL);

	// Call the USB driver
//	DebugPrintMsg("Sending set report");
	status = CallUSBDI( dx, urb,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	// Check statuses
	if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))
	{
//		DebugPrint("status %x URB status %x", status, urb->UrbHeader.Status);
		status = STATUS_UNSUCCESSFUL;
	}
	ExFreePool(urb);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbGetIdleRate:	Get the current HID idle rate

const UCHAR GET_IDLE = 0x02;

NTSTATUS UsbGetIdleRate( IN PWHCEB01_DEVICE_EXTENSION dx)
{
	// Allocate memory for URB
	USHORT UrbSize = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
	PURB urb ;
	NTSTATUS status;
	UCHAR IdleRate = 0;

	urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize);
	if( urb==NULL)
	{
//		DebugPrintMsg("No URB memory");
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Build URB to send Class interface control request on Default pipe

	UsbBuildVendorRequest(urb,
		URB_FUNCTION_CLASS_INTERFACE, UrbSize,
		USBD_TRANSFER_DIRECTION_IN,		// Direction in
		0,			// Reserved bits
		GET_IDLE,	// Request
		0x0000,		// No report type, Report id zero
		0,			// interface index
		&IdleRate, NULL, 1,	// Output data
		NULL);

	// Call the USB driver
	TRACE0("Sending Get Idle request");
	status = CallUSBDI( dx, urb,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	// Check statuses
	if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))
	{
//		DebugPrint("status %x URB status %x", status, urb->UrbHeader.Status);
		status = STATUS_UNSUCCESSFUL;
	}
//	DebugPrint( "Idle rate is %d units of 4ms", IdleRate);
	ExFreePool(urb);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	CallUSBDI:	Send off URB etc and wait for IOCTL to complete
//				Build Internal IOCTL IRP to send to USBDI
//				Call USBDI and wait for IRP to complete
//				Must be called at PASSIVE_LEVEL

NTSTATUS CallUSBDI( IN PWHCEB01_DEVICE_EXTENSION dx, IN PVOID UrbEtc,
					IN ULONG IoControlCode/*=IOCTL_INTERNAL_USB_SUBMIT_URB*/,
				    IN ULONG Arg2/*=0*/)
{

	NTSTATUS status;
	IO_STATUS_BLOCK IoStatus;
	KEVENT event;
	PIRP Irp;
	PIO_STACK_LOCATION NextIrpStack;
	LARGE_INTEGER timeOut;
	timeOut.QuadPart=WHCEB01_TIMEOUT;

#ifdef DEBUG_INTERFACE
	TRACE0("*****进入CallUSBDI()*****");
#endif//DEBUG_INTERFACE
	// Initialise IRP completion event
	KeInitializeEvent(&event, NotificationEvent, FALSE);

	// Build Internal IOCTL IRP
	Irp = IoBuildDeviceIoControlRequest(
					IoControlCode, dx->NextStackDevice,
					NULL, 0,	// Input buffer
					NULL, 0,	// Output buffer
					TRUE, &event, &IoStatus);

	// Get IRP stack location for next driver down (already set up)
	NextIrpStack = IoGetNextIrpStackLocation(Irp);
	// Store pointer to the URB etc
	NextIrpStack->Parameters.Others.Argument1 = UrbEtc;
	//NextIrpStack->Parameters.Others.Argument2 = (PVOID)Arg2;

	// Call the driver and wait for completion if necessary
	status = IoCallDriver( dx->NextStackDevice, Irp);
	if (status == STATUS_PENDING)
	{

		TRACE0("***** CallUSBDI: waiting for URB completion*****");

		status = KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL);//&timeOut );
		if( status != STATUS_SUCCESS )
		{
			TRACE1( "KeWaitForSingleObject faild :0x%x" , status );
		}
		status = IoStatus.Status;
	}

	// return IRP completion status

	TRACE1("*****CallUSBDI returned %x*****",status);

	return status;
}

/////////////////////////////////////////////////////////////////////////////
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/////////////////////////////////////////////////////////////////////////////
//函数名称:Whceb01ResetPipe
//函数功能:复位管道
//入口参数:设备扩展
//          要复位的管道句柄
//返回值  :
/////////////////////////////////////////////////////////////////////////////
NTSTATUS Whceb01ResetPipe( IN PWHCEB01_DEVICE_EXTENSION dx, IN USBD_PIPE_HANDLE hPipe )
{
	URB urb;
	NTSTATUS status;

	urb.UrbHeader.Length = (USHORT) sizeof(struct _URB_PIPE_REQUEST);
	urb.UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
	urb.UrbPipeRequest.PipeHandle = hPipe;

	status = CallUSBDI( dx, &urb ,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//函数名称:Whceb01ResetDevice
//函数功能:复位设备
//入口参数:设备扩展
//返回值  :
/////////////////////////////////////////////////////////////////////////////
NTSTATUS Whceb01ResetDevice( IN PWHCEB01_DEVICE_EXTENSION dx )
{
	NTSTATUS status;
	IO_STATUS_BLOCK		IoStatus;
	KEVENT				event;
	PIRP Irp;

	KeInitializeEvent( &event, NotificationEvent, FALSE );
	
	Irp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_RESET_PORT,
		                                  dx->NextStackDevice,
										  NULL, 0,
										  NULL, 0,
										  TRUE, &event, &IoStatus);
	if(!Irp)
		return STATUS_UNSUCCESSFUL;

	status = IoCallDriver( dx->NextStackDevice, Irp );
	if(status == STATUS_PENDING)
	{
		KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL );
		status = IoStatus.Status;
	}

	return status;
}

/////////////////////////////////////////////////////////////////////////////
//函数名称:Whceb01TransferHostToDevice
//函数功能:host-to-device控制传输函数
//入口参数:设备扩展
//          host-to-device缓冲区指针                    
//          host-to-device缓冲区长度
//返回值  :
/////////////////////////////////////////////////////////////////////////////
NTSTATUS Whceb01TransferHostToDevice( IN  PWHCEB01_DEVICE_EXTENSION dx, 
									   IN  PVOID BufferHostToDevice,
									   IN  ULONG BufferHostToDeviceLength)
{
	NTSTATUS status;
	USHORT	UrbSize = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
	PURB	urb ;

	#ifdef DEBUG_INTERFACE
	TRACE0("*****进入Whceb01IcTransferHostToDevice( )*****");
#endif//DEBUG_INTERFACE
	urb = (PURB)ExAllocatePool( NonPagedPool, UrbSize);
	if( urb == NULL){
		return STATUS_INSUFFICIENT_RESOURCES;
	}


	UsbBuildVendorRequest( urb, URB_FUNCTION_VENDOR_ENDPOINT, UrbSize,
						   USBD_SHORT_TRANSFER_OK, //Transfer flags
                           0x0,                //Reserved bits
						   0x0,                //Request
						   0x0,                //Value
						   0x0,                //Index
						   BufferHostToDevice, //TransferBuffer
						   NULL,               //TransferBufferMdl
						   BufferHostToDeviceLength, //TransferBufferLength
						   NULL);              //Link

	status = CallUSBDI( dx, urb ,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	if( !NT_SUCCESS(status)||!USBD_SUCCESS(urb->UrbHeader.Status))
	{
#ifdef DEBUG_INTERFACE
		TRACE2( "-----status = %x, URB status = %x-----", status, urb->UrbHeader.Status);
#endif//DEBUG_INTERFACE
		status = STATUS_UNSUCCESSFUL;
	}

	ExFreePool(urb);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//函数名称:Whceb01TransferDeviceToHost
//函数功能:device-to-host控制传输函数
//入口参数:设备扩展
//          device-to-host缓冲区指针                    
//          device-to-host缓冲区长度
//返回值  :
/////////////////////////////////////////////////////////////////////////////
NTSTATUS Whceb01TransferDeviceToHost( IN  PWHCEB01_DEVICE_EXTENSION dx,
									   OUT PVOID BufferDeviceToHost,
									   IN  ULONG BufferDeviceToHostLength)
{


	USHORT	UrbSize = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
	PURB	urb ;
	NTSTATUS status;

#ifdef DEBUG_INTERFACE
	DebugPrintMsg("*****进入Whceb01IcTransferDeviceToHost( )*****");
#endif//DEBUG_INTERFACE

	urb = (PURB)ExAllocatePool( NonPagedPool, UrbSize);
	if( urb == NULL)
	{
#ifdef DEBUG_INTERFACE
		TRACE0("-----Fail to allocate memory------");
#endif//DEBUG_INTERFACE
		return STATUS_INSUFFICIENT_RESOURCES;
	}


	UsbBuildVendorRequest( urb, URB_FUNCTION_VENDOR_ENDPOINT, UrbSize,
						   USBD_TRANSFER_DIRECTION_IN|USBD_SHORT_TRANSFER_OK, //Transfer flags
                           0x0,                //Reserved bits
						   0x0,                //Request
						   0x0,                //Value
						   0x0,                //Index
						   BufferDeviceToHost, //TransferBuffer
						   NULL,               //TransferBufferMdl
						   BufferDeviceToHostLength, //TransferBufferLength
						   NULL);              //Link

	status = CallUSBDI( dx, urb ,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	if( !NT_SUCCESS(status)||!USBD_SUCCESS(urb->UrbHeader.Status))
	{
#ifdef DEBUG_INTERFACE
		TRACE2( "-----status = %x, URB status = %x-----", status, urb->UrbHeader.Status);
#endif//DEBUG_INTERFACE
		status = STATUS_UNSUCCESSFUL;
	}

	ExFreePool(urb);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//函数名称:Whceb01InterruptTransferHtD
//函数功能:host-to-device中断传输函数
//入口参数:设备扩展
//          host-to-device缓冲区指针                    
//          host-to-device缓冲区长度
//返回值  :
/////////////////////////////////////////////////////////////////////////////
NTSTATUS Whceb01InterruptTransferHtD( IN  PWHCEB01_DEVICE_EXTENSION dx, PWHCEB01_CHANNEL pChannel ,
									   IN  PVOID BufferHostToDevice,
									   IN  ULONG BufferHostToDeviceLength)
{
	USHORT UrbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
	PURB urb ;
	NTSTATUS status;


	TRACE0("*****Enter Whceb01InterruptTransferHtD()***USBD_TRANSFER_DIRECTION_OUT**");

	if( pChannel->OutputHandle == NULL)
		return STATUS_INVALID_HANDLE;

	urb = (PURB)ExAllocatePool( NonPagedPool, UrbSize );
	if( urb == NULL)
	{

		TRACE0("-----Fail to allocate memory------");

		return STATUS_INSUFFICIENT_RESOURCES;
	}

	UsbBuildInterruptOrBulkTransferRequest( urb, UrbSize, 
		                          pChannel->OutputHandle  ,
								  BufferHostToDevice, NULL,
								  BufferHostToDeviceLength,
								  //USBD_SHORT_TRANSFER_OK,
								  USBD_TRANSFER_DIRECTION_OUT,
								  NULL);

	status = CallUSBDI( dx, urb ,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
    if( !NT_SUCCESS(status)||!USBD_SUCCESS(urb->UrbHeader.Status))
	{

		TRACE2( "-Error----status = %x, URB status = %x-----", status, urb->UrbHeader.Status);

		status = STATUS_UNSUCCESSFUL;
	}

	ExFreePool(urb);

	TRACE1("*****Whceb01InterruptTransferHtD()结束,status=%d*****", status);

	return status;
}

/////////////////////////////////////////////////////////////////////////////
//函数名称:Whceb01InterruptTransferDtH
//函数功能:device-to-host中断传输函数
//入口参数:设备扩展
//          device-to-host缓冲区指针                    
//          device-to-host缓冲区长度
//返回值  :
/////////////////////////////////////////////////////////////////////////////
NTSTATUS Whceb01InterruptTransferDtH( IN  PWHCEB01_DEVICE_EXTENSION dx, PWHCEB01_CHANNEL pChannel ,
									   OUT PVOID BufferDeviceToHost,
									   IN  ULONG BufferDeviceToHostLength)
{
	USHORT UrbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
	PURB urb;
	NTSTATUS status;


	TRACE0("*****进入Whceb01InterruptTransferDtH()*****");


	if( pChannel->InputHandle == NULL)
		return STATUS_INVALID_HANDLE;
	if(BufferDeviceToHost == NULL)
		return STATUS_INVALID_PARAMETER;


	urb = (PURB)ExAllocatePool( NonPagedPool, UrbSize );
	if( urb == NULL)
	{

		TRACE0("-----Fail to allocate memory------");

		return STATUS_INSUFFICIENT_RESOURCES;
	}

	UsbBuildInterruptOrBulkTransferRequest( urb, UrbSize, 
		                          pChannel->InputHandle,
								  BufferDeviceToHost, NULL,
								  BufferDeviceToHostLength,
								  USBD_TRANSFER_DIRECTION_IN|USBD_SHORT_TRANSFER_OK, //liusf modified
								  //USBD_TRANSFER_DIRECTION_IN,  
								  NULL);
	status = CallUSBDI( dx, urb ,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
    if( !NT_SUCCESS(status)||!USBD_SUCCESS(urb->UrbHeader.Status))
	{

		TRACE2( "-----status = %x, URB status = %x-----", status, urb->UrbHeader.Status);

		status = STATUS_UNSUCCESSFUL;
	}

	ExFreePool(urb);


	TRACE1("*****Whceb01InterruptTransferDtH()结束,status=%x*****", status);

	return status;
}

⌨️ 快捷键说明

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