libusbp_error * libusbp_device_copy(const libusbp_device * source, libusbp_device ** dest) { if (dest == NULL) { return error_create("Device output pointer is null."); } *dest = NULL; if (source == NULL) { return NULL; } libusbp_error * error = NULL; // Allocate memory for the device itself. libusbp_device * new_device = NULL; if (error == NULL) { error = device_allocate(&new_device); } // Copy the device instance ID. if (error == NULL) { assert(source->device_instance_id != NULL); size_t size = strlen(source->device_instance_id) + 1; char * new_id = malloc(size); if (new_id == NULL) { error = &error_no_memory; } else { memcpy(new_id, source->device_instance_id, size); new_device->device_instance_id = new_id; } } if (error == NULL) { new_device->vendor_id = source->vendor_id; new_device->product_id = source->product_id; new_device->revision = source->revision; } // Pass the device to the caller. if (error == NULL) { *dest = new_device; new_device = NULL; } libusbp_device_free(new_device); return error; }
libusbp_error * create_device(io_service_t service, libusbp_device ** device) { assert(service != MACH_PORT_NULL); assert(device != NULL); libusbp_error * error = NULL; // Allocate the device. libusbp_device * new_device = NULL; if (error == NULL) { error = device_allocate(&new_device); } // Get the numeric IDs. if (error == NULL) { error = get_uint16(service, CFSTR(kUSBVendorID), &new_device->vendor_id); } if (error == NULL) { error = get_uint16(service, CFSTR(kUSBProductID), &new_device->product_id); } if (error == NULL) { error = get_uint16(service, CFSTR(kUSBDeviceReleaseNumber), &new_device->revision); } // Get the serial number. if (error == NULL) { error = get_string(service, CFSTR(kUSBSerialNumberString), &new_device->serial_number); } // Get the ID. if (error == NULL) { error = get_id(service, &new_device->id); } // Pass the device to the caller. if (error == NULL) { *device = new_device; new_device = NULL; } libusbp_device_free(new_device); return error; }
libusbp_error * libusbp_device_copy(const libusbp_device * source, libusbp_device ** dest) { if (dest == NULL) { return error_create("Device output pointer is null."); } *dest = NULL; if (source == NULL) { return NULL; } libusbp_error * error = NULL; // Allocate the device. libusbp_device * new_device = NULL; if (error == NULL) { error = device_allocate(&new_device); } // Copy the simple fields, while leaving the pointers owned by the // device NULL so that libusbp_device_free is still OK to call. if (error == NULL) { memcpy(new_device, source, sizeof(libusbp_device)); new_device->serial_number = NULL; } // Copy the serial number. if (error == NULL && source->serial_number != NULL) { error = string_copy(source->serial_number, &new_device->serial_number); } // Pass the device to the caller. if (error == NULL) { *dest = new_device; new_device = NULL; } libusbp_device_free(new_device); return error; }
libusbp_error * create_device(HDEVINFO list, PSP_DEVINFO_DATA info, libusbp_device ** device) { assert(list != INVALID_HANDLE_VALUE); assert(info != NULL); assert(info->cbSize == sizeof(SP_DEVINFO_DATA)); assert(device != NULL); *device = NULL; libusbp_error * error = NULL; // Allocate memory for the device itself. libusbp_device * new_device = NULL; if (error == NULL) { error = device_allocate(&new_device); } // Get the device instance ID. if (error == NULL) { error = create_id_string(list, info, &new_device->device_instance_id); } // Get the vendor ID, product ID, and revision from the hardware IDs. char * new_ids = NULL; if (error == NULL) { error = device_get_hardware_ids(list, info, &new_ids); } if (error == NULL) { error = device_take_info_from_hardware_ids(new_device, new_ids); } // Return the device to the caller. if (error == NULL) { *device = new_device; new_device = NULL; } libusbp_string_free(new_ids); libusbp_device_free(new_device); return error; }
static struct jaylink_device *probe_device(struct jaylink_context *ctx, struct libusb_device *usb_dev) { int ret; struct libusb_device_descriptor desc; struct libusb_device_handle *usb_devh; struct jaylink_device *dev; char buf[USB_SERIAL_NUMBER_LENGTH + 1]; uint8_t usb_address; uint32_t serial_number; bool valid_serial_number; bool found_device; size_t i; ret = libusb_get_device_descriptor(usb_dev, &desc); if (ret != LIBUSB_SUCCESS) { log_warn(ctx, "Failed to get device descriptor: %s.", libusb_error_name(ret)); return NULL; } if (desc.idVendor != USB_VENDOR_ID) return NULL; found_device = false; for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) { if (pids[i][0] == desc.idProduct) { found_device = true; usb_address = pids[i][1]; break; } } if (!found_device) return NULL; log_dbg(ctx, "Found device (VID:PID = %04x:%04x, bus:address = " "%03u:%03u).", desc.idVendor, desc.idProduct, libusb_get_bus_number(usb_dev), libusb_get_device_address(usb_dev)); /* * Search for an already allocated device instance for this device and * if found return a reference to it. */ dev = find_device(ctx, usb_dev); if (dev) { log_dbg(ctx, "Device: USB address = %u.", dev->usb_address); if (dev->valid_serial_number) log_dbg(ctx, "Device: Serial number = %u.", dev->serial_number); else log_dbg(ctx, "Device: Serial number = N/A."); log_dbg(ctx, "Using existing device instance."); return jaylink_ref_device(dev); } /* Open the device to be able to retrieve its serial number. */ ret = libusb_open(usb_dev, &usb_devh); if (ret != LIBUSB_SUCCESS) { log_warn(ctx, "Failed to open device: %s.", libusb_error_name(ret)); return NULL; } valid_serial_number = true; ret = libusb_get_string_descriptor_ascii(usb_devh, desc.iSerialNumber, (unsigned char *)buf, USB_SERIAL_NUMBER_LENGTH + 1); libusb_close(usb_devh); if (ret < 0) { log_warn(ctx, "Failed to retrieve serial number: %s.", libusb_error_name(ret)); valid_serial_number = false; } if (valid_serial_number) { if (!parse_serial_number(buf, &serial_number)) { log_warn(ctx, "Failed to parse serial number."); return NULL; } } log_dbg(ctx, "Device: USB address = %u.", usb_address); if (valid_serial_number) log_dbg(ctx, "Device: Serial number = %u.", serial_number); else log_dbg(ctx, "Device: Serial number = N/A."); log_dbg(ctx, "Allocating new device instance."); dev = device_allocate(ctx); if (!dev) { log_warn(ctx, "Device instance malloc failed."); return NULL; } dev->interface = JAYLINK_HIF_USB; dev->usb_dev = libusb_ref_device(usb_dev); dev->usb_address = usb_address; dev->serial_number = serial_number; dev->valid_serial_number = valid_serial_number; return dev; }