adb.cpp revision bc36bdbdc8bb64011bc573a14d54576946fa1006
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 173313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#define TRACE_TAG TRACE_ADB 183313426fad9eaaf53017cdbde889ebcec91358ecDan Albert 193313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "sysdeps.h" 203313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "adb.h" 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 24ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stdarg.h> 25c7993af64baec271a238646bc20aaa846866c4a9Scott Anderson#include <stddef.h> 26ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stdint.h> 27ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stdio.h> 28ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <stdlib.h> 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 301f546e6d1f6ccd1964336ddf0d8e8b3b11b1e945Mike Lockwood#include <sys/time.h> 31ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <time.h> 32ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 33ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#include <string> 34e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert#include <vector> 35e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert#include <unordered_map> 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 379313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert#include <base/logging.h> 38cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low#include <base/macros.h> 397b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes#include <base/stringprintf.h> 408d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes#include <base/strings.h> 417b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes 42d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#include "adb_auth.h" 43cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_io.h" 44e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#include "adb_listeners.h" 453d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes#include "adb_utils.h" 467664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "transport.h" 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 49e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if !ADB_HOST 51893a4a47e8c9290128b9254af0246e36f821c260Nick Kralevich#include <cutils/properties.h> 52e2864bf727d6a404bd871f063c03e36cc8eedeecNick Kralevich#include <sys/capability.h> 53885342a0f2c834a6b680284047c47c9d04b32565Jeff Sharkey#include <sys/mount.h> 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#if !ADB_HOST 579313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertconst char* adb_device_banner = "device"; 589313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertstatic android::base::LogdLogger gLogdLogger; 591792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#else 601792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertconst char* adb_device_banner = "host"; 61e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#endif 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 639313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid AdbLogger(android::base::LogId id, android::base::LogSeverity severity, 649313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert const char* tag, const char* file, unsigned int line, 659313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert const char* message) { 669313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert android::base::StderrLogger(id, severity, tag, file, line, message); 679313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert#if !ADB_HOST 689313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert gLogdLogger(id, severity, tag, file, line, message); 699313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert#endif 709313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert} 719313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert 7242ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughesstd::string adb_version() { 7342ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes // Don't change the format of this --- it's parsed by ddmlib. 7442ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes return android::base::StringPrintf("Android Debug Bridge version %d.%d.%d\n" 7542ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes "Revision %s\n", 7642ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION, 7742ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes ADB_REVISION); 7842ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes} 7942ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes 809313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid fatal(const char *fmt, ...) { 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list ap; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(ap, fmt); 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "error: "); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vfprintf(stderr, fmt, ap); 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "\n"); 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_end(ap); 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 909313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid fatal_errno(const char* fmt, ...) { 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_list ap; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_start(ap, fmt); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "error: %s: ", strerror(errno)); 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project vfprintf(stderr, fmt, ap); 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "\n"); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project va_end(ap); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 100ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if !ADB_HOST 1019313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertstatic std::string get_log_file_name() { 102ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert struct tm now; 103ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert time_t t; 104ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert tzset(); 105ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert time(&t); 106ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert localtime_r(&t, &now); 107ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 1088743ef98414b336f222327253f2cde6bf6aee386Dan Albert char timestamp[PATH_MAX]; 1098743ef98414b336f222327253f2cde6bf6aee386Dan Albert strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now); 1108743ef98414b336f222327253f2cde6bf6aee386Dan Albert 1119313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert return android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp, 1129313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert getpid()); 1139313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert} 1149313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert 1159313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid start_device_log(void) { 1169313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert int fd = unix_open(get_log_file_name().c_str(), 1179313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640); 118ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert if (fd == -1) { 119ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return; 120ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert } 121ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 1229313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert // Redirect stdout and stderr to the log file. 123ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert dup2(fd, STDOUT_FILENO); 124ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert dup2(fd, STDERR_FILENO); 125ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); 1266ac5d7dc56a016718d2a26803435505e983e5d80Spencer Low unix_close(fd); 127ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert} 128ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif 129ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 130ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertint adb_trace_mask; 131ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 132ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting_from_env() { 133ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert const char* setting = getenv("ADB_TRACE"); 134ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert if (setting == nullptr) { 135ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert setting = ""; 136ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert } 137ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 138ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return std::string(setting); 139ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert} 140ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 141ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if !ADB_HOST 142ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting_from_prop() { 143ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert char buf[PROPERTY_VALUE_MAX]; 144ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert property_get("persist.adb.trace_mask", buf, ""); 145ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return std::string(buf); 146ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert} 147ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif 148ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 149ea2175ab6bae74409620374a96fc9a0097a1845cDan Albertstd::string get_trace_setting() { 150ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#if ADB_HOST 151ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return get_trace_setting_from_env(); 152ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#else 153ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert return get_trace_setting_from_prop(); 154ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif 155ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert} 156ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 157e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert// Split the space separated list of tags from the trace setting and build the 158e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert// trace mask from it. note that '1' and 'all' are special cases to enable all 159e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert// tracing. 160ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// 161ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// adb's trace setting comes from the ADB_TRACE environment variable, whereas 162ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert// adbd's comes from the system property persist.adb.trace_mask. 1639313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertstatic void setup_trace_mask() { 164ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert const std::string trace_setting = get_trace_setting(); 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 166e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert std::unordered_map<std::string, int> trace_flags = { 167e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"1", 0}, 168e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"all", 0}, 169e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"adb", TRACE_ADB}, 170e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"sockets", TRACE_SOCKETS}, 171e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"packets", TRACE_PACKETS}, 172e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"rwx", TRACE_RWX}, 173e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"usb", TRACE_USB}, 174e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"sync", TRACE_SYNC}, 175e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"sysdeps", TRACE_SYSDEPS}, 176e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"transport", TRACE_TRANSPORT}, 177e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"jdwp", TRACE_JDWP}, 178e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert {"services", TRACE_SERVICES}, 17980f67029e002a97dd4f752881d820b3161f729f1David Pursell {"auth", TRACE_AUTH}, 180a10801674cb9e23ae549fb7f861cb33d8c629e80Yabin Cui {"fdevent", TRACE_FDEVENT}, 18180f67029e002a97dd4f752881d820b3161f729f1David Pursell {"shell", TRACE_SHELL}}; 182e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert 183e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert std::vector<std::string> elements = android::base::Split(trace_setting, " "); 184e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert for (const auto& elem : elements) { 185e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert const auto& flag = trace_flags.find(elem); 186e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert if (flag == trace_flags.end()) { 1877a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Unknown trace flag: %s", flag->first.c_str()); 188e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert continue; 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 190e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert 191e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert if (flag->second == 0) { 192e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert // 0 is used for the special values "1" and "all" that enable all 193e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert // tracing. 194e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert adb_trace_mask = ~0; 195e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert return; 196e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert } else { 197e246219d0c9897b1c08204d6c535d5d341c4e7eeDan Albert adb_trace_mask |= 1 << flag->second; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 2009313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert} 201ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert 2029313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albertvoid adb_trace_init(char** argv) { 2037430916098fd264d569d398614d1d725adfca165Spencer Low#if !ADB_HOST 2046f009d9496fc060ba76f97348aa0702a62fcf927Paul Lawrence // Don't open log file if no tracing, since this will block 2056f009d9496fc060ba76f97348aa0702a62fcf927Paul Lawrence // the crypto unmount of /data 2067430916098fd264d569d398614d1d725adfca165Spencer Low if (!get_trace_setting().empty()) { 2077430916098fd264d569d398614d1d725adfca165Spencer Low if (isatty(STDOUT_FILENO) == 0) { 2087430916098fd264d569d398614d1d725adfca165Spencer Low start_device_log(); 2097430916098fd264d569d398614d1d725adfca165Spencer Low } 2109313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert } 211ea2175ab6bae74409620374a96fc9a0097a1845cDan Albert#endif 2129313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert 2139313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert setup_trace_mask(); 2149313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert android::base::InitLogging(argv, AdbLogger); 21542ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes 21642ae2604f43ef88be748f125e8733f2c08b83faeElliott Hughes D("%s", adb_version().c_str()); 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 219bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albertapacket* get_apacket(void) 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 221bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket))); 222bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (p == nullptr) { 223bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert fatal("failed to allocate an apacket"); 224bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 225bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memset(p, 0, sizeof(apacket) - MAX_PAYLOAD); 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return p; 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid put_apacket(apacket *p) 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(p); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 235d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Gobyvoid handle_online(atransport *t) 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2377a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("adb: online"); 238d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby t->online = 1; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_offline(atransport *t) 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2437a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("adb: offline"); 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //Close the associated usb 245d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby t->online = 0; 24634f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui 247b329824e6c5373ae303269dca285d835ce57e514Yabin Cui // This is necessary to avoid a race condition that occurred when a transport closes 24834f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui // while a client socket is still active. 24934f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui close_all_sockets(t); 25034f45c566365c966c78264e8a4dc0cf69957b6faYabin Cui 251b329824e6c5373ae303269dca285d835ce57e514Yabin Cui t->RunDisconnects(); 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby#if DEBUG_PACKETS 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DUMPMAX 32 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid print_packet(const char *label, apacket *p) 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *tag; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *x; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(p->msg.command){ 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_SYNC: tag = "SYNC"; break; 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_CNXN: tag = "CNXN" ; break; 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OPEN: tag = "OPEN"; break; 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OKAY: tag = "OKAY"; break; 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_CLSE: tag = "CLSE"; break; 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_WRTE: tag = "WRTE"; break; 269d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby case A_AUTH: tag = "AUTH"; break; 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: tag = "????"; break; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s: %s %08x %08x %04x \"", 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length); 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = p->msg.data_length; 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = (char*) p->data; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(count > DUMPMAX) { 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = DUMPMAX; 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tag = "\n"; 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tag = "\"\n"; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count-- > 0){ 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((*x >= ' ') && (*x < 127)) { 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fputc(*x, stderr); 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fputc('.', stderr); 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x++; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 291d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby fputs(tag, stderr); 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_ready(unsigned local, unsigned remote, atransport *t) 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2977a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Calling send_ready"); 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_OKAY; 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = local; 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = remote; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void send_close(unsigned local, unsigned remote, atransport *t) 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 3077a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Calling send_close"); 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project apacket *p = get_apacket(); 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.command = A_CLSE; 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg0 = local; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->msg.arg1 = remote; 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3151792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertstd::string get_connection_string() { 3161792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert std::vector<std::string> connection_properties; 3171792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3181792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#if !ADB_HOST 3191792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert static const char* cnxn_props[] = { 320e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson "ro.product.name", 321e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson "ro.product.model", 322e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson "ro.product.device", 323e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson }; 3241792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3251792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert for (const auto& prop_name : cnxn_props) { 326e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson char value[PROPERTY_VALUE_MAX]; 3271792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert property_get(prop_name, value, ""); 3281792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert connection_properties.push_back( 3291792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert android::base::StringPrintf("%s=%s", prop_name, value)); 330e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson } 331e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson#endif 3321792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3331792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert connection_properties.push_back(android::base::StringPrintf( 3341792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert "features=%s", android::base::Join(supported_features(), ',').c_str())); 3351792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3361792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert return android::base::StringPrintf( 3371792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert "%s::%s", adb_device_banner, 3381792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert android::base::Join(connection_properties, ';').c_str()); 339e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson} 340e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson 3411792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertvoid send_connect(atransport* t) { 3427a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Calling send_connect"); 3431792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert apacket* cp = get_apacket(); 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cp->msg.command = A_CNXN; 3453d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer cp->msg.arg0 = t->get_protocol_version(); 3463d2904cdf2371e26c0465184436bd063979a5d97Tamas Berghammer cp->msg.arg1 = t->get_max_payload(); 3471792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3481792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert std::string connection_str = get_connection_string(); 3491792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert // Connect and auth packets are limited to MAX_PAYLOAD_V1 because we don't 3501792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert // yet know how much data the other size is willing to accept. 3511792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert if (connection_str.length() > MAX_PAYLOAD_V1) { 3521792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert LOG(FATAL) << "Connection banner is too long (length = " 3531792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert << connection_str.length() << ")"; 3541792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert } 3551792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 3561792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert memcpy(cp->data, connection_str.c_str(), connection_str.length()); 3571792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert cp->msg.data_length = connection_str.length(); 3581792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(cp, t); 360d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby} 361d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 3628d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// qual_overwrite is used to overwrite a qualifier string. dst is a 3638d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// pointer to a char pointer. It is assumed that if *dst is non-NULL, it 3648d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// was malloc'ed and needs to freed. *dst will be set to a dup of src. 3658d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes// TODO: switch to std::string for these atransport fields instead. 3668d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughesstatic void qual_overwrite(char** dst, const std::string& src) { 367e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson free(*dst); 3688d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes *dst = strdup(src.c_str()); 369e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson} 370e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson 3711792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertvoid parse_banner(const std::string& banner, atransport* t) { 3727a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("parse_banner: %s", banner.c_str()); 3738d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 3748d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes // The format is something like: 3758d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes // "device::ro.product.name=x;ro.product.model=y;ro.product.device=z;". 3768d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes std::vector<std::string> pieces = android::base::Split(banner, ":"); 3778d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 3788d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (pieces.size() > 2) { 3798d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes const std::string& props = pieces[2]; 3808d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes for (auto& prop : android::base::Split(props, ";")) { 3818d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes // The list of properties was traditionally ;-terminated rather than ;-separated. 3828d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (prop.empty()) continue; 3838d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 3848d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes std::vector<std::string> key_value = android::base::Split(prop, "="); 3858d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (key_value.size() != 2) continue; 3868d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes 3878d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes const std::string& key = key_value[0]; 3888d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes const std::string& value = key_value[1]; 3898d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (key == "ro.product.name") { 3908d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes qual_overwrite(&t->product, value); 3918d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (key == "ro.product.model") { 3928d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes qual_overwrite(&t->model, value); 3938d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (key == "ro.product.device") { 3948d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes qual_overwrite(&t->device, value); 3951792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert } else if (key == "features") { 3961792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert for (const auto& feature : android::base::Split(value, ",")) { 3971792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert t->add_feature(feature); 3981792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert } 399e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson } 400e82c2db05cae70a0490a1f84b7211ef42c329671Scott Anderson } 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4038d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes const std::string& type = pieces[0]; 4048d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes if (type == "bootloader") { 4057a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("setting connection_state to kCsBootloader"); 406dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert t->connection_state = kCsBootloader; 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 4088d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (type == "device") { 4097a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("setting connection_state to kCsDevice"); 410dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert t->connection_state = kCsDevice; 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 4128d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (type == "recovery") { 4137a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("setting connection_state to kCsRecovery"); 414dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert t->connection_state = kCsRecovery; 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project update_transports(); 4168d5fa6da44d56511b3e173bc463cbc65ff221b4aElliott Hughes } else if (type == "sideload") { 4177a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("setting connection_state to kCsSideload"); 418dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert t->connection_state = kCsSideload; 419447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker update_transports(); 4203ce9575af76fa6dc110506080434303b9459abf4Elliott Hughes } else { 4217a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("setting connection_state to kCsHost"); 422dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert t->connection_state = kCsHost; 423447f061da19fe46bae35f1cdd93eeb16bc225463Doug Zongker } 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4261792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albertstatic void handle_new_connection(atransport* t, apacket* p) { 4271792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert if (t->connection_state != kCsOffline) { 4281792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert t->connection_state = kCsOffline; 4291792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert handle_offline(t); 4301792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert } 4311792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 4321792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert t->update_version(p->msg.arg0, p->msg.arg1); 4331792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert std::string banner(reinterpret_cast<const char*>(p->data), 4341792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert p->msg.data_length); 4351792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert parse_banner(banner, t); 4361792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 4371792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#if ADB_HOST 4381792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert handle_online(t); 4391792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#else 4401792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert if (!auth_required) { 4411792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert handle_online(t); 4421792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert send_connect(t); 4431792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert } else { 4441792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert send_auth_request(t); 4451792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert } 4461792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert#endif 4471792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert} 4481792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid handle_packet(apacket *p, atransport *t) 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asocket *s; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4537a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("handle_packet() %c%c%c%c", ((char*) (&(p->msg.command)))[0], 454899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta ((char*) (&(p->msg.command)))[1], 455899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta ((char*) (&(p->msg.command)))[2], 456899913f8168b54e00971c0e8d4ae16d06a4651feViral Mehta ((char*) (&(p->msg.command)))[3]); 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print_packet("recv", p); 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(p->msg.command){ 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_SYNC: 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(p->msg.arg0){ 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 463661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#if ADB_HOST 464661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui send_connect(t); 465661327e8e40f95076e0e8abe86193da16b061bd8Yabin Cui#endif 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 467dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert t->connection_state = kCsOffline; 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project handle_offline(t); 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_packet(p, t); 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4731792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert case A_CNXN: // CONNECT(version, maxdata, "system-id-string") 4741792c23cb892ab58590b2cdfce0d0ece30c21787Dan Albert handle_new_connection(t, p); 475d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby break; 476d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby 477d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby case A_AUTH: 478d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (p->msg.arg0 == ADB_AUTH_TOKEN) { 479dcd78a15d0be143d48fc93af6a9fa5748dbf9790Dan Albert t->connection_state = kCsUnauthorized; 480d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby t->key = adb_auth_nextkey(t->key); 481d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (t->key) { 482d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby send_auth_response(p->data, p->msg.data_length, t); 483d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else { 484d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby /* No more private keys to try, send the public key */ 485d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby send_auth_publickey(t); 486d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } 487d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) { 488d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (adb_auth_verify(t->token, p->data, p->msg.data_length)) { 489d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby adb_auth_verified(t); 490d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby t->failed_auth_attempts = 0; 491d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else { 492d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby if (t->failed_auth_attempts++ > 10) 493d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby adb_sleep_ms(1000); 494d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby send_auth_request(t); 495d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } 496d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) { 497d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby adb_auth_confirm_key(p->data, p->msg.data_length, t); 498d5fcafaf41f8ec90986c813f75ec78402096af2dBenoit Goby } 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OPEN: /* OPEN(local-id, 0, "destination") */ 502818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) { 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *name = (char*) p->data; 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; 5050955c66b226db7a7f34613f834f7b0a145fd407dDavid Pursell s = create_local_service_socket(name, t); 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s == 0) { 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_close(0, p->msg.arg0, t); 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = create_remote_socket(p->msg.arg0, t); 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = s; 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_ready(s->id, s->peer->id, t); 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->ready(s); 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case A_OKAY: /* READY(local-id, remote-id, "") */ 518818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) { 519818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if((s = find_local_socket(p->msg.arg1, 0))) { 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->peer == 0) { 521818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner /* On first READY message, create the connection. */ 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer = create_remote_socket(p->msg.arg0, t); 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project s->peer->peer = s; 524818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->ready(s); 525818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } else if (s->peer->id == p->msg.arg0) { 526818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner /* Other READY messages must use the same local-id */ 527818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->ready(s); 528818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } else { 5297a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s", 530818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial); 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 536818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */ 537818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (t->online && p->msg.arg1 != 0) { 538818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) { 539818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner /* According to protocol.txt, p->msg.arg0 might be 0 to indicate 540818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * a failed OPEN only. However, due to a bug in previous ADB 541818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * versions, CLOSE(0, remote-id, "") was also used for normal 542818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * CLOSE() operations. 543818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * 544818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * This is bad because it means a compromised adbd could 545818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * send packets to close connections between the host and 546818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * other devices. To avoid this, only allow this if the local 547818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner * socket has a peer on the same transport. 548818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner */ 549818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) { 5507a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s", 551818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner p->msg.arg1, t->serial, s->peer->transport->serial); 552818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } else { 553818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner s->close(s); 554818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner } 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 559818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner case A_WRTE: /* WRITE(local-id, remote-id, <data>) */ 560818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) { 561818d641c420f5d4f35f4e8706937c17b974146d1David 'Digit' Turner if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) { 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned rid = p->msg.arg0; 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p->len = p->msg.data_length; 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(s->enqueue(s, p) == 0) { 5667a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Enqueue the socket"); 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project send_ready(s->id, rid, t); 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("handle_packet: what is %08x?!\n", p->msg.command); 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project put_apacket(p); 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 582571c1367682c83cb23481cc9c1028c8588a1fed0JP Abgrall 5832122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low#ifdef _WIN32 5842122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 585bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// Try to make a handle non-inheritable and if there is an error, don't output 586bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// any error info, but leave GetLastError() for the caller to read. This is 587bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// convenient if the caller is expecting that this may fail and they'd like to 588bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// ignore such a failure. 589bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Lowstatic bool _try_make_handle_noninheritable(HANDLE h) { 5902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (h != INVALID_HANDLE_VALUE && h != NULL) { 591bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low return SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0) ? true : false; 592bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low } 593bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low 594bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low return true; 595bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low} 596bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low 597bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// Try to make a handle non-inheritable with the expectation that this should 598bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low// succeed, so if this fails, output error info. 599bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Lowstatic bool _make_handle_noninheritable(HANDLE h) { 600bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low if (!_try_make_handle_noninheritable(h)) { 601bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low // Show the handle value to give us a clue in case we have problems 602bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low // with pseudo-handle values. 603bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low fprintf(stderr, "Cannot make handle 0x%p non-inheritable: %s\n", 604bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low h, SystemErrorCodeToString(GetLastError()).c_str()); 605bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low return false; 6062122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6072122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return true; 6092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 6102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low// Create anonymous pipe, preventing inheritance of the read pipe and setting 6122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low// security of the write pipe to sa. 6132122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic bool _create_anonymous_pipe(unique_handle* pipe_read_out, 6142122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle* pipe_write_out, 6152122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low SECURITY_ATTRIBUTES* sa) { 6162122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low HANDLE pipe_read_raw = NULL; 6172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low HANDLE pipe_write_raw = NULL; 6182122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!CreatePipe(&pipe_read_raw, &pipe_write_raw, sa, 0)) { 6192122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Cannot create pipe: %s\n", 6202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low SystemErrorCodeToString(GetLastError()).c_str()); 6212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return false; 6222122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6232122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6242122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle pipe_read(pipe_read_raw); 6252122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low pipe_read_raw = NULL; 6262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle pipe_write(pipe_write_raw); 6272122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low pipe_write_raw = NULL; 6282122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6292122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!_make_handle_noninheritable(pipe_read.get())) { 6302122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return false; 6312122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6322122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6332122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low *pipe_read_out = std::move(pipe_read); 6342122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low *pipe_write_out = std::move(pipe_write); 6352122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6362122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return true; 6372122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 6382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6392122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low// Read from a pipe (that we take ownership of) and write what is returned to 6402122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low// GetStdHandle(nStdHandle). Return on error or when the pipe is closed. 6412122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic unsigned _redirect_pipe_thread(HANDLE h, DWORD nStdHandle) { 6422122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Take ownership of the HANDLE and close when we're done. 6432122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle read_pipe(h); 6442122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const HANDLE write_handle = GetStdHandle(nStdHandle); 6452122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const char* output_name = nStdHandle == STD_OUTPUT_HANDLE ? 6462122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low "stdout" : "stderr"; 6472122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6482122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low while (true) { 6492122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low char buf[64 * 1024]; 6502122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low DWORD bytes_read = 0; 6512122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!ReadFile(read_pipe.get(), buf, sizeof(buf), &bytes_read, NULL)) { 6522122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const DWORD err = GetLastError(); 6532122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // ERROR_BROKEN_PIPE is expected when the subprocess closes 6542122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // the other end of the pipe. 6552122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (err == ERROR_BROKEN_PIPE) { 6562122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return EXIT_SUCCESS; 6572122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } else { 6582122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Failed to read from %s: %s\n", output_name, 6592122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low SystemErrorCodeToString(err).c_str()); 6602122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return EXIT_FAILURE; 6612122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6622122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6632122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6642122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Don't try to write if our stdout/stderr was not setup by the 6652122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // parent process. 6662122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (write_handle != NULL && write_handle != INVALID_HANDLE_VALUE) { 6672122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low DWORD bytes_written = 0; 6682122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!WriteFile(write_handle, buf, bytes_read, &bytes_written, 6692122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low NULL)) { 6702122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Failed to write to %s: %s\n", output_name, 6712122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low SystemErrorCodeToString(GetLastError()).c_str()); 6722122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return EXIT_FAILURE; 6732122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6742122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6752122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (bytes_written != bytes_read) { 6762122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Only wrote %lu of %lu bytes to %s\n", 6772122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low bytes_written, bytes_read, output_name); 6782122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return EXIT_FAILURE; 6792122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6802122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6812122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 6822122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 6832122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6842122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic unsigned __stdcall _redirect_stdout_thread(HANDLE h) { 68549ee7cf9a10f66ffa9a3490c69db5fa46e0a966bSiva Velusamy adb_thread_setname("stdout redirect"); 6862122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return _redirect_pipe_thread(h, STD_OUTPUT_HANDLE); 6872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 6882122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6892122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Lowstatic unsigned __stdcall _redirect_stderr_thread(HANDLE h) { 69049ee7cf9a10f66ffa9a3490c69db5fa46e0a966bSiva Velusamy adb_thread_setname("stderr redirect"); 6912122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return _redirect_pipe_thread(h, STD_ERROR_HANDLE); 6922122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low} 6932122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 6942122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low#endif 6952122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 696a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzingerint launch_server(int server_port) 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 698e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#if defined(_WIN32) 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we need to start the server in the background */ 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we create a PIPE that will be used to wait for the server's "OK" */ 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* message since the pipe handles must be inheritable, we use a */ 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* security attribute */ 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SECURITY_ATTRIBUTES sa; 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sa.nLength = sizeof(sa); 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sa.lpSecurityDescriptor = NULL; 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sa.bInheritHandle = TRUE; 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Redirect stdin to Windows /dev/null. If we instead pass an original 7092122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // stdin/stdout/stderr handle and it is a console handle, when the adb 7102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // server starts up, the C Runtime will see a console handle for a process 7112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // that isn't connected to a console and it will configure 7122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // stdin/stdout/stderr to be closed. At that point, freopen() could be used 7132122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // to reopen stderr/out, but it would take more massaging to fixup the file 7142122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // descriptor number that freopen() uses. It's simplest to avoid all of this 7152122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // complexity by just redirecting stdin to `nul' and then the C Runtime acts 7162122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // as expected. 7172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle nul_read(CreateFileW(L"nul", GENERIC_READ, 7182122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 7192122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low FILE_ATTRIBUTE_NORMAL, NULL)); 7202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (nul_read.get() == INVALID_HANDLE_VALUE) { 7212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Cannot open 'nul': %s\n", 7228df90321769c670b546a7ff0e7a14f2d7a79cc25Spencer Low SystemErrorCodeToString(GetLastError()).c_str()); 723d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low return -1; 724d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low } 725d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low 7262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // create pipes with non-inheritable read handle, inheritable write handle 7272122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle ack_read, ack_write; 7282122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!_create_anonymous_pipe(&ack_read, &ack_write, &sa)) { 729d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low return -1; 730d0f66c361641dc30162877ee3e4b4690d6833442Spencer Low } 7312122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle stdout_read, stdout_write; 7322122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!_create_anonymous_pipe(&stdout_read, &stdout_write, &sa)) { 7332122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return -1; 7342122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 7352122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle stderr_read, stderr_write; 7362122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!_create_anonymous_pipe(&stderr_read, &stderr_write, &sa)) { 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 740267aa8b00eadf273321e492026af74b7baad890eRay Donnelly /* Some programs want to launch an adb command and collect its output by 741267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * calling CreateProcess with inheritable stdout/stderr handles, then 742267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * using read() to get its output. When this happens, the stdout/stderr 743267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * handles passed to the adb client process will also be inheritable. 744267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * When starting the adb server here, care must be taken to reset them 745267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * to non-inheritable. 746267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * Otherwise, something bad happens: even if the adb command completes, 747267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * the calling process is stuck while read()-ing from the stdout/stderr 748267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * descriptors, because they're connected to corresponding handles in the 749267aa8b00eadf273321e492026af74b7baad890eRay Donnelly * adb server process (even if the latter never uses/writes to them). 7502122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low * Note that even if we don't pass these handles in the STARTUPINFO struct, 7512122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low * if they're marked inheritable, they're still inherited, requiring us to 7522122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low * deal with this. 7532122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low * 7542122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low * If we're still having problems with inheriting random handles in the 7552122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low * future, consider using PROC_THREAD_ATTRIBUTE_HANDLE_LIST to explicitly 7562122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low * specify which handles should be inherited: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx 757bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low * 758bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low * Older versions of Windows return console pseudo-handles that cannot be 759bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low * made non-inheritable, so ignore those failures. 760267aa8b00eadf273321e492026af74b7baad890eRay Donnelly */ 761bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low _try_make_handle_noninheritable(GetStdHandle(STD_INPUT_HANDLE)); 762bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low _try_make_handle_noninheritable(GetStdHandle(STD_OUTPUT_HANDLE)); 763bc36bdbdc8bb64011bc573a14d54576946fa1006Spencer Low _try_make_handle_noninheritable(GetStdHandle(STD_ERROR_HANDLE)); 764267aa8b00eadf273321e492026af74b7baad890eRay Donnelly 7652122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low STARTUPINFOW startup; 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ZeroMemory( &startup, sizeof(startup) ); 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.cb = sizeof(startup); 7682122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low startup.hStdInput = nul_read.get(); 7692122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low startup.hStdOutput = stdout_write.get(); 7702122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low startup.hStdError = stderr_write.get(); 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project startup.dwFlags = STARTF_USESTDHANDLES; 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7735c398d2ce96150e94e596e959bfe2246b94de660Spencer Low // Verify that the pipe_write handle value can be passed on the command line 7745c398d2ce96150e94e596e959bfe2246b94de660Spencer Low // as %d and that the rest of adb code can pass it around in an int. 7752122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const int ack_write_as_int = cast_handle_to_int(ack_write.get()); 7762122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (cast_int_to_handle(ack_write_as_int) != ack_write.get()) { 7775c398d2ce96150e94e596e959bfe2246b94de660Spencer Low // If this fires, either handle values are larger than 32-bits or else 7785c398d2ce96150e94e596e959bfe2246b94de660Spencer Low // there is a bug in our casting. 7795c398d2ce96150e94e596e959bfe2246b94de660Spencer Low // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx 7802122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Cannot fit pipe handle value into 32-bits: 0x%p\n", 7812122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ack_write.get()); 7825c398d2ce96150e94e596e959bfe2246b94de660Spencer Low return -1; 7835c398d2ce96150e94e596e959bfe2246b94de660Spencer Low } 7845c398d2ce96150e94e596e959bfe2246b94de660Spencer Low 7852122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // get path of current program 7862122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low WCHAR program_path[MAX_PATH]; 7872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const DWORD module_result = GetModuleFileNameW(NULL, program_path, 7882122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low arraysize(program_path)); 7892122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if ((module_result >= arraysize(program_path)) || (module_result == 0)) { 7902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // String truncation or some other error. 7912122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Cannot get executable path: %s\n", 7922122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low SystemErrorCodeToString(GetLastError()).c_str()); 7932122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return -1; 7942122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 7952122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 7962122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low WCHAR args[64]; 797cf4ff64f2d3cdc4ffa2f06e594d18a965f591a82Spencer Low snwprintf(args, arraysize(args), 7985c398d2ce96150e94e596e959bfe2246b94de660Spencer Low L"adb -P %d fork-server server --reply-fd %d", server_port, 7992122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ack_write_as_int); 8002122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low PROCESS_INFORMATION pinfo; 8022122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ZeroMemory(&pinfo, sizeof(pinfo)); 8032122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8042122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!CreateProcessW( 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project program_path, /* program path */ 806a09558c2e205771e6830eeb6241c5c0e3b1cf4ceWenhao Li args, 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* the fork-server argument will set the 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project debug = 2 in the child */ 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* process handle is not inheritable */ 810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* thread handle is not inheritable */ 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project TRUE, /* yes, inherit some handles */ 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DETACHED_PROCESS, /* the new process doesn't have a console */ 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* use parent's environment block */ 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project NULL, /* use parent's starting directory */ 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project &startup, /* startup info, i.e. std handles */ 8162122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low &pinfo )) { 8172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Cannot create process: %s\n", 8182122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low SystemErrorCodeToString(GetLastError()).c_str()); 8192122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return -1; 8202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8222122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle process_handle(pinfo.hProcess); 8232122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low pinfo.hProcess = NULL; 8242122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8252122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Close handles that we no longer need to complete the rest. 8262122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low CloseHandle(pinfo.hThread); 8272122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low pinfo.hThread = NULL; 8282122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8292122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low nul_read.reset(); 8302122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low ack_write.reset(); 8312122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low stdout_write.reset(); 8322122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low stderr_write.reset(); 8332122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8342122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Start threads to read from subprocess stdout/stderr and write to ours 8352122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // to make subprocess errors easier to diagnose. 8362122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8372122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // In the past, reading from a pipe before the child process's C Runtime 8382122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // started up and called GetFileType() caused a hang: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx#10244216 8392122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // This is reportedly fixed in Windows Vista: https://support.microsoft.com/en-us/kb/2009703 8402122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // I was unable to reproduce the problem on Windows XP. It sounds like a 8412122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Windows Update may have fixed this: https://www.duckware.com/tech/peeknamedpipe.html 8422122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle stdout_thread(reinterpret_cast<HANDLE>( 8432122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low _beginthreadex(NULL, 0, _redirect_stdout_thread, stdout_read.get(), 8442122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 0, NULL))); 8452122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (stdout_thread.get() == nullptr) { 8462122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Cannot create thread: %s\n", strerror(errno)); 8472122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return -1; 8482122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 8492122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low stdout_read.release(); // Transfer ownership to new thread 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8512122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low unique_handle stderr_thread(reinterpret_cast<HANDLE>( 8522122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low _beginthreadex(NULL, 0, _redirect_stderr_thread, stderr_read.get(), 8532122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 0, NULL))); 8542122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (stderr_thread.get() == nullptr) { 8552122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Cannot create thread: %s\n", strerror(errno)); 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 8582122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low stderr_read.release(); // Transfer ownership to new thread 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8602122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low bool got_ack = false; 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8622122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Wait for the "OK\n" message, for the pipe to be closed, or other error. 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 8642122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low char temp[3]; 8652122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low DWORD count = 0; 8662122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8672122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (ReadFile(ack_read.get(), temp, sizeof(temp), &count, NULL)) { 8682122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const CHAR expected[] = "OK\n"; 8692122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const DWORD expected_length = arraysize(expected) - 1; 8702122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (count == expected_length && 8712122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low memcmp(temp, expected, expected_length) == 0) { 8722122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low got_ack = true; 8732122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } else { 8742122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "ADB server didn't ACK\n"); 8752122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 8762122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } else { 8772122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const DWORD err = GetLastError(); 8782122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // If the ACK was not written and the process exited, GetLastError() 8792122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // is probably ERROR_BROKEN_PIPE, in which case that info is not 8802122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // useful to the user. 8812122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "could not read ok from ADB Server%s\n", 8822122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low err == ERROR_BROKEN_PIPE ? "" : 8832122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low android::base::StringPrintf(": %s", 8842122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low SystemErrorCodeToString(err).c_str()).c_str()); 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 8862122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 8872122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 8882122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Always try to wait a bit for threads reading stdout/stderr to finish. 8892122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // If the process started ok, it should close the pipes causing the threads 8902122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // to finish. If the process had an error, it should exit, also causing 8912122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // the pipes to be closed. In that case we want to read all of the output 8922122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // and write it out so that the user can diagnose failures. 8932122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const DWORD thread_timeout_ms = 15 * 1000; 8942122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const HANDLE threads[] = { stdout_thread.get(), stderr_thread.get() }; 8952122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low const DWORD wait_result = WaitForMultipleObjects(arraysize(threads), 8962122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low threads, TRUE, thread_timeout_ms); 8972122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (wait_result == WAIT_TIMEOUT) { 8982122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Threads did not finish after waiting a little while. Perhaps the 8992122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // server didn't close pipes, or it is hung. 9002122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Timed-out waiting for threads to finish reading from " 9012122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low "ADB Server\n"); 9022122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // Process handles are signaled when the process exits, so if we wait 9032122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // on the handle for 0 seconds and it returns 'timeout', that means that 9042122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // the process is still running. 9052122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (WaitForSingleObject(process_handle.get(), 0) == WAIT_TIMEOUT) { 9062122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // We could TerminateProcess(), but that seems somewhat presumptive. 9072122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "ADB Server is running: process id %lu\n", 9082122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low pinfo.dwProcessId); 909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 9102122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return -1; 9112122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 9122122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 9132122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (wait_result != WAIT_OBJECT_0) { 9142122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low fprintf(stderr, "Unexpected result waiting for threads: %lu: %s\n", 9152122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low wait_result, SystemErrorCodeToString(GetLastError()).c_str()); 9162122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return -1; 9172122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low } 9182122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 9192122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low // For now ignore the thread exit codes and assume they worked properly. 9202122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low 9212122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low if (!got_ack) { 9222122c7a1483dc6050b33f58fad4a15d5acd79fddSpencer Low return -1; 923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 924e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#else /* !defined(_WIN32) */ 925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char path[PATH_MAX]; 926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd[2]; 927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // set up a pipe so the child can tell us when it is ready. 9299f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy // fd[0] will be parent's end, and the child will write on fd[1] 930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pipe(fd)) { 931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); 932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 9343166410a82f43d39201be98a8d35c51baa86cb53Alexey Tarasov get_my_path(path, PATH_MAX); 935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pid_t pid = fork(); 936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(pid < 0) return -1; 937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pid == 0) { 939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // child side of the fork 940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd[0]); 942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 943d7b33085117ccbb908a883f624cb1fe5495ee92aMatt Gumbel char str_port[30]; 9449f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy snprintf(str_port, sizeof(str_port), "%d", server_port); 9459f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy char reply_fd[30]; 9469f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]); 947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // child process 9489f2d1a9cfc04e1d5970823da1878097288a9a9cdSiva Velusamy int result = execl(path, "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL); 949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // this should not return 950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); 951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // parent side of the fork 953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char temp[3]; 955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; 957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // wait for the "OK\n" message 958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd[1]); 959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret = adb_read(fd[0], temp, 3); 960408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_errno = errno; 961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd[0]); 962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret < 0) { 963408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); 964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { 967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "ADB server didn't ACK\n" ); 968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsid(); 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 973e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#endif /* !defined(_WIN32) */ 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 976e77b6a08623bba383ce55cd6653bec76cdf57792Yabin Cui#endif /* ADB_HOST */ 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 978252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// Try to handle a network forwarding request. 979252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// This returns 1 on success, 0 on failure, and -1 to indicate this is not 980252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner// a forwarding-related request. 981aee80fb67bcc3fc5209050c40bd8efc1bbcc0610Elliott Hughesint handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd) 982252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner{ 983252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (!strcmp(service, "list-forward")) { 984252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner // Create the list of forward redirections. 985e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes std::string listeners = format_listeners(); 986252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST 987e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(reply_fd); 988252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 989e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendProtocolString(reply_fd, listeners); 990252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 991252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 992252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 993252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (!strcmp(service, "killforward-all")) { 994252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner remove_all_listeners(); 995252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST 996252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner /* On the host: 1st OKAY is connect, 2nd OKAY is status */ 997e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(reply_fd); 998252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 999e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(reply_fd); 1000252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 1001252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1002252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 1003424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (!strncmp(service, "forward:", 8) || !strncmp(service, "killforward:", 12)) { 1004424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes // killforward:local 1005424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes // forward:(norebind:)?local;remote 1006424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes bool kill_forward = false; 1007424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes bool no_rebind = false; 1008424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (android::base::StartsWith(service, "killforward:")) { 1009424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes kill_forward = true; 1010424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes service += 12; 1011a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low } else { 1012a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low service += 8; // skip past "forward:" 1013424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (android::base::StartsWith(service, "norebind:")) { 1014424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes no_rebind = true; 1015424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes service += 9; 1016424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes } 1017252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1018252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 1019424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes std::vector<std::string> pieces = android::base::Split(service, ";"); 1020252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 1021424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (kill_forward) { 1022424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes // Check killforward: parameter format: '<local>' 1023424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (pieces.size() != 1 || pieces[0].empty()) { 1024424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes SendFail(reply_fd, android::base::StringPrintf("bad killforward: %s", service)); 1025252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 1026252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1027252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } else { 1028424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes // Check forward: parameter format: '<local>;<remote>' 1029424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (pieces.size() != 2 || pieces[0].empty() || pieces[1].empty() || pieces[1][0] == '*') { 1030424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes SendFail(reply_fd, android::base::StringPrintf("bad forward: %s", service)); 1031252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 1032252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1033252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1034252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 10357be29c819b4fb8bf9b1d4b69a4333f8765de0281Elliott Hughes std::string error_msg; 1036424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes atransport* transport = acquire_one_transport(kCsAny, type, serial, &error_msg); 1037252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (!transport) { 1038e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(reply_fd, error_msg); 1039252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 1040252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1041252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 10425200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low std::string error; 10433bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes InstallStatus r; 1044424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (kill_forward) { 1045424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes r = remove_listener(pieces[0].c_str(), transport); 1046252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } else { 10475200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low r = install_listener(pieces[0], pieces[1].c_str(), transport, 10485200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low no_rebind, &error); 1049252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 10507b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes if (r == INSTALL_STATUS_OK) { 1051252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#if ADB_HOST 1052252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner /* On the host: 1st OKAY is connect, 2nd OKAY is status */ 1053e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(reply_fd); 1054252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner#endif 1055e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(reply_fd); 1056252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 1057252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1058252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 10597b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes std::string message; 10607b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes switch (r) { 1061424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes case INSTALL_STATUS_OK: message = "success (!)"; break; 10627b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes case INSTALL_STATUS_INTERNAL_ERROR: message = "internal error"; break; 10637b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes case INSTALL_STATUS_CANNOT_BIND: 1064bf7c605d87f87c03066c384cecb0f0c91aa31403Spencer Low message = android::base::StringPrintf("cannot bind listener: %s", 10655200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low error.c_str()); 10667b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes break; 10677b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes case INSTALL_STATUS_CANNOT_REBIND: 1068a6b340af123b82e3aaa33cb2a0d45f637eeb4759Spencer Low message = android::base::StringPrintf("cannot rebind existing socket"); 10697b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes break; 1070424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes case INSTALL_STATUS_LISTENER_NOT_FOUND: 1071424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes message = android::base::StringPrintf("listener '%s' not found", service); 1072424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes break; 1073252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1074e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(reply_fd, message); 1075252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 1; 1076252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 1077252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner return 0; 1078252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner} 1079252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 1080e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes#if ADB_HOST 1081e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughesstatic int SendOkay(int fd, const std::string& s) { 1082e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes SendOkay(fd); 1083e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes SendProtocolString(fd, s); 1084e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes return 0; 1085e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes} 1086e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes#endif 1087e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes 1088c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albertint handle_host_request(const char* service, TransportType type, 1089c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert const char* serial, int reply_fd, asocket* s) { 1090c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert if (strcmp(service, "kill") == 0) { 1091c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert fprintf(stderr, "adb server killed by remote request\n"); 1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fflush(stdout); 1093e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(reply_fd); 1094f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low 1095f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low // At least on Windows, if we exit() without shutdown(SD_SEND) or 1096f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low // closesocket(), the client's next recv() will error-out with 1097f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low // WSAECONNRESET and they'll never read the OKAY. 1098f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low adb_shutdown(reply_fd); 1099f18fc0879be9cd506be6b1e051feb543b0746bdbSpencer Low 1100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // "transport:" is used for switching transport with a specified serial number 1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // "transport-usb:" is used for switching transport to the only USB transport 1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // "transport-local:" is used for switching transport to the only local transport 1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // "transport-any:" is used for switching transport to the only transport 1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(service, "transport", strlen("transport"))) { 11093bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes TransportType type = kTransportAny; 1110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { 1112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project type = kTransportUsb; 1113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { 1114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project type = kTransportLocal; 1115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { 1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project type = kTransportAny; 1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(service, "transport:", strlen("transport:"))) { 1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project service += strlen("transport:"); 11193175c8e9bfcb01f181d7300755da15a999e5461cTom Marlin serial = service; 1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1122e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes std::string error_msg; 1123e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg); 1124e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes if (t != nullptr) { 1125e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes s->transport = t; 1126e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendOkay(reply_fd); 1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1128e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes SendFail(reply_fd, error_msg); 1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // return a list of all connected devices 1134e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson if (!strncmp(service, "devices", 7)) { 1135e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes bool long_listing = (strcmp(service+7, "-l") == 0); 1136e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes if (long_listing || service[7] == 0) { 11377a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Getting device list..."); 1138e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes std::string device_list = list_transports(long_listing); 11397a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Sending device list..."); 1140e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes return SendOkay(reply_fd, device_list); 1141e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 1142e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes return 1; 1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 114590d4b739ab94fded63086de1261e70a3d39ceb1dDan Albert if (!strcmp(service, "features")) { 1146880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell std::string error_msg; 1147880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg); 1148880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell if (t != nullptr) { 1149880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell SendOkay(reply_fd, android::base::Join(t->features(), '\n')); 1150880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell } else { 1151880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell SendFail(reply_fd, error_msg); 1152880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell } 1153880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell return 0; 1154880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell } 1155880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell 1156880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell if (!strncmp(service, "check-feature:", strlen("check-feature:"))) { 1157880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell std::string error_msg; 1158880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg); 1159880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell if (t && t->CanUseFeature(service + strlen("check-feature:"))) { 1160880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell // We could potentially extend this to reply with the feature 1161880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell // version if that becomes necessary. 1162880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell SendOkay(reply_fd, "1"); 1163880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell } else { 1164880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell // Empty response means unsupported feature. 1165880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell SendOkay(reply_fd, ""); 1166880be434a9ec197100fe5c6f0b299353d13b916bDavid Pursell } 116790d4b739ab94fded63086de1261e70a3d39ceb1dDan Albert return 0; 116890d4b739ab94fded63086de1261e70a3d39ceb1dDan Albert } 116990d4b739ab94fded63086de1261e70a3d39ceb1dDan Albert 117074d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood // remove TCP transport 117174d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood if (!strncmp(service, "disconnect:", 11)) { 11723d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes const std::string address(service + 11); 11733d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes if (address.empty()) { 1174f4b9928563e97620fc1d9bd5c2efdaa0ded96488Yabin Cui kick_all_tcp_devices(); 11753d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes return SendOkay(reply_fd, "disconnected everything"); 117674d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood } 117774d7ff8cfd490852d3df1c4b9d8a21beed619caaMike Lockwood 11783d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes std::string serial; 11793d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes std::string host; 11803d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; 11813d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes std::string error; 11823d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes if (!parse_host_and_port(address, &serial, &host, &port, &error)) { 11833d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes return SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s", 11843d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes address.c_str(), error.c_str())); 11853d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes } 11863d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes atransport* t = find_transport(serial.c_str()); 11873d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes if (t == nullptr) { 11883d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes return SendFail(reply_fd, android::base::StringPrintf("no such device '%s'", 11893d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes serial.c_str())); 11903d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes } 1191f4b9928563e97620fc1d9bd5c2efdaa0ded96488Yabin Cui kick_transport(t); 11923d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes return SendOkay(reply_fd, android::base::StringPrintf("disconnected %s", address.c_str())); 11932f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood } 11942f38b699713dc2587a771bd5d4c6a47329728f5eMike Lockwood 1195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // returns our value for ADB_SERVER_VERSION 1196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(service, "version")) { 1197e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes return SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION)); 1198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1200e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes // These always report "unknown" rather than the actual error, for scripts. 1201e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes if (!strcmp(service, "get-serialno")) { 1202e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes std::string ignored; 1203e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored); 1204e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes return SendOkay(reply_fd, (t && t->serial) ? t->serial : "unknown"); 1205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1206e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes if (!strcmp(service, "get-devpath")) { 1207e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes std::string ignored; 1208e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored); 1209e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes return SendOkay(reply_fd, (t && t->devpath) ? t->devpath : "unknown"); 1210e109d266c12c5f537d429ca4b892f2719e02c2daScott Anderson } 1211e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes if (!strcmp(service, "get-state")) { 1212e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes std::string ignored; 1213e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored); 1214e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes return SendOkay(reply_fd, t ? t->connection_state_name() : "unknown"); 1215e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes } 1216e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes 1217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // indicates a new emulator instance has started 1218e2d3677cc2239a8530d33e3c5e24e65fff096801Elliott Hughes if (!strncmp(service, "emulator:", 9)) { 1219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int port = atoi(service+9); 1220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project local_connect(port); 1221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* we don't even need to send a reply */ 1222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1224dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye#endif // ADB_HOST 1225dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye 12263bd73c12c07dcefc965abeef535ac53c4754d682Elliott Hughes int ret = handle_forward_request(service, type, serial, reply_fd); 1227dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye if (ret >= 0) 1228dc22c3c7a82ad1919c52dc4d00c601ad7210c61bSimon Ye return ret - 1; 1229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 1230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1231