blob: 658192891168f0d497e933a711b0d26b61e4780b [file] [log] [blame]
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yabin Cui19bec5b2015-09-22 15:52:57 -070017#define TRACE_TAG USB
Dan Albertdb6fe642015-03-19 15:21:08 -070018
19#include "sysdeps.h"
20
Josh Gao6b55e752020-03-27 18:09:56 -070021#include "client/usb.h"
22
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070023// clang-format off
Dan Albertb302d122015-02-24 15:51:19 -080024#include <winsock2.h> // winsock.h *must* be included before windows.h.
Josh Gaoe7daf572016-09-21 12:37:10 -070025#include <windows.h>
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070026// clang-format on
Josh Gaoe7daf572016-09-21 12:37:10 -070027#include <usb100.h>
28#include <winerror.h>
29
Dan Albertb302d122015-02-24 15:51:19 -080030#include <errno.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080031#include <stdio.h>
Christopher Ferris054d1702014-11-06 14:34:24 -080032#include <stdlib.h>
Josh Gaoe7daf572016-09-21 12:37:10 -070033
Josh Gao511ff8a2017-12-08 13:05:40 -080034#include <algorithm>
Josh Gaoe7daf572016-09-21 12:37:10 -070035#include <mutex>
Elliott Hughes73925982016-11-15 12:37:32 -080036#include <thread>
Josh Gaoe7daf572016-09-21 12:37:10 -070037
38#include <adb_api.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080039
David Pursellc573d522016-01-27 08:52:53 -080040#include <android-base/errors.h>
41
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080042#include "adb.h"
Josh Gao70267e42016-11-15 18:55:47 -080043#include "sysdeps/chrono.h"
Dan Albertb302d122015-02-24 15:51:19 -080044#include "transport.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080045
46/** Structure usb_handle describes our connection to the usb device via
47 AdbWinApi.dll. This structure is returned from usb_open() routine and
48 is expected in each subsequent call that is accessing the device.
Spencer Low9f1ba562015-07-22 16:17:07 -070049
50 Most members are protected by usb_lock, except for adb_{read,write}_pipe which
51 rely on AdbWinApi.dll's handle validation and AdbCloseHandle(endpoint)'s
52 ability to break a thread out of pipe IO.
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080053*/
Josh Gaof2d6af52021-04-27 20:32:02 -070054struct usb_handle {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070055 /// Handle to USB interface
56 ADBAPIHANDLE adb_interface;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080057
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070058 /// Handle to USB read pipe (endpoint)
59 ADBAPIHANDLE adb_read_pipe;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080060
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070061 /// Handle to USB write pipe (endpoint)
62 ADBAPIHANDLE adb_write_pipe;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080063
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070064 /// Interface name
65 wchar_t* interface_name;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080066
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070067 /// Maximum packet size.
68 unsigned max_packet_size;
Josh Gao3734cf02017-05-02 15:01:09 -070069
Mark Salyzynd4bf94d2017-10-04 15:05:40 -070070 /// Mask for determining when to use zero length packets
71 unsigned zero_mask;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080072};
73
74/// Class ID assigned to the device by androidusb.sys
75static const GUID usb_class_id = ANDROID_USB_CLASS_ID;
76
77/// List of opened usb handles
Pirama Arumuga Nainar2c513a12018-06-01 11:30:15 -070078static std::vector<usb_handle*>& handle_list = *new std::vector<usb_handle*>();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080079
80/// Locker for the list of opened usb handles
Josh Gaoe7daf572016-09-21 12:37:10 -070081static std::mutex& usb_lock = *new std::mutex();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080082
83/// Checks if there is opened usb handle in handle_list for this device.
Spencer Low66763962015-11-12 20:13:21 -080084int known_device(const wchar_t* dev_name);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080085
86/// Checks if there is opened usb handle in handle_list for this device.
87/// usb_lock mutex must be held before calling this routine.
Spencer Low66763962015-11-12 20:13:21 -080088int known_device_locked(const wchar_t* dev_name);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080089
90/// Registers opened usb handle (adds it to handle_list).
91int register_new_device(usb_handle* handle);
92
93/// Checks if interface (device) matches certain criteria
94int recognized_device(usb_handle* handle);
95
96/// Enumerates present and available interfaces (devices), opens new ones and
97/// registers usb transport for them.
98void find_devices();
99
Spencer Low9f1ba562015-07-22 16:17:07 -0700100/// Kicks all USB devices
101static void kick_devices();
102
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800103/// Entry point for thread that polls (every second) for new usb interfaces.
104/// This routine calls find_devices in infinite loop.
Josh Gao0f3312a2017-04-12 17:00:49 -0700105static void device_poll_thread();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800106
107/// Initializes this module
108void usb_init();
109
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800110/// Opens usb interface (device) by interface (device) name.
111usb_handle* do_usb_open(const wchar_t* interface_name);
112
113/// Writes data to the opened usb handle
114int usb_write(usb_handle* handle, const void* data, int len);
115
116/// Reads data using the opened usb handle
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700117int usb_read(usb_handle* handle, void* data, int len);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800118
119/// Cleans up opened usb handle
120void usb_cleanup_handle(usb_handle* handle);
121
122/// Cleans up (but don't close) opened usb handle
123void usb_kick(usb_handle* handle);
124
125/// Closes opened usb handle
126int usb_close(usb_handle* handle);
127
Spencer Low66763962015-11-12 20:13:21 -0800128int known_device_locked(const wchar_t* dev_name) {
Yi Kong86e67182018-07-13 18:15:16 -0700129 if (nullptr != dev_name) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700130 // Iterate through the list looking for the name match.
Josh Gao511ff8a2017-12-08 13:05:40 -0800131 for (usb_handle* usb : handle_list) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700132 // In Windows names are not case sensetive!
Yi Kong86e67182018-07-13 18:15:16 -0700133 if ((nullptr != usb->interface_name) && (0 == wcsicmp(usb->interface_name, dev_name))) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700134 return 1;
135 }
136 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800137 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800138
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700139 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800140}
141
Spencer Low66763962015-11-12 20:13:21 -0800142int known_device(const wchar_t* dev_name) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700143 int ret = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800144
Yi Kong86e67182018-07-13 18:15:16 -0700145 if (nullptr != dev_name) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700146 std::lock_guard<std::mutex> lock(usb_lock);
147 ret = known_device_locked(dev_name);
148 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800149
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700150 return ret;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800151}
152
153int register_new_device(usb_handle* handle) {
Yi Kong86e67182018-07-13 18:15:16 -0700154 if (nullptr == handle) return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800155
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700156 std::lock_guard<std::mutex> lock(usb_lock);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800157
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700158 // Check if device is already in the list
159 if (known_device_locked(handle->interface_name)) {
160 return 0;
161 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800162
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700163 // Not in the list. Add this handle to the list.
Josh Gao511ff8a2017-12-08 13:05:40 -0800164 handle_list.push_back(handle);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800165
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700166 return 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800167}
168
Josh Gao0f3312a2017-04-12 17:00:49 -0700169void device_poll_thread() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700170 adb_thread_setname("Device Poll");
171 D("Created device thread");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800172
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700173 while (true) {
174 find_devices();
Daniel Colascione2155f3f2019-11-04 11:33:58 -0800175 adb_notify_device_scan_complete();
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700176 std::this_thread::sleep_for(1s);
177 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800178}
179
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700180static LRESULT CALLBACK _power_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
181 switch (uMsg) {
182 case WM_POWERBROADCAST:
183 switch (wParam) {
184 case PBT_APMRESUMEAUTOMATIC:
185 // Resuming from sleep or hibernation, so kick all existing USB devices
186 // and then allow the device_poll_thread to redetect USB devices from
187 // scratch. If we don't do this, existing USB devices will never respond
188 // to us because they'll be waiting for the connect/auth handshake.
189 D("Received (WM_POWERBROADCAST, PBT_APMRESUMEAUTOMATIC) notification, "
190 "so kicking all USB devices\n");
191 kick_devices();
192 return TRUE;
193 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700194 }
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700195 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
Spencer Low9f1ba562015-07-22 16:17:07 -0700196}
197
Josh Gao0f3312a2017-04-12 17:00:49 -0700198static void _power_notification_thread() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700199 // This uses a thread with its own window message pump to get power
200 // notifications. If adb runs from a non-interactive service account, this
201 // might not work (not sure). If that happens to not work, we could use
202 // heavyweight WMI APIs to get power notifications. But for the common case
203 // of a developer's interactive session, a window message pump is more
204 // appropriate.
205 D("Created power notification thread");
206 adb_thread_setname("Power Notifier");
Spencer Low9f1ba562015-07-22 16:17:07 -0700207
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700208 // Window class names are process specific.
209 static const WCHAR kPowerNotificationWindowClassName[] = L"PowerNotificationWindow";
Spencer Low9f1ba562015-07-22 16:17:07 -0700210
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700211 // Get the HINSTANCE corresponding to the module that _power_window_proc
212 // is in (the main module).
Yi Kong86e67182018-07-13 18:15:16 -0700213 const HINSTANCE instance = GetModuleHandleW(nullptr);
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700214 if (!instance) {
215 // This is such a common API call that this should never fail.
Elliott Hughese64126b2018-10-19 13:59:44 -0700216 LOG(FATAL) << "GetModuleHandleW failed: "
217 << android::base::SystemErrorCodeToString(GetLastError());
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700218 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700219
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700220 WNDCLASSEXW wndclass;
221 memset(&wndclass, 0, sizeof(wndclass));
222 wndclass.cbSize = sizeof(wndclass);
223 wndclass.lpfnWndProc = _power_window_proc;
224 wndclass.hInstance = instance;
225 wndclass.lpszClassName = kPowerNotificationWindowClassName;
226 if (!RegisterClassExW(&wndclass)) {
Elliott Hughese64126b2018-10-19 13:59:44 -0700227 LOG(FATAL) << "RegisterClassExW failed: "
228 << android::base::SystemErrorCodeToString(GetLastError());
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700229 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700230
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700231 if (!CreateWindowExW(WS_EX_NOACTIVATE, kPowerNotificationWindowClassName,
Yi Kong86e67182018-07-13 18:15:16 -0700232 L"ADB Power Notification Window", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr,
233 instance, nullptr)) {
Elliott Hughese64126b2018-10-19 13:59:44 -0700234 LOG(FATAL) << "CreateWindowExW failed: "
235 << android::base::SystemErrorCodeToString(GetLastError());
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700236 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700237
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700238 MSG msg;
Yi Kong86e67182018-07-13 18:15:16 -0700239 while (GetMessageW(&msg, nullptr, 0, 0)) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700240 TranslateMessage(&msg);
241 DispatchMessageW(&msg);
242 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700243
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700244 // GetMessageW() will return false if a quit message is posted. We don't
245 // do that, but it might be possible for that to occur when logging off or
246 // shutting down. Not a big deal since the whole process will be going away
247 // soon anyway.
248 D("Power notification thread exiting");
Spencer Low9f1ba562015-07-22 16:17:07 -0700249}
250
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800251void usb_init() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700252 std::thread(device_poll_thread).detach();
253 std::thread(_power_notification_thread).detach();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800254}
255
Josh Gao165460f2017-05-09 13:43:35 -0700256void usb_cleanup() {}
257
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800258usb_handle* do_usb_open(const wchar_t* interface_name) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700259 unsigned long name_len = 0;
Spencer Low9f1ba562015-07-22 16:17:07 -0700260
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700261 // Allocate our handle
262 usb_handle* ret = (usb_handle*)calloc(1, sizeof(usb_handle));
Yi Kong86e67182018-07-13 18:15:16 -0700263 if (nullptr == ret) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700264 D("Could not allocate %u bytes for usb_handle: %s", sizeof(usb_handle), strerror(errno));
265 goto fail;
266 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800267
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700268 // Create interface.
269 ret->adb_interface = AdbCreateInterfaceByName(interface_name);
Yi Kong86e67182018-07-13 18:15:16 -0700270 if (nullptr == ret->adb_interface) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700271 D("AdbCreateInterfaceByName failed: %s",
272 android::base::SystemErrorCodeToString(GetLastError()).c_str());
273 goto fail;
274 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800275
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700276 // Open read pipe (endpoint)
277 ret->adb_read_pipe = AdbOpenDefaultBulkReadEndpoint(
278 ret->adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite);
Yi Kong86e67182018-07-13 18:15:16 -0700279 if (nullptr == ret->adb_read_pipe) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700280 D("AdbOpenDefaultBulkReadEndpoint failed: %s",
281 android::base::SystemErrorCodeToString(GetLastError()).c_str());
282 goto fail;
283 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800284
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700285 // Open write pipe (endpoint)
286 ret->adb_write_pipe = AdbOpenDefaultBulkWriteEndpoint(
287 ret->adb_interface, AdbOpenAccessTypeReadWrite, AdbOpenSharingModeReadWrite);
Yi Kong86e67182018-07-13 18:15:16 -0700288 if (nullptr == ret->adb_write_pipe) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700289 D("AdbOpenDefaultBulkWriteEndpoint failed: %s",
290 android::base::SystemErrorCodeToString(GetLastError()).c_str());
291 goto fail;
292 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700293
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700294 // Save interface name
295 // First get expected name length
Yi Kong86e67182018-07-13 18:15:16 -0700296 AdbGetInterfaceName(ret->adb_interface, nullptr, &name_len, false);
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700297 if (0 == name_len) {
298 D("AdbGetInterfaceName returned name length of zero: %s",
299 android::base::SystemErrorCodeToString(GetLastError()).c_str());
300 goto fail;
301 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700302
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700303 ret->interface_name = (wchar_t*)malloc(name_len * sizeof(ret->interface_name[0]));
Yi Kong86e67182018-07-13 18:15:16 -0700304 if (nullptr == ret->interface_name) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700305 D("Could not allocate %lu characters for interface_name: %s", name_len, strerror(errno));
306 goto fail;
307 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700308
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700309 // Now save the name
310 if (!AdbGetInterfaceName(ret->adb_interface, ret->interface_name, &name_len, false)) {
311 D("AdbGetInterfaceName failed: %s",
312 android::base::SystemErrorCodeToString(GetLastError()).c_str());
313 goto fail;
314 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700315
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700316 // We're done at this point
317 return ret;
Spencer Low9f1ba562015-07-22 16:17:07 -0700318
319fail:
Yi Kong86e67182018-07-13 18:15:16 -0700320 if (nullptr != ret) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700321 usb_cleanup_handle(ret);
322 free(ret);
323 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800324
Yi Kong86e67182018-07-13 18:15:16 -0700325 return nullptr;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800326}
327
328int usb_write(usb_handle* handle, const void* data, int len) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700329 unsigned long time_out = 5000;
330 unsigned long written = 0;
331 int err = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800332
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700333 D("usb_write %d", len);
Yi Kong86e67182018-07-13 18:15:16 -0700334 if (nullptr == handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700335 D("usb_write was passed NULL handle");
336 err = EINVAL;
337 goto fail;
Spencer Low9f1ba562015-07-22 16:17:07 -0700338 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700339
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700340 // Perform write
341 if (!AdbWriteEndpointSync(handle->adb_write_pipe, (void*)data, (unsigned long)len, &written,
342 time_out)) {
343 D("AdbWriteEndpointSync failed: %s",
344 android::base::SystemErrorCodeToString(GetLastError()).c_str());
345 err = EIO;
346 goto fail;
347 }
348
349 // Make sure that we've written what we were asked to write
350 D("usb_write got: %ld, expected: %d", written, len);
351 if (written != (unsigned long)len) {
352 // If this occurs, this code should be changed to repeatedly call
353 // AdbWriteEndpointSync() until all bytes are written.
354 D("AdbWriteEndpointSync was supposed to write %d, but only wrote %ld", len, written);
355 err = EIO;
356 goto fail;
357 }
358
359 if (handle->zero_mask && (len & handle->zero_mask) == 0) {
360 // Send a zero length packet
Josh Gao9fae8762018-08-22 15:13:18 -0700361 unsigned long dummy;
362 if (!AdbWriteEndpointSync(handle->adb_write_pipe, (void*)data, 0, &dummy, time_out)) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700363 D("AdbWriteEndpointSync of zero length packet failed: %s",
364 android::base::SystemErrorCodeToString(GetLastError()).c_str());
365 err = EIO;
366 goto fail;
367 }
368 }
369
Jerry Zhang76d17db2018-05-15 16:20:41 -0700370 return written;
Spencer Low9f1ba562015-07-22 16:17:07 -0700371
372fail:
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700373 // Any failure should cause us to kick the device instead of leaving it a
374 // zombie state with potential to hang.
Yi Kong86e67182018-07-13 18:15:16 -0700375 if (nullptr != handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700376 D("Kicking device due to error in usb_write");
377 usb_kick(handle);
378 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700379
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700380 D("usb_write failed");
381 errno = err;
382 return -1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800383}
384
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700385int usb_read(usb_handle* handle, void* data, int len) {
386 unsigned long time_out = 0;
387 unsigned long read = 0;
388 int err = 0;
389 int orig_len = len;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800390
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700391 D("usb_read %d", len);
Yi Kong86e67182018-07-13 18:15:16 -0700392 if (nullptr == handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700393 D("usb_read was passed NULL handle");
394 err = EINVAL;
395 goto fail;
Spencer Low9f1ba562015-07-22 16:17:07 -0700396 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800397
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700398 while (len == orig_len) {
399 if (!AdbReadEndpointSync(handle->adb_read_pipe, data, len, &read, time_out)) {
400 D("AdbReadEndpointSync failed: %s",
401 android::base::SystemErrorCodeToString(GetLastError()).c_str());
402 err = EIO;
403 goto fail;
404 }
405 D("usb_read got: %ld, expected: %d", read, len);
Spencer Low9f1ba562015-07-22 16:17:07 -0700406
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700407 data = (char*)data + read;
408 len -= read;
409 }
410
411 return orig_len - len;
Spencer Low9f1ba562015-07-22 16:17:07 -0700412
413fail:
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700414 // Any failure should cause us to kick the device instead of leaving it a
415 // zombie state with potential to hang.
Yi Kong86e67182018-07-13 18:15:16 -0700416 if (nullptr != handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700417 D("Kicking device due to error in usb_read");
418 usb_kick(handle);
419 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700420
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700421 D("usb_read failed");
422 errno = err;
423 return -1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800424}
425
Spencer Low9f1ba562015-07-22 16:17:07 -0700426// Wrapper around AdbCloseHandle() that logs diagnostics.
427static void _adb_close_handle(ADBAPIHANDLE adb_handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700428 if (!AdbCloseHandle(adb_handle)) {
429 D("AdbCloseHandle(%p) failed: %s", adb_handle,
430 android::base::SystemErrorCodeToString(GetLastError()).c_str());
431 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700432}
433
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800434void usb_cleanup_handle(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700435 D("usb_cleanup_handle");
Yi Kong86e67182018-07-13 18:15:16 -0700436 if (nullptr != handle) {
437 if (nullptr != handle->interface_name) free(handle->interface_name);
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700438 // AdbCloseHandle(pipe) will break any threads out of pending IO calls and
439 // wait until the pipe no longer uses the interface. Then we can
440 // AdbCloseHandle() the interface.
Yi Kong86e67182018-07-13 18:15:16 -0700441 if (nullptr != handle->adb_write_pipe) _adb_close_handle(handle->adb_write_pipe);
442 if (nullptr != handle->adb_read_pipe) _adb_close_handle(handle->adb_read_pipe);
443 if (nullptr != handle->adb_interface) _adb_close_handle(handle->adb_interface);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800444
Yi Kong86e67182018-07-13 18:15:16 -0700445 handle->interface_name = nullptr;
446 handle->adb_write_pipe = nullptr;
447 handle->adb_read_pipe = nullptr;
448 handle->adb_interface = nullptr;
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700449 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800450}
451
Josh Gao3a2172b2019-03-28 15:47:44 -0700452void usb_reset(usb_handle* handle) {
453 // Unimplemented on Windows.
454 usb_kick(handle);
455}
456
Spencer Low9f1ba562015-07-22 16:17:07 -0700457static void usb_kick_locked(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700458 // The reason the lock must be acquired before calling this function is in
459 // case multiple threads are trying to kick the same device at the same time.
460 usb_cleanup_handle(handle);
Spencer Low9f1ba562015-07-22 16:17:07 -0700461}
462
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800463void usb_kick(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700464 D("usb_kick");
Yi Kong86e67182018-07-13 18:15:16 -0700465 if (nullptr != handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700466 std::lock_guard<std::mutex> lock(usb_lock);
467 usb_kick_locked(handle);
468 } else {
469 errno = EINVAL;
470 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800471}
472
473int usb_close(usb_handle* handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700474 D("usb_close");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800475
Yi Kong86e67182018-07-13 18:15:16 -0700476 if (nullptr != handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700477 // Remove handle from the list
478 {
479 std::lock_guard<std::mutex> lock(usb_lock);
Josh Gao511ff8a2017-12-08 13:05:40 -0800480 handle_list.erase(std::remove(handle_list.begin(), handle_list.end(), handle),
481 handle_list.end());
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700482 }
483
484 // Cleanup handle
485 usb_cleanup_handle(handle);
486 free(handle);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800487 }
488
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700489 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800490}
491
Josh Gao3734cf02017-05-02 15:01:09 -0700492size_t usb_get_max_packet_size(usb_handle* handle) {
493 return handle->max_packet_size;
494}
495
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800496int recognized_device(usb_handle* handle) {
Yi Kong86e67182018-07-13 18:15:16 -0700497 if (nullptr == handle) return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800498
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700499 // Check vendor and product id first
500 USB_DEVICE_DESCRIPTOR device_desc;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800501
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700502 if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, &device_desc)) {
503 D("AdbGetUsbDeviceDescriptor failed: %s",
David Pursellc573d522016-01-27 08:52:53 -0800504 android::base::SystemErrorCodeToString(GetLastError()).c_str());
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700505 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800506 }
507
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700508 // Then check interface properties
509 USB_INTERFACE_DESCRIPTOR interf_desc;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800510
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700511 if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, &interf_desc)) {
512 D("AdbGetUsbInterfaceDescriptor failed: %s",
513 android::base::SystemErrorCodeToString(GetLastError()).c_str());
514 return 0;
515 }
516
517 // Must have two endpoints
518 if (2 != interf_desc.bNumEndpoints) {
519 return 0;
520 }
521
Mark Salyzyn21a991d2017-10-04 15:05:40 -0700522 if (!is_adb_interface(interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass,
523 interf_desc.bInterfaceProtocol)) {
524 return 0;
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700525 }
526
Mark Salyzyn21a991d2017-10-04 15:05:40 -0700527 AdbEndpointInformation endpoint_info;
528 // assuming zero is a valid bulk endpoint ID
529 if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) {
530 handle->max_packet_size = endpoint_info.max_packet_size;
531 handle->zero_mask = endpoint_info.max_packet_size - 1;
532 D("device zero_mask: 0x%x", handle->zero_mask);
533 } else {
534 D("AdbGetEndpointInformation failed: %s",
535 android::base::SystemErrorCodeToString(GetLastError()).c_str());
536 }
537
538 return 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800539}
540
541void find_devices() {
Yi Kong86e67182018-07-13 18:15:16 -0700542 usb_handle* handle = nullptr;
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700543 char entry_buffer[2048];
544 AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]);
545 unsigned long entry_buffer_size = sizeof(entry_buffer);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800546
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700547 // Enumerate all present and active interfaces.
548 ADBAPIHANDLE enum_handle = AdbEnumInterfaces(usb_class_id, true, true, true);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800549
Yi Kong86e67182018-07-13 18:15:16 -0700550 if (nullptr == enum_handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700551 D("AdbEnumInterfaces failed: %s",
552 android::base::SystemErrorCodeToString(GetLastError()).c_str());
553 return;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800554 }
555
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700556 while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) {
557 // Lets see if we already have this device in the list
558 if (!known_device(next_interface->device_name)) {
559 // This seems to be a new device. Open it!
560 handle = do_usb_open(next_interface->device_name);
Yi Kong86e67182018-07-13 18:15:16 -0700561 if (nullptr != handle) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700562 // Lets see if this interface (device) belongs to us
563 if (recognized_device(handle)) {
564 D("adding a new device %ls", next_interface->device_name);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800565
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700566 // We don't request a wchar_t string from AdbGetSerialNumber() because of a bug
567 // in adb_winusb_interface.cpp:CopyMemory(buffer, ser_num->bString,
568 // bytes_written) where the last parameter should be (str_len *
569 // sizeof(wchar_t)). The bug reads 2 bytes past the end of a stack buffer in the
570 // best case, and in the unlikely case of a long serial number, it will read 2
571 // bytes past the end of a heap allocation. This doesn't affect the resulting
572 // string, but we should avoid the bad reads in the first place.
573 char serial_number[512];
574 unsigned long serial_number_len = sizeof(serial_number);
575 if (AdbGetSerialNumber(handle->adb_interface, serial_number, &serial_number_len,
576 true)) {
Vince Harron5703eb32021-11-12 12:40:58 -0800577 if (!transport_server_owns_device(serial_number)) {
578 // We aren't allowed to communicate with this device. Don't open this
579 // device.
580 D("ignoring device: not owned by this server serial: '%s'",
581 serial_number);
582 usb_cleanup_handle(handle);
583 free(handle);
584 return;
585 }
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700586 // Lets make sure that we don't duplicate this device
587 if (register_new_device(handle)) {
Yi Kong86e67182018-07-13 18:15:16 -0700588 register_usb_transport(handle, serial_number, nullptr, 1);
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700589 } else {
590 D("register_new_device failed for %ls", next_interface->device_name);
591 usb_cleanup_handle(handle);
592 free(handle);
593 }
594 } else {
595 D("cannot get serial number: %s",
596 android::base::SystemErrorCodeToString(GetLastError()).c_str());
597 usb_cleanup_handle(handle);
598 free(handle);
599 }
600 } else {
601 usb_cleanup_handle(handle);
602 free(handle);
603 }
604 }
605 }
Spencer Low9f1ba562015-07-22 16:17:07 -0700606
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700607 entry_buffer_size = sizeof(entry_buffer);
608 }
609
610 if (GetLastError() != ERROR_NO_MORE_ITEMS) {
611 // Only ERROR_NO_MORE_ITEMS is expected at the end of enumeration.
612 D("AdbNextInterface failed: %s",
613 android::base::SystemErrorCodeToString(GetLastError()).c_str());
614 }
615
616 _adb_close_handle(enum_handle);
Spencer Low9f1ba562015-07-22 16:17:07 -0700617}
618
619static void kick_devices() {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700620 // Need to acquire lock to safely walk the list which might be modified
621 // by another thread.
622 std::lock_guard<std::mutex> lock(usb_lock);
Josh Gao511ff8a2017-12-08 13:05:40 -0800623 for (usb_handle* usb : handle_list) {
Mark Salyzynd4bf94d2017-10-04 15:05:40 -0700624 usb_kick_locked(usb);
625 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800626}