int recognized_device(usb_handle* handle, ifc_match_func callback) { struct usb_ifc_info info; USB_DEVICE_DESCRIPTOR device_desc; USB_INTERFACE_DESCRIPTOR interf_desc; if (NULL == handle) return 0; // Check vendor and product id first if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, &device_desc)) { return 0; } // Then check interface properties if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, &interf_desc)) { return 0; } // Must have two endpoints if (2 != interf_desc.bNumEndpoints) { return 0; } info.dev_vendor = device_desc.idVendor; info.dev_product = device_desc.idProduct; info.dev_class = device_desc.bDeviceClass; info.dev_subclass = device_desc.bDeviceSubClass; info.dev_protocol = device_desc.bDeviceProtocol; info.ifc_class = interf_desc.bInterfaceClass; info.ifc_subclass = interf_desc.bInterfaceSubClass; info.ifc_protocol = interf_desc.bInterfaceProtocol; info.writable = 1; // read serial number (if there is one) unsigned long serial_number_len = sizeof(info.serial_number); if (!AdbGetSerialNumber(handle->adb_interface, info.serial_number, &serial_number_len, true)) { info.serial_number[0] = 0; } info.device_path[0] = 0; if (callback(&info) == 0) { return 1; } return 0; }
bool DeviceHandShake(ADBAPIHANDLE adb_interface) { // Get interface name char interf_name[512]; unsigned long name_size = sizeof(interf_name); if (!AdbGetInterfaceName(adb_interface, interf_name, &name_size, true)) { printf("\nDeviceHandShake: AdbGetInterfaceName returned error %u", GetLastError()); return false; } printf("\n\nDeviceHandShake on %s", interf_name); char* ser_num = NULL; name_size = 0; if (!AdbGetSerialNumber(adb_interface, ser_num, &name_size, true)) { ser_num = reinterpret_cast<char*>(malloc(name_size)); if (NULL != ser_num) { if (!AdbGetSerialNumber(adb_interface, ser_num, &name_size, true)) { printf("\n AdbGetSerialNumber returned error %u", GetLastError()); AdbCloseHandle(adb_interface); return false; } printf("\nInterface serial number is %s", ser_num); free(ser_num); } } // Get default read endpoint ADBAPIHANDLE adb_read = AdbOpenDefaultBulkReadEndpoint(adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite); if (NULL == adb_read) { printf("\n AdbOpenDefaultBulkReadEndpoint returned error %u", GetLastError()); return false; } // Get default write endpoint ADBAPIHANDLE adb_write = AdbOpenDefaultBulkWriteEndpoint(adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite); if (NULL == adb_write) { printf("\n AdbOpenDefaultBulkWriteEndpoint returned error %u", GetLastError()); AdbCloseHandle(adb_read); return false; } // Send connect message message msg_send; msg_send.command = A_CNXN; msg_send.arg0 = A_VERSION; msg_send.arg1 = MAX_PAYLOAD; msg_send.data_length = 0; msg_send.data_crc32 = 0; msg_send.magic = msg_send.command ^ 0xffffffff; ULONG written_bytes = 0; bool write_res = AdbWriteEndpointSync(adb_write, &msg_send, sizeof(msg_send), &written_bytes, 500); if (!write_res) { printf("\n AdbWriteEndpointSync returned error %u", GetLastError()); AdbCloseHandle(adb_write); AdbCloseHandle(adb_read); return false; } // Receive handshake message msg_rcv; ULONG read_bytes = 0; bool read_res = AdbReadEndpointSync(adb_read, &msg_rcv, sizeof(msg_rcv), &read_bytes, 512); if (!read_res) { printf("\n AdbReadEndpointSync returned error %u", GetLastError()); AdbCloseHandle(adb_write); AdbCloseHandle(adb_read); return false; } printf("\n Read handshake: %u bytes received", read_bytes); char* cmd_ansi = reinterpret_cast<char*>(&msg_rcv.command); printf("\n command = %08X (%c%c%c%c)", msg_rcv.command, cmd_ansi[0], cmd_ansi[1], cmd_ansi[2], cmd_ansi[3]); printf("\n arg0 = %08X", msg_rcv.arg0); printf("\n arg1 = %08X", msg_rcv.arg1); printf("\n data_length = %u", msg_rcv.data_length); printf("\n data_crc32 = %08X", msg_rcv.data_crc32); printf("\n magic = %08X", msg_rcv.magic); if (0 != msg_rcv.data_length) { char* buf = reinterpret_cast<char*>(malloc(msg_rcv.data_length)); read_res = AdbReadEndpointSync(adb_read, buf, msg_rcv.data_length, &read_bytes, 512); if (!read_res) { printf("\n AdbReadEndpointSync (data) returned error %u", GetLastError()); free(buf); AdbCloseHandle(adb_write); AdbCloseHandle(adb_read); return false; } for (ULONG n = 0; n < read_bytes; n++) { if (0 == (n % 16)) printf("\n "); printf("%02X ", buf[n]); } printf("\n %s", buf); delete buf; } AdbCloseHandle(adb_write); AdbCloseHandle(adb_read); return true; }
bool TestInterfaceHandle(ADBAPIHANDLE interface_handle) { // Get interface name. char intr_name[4096]; unsigned long intr_name_size = sizeof(intr_name); if (AdbGetInterfaceName(interface_handle, intr_name, &intr_name_size, true)) { printf("\n+++ Interface name %s", intr_name); } else { printf("\n--- AdbGetInterfaceName failure %u", GetLastError()); return false; } // Get device descriptor for the interface USB_DEVICE_DESCRIPTOR dev_desc; if (AdbGetUsbDeviceDescriptor(interface_handle, &dev_desc)) { printf("\n+++ Device descriptor:"); printf("\n bLength = %u", dev_desc.bLength); printf("\n bDescriptorType = %u", dev_desc.bDescriptorType); printf("\n bcdUSB = %u", dev_desc.bcdUSB); printf("\n bDeviceClass = %u", dev_desc.bDeviceClass); printf("\n bDeviceSubClass = %u", dev_desc.bDeviceSubClass); printf("\n bDeviceProtocol = %u", dev_desc.bDeviceProtocol); printf("\n bMaxPacketSize0 = %u", dev_desc.bMaxPacketSize0); printf("\n idVendor = %X", dev_desc.idVendor); printf("\n idProduct = %X", dev_desc.idProduct); printf("\n bcdDevice = %u", dev_desc.bcdDevice); printf("\n iManufacturer = %u", dev_desc.iManufacturer); printf("\n iProduct = %u", dev_desc.iProduct); printf("\n iSerialNumber = %u", dev_desc.iSerialNumber); printf("\n bNumConfigurations = %u", dev_desc.bDescriptorType); } else { printf("\n--- AdbGetUsbDeviceDescriptor failure %u", GetLastError()); return false; } // Get configuration descriptor for the interface USB_CONFIGURATION_DESCRIPTOR config_desc; if (AdbGetUsbConfigurationDescriptor(interface_handle, &config_desc)) { printf("\n+++ Configuration descriptor:"); printf("\n bLength = %u", config_desc.bLength); printf("\n bDescriptorType = %u", config_desc.bDescriptorType); printf("\n wTotalLength = %u", config_desc.wTotalLength); printf("\n bNumInterfaces = %u", config_desc.bNumInterfaces); printf("\n bConfigurationValue = %u", config_desc.bConfigurationValue); printf("\n iConfiguration = %u", config_desc.iConfiguration); printf("\n bmAttributes = %u", config_desc.bmAttributes); printf("\n MaxPower = %u", config_desc.MaxPower); } else { printf("\n--- AdbGetUsbConfigurationDescriptor failure %u", GetLastError()); return false; } // Get device serial number char ser_num[1024]; unsigned long ser_num_size = sizeof(ser_num); if (AdbGetSerialNumber(interface_handle, ser_num, &ser_num_size, true)) { printf("\n+++ Serial number: %s", ser_num); } else { printf("\n--- AdbGetSerialNumber failure %u", GetLastError()); return false; } // Get interface descriptor USB_INTERFACE_DESCRIPTOR intr_desc; if (AdbGetUsbInterfaceDescriptor(interface_handle, &intr_desc)) { printf("\n+++ Interface descriptor:"); printf("\n bDescriptorType = %u", intr_desc.bDescriptorType); printf("\n bInterfaceNumber = %u", intr_desc.bInterfaceNumber); printf("\n bAlternateSetting = %u", intr_desc.bAlternateSetting); printf("\n bNumEndpoints = %u", intr_desc.bNumEndpoints); printf("\n bInterfaceClass = %u", intr_desc.bInterfaceClass); printf("\n bInterfaceSubClass = %u", intr_desc.bInterfaceSubClass); printf("\n bInterfaceProtocol = %u", intr_desc.bInterfaceProtocol); printf("\n iInterface = %u", intr_desc.iInterface); } else { printf("\n--- AdbGetUsbInterfaceDescriptor failure %u", GetLastError()); return false; } // Enumerate interface's endpoints AdbEndpointInformation pipe_info; for (UCHAR pipe = 0; pipe < intr_desc.bNumEndpoints; pipe++) { if (AdbGetEndpointInformation(interface_handle, pipe, &pipe_info)) { printf("\n PIPE %u info:", pipe); printf("\n max_packet_size = %u", pipe_info.max_packet_size); printf("\n max_transfer_size = %u", pipe_info.max_transfer_size); printf("\n endpoint_type = %u", pipe_info.endpoint_type); printf("\n endpoint_address = %02X", pipe_info.endpoint_address); printf("\n polling_interval = %u", pipe_info.polling_interval); printf("\n setting_index = %u", pipe_info.setting_index); } else { printf("\n--- AdbGetEndpointInformation(%u) failure %u", pipe, GetLastError()); return false; } } // Get default bulk read endpoint info if (AdbGetDefaultBulkReadEndpointInformation(interface_handle, &pipe_info)) { printf("\n Default Bulk Read Pipe info:"); printf("\n max_packet_size = %u", pipe_info.max_packet_size); printf("\n max_transfer_size = %u", pipe_info.max_transfer_size); printf("\n endpoint_type = %u", pipe_info.endpoint_type); printf("\n endpoint_address = %02X", pipe_info.endpoint_address); printf("\n polling_interval = %u", pipe_info.polling_interval); printf("\n setting_index = %u", pipe_info.setting_index); } else { printf("\n--- AdbGetDefaultBulkReadEndpointInformation failure %u", GetLastError()); return false; } // Get default bulk write endpoint info if (AdbGetDefaultBulkWriteEndpointInformation(interface_handle, &pipe_info)) { printf("\n Default Bulk Write Pipe info:"); printf("\n max_packet_size = %u", pipe_info.max_packet_size); printf("\n max_transfer_size = %u", pipe_info.max_transfer_size); printf("\n endpoint_type = %u", pipe_info.endpoint_type); printf("\n endpoint_address = %02X", pipe_info.endpoint_address); printf("\n polling_interval = %u", pipe_info.polling_interval); printf("\n setting_index = %u", pipe_info.setting_index); } else { printf("\n--- AdbGetDefaultBulkWriteEndpointInformation failure %u", GetLastError()); return false; } // Test a handshake on that interface DeviceHandShake(interface_handle); return true; }
void find_devices() { usb_handle* handle = nullptr; char entry_buffer[2048]; AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); unsigned long entry_buffer_size = sizeof(entry_buffer); // Enumerate all present and active interfaces. ADBAPIHANDLE enum_handle = AdbEnumInterfaces(usb_class_id, true, true, true); if (nullptr == enum_handle) { D("AdbEnumInterfaces failed: %s", android::base::SystemErrorCodeToString(GetLastError()).c_str()); return; } while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { // Lets see if we already have this device in the list if (!known_device(next_interface->device_name)) { // This seems to be a new device. Open it! handle = do_usb_open(next_interface->device_name); if (nullptr != handle) { // Lets see if this interface (device) belongs to us if (recognized_device(handle)) { D("adding a new device %ls", next_interface->device_name); // We don't request a wchar_t string from AdbGetSerialNumber() because of a bug // in adb_winusb_interface.cpp:CopyMemory(buffer, ser_num->bString, // bytes_written) where the last parameter should be (str_len * // sizeof(wchar_t)). The bug reads 2 bytes past the end of a stack buffer in the // best case, and in the unlikely case of a long serial number, it will read 2 // bytes past the end of a heap allocation. This doesn't affect the resulting // string, but we should avoid the bad reads in the first place. char serial_number[512]; unsigned long serial_number_len = sizeof(serial_number); if (AdbGetSerialNumber(handle->adb_interface, serial_number, &serial_number_len, true)) { // Lets make sure that we don't duplicate this device if (register_new_device(handle)) { register_usb_transport(handle, serial_number, nullptr, 1); } else { D("register_new_device failed for %ls", next_interface->device_name); usb_cleanup_handle(handle); free(handle); } } else { D("cannot get serial number: %s", android::base::SystemErrorCodeToString(GetLastError()).c_str()); usb_cleanup_handle(handle); free(handle); } } else { usb_cleanup_handle(handle); free(handle); } } } entry_buffer_size = sizeof(entry_buffer); } if (GetLastError() != ERROR_NO_MORE_ITEMS) { // Only ERROR_NO_MORE_ITEMS is expected at the end of enumeration. D("AdbNextInterface failed: %s", android::base::SystemErrorCodeToString(GetLastError()).c_str()); } _adb_close_handle(enum_handle); }