Skip to content

Commit

Permalink
Add a bunch of sanity checks
Browse files Browse the repository at this point in the history
  • Loading branch information
Megamouse committed Sep 26, 2024
1 parent ba28d38 commit 78d45c5
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 13 deletions.
88 changes: 83 additions & 5 deletions libusb/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length);
static hid_device *new_hid_device(void)
{
hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
if (!dev)
return NULL;

dev->blocking = 1;

hidapi_thread_state_init(&dev->thread_state);
Expand All @@ -148,6 +151,9 @@ static hid_device *new_hid_device(void)

static void free_hid_device(hid_device *dev)
{
if (!dev)
return;

/* Clean up the thread objects */
hidapi_thread_state_destroy(&dev->thread_state);

Expand All @@ -169,6 +175,9 @@ static void register_error(hid_device *dev, const char *op)
Only call with a num_bytes of 0, 1, 2, or 4. */
static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur)
{
if (!rpt)
return 0;

/* Return if there aren't enough bytes. */
if (cur + num_bytes >= len)
return 0;
Expand Down Expand Up @@ -198,6 +207,9 @@ static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur
static int get_usage(uint8_t *report_descriptor, size_t size,
unsigned short *usage_page, unsigned short *usage)
{
if (!report_descriptor || !usage_page || !usage)
return -1;

unsigned int i = 0;
int size_code;
int data_len, key_size;
Expand Down Expand Up @@ -546,8 +558,10 @@ static void fill_device_info_usage(struct hid_device_info *cur_dev, libusb_devic
get_usage(hid_report_descriptor, res, &page, &usage);
}

cur_dev->usage_page = page;
cur_dev->usage = usage;
if (cur_dev) {
cur_dev->usage_page = page;
cur_dev->usage = usage;
}
}

#ifdef INVASIVE_GET_USAGE
Expand Down Expand Up @@ -632,6 +646,9 @@ static struct hid_device_info * create_device_info_for_device(libusb_device *dev

static uint16_t get_report_descriptor_size_from_interface_descriptors(const struct libusb_interface_descriptor *intf_desc)
{
if (!intf_desc)
return 0;

int i = 0;
int found_hid_report_descriptor = 0;
uint16_t result = HID_API_MAX_REPORT_DESCRIPTOR_SIZE;
Expand Down Expand Up @@ -717,7 +734,8 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de
0x9886, /* ASTRO Gaming */
};

if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
if (intf_desc &&
intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
intf_desc->bInterfaceSubClass == xb360_iface_subclass &&
(intf_desc->bInterfaceProtocol == xb360_iface_protocol ||
intf_desc->bInterfaceProtocol == xb360w_iface_protocol)) {
Expand Down Expand Up @@ -750,7 +768,8 @@ static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_de
0x3537, /* GameSir */
};

if (intf_desc->bInterfaceNumber == 0 &&
if (intf_desc &&
intf_desc->bInterfaceNumber == 0 &&
intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC &&
intf_desc->bInterfaceSubClass == xb1_iface_subclass &&
intf_desc->bInterfaceProtocol == xb1_iface_protocol) {
Expand All @@ -769,6 +788,8 @@ static int should_enumerate_interface(unsigned short vendor_id, const struct lib
#if 0
printf("Checking interface 0x%x %d/%d/%d/%d\n", vendor_id, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol);
#endif
if (!intf_desc)
return 0;

if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID)
return 1;
Expand Down Expand Up @@ -950,6 +971,9 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const

static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
{
if (!transfer)
return;

hid_device *dev = transfer->user_data;
int res;

Expand Down Expand Up @@ -1018,6 +1042,9 @@ static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)

static void *read_thread(void *param)
{
if (!param)
return NULL;

int res;
hid_device *dev = param;
uint8_t *buf;
Expand Down Expand Up @@ -1118,6 +1145,9 @@ static void init_xboxone(libusb_device_handle *device_handle, unsigned short idV

(void)idProduct;

if (!conf_desc)
return;

for (j = 0; j < conf_desc->bNumInterfaces; j++) {
const struct libusb_interface *intf = &conf_desc->interface[j];
for (k = 0; k < intf->num_altsetting; k++) {
Expand Down Expand Up @@ -1158,6 +1188,9 @@ static void init_xboxone(libusb_device_handle *device_handle, unsigned short idV

static int hidapi_initialize_device(hid_device *dev, const struct libusb_interface_descriptor *intf_desc, const struct libusb_config_descriptor *conf_desc)
{
if (!conf_desc)
return 0;

int i =0;
int res = 0;
struct libusb_device_descriptor desc;
Expand Down Expand Up @@ -1405,6 +1438,9 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys

int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
{
if (!dev)
return -1;

int res;
int report_number;
int skipped_report_id = 0;
Expand Down Expand Up @@ -1447,11 +1483,14 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
This should be called with dev->mutex locked. */
static int return_data(hid_device *dev, unsigned char *data, size_t length)
{
if (!dev)
return 0;

/* Copy the data out of the linked list item (rpt) into the
return buffer (data), and delete the liked list item. */
struct input_report *rpt = dev->input_reports;
size_t len = (length < rpt->len)? length: rpt->len;
if (len > 0)
if (data && len > 0)
memcpy(data, rpt->data, len);
dev->input_reports = rpt->next;
free(rpt->data);
Expand All @@ -1461,13 +1500,19 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length)

static void cleanup_mutex(void *param)
{
if (!param)
return;

hid_device *dev = param;
hidapi_thread_mutex_unlock(&dev->thread_state);
}


int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
{
if (!dev)
return -1;

#if 0
int transferred;
int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000);
Expand Down Expand Up @@ -1556,6 +1601,9 @@ int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)

int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
{
if (!dev)
return -1;

dev->blocking = !nonblock;

return 0;
Expand All @@ -1564,6 +1612,9 @@ int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)

int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
{
if (!dev || !data)
return -1;

int res = -1;
int skipped_report_id = 0;
int report_number = data[0];
Expand Down Expand Up @@ -1594,6 +1645,9 @@ int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char

int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
{
if (!dev || !data)
return -1;

int res = -1;
int skipped_report_id = 0;
int report_number = data[0];
Expand Down Expand Up @@ -1624,6 +1678,9 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,

int HID_API_EXPORT hid_send_output_report(hid_device *dev, const unsigned char *data, size_t length)
{
if (!dev || !data)
return -1;

int res = -1;
int skipped_report_id = 0;
int report_number = data[0];
Expand Down Expand Up @@ -1654,6 +1711,9 @@ int HID_API_EXPORT hid_send_output_report(hid_device *dev, const unsigned char *

int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length)
{
if (!dev || !data)
return -1;

int res = -1;
int skipped_report_id = 0;
int report_number = data[0];
Expand Down Expand Up @@ -1727,20 +1787,32 @@ void HID_API_EXPORT hid_close(hid_device *dev)

int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
if (!dev)
return -1;

return hid_get_indexed_string(dev, dev->manufacturer_index, string, maxlen);
}

int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
if (!dev)
return -1;

return hid_get_indexed_string(dev, dev->product_index, string, maxlen);
}

int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
if (!dev)
return -1;

return hid_get_indexed_string(dev, dev->serial_index, string, maxlen);
}

HID_API_EXPORT struct hid_device_info *HID_API_CALL hid_get_device_info(hid_device *dev) {
if (!dev)
return NULL;

if (!dev->device_info) {
struct libusb_device_descriptor desc;
libusb_device *usb_device = libusb_get_device(dev->device_handle);
Expand All @@ -1759,6 +1831,9 @@ HID_API_EXPORT struct hid_device_info *HID_API_CALL hid_get_device_info(hid_devi

int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
{
if (!dev || !string)
return -1;

wchar_t *str;

str = get_usb_string(dev->device_handle, string_index);
Expand All @@ -1775,6 +1850,9 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index

int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
{
if (!dev)
return -1;

return hid_get_report_descriptor_libusb(dev->device_handle, dev->interface, dev->report_descriptor_size, buf, buf_size);
}

Expand Down
Loading

0 comments on commit 78d45c5

Please sign in to comment.