在命令行執(zhí)行adb devices,你會得到連接上的設(shè)備,結(jié)果里面有每個設(shè)備的標(biāo)識(serial number)。在adb的其他命令中,你可以用adb –s 來指定用某一個設(shè)備來執(zhí)行命令,但是每個設(shè)備的serial number都不一樣,adb是如何得到的呢?查看adb的源碼后,發(fā)現(xiàn)其獲取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發(fā)送ADB_IOCTL_GET_SERIAL_NUMBER獲取的,而上面CreateFile使用的interface_name是adb設(shè)備的全路徑,格式如"http:////?//usb#vid_xxxx&pid_xxxx&mi_xx#123456789abcdef#{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX},創(chuàng)建adb設(shè)備的代碼如下:
-
- 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"http:////?//usb#vid_%04x&pid_%04x#",
- vendor_id, product_id);
- } else {
-
- swprintf(match_name, L"http:////?//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設(shè)備(classid:{0xf72fe0d4, 0xcbcb, 0x407d, {0x88, 0x14, 0x9e, 0xd6, 0x73, 0xd0, 0xdd, 0x6b}}),所以插上usb后起碼要1秒adb devices才能發(fā)現(xiàn)新設(shè)備。
-
- void* device_poll_thread(void* unused) {
- D("Created device thread/n");
- while(1) {
- find_devices();
- adb_sleep_ms(1000);
- }
- return NULL;
- }
如果你用windows監(jiān)聽usb設(shè)備的方式去監(jiān)聽adb設(shè)備,你可以在PDEV_BROADCAST_DEVICEINTERFACE結(jié)構(gòu)體的dbcc_name字段獲得GetSerialNumber函數(shù)所使用的interface_name。