📄 cusbintf.cpp
字号:
//
// Gets the status of a pipe, and stores it in a local buffer. This doesn't seem like
// it does anything useful since there is no way for the caller to check the buffer
//
NTSTATUS CUsbInterface::UsbGetStatusPipe(DWORD pipe_number, UCHAR interface_number)
{
USBD_PIPE_INFORMATION* p_pipe = getPipe(interface_number, pipe_number);
if(!p_pipe)
{
DbgLogError(("GetStatusPipe on invalid pipe, interface = %x, pipe = %x\n", interface_number, pipe_number));
return STATUS_UNSUCCESSFUL;
}
PURB p_urb = (PURB) new BYTE[sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST)];
DWORD p_buffer[128];
if(!p_urb)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(p_urb, sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST));
p_urb->UrbHeader.Length = (USHORT)sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST);
p_urb->UrbHeader.Function = URB_FUNCTION_GET_STATUS_FROM_ENDPOINT;
p_urb->UrbPipeRequest.PipeHandle = p_pipe->PipeHandle;
p_urb->UrbControlGetStatusRequest.TransferBufferLength = sizeof(USHORT);
p_urb->UrbControlGetStatusRequest.TransferBufferMDL = NULL;
p_urb->UrbControlGetStatusRequest.TransferBuffer = p_buffer;
p_urb->UrbControlGetStatusRequest.Index = (USHORT)pipe_number;
p_urb->UrbControlGetStatusRequest.UrbLink = NULL;
NTSTATUS status = UsbCall_GSPN(p_urb);
delete [] (BYTE *)p_urb;
return status;
}
/////////////////////////////////////////////////////////////////////////////////////////
DWORD CUsbInterface::getMaximumTransferSize(DWORD pipe_number, UCHAR interface_number)
{
USBD_PIPE_INFORMATION* p_pipe = getPipe(interface_number, pipe_number);
if(p_pipe)
{
return p_pipe->MaximumTransferSize;
}
else
{
return 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
DWORD CUsbInterface::getMaximumPaketSize(DWORD pipe_number, UCHAR interface_number)
{
USBD_PIPE_INFORMATION* p_pipe = getPipe(interface_number, pipe_number);
if(p_pipe)
{
return p_pipe->MaximumPacketSize;
}
else
{
return 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS CUsbInterface::ConfigDevice()
{
NTSTATUS status;
// clear error condition
_error_occured = FALSE;
//Get the USB device descriptor
status = UsbDeviceGetDescriptor();
if (!NT_SUCCESS(status))
{
DbgLogError(("UsbDeviceGetDescriptor() Failed Status(0x%x)\n", status));
return status;
}
//Get the USB configuration descriptor(s)
status = UsbConfigGetDescriptor(_device_descriptor.bNumConfigurations);
if (!NT_SUCCESS(status))
{
DbgLogError(("UsbConfigGetDescriptor() Failed Status(0x%x)\n", status));
return status;
}
_is_descriptor_available = TRUE;
//Select the USB configuration
status = UsbConfigSelect(_config_index);
if (!NT_SUCCESS(status))
{
DbgLogError(("UsbConfigSelect() Failed Status(0x%x)\n", status));
}
// set usb config event
setUsbConfigEvent();
return (status);
}
/////////////////////////////////////////////////////////////////////////////////////////
//CUsbInterface::freeInterface
//
// Free any interfaces we have allocated
//
void CUsbInterface::freeInterfaces()
{
//Delete all interfaces for the current configuration
if (_p_interfaces)
{
if (_p_configs && _p_configs[_config_index])
{
DWORD i;
for (i = 0; i < _p_configs[_config_index]->bNumInterfaces; i++)
{
if(_p_interfaces[i])
{
delete [] (BYTE *)_p_interfaces[i];
_p_interfaces[i] = NULL;
}
}
}
delete [] (BYTE *)_p_interfaces;
_p_interfaces = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
void CUsbInterface::UnConfigDevice()
{
UCHAR i;
DbgLogInfo(("CUsbInterface::UnConfigDevice()\n"));
//Delete any allocated interfaces
freeInterfaces();
//Delete all configurations
if (_p_configs)
{
for (i = 0; i < _device_descriptor.bNumConfigurations; i++)
{
if(_p_configs[i])
{
delete [] (BYTE *)_p_configs[i];
_p_configs[i] = NULL;
}
}
delete [] (BYTE *)_p_configs;
_p_configs = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//CUsbInterface::staticUsbCallCompletion
//
// This is a completion routine for synchronous I/O operations. The sender of the IRP
// waits on the event, which is sent in the context parameter. We signal the event
// when the completion routine runs.
//
extern "C"
{
NTSTATUS staticUsbCallCompletion(DEVICE_OBJECT* p_device,
IRP* p_irp,
void* p_context)
{
KEVENT* p_event = (KEVENT *)p_context;
if(p_event)
{
KeSetEvent(p_event, IO_NO_INCREMENT, 0);
}
return (STATUS_MORE_PROCESSING_REQUIRED);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//CUsbInterface::UsbDeviceGetDescriptor
//
// Get the USB device descriptor from the device.
//
NTSTATUS CUsbInterface::UsbDeviceGetDescriptor()
{
PURB p_urb = (PURB) new _URB_CONTROL_DESCRIPTOR_REQUEST;
if(!p_urb)
{
DbgLogError(("UsbDeviceGetDescriptor() Unable to allocate p_urb\n"));
return (STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(p_urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST));
p_urb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
p_urb->UrbHeader.Length = (WORD)sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
p_urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
p_urb->UrbControlDescriptorRequest.TransferBuffer = &_device_descriptor;
p_urb->UrbControlDescriptorRequest.DescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
NTSTATUS status = UsbCall_GSPN(p_urb);
#if DBG
if (NT_SUCCESS(status))
{
DumpUsbDevDescriptor(&_device_descriptor);
}
#endif
delete p_urb;
return (status);
}
/////////////////////////////////////////////////////////////////////////////////////////
//CUsbInterface::getUsbSerialNumber()
//
// Get the USB serial number from the device.
//
// serialNumber is pointer to string which stores the serial number of usb device
//
NTSTATUS CUsbInterface::getUsbSerialNumber(PWCHAR pSerialNumber, DWORD size, DWORD *p_actual_size)
{
NTSTATUS status = STATUS_SUCCESS;
if (!_is_initialized )
{
DbgLogError(("CUsbInterface::getUsbSerialNumber() Device not Initialized...\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
if (!pSerialNumber || (size <= 0) || !p_actual_size )
{
DbgLogError(("CUsbInterface::getUsbSerialNumber() Null pointer or zero size...\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
if(!_device_descriptor.iSerialNumber)
{
DbgLogError(("CUsbInterface::getUsbSerialNumber() No serial number Index...\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
PURB p_urb = (PURB) new _URB_CONTROL_DESCRIPTOR_REQUEST;
if(!p_urb)
{
DbgLogError(("CUsbInterface:getUsbSerialNumber() Unable to allocate p_urb\n"));
return (STATUS_INSUFFICIENT_RESOURCES);
}
// set the actual size to zero
*p_actual_size = 0;
RtlZeroMemory(p_urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST));
USB_STRING_DESCRIPTOR USD, *pFullUSD = NULL;
USHORT langID = 0x0409; // usa
UsbBuildGetDescriptorRequest(
p_urb, // points to the URB to be filled in
sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST),
USB_STRING_DESCRIPTOR_TYPE,
_device_descriptor.iSerialNumber, // index of string descriptor
langID, // language ID of string.
&USD, // points to a USB_STRING_DESCRIPTOR.
NULL,
sizeof(USB_STRING_DESCRIPTOR),
NULL
);
//Send the URB to the USB bus driver.
status = UsbCall_GSPN(p_urb);
if (NT_SUCCESS(status))
{
// now we got the correct length of string descriptor
pFullUSD = (USB_STRING_DESCRIPTOR *) new BYTE[USD.bLength];
if(!pFullUSD)
{
DbgLogError(("CUsbInterface:getUsbSerialNumber() Unable to allocate USB string descriptor\n"));
if(p_urb)
{
delete p_urb;
}
return (STATUS_INSUFFICIENT_RESOURCES);
}
UsbBuildGetDescriptorRequest(
p_urb, // points to the URB to be filled in
sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST),
USB_STRING_DESCRIPTOR_TYPE,
_device_descriptor.iSerialNumber, // index of string descriptor
langID, // language ID of string
pFullUSD,
NULL,
USD.bLength,
NULL
);
//Send the URB to the USB bus driver.
status = UsbCall_GSPN(p_urb);
if (NT_SUCCESS(status))
{
DbgLogInfo(("CUsbInterface::getUsbSerialNumber - Got serial number, and size %d\n",USD.bLength ));
// copy the original string back to caller
if(size >= USD.bLength)
{
RtlCopyMemory((PBYTE)pSerialNumber, (PBYTE)pFullUSD->bString, USD.bLength);
*p_actual_size = USD.bLength;
}
else
{
RtlCopyMemory((PBYTE)pSerialNumber, (PBYTE)pFullUSD->bString, size);
*p_actual_size = size;
}
}
if(pFullUSD)
{
delete [] pFullUSD;
pFullUSD = NULL;
}
}
else
{
DbgLogError(("CUsbInterface:getUsbSerialNumber() Unable to get string descriptor\n"));
}
delete p_urb;
return (status);
}
/////////////////////////////////////////////////////////////////////////////////////////
//CUsbInterface::UsbConfigGetDescriptor()
//
// Get the USB configuration descriptor(s) from the device.
//
// config_count is the number of configuration descriptors to query. This will save
// the configuration descriptors in the _p_configs array if it is successful
//
NTSTATUS CUsbInterface::UsbConfigGetDescriptor(DWORD config_count)
{
PURB p_urb = (PURB) new _URB_CONTROL_DESCRIPTOR_REQUEST;
if(!p_urb)
{
DbgLogError(("UsbConfigGetDescriptor() Unable to allocate p_urb\n"));
return (STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(p_urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST));
//Allocate memory for the configuration descriptors based on the number of available configurations
_p_configs = new PUSB_CONFIGURATION_DESCRIPTOR[config_count];
if(!_p_configs)
{
DbgLogError(("UsbConfigGetDescriptor() Unable to allocate _p_configs\n"));
if(p_urb)
{
delete p_urb;
}
return (STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(_p_configs, sizeof(PUSB_CONFIGURATION_DESCRIPTOR)* config_count);
NTSTATUS status;
//Get each configuration.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -