summaryrefslogtreecommitdiffstats
path: root/adbbu/twrpback.cpp
diff options
context:
space:
mode:
authorbigbiff bigbiff <bigbiff@teamw.in>2017-09-25 16:51:56 +0200
committerDees Troy <dees_troy@teamw.in>2017-11-27 16:43:20 +0100
commitadcb4d8cb7ee3ace4f0ee4a8ee8968b744db56b0 (patch)
tree0a1993c0cffa55a78c6674045c0b9083c22f2db8 /adbbu/twrpback.cpp
parentADB Backup: add ability for TWRP GUI to restore (diff)
downloadandroid_bootable_recovery-adcb4d8cb7ee3ace4f0ee4a8ee8968b744db56b0.tar
android_bootable_recovery-adcb4d8cb7ee3ace4f0ee4a8ee8968b744db56b0.tar.gz
android_bootable_recovery-adcb4d8cb7ee3ace4f0ee4a8ee8968b744db56b0.tar.bz2
android_bootable_recovery-adcb4d8cb7ee3ace4f0ee4a8ee8968b744db56b0.tar.lz
android_bootable_recovery-adcb4d8cb7ee3ace4f0ee4a8ee8968b744db56b0.tar.xz
android_bootable_recovery-adcb4d8cb7ee3ace4f0ee4a8ee8968b744db56b0.tar.zst
android_bootable_recovery-adcb4d8cb7ee3ace4f0ee4a8ee8968b744db56b0.zip
Diffstat (limited to 'adbbu/twrpback.cpp')
-rw-r--r--adbbu/twrpback.cpp424
1 files changed, 239 insertions, 185 deletions
diff --git a/adbbu/twrpback.cpp b/adbbu/twrpback.cpp
index 2c7ea6966..d88a9c9da 100644
--- a/adbbu/twrpback.cpp
+++ b/adbbu/twrpback.cpp
@@ -36,6 +36,7 @@
#include "twadbstream.h"
#include "twrpback.hpp"
+#include "libtwadbbu.hpp"
#include "../twrpDigest/twrpDigest.hpp"
#include "../twrpDigest/twrpMD5.hpp"
#include "../twrpAdbBuFifo.hpp"
@@ -124,13 +125,13 @@ void twrpback::close_restore_fds() {
unlink(TW_ADB_RESTORE);
}
-int twrpback::backup(std::string command) {
+bool twrpback::backup(std::string command) {
twrpMD5 digest;
bool breakloop = false;
int bytes = 0, errctr = 0;
- char result[MAX_ADB_READ];
- uint64_t totalbytes = 0, dataChunkBytes = 0;
- int64_t count = -1; // Count of how many blocks set
+ char adbReadStream[MAX_ADB_READ];
+ uint64_t totalbytes = 0, dataChunkBytes = 0, fileBytes = 0;
+ int64_t count = false; // Count of how many blocks set
uint64_t md5fnsize = 0;
struct AdbBackupControlType endadb;
@@ -143,12 +144,12 @@ int twrpback::backup(std::string command) {
adbd_fp = fdopen(adbd_fd, "w");
if (adbd_fp == NULL) {
adblogwrite("Unable to open adb_fp\n");
- return -1;
+ return false;
}
if (mkfifo(TW_ADB_BACKUP, 0666) < 0) {
adblogwrite("Unable to create TW_ADB_BACKUP fifo\n");
- return -1;
+ return false;
}
adblogwrite("opening TW_ADB_FIFO\n");
@@ -160,7 +161,7 @@ int twrpback::backup(std::string command) {
if (errctr > ADB_BU_MAX_ERROR) {
adblogwrite("Unable to open TW_ADB_FIFO\n");
close_backup_fds();
- return -1;
+ return false;
}
}
@@ -168,15 +169,15 @@ int twrpback::backup(std::string command) {
if (snprintf(operation, sizeof(operation), "adbbackup %s", command.c_str()) >= sizeof(operation)) {
adblogwrite("Operation too big to write to ORS_INPUT_FILE\n");
close_backup_fds();
- return -1;
+ return false;
}
if (write(write_fd, operation, sizeof(operation)) != sizeof(operation)) {
adblogwrite("Unable to write to ORS_INPUT_FILE\n");
close_backup_fds();
- return -1;
+ return false;
}
- memset(&result, 0, sizeof(result));
+ memset(&adbReadStream, 0, sizeof(adbReadStream));
memset(&cmd, 0, sizeof(cmd));
adblogwrite("opening TW_ADB_BU_CONTROL\n");
@@ -184,7 +185,7 @@ int twrpback::backup(std::string command) {
if (adb_control_bu_fd < 0) {
adblogwrite("Unable to open TW_ADB_BU_CONTROL for reading.\n");
close_backup_fds();
- return -1;
+ return false;
}
adblogwrite("opening TW_ADB_BACKUP\n");
@@ -192,7 +193,7 @@ int twrpback::backup(std::string command) {
if (adb_read_fd < 0) {
adblogwrite("Unable to open TW_ADB_BACKUP for reading.\n");
close_backup_fds();
- return -1;
+ return false;
}
//loop until TWENDADB sent
@@ -208,7 +209,7 @@ int twrpback::backup(std::string command) {
writedata = false;
adblogwrite("Error received. Quitting...\n");
close_backup_fds();
- return -1;
+ return false;
}
//we received the end of adb backup stream so we should break the loop
else if (cmdtype == TWENDADB) {
@@ -223,13 +224,13 @@ int twrpback::backup(std::string command) {
//we recieved the TWSTREAMHDR structure metadata to write to adb
else if (cmdtype == TWSTREAMHDR) {
writedata = false;
- adblogwrite("Writing TWSTREAMHDR\n");
+ adblogwrite("writing TWSTREAMHDR\n");
if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) {
std::stringstream str;
str << strerror(errno);
adblogwrite("Error writing TWSTREAMHDR to adbd" + str.str() + "\n");
close_backup_fds();
- return -1;
+ return false;
}
fflush(adbd_fp);
}
@@ -237,16 +238,17 @@ int twrpback::backup(std::string command) {
else if (cmdtype == TWIMG) {
struct twfilehdr twimghdr;
- adblogwrite("Writing TWIMG\n");
+ adblogwrite("writing TWIMG\n");
digest.init();
memset(&twimghdr, 0, sizeof(twimghdr));
memcpy(&twimghdr, cmd, sizeof(cmd));
md5fnsize = twimghdr.size;
+ compressed = false;
- if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) {
+ if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) {
adblogwrite("Error writing TWIMG to adbd\n");
close_backup_fds();
- return -1;
+ return false;
}
fflush(adbd_fp);
writedata = true;
@@ -255,7 +257,7 @@ int twrpback::backup(std::string command) {
else if (cmdtype == TWFN) {
struct twfilehdr twfilehdr;
- adblogwrite("Writing TWFN\n");
+ adblogwrite("writing TWFN\n");
digest.init();
ADBSTRUCT_STATIC_ASSERT(sizeof(twfilehdr) == MAX_ADB_READ);
@@ -269,7 +271,7 @@ int twrpback::backup(std::string command) {
if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) {
adblogwrite("Error writing TWFN to adbd\n");
close_backup_fds();
- return -1;
+ return false;
}
fflush(adbd_fp);
writedata = true;
@@ -284,36 +286,43 @@ int twrpback::backup(std::string command) {
*/
else if (cmdtype == TWEOF) {
adblogwrite("received TWEOF\n");
- count = totalbytes / MAX_ADB_READ + 1;
- count = count * MAX_ADB_READ;
-
- while ((bytes = read(adb_read_fd, &result, sizeof(result))) > 0) {
+ while ((bytes = read(adb_read_fd, &adbReadStream, sizeof(adbReadStream)) != 0)) {
totalbytes += bytes;
- char *writeresult = new char [bytes];
- memcpy(writeresult, result, bytes);
- digest.update((unsigned char *) writeresult, bytes);
- if (fwrite(writeresult, 1, bytes, adbd_fp) != bytes) {
- adblogwrite("Error writing backup data to adbd\n");
- close_backup_fds();
- return -1;
+ fileBytes += bytes;
+ dataChunkBytes += bytes;
+
+ char *writeAdbReadStream = new char [bytes];
+ memcpy(writeAdbReadStream, adbReadStream, bytes);
+
+ digest.update((unsigned char *) writeAdbReadStream, bytes);
+ if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) < 0) {
+ std::stringstream str;
+ str << strerror(errno);
+ adblogwrite("Cannot write to adbd stream: " + str.str() + "\n");
}
fflush(adbd_fp);
- delete [] writeresult;
- memset(&result, 0, sizeof(result));
+ delete [] writeAdbReadStream;
+ memset(adbReadStream, 0, sizeof(adbReadStream));
}
- if ((totalbytes % MAX_ADB_READ) != 0) {
- adblogwrite("writing padding to stream\n");
- char padding[count - totalbytes];
- memset(padding, 0, sizeof(padding));
- if (fwrite(padding, 1, sizeof(padding), adbd_fp) != sizeof(padding)) {
+ count = fileBytes / DATA_MAX_CHUNK_SIZE + 1;
+ count = count * DATA_MAX_CHUNK_SIZE;
+
+ if (fileBytes % DATA_MAX_CHUNK_SIZE != 0) {
+ char padding[count - fileBytes];
+ int paddingBytes = sizeof(padding);
+ std::stringstream paddingStr;
+ paddingStr << paddingBytes;
+ memset(padding, 0, paddingBytes);
+ adblogwrite("writing padding to stream: " + paddingStr.str() + " bytes\n");
+ if (fwrite(padding, 1, paddingBytes, adbd_fp) != sizeof(padding)) {
adblogwrite("Error writing padding to adbd\n");
close_backup_fds();
- return -1;
+ return false;
}
- digest.update((unsigned char *) padding, sizeof(padding));
+ totalbytes += paddingBytes;
+ digest.update((unsigned char *) padding, paddingBytes);
fflush(adbd_fp);
- totalbytes = 0;
}
AdbBackupFileTrailer md5trailer;
@@ -336,11 +345,12 @@ int twrpback::backup(std::string command) {
if (fwrite(&md5trailer, 1, sizeof(md5trailer), adbd_fp) != sizeof(md5trailer)) {
adblogwrite("Error writing md5trailer to adbd\n");
close_backup_fds();
- return -1;
+ return false;
}
fflush(adbd_fp);
writedata = false;
firstDataPacket = true;
+ fileBytes = 0;
}
memset(&cmd, 0, sizeof(cmd));
}
@@ -349,59 +359,76 @@ int twrpback::backup(std::string command) {
//to the adb stream.
//If the stream is compressed, we need to always write the data.
if (writedata || compressed) {
- while ((bytes = read(adb_read_fd, &result, sizeof(result))) > 0) {
+ while ((bytes = read(adb_read_fd, &adbReadStream, sizeof(adbReadStream))) > 0) {
if (firstDataPacket) {
- struct AdbBackupControlType data_block;
-
- memset(&data_block, 0, sizeof(data_block));
- strncpy(data_block.start_of_header, TWRP, sizeof(data_block.start_of_header));
- strncpy(data_block.type, TWDATA, sizeof(data_block.type));
- data_block.crc = crc32(0L, Z_NULL, 0);
- data_block.crc = crc32(data_block.crc, (const unsigned char*) &data_block, sizeof(data_block));
- if (fwrite(&data_block, 1, sizeof(data_block), adbd_fp) != sizeof(data_block)) {
- adblogwrite("Error writing data_block to adbd\n");
+ if (!twadbbu::Write_TWDATA(adbd_fp)) {
close_backup_fds();
- return -1;
+ return false;
}
fflush(adbd_fp);
firstDataPacket = false;
+ dataChunkBytes += sizeof(adbReadStream);
}
- char *writeresult = new char [bytes];
- memcpy(writeresult, result, bytes);
+ char *writeAdbReadStream = new char [bytes];
+ memcpy(writeAdbReadStream, adbReadStream, bytes);
- digest.update((unsigned char *) writeresult, bytes);
+ digest.update((unsigned char *) writeAdbReadStream, bytes);
totalbytes += bytes;
+ fileBytes += bytes;
dataChunkBytes += bytes;
- if (fwrite(writeresult, 1, bytes, adbd_fp) != bytes) {
+ if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) != bytes) {
adblogwrite("Error writing backup data to adbd\n");
close_backup_fds();
- return -1;
+ return false;
}
fflush(adbd_fp);
+ delete [] writeAdbReadStream;
- delete [] writeresult;
- memset(&result, 0, sizeof(result));
- if (dataChunkBytes == DATA_MAX_CHUNK_SIZE - sizeof(result)) {
- struct AdbBackupControlType data_block;
-
- memset(&data_block, 0, sizeof(data_block));
- strncpy(data_block.start_of_header, TWRP, sizeof(data_block.start_of_header));
- strncpy(data_block.type, TWDATA, sizeof(data_block.type));
- data_block.crc = crc32(0L, Z_NULL, 0);
- data_block.crc = crc32(data_block.crc, (const unsigned char*) &data_block, sizeof(data_block));
- if (fwrite(&data_block, 1, sizeof(data_block), adbd_fp) != sizeof(data_block)) {
- adblogwrite("Error writing data_block to adbd\n");
- close_backup_fds();
- return -1;
+ memset(&adbReadStream, 0, sizeof(adbReadStream));
+
+ if (dataChunkBytes == DATA_MAX_CHUNK_SIZE) {
+ dataChunkBytes = 0;
+ firstDataPacket = true;
+ }
+ else if (dataChunkBytes > (DATA_MAX_CHUNK_SIZE - sizeof(adbReadStream))) {
+ int bytesLeft = DATA_MAX_CHUNK_SIZE - dataChunkBytes;
+ char extraData[bytesLeft];
+
+ memset(&extraData, 0, bytesLeft);
+ while ((bytes = read(adb_read_fd, &extraData, bytesLeft)) != 0) {
+ if (bytes > 0) {
+ totalbytes += bytes;
+ fileBytes += bytes;
+ dataChunkBytes += bytes;
+
+ bytesLeft -= bytes;
+ char *writeAdbReadStream = new char [bytes];
+ memcpy(writeAdbReadStream, extraData, bytes);
+
+ digest.update((unsigned char *) writeAdbReadStream, bytes);
+ if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) < 0) {
+ std::stringstream str;
+ str << strerror(errno);
+ adblogwrite("Cannot write to adbd stream: " + str.str() + "\n");
+ close_restore_fds();
+ return false;
+ }
+ fflush(adbd_fp);
+ delete [] writeAdbReadStream;
+ }
+ memset(&extraData, 0, bytesLeft);
+ if (bytesLeft == 0) {
+ break;
+ }
}
+
fflush(adbd_fp);
dataChunkBytes = 0;
+ firstDataPacket = true;
}
-
}
- compressed = false;
}
}
@@ -409,23 +436,25 @@ int twrpback::backup(std::string command) {
if (fwrite(&endadb, 1, sizeof(endadb), adbd_fp) != sizeof(endadb)) {
adblogwrite("Error writing endadb to adbd\n");
close_backup_fds();
- return -1;
+ return false;
}
fflush(adbd_fp);
close_backup_fds();
return 0;
}
-int twrpback::restore(void) {
+bool twrpback::restore(void) {
twrpMD5 digest;
char cmd[MAX_ADB_READ];
- char result[MAX_ADB_READ];
+ char readAdbStream[MAX_ADB_READ];
struct AdbBackupControlType structcmd;
- int adb_control_twrp_fd, errctr = 0;
+ int errctr = 0;
uint64_t totalbytes = 0, dataChunkBytes = 0;
uint64_t md5fnsize = 0;
bool writedata, read_from_adb;
bool breakloop, eofsent, md5trsent;
+ bool compressed;
+ bool md5TrailerReceived = false;
breakloop = false;
read_from_adb = true;
@@ -436,13 +465,13 @@ int twrpback::restore(void) {
if (adbd_fp == NULL) {
adblogwrite("Unable to open adb_fp\n");
close_restore_fds();
- return -1;
+ return false;
}
if(mkfifo(TW_ADB_RESTORE, 0666)) {
adblogwrite("Unable to create TW_ADB_RESTORE fifo\n");
close_restore_fds();
- return -1;
+ return false;
}
adblogwrite("opening TW_ADB_FIFO\n");
@@ -454,7 +483,7 @@ int twrpback::restore(void) {
if (errctr > ADB_BU_MAX_ERROR) {
adblogwrite("Unable to open TW_ADB_FIFO\n");
close_restore_fds();
- return -1;
+ return false;
}
}
@@ -463,10 +492,10 @@ int twrpback::restore(void) {
if (write(write_fd, operation, sizeof(operation)) != sizeof(operation)) {
adblogwrite("Unable to write to TW_ADB_FIFO\n");
close_restore_fds();
- return -1;
+ return false;
}
- memset(&result, 0, sizeof(result));
+ memset(&readAdbStream, 0, sizeof(readAdbStream));
memset(&cmd, 0, sizeof(cmd));
adblogwrite("opening TW_ADB_BU_CONTROL\n");
@@ -476,7 +505,7 @@ int twrpback::restore(void) {
str << strerror(errno);
adblogwrite("Unable to open TW_ADB_BU_CONTROL for writing. " + str.str() + "\n");
close_restore_fds();
- return -1;
+ return false;
}
adblogwrite("opening TW_ADB_TWRP_CONTROL\n");
@@ -492,7 +521,7 @@ int twrpback::restore(void) {
if (errctr > ADB_BU_MAX_ERROR) {
adblogwrite("Unable to open TW_ADB_TWRP_CONTROL\n");
close_backup_fds();
- return -1;
+ return false;
}
}
}
@@ -511,7 +540,7 @@ int twrpback::restore(void) {
struct AdbBackupControlType tweof;
memset(&tweof, 0, sizeof(tweof));
- memcpy(&tweof, result, sizeof(result));
+ memcpy(&tweof, readAdbStream, sizeof(readAdbStream));
read_from_adb = true;
}
//Break when TWRP sends TWENDADB
@@ -524,15 +553,14 @@ int twrpback::restore(void) {
else if (cmdtype == TWERROR) {
adblogwrite("Error received. Quitting...\n");
close_restore_fds();
- return -1;
+ return false;
}
}
//If we should read from the adb stream, write commands and data to TWRP
if (read_from_adb) {
int readbytes;
- if ((readbytes = fread(result, 1, sizeof(result), adbd_fp)) == sizeof(result)) {
- totalbytes += readbytes;
- memcpy(&structcmd, result, sizeof(result));
+ if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) == sizeof(readAdbStream)) {
+ memcpy(&structcmd, readAdbStream, sizeof(readAdbStream));
std::string cmdtype = structcmd.get_type();
//Tell TWRP we have read the entire adb stream
@@ -540,9 +568,8 @@ int twrpback::restore(void) {
struct AdbBackupControlType endadb;
uint32_t crc, endadbcrc;
- totalbytes -= sizeof(result);
memset(&endadb, 0, sizeof(endadb));
- memcpy(&endadb, result, sizeof(result));
+ memcpy(&endadb, readAdbStream, sizeof(readAdbStream));
endadbcrc = endadb.crc;
memset(&endadb.crc, 0, sizeof(endadb.crc));
crc = crc32(0L, Z_NULL, 0);
@@ -555,14 +582,14 @@ int twrpback::restore(void) {
str << strerror(errno);
adblogwrite("Cannot write to ADB_CONTROL_READ_FD: " + str.str() + "\n");
close_restore_fds();
- return -1;
+ return false;
}
read_from_adb = false;
}
else {
adblogwrite("ADB TWENDADB crc header doesn't match\n");
close_restore_fds();
- return -1;
+ return false;
}
}
//Send TWRP partition metadata
@@ -571,10 +598,9 @@ int twrpback::restore(void) {
uint32_t crc, cnthdrcrc;
ADBSTRUCT_STATIC_ASSERT(sizeof(cnthdr) == MAX_ADB_READ);
- totalbytes -= sizeof(result);
memset(&cnthdr, 0, sizeof(cnthdr));
- memcpy(&cnthdr, result, sizeof(result));
+ memcpy(&cnthdr, readAdbStream, sizeof(readAdbStream));
cnthdrcrc = cnthdr.crc;
memset(&cnthdr.crc, 0, sizeof(cnthdr.crc));
crc = crc32(0L, Z_NULL, 0);
@@ -582,18 +608,18 @@ int twrpback::restore(void) {
if (crc == cnthdrcrc) {
adblogwrite("Restoring TWSTREAMHDR\n");
- if (write(adb_control_twrp_fd, result, sizeof(result)) < 0) {
+ if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 0) {
std::stringstream str;
str << strerror(errno);
adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n");
close_restore_fds();
- return -1;
+ return false;
}
}
else {
adblogwrite("ADB TWSTREAMHDR crc header doesn't match\n");
close_restore_fds();
- return -1;
+ return false;
}
}
//Tell TWRP we are sending a partition image
@@ -602,10 +628,9 @@ int twrpback::restore(void) {
uint32_t crc, twimghdrcrc;
digest.init();
- totalbytes -= sizeof(result);
adblogwrite("Restoring TWIMG\n");
memset(&twimghdr, 0, sizeof(twimghdr));
- memcpy(&twimghdr, result, sizeof(result));
+ memcpy(&twimghdr, readAdbStream, sizeof(readAdbStream));
md5fnsize = twimghdr.size;
twimghdrcrc = twimghdr.crc;
memset(&twimghdr.crc, 0, sizeof(twimghdr.crc));
@@ -613,18 +638,18 @@ int twrpback::restore(void) {
crc = crc32(0L, Z_NULL, 0);
crc = crc32(crc, (const unsigned char*) &twimghdr, sizeof(twimghdr));
if (crc == twimghdrcrc) {
- if (write(adb_control_twrp_fd, result, sizeof(result)) < 1) {
+ if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) {
std::stringstream str;
str << strerror(errno);
adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n");
close_restore_fds();
- return -1;
+ return false;
}
}
else {
adblogwrite("ADB TWIMG crc header doesn't match\n");
close_restore_fds();
- return -1;
+ return false;
}
adblogwrite("opening TW_ADB_RESTORE\n");
adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY);
@@ -633,12 +658,11 @@ int twrpback::restore(void) {
else if (cmdtype == TWFN) {
struct twfilehdr twfilehdr;
uint32_t crc, twfilehdrcrc;
- digest.init();
- totalbytes -= sizeof(result);
+ digest.init();
adblogwrite("Restoring TWFN\n");
memset(&twfilehdr, 0, sizeof(twfilehdr));
- memcpy(&twfilehdr, result, sizeof(result));
+ memcpy(&twfilehdr, readAdbStream, sizeof(readAdbStream));
md5fnsize = twfilehdr.size;
twfilehdrcrc = twfilehdr.crc;
memset(&twfilehdr.crc, 0, sizeof(twfilehdr.crc));
@@ -647,111 +671,82 @@ int twrpback::restore(void) {
crc = crc32(crc, (const unsigned char*) &twfilehdr, sizeof(twfilehdr));
if (crc == twfilehdrcrc) {
- if (write(adb_control_twrp_fd, result, sizeof(result)) < 1) {
+ if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) {
std::stringstream str;
str << strerror(errno);
adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n");
close_restore_fds();
- return -1;
+ return false;
}
}
else {
adblogwrite("ADB TWFN crc header doesn't match\n");
close_restore_fds();
- return -1;
+ return false;
}
adblogwrite("opening TW_ADB_RESTORE\n");
adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY);
}
+ else if (cmdtype == MD5TRAILER) {
+ read_from_adb = false; //don't read from adb until TWRP sends TWEOF
+ close(adb_write_fd);
+ md5TrailerReceived = true;
+ if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) {
+ close_restore_fds();
+ return false;
+ }
+ }
//Send the tar or partition image md5 to TWRP
else if (cmdtype == TWDATA) {
- totalbytes -= sizeof(result);
+ dataChunkBytes += sizeof(readAdbStream);
while (1) {
- if ((readbytes = fread(result, 1, sizeof(result), adbd_fp)) != sizeof(result)) {
+ if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) != sizeof(readAdbStream)) {
close_restore_fds();
- return -1;
+ return false;
}
- totalbytes += readbytes;
- memcpy(&structcmd, result, sizeof(result));
- std::string cmdtype = structcmd.get_type();
- if (cmdtype.substr(0, sizeof(MD5TRAILER) - 1) == MD5TRAILER) {
- struct AdbBackupFileTrailer md5tr;
- uint32_t crc, md5trcrc, md5ident, md5identmatch;
-
- ADBSTRUCT_STATIC_ASSERT(sizeof(md5tr) == MAX_ADB_READ);
- memset(&md5tr, 0, sizeof(md5tr));
- memcpy(&md5tr, result, sizeof(result));
- md5ident = md5tr.ident;
-
- memset(&md5tr.ident, 0, sizeof(md5tr.ident));
-
- md5identmatch = crc32(0L, Z_NULL, 0);
- md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5tr, sizeof(md5tr));
- md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5fnsize, sizeof(md5fnsize));
-
- if (md5identmatch == md5ident) {
- totalbytes -= sizeof(result);
- close(adb_write_fd);
- adblogwrite("Restoring MD5TRAILER\n");
- md5trcrc = md5tr.crc;
- memset(&md5tr.crc, 0, sizeof(md5tr.crc));
- crc = crc32(0L, Z_NULL, 0);
- crc = crc32(crc, (const unsigned char*) &md5tr, sizeof(md5tr));
- if (crc == md5trcrc) {
- if (write(adb_control_twrp_fd, result, sizeof(result)) < 1) {
- std::stringstream str;
- str << strerror(errno);
- adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n");
- close_restore_fds();
- return -1;
- }
- }
- else {
- adblogwrite("ADB MD5TRAILER crc header doesn't match\n");
- close_restore_fds();
- return -1;
- }
-
- AdbBackupFileTrailer md5;
-
- memset(&md5, 0, sizeof(md5));
- strncpy(md5.start_of_trailer, TWRP, sizeof(md5.start_of_trailer));
- strncpy(md5.type, TWMD5, sizeof(md5.type));
- std::string md5string = digest.return_digest_string();
- strncpy(md5.md5, md5string.c_str(), sizeof(md5.md5));
-
- adblogwrite("Sending MD5Check\n");
- if (write(adb_control_twrp_fd, &md5, sizeof(md5)) < 1) {
- std::stringstream str;
- str << strerror(errno);
- adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n");
- close_restore_fds();
- return -1;
- }
- read_from_adb = false; //don't read from adb until TWRP sends TWEOF
- break;
+ memcpy(&structcmd, readAdbStream, sizeof(readAdbStream));
+
+ char *readAdbReadStream = new char [readbytes];
+ memcpy(readAdbReadStream, readAdbStream, readbytes);
+ std::string cmdtype = structcmd.get_type();
+ dataChunkBytes += readbytes;
+ delete [] readAdbReadStream;
+ totalbytes += readbytes;
+ digest.update((unsigned char*)readAdbReadStream, readbytes);
+
+ if (cmdtype == MD5TRAILER) {
+ read_from_adb = false; //don't read from adb until TWRP sends TWEOF
+ close(adb_write_fd);
+ if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) {
+ close_restore_fds();
+ return false;
}
+ break;
}
- digest.update((unsigned char*)result, sizeof(result));
- dataChunkBytes += readbytes;
- if (write(adb_write_fd, result, sizeof(result)) < 0) {
- std::stringstream str;
- str << strerror(errno);
- adblogwrite("Cannot write to adb_write_fd\n" + str.str() + ". Retrying.\n");
- while(write(adb_write_fd, result, sizeof(result)) < 0) {
- adblogwrite("Cannot write to adb_write_fd\n" + str.str() + ". Retrying.\n");
- continue;
- }
+
+ if (write(adb_write_fd, readAdbStream, sizeof(readAdbStream)) < 0) {
+ adblogwrite("end of stream reached.\n");
+ break;
}
- if (dataChunkBytes == ((DATA_MAX_CHUNK_SIZE) - sizeof(result))) {
+ if (dataChunkBytes == DATA_MAX_CHUNK_SIZE) {
dataChunkBytes = 0;
break;
}
- memset(&result, 0, sizeof(result));
+ memset(&readAdbStream, 0, sizeof(readAdbStream));
+ }
+ }
+ else {
+ if (!md5TrailerReceived) {
+ char *readAdbReadStream = new char [readbytes];
+ memcpy(readAdbReadStream, readAdbStream, readbytes);
+ digest.update((unsigned char*)readAdbReadStream, readbytes);
+ totalbytes += readbytes;
+ delete [] readAdbReadStream;
}
+
}
}
}
@@ -760,7 +755,7 @@ int twrpback::restore(void) {
std::stringstream str;
str << totalbytes;
adblogwrite(str.str() + " bytes restored from adbbackup\n");
- return 0;
+ return true;
}
void twrpback::streamFileForTWRP(void) {
@@ -785,3 +780,62 @@ void twrpback::threadStream(void) {
pthread_create(&thread, NULL, p, this);
pthread_join(thread, NULL);
}
+
+bool twrpback::checkMD5Trailer(char readAdbStream[], uint64_t md5fnsize, twrpMD5 *digest) {
+ struct AdbBackupFileTrailer md5tr;
+ uint32_t crc, md5trcrc, md5ident, md5identmatch;
+
+ ADBSTRUCT_STATIC_ASSERT(sizeof(md5tr) == MAX_ADB_READ);
+ memset(&md5tr, 0, sizeof(md5tr));
+ memcpy(&md5tr, readAdbStream, MAX_ADB_READ);
+ md5ident = md5tr.ident;
+
+ memset(&md5tr.ident, 0, sizeof(md5tr.ident));
+
+ md5identmatch = crc32(0L, Z_NULL, 0);
+ md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5tr, sizeof(md5tr));
+ md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5fnsize, sizeof(md5fnsize));
+
+ if (md5identmatch == md5ident) {
+ adblogwrite("checking MD5TRAILER\n");
+ md5trcrc = md5tr.crc;
+ memset(&md5tr.crc, 0, sizeof(md5tr.crc));
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, (const unsigned char*) &md5tr, sizeof(md5tr));
+ if (crc == md5trcrc) {
+ if (write(adb_control_twrp_fd, &md5tr, sizeof(md5tr)) < 1) {
+ std::stringstream str;
+ str << strerror(errno);
+ adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n");
+ close_restore_fds();
+ return false;
+ }
+ }
+ else {
+ adblogwrite("ADB MD5TRAILER crc header doesn't match\n");
+ close_restore_fds();
+ return false;
+ }
+
+ AdbBackupFileTrailer md5;
+
+ memset(&md5, 0, sizeof(md5));
+ strncpy(md5.start_of_trailer, TWRP, sizeof(md5.start_of_trailer));
+ strncpy(md5.type, TWMD5, sizeof(md5.type));
+ std::string md5string = digest->return_digest_string();
+ strncpy(md5.md5, md5string.c_str(), sizeof(md5.md5));
+
+ adblogwrite("sending MD5 verification\n");
+ std::stringstream dstr;
+ dstr << adb_control_twrp_fd;
+ if (write(adb_control_twrp_fd, &md5, sizeof(md5)) < 1) {
+ std::stringstream str;
+ str << strerror(errno);
+ adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n");
+ close_restore_fds();
+ return false;
+ }
+ return true;
+ }
+ return false;
+}