📄 whusb20usb.c
字号:
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 + -