diff --git a/base/include/base/parseint.h b/base/include/base/parseint.h new file mode 100644 index 000000000..0543795e1 --- /dev/null +++ b/base/include/base/parseint.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_PARSEINT_H +#define BASE_PARSEINT_H + +#include +#include + +#include + +namespace android { +namespace base { + +// Parses the unsigned decimal integer in the string 's' and sets 'out' to +// that value. Optionally allows the caller to define a 'max' beyond which +// otherwise valid values will be rejected. Returns boolean success. +template +bool ParseUint(const char* s, T* out, + T max = std::numeric_limits::max()) { + int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10; + errno = 0; + char* end; + unsigned long long int result = strtoull(s, &end, base); + if (errno != 0 || s == end || *end != '\0') { + return false; + } + if (max < result) { + return false; + } + *out = static_cast(result); + return true; +} + +// Parses the signed decimal integer in the string 's' and sets 'out' to +// that value. Optionally allows the caller to define a 'min' and 'max +// beyond which otherwise valid values will be rejected. Returns boolean +// success. +template +bool ParseInt(const char* s, T* out, + T min = std::numeric_limits::min(), + T max = std::numeric_limits::max()) { + int base = (s[0] == '0' && s[1] == 'x') ? 16 : 10; + errno = 0; + char* end; + long long int result = strtoll(s, &end, base); + if (errno != 0 || s == end || *end != '\0') { + return false; + } + if (result < min || max < result) { + return false; + } + *out = static_cast(result); + return true; +} + +} // namespace base +} // namespace android + +#endif // BASE_PARSEINT_H diff --git a/fastboot/Android.mk b/fastboot/Android.mk index 66a470a64..739ab9da8 100644 --- a/fastboot/Android.mk +++ b/fastboot/Android.mk @@ -21,7 +21,7 @@ include $(CLEAR_VARS) LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \ $(LOCAL_PATH)/../../extras/ext4_utils \ $(LOCAL_PATH)/../../extras/f2fs_utils -LOCAL_SRC_FILES := protocol.c engine.c bootimg_utils.cpp fastboot.cpp util.c fs.c +LOCAL_SRC_FILES := protocol.cpp engine.cpp bootimg_utils.cpp fastboot.cpp util.cpp fs.cpp LOCAL_MODULE := fastboot LOCAL_MODULE_TAGS := debug LOCAL_CONLYFLAGS += -std=gnu99 @@ -29,33 +29,7 @@ LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code LOCAL_CFLAGS += -DFASTBOOT_REVISION='"$(fastboot_version)"' -ifeq ($(HOST_OS),linux) - LOCAL_SRC_FILES += usb_linux.c util_linux.c -endif - -ifeq ($(HOST_OS),darwin) - LOCAL_SRC_FILES += usb_osx.c util_osx.c - LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon - LOCAL_CFLAGS += -Wno-unused-parameter -endif - -ifeq ($(HOST_OS),windows) - LOCAL_SRC_FILES += usb_windows.c util_windows.c - EXTRA_STATIC_LIBS := AdbWinApi - ifneq ($(strip $(USE_CYGWIN)),) - # Pure cygwin case - LOCAL_LDLIBS += -lpthread - endif - ifneq ($(strip $(USE_MINGW)),) - # MinGW under Linux case - LOCAL_LDLIBS += -lws2_32 - USE_SYSDEPS_WIN32 := 1 - endif - LOCAL_C_INCLUDES += development/host/windows/usb/api -endif - -LOCAL_STATIC_LIBRARIES := \ - $(EXTRA_STATIC_LIBS) \ +LOCAL_STATIC_LIBRARIES += \ libziparchive-host \ libext4_utils_host \ libsparse_host \ @@ -64,23 +38,37 @@ LOCAL_STATIC_LIBRARIES := \ libz \ libbase -ifneq ($(HOST_OS),windows) -LOCAL_STATIC_LIBRARIES += libselinux -endif # HOST_OS != windows - ifeq ($(HOST_OS),linux) -# libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn") -LOCAL_CFLAGS += -DUSE_F2FS -LOCAL_LDFLAGS += -ldl -rdynamic -Wl,-rpath,. -LOCAL_REQUIRED_MODULES := libf2fs_fmt_host_dyn -# The following libf2fs_* are from system/extras/f2fs_utils, -# and do not use code in external/f2fs-tools. -LOCAL_STATIC_LIBRARIES += libf2fs_utils_host libf2fs_ioutils_host libf2fs_dlutils_host + LOCAL_SRC_FILES += usb_linux.cpp util_linux.cpp + LOCAL_STATIC_LIBRARIES += libselinux + + # libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn") + LOCAL_CFLAGS += -DUSE_F2FS + LOCAL_LDFLAGS += -ldl -rdynamic -Wl,-rpath,. + LOCAL_REQUIRED_MODULES += libf2fs_fmt_host_dyn + # The following libf2fs_* are from system/extras/f2fs_utils, + # and do not use code in external/f2fs-tools. + LOCAL_STATIC_LIBRARIES += libf2fs_utils_host libf2fs_ioutils_host libf2fs_dlutils_host endif -# libc++ not available on windows yet +ifeq ($(HOST_OS),darwin) + LOCAL_SRC_FILES += usb_osx.cpp util_osx.cpp + LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon + LOCAL_CFLAGS += -Wno-unused-parameter + LOCAL_STATIC_LIBRARIES += libselinux +endif + +ifeq ($(HOST_OS),windows) + LOCAL_SRC_FILES += usb_windows.cpp util_windows.cpp + LOCAL_STATIC_LIBRARIES += AdbWinApi + LOCAL_REQUIRED_MODULES += AdbWinApi + LOCAL_LDLIBS += -lws2_32 + LOCAL_C_INCLUDES += development/host/windows/usb/api +endif + +# libc++ not available on windows yet. ifneq ($(HOST_OS),windows) - LOCAL_CXX_STL := libc++_static + LOCAL_CXX_STL := libc++_static endif # Don't add anything here, we don't want additional shared dependencies @@ -97,10 +85,9 @@ endif $(call dist-for-goals,dist_files sdk,$(my_dist_files)) my_dist_files := - ifeq ($(HOST_OS),linux) include $(CLEAR_VARS) -LOCAL_SRC_FILES := usbtest.c usb_linux.c util.c +LOCAL_SRC_FILES := usbtest.cpp usb_linux.cpp util.cpp LOCAL_MODULE := usbtest LOCAL_CFLAGS := -Werror include $(BUILD_HOST_EXECUTABLE) diff --git a/fastboot/bootimg_utils.cpp b/fastboot/bootimg_utils.cpp index d8905a617..c1028ef3c 100644 --- a/fastboot/bootimg_utils.cpp +++ b/fastboot/bootimg_utils.cpp @@ -32,32 +32,27 @@ #include #include -void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline) +void bootimg_set_cmdline(boot_img_hdr* h, const char* cmdline) { strcpy((char*) h->cmdline, cmdline); } -boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offset, - void *ramdisk, unsigned ramdisk_size, unsigned ramdisk_offset, - void *second, unsigned second_size, unsigned second_offset, - unsigned page_size, unsigned base, unsigned tags_offset, - unsigned *bootimg_size) +boot_img_hdr* mkbootimg(void* kernel, int64_t kernel_size, off_t kernel_offset, + void* ramdisk, int64_t ramdisk_size, off_t ramdisk_offset, + void* second, int64_t second_size, off_t second_offset, + size_t page_size, size_t base, off_t tags_offset, + int64_t* bootimg_size) { - unsigned kernel_actual; - unsigned ramdisk_actual; - unsigned second_actual; - unsigned page_mask; + size_t page_mask = page_size - 1; - page_mask = page_size - 1; - - kernel_actual = (kernel_size + page_mask) & (~page_mask); - ramdisk_actual = (ramdisk_size + page_mask) & (~page_mask); - second_actual = (second_size + page_mask) & (~page_mask); + int64_t kernel_actual = (kernel_size + page_mask) & (~page_mask); + int64_t ramdisk_actual = (ramdisk_size + page_mask) & (~page_mask); + int64_t second_actual = (second_size + page_mask) & (~page_mask); *bootimg_size = page_size + kernel_actual + ramdisk_actual + second_actual; boot_img_hdr* hdr = reinterpret_cast(calloc(*bootimg_size, 1)); - if (hdr == 0) { + if (hdr == nullptr) { return hdr; } @@ -74,12 +69,9 @@ boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offs hdr->page_size = page_size; + memcpy(hdr->magic + page_size, kernel, kernel_size); + memcpy(hdr->magic + page_size + kernel_actual, ramdisk, ramdisk_size); + memcpy(hdr->magic + page_size + kernel_actual + ramdisk_actual, second, second_size); - memcpy(hdr->magic + page_size, - kernel, kernel_size); - memcpy(hdr->magic + page_size + kernel_actual, - ramdisk, ramdisk_size); - memcpy(hdr->magic + page_size + kernel_actual + ramdisk_actual, - second, second_size); return hdr; } diff --git a/fastboot/bootimg_utils.h b/fastboot/bootimg_utils.h index b1a86cda7..fcc866297 100644 --- a/fastboot/bootimg_utils.h +++ b/fastboot/bootimg_utils.h @@ -30,20 +30,14 @@ #define _FASTBOOT_BOOTIMG_UTILS_H_ #include +#include +#include -#if defined(__cplusplus) -extern "C" { -#endif - -void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline); -boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, unsigned kernel_offset, - void *ramdisk, unsigned ramdisk_size, unsigned ramdisk_offset, - void *second, unsigned second_size, unsigned second_offset, - unsigned page_size, unsigned base, unsigned tags_offset, - unsigned *bootimg_size); - -#if defined(__cplusplus) -} -#endif +void bootimg_set_cmdline(boot_img_hdr* h, const char* cmdline); +boot_img_hdr* mkbootimg(void* kernel, int64_t kernel_size, off_t kernel_offset, + void* ramdisk, int64_t ramdisk_size, off_t ramdisk_offset, + void* second, int64_t second_size, off_t second_offset, + size_t page_size, size_t base, off_t tags_offset, + int64_t* bootimg_size); #endif diff --git a/fastboot/engine.c b/fastboot/engine.cpp similarity index 78% rename from fastboot/engine.c rename to fastboot/engine.cpp index 2f90e419a..44796d7d9 100644 --- a/fastboot/engine.c +++ b/fastboot/engine.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -39,16 +38,6 @@ #include #include -#ifdef USE_MINGW -#include -#else -#include -#endif - -#ifndef __unused -#define __unused __attribute__((__unused__)) -#endif - #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define OP_DOWNLOAD 1 @@ -62,18 +51,20 @@ typedef struct Action Action; #define CMD_SIZE 64 -struct Action -{ +struct Action { unsigned op; - Action *next; + Action* next; char cmd[CMD_SIZE]; - const char *prod; - void *data; - unsigned size; + const char* prod; + void* data; + + // The protocol only supports 32-bit sizes, so you'll have to break + // anything larger into chunks. + uint32_t size; const char *msg; - int (*func)(Action *a, int status, char *resp); + int (*func)(Action* a, int status, const char* resp); double start; }; @@ -84,45 +75,20 @@ static Action *action_last = 0; -int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...) -{ - char cmd[CMD_SIZE] = "getvar:"; - int getvar_len = strlen(cmd); - va_list args; +bool fb_getvar(usb_handle* usb, const std::string& key, std::string* value) { + std::string cmd = "getvar:"; + cmd += key; - response[FB_RESPONSE_SZ] = '\0'; - va_start(args, fmt); - vsnprintf(cmd + getvar_len, sizeof(cmd) - getvar_len, fmt, args); - va_end(args); - cmd[CMD_SIZE - 1] = '\0'; - return fb_command_response(usb, cmd, response); + char buf[FB_RESPONSE_SZ + 1]; + memset(buf, 0, sizeof(buf)); + if (fb_command_response(usb, cmd.c_str(), buf)) { + return false; + } + *value = buf; + return true; } - -/* Return true if this partition is supported by the fastboot format command. - * It is also used to determine if we should first erase a partition before - * flashing it with an ext4 filesystem. See needs_erase() - * - * Not all devices report the filesystem type, so don't report any errors, - * just return false. - */ -int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override) -{ - char fs_type[FB_RESPONSE_SZ + 1] = {0,}; - int status; - - if (type_override) { - return !!fs_get_generator(type_override); - } - status = fb_getvar(usb, fs_type, "partition-type:%s", partition); - if (status) { - return 0; - } - return !!fs_get_generator(fs_type); -} - -static int cb_default(Action *a, int status, char *resp) -{ +static int cb_default(Action* a, int status, const char* resp) { if (status) { fprintf(stderr,"FAILED (%s)\n", resp); } else { @@ -135,12 +101,11 @@ static int cb_default(Action *a, int status, char *resp) static Action *queue_action(unsigned op, const char *fmt, ...) { - Action *a; va_list ap; size_t cmdsize; - a = calloc(1, sizeof(Action)); - if (a == 0) die("out of memory"); + Action* a = reinterpret_cast(calloc(1, sizeof(Action))); + if (a == nullptr) die("out of memory"); va_start(ap, fmt); cmdsize = vsnprintf(a->cmd, sizeof(a->cmd), fmt, ap); @@ -198,8 +163,7 @@ void fb_queue_flash_sparse(const char *ptn, struct sparse_file *s, unsigned sz) a->msg = mkmsg("writing '%s'", ptn); } -static int match(char *str, const char **value, unsigned count) -{ +static int match(const char* str, const char** value, unsigned count) { unsigned n; for (n = 0; n < count; n++) { @@ -222,9 +186,9 @@ static int match(char *str, const char **value, unsigned count) -static int cb_check(Action *a, int status, char *resp, int invert) +static int cb_check(Action* a, int status, const char* resp, int invert) { - const char **value = a->data; + const char** value = reinterpret_cast(a->data); unsigned count = a->size; unsigned n; int yes; @@ -265,18 +229,16 @@ static int cb_check(Action *a, int status, char *resp, int invert) return -1; } -static int cb_require(Action *a, int status, char *resp) -{ +static int cb_require(Action*a, int status, const char* resp) { return cb_check(a, status, resp, 0); } -static int cb_reject(Action *a, int status, char *resp) -{ +static int cb_reject(Action* a, int status, const char* resp) { return cb_check(a, status, resp, 1); } void fb_queue_require(const char *prod, const char *var, - int invert, unsigned nvalues, const char **value) + bool invert, size_t nvalues, const char **value) { Action *a; a = queue_action(OP_QUERY, "getvar:%s", var); @@ -285,11 +247,10 @@ void fb_queue_require(const char *prod, const char *var, a->size = nvalues; a->msg = mkmsg("checking %s", var); a->func = invert ? cb_reject : cb_require; - if (a->data == 0) die("out of memory"); + if (a->data == nullptr) die("out of memory"); } -static int cb_display(Action *a, int status, char *resp) -{ +static int cb_display(Action* a, int status, const char* resp) { if (status) { fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); return status; @@ -303,17 +264,16 @@ void fb_queue_display(const char *var, const char *prettyname) Action *a; a = queue_action(OP_QUERY, "getvar:%s", var); a->data = strdup(prettyname); - if (a->data == 0) die("out of memory"); + if (a->data == nullptr) die("out of memory"); a->func = cb_display; } -static int cb_save(Action *a, int status, char *resp) -{ +static int cb_save(Action* a, int status, const char* resp) { if (status) { fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); return status; } - strncpy(a->data, resp, a->size); + strncpy(reinterpret_cast(a->data), resp, a->size); return 0; } @@ -326,8 +286,7 @@ void fb_queue_query_save(const char *var, char *dest, unsigned dest_size) a->func = cb_save; } -static int cb_do_nothing(Action *a __unused, int status __unused, char *resp __unused) -{ +static int cb_do_nothing(Action*, int , const char*) { fprintf(stderr,"\n"); return 0; } @@ -398,7 +357,7 @@ int fb_execute_queue(usb_handle *usb) } else if (a->op == OP_NOTICE) { fprintf(stderr,"%s\n",(char*)a->data); } else if (a->op == OP_DOWNLOAD_SPARSE) { - status = fb_download_data_sparse(usb, a->data); + status = fb_download_data_sparse(usb, reinterpret_cast(a->data)); status = a->func(a, status, status ? fb_get_error() : ""); if (status) break; } else if (a->op == OP_WAIT_FOR_DISCONNECT) { @@ -411,8 +370,3 @@ int fb_execute_queue(usb_handle *usb) fprintf(stderr,"finished. total time: %.3fs\n", (now() - start)); return status; } - -int fb_queue_is_empty(void) -{ - return (action_list == NULL); -} diff --git a/fastboot/engineering_key.p12 b/fastboot/engineering_key.p12 deleted file mode 100644 index d8183b055..000000000 Binary files a/fastboot/engineering_key.p12 and /dev/null differ diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index de4c0ea41..d68ca85f7 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -44,6 +43,8 @@ #include #include +#include +#include #include #include @@ -67,12 +68,12 @@ static int long_listing = 0; static int64_t sparse_limit = -1; static int64_t target_sparse_limit = -1; -unsigned page_size = 2048; -unsigned base_addr = 0x10000000; -unsigned kernel_offset = 0x00008000; -unsigned ramdisk_offset = 0x01000000; -unsigned second_offset = 0x00f00000; -unsigned tags_offset = 0x00000100; +static unsigned page_size = 2048; +static unsigned base_addr = 0x10000000; +static unsigned kernel_offset = 0x00008000; +static unsigned ramdisk_offset = 0x01000000; +static unsigned second_offset = 0x00f00000; +static unsigned tags_offset = 0x00000100; enum fb_buffer_type { FB_BUFFER, @@ -81,8 +82,8 @@ enum fb_buffer_type { struct fastboot_buffer { enum fb_buffer_type type; - void *data; - unsigned int sz; + void* data; + int64_t sz; }; static struct { @@ -97,8 +98,7 @@ static struct { {"vendor.img", "vendor.sig", "vendor", true}, }; -char *find_item(const char *item, const char *product) -{ +static char* find_item(const char* item, const char* product) { char *dir; const char *fn; char path[PATH_MAX + 128]; @@ -139,36 +139,26 @@ char *find_item(const char *item, const char *product) return strdup(path); } -static int64_t file_size(int fd) -{ - struct stat st; - int ret; - - ret = fstat(fd, &st); - - return ret ? -1 : st.st_size; +static int64_t get_file_size(int fd) { + struct stat sb; + return fstat(fd, &sb) == -1 ? -1 : sb.st_size; } -static void *load_fd(int fd, unsigned *_sz) -{ - char *data; - int sz; +static void* load_fd(int fd, int64_t* sz) { int errno_tmp; + char* data = nullptr; - data = 0; - - sz = file_size(fd); - if (sz < 0) { + *sz = get_file_size(fd); + if (*sz < 0) { goto oops; } - data = (char*) malloc(sz); - if(data == 0) goto oops; + data = (char*) malloc(*sz); + if (data == nullptr) goto oops; - if(read(fd, data, sz) != sz) goto oops; + if(read(fd, data, *sz) != *sz) goto oops; close(fd); - if(_sz) *_sz = sz; return data; oops: @@ -179,35 +169,22 @@ oops: return 0; } -static void *load_file(const char *fn, unsigned *_sz) -{ - int fd; - - fd = open(fn, O_RDONLY | O_BINARY); - if(fd < 0) return 0; - - return load_fd(fd, _sz); +static void* load_file(const char* fn, int64_t* sz) { + int fd = open(fn, O_RDONLY | O_BINARY); + if (fd == -1) return nullptr; + return load_fd(fd, sz); } -int match_fastboot_with_serial(usb_ifc_info *info, const char *local_serial) -{ - if(!(vendor_id && (info->dev_vendor == vendor_id)) && - (info->dev_vendor != 0x18d1) && // Google - (info->dev_vendor != 0x8087) && // Intel - (info->dev_vendor != 0x0451) && - (info->dev_vendor != 0x0502) && - (info->dev_vendor != 0x0fce) && // Sony Ericsson - (info->dev_vendor != 0x05c6) && // Qualcomm - (info->dev_vendor != 0x22b8) && // Motorola - (info->dev_vendor != 0x0955) && // Nvidia - (info->dev_vendor != 0x413c) && // DELL - (info->dev_vendor != 0x2314) && // INQ Mobile - (info->dev_vendor != 0x0b05) && // Asus - (info->dev_vendor != 0x0bb4)) // HTC - return -1; - if(info->ifc_class != 0xff) return -1; - if(info->ifc_subclass != 0x42) return -1; - if(info->ifc_protocol != 0x03) return -1; +static int match_fastboot_with_serial(usb_ifc_info* info, const char* local_serial) { + // Require a matching vendor id if the user specified one with -i. + if (vendor_id != 0 && info->dev_vendor != vendor_id) { + return -1; + } + + if (info->ifc_class != 0xff || info->ifc_subclass != 0x42 || info->ifc_protocol != 0x03) { + return -1; + } + // require matching serial number or device path if requested // at the command line with the -s option. if (local_serial && (strcmp(local_serial, info->serial_number) != 0 && @@ -215,14 +192,12 @@ int match_fastboot_with_serial(usb_ifc_info *info, const char *local_serial) return 0; } -int match_fastboot(usb_ifc_info *info) -{ +static int match_fastboot(usb_ifc_info* info) { return match_fastboot_with_serial(info, serial); } -int list_devices_callback(usb_ifc_info *info) -{ - if (match_fastboot_with_serial(info, NULL) == 0) { +static int list_devices_callback(usb_ifc_info* info) { + if (match_fastboot_with_serial(info, nullptr) == 0) { const char* serial = info->serial_number; if (!info->writable) { serial = "no permissions"; // like "adb devices" @@ -243,8 +218,7 @@ int list_devices_callback(usb_ifc_info *info) return -1; } -usb_handle *open_device(void) -{ +static usb_handle* open_device() { static usb_handle *usb = 0; int announce = 1; @@ -255,103 +229,99 @@ usb_handle *open_device(void) if(usb) return usb; if(announce) { announce = 0; - fprintf(stderr,"< waiting for device >\n"); + fprintf(stderr, "< waiting for %s >\n", serial ? serial : "any device"); } usleep(1000); } } -void list_devices(void) { +static void list_devices() { // We don't actually open a USB device here, // just getting our callback called so we can // list all the connected devices. usb_open(list_devices_callback); } -void usage(void) -{ +static void usage() { fprintf(stderr, /* 1234567890123456789012345678901234567890123456789012345678901234567890123456 */ "usage: fastboot [