在命令行执行adb devices,你会得到连接上的设备,结果里面有每个设备的标识(serial number)。在adb的其他命令中,你可以用adb –s 来指定用某一个设备来执行命令,但是每个设备的serial number都不一样,adb是如何得到的呢?查看adb的源码后,发现其获取serial number的代码如下:
-
- bool AdbInterfaceObject::GetSerialNumber(void* buffer,
- unsigned long* buffer_char_size,
- bool ansi) {
- if (!IsOpened()) {
- SetLastError(ERROR_INVALID_HANDLE);
- return false;
- }
-
- HANDLE usb_device_handle = CreateFile(interface_name().c_str(),
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (INVALID_HANDLE_VALUE == usb_device_handle)
- return NULL;
- WCHAR serial_number[512];
-
- DWORD ret_bytes = 0;
- BOOL ret = DeviceIoControl(usb_device_handle,
- ADB_IOCTL_GET_SERIAL_NUMBER,
- NULL, 0,
- serial_number, sizeof(serial_number),
- &ret_bytes,
- NULL);
-
- ULONG error = ret ? NO_ERROR : GetLastError();
- ::CloseHandle(usb_device_handle);
- if (NO_ERROR != error) {
- SetLastError(error);
- return false;
- }
- unsigned long str_len =
- static_cast(wcslen(serial_number) + 1);
- if ((NULL == buffer) || (*buffer_char_size < str_len)) {
- *buffer_char_size = str_len;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return false;
- }
- if (!ansi) {
-
- wcscpy(reinterpret_cast(buffer), serial_number);
- return true;
- }
-
- int res = WideCharToMultiByte(CP_ACP,
- 0,
- serial_number,
- static_cast(str_len),
- reinterpret_cast(buffer),
- static_cast(*buffer_char_size),
- NULL,
- NULL);
- return (res != 0);
- }
从上面的代码可以看到,adb是通过DeviceIoControl发送ADB_IOCTL_GET_SERIAL_NUMBER获取的,而上面CreateFile使用的interface_name是adb设备的全路径,格式如"////?//usb#vid_xxxx&pid_xxxx&mi_xx#123456789abcdef#{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX},创建adb设备的代码如下:
-
- ADBAPIHANDLE AdbCreateInterface(GUID class_id,
- unsigned short vendor_id,
- unsigned short product_id,
- unsigned char interface_id) {
-
- AdbEnumInterfaceArray interfaces;
- if (!EnumerateDeviceInterfaces(class_id,
- DIGCF_DEVICEINTERFACE | DIGCF_PRESENT,
- true,
- true,
- &interfaces)) {
- return NULL;
- }
- if (interfaces.empty()) {
- SetLastError(ERROR_DEVICE_NOT_AVAILABLE);
- return NULL;
- }
-
-
-
-
-
-
-
-
-
-
- wchar_t match_name[64];
- if (0xFF == interface_id) {
-
- swprintf(match_name, L"////?//usb#vid_%04x&pid_%04x#",
- vendor_id, product_id);
- } else {
-
- swprintf(match_name, L"////?//usb#vid_%04x&pid_%04x&mi_%02x#",
- vendor_id, product_id, interface_id);
- }
- size_t match_len = wcslen(match_name);
- for (AdbEnumInterfaceArray::iterator it = interfaces.begin();
- it != interfaces.end(); it++) {
- const AdbInstanceEnumEntry& next_interface = *it;
- if (0 == wcsnicmp(match_name,
- next_interface.device_name().c_str(),
- match_len)) {
-
- return AdbCreateInterfaceByName(next_interface.device_name().c_str());
- }
- }
- SetLastError(ERROR_DEVICE_NOT_AVAILABLE);
- return NULL;
- }
adb是每个1秒没有所有的usb设备(classid:{0xf72fe0d4, 0xcbcb, 0x407d, {0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b}}),所以插上usb后起码要1秒adb devices才能发现新设备。
-
- void* device_poll_thread(void* unused) {
- D("Created device thread/n");
- while(1) {
- find_devices();
- adb_sleep_ms(1000);
- }
- return NULL;
- }
如果你用windows监听usb设备的方式去监听adb设备,你可以在PDEV_BROADCAST_DEVICEINTERFACE结构体的dbcc_name字段获得GetSerialNumber函数所使用的interface_name。