Zip install works again

This commit is contained in:
Dees_Troy
2012-09-10 20:32:10 -04:00
parent 63c8df756b
commit 657c309486
6 changed files with 454 additions and 207 deletions
+400 -185
View File
@@ -43,8 +43,6 @@
#include "bootloader.h"
#include "common.h"
#include "extra-functions.h"
#include "cutils/properties.h"
#include "install.h"
#include "minuitwrp/minui.h"
#include "minzip/DirUtil.h"
#include "minzip/Zip.h"
@@ -52,13 +50,22 @@
#include "roots.h"
#include "data.h"
#include "variables.h"
#include "install.h"
#include "mincrypt/rsa.h"
#include "verifier.h"
#include "mincrypt/sha.h"
#ifndef PUBLIC_KEYS_FILE
#define PUBLIC_KEYS_FILE "/res/keys"
#endif
#ifndef ASSUMED_UPDATE_BINARY_NAME
#define ASSUMED_UPDATE_BINARY_NAME "META-INF/com/google/android/update-binary"
#endif
enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT };
//kang system() from bionic/libc/unistd and rename it __system() so we can be even more hackish :)
#undef _PATH_BSHELL
#define _PATH_BSHELL "/sbin/sh"
static const char *SIDELOAD_TEMP_DIR = "/tmp/sideload";
extern char **environ;
int __system(const char *command) {
@@ -414,43 +421,400 @@ int check_md5(char* path) {
return o;
}
static int really_install_package(const char *path, int* wipe_cache)
{
//ui->SetBackground(RecoveryUI::INSTALLING);
LOGI("Finding update package...\n");
//ui->SetProgressType(RecoveryUI::INDETERMINATE);
LOGI("Update location: %s\n", path);
static void set_sdcard_update_bootloader_message() {
struct bootloader_message boot;
memset(&boot, 0, sizeof(boot));
strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));
set_bootloader_message(&boot);
}
if (ensure_path_mounted(path) != 0) {
LOGE("Can't mount %s\n", path);
int TWtry_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {
const ZipEntry* binary_entry =
mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
if (binary_entry == NULL) {
mzCloseZipArchive(zip);
return INSTALL_CORRUPT;
}
LOGI("Opening update package...\n");
int numKeys;
/*RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
if (loadedKeys == NULL) {
LOGE("Failed to load keys\n");
return INSTALL_CORRUPT;
const char* binary = "/tmp/update_binary";
unlink(binary);
int fd = creat(binary, 0755);
if (fd < 0) {
mzCloseZipArchive(zip);
LOGE("Can't make %s\n", binary);
return INSTALL_ERROR;
}
LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);*/
bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
close(fd);
mzCloseZipArchive(zip);
// Give verification half the progress bar...
LOGI("Verifying update package...\n");
//ui->SetProgressType(RecoveryUI::DETERMINATE);
//ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
if (!ok) {
LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
return INSTALL_ERROR;
}
int err;
/*err = verify_file(path, loadedKeys, numKeys);
free(loadedKeys);
LOGI("verify_file returned %d\n", err);
if (err != VERIFY_SUCCESS) {
LOGE("signature verification failed\n");
return INSTALL_CORRUPT;
}*/
int pipefd[2];
pipe(pipefd);
/* Try to open the package.
// When executing the update binary contained in the package, the
// arguments passed are:
//
// - the version number for this interface
//
// - an fd to which the program can write in order to update the
// progress bar. The program can write single-line commands:
//
// progress <frac> <secs>
// fill up the next <frac> part of of the progress bar
// over <secs> seconds. If <secs> is zero, use
// set_progress commands to manually control the
// progress of this segment of the bar
//
// set_progress <frac>
// <frac> should be between 0.0 and 1.0; sets the
// progress bar within the segment defined by the most
// recent progress command.
//
// firmware <"hboot"|"radio"> <filename>
// arrange to install the contents of <filename> in the
// given partition on reboot.
//
// (API v2: <filename> may start with "PACKAGE:" to
// indicate taking a file from the OTA package.)
//
// (API v3: this command no longer exists.)
//
// ui_print <string>
// display <string> on the screen.
//
// - the name of the package zip file.
//
const char** args = (const char**)malloc(sizeof(char*) * 5);
args[0] = binary;
args[1] = EXPAND(RECOVERY_API_VERSION); // defined in Android.mk
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, (char* const*)args);
fprintf(stdout, "E:Can't run %s (error)\n", binary);
_exit(-1);
}
close(pipefd[1]);
*wipe_cache = 0;
char buffer[1024];
FILE* from_child = fdopen(pipefd[0], "r");
LOGI("8\n");
while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
char* command = strtok(buffer, " \n");
if (command == NULL) {
continue;
} else if (strcmp(command, "progress") == 0) {
char* fraction_s = strtok(NULL, " \n");
char* seconds_s = strtok(NULL, " \n");
float fraction = strtof(fraction_s, NULL);
int seconds = strtol(seconds_s, NULL, 10);
//ui->ShowProgress(fraction * (1-VERIFICATION_PROGRESS_FRACTION), seconds);
} else if (strcmp(command, "set_progress") == 0) {
char* fraction_s = strtok(NULL, " \n");
float fraction = strtof(fraction_s, NULL);
//ui->SetProgress(fraction);
} else if (strcmp(command, "ui_print") == 0) {
char* str = strtok(NULL, "\n");
if (str) {
//ui->Print("%s", str);
} else {
//ui->Print("\n");
}
} else if (strcmp(command, "wipe_cache") == 0) {
*wipe_cache = 1;
} else if (strcmp(command, "clear_display") == 0) {
//ui->SetBackground(RecoveryUI::NONE);
} else {
LOGE("unknown command [%s]\n", command);
}
}
fclose(from_child);
int status;
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
return INSTALL_ERROR;
}
return INSTALL_SUCCESS;
}
// Look for an RSA signature embedded in the .ZIP file comment given
// the path to the zip. Verify it matches one of the given public
// keys.
//
// Return VERIFY_SUCCESS, VERIFY_FAILURE (if any error is encountered
// or no key matches the signature).
int TWverify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKeys) {
//ui->SetProgress(0.0);
FILE* f = fopen(path, "rb");
if (f == NULL) {
LOGE("failed to open %s (%s)\n", path, strerror(errno));
return VERIFY_FAILURE;
}
// An archive with a whole-file signature will end in six bytes:
//
// (2-byte signature start) $ff $ff (2-byte comment size)
//
// (As far as the ZIP format is concerned, these are part of the
// archive comment.) We start by reading this footer, this tells
// us how far back from the end we have to start reading to find
// the whole comment.
#define FOOTER_SIZE 6
if (fseek(f, -FOOTER_SIZE, SEEK_END) != 0) {
LOGE("failed to seek in %s (%s)\n", path, strerror(errno));
fclose(f);
return VERIFY_FAILURE;
}
unsigned char footer[FOOTER_SIZE];
if (fread(footer, 1, FOOTER_SIZE, f) != FOOTER_SIZE) {
LOGE("failed to read footer from %s (%s)\n", path, strerror(errno));
fclose(f);
return VERIFY_FAILURE;
}
if (footer[2] != 0xff || footer[3] != 0xff) {
fclose(f);
return VERIFY_FAILURE;
}
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);
if (signature_start - FOOTER_SIZE < RSANUMBYTES) {
// "signature" block isn't big enough to contain an RSA block.
LOGE("signature is too short\n");
fclose(f);
return VERIFY_FAILURE;
}
#define EOCD_HEADER_SIZE 22
// The end-of-central-directory record is 22 bytes plus any
// comment length.
size_t eocd_size = comment_size + EOCD_HEADER_SIZE;
if (fseek(f, -eocd_size, SEEK_END) != 0) {
LOGE("failed to seek in %s (%s)\n", path, strerror(errno));
fclose(f);
return VERIFY_FAILURE;
}
// Determine how much of the file is covered by the signature.
// This is everything except the signature data and length, which
// includes all of the EOCD except for the comment length field (2
// bytes) and the comment data.
size_t signed_len = ftell(f) + EOCD_HEADER_SIZE - 2;
unsigned char* eocd = (unsigned char*)malloc(eocd_size);
if (eocd == NULL) {
LOGE("malloc for EOCD record failed\n");
fclose(f);
return VERIFY_FAILURE;
}
if (fread(eocd, 1, eocd_size, f) != eocd_size) {
LOGE("failed to read eocd from %s (%s)\n", path, strerror(errno));
fclose(f);
return VERIFY_FAILURE;
}
// If this is really is the EOCD record, it will begin with the
// magic number $50 $4b $05 $06.
if (eocd[0] != 0x50 || eocd[1] != 0x4b ||
eocd[2] != 0x05 || eocd[3] != 0x06) {
LOGE("signature length doesn't match EOCD marker\n");
fclose(f);
return VERIFY_FAILURE;
}
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) {
// if the sequence $50 $4b $05 $06 appears anywhere after
// the real one, minzip will find the later (wrong) one,
// which could be exploitable. Fail verification if
// this sequence occurs anywhere after the real one.
LOGE("EOCD marker occurs after start of EOCD\n");
fclose(f);
return VERIFY_FAILURE;
}
}
#define BUFFER_SIZE 4096
SHA_CTX ctx;
SHA_init(&ctx);
unsigned char* buffer = (unsigned char*)malloc(BUFFER_SIZE);
if (buffer == NULL) {
LOGE("failed to alloc memory for sha1 buffer\n");
fclose(f);
return VERIFY_FAILURE;
}
double frac = -1.0;
size_t so_far = 0;
fseek(f, 0, SEEK_SET);
while (so_far < signed_len) {
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));
fclose(f);
return VERIFY_FAILURE;
}
SHA_update(&ctx, buffer, size);
so_far += size;
double f = so_far / (double)signed_len;
if (f > frac + 0.02 || size == so_far) {
//ui->SetProgress(f);
frac = f;
}
}
fclose(f);
free(buffer);
const uint8_t* sha1 = SHA_final(&ctx);
for (i = 0; i < numKeys; ++i) {
// The 6 bytes is the "(signature_start) $ff $ff (comment_size)" that
// the signing tool appends after the signature itself.
if (RSA_verify(pKeys+i, eocd + eocd_size - 6 - RSANUMBYTES,
RSANUMBYTES, sha1)) {
LOGI("whole-file signature verified against key %d\n", i);
free(eocd);
return VERIFY_SUCCESS;
}
}
free(eocd);
LOGE("failed to verify whole-file signature\n");
return VERIFY_FAILURE;
}
// Reads a file containing one or more public keys as produced by
// DumpPublicKey: this is an RSAPublicKey struct as it would appear
// as a C source literal, eg:
//
// "{64,0xc926ad21,{1795090719,...,-695002876},{-857949815,...,1175080310}}"
//
// (Note that the braces and commas in this example are actual
// characters the parser expects to find in the file; the ellipses
// indicate more numbers omitted from this example.)
//
// The file may contain multiple keys in this format, separated by
// commas. The last key must not be followed by a comma.
//
// Returns NULL if the file failed to parse, or if it contain zero keys.
static RSAPublicKey*
TWload_keys(const char* filename, int* numKeys) {
RSAPublicKey* out = NULL;
*numKeys = 0;
FILE* f = fopen(filename, "r");
if (f == NULL) {
LOGE("opening %s: ERROR\n", filename);
goto exit;
}
{
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)) {
case ',':
// more keys to come.
break;
case EOF:
done = true;
break;
default:
LOGE("unexpected character between keys\n");
goto exit;
}
}
}
fclose(f);
return out;
exit:
if (f) fclose(f);
free(out);
*numKeys = 0;
return NULL;
}
int TWinstall_zip(const char* path, int* wipe_cache) {
int err;
if (DataManager_GetIntValue(TW_SIGNED_ZIP_VERIFY_VAR)) {
int numKeys;
RSAPublicKey* loadedKeys = TWload_keys(PUBLIC_KEYS_FILE, &numKeys);
if (loadedKeys == NULL) {
LOGE("Failed to load keys\n");
return -1;
}
LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);
// Give verification half the progress bar...
//ui->Print("Verifying update package...\n");
//ui->SetProgressType(RecoveryUI::DETERMINATE);
//ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
err = TWverify_file(path, loadedKeys, numKeys);
free(loadedKeys);
LOGI("verify_file returned %d\n", err);
if (err != VERIFY_SUCCESS) {
LOGE("signature verification failed\n");
return -1;
}
}
/* Try to open the package.
*/
ZipArchive zip;
err = mzOpenZipArchive(path, &zip);
@@ -461,157 +825,8 @@ static int really_install_package(const char *path, int* wipe_cache)
/* Verify and install the contents of the package.
*/
LOGI("Installing update...\n");
return try_update_binary(path, &zip, wipe_cache);
}
static void set_sdcard_update_bootloader_message() {
struct bootloader_message boot;
memset(&boot, 0, sizeof(boot));
strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));
set_bootloader_message(&boot);
}
static char* copy_sideloaded_package(const char* original_path) {
if (ensure_path_mounted(original_path) != 0) {
LOGE("Can't mount %s\n", original_path);
return NULL;
}
if (ensure_path_mounted(SIDELOAD_TEMP_DIR) != 0) {
LOGE("Can't mount %s\n", SIDELOAD_TEMP_DIR);
return NULL;
}
if (mkdir(SIDELOAD_TEMP_DIR, 0700) != 0) {
if (errno != EEXIST) {
LOGE("Can't mkdir %s (%s)\n", SIDELOAD_TEMP_DIR, strerror(errno));
return NULL;
}
}
// verify that SIDELOAD_TEMP_DIR is exactly what we expect: a
// directory, owned by root, readable and writable only by root.
struct stat st;
if (stat(SIDELOAD_TEMP_DIR, &st) != 0) {
LOGE("failed to stat %s (%s)\n", SIDELOAD_TEMP_DIR, strerror(errno));
return NULL;
}
if (!S_ISDIR(st.st_mode)) {
LOGE("%s isn't a directory\n", SIDELOAD_TEMP_DIR);
return NULL;
}
if ((st.st_mode & 0777) != 0700) {
LOGE("%s has perms %o\n", SIDELOAD_TEMP_DIR, st.st_mode);
return NULL;
}
if (st.st_uid != 0) {
LOGE("%s owned by %lu; not root\n", SIDELOAD_TEMP_DIR, st.st_uid);
return NULL;
}
char copy_path[PATH_MAX];
strcpy(copy_path, SIDELOAD_TEMP_DIR);
strcat(copy_path, "/package.zip");
char* buffer = malloc(BUFSIZ);
if (buffer == NULL) {
LOGE("Failed to allocate buffer\n");
return NULL;
}
size_t read;
FILE* fin = fopen(original_path, "rb");
if (fin == NULL) {
LOGE("Failed to open %s (%s)\n", original_path, strerror(errno));
return NULL;
}
FILE* fout = fopen(copy_path, "wb");
if (fout == NULL) {
LOGE("Failed to open %s (%s)\n", copy_path, strerror(errno));
return NULL;
}
while ((read = fread(buffer, 1, BUFSIZ, fin)) > 0) {
if (fwrite(buffer, 1, read, fout) != read) {
LOGE("Short write of %s (%s)\n", copy_path, strerror(errno));
return NULL;
}
}
free(buffer);
if (fclose(fout) != 0) {
LOGE("Failed to close %s (%s)\n", copy_path, strerror(errno));
return NULL;
}
if (fclose(fin) != 0) {
LOGE("Failed to close %s (%s)\n", original_path, strerror(errno));
return NULL;
}
// "adb push" is happy to overwrite read-only files when it's
// running as root, but we'll try anyway.
if (chmod(copy_path, 0400) != 0) {
LOGE("Failed to chmod %s (%s)\n", copy_path, strerror(errno));
return NULL;
}
return strdup(copy_path);
}
int install_zip_package(const char* zip_path_filename) {
int result = 0;
//mount_current_storage();
int md5_req = DataManager_GetIntValue(TW_FORCE_MD5_CHECK_VAR);
if (md5_req == 1) {
ui_print("\n-- Verify md5 for %s", zip_path_filename);
int md5chk = check_md5((char*) zip_path_filename);
if (md5chk == 1) {
ui_print("\n-- Md5 verified, continue");
result = 0;
}
else if (md5chk == -1) {
if (md5_req == 1) {
ui_print("\n-- No md5 file found!");
ui_print("\n-- Aborting install");
result = INSTALL_ERROR;
}
else {
ui_print("\n-- No md5 file found, ignoring");
}
}
else if (md5chk == -2) {
ui_print("\n-- md5 file doesn't match!");
ui_print("\n-- Aborting install");
result = INSTALL_ERROR;
}
printf("%d\n", result);
}
if (result != INSTALL_ERROR) {
ui_print("\n-- Install %s ...\n", zip_path_filename);
set_sdcard_update_bootloader_message();
char* copy;
if (DataManager_GetIntValue(TW_FLASH_ZIP_IN_PLACE) == 1 && strlen(zip_path_filename) > 6 && strncmp(zip_path_filename, "/cache", 6) != 0) {
copy = strdup(zip_path_filename);
} else {
copy = copy_sideloaded_package(zip_path_filename);
//unmount_current_storage();
}
if (copy) {
result = really_install_package(copy, 0);
free(copy);
//update_system_details();
} else {
result = INSTALL_ERROR;
}
}
//mount_current_storage();
//finish_recovery(NULL);
return result;
//ui->Print("Installing update...\n");
return TWtry_update_binary(path, &zip, wipe_cache);
}
//partial kangbang from system/vold
+9 -2
View File
@@ -1,15 +1,22 @@
#ifndef _EXTRAFUNCTIONS_HEADER
#define _EXTRAFUNCTIONS_HEADER
#include "mincrypt/rsa.h"
#include "minzip/Zip.h"
int __system(const char *command);
FILE * __popen(const char *program, const char *type);
int __pclose(FILE *iop);
// Install Zip functions
int TWtry_update_binary(const char *path, ZipArchive *zip, int* wipe_cache);
static RSAPublicKey* TWload_keys(const char* filename, int* numKeys);
int TWverify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKeys);
int TWinstall_zip(const char* path, int* wipe_cache);
// Device ID variable / function
extern char device_id[64];
void get_device_id();
static char* copy_sideloaded_package(const char* original_path);
int install_zip_package(const char* zip_path_filename);
void wipe_dalvik_cache();
void wipe_battery_stats();
+14 -9
View File
@@ -14,6 +14,7 @@
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string>
#include <sstream>
@@ -28,7 +29,6 @@ extern "C" {
#include "../extra-functions.h"
#include "../variables.h"
int install_zip_package(const char* zip_path_filename);
void fix_perms();
void wipe_dalvik_cache(void);
int check_backup_name(int show_error);
@@ -53,7 +53,6 @@ int gui_start();
#include "rapidxml.hpp"
#include "objects.hpp"
void curtainClose(void);
GUIAction::GUIAction(xml_node<>* node)
@@ -159,7 +158,7 @@ void GUIAction::simulate_progress_bar(void)
}
}
int GUIAction::flash_zip(std::string filename, std::string pageName, const int simulate)
int GUIAction::flash_zip(std::string filename, std::string pageName, const int simulate, int* wipe_cache)
{
int ret_val = 0;
@@ -177,7 +176,10 @@ int GUIAction::flash_zip(std::string filename, std::string pageName, const int s
int fd = -1;
ZipArchive zip;
if (mzOpenZipArchive(filename.c_str(), &zip))
if (!PartitionManager.Mount_By_Path(filename, true))
return -1;
if (mzOpenZipArchive(filename.c_str(), &zip))
{
LOGE("Unable to open zip file.\n");
return -1;
@@ -195,14 +197,14 @@ int GUIAction::flash_zip(std::string filename, std::string pageName, const int s
!PageManager::LoadPackage("install", "/tmp/twrp.zip", "main"))
{
mzCloseZipArchive(&zip);
PageManager::SelectPackage("install");
PageManager::SelectPackage("install");
gui_changePage("main");
}
else
{
// In this case, we just use the default page
mzCloseZipArchive(&zip);
gui_changePage(pageName);
gui_changePage(pageName);
}
if (fd >= 0)
close(fd);
@@ -210,7 +212,7 @@ int GUIAction::flash_zip(std::string filename, std::string pageName, const int s
if (simulate) {
simulate_progress_bar();
} else {
ret_val = install_zip_package(filename.c_str());
ret_val = TWinstall_zip(filename.c_str(), wipe_cache);
// Now, check if we need to ensure TWRP remains installed...
struct stat st;
@@ -624,14 +626,14 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
if (function == "flash")
{
int i, ret_val = 0;
int i, ret_val = 0, wipe_cache = 0;
for (i=0; i<zip_queue_index; i++) {
operation_start("Flashing");
DataManager::SetValue("tw_filename", zip_queue[i]);
DataManager::SetValue(TW_ZIP_INDEX, (i + 1));
ret_val = flash_zip(zip_queue[i], arg, simulate);
ret_val = flash_zip(zip_queue[i], arg, simulate, &wipe_cache);
if (ret_val != 0) {
ui_print("Error flashing zip '%s'\n", zip_queue[i].c_str());
i = 10; // Error flashing zip - exit queue
@@ -641,6 +643,9 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
zip_queue_index = 0;
DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index);
if (wipe_cache)
PartitionManager.Wipe_By_Path("/cache");
if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) {
operation_start("ReinjectTWRP");
ui_print("Injecting TWRP into boot image...\n");
+1 -1
View File
@@ -251,7 +251,7 @@ protected:
virtual int doAction(Action action, int isThreaded = 0);
static void* thread_start(void *cookie);
void simulate_progress_bar(void);
int flash_zip(std::string filename, std::string pageName, const int simulate);
int flash_zip(std::string filename, std::string pageName, const int simulate, int* wipe_cache);
void operation_start(const string operation_name);
void operation_end(const int operation_status, const int simulate);
static void* command_thread(void *cookie);
+26 -6
View File
@@ -29,6 +29,10 @@
#include <unistd.h>
#include <dirent.h>
#ifdef TW_INCLUDE_CRYPTO
#include "cutils/properties.h"
#endif
#include "variables.h"
#include "common.h"
#include "partitions.hpp"
@@ -156,12 +160,28 @@ bool TWPartition::Process_Fstab_Line(string Line, bool Display_Error) {
Has_Data_Media = true;
Is_Storage = true;
Storage_Path = "/data/media";
Make_Dir("/sdcard", Display_Error);
Make_Dir("/emmc", Display_Error);
if (strcmp(EXPAND(TW_EXTERNAL_STORAGE_PATH), "/sdcard") == 0) {
Make_Dir("/emmc", Display_Error);
Symlink_Path = "/data/media";
Symlink_Mount_Point = "/emmc";
} else {
Make_Dir("/sdcard", Display_Error);
Symlink_Path = "/data/media";
Symlink_Mount_Point = "/sdcard";
}
#endif
#ifdef TW_INCLUDE_CRYPTO
Can_Be_Encrypted = true;
if (!Mount(false)) {
char crypto_blkdev[255];
property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
if (strcmp(crypto_blkdev, "error") != 0) {
DataManager::SetValue(TW_DATA_BLK_DEVICE, Block_Device);
DataManager::SetValue(TW_IS_DECRYPTED, 1);
Is_Encrypted = true;
Is_Decrypted = true;
Decrypted_Block_Device = crypto_blkdev;
LOGI("Data already decrypted, new block device: '%s'\n", crypto_blkdev);
} else if (!Mount(false)) {
Is_Encrypted = true;
Is_Decrypted = false;
DataManager::SetValue(TW_IS_ENCRYPTED, 1);
@@ -320,7 +340,7 @@ void TWPartition::Setup_File_System(bool Display_Error) {
// Check to see if the block device exists
if (Path_Exists(Block_Device)) {
Is_Present = true;
} else if (Alternate_Block_Device != "" && Path_Exists(Alternate_Block_Device)) {
} else if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) {
Flip_Block_Device();
Is_Present = true;
}
@@ -334,7 +354,7 @@ void TWPartition::Setup_File_System(bool Display_Error) {
void TWPartition::Setup_Image(bool Display_Error) {
if (Path_Exists(Block_Device)) {
Is_Present = true;
} else if (Alternate_Block_Device != "" && Path_Exists(Alternate_Block_Device)) {
} else if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) {
Flip_Block_Device();
Is_Present = true;
}
@@ -595,7 +615,7 @@ bool TWPartition::Mount(bool Display_Error) {
if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
Check_FS_Type();
if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
if (Alternate_Block_Device != "" && Path_Exists(Alternate_Block_Device)) {
if (!Alternate_Block_Device.empty() && Path_Exists(Alternate_Block_Device)) {
Flip_Block_Device();
Check_FS_Type();
if (mount(Block_Device.c_str(), Mount_Point.c_str(), Current_File_System.c_str(), 0, NULL) != 0) {
+4 -4
View File
@@ -116,7 +116,7 @@ int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
// Iterate through all partitions
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Mount_Point == Local_Path) {
if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
ret = (*iter)->Mount(Display_Error);
found = true;
} else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
@@ -185,7 +185,7 @@ int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
// Iterate through all partitions
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Mount_Point == Local_Path) {
if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
ret = (*iter)->UnMount(Display_Error);
found = true;
} else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
@@ -297,7 +297,7 @@ TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
string Local_Path = Get_Root_Path(Path);
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Mount_Point == Local_Path)
if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
return (*iter);
}
return NULL;
@@ -555,7 +555,7 @@ int TWPartitionManager::Wipe_By_Path(string Path) {
// Iterate through all partitions
for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
if ((*iter)->Mount_Point == Local_Path) {
if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
ret = (*iter)->Wipe();
found = true;
} else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {