adb devices获得的设备标识

在命令行执行adb devices,你会得到连接上的设备,结果里面有每个设备的标识(serial number)。在adb的其他命令中,你可以用adb –s 来指定用某一个设备来执行命令,但是每个设备的serial number都不一样,adb是如何得到的呢?查看adb的源码后,发现其获取serial number的代码如下:

[cpp]  view plain copy
  1. //D:/project/android/android-1.5/development/host/windows/usb/api/adb_interface.cpp  
  2. bool AdbInterfaceObject::GetSerialNumber(void* buffer,   
  3.                                          unsigned long* buffer_char_size,   
  4.                                          bool ansi) {   
  5.   if (!IsOpened()) {   
  6.     SetLastError(ERROR_INVALID_HANDLE);   
  7.     return false;   
  8.   }  
  9.   // Open USB device for this intefface   
  10.   HANDLE usb_device_handle = CreateFile(interface_name().c_str(),   
  11.                                         GENERIC_READ,   
  12.                                         FILE_SHARE_READ | FILE_SHARE_WRITE,   
  13.                                         NULL,   
  14.                                         OPEN_EXISTING,   
  15.                                         0,   
  16.                                         NULL);   
  17.   if (INVALID_HANDLE_VALUE == usb_device_handle)   
  18.     return NULL;  
  19.   WCHAR serial_number[512];  
  20.   // Send IOCTL   
  21.   DWORD ret_bytes = 0;   
  22.   BOOL ret = DeviceIoControl(usb_device_handle,   
  23.                              ADB_IOCTL_GET_SERIAL_NUMBER,   
  24.                              NULL, 0,   
  25.                              serial_number, sizeof(serial_number),   
  26.                              &ret_bytes,   
  27.                              NULL);  
  28.   // Preserve error accross CloseHandle   
  29.   ULONG error = ret ? NO_ERROR : GetLastError();  
  30.   ::CloseHandle(usb_device_handle);  
  31.   if (NO_ERROR != error) {   
  32.     SetLastError(error);   
  33.     return false;   
  34.   }  
  35.   unsigned long str_len =   
  36.     static_cast(wcslen(serial_number) + 1);  
  37.   if ((NULL == buffer) || (*buffer_char_size < str_len)) {   
  38.     *buffer_char_size = str_len;   
  39.     SetLastError(ERROR_INSUFFICIENT_BUFFER);   
  40.     return false;   
  41.   }  
  42.   if (!ansi) {   
  43.     // If user asked for wide char name just return it   
  44.     wcscpy(reinterpret_cast(buffer), serial_number);   
  45.     return true;   
  46.   }  
  47.   // We need to convert name from wide char to ansi string   
  48.   int res = WideCharToMultiByte(CP_ACP,   
  49.                                 0,   
  50.                                 serial_number,   
  51.                                 static_cast(str_len),   
  52.                                 reinterpret_cast(buffer),   
  53.                                 static_cast(*buffer_char_size),   
  54.                                 NULL,   
  55.                                 NULL);   
  56.   return (res != 0);   
  57. }  
 

从上面的代码可以看到,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设备的代码如下:

[cpp]  view plain copy
  1. //D:/project/android/android-1.5/development/host/windows/usb/api/adb_api.cpp  
  2. ADBAPIHANDLE AdbCreateInterface(GUID class_id,   
  3.                                 unsigned short vendor_id,   
  4.                                 unsigned short product_id,   
  5.                                 unsigned char interface_id) {   
  6.   // Enumerate all active interfaces for the given class   
  7.   AdbEnumInterfaceArray interfaces;  
  8.   if (!EnumerateDeviceInterfaces(class_id,   
  9.                                  DIGCF_DEVICEINTERFACE | DIGCF_PRESENT,   
  10.                                  true,   
  11.                                  true,   
  12.                                  &interfaces)) {   
  13.     return NULL;   
  14.   }  
  15.   if (interfaces.empty()) {   
  16.     SetLastError(ERROR_DEVICE_NOT_AVAILABLE);   
  17.     return NULL;   
  18.   }  
  19.   // Now iterate over active interfaces looking for the name match.   
  20.   // The name is formatted as such:   
  21.   // "////?//usb#vid_xxxx&pid_xxxx&mi_xx#123456789abcdef#{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"   
  22.   // where   
  23.   //    vid_xxxx is for the vendor id (xxxx are hex for the given vendor id),   
  24.   //    pid_xxxx is for the product id (xxxx are hex for the given product id)   
  25.   //    mi_xx is for the interface id  (xx are hex for the given interface id)   
  26.   // EnumerateDeviceInterfaces will guarantee that returned interface names   
  27.   // will have our class id at the end of the name (those last XXXes in the   
  28.   // format). So, we only need to match the beginning of the name   
  29.   wchar_t match_name[64];   
  30.   if (0xFF == interface_id) {   
  31.     // No interface id for the name.   
  32.     swprintf(match_name, L"////?//usb#vid_%04x&pid_%04x#",   
  33.              vendor_id, product_id);   
  34.   } else {   
  35.     // With interface id for the name.   
  36.     swprintf(match_name, L"////?//usb#vid_%04x&pid_%04x&mi_%02x#",   
  37.              vendor_id, product_id, interface_id);   
  38.   }   
  39.   size_t match_len = wcslen(match_name);  
  40.   for (AdbEnumInterfaceArray::iterator it = interfaces.begin();   
  41.        it != interfaces.end(); it++) {   
  42.     const AdbInstanceEnumEntry& next_interface = *it;   
  43.     if (0 == wcsnicmp(match_name,   
  44.                       next_interface.device_name().c_str(),   
  45.                       match_len)) {   
  46.       // Found requested interface among active interfaces.   
  47.       return AdbCreateInterfaceByName(next_interface.device_name().c_str());   
  48.     }   
  49.   }  
  50.   SetLastError(ERROR_DEVICE_NOT_AVAILABLE);   
  51.   return NULL;   
  52. }  
 

adb是每个1秒没有所有的usb设备(classid:{0xf72fe0d4, 0xcbcb, 0x407d, {0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b}}),所以插上usb后起码要1秒adb devices才能发现新设备。

[cpp]  view plain copy
  1. //D:/project/android/android-1.5/system/core/adb/usb_windows.c  
  2. void* device_poll_thread(void* unused) {   
  3.   D("Created device thread/n");  
  4.   while(1) {   
  5.     find_devices();   
  6.     adb_sleep_ms(1000);   
  7.   }  
  8.   return NULL;   
  9. }  
 

如果你用windows监听usb设备的方式去监听adb设备,你可以在PDEV_BROADCAST_DEVICEINTERFACE结构体的dbcc_name字段获得GetSerialNumber函数所使用的interface_name。

你可能感兴趣的:(adb devices获得的设备标识)