turn recovery into a C++ binary
Change-Id: I423a23581048d451d53eef46e5f5eac485b77555
This commit is contained in:
parent
d0181b8fcd
commit
28ce47cfa6
20 changed files with 253 additions and 147 deletions
14
Android.mk
14
Android.mk
|
@ -4,12 +4,12 @@ include $(CLEAR_VARS)
|
|||
commands_recovery_local_path := $(LOCAL_PATH)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
recovery.c \
|
||||
bootloader.c \
|
||||
install.c \
|
||||
roots.c \
|
||||
ui.c \
|
||||
verifier.c
|
||||
recovery.cpp \
|
||||
bootloader.cpp \
|
||||
install.cpp \
|
||||
roots.cpp \
|
||||
ui.cpp \
|
||||
verifier.cpp
|
||||
|
||||
LOCAL_MODULE := recovery
|
||||
|
||||
|
@ -50,7 +50,7 @@ include $(BUILD_EXECUTABLE)
|
|||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := verifier_test.c verifier.c
|
||||
LOCAL_SRC_FILES := verifier_test.cpp verifier.cpp
|
||||
|
||||
LOCAL_MODULE := verifier_test
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#ifndef _RECOVERY_BOOTLOADER_H
|
||||
#define _RECOVERY_BOOTLOADER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Bootloader Message
|
||||
*
|
||||
* This structure describes the content of a block in flash
|
||||
|
@ -47,4 +51,8 @@ struct bootloader_message {
|
|||
int get_bootloader_message(struct bootloader_message *out);
|
||||
int set_bootloader_message(const struct bootloader_message *in);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
63
common.h
63
common.h
|
@ -19,61 +19,12 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
// Initialize the graphics system.
|
||||
void ui_init();
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Use KEY_* codes from <linux/input.h> or KEY_DREAM_* from "minui/minui.h".
|
||||
int ui_wait_key(); // waits for a key/button press, returns the code
|
||||
int ui_key_pressed(int key); // returns >0 if the code is currently pressed
|
||||
int ui_text_visible(); // returns >0 if text log is currently visible
|
||||
int ui_text_ever_visible(); // returns >0 if text log was ever visible
|
||||
void ui_show_text(int visible);
|
||||
void ui_clear_key_queue();
|
||||
|
||||
// Write a message to the on-screen log shown with Alt-L (also to stderr).
|
||||
// The screen is small, and users may need to report these messages to support,
|
||||
// so keep the output short and not too cryptic.
|
||||
void ui_print(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
// Display some header text followed by a menu of items, which appears
|
||||
// at the top of the screen (in place of any scrolling ui_print()
|
||||
// output, if necessary).
|
||||
void ui_start_menu(char** headers, char** items, int initial_selection);
|
||||
// Set the menu highlight to the given index, and return it (capped to
|
||||
// the range [0..numitems).
|
||||
int ui_menu_select(int sel);
|
||||
// End menu mode, resetting the text overlay so that ui_print()
|
||||
// statements will be displayed.
|
||||
void ui_end_menu();
|
||||
|
||||
// Set the icon (normally the only thing visible besides the progress bar).
|
||||
enum {
|
||||
BACKGROUND_ICON_NONE,
|
||||
BACKGROUND_ICON_INSTALLING,
|
||||
BACKGROUND_ICON_ERROR,
|
||||
NUM_BACKGROUND_ICONS
|
||||
};
|
||||
void ui_set_background(int icon);
|
||||
|
||||
// Show a progress bar and define the scope of the next operation:
|
||||
// portion - fraction of the progress bar the next operation will use
|
||||
// seconds - expected time interval (progress bar moves at this minimum rate)
|
||||
void ui_show_progress(float portion, int seconds);
|
||||
void ui_set_progress(float fraction); // 0.0 - 1.0 within the defined scope
|
||||
|
||||
// Default allocation of progress bar segments to operations
|
||||
static const int VERIFICATION_PROGRESS_TIME = 60;
|
||||
static const float VERIFICATION_PROGRESS_FRACTION = 0.25;
|
||||
static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4;
|
||||
static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1;
|
||||
|
||||
// Show a rotating "barberpole" for ongoing operations. Updates automatically.
|
||||
void ui_show_indeterminate_progress();
|
||||
|
||||
// Hide and reset the progress bar.
|
||||
void ui_reset_progress();
|
||||
|
||||
#define LOGE(...) ui_print("E:" __VA_ARGS__)
|
||||
// TODO: restore ui_print for LOGE
|
||||
#define LOGE(...) fprintf(stdout, "E:" __VA_ARGS__)
|
||||
#define LOGW(...) fprintf(stdout, "W:" __VA_ARGS__)
|
||||
#define LOGI(...) fprintf(stdout, "I:" __VA_ARGS__)
|
||||
|
||||
|
@ -129,4 +80,8 @@ typedef struct {
|
|||
// fopen a file, mounting volumes and making parent dirs as necessary.
|
||||
FILE* fopen_path(const char *path, const char *mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RECOVERY_COMMON_H
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "mtdutils/mtdutils.h"
|
||||
#include "roots.h"
|
||||
#include "verifier.h"
|
||||
#include "ui.h"
|
||||
|
||||
#define ASSUMED_UPDATE_BINARY_NAME "META-INF/com/google/android/update-binary"
|
||||
#define PUBLIC_KEYS_FILE "/res/keys"
|
||||
|
@ -46,7 +47,7 @@ try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {
|
|||
return INSTALL_CORRUPT;
|
||||
}
|
||||
|
||||
char* binary = "/tmp/update_binary";
|
||||
const char* binary = "/tmp/update_binary";
|
||||
unlink(binary);
|
||||
int fd = creat(binary, 0755);
|
||||
if (fd < 0) {
|
||||
|
@ -100,18 +101,19 @@ try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {
|
|||
// - the name of the package zip file.
|
||||
//
|
||||
|
||||
char** args = malloc(sizeof(char*) * 5);
|
||||
const char** args = (const char**)malloc(sizeof(char*) * 5);
|
||||
args[0] = binary;
|
||||
args[1] = EXPAND(RECOVERY_API_VERSION); // defined in Android.mk
|
||||
args[2] = malloc(10);
|
||||
sprintf(args[2], "%d", pipefd[1]);
|
||||
char* temp = (char*)malloc(10);
|
||||
sprintf(temp, "%d", pipefd[1]);
|
||||
args[2] = temp;
|
||||
args[3] = (char*)path;
|
||||
args[4] = NULL;
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(pipefd[0]);
|
||||
execv(binary, args);
|
||||
execv(binary, (char* const*)args);
|
||||
fprintf(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
|
||||
_exit(-1);
|
||||
}
|
||||
|
@ -188,31 +190,32 @@ load_keys(const char* filename, int* numKeys) {
|
|||
goto exit;
|
||||
}
|
||||
|
||||
int i;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
++*numKeys;
|
||||
out = realloc(out, *numKeys * sizeof(RSAPublicKey));
|
||||
RSAPublicKey* key = out + (*numKeys - 1);
|
||||
if (fscanf(f, " { %i , 0x%x , { %u",
|
||||
&(key->len), &(key->n0inv), &(key->n[0])) != 3) {
|
||||
goto exit;
|
||||
}
|
||||
if (key->len != RSANUMWORDS) {
|
||||
LOGE("key length (%d) does not match expected size\n", key->len);
|
||||
goto exit;
|
||||
}
|
||||
for (i = 1; i < key->len; ++i) {
|
||||
if (fscanf(f, " , %u", &(key->n[i])) != 1) goto exit;
|
||||
}
|
||||
if (fscanf(f, " } , { %u", &(key->rr[0])) != 1) goto exit;
|
||||
for (i = 1; i < key->len; ++i) {
|
||||
if (fscanf(f, " , %u", &(key->rr[i])) != 1) goto exit;
|
||||
}
|
||||
fscanf(f, " } } ");
|
||||
{
|
||||
int i;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
++*numKeys;
|
||||
out = (RSAPublicKey*)realloc(out, *numKeys * sizeof(RSAPublicKey));
|
||||
RSAPublicKey* key = out + (*numKeys - 1);
|
||||
if (fscanf(f, " { %i , 0x%x , { %u",
|
||||
&(key->len), &(key->n0inv), &(key->n[0])) != 3) {
|
||||
goto exit;
|
||||
}
|
||||
if (key->len != RSANUMWORDS) {
|
||||
LOGE("key length (%d) does not match expected size\n", key->len);
|
||||
goto exit;
|
||||
}
|
||||
for (i = 1; i < key->len; ++i) {
|
||||
if (fscanf(f, " , %u", &(key->n[i])) != 1) goto exit;
|
||||
}
|
||||
if (fscanf(f, " } , { %u", &(key->rr[0])) != 1) goto exit;
|
||||
for (i = 1; i < key->len; ++i) {
|
||||
if (fscanf(f, " , %u", &(key->rr[i])) != 1) goto exit;
|
||||
}
|
||||
fscanf(f, " } } ");
|
||||
|
||||
// if the line ends in a comma, this file has more keys.
|
||||
switch (fgetc(f)) {
|
||||
// if the line ends in a comma, this file has more keys.
|
||||
switch (fgetc(f)) {
|
||||
case ',':
|
||||
// more keys to come.
|
||||
break;
|
||||
|
@ -224,6 +227,7 @@ load_keys(const char* filename, int* numKeys) {
|
|||
default:
|
||||
LOGE("unexpected character between keys\n");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT };
|
||||
// Install the package specified by root_path. If INSTALL_SUCCESS is
|
||||
// returned and *wipe_cache is true on exit, caller should wipe the
|
||||
|
@ -26,4 +30,8 @@ enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT };
|
|||
int install_package(const char *root_path, int* wipe_cache,
|
||||
const char* install_file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RECOVERY_INSTALL_H_
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* gr_surface;
|
||||
typedef unsigned short gr_pixel;
|
||||
|
||||
|
@ -69,4 +73,8 @@ void ev_dispatch(void);
|
|||
int res_create_surface(const char* name, gr_surface* pSurface);
|
||||
void res_free_surface(gr_surface surface);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include <stdbool.h>
|
||||
#include <utime.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Like "mkdir -p", try to guarantee that all directories
|
||||
* specified in path are present, creating as many directories
|
||||
* as necessary. The specified mode is passed to all mkdir
|
||||
|
@ -48,4 +52,8 @@ int dirUnlinkHierarchy(const char *path);
|
|||
int dirSetHierarchyPermissions(const char *path,
|
||||
int uid, int gid, int dirMode, int fileMode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MINZIP_DIRUTIL_H_
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
#include "Hash.h"
|
||||
#include "SysUtil.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* One entry in the Zip archive. Treat this as opaque -- use accessors below.
|
||||
*
|
||||
|
@ -210,4 +214,8 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
|
|||
int flags, const struct utimbuf *timestamp,
|
||||
void (*callback)(const char *fn, void*), void *cookie);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_MINZIP_ZIP*/
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#ifndef MTDUTILS_MOUNTS_H_
|
||||
#define MTDUTILS_MOUNTS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct MountedVolume MountedVolume;
|
||||
|
||||
int scan_mounted_volumes(void);
|
||||
|
@ -30,4 +34,8 @@ int unmount_mounted_volume(const MountedVolume *volume);
|
|||
|
||||
int remount_read_only(const MountedVolume* volume);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MTDUTILS_MOUNTS_H_
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
#include <sys/types.h> // for size_t, etc.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct MtdPartition MtdPartition;
|
||||
|
||||
int mtd_scan_partitions(void);
|
||||
|
@ -53,4 +57,8 @@ off_t mtd_erase_blocks(MtdWriteContext *, int blocks); /* 0 ok, -1 for all */
|
|||
off_t mtd_find_write_start(MtdWriteContext *ctx, off_t pos);
|
||||
int mtd_write_close(MtdWriteContext *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MTDUTILS_H_
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "minzip/DirUtil.h"
|
||||
#include "roots.h"
|
||||
#include "recovery_ui.h"
|
||||
#include "ui.h"
|
||||
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "send_intent", required_argument, NULL, 's' },
|
||||
|
@ -349,7 +350,7 @@ copy_sideloaded_package(const char* original_path) {
|
|||
strcpy(copy_path, SIDELOAD_TEMP_DIR);
|
||||
strcat(copy_path, "/package.zip");
|
||||
|
||||
char* buffer = malloc(BUFSIZ);
|
||||
char* buffer = (char*)malloc(BUFSIZ);
|
||||
if (buffer == NULL) {
|
||||
LOGE("Failed to allocate buffer\n");
|
||||
return NULL;
|
||||
|
@ -396,22 +397,22 @@ copy_sideloaded_package(const char* original_path) {
|
|||
return strdup(copy_path);
|
||||
}
|
||||
|
||||
static char**
|
||||
static const char**
|
||||
prepend_title(const char** headers) {
|
||||
char* title[] = { "Android system recovery <"
|
||||
EXPAND(RECOVERY_API_VERSION) "e>",
|
||||
"",
|
||||
NULL };
|
||||
const char* title[] = { "Android system recovery <"
|
||||
EXPAND(RECOVERY_API_VERSION) "e>",
|
||||
"",
|
||||
NULL };
|
||||
|
||||
// count the number of lines in our title, plus the
|
||||
// caller-provided headers.
|
||||
int count = 0;
|
||||
char** p;
|
||||
const char** p;
|
||||
for (p = title; *p; ++p, ++count);
|
||||
for (p = headers; *p; ++p, ++count);
|
||||
|
||||
char** new_headers = malloc((count+1) * sizeof(char*));
|
||||
char** h = new_headers;
|
||||
const char** new_headers = (const char**)malloc((count+1) * sizeof(char*));
|
||||
const char** h = new_headers;
|
||||
for (p = title; *p; ++p, ++h) *h = *p;
|
||||
for (p = headers; *p; ++p, ++h) *h = *p;
|
||||
*h = NULL;
|
||||
|
@ -420,8 +421,8 @@ prepend_title(const char** headers) {
|
|||
}
|
||||
|
||||
static int
|
||||
get_menu_selection(char** headers, char** items, int menu_only,
|
||||
int initial_selection) {
|
||||
get_menu_selection(const char* const * headers, const char* const * items,
|
||||
int menu_only, int initial_selection) {
|
||||
// throw away keys pressed previously, so user doesn't
|
||||
// accidentally trigger menu items.
|
||||
ui_clear_key_queue();
|
||||
|
@ -495,14 +496,14 @@ update_directory(const char* path, const char* unmount_when_done,
|
|||
return 0;
|
||||
}
|
||||
|
||||
char** headers = prepend_title(MENU_HEADERS);
|
||||
const char** headers = prepend_title(MENU_HEADERS);
|
||||
|
||||
int d_size = 0;
|
||||
int d_alloc = 10;
|
||||
char** dirs = malloc(d_alloc * sizeof(char*));
|
||||
char** dirs = (char**)malloc(d_alloc * sizeof(char*));
|
||||
int z_size = 1;
|
||||
int z_alloc = 10;
|
||||
char** zips = malloc(z_alloc * sizeof(char*));
|
||||
char** zips = (char**)malloc(z_alloc * sizeof(char*));
|
||||
zips[0] = strdup("../");
|
||||
|
||||
while ((de = readdir(d)) != NULL) {
|
||||
|
@ -516,9 +517,9 @@ update_directory(const char* path, const char* unmount_when_done,
|
|||
|
||||
if (d_size >= d_alloc) {
|
||||
d_alloc *= 2;
|
||||
dirs = realloc(dirs, d_alloc * sizeof(char*));
|
||||
dirs = (char**)realloc(dirs, d_alloc * sizeof(char*));
|
||||
}
|
||||
dirs[d_size] = malloc(name_len + 2);
|
||||
dirs[d_size] = (char*)malloc(name_len + 2);
|
||||
strcpy(dirs[d_size], de->d_name);
|
||||
dirs[d_size][name_len] = '/';
|
||||
dirs[d_size][name_len+1] = '\0';
|
||||
|
@ -528,7 +529,7 @@ update_directory(const char* path, const char* unmount_when_done,
|
|||
strncasecmp(de->d_name + (name_len-4), ".zip", 4) == 0) {
|
||||
if (z_size >= z_alloc) {
|
||||
z_alloc *= 2;
|
||||
zips = realloc(zips, z_alloc * sizeof(char*));
|
||||
zips = (char**)realloc(zips, z_alloc * sizeof(char*));
|
||||
}
|
||||
zips[z_size++] = strdup(de->d_name);
|
||||
}
|
||||
|
@ -541,7 +542,7 @@ update_directory(const char* path, const char* unmount_when_done,
|
|||
// append dirs to the zips list
|
||||
if (d_size + z_size + 1 > z_alloc) {
|
||||
z_alloc = d_size + z_size + 1;
|
||||
zips = realloc(zips, z_alloc * sizeof(char*));
|
||||
zips = (char**)realloc(zips, z_alloc * sizeof(char*));
|
||||
}
|
||||
memcpy(zips + z_size, dirs, d_size * sizeof(char*));
|
||||
free(dirs);
|
||||
|
@ -606,28 +607,28 @@ update_directory(const char* path, const char* unmount_when_done,
|
|||
static void
|
||||
wipe_data(int confirm) {
|
||||
if (confirm) {
|
||||
static char** title_headers = NULL;
|
||||
static const char** title_headers = NULL;
|
||||
|
||||
if (title_headers == NULL) {
|
||||
char* headers[] = { "Confirm wipe of all user data?",
|
||||
" THIS CAN NOT BE UNDONE.",
|
||||
"",
|
||||
NULL };
|
||||
const char* headers[] = { "Confirm wipe of all user data?",
|
||||
" THIS CAN NOT BE UNDONE.",
|
||||
"",
|
||||
NULL };
|
||||
title_headers = prepend_title((const char**)headers);
|
||||
}
|
||||
|
||||
char* items[] = { " No",
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
" Yes -- delete all user data", // [7]
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
NULL };
|
||||
const char* items[] = { " No",
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
" Yes -- delete all user data", // [7]
|
||||
" No",
|
||||
" No",
|
||||
" No",
|
||||
NULL };
|
||||
|
||||
int chosen_item = get_menu_selection(title_headers, items, 1, 0);
|
||||
if (chosen_item != 7) {
|
||||
|
@ -644,7 +645,7 @@ wipe_data(int confirm) {
|
|||
|
||||
static void
|
||||
prompt_and_wait() {
|
||||
char** headers = prepend_title((const char**)MENU_HEADERS);
|
||||
const char** headers = prepend_title((const char**)MENU_HEADERS);
|
||||
|
||||
for (;;) {
|
||||
finish_recovery(NULL);
|
||||
|
@ -777,7 +778,7 @@ main(int argc, char **argv) {
|
|||
// "/cache/foo".
|
||||
if (strncmp(update_package, "CACHE:", 6) == 0) {
|
||||
int len = strlen(update_package) + 10;
|
||||
char* modified_path = malloc(len);
|
||||
char* modified_path = (char*)malloc(len);
|
||||
strlcpy(modified_path, "/cache/", len);
|
||||
strlcat(modified_path, update_package+6, len);
|
||||
printf("(replacing path \"%s\" with \"%s\")\n",
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Called before UI library is initialized. Can change things like
|
||||
// how many frames are included in various animations, etc.
|
||||
extern void device_ui_init(UIParameters* ui_parameters);
|
||||
|
@ -84,4 +88,8 @@ extern char* MENU_HEADERS[];
|
|||
// Text of menu items.
|
||||
extern char* MENU_ITEMS[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,7 +33,7 @@ static Volume* device_volumes = NULL;
|
|||
|
||||
static int parse_options(char* options, Volume* volume) {
|
||||
char* option;
|
||||
while (option = strtok(options, ",")) {
|
||||
while ((option = strtok(options, ","))) {
|
||||
options = NULL;
|
||||
|
||||
if (strncmp(option, "length=", 7) == 0) {
|
||||
|
@ -48,7 +48,7 @@ static int parse_options(char* options, Volume* volume) {
|
|||
|
||||
void load_volume_table() {
|
||||
int alloc = 2;
|
||||
device_volumes = malloc(alloc * sizeof(Volume));
|
||||
device_volumes = (Volume*)malloc(alloc * sizeof(Volume));
|
||||
|
||||
// Insert an entry for /tmp, which is the ramdisk and is always mounted.
|
||||
device_volumes[0].mount_point = "/tmp";
|
||||
|
@ -91,7 +91,7 @@ void load_volume_table() {
|
|||
if (mount_point && fs_type && device) {
|
||||
while (num_volumes >= alloc) {
|
||||
alloc *= 2;
|
||||
device_volumes = realloc(device_volumes, alloc*sizeof(Volume));
|
||||
device_volumes = (Volume*)realloc(device_volumes, alloc*sizeof(Volume));
|
||||
}
|
||||
device_volumes[num_volumes].mount_point = strdup(mount_point);
|
||||
device_volumes[num_volumes].fs_type = strdup(fs_type);
|
8
roots.h
8
roots.h
|
@ -19,6 +19,10 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Load and parse volume data from /etc/recovery.fstab.
|
||||
void load_volume_table();
|
||||
|
||||
|
@ -38,4 +42,8 @@ int ensure_path_unmounted(const char* path);
|
|||
// it is mounted.
|
||||
int format_volume(const char* volume);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RECOVERY_ROOTS_H_
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <cutils/android_reboot.h>
|
||||
#include "minui/minui.h"
|
||||
#include "recovery_ui.h"
|
||||
#include "ui.h"
|
||||
|
||||
#define MAX_COLS 96
|
||||
#define MAX_ROWS 32
|
||||
|
@ -397,8 +398,8 @@ void ui_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
gProgressBarIndeterminate = malloc(ui_parameters.indeterminate_frames *
|
||||
sizeof(gr_surface));
|
||||
gProgressBarIndeterminate = (gr_surface*)malloc(ui_parameters.indeterminate_frames *
|
||||
sizeof(gr_surface));
|
||||
for (i = 0; i < ui_parameters.indeterminate_frames; ++i) {
|
||||
char filename[40];
|
||||
// "indeterminate01.png", "indeterminate02.png", ...
|
||||
|
@ -410,8 +411,8 @@ void ui_init(void)
|
|||
}
|
||||
|
||||
if (ui_parameters.installing_frames > 0) {
|
||||
gInstallationOverlay = malloc(ui_parameters.installing_frames *
|
||||
sizeof(gr_surface));
|
||||
gInstallationOverlay = (gr_surface*)malloc(ui_parameters.installing_frames *
|
||||
sizeof(gr_surface));
|
||||
for (i = 0; i < ui_parameters.installing_frames; ++i) {
|
||||
char filename[40];
|
||||
// "icon_installing_overlay01.png",
|
||||
|
@ -529,7 +530,8 @@ void ui_print(const char *fmt, ...)
|
|||
pthread_mutex_unlock(&gUpdateMutex);
|
||||
}
|
||||
|
||||
void ui_start_menu(char** headers, char** items, int initial_selection) {
|
||||
void ui_start_menu(const char* const * headers, const char* const * items,
|
||||
int initial_selection) {
|
||||
int i;
|
||||
pthread_mutex_lock(&gUpdateMutex);
|
||||
if (text_rows > 0 && text_cols > 0) {
|
75
ui.h
Normal file
75
ui.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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 RECOVERY_UI_H
|
||||
#define RECOVERY_UI_H
|
||||
|
||||
// Initialize the graphics system.
|
||||
void ui_init();
|
||||
|
||||
// Use KEY_* codes from <linux/input.h> or KEY_DREAM_* from "minui/minui.h".
|
||||
int ui_wait_key(); // waits for a key/button press, returns the code
|
||||
int ui_key_pressed(int key); // returns >0 if the code is currently pressed
|
||||
int ui_text_visible(); // returns >0 if text log is currently visible
|
||||
int ui_text_ever_visible(); // returns >0 if text log was ever visible
|
||||
void ui_show_text(int visible);
|
||||
void ui_clear_key_queue();
|
||||
|
||||
// Write a message to the on-screen log shown with Alt-L (also to stderr).
|
||||
// The screen is small, and users may need to report these messages to support,
|
||||
// so keep the output short and not too cryptic.
|
||||
void ui_print(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
// Display some header text followed by a menu of items, which appears
|
||||
// at the top of the screen (in place of any scrolling ui_print()
|
||||
// output, if necessary).
|
||||
void ui_start_menu(const char* const * headers, const char* const * items,
|
||||
int initial_selection);
|
||||
// Set the menu highlight to the given index, and return it (capped to
|
||||
// the range [0..numitems).
|
||||
int ui_menu_select(int sel);
|
||||
// End menu mode, resetting the text overlay so that ui_print()
|
||||
// statements will be displayed.
|
||||
void ui_end_menu();
|
||||
|
||||
// Set the icon (normally the only thing visible besides the progress bar).
|
||||
enum {
|
||||
BACKGROUND_ICON_NONE,
|
||||
BACKGROUND_ICON_INSTALLING,
|
||||
BACKGROUND_ICON_ERROR,
|
||||
NUM_BACKGROUND_ICONS
|
||||
};
|
||||
void ui_set_background(int icon);
|
||||
|
||||
// Show a progress bar and define the scope of the next operation:
|
||||
// portion - fraction of the progress bar the next operation will use
|
||||
// seconds - expected time interval (progress bar moves at this minimum rate)
|
||||
void ui_show_progress(float portion, int seconds);
|
||||
void ui_set_progress(float fraction); // 0.0 - 1.0 within the defined scope
|
||||
|
||||
// Default allocation of progress bar segments to operations
|
||||
static const int VERIFICATION_PROGRESS_TIME = 60;
|
||||
static const float VERIFICATION_PROGRESS_FRACTION = 0.25;
|
||||
static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4;
|
||||
static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1;
|
||||
|
||||
// Show a rotating "barberpole" for ongoing operations. Updates automatically.
|
||||
void ui_show_indeterminate_progress();
|
||||
|
||||
// Hide and reset the progress bar.
|
||||
void ui_reset_progress();
|
||||
|
||||
#endif // RECOVERY_UI_H
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "verifier.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "mincrypt/rsa.h"
|
||||
#include "mincrypt/sha.h"
|
||||
|
@ -69,8 +70,8 @@ int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKey
|
|||
return VERIFY_FAILURE;
|
||||
}
|
||||
|
||||
int comment_size = footer[4] + (footer[5] << 8);
|
||||
int signature_start = footer[0] + (footer[1] << 8);
|
||||
size_t comment_size = footer[4] + (footer[5] << 8);
|
||||
size_t signature_start = footer[0] + (footer[1] << 8);
|
||||
LOGI("comment is %d bytes; signature %d bytes from end\n",
|
||||
comment_size, signature_start);
|
||||
|
||||
|
@ -99,7 +100,7 @@ int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKey
|
|||
// bytes) and the comment data.
|
||||
size_t signed_len = ftell(f) + EOCD_HEADER_SIZE - 2;
|
||||
|
||||
unsigned char* eocd = malloc(eocd_size);
|
||||
unsigned char* eocd = (unsigned char*)malloc(eocd_size);
|
||||
if (eocd == NULL) {
|
||||
LOGE("malloc for EOCD record failed\n");
|
||||
fclose(f);
|
||||
|
@ -120,7 +121,7 @@ int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKey
|
|||
return VERIFY_FAILURE;
|
||||
}
|
||||
|
||||
int i;
|
||||
size_t i;
|
||||
for (i = 4; i < eocd_size-3; ++i) {
|
||||
if (eocd[i ] == 0x50 && eocd[i+1] == 0x4b &&
|
||||
eocd[i+2] == 0x05 && eocd[i+3] == 0x06) {
|
||||
|
@ -138,7 +139,7 @@ int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKey
|
|||
|
||||
SHA_CTX ctx;
|
||||
SHA_init(&ctx);
|
||||
unsigned char* buffer = malloc(BUFFER_SIZE);
|
||||
unsigned char* buffer = (unsigned char*)malloc(BUFFER_SIZE);
|
||||
if (buffer == NULL) {
|
||||
LOGE("failed to alloc memory for sha1 buffer\n");
|
||||
fclose(f);
|
||||
|
@ -149,7 +150,7 @@ int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKey
|
|||
size_t so_far = 0;
|
||||
fseek(f, 0, SEEK_SET);
|
||||
while (so_far < signed_len) {
|
||||
int size = BUFFER_SIZE;
|
||||
size_t size = BUFFER_SIZE;
|
||||
if (signed_len - so_far < size) size = signed_len - so_far;
|
||||
if (fread(buffer, 1, size, f) != size) {
|
||||
LOGE("failed to read data from %s (%s)\n", path, strerror(errno));
|
|
@ -1,11 +1,7 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# A test suite for applypatch. Run in a client where you have done
|
||||
# envsetup, choosecombo, etc.
|
||||
#
|
||||
# DO NOT RUN THIS ON A DEVICE YOU CARE ABOUT. It will mess up your
|
||||
# system partition.
|
||||
#
|
||||
# A test suite for recovery's package signature verifier. Run in a
|
||||
# client where you have done envsetup, lunch, etc.
|
||||
#
|
||||
# TODO: find some way to get this run regularly along with the rest of
|
||||
# the tests.
|
||||
|
|
Loading…
Reference in a new issue