Esempio n. 1
0
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);
}