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

📄 whusb20usb.c

📁 linux 下的驱动程序 欢迎下载
💻 C
📖 第 1 页 / 共 3 页
字号:
		TRACE1("***** bInterfaceNumber = %x *****", id->bInterfaceNumber);
		TRACE1("***** bAlternateSetting = %x *****", id->bAlternateSetting);
		TRACE1("***** bNumEndpoints = %x *****", id->bNumEndpoints);
		TRACE1("***** bInterfaceClass = %x *****", id->bInterfaceClass);
		TRACE1("***** bInterfaceSubClass = %x *****", id->bInterfaceSubClass);
		TRACE1("***** bInterfaceProtocol = %x *****", id->bInterfaceProtocol);
		TRACE1("***** iInterface = %x *****", id->iInterface);


	// Build list of interfaces we are interested in
	
	ilist[0].InterfaceDescriptor = id;
	ilist[0].Interface = NULL;	// Will point to urb->UrbUsbSelectConfiguration.Interface
	ilist[1].InterfaceDescriptor = NULL;

	// Create select configuration URB
	urb = USBD_CreateConfigurationRequestEx( Descriptors, ilist);
	      //////In addition to creating a URB, USBD_CreateConfigurationRequestEx()
	      //////also initializes the "Interface" members of your USBD_INTERFACE_LIST
	      //////entries to point to USBD_INTERFACE_INFORMATION structures.

	//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	dx->hWhceb01ConfigurationHandle = urb->UrbSelectConfiguration.ConfigurationHandle;//保存配置句柄
	InterfaceInfo = ilist[0].Interface;
	dx->hWhceb01InterfaceHandle = InterfaceInfo->InterfaceHandle;//保存接口句柄
	dx->Whceb01NumOfPipes = InterfaceInfo->NumberOfPipes;   

	TRACE1("  ----------InterfaceInfo = %x -------",ilist[0].Interface);
	TRACE1("  ----------NumberOfPipes = %x -------",InterfaceInfo->NumberOfPipes);
	TRACE1("  ----------ilist[1].InterfaceDescriptor = %x -------",ilist[1].InterfaceDescriptor);
	TRACE1("  ----------ilist[1].Interface = %x -------",ilist[1].Interface);

	//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

	// Call the USB driver
	for( i = 0 ; i < (dx->Whceb01NumOfPipes) ; i++ )
	{
		InterfaceInfo->Pipes[i].MaximumTransferSize = 1024*64;//设置最大传输长度为60K
	}

	TRACE0("Start to Select Configuration");

	status = CallUSBDI( dx, urb,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	// Check statuses
	if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))
	{
		TRACE0("==========Select Configuration failed!========");
		TRACE2("status %x URB status %x", status, urb->UrbHeader.Status);

		status = STATUS_UNSUCCESSFUL;
	}
	else
	{
		// Select config worked

		TRACE0("---------Select Configuration Success --------------");
		TRACE0("++++++++++++Get the Handle of pipe++++++++++++++++");


		for(i=0;i<(dx->Whceb01NumOfPipes);i++ )
		{
			PUSBD_PIPE_INFORMATION pi = &InterfaceInfo->Pipes[i];
			
			//通道0   入:0x86   出:0x02
			if( ( pi->PipeType == UsbdPipeTypeBulk ) && ( pi->EndpointAddress == 0x86 ) )
				dx->hWhceb01InterruptInHandle[0] = pi->PipeHandle;
			else if( ( pi->PipeType == UsbdPipeTypeBulk ) && ( pi->EndpointAddress ==0x02 ) )
                dx->hWhceb01InterruptOutHandle[0] = pi->PipeHandle;

			//通道1    入:0x88   出:0x04
			else if( ( pi->PipeType == UsbdPipeTypeBulk ) && ( pi->EndpointAddress == 0x88 ) )
				dx->hWhceb01InterruptInHandle[1] = pi->PipeHandle;
			else if( ( pi->PipeType == UsbdPipeTypeBulk ) && ( pi->EndpointAddress == 0x04 ) )
				dx->hWhceb01InterruptOutHandle[1] = pi->PipeHandle;


		    TRACE5("Pipes[%d] : MaximumPacketSize %d EndpointAddress 0x%2x Interval %dms PipeType %d ",
				i, pi->MaximumPacketSize, pi->EndpointAddress, pi->Interval, pi->PipeType );
			TRACE1("               MaximumTransferSize %d", pi->MaximumTransferSize);

		}
	}


    TRACE1 ("Configuration Handle = %x", dx->hWhceb01ConfigurationHandle);
	TRACE1 ("Interface Handle = %x", dx->hWhceb01InterfaceHandle);
	TRACE1 ("Pipe Num = %d", dx->Whceb01NumOfPipes);		
	TRACE1 ("InterruptIn Handle = %x", dx->hWhceb01InterruptInHandle[0]);
	TRACE1 ("InterruptOut Handle = %x", dx->hWhceb01InterruptOutHandle[0]);

	TRACE1 ("-----hWhceb01InterruptInHandle = %x", dx->hWhceb01InterruptInHandle[1]);
	TRACE1 ("-----hWhceb01InterruptOutHandle = %x", dx->hWhceb01InterruptOutHandle[1]);

	FreeIfAllocated(urb);
	FreeIfAllocated( Descriptors );
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbDeselectConfiguration:	Turn off device by selecting no configuration

NTSTATUS UsbDeselectConfiguration( IN PWHCEB01_DEVICE_EXTENSION dx)
{
	NTSTATUS status ;
	USHORT UrbSize = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
	PURB urb ;
	ULONG	i = 0;
	
	urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize);

	for( i = 0 ; i < MAX_CHANNEL ; i ++ )
	{
		dx->hWhceb01InterruptInHandle[i] = NULL ;
		dx->hWhceb01InterruptOutHandle[i] = NULL;
		dx->ChannelisUsed[i] = FALSE; 
	}

	// Allocate memory for URB

	if( urb==NULL)
	{
		TRACE0("No URB memory");
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	// Build select configuration URB with NULL Config descriptor
	UsbBuildSelectConfigurationRequest( urb, UrbSize, NULL);

	// Call the USB driver
	TRACE0("Deselecting configuration");
	status = CallUSBDI( dx, urb,IOCTL_INTERNAL_USB_SUBMIT_URB,0);
	// Check statuses
	if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status))
	{
		TRACE2("status %x URB status %x", status, urb->UrbHeader.Status);
		status = STATUS_UNSUCCESSFUL;
	}

	ExFreePool(urb);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbDoInterruptTransfer:	Wait for non-zero 8 byte input report, or timeout

NTSTATUS UsbDoInterruptTransfer( IN PWHCEB01_DEVICE_EXTENSION dx, IN PVOID UserBuffer, ULONG* UserBufferSize)
{
	ULONG InputBufferSize = *UserBufferSize;
	NTSTATUS status = STATUS_SUCCESS;
	ULONG OutputBufferSize = 8;
	USHORT UrbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
	PURB urb ;
	LARGE_INTEGER StartTickCount;
	ULONG UnitsOf100ns ;

	*UserBufferSize = 0;  
	// Check we're selected
	if( dx->hWhceb01PipeHandle==NULL)
		return STATUS_INVALID_HANDLE;

	// Check input parameters
	//liusf modified
	if( UserBuffer==NULL || InputBufferSize<8)
		return STATUS_INVALID_PARAMETER;

	// Keyboard input reports are always 8 bytes long

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

	// Remember when we started
	// Get start tick count and length of tick in 100ns units
	
	KeQueryTickCount( &StartTickCount);
	UnitsOf100ns = KeQueryTimeIncrement();
//	DebugPrint("Time increment %d", UnitsOf100ns);

	// Loop until non-zero report read, error, bad length, or timed out
//	DebugPrintMsg("Reading Interrupt data");
	while( TRUE )
	{
		LARGE_INTEGER TickCountNow;
		ULONG ticks ;
		__int64* pData;

		// Build Do Bulk or Interrupt transfer request
		UsbBuildInterruptOrBulkTransferRequest(
			urb, UrbSize,
			dx->hWhceb01PipeHandle,
			UserBuffer, NULL, OutputBufferSize,
			USBD_TRANSFER_DIRECTION_IN,
			NULL);

		// Call the USB driver
		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;
			break;
		}

		// Give up if count of bytes transferred was not 8
		//liusf modified
		
		if( urb->UrbBulkOrInterruptTransfer.TransferBufferLength!=OutputBufferSize)
			break;

		// If data non-zero then exit as we have a keypress
		pData = (__int64 *)UserBuffer;
		if( *pData!=0i64)
		{
//			DebugPrint("Got some data");
			break;
		}

		// Check for timeout
		
		KeQueryTickCount( &TickCountNow);
		ticks = (ULONG)(TickCountNow.QuadPart - StartTickCount.QuadPart);
		if( ticks*UnitsOf100ns/10000000 >= dx->UsbTimeout)
		{
			TRACE1("Timeout %d 100ns", ticks*UnitsOf100ns);
			status = STATUS_NO_MEDIA_IN_DEVICE;
			break;
		}
	}
	*UserBufferSize = urb->UrbBulkOrInterruptTransfer.TransferBufferLength;

//	DebugPrint("Transfer length %d", urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
	if( NT_SUCCESS(status))
	{
		PUCHAR bd = (PUCHAR)UserBuffer;
//		DebugPrint("Transfer data %2x %2x %2x %2x %2x %2x %2x %2x",
//			bd[0], bd[1], bd[2], bd[3], bd[4], bd[5], bd[6], bd[7]);
	}

	ExFreePool(urb);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbGetStatuses:	Get device, interface and endpoint statuses

NTSTATUS UsbGetStatuses( IN PWHCEB01_DEVICE_EXTENSION dx,
						 OUT PUCHAR Statuses,
						 IN ULONG Size)
{
	USHORT UrbSize = sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST);
	PURB urb;
	NTSTATUS status ;

	// Input buffer must have 2 bytes for each status
	if( Size!=6)
		return STATUS_INVALID_PARAMETER;

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

	/////////////////////////////////////////////////////////////////////////
	// Build URB to get device status
	UsbBuildGetStatusRequest(
		urb,
		URB_FUNCTION_GET_STATUS_FROM_DEVICE, 0,		// Op and Index
		Statuses, NULL,    // Transfer buffer
		NULL);	// Link URB

	// Call the USB driver
//	DebugPrintMsg("Getting device status");
	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;
		goto fail;
	}
	Size = urb->UrbControlGetStatusRequest.TransferBufferLength;
	if( Size!=2) goto fail;

	/////////////////////////////////////////////////////////////////////////
	// Build URB to get interface status
	UsbBuildGetStatusRequest(
		urb,
		URB_FUNCTION_GET_STATUS_FROM_INTERFACE, 0,		// Op and Index
		Statuses+2, NULL,    // Transfer buffer
		NULL);	// Link URB

	// Call the USB driver
//	DebugPrintMsg("Getting interface status");
	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;
		goto fail;
	}
	Size = urb->UrbControlGetStatusRequest.TransferBufferLength;
	if( Size!=2) goto fail;

	/////////////////////////////////////////////////////////////////////////
	// Build URB to get endpoint status
	UsbBuildGetStatusRequest(
		urb,
		URB_FUNCTION_GET_STATUS_FROM_ENDPOINT, 0,		// Op and Index
		Statuses+4, NULL,    // Transfer buffer
		NULL);	// Link URB

	// Call the USB driver
//	DebugPrintMsg("Getting endpoint status");
	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;
		goto fail;
	}
	Size = urb->UrbControlGetStatusRequest.TransferBufferLength;
	if( Size!=2) goto fail;

	/////////////////////////////////////////////////////////////////////////
fail:
	ExFreePool(urb);
	return status;
}


/////////////////////////////////////////////////////////////////////////////
//	UsbGetFrameInfo:	Get current frame length and two frame numbers

NTSTATUS UsbGetFrameInfo( IN PWHCEB01_DEVICE_EXTENSION dx,
						  OUT ULONG* FrameLength,
						  OUT ULONG* FrameNumber,
						  OUT ULONG* FrameAlterNumber)
{
	// Allocate memory for URB
	USHORT UrbSize = sizeof(struct _URB_GET_FRAME_LENGTH);
	PURB urb;
	NTSTATUS status;

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

	/////////////////////////////////////////////////////////////////////////
	// Get current frame number
	// Build URB by hand
	urb->UrbHeader.Length = UrbSize;
	urb->UrbHeader.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;

	// Call the USB driver
//	DebugPrintMsg("Getting current frame number");
	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;
		goto fail;
	}
	*FrameNumber = urb->UrbGetCurrentFrameNumber.FrameNumber;
//	DebugPrint("FrameNumber %d", FrameNumber);

	/////////////////////////////////////////////////////////////////////////
	// Get current frame length and frame number when length can be altered
	// Build URB by hand
	urb->UrbHeader.Length = UrbSize;
	urb->UrbHeader.Function = URB_FUNCTION_GET_FRAME_LENGTH;

	// Call the USB driver
//	DebugPrintMsg("Getting frame info");
	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;
	}

	// Store info
	*FrameLength = urb->UrbGetFrameLength.FrameLength;
	*FrameAlterNumber = urb->UrbGetFrameLength.FrameNumber;
	DebugPrint("FrameLength %d FrameAlterNumber %d", FrameLength, FrameAlterNumber);
fail:
	ExFreePool(urb);
	return status;
}

/////////////////////////////////////////////////////////////////////////////
//	UsbSendOutputReport:	Send one byte as a SET_REPORT control transfer

const UCHAR SET_REPORT = 0x09;

NTSTATUS UsbSendOutputReport( IN PWHCEB01_DEVICE_EXTENSION dx, IN UCHAR OutputData)
{
	// Allocate memory for URB
	USHORT UrbSize = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);

⌨️ 快捷键说明

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