summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
Diffstat (limited to 'adb')
-rw-r--r--adb/Android.mk9
-rw-r--r--adb/SERVICES.TXT17
-rw-r--r--adb/SYNC.TXT84
-rw-r--r--adb/adb.c287
-rw-r--r--adb/adb.h2
-rw-r--r--adb/adb_auth_host.c4
-rw-r--r--adb/adb_client.c5
-rw-r--r--adb/backup_service.c5
-rw-r--r--adb/commandline.c110
-rw-r--r--adb/file_sync_client.c93
-rw-r--r--adb/file_sync_service.c24
-rw-r--r--adb/file_sync_service.h6
-rw-r--r--adb/framebuffer_service.c2
-rw-r--r--adb/remount_service.c11
-rw-r--r--adb/services.c23
-rw-r--r--adb/sockets.c13
-rw-r--r--adb/sysdeps.h2
-rw-r--r--adb/sysdeps_win32.c11
-rw-r--r--adb/transport.c4
-rw-r--r--adb/transport_local.c2
-rwxr-xr-xadb/usb_vendors.c23
-rw-r--r--adb/usb_windows.c4
22 files changed, 535 insertions, 206 deletions
diff --git a/adb/Android.mk b/adb/Android.mk
index 62f012c..50e28a6 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -74,7 +74,7 @@ else
LOCAL_SRC_FILES += fdevent.c
endif
-LOCAL_CFLAGS += -O2 -g -DADB_HOST=1 -Wall -Wno-unused-parameter
+LOCAL_CFLAGS += -O2 -g -DADB_HOST=1 -Wall -Wno-unused-parameter -Werror
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
LOCAL_MODULE := adb
LOCAL_MODULE_TAGS := debug
@@ -116,7 +116,7 @@ LOCAL_SRC_FILES := \
remount_service.c \
usb_linux_client.c
-LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
+LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter -Werror
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
@@ -138,8 +138,6 @@ include $(BUILD_EXECUTABLE)
ifneq ($(SDK_ONLY),true)
include $(CLEAR_VARS)
-LOCAL_LDLIBS := -lrt -ldl -lpthread
-
LOCAL_SRC_FILES := \
adb.c \
console.c \
@@ -162,8 +160,7 @@ LOCAL_CFLAGS := \
-g \
-DADB_HOST=1 \
-DADB_HOST_ON_TARGET=1 \
- -Wall \
- -Wno-unused-parameter \
+ -Wall -Wno-unused-parameter -Werror \
-D_XOPEN_SOURCE \
-D_GNU_SOURCE
diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT
index 7f85dc3..63000f2 100644
--- a/adb/SERVICES.TXT
+++ b/adb/SERVICES.TXT
@@ -240,3 +240,20 @@ sync:
This starts the file synchronisation service, used to implement "adb push"
and "adb pull". Since this service is pretty complex, it will be detailed
in a companion document named SYNC.TXT
+
+reverse:<forward-command>
+ This implements the 'adb reverse' feature, i.e. the ability to reverse
+ socket connections from a device to the host. <forward-command> is one
+ of the forwarding commands that are described above, as in:
+
+ list-forward
+ forward:<local>;<remote>
+ forward:norebind:<local>;<remote>
+ killforward-all
+ killforward:<local>
+
+ Note that in this case, <local> corresponds to the socket on the device
+ and <remote> corresponds to the socket on the host.
+
+ The output of reverse:list-forward is the same as host:list-forward
+ except that <serial> will be just 'host'.
diff --git a/adb/SYNC.TXT b/adb/SYNC.TXT
new file mode 100644
index 0000000..e74d217
--- /dev/null
+++ b/adb/SYNC.TXT
@@ -0,0 +1,84 @@
+This file tries to document file related requests a client can make
+to the ADB server of an adbd daemon. See the OVERVIEW.TXT document
+to understand what's going on here. See the SERVICES.TXT to learn more
+about the other requests that are possible.
+
+SYNC SERVICES:
+
+
+Requesting the sync service ("sync:") using the protocol as described in
+SERVICES.TXT sets the connection in sync mode. This mode is a binary mode that
+differ from the regular adb protocol. The connection stays in sync mode until
+explicitly terminated (see below).
+
+After the initial "sync:" command is sent the server must respond with either
+"OKAY" or "FAIL" as per usual.
+
+In sync mode both the server and the client will frequently use eight-byte
+packets to communicate in this document called sync request and sync
+responses. The first four bytes is an id and specifies sync request is
+represented by four utf-8 characters. The last four bytes is a Little-Endian
+integer, with various uses. This number will be called "length" below. In fact
+all binary integers are Little-Endian in the sync mode. Sync mode is
+implicitly exited after each sync request, and normal adb communication
+follows as described in SERVICES.TXT.
+
+The following sync requests are accepted:
+LIST - List the files in a folder
+SEND - Send a file to device
+RECV - Retreive a file from device
+
+Not yet documented:
+STAT - Stat a file
+ULNK - Unlink (remove) a file. (Not currently supported)
+
+For all of the sync request above the must be followed by length number of
+bytes containing an utf-8 string with a remote filename.
+
+LIST:
+Lists files in the directory specified by the remote filename. The server will
+respond with zero or more directory entries or "dents".
+
+The directory entries will be returned in the following form
+1. A four-byte sync response id beeing "DENT"
+2. A four-byte integer representing file mode.
+3. A four-byte integer representing file size.
+4. A four-byte integer representing last modified time.
+5. A four-byte integer representing file name length.
+6. length number of bytes containing an utf-8 string representing the file
+ name.
+
+When an sync response "DONE" is received the listing is done.
+
+SEND:
+The remote file name is split into two parts separated by the last
+comma (","). The first part is the actual path, while the second is a decimal
+encoded file mode containing the permissions of the file on device.
+
+Note that some file types will be deleted before the copying starts, and if
+the transfer fails. Some file types will not be deleted, which allows
+ adb push disk_image /some_block_device
+to work.
+
+After this the actual file is sent in chunks. Each chucks has the following
+format.
+A sync request with id "DATA" and length equal to the chunk size. After
+follows chunk size number of bytes. This is repeated until the file is
+transfered. Each chunk must not be larger than 64k.
+
+When the file is tranfered a sync request "DONE" is sent, where length is set
+to the last modified time for the file. The server responds to this last
+request (but not to chuck requests) with an "OKAY" sync response (length can
+be ignored).
+
+
+RECV:
+Retrieves a file from device to a local file. The remote path is the path to
+the file that will be returned. Just as for the SEND sync request the file
+received is split up into chunks. The sync response id is "DATA" and length is
+the chuck size. After follows chunk size number of bytes. This is repeated
+until the file is transfered. Each chuck will not be larger than 64k.
+
+When the file is transfered a sync resopnse "DONE" is retrieved where the
+length can be ignored.
+
diff --git a/adb/adb.c b/adb/adb.c
index e116414..90bdbaa 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -318,6 +318,26 @@ static size_t fill_connect_data(char *buf, size_t bufsize)
#endif
}
+#if !ADB_HOST
+static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
+ char header[5];
+ if (msglen > 0xffff)
+ msglen = 0xffff;
+ snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
+ writex(fd, header, 4);
+ writex(fd, msg, msglen);
+}
+#endif
+
+static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
+ char header[9];
+ if (msglen > 0xffff)
+ msglen = 0xffff;
+ snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen);
+ writex(fd, header, 8);
+ writex(fd, msg, msglen);
+}
+
static void send_connect(atransport *t)
{
D("Calling send_connect \n");
@@ -1324,29 +1344,29 @@ int adb_main(int is_daemon, int server_port)
" unchanged.\n");
}
+ /* add extra groups:
+ ** AID_ADB to access the USB driver
+ ** AID_LOG to read system logs (adb logcat)
+ ** AID_INPUT to diagnose input issues (getevent)
+ ** AID_INET to diagnose network issues (netcfg, ping)
+ ** AID_GRAPHICS to access the frame buffer
+ ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
+ ** AID_SDCARD_R to allow reading from the SD card
+ ** AID_SDCARD_RW to allow writing to the SD card
+ ** AID_NET_BW_STATS to read out qtaguid statistics
+ */
+ gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
+ AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
+ AID_NET_BW_STATS };
+ if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
+ exit(1);
+ }
+
/* don't listen on a port (default 5037) if running in secure mode */
/* don't run as root if we are running in secure mode */
if (should_drop_privileges()) {
drop_capabilities_bounding_set_if_needed();
- /* add extra groups:
- ** AID_ADB to access the USB driver
- ** AID_LOG to read system logs (adb logcat)
- ** AID_INPUT to diagnose input issues (getevent)
- ** AID_INET to diagnose network issues (netcfg, ping)
- ** AID_GRAPHICS to access the frame buffer
- ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
- ** AID_SDCARD_R to allow reading from the SD card
- ** AID_SDCARD_RW to allow writing to the SD card
- ** AID_NET_BW_STATS to read out qtaguid statistics
- */
- gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
- AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
- AID_NET_BW_STATS };
- if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
- exit(1);
- }
-
/* then switch user and group to "shell" */
if (setgid(AID_SHELL) != 0) {
exit(1);
@@ -1418,10 +1438,123 @@ int adb_main(int is_daemon, int server_port)
return 0;
}
+// Try to handle a network forwarding request.
+// This returns 1 on success, 0 on failure, and -1 to indicate this is not
+// a forwarding-related request.
+int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
+{
+ if (!strcmp(service, "list-forward")) {
+ // Create the list of forward redirections.
+ int buffer_size = format_listeners(NULL, 0);
+ // Add one byte for the trailing zero.
+ char* buffer = malloc(buffer_size + 1);
+ if (buffer == NULL) {
+ sendfailmsg(reply_fd, "not enough memory");
+ return 1;
+ }
+ (void) format_listeners(buffer, buffer_size + 1);
+#if ADB_HOST
+ send_msg_with_okay(reply_fd, buffer, buffer_size);
+#else
+ send_msg_with_header(reply_fd, buffer, buffer_size);
+#endif
+ free(buffer);
+ return 1;
+ }
+
+ if (!strcmp(service, "killforward-all")) {
+ remove_all_listeners();
+#if ADB_HOST
+ /* On the host: 1st OKAY is connect, 2nd OKAY is status */
+ adb_write(reply_fd, "OKAY", 4);
+#endif
+ adb_write(reply_fd, "OKAY", 4);
+ return 1;
+ }
+
+ if (!strncmp(service, "forward:",8) ||
+ !strncmp(service, "killforward:",12)) {
+ char *local, *remote, *err;
+ int r;
+ atransport *transport;
+
+ int createForward = strncmp(service, "kill", 4);
+ int no_rebind = 0;
+
+ local = strchr(service, ':') + 1;
+
+ // Handle forward:norebind:<local>... here
+ if (createForward && !strncmp(local, "norebind:", 9)) {
+ no_rebind = 1;
+ local = strchr(local, ':') + 1;
+ }
+
+ remote = strchr(local,';');
+
+ if (createForward) {
+ // Check forward: parameter format: '<local>;<remote>'
+ if(remote == 0) {
+ sendfailmsg(reply_fd, "malformed forward spec");
+ return 1;
+ }
+
+ *remote++ = 0;
+ if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
+ sendfailmsg(reply_fd, "malformed forward spec");
+ return 1;
+ }
+ } else {
+ // Check killforward: parameter format: '<local>'
+ if (local[0] == 0) {
+ sendfailmsg(reply_fd, "malformed forward spec");
+ return 1;
+ }
+ }
+
+ transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
+ if (!transport) {
+ sendfailmsg(reply_fd, err);
+ return 1;
+ }
+
+ if (createForward) {
+ r = install_listener(local, remote, transport, no_rebind);
+ } else {
+ r = remove_listener(local, transport);
+ }
+ if(r == 0) {
+#if ADB_HOST
+ /* On the host: 1st OKAY is connect, 2nd OKAY is status */
+ writex(reply_fd, "OKAY", 4);
+#endif
+ writex(reply_fd, "OKAY", 4);
+ return 1;
+ }
+
+ if (createForward) {
+ const char* message;
+ switch (r) {
+ case INSTALL_STATUS_CANNOT_BIND:
+ message = "cannot bind to socket";
+ break;
+ case INSTALL_STATUS_CANNOT_REBIND:
+ message = "cannot rebind existing socket";
+ break;
+ default:
+ message = "internal error";
+ }
+ sendfailmsg(reply_fd, message);
+ } else {
+ sendfailmsg(reply_fd, "cannot remove listener");
+ }
+ return 1;
+ }
+ return 0;
+}
+
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
{
atransport *transport = NULL;
- char buf[4096];
if(!strcmp(service, "kill")) {
fprintf(stderr,"adb server killed by remote request\n");
@@ -1467,13 +1600,11 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
char buffer[4096];
int use_long = !strcmp(service+7, "-l");
if (use_long || service[7] == 0) {
- memset(buf, 0, sizeof(buf));
memset(buffer, 0, sizeof(buffer));
D("Getting device list \n");
list_transports(buffer, sizeof(buffer), use_long);
- snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
D("Wrote device list \n");
- writex(reply_fd, buf, strlen(buf));
+ send_msg_with_okay(reply_fd, buffer, strlen(buffer));
return 0;
}
}
@@ -1502,8 +1633,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
}
}
- snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
- writex(reply_fd, buf, strlen(buf));
+ send_msg_with_okay(reply_fd, buffer, strlen(buffer));
return 0;
}
@@ -1511,8 +1641,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
if (!strcmp(service, "version")) {
char version[12];
snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
- snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version);
- writex(reply_fd, buf, strlen(buf));
+ send_msg_with_okay(reply_fd, version, strlen(version));
return 0;
}
@@ -1522,8 +1651,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
if (transport && transport->serial) {
out = transport->serial;
}
- snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
- writex(reply_fd, buf, strlen(buf));
+ send_msg_with_okay(reply_fd, out, strlen(out));
return 0;
}
if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
@@ -1532,8 +1660,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
if (transport && transport->devpath) {
out = transport->devpath;
}
- snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
- writex(reply_fd, buf, strlen(buf));
+ send_msg_with_okay(reply_fd, out, strlen(out));
return 0;
}
// indicates a new emulator instance has started
@@ -1545,106 +1672,14 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
}
#endif // ADB_HOST
- if(!strcmp(service,"list-forward")) {
- // Create the list of forward redirections.
- char header[9];
- int buffer_size = format_listeners(NULL, 0);
- // Add one byte for the trailing zero.
- char* buffer = malloc(buffer_size+1);
- (void) format_listeners(buffer, buffer_size+1);
- snprintf(header, sizeof header, "OKAY%04x", buffer_size);
- writex(reply_fd, header, 8);
- writex(reply_fd, buffer, buffer_size);
- free(buffer);
- return 0;
- }
-
- if (!strcmp(service,"killforward-all")) {
- remove_all_listeners();
- adb_write(reply_fd, "OKAYOKAY", 8);
- return 0;
- }
-
- if(!strncmp(service,"forward:",8) ||
- !strncmp(service,"killforward:",12)) {
- char *local, *remote, *err;
- int r;
- atransport *transport;
-
- int createForward = strncmp(service,"kill",4);
- int no_rebind = 0;
-
- local = strchr(service, ':') + 1;
-
- // Handle forward:norebind:<local>... here
- if (createForward && !strncmp(local, "norebind:", 9)) {
- no_rebind = 1;
- local = strchr(local, ':') + 1;
- }
-
- remote = strchr(local,';');
-
- if (createForward) {
- // Check forward: parameter format: '<local>;<remote>'
- if(remote == 0) {
- sendfailmsg(reply_fd, "malformed forward spec");
- return 0;
- }
-
- *remote++ = 0;
- if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
- sendfailmsg(reply_fd, "malformed forward spec");
- return 0;
- }
- } else {
- // Check killforward: parameter format: '<local>'
- if (local[0] == 0) {
- sendfailmsg(reply_fd, "malformed forward spec");
- return 0;
- }
- }
-
- transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
- if (!transport) {
- sendfailmsg(reply_fd, err);
- return 0;
- }
-
- if (createForward) {
- r = install_listener(local, remote, transport, no_rebind);
- } else {
- r = remove_listener(local, transport);
- }
- if(r == 0) {
- /* 1st OKAY is connect, 2nd OKAY is status */
- writex(reply_fd, "OKAYOKAY", 8);
- return 0;
- }
-
- if (createForward) {
- const char* message;
- switch (r) {
- case INSTALL_STATUS_CANNOT_BIND:
- message = "cannot bind to socket";
- break;
- case INSTALL_STATUS_CANNOT_REBIND:
- message = "cannot rebind existing socket";
- break;
- default:
- message = "internal error";
- }
- sendfailmsg(reply_fd, message);
- } else {
- sendfailmsg(reply_fd, "cannot remove listener");
- }
- return 0;
- }
+ int ret = handle_forward_request(service, ttype, serial, reply_fd);
+ if (ret >= 0)
+ return ret - 1;
if(!strncmp(service,"get-state",strlen("get-state"))) {
transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
char *state = connection_state_name(transport);
- snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state);
- writex(reply_fd, buf, strlen(buf));
+ send_msg_with_okay(reply_fd, state, strlen(state));
return 0;
}
return -1;
diff --git a/adb/adb.h b/adb/adb.h
index 6f5c93c..2504f99 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -323,6 +323,8 @@ asocket* create_jdwp_tracker_service_socket();
int create_jdwp_connection_fd(int jdwp_pid);
#endif
+int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd);
+
#if !ADB_HOST
typedef enum {
BACKUP,
diff --git a/adb/adb_auth_host.c b/adb/adb_auth_host.c
index 9039d42..783774a 100644
--- a/adb/adb_auth_host.c
+++ b/adb/adb_auth_host.c
@@ -159,13 +159,13 @@ static int write_public_keyfile(RSA *private_key, const char *private_key_path)
bio = BIO_push(b64, bfile);
BIO_write(bio, &pkey, sizeof(pkey));
- BIO_flush(bio);
+ (void) BIO_flush(bio);
BIO_pop(b64);
BIO_free(b64);
get_user_info(info, sizeof(info));
BIO_write(bfile, info, strlen(info));
- BIO_flush(bfile);
+ (void) BIO_flush(bfile);
BIO_free_all(bfile);
return 1;
diff --git a/adb/adb_client.c b/adb/adb_client.c
index 586cd7b..1e47486 100644
--- a/adb/adb_client.c
+++ b/adb/adb_client.c
@@ -324,7 +324,10 @@ char *adb_query(const char *service)
buf[4] = 0;
n = strtoul(buf, 0, 16);
- if(n > 1024) goto oops;
+ if(n >= 0xffff) {
+ strcpy(__adb_error, "reply is too long (>= 64kB)");
+ goto oops;
+ }
tmp = malloc(n + 1);
if(tmp == 0) goto oops;
diff --git a/adb/backup_service.c b/adb/backup_service.c
index 669ff86..654e0f3 100644
--- a/adb/backup_service.c
+++ b/adb/backup_service.c
@@ -52,15 +52,12 @@ int backup_service(BackupOperation op, char* args) {
pid_t pid;
int s[2];
char* operation;
- int socketnum;
- // Command string and choice of stdin/stdout for the pipe depend on our invocation
+ // Command string depends on our invocation
if (op == BACKUP) {
operation = "backup";
- socketnum = STDOUT_FILENO;
} else {
operation = "restore";
- socketnum = STDIN_FILENO;
}
D("backup_service(%s, %s)\n", operation, args);
diff --git a/adb/commandline.c b/adb/commandline.c
index 61167b2..2e4cd37 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -107,8 +107,12 @@ void help()
" will disconnect from all connected TCP/IP devices.\n"
"\n"
"device commands:\n"
- " adb push <local> <remote> - copy file/dir to device\n"
- " adb pull <remote> [<local>] - copy file/dir from device\n"
+ " adb push [-p] <local> <remote>\n"
+ " - copy file/dir to device\n"
+ " ('-p' to display the transfer progress)\n"
+ " adb pull [-p] <remote> [<local>]\n"
+ " - copy file/dir from device\n"
+ " ('-p' to display the transfer progress)\n"
" adb sync [ <directory> ] - copy host->device only if changed\n"
" (-l means list but don't copy)\n"
" (see 'adb help all')\n"
@@ -132,6 +136,19 @@ void help()
" if <local> is already forwarded\n"
" adb forward --remove <local> - remove a specific forward socket connection\n"
" adb forward --remove-all - remove all forward socket connections\n"
+ " adb reverse --list - list all reverse socket connections from device\n"
+ " adb reverse <remote> <local> - reverse socket connections\n"
+ " reverse specs are one of:\n"
+ " tcp:<port>\n"
+ " localabstract:<unix domain socket name>\n"
+ " localreserved:<unix domain socket name>\n"
+ " localfilesystem:<unix domain socket name>\n"
+ " adb reverse --norebind <remote> <local>\n"
+ " - same as 'adb reverse <remote> <local>' but fails\n"
+ " if <remote> is already reversed.\n"
+ " adb reverse --remove <remote>\n"
+ " - remove a specific reversed socket connection\n"
+ " adb reverse --remove-all - remove all reversed socket connections from device\n"
" adb jdwp - list PIDs of processes hosting a JDWP transport\n"
" adb install [-l] [-r] [-d] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>\n"
" - push this package file to the device and install it\n"
@@ -403,7 +420,7 @@ int adb_download_buffer(const char *service, const char *fn, const void* data, i
}
int opt = CHUNK_SIZE;
- opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
+ opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
total = sz;
ptr = data;
@@ -678,10 +695,10 @@ static int logcat(transport_type transport, char* serial, int argc, char **argv)
return 0;
}
-static int mkdirs(char *path)
+static int mkdirs(const char *path)
{
int ret;
- char *x = path + 1;
+ char *x = (char *)path + 1;
for(;;) {
x = adb_dirstart(x);
@@ -724,7 +741,7 @@ static int backup(int argc, char** argv) {
if (argc < 2) return usage();
adb_unlink(filename);
- mkdirs((char *)filename);
+ mkdirs(filename);
outFd = adb_creat(filename, 0640);
if (outFd < 0) {
fprintf(stderr, "adb: unable to open file %s\n", filename);
@@ -922,6 +939,28 @@ static const char *find_product_out_path(const char *hint)
return path_buf;
}
+
+static void parse_push_pull_args(char** arg, int narg, char const** path1, char const** path2,
+ int* show_progress) {
+ *show_progress = 0;
+
+ if ((narg > 0) && !strcmp(*arg, "-p")) {
+ *show_progress = 1;
+ ++arg;
+ --narg;
+ }
+
+ if (narg > 0) {
+ *path1 = *arg;
+ ++arg;
+ --narg;
+ }
+
+ if (narg > 0) {
+ *path2 = *arg;
+ }
+}
+
int adb_commandline(int argc, char **argv)
{
char buf[4096];
@@ -1274,8 +1313,11 @@ top:
return 0;
}
- if(!strcmp(argv[0], "forward")) {
+ if(!strcmp(argv[0], "forward") ||
+ !strcmp(argv[0], "reverse"))
+ {
char host_prefix[64];
+ char reverse = (char) !strcmp(argv[0], "reverse");
char remove = 0;
char remove_all = 0;
char list = 0;
@@ -1304,15 +1346,19 @@ top:
}
// Determine the <host-prefix> for this command.
- if (serial) {
- snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
- serial);
- } else if (ttype == kTransportUsb) {
- snprintf(host_prefix, sizeof host_prefix, "host-usb");
- } else if (ttype == kTransportLocal) {
- snprintf(host_prefix, sizeof host_prefix, "host-local");
+ if (reverse) {
+ snprintf(host_prefix, sizeof host_prefix, "reverse");
} else {
- snprintf(host_prefix, sizeof host_prefix, "host");
+ if (serial) {
+ snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
+ serial);
+ } else if (ttype == kTransportUsb) {
+ snprintf(host_prefix, sizeof host_prefix, "host-usb");
+ } else if (ttype == kTransportLocal) {
+ snprintf(host_prefix, sizeof host_prefix, "host-local");
+ } else {
+ snprintf(host_prefix, sizeof host_prefix, "host");
+ }
}
// Implement forward --list
@@ -1369,18 +1415,29 @@ top:
}
if(!strcmp(argv[0], "push")) {
- if(argc != 3) return usage();
- return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
+ int show_progress = 0;
+ const char* lpath = NULL, *rpath = NULL;
+
+ parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress);
+
+ if ((lpath != NULL) && (rpath != NULL)) {
+ return do_sync_push(lpath, rpath, 0 /* no verify APK */, show_progress);
+ }
+
+ return usage();
}
if(!strcmp(argv[0], "pull")) {
- if (argc == 2) {
- return do_sync_pull(argv[1], ".");
- } else if (argc == 3) {
- return do_sync_pull(argv[1], argv[2]);
- } else {
- return usage();
+ int show_progress = 0;
+ const char* rpath = NULL, *lpath = ".";
+
+ parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress);
+
+ if (rpath != NULL) {
+ return do_sync_pull(rpath, lpath, show_progress);
}
+
+ return usage();
}
if(!strcmp(argv[0], "install")) {
@@ -1687,6 +1744,8 @@ int install_app(transport_type transport, char* serial, int argc, char** argv)
} else if (!strcmp(argv[i], "--key")) {
verify_apk = 0;
i++;
+ } else if (!strcmp(argv[i], "--abi")) {
+ i++;
}
}
@@ -1718,7 +1777,7 @@ int install_app(transport_type transport, char* serial, int argc, char** argv)
}
}
- err = do_sync_push(apk_file, apk_dest, verify_apk);
+ err = do_sync_push(apk_file, apk_dest, verify_apk, 0 /* no show progress */);
if (err) {
goto cleanup_apk;
} else {
@@ -1726,7 +1785,8 @@ int install_app(transport_type transport, char* serial, int argc, char** argv)
}
if (verification_file != NULL) {
- err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */);
+ err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */,
+ 0 /* no show progress */);
if (err) {
goto cleanup_apk;
} else {
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index 9fec081..dc4e77f 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -62,6 +62,22 @@ static void END()
total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL);
}
+static const char* transfer_progress_format = "\rTransferring: %llu/%llu (%d%%)";
+
+static void print_transfer_progress(unsigned long long bytes_current,
+ unsigned long long bytes_total) {
+ if (bytes_total == 0) return;
+
+ fprintf(stderr, transfer_progress_format, bytes_current, bytes_total,
+ (int) (bytes_current * 100 / bytes_total));
+
+ if (bytes_current == bytes_total) {
+ fputc('\n', stderr);
+ }
+
+ fflush(stderr);
+}
+
void sync_quit(int fd)
{
syncmsg msg;
@@ -207,9 +223,10 @@ int sync_readmode(int fd, const char *path, unsigned *mode)
return 0;
}
-static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
+static int write_data_file(int fd, const char *path, syncsendbuf *sbuf, int show_progress)
{
int lfd, err = 0;
+ unsigned long long size = 0;
lfd = adb_open(path, O_RDONLY);
if(lfd < 0) {
@@ -217,6 +234,17 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
return -1;
}
+ if (show_progress) {
+ // Determine local file size.
+ struct stat st;
+ if (lstat(path, &st)) {
+ fprintf(stderr,"cannot stat '%s': %s\n", path, strerror(errno));
+ return -1;
+ }
+
+ size = st.st_size;
+ }
+
sbuf->id = ID_DATA;
for(;;) {
int ret;
@@ -238,13 +266,18 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
break;
}
total_bytes += ret;
+
+ if (show_progress) {
+ print_transfer_progress(total_bytes, size);
+ }
}
adb_close(lfd);
return err;
}
-static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf)
+static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf,
+ int show_progress)
{
int err = 0;
int total = 0;
@@ -264,6 +297,10 @@ static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *s
}
total += count;
total_bytes += count;
+
+ if (show_progress) {
+ print_transfer_progress(total, size);
+ }
}
return err;
@@ -295,7 +332,7 @@ static int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
#endif
static int sync_send(int fd, const char *lpath, const char *rpath,
- unsigned mtime, mode_t mode, int verifyApk)
+ unsigned mtime, mode_t mode, int verifyApk, int show_progress)
{
syncmsg msg;
int len, r;
@@ -377,10 +414,10 @@ static int sync_send(int fd, const char *lpath, const char *rpath,
}
if (file_buffer) {
- write_data_buffer(fd, file_buffer, size, sbuf);
+ write_data_buffer(fd, file_buffer, size, sbuf, show_progress);
free(file_buffer);
} else if (S_ISREG(mode))
- write_data_file(fd, lpath, sbuf);
+ write_data_file(fd, lpath, sbuf, show_progress);
#ifdef HAVE_SYMLINKS
else if (S_ISLNK(mode))
write_data_link(fd, lpath, sbuf);
@@ -419,10 +456,10 @@ fail:
return -1;
}
-static int mkdirs(char *name)
+static int mkdirs(const char *name)
{
int ret;
- char *x = name + 1;
+ char *x = (char *)name + 1;
for(;;) {
x = adb_dirstart(x);
@@ -438,17 +475,38 @@ static int mkdirs(char *name)
return 0;
}
-int sync_recv(int fd, const char *rpath, const char *lpath)
+int sync_recv(int fd, const char *rpath, const char *lpath, int show_progress)
{
syncmsg msg;
int len;
int lfd = -1;
char *buffer = send_buffer.data;
unsigned id;
+ unsigned long long size = 0;
len = strlen(rpath);
if(len > 1024) return -1;
+ if (show_progress) {
+ // Determine remote file size.
+ syncmsg stat_msg;
+ stat_msg.req.id = ID_STAT;
+ stat_msg.req.namelen = htoll(len);
+
+ if (writex(fd, &stat_msg.req, sizeof(stat_msg.req)) ||
+ writex(fd, rpath, len)) {
+ return -1;
+ }
+
+ if (readx(fd, &stat_msg.stat, sizeof(stat_msg.stat))) {
+ return -1;
+ }
+
+ if (stat_msg.stat.id != ID_STAT) return -1;
+
+ size = ltohl(stat_msg.stat.size);
+ }
+
msg.req.id = ID_RECV;
msg.req.namelen = htoll(len);
if(writex(fd, &msg.req, sizeof(msg.req)) ||
@@ -463,7 +521,7 @@ int sync_recv(int fd, const char *rpath, const char *lpath)
if((id == ID_DATA) || (id == ID_DONE)) {
adb_unlink(lpath);
- mkdirs((char *)lpath);
+ mkdirs(lpath);
lfd = adb_creat(lpath, 0644);
if(lfd < 0) {
fprintf(stderr,"cannot create '%s': %s\n", lpath, strerror(errno));
@@ -502,6 +560,10 @@ int sync_recv(int fd, const char *rpath, const char *lpath)
}
total_bytes += len;
+
+ if (show_progress) {
+ print_transfer_progress(total_bytes, size);
+ }
}
adb_close(lfd);
@@ -721,7 +783,8 @@ static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, i
if(ci->flag == 0) {
fprintf(stderr,"%spush: %s -> %s\n", listonly ? "would " : "", ci->src, ci->dst);
if(!listonly &&
- sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */)){
+ sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */,
+ 0 /* no show progress */)) {
return 1;
}
pushed++;
@@ -739,7 +802,7 @@ static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, i
}
-int do_sync_push(const char *lpath, const char *rpath, int verifyApk)
+int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int show_progress)
{
struct stat st;
unsigned mode;
@@ -786,7 +849,7 @@ int do_sync_push(const char *lpath, const char *rpath, int verifyApk)
rpath = tmp;
}
BEGIN();
- if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, verifyApk)) {
+ if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, verifyApk, show_progress)) {
return 1;
} else {
END();
@@ -923,7 +986,7 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
next = ci->next;
if (ci->flag == 0) {
fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst);
- if (sync_recv(fd, ci->src, ci->dst)) {
+ if (sync_recv(fd, ci->src, ci->dst, 0 /* no show progress */)) {
return 1;
}
pulled++;
@@ -940,7 +1003,7 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
return 0;
}
-int do_sync_pull(const char *rpath, const char *lpath)
+int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
{
unsigned mode;
struct stat st;
@@ -981,7 +1044,7 @@ int do_sync_pull(const char *rpath, const char *lpath)
}
}
BEGIN();
- if(sync_recv(fd, rpath, lpath)) {
+ if (sync_recv(fd, rpath, lpath, show_progress)) {
return 1;
} else {
END();
diff --git a/adb/file_sync_service.c b/adb/file_sync_service.c
index 577fb8f..1d80d26 100644
--- a/adb/file_sync_service.c
+++ b/adb/file_sync_service.c
@@ -68,7 +68,7 @@ static int mkdirs(char *name)
*x = '/';
return ret;
}
- selinux_android_restorecon(name);
+ selinux_android_restorecon(name, 0);
}
*x++ = '/';
}
@@ -172,7 +172,7 @@ static int fail_errno(int s)
}
static int handle_send_file(int s, char *path, uid_t uid,
- gid_t gid, mode_t mode, char *buffer)
+ gid_t gid, mode_t mode, char *buffer, bool do_unlink)
{
syncmsg msg;
unsigned int timestamp = 0;
@@ -236,7 +236,7 @@ static int handle_send_file(int s, char *path, uid_t uid,
if(writex(fd, buffer, len)) {
int saved_errno = errno;
adb_close(fd);
- adb_unlink(path);
+ if (do_unlink) adb_unlink(path);
fd = -1;
errno = saved_errno;
if(fail_errno(s)) return -1;
@@ -246,7 +246,7 @@ static int handle_send_file(int s, char *path, uid_t uid,
if(fd >= 0) {
struct utimbuf u;
adb_close(fd);
- selinux_android_restorecon(path);
+ selinux_android_restorecon(path, 0);
u.actime = timestamp;
u.modtime = timestamp;
utime(path, &u);
@@ -261,7 +261,7 @@ static int handle_send_file(int s, char *path, uid_t uid,
fail:
if(fd >= 0)
adb_close(fd);
- adb_unlink(path);
+ if (do_unlink) adb_unlink(path);
return -1;
}
@@ -323,6 +323,7 @@ static int do_send(int s, char *path, char *buffer)
char *tmp;
unsigned int mode;
int is_link, ret;
+ bool do_unlink;
tmp = strrchr(path,',');
if(tmp) {
@@ -339,11 +340,16 @@ static int do_send(int s, char *path, char *buffer)
if(!tmp || errno) {
mode = 0644;
is_link = 0;
+ do_unlink = true;
+ } else {
+ struct stat st;
+ /* Don't delete files before copying if they are not "regular" */
+ do_unlink = lstat(path, &st) || S_ISREG(st.st_mode) || S_ISLNK(st.st_mode);
+ if (do_unlink) {
+ adb_unlink(path);
+ }
}
- adb_unlink(path);
-
-
#ifdef HAVE_SYMLINKS
if(is_link)
ret = handle_send_link(s, path, buffer);
@@ -366,7 +372,7 @@ static int do_send(int s, char *path, char *buffer)
if (is_on_system(path)) {
fs_config(tmp, 0, &uid, &gid, &mode, &cap);
}
- ret = handle_send_file(s, path, uid, gid, mode, buffer);
+ ret = handle_send_file(s, path, uid, gid, mode, buffer, do_unlink);
}
return ret;
diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h
index e402e06..3e7e096 100644
--- a/adb/file_sync_service.h
+++ b/adb/file_sync_service.h
@@ -72,15 +72,15 @@ typedef union {
struct {
unsigned id;
unsigned msglen;
- } status;
+ } status;
} syncmsg;
void file_sync_service(int fd, void *cookie);
int do_sync_ls(const char *path);
-int do_sync_push(const char *lpath, const char *rpath, int verifyApk);
+int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int show_progress);
int do_sync_sync(const char *lpath, const char *rpath, int listonly);
-int do_sync_pull(const char *rpath, const char *lpath);
+int do_sync_pull(const char *rpath, const char *lpath, int show_progress);
#define SYNC_DATA_MAX (64*1024)
diff --git a/adb/framebuffer_service.c b/adb/framebuffer_service.c
index fa7fd98..8cbe840 100644
--- a/adb/framebuffer_service.c
+++ b/adb/framebuffer_service.c
@@ -61,7 +61,7 @@ void framebuffer_service(int fd, void *cookie)
int w, h, f;
int fds[2];
- if (pipe(fds) < 0) goto pipefail;
+ if (pipe2(fds, O_CLOEXEC) < 0) goto pipefail;
pid_t pid = fork();
if (pid < 0) goto done;
diff --git a/adb/remount_service.c b/adb/remount_service.c
index ad61284..d3a649b 100644
--- a/adb/remount_service.c
+++ b/adb/remount_service.c
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
#include <stdio.h>
-#include <unistd.h>
+#include <stdlib.h>
#include <string.h>
-#include <fcntl.h>
#include <sys/mount.h>
-#include <errno.h>
+#include <unistd.h>
#include "sysdeps.h"
@@ -35,7 +35,6 @@ static char *find_mount(const char *dir)
{
int fd;
int res;
- int size;
char *token = NULL;
const char delims[] = "\n";
char buf[4096];
@@ -45,7 +44,7 @@ static char *find_mount(const char *dir)
return NULL;
buf[sizeof(buf) - 1] = '\0';
- size = adb_read(fd, buf, sizeof(buf) - 1);
+ adb_read(fd, buf, sizeof(buf) - 1);
adb_close(fd);
token = strtok(buf, delims);
diff --git a/adb/services.c b/adb/services.c
index dcaf276..7b809da 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -141,6 +141,17 @@ cleanup:
adb_close(fd);
}
+void reverse_service(int fd, void* arg)
+{
+ const char* command = arg;
+
+ if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
+ sendfailmsg(fd, "not a reverse forwarding command");
+ }
+ free(arg);
+ adb_close(fd);
+}
+
#endif
static int create_service_thread(void (*func)(int, void *), void *cookie)
@@ -385,6 +396,16 @@ int service_to_fd(const char *name)
ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port);
} else if(!strncmp(name, "usb:", 4)) {
ret = create_service_thread(restart_usb_service, NULL);
+ } else if (!strncmp(name, "reverse:", 8)) {
+ char* cookie = strdup(name + 8);
+ if (cookie == NULL) {
+ ret = -1;
+ } else {
+ ret = create_service_thread(reverse_service, cookie);
+ if (ret < 0) {
+ free(cookie);
+ }
+ }
#endif
}
if (ret >= 0) {
@@ -447,7 +468,7 @@ static void connect_device(char* host, char* buffer, int buffer_size)
snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
- fd = socket_network_client(hostbuf, port, SOCK_STREAM);
+ fd = socket_network_client_timeout(hostbuf, port, SOCK_STREAM, 10);
if (fd < 0) {
snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);
return;
diff --git a/adb/sockets.c b/adb/sockets.c
index de14a22..faa9564 100644
--- a/adb/sockets.c
+++ b/adb/sockets.c
@@ -23,6 +23,10 @@
#include "sysdeps.h"
+#if !ADB_HOST
+#include <cutils/properties.h>
+#endif
+
#define TRACE_TAG TRACE_SOCKETS
#include "adb.h"
@@ -428,6 +432,9 @@ asocket *create_local_service_socket(const char *name)
{
asocket *s;
int fd;
+#if !ADB_HOST
+ char debug[PROPERTY_VALUE_MAX];
+#endif
#if !ADB_HOST
if (!strcmp(name,"jdwp")) {
@@ -444,7 +451,11 @@ asocket *create_local_service_socket(const char *name)
D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
#if !ADB_HOST
- if ((!strncmp(name, "root:", 5) && getuid() != 0)
+ if (!strncmp(name, "root:", 5))
+ property_get("ro.debuggable", debug, "");
+
+ if ((!strncmp(name, "root:", 5) && getuid() != 0
+ && strcmp(debug, "1") == 0)
|| !strncmp(name, "usb:", 4)
|| !strncmp(name, "tcpip:", 6)) {
D("LS(%d): enabling exit_on_close\n", s->id);
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 4033b72..ba4306f 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -169,6 +169,8 @@ extern void* load_file(const char* pathname, unsigned* psize);
/* normally provided by <cutils/sockets.h> */
extern int socket_loopback_client(int port, int type);
extern int socket_network_client(const char *host, int port, int type);
+extern int socket_network_client_timeout(const char *host, int port, int type,
+ int timeout);
extern int socket_loopback_server(int port, int type);
extern int socket_inaddr_any_server(int port, int type);
diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c
index 2105b16..29f58ec 100644
--- a/adb/sysdeps_win32.c
+++ b/adb/sysdeps_win32.c
@@ -701,6 +701,13 @@ int socket_network_client(const char *host, int port, int type)
}
+int socket_network_client_timeout(const char *host, int port, int type, int timeout)
+{
+ // TODO: implement timeouts for Windows.
+ return socket_network_client(host, port, type);
+}
+
+
int socket_inaddr_any_server(int port, int type)
{
FH f = _fh_alloc( &_fh_socket_class );
@@ -956,7 +963,7 @@ bip_buffer_write( BipBuffer bip, const void* src, int len )
avail = len;
memcpy( bip->buff + bip->a_end, src, avail );
- src += avail;
+ src = (const char *)src + avail;
count += avail;
len -= avail;
@@ -1049,7 +1056,7 @@ bip_buffer_read( BipBuffer bip, void* dst, int len )
avail = len;
memcpy( dst, bip->buff + bip->a_start, avail );
- dst += avail;
+ dst = (char *)dst + avail;
count += avail;
len -= avail;
diff --git a/adb/transport.c b/adb/transport.c
index 6002530..f35880c 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -1188,6 +1188,10 @@ int writex(int fd, const void *ptr, size_t len)
D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno));
if (errno == EINTR)
continue;
+ if (errno == EAGAIN) {
+ adb_sleep_ms(1); // just yield some cpu time
+ continue;
+ }
} else {
D("writex: fd=%d disconnected\n", fd);
}
diff --git a/adb/transport_local.c b/adb/transport_local.c
index d2dbca6..948cc15 100644
--- a/adb/transport_local.c
+++ b/adb/transport_local.c
@@ -48,7 +48,7 @@ static inline void fix_endians(apacket *p)
* local transport it is connected. The list is used to detect when we're
* trying to connect twice to a given local transport.
*/
-#define ADB_LOCAL_TRANSPORT_MAX 16
+#define ADB_LOCAL_TRANSPORT_MAX 64
ADB_MUTEX_DEFINE( local_transports_lock );
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index cd5885e..957e5db 100755
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -51,7 +51,9 @@
// BYD's USB Vendor ID
#define VENDOR_ID_BYD 0x1D91
// Compal's USB Vendor ID
-#define VENDOR_ID_COMPAL 0x1219
+#define VENDOR_ID_COMPAL 0x04B7
+// Compalcomm's USB Vendor ID
+#define VENDOR_ID_COMPALCOMM 0x1219
// Dell's USB Vendor ID
#define VENDOR_ID_DELL 0x413c
// ECS's USB Vendor ID
@@ -72,6 +74,8 @@
#define VENDOR_ID_GIGABYTE 0x0414
// Gigaset's USB Vendor ID
#define VENDOR_ID_GIGASET 0x1E85
+// GIONEE's USB Vendor ID
+#define VENDOR_ID_GIONEE 0x271D
// Google's USB Vendor ID
#define VENDOR_ID_GOOGLE 0x18d1
// Haier's USB Vendor ID
@@ -80,6 +84,8 @@
#define VENDOR_ID_HARRIS 0x19A5
// Hisense's USB Vendor ID
#define VENDOR_ID_HISENSE 0x109b
+// Honeywell's USB Vendor ID
+#define VENDOR_ID_HONEYWELL 0x0c2e
// HP's USB Vendor ID
#define VENDOR_ID_HP 0x03f0
// HTC's USB Vendor ID
@@ -90,6 +96,8 @@
#define VENDOR_ID_INQ_MOBILE 0x2314
// Intel's USB Vendor ID
#define VENDOR_ID_INTEL 0x8087
+// Intermec's USB Vendor ID
+#define VENDOR_ID_INTERMEC 0x067e
// IRiver's USB Vendor ID
#define VENDOR_ID_IRIVER 0x2420
// K-Touch's USB Vendor ID
@@ -138,6 +146,8 @@
#define VENDOR_ID_PMC 0x04DA
// Positivo's USB Vendor ID
#define VENDOR_ID_POSITIVO 0x1662
+// Prestigio's USB Vendor ID
+#define VENDOR_ID_PRESTIGIO 0x29e4
// Qisda's USB Vendor ID
#define VENDOR_ID_QISDA 0x1D45
// Qualcomm's USB Vendor ID
@@ -152,6 +162,8 @@
#define VENDOR_ID_SHARP 0x04dd
// SK Telesys's USB Vendor ID
#define VENDOR_ID_SK_TELESYS 0x1F53
+// Smartisan's USB Vendor ID
+#define VENDOR_ID_SMARTISAN 0x29a9
// Sony's USB Vendor ID
#define VENDOR_ID_SONY 0x054C
// Sony Ericsson's USB Vendor ID
@@ -166,6 +178,8 @@
#define VENDOR_ID_TI 0x0451
// Toshiba's USB Vendor ID
#define VENDOR_ID_TOSHIBA 0x0930
+// Unowhy's USB Vendor ID
+#define VENDOR_ID_UNOWHY 0x2A49
// Vizio's USB Vendor ID
#define VENDOR_ID_VIZIO 0xE040
// Wacom's USB Vendor ID
@@ -191,6 +205,7 @@ int builtInVendorIds[] = {
VENDOR_ID_ASUS,
VENDOR_ID_BYD,
VENDOR_ID_COMPAL,
+ VENDOR_ID_COMPALCOMM,
VENDOR_ID_DELL,
VENDOR_ID_ECS,
VENDOR_ID_EMERGING_TECH,
@@ -201,15 +216,18 @@ int builtInVendorIds[] = {
VENDOR_ID_GARMIN_ASUS,
VENDOR_ID_GIGABYTE,
VENDOR_ID_GIGASET,
+ VENDOR_ID_GIONEE,
VENDOR_ID_GOOGLE,
VENDOR_ID_HAIER,
VENDOR_ID_HARRIS,
VENDOR_ID_HISENSE,
+ VENDOR_ID_HONEYWELL,
VENDOR_ID_HP,
VENDOR_ID_HTC,
VENDOR_ID_HUAWEI,
VENDOR_ID_INQ_MOBILE,
VENDOR_ID_INTEL,
+ VENDOR_ID_INTERMEC,
VENDOR_ID_IRIVER,
VENDOR_ID_KOBO,
VENDOR_ID_K_TOUCH,
@@ -234,6 +252,7 @@ int builtInVendorIds[] = {
VENDOR_ID_PHILIPS,
VENDOR_ID_PMC,
VENDOR_ID_POSITIVO,
+ VENDOR_ID_PRESTIGIO,
VENDOR_ID_QISDA,
VENDOR_ID_QUALCOMM,
VENDOR_ID_QUANTA,
@@ -241,6 +260,7 @@ int builtInVendorIds[] = {
VENDOR_ID_SAMSUNG,
VENDOR_ID_SHARP,
VENDOR_ID_SK_TELESYS,
+ VENDOR_ID_SMARTISAN,
VENDOR_ID_SONY,
VENDOR_ID_SONY_ERICSSON,
VENDOR_ID_T_AND_A,
@@ -248,6 +268,7 @@ int builtInVendorIds[] = {
VENDOR_ID_TELEEPOCH,
VENDOR_ID_TI,
VENDOR_ID_TOSHIBA,
+ VENDOR_ID_UNOWHY,
VENDOR_ID_VIZIO,
VENDOR_ID_WACOM,
VENDOR_ID_XIAOMI,
diff --git a/adb/usb_windows.c b/adb/usb_windows.c
index 4936b77..1309a78 100644
--- a/adb/usb_windows.c
+++ b/adb/usb_windows.c
@@ -310,14 +310,14 @@ int usb_read(usb_handle *handle, void* data, int len) {
int xfer = (len > 4096) ? 4096 : len;
ret = AdbReadEndpointSync(handle->adb_read_pipe,
- (void*)data,
+ data,
(unsigned long)xfer,
&read,
time_out);
int saved_errno = GetLastError();
D("usb_write got: %ld, expected: %d, errno: %d\n", read, xfer, saved_errno);
if (ret) {
- data += read;
+ data = (char *)data + read;
len -= read;
if (len == 0)