blob: 855b311be021acf0a9c2911fecb779d283ac6ce1 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001/* Partition Management classes for TWRP
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 *
17 * The code was written from scratch by Dees_Troy dees_troy at
18 * yahoo
19 *
20 * Copyright (c) 2012
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/stat.h>
27#include <sys/vfs.h>
28#include <unistd.h>
Dees_Troy5bf43922012-09-07 16:07:55 -040029#include <vector>
Dees_Troy63c8df72012-09-10 14:02:05 -040030#include <dirent.h>
31#include <time.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040032
33#include "variables.h"
34#include "common.h"
35#include "partitions.hpp"
Dees_Troy5bf43922012-09-07 16:07:55 -040036#include "data.hpp"
Dees_Troy38bd7602012-09-14 13:33:53 -040037#include "twrp-functions.hpp"
38
39extern "C" {
40 #include "extra-functions.h"
41 int __system(const char *command);
42}
Dees_Troy5bf43922012-09-07 16:07:55 -040043
44#ifdef TW_INCLUDE_CRYPTO
45 #ifdef TW_INCLUDE_JB_CRYPTO
46 #include "crypto/jb/cryptfs.h"
47 #else
48 #include "crypto/ics/cryptfs.h"
49 #endif
50 #include "cutils/properties.h"
51#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040052
53int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -040054 FILE *fstabFile;
55 char fstab_line[MAX_FSTAB_LINE_LENGTH];
56
57 fstabFile = fopen(Fstab_Filename.c_str(), "rt");
58 if (fstabFile == NULL) {
59 LOGE("Critical Error: Unable to open fstab at '%s'.\n", Fstab_Filename.c_str());
60 return false;
61 }
62
63 while (fgets(fstab_line, sizeof(fstab_line), fstabFile) != NULL) {
64 if (fstab_line[0] != '/')
65 continue;
66
67 TWPartition* partition = new TWPartition();
68 string line(fstab_line);
69 if (partition->Process_Fstab_Line(line, Display_Error)) {
70 Partitions.push_back(partition);
71 } else {
72 delete partition;
73 }
74 }
75 fclose(fstabFile);
76 if (!Write_Fstab()) {
77 if (Display_Error)
78 LOGE("Error creating fstab\n");
79 else
80 LOGI("Error creating fstab\n");
81 }
Dees_Troy51127312012-09-08 13:08:49 -040082 Update_System_Details();
Dees_Troy5bf43922012-09-07 16:07:55 -040083 return true;
84}
85
86int TWPartitionManager::Write_Fstab(void) {
87 FILE *fp;
88 std::vector<TWPartition*>::iterator iter;
89 string Line;
90
91 fp = fopen("/etc/fstab", "w");
92 if (fp == NULL) {
Dees_Troy63c8df72012-09-10 14:02:05 -040093 LOGI("Can not open /etc/fstab.\n");
Dees_Troy5bf43922012-09-07 16:07:55 -040094 return false;
95 }
Dees_Troy63c8df72012-09-10 14:02:05 -040096 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -040097 if ((*iter)->Can_Be_Mounted) {
Dees_Troy38bd7602012-09-14 13:33:53 -040098 Line = (*iter)->Actual_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
Dees_Troy5bf43922012-09-07 16:07:55 -040099 fputs(Line.c_str(), fp);
Dees_Troy51127312012-09-08 13:08:49 -0400100 // Handle subpartition tracking
101 if ((*iter)->Is_SubPartition) {
102 TWPartition* ParentPartition = Find_Partition_By_Path((*iter)->SubPartition_Of);
103 if (ParentPartition)
104 ParentPartition->Has_SubPartition = true;
105 else
106 LOGE("Unable to locate parent partition '%s' of '%s'\n", (*iter)->SubPartition_Of.c_str(), (*iter)->Mount_Point.c_str());
107 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400108 }
109 }
110 fclose(fp);
111 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400112}
113
114int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400115 std::vector<TWPartition*>::iterator iter;
116 int ret = false;
117 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400118 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400119
Dees_Troy43d8b002012-09-17 16:00:01 -0400120 if (Local_Path == "/tmp")
121 return true;
122
Dees_Troy5bf43922012-09-07 16:07:55 -0400123 // Iterate through all partitions
124 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400125 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400126 ret = (*iter)->Mount(Display_Error);
127 found = true;
Dees_Troy51127312012-09-08 13:08:49 -0400128 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400129 (*iter)->Mount(Display_Error);
Dees_Troy51127312012-09-08 13:08:49 -0400130 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400131 }
132 if (found) {
133 return ret;
134 } else if (Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400135 LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400136 } else {
Dees_Troy51127312012-09-08 13:08:49 -0400137 LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400138 }
139 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400140}
141
142int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400143 TWPartition* Part = Find_Partition_By_Block(Block);
Dees_Troy5bf43922012-09-07 16:07:55 -0400144
Dees_Troy51127312012-09-08 13:08:49 -0400145 if (Part) {
146 if (Part->Has_SubPartition) {
147 std::vector<TWPartition*>::iterator subpart;
148
149 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
150 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
151 (*subpart)->Mount(Display_Error);
152 }
153 return Part->Mount(Display_Error);
154 } else
155 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400156 }
157 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400158 LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400159 else
Dees_Troy51127312012-09-08 13:08:49 -0400160 LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400161 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400162}
163
164int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400165 TWPartition* Part = Find_Partition_By_Name(Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400166
Dees_Troy51127312012-09-08 13:08:49 -0400167 if (Part) {
168 if (Part->Has_SubPartition) {
169 std::vector<TWPartition*>::iterator subpart;
170
171 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
172 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
173 (*subpart)->Mount(Display_Error);
174 }
175 return Part->Mount(Display_Error);
176 } else
177 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400178 }
179 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400180 LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400181 else
Dees_Troy51127312012-09-08 13:08:49 -0400182 LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400183 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400184}
185
186int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400187 std::vector<TWPartition*>::iterator iter;
188 int ret = false;
189 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400190 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy51127312012-09-08 13:08:49 -0400191
192 // Iterate through all partitions
193 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400194 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy51127312012-09-08 13:08:49 -0400195 ret = (*iter)->UnMount(Display_Error);
196 found = true;
197 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
198 (*iter)->UnMount(Display_Error);
199 }
200 }
201 if (found) {
202 return ret;
203 } else if (Display_Error) {
204 LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
205 } else {
206 LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
207 }
208 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400209}
210
211int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400212 TWPartition* Part = Find_Partition_By_Block(Block);
213
214 if (Part) {
215 if (Part->Has_SubPartition) {
216 std::vector<TWPartition*>::iterator subpart;
217
218 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
219 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
220 (*subpart)->UnMount(Display_Error);
221 }
222 return Part->UnMount(Display_Error);
223 } else
224 return Part->UnMount(Display_Error);
225 }
226 if (Display_Error)
227 LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
228 else
229 LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
230 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400231}
232
233int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400234 TWPartition* Part = Find_Partition_By_Name(Name);
235
236 if (Part) {
237 if (Part->Has_SubPartition) {
238 std::vector<TWPartition*>::iterator subpart;
239
240 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
241 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
242 (*subpart)->UnMount(Display_Error);
243 }
244 return Part->UnMount(Display_Error);
245 } else
246 return Part->UnMount(Display_Error);
247 }
248 if (Display_Error)
249 LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
250 else
251 LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
252 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400253}
254
255int TWPartitionManager::Is_Mounted_By_Path(string Path) {
Dees_Troy51127312012-09-08 13:08:49 -0400256 TWPartition* Part = Find_Partition_By_Path(Path);
257
258 if (Part)
259 return Part->Is_Mounted();
260 else
261 LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
262 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400263}
264
265int TWPartitionManager::Is_Mounted_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400266 TWPartition* Part = Find_Partition_By_Block(Block);
267
268 if (Part)
269 return Part->Is_Mounted();
270 else
271 LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
272 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400273}
274
275int TWPartitionManager::Is_Mounted_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400276 TWPartition* Part = Find_Partition_By_Name(Name);
277
278 if (Part)
279 return Part->Is_Mounted();
280 else
281 LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
282 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400283}
284
Dees_Troy5bf43922012-09-07 16:07:55 -0400285int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400286 string current_storage_path = DataManager::GetCurrentStoragePath();
287
288 if (Mount_By_Path(current_storage_path, Display_Error)) {
289 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
290 if (FreeStorage)
291 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
292 return true;
293 }
294 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400295}
296
Dees_Troy5bf43922012-09-07 16:07:55 -0400297int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
298 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
299}
300
301TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
302 std::vector<TWPartition*>::iterator iter;
Dees_Troy38bd7602012-09-14 13:33:53 -0400303 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400304
305 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400306 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
Dees_Troy5bf43922012-09-07 16:07:55 -0400307 return (*iter);
308 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400309 return NULL;
310}
311
Dees_Troy5bf43922012-09-07 16:07:55 -0400312TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400313 std::vector<TWPartition*>::iterator iter;
314
315 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400316 if ((*iter)->Primary_Block_Device == Block || (*iter)->Alternate_Block_Device == Block || ((*iter)->Is_Decrypted && (*iter)->Decrypted_Block_Device == Block))
Dees_Troy51127312012-09-08 13:08:49 -0400317 return (*iter);
318 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400319 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400320}
321
322TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400323 std::vector<TWPartition*>::iterator iter;
324
325 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
326 if ((*iter)->Display_Name == Name)
327 return (*iter);
328 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400329 return NULL;
330}
Dees_Troy51a0e822012-09-05 15:24:24 -0400331
Dees_Troy43d8b002012-09-17 16:00:01 -0400332bool TWPartitionManager::Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename)
333{
334 char command[512];
335 string Full_File = Backup_Folder + Backup_Filename;
336
Dees_Troy4a2a1262012-09-18 09:33:47 -0400337 if (!generate_md5)
Dees_Troy43d8b002012-09-17 16:00:01 -0400338 return true;
Dees_Troy43d8b002012-09-17 16:00:01 -0400339
Dees_Troy4a2a1262012-09-18 09:33:47 -0400340 ui_print(" * Generating md5...");
Dees_Troy43d8b002012-09-17 16:00:01 -0400341
342 if (TWFunc::Path_Exists(Full_File)) {
343 sprintf(command, "cd '%s' && md5sum %s > %s.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), Backup_Filename.c_str());
344 LOGI("MD5 command is: '%s'\n", command);
345 if (system(command) == 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400346 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400347 return true;
348 } else {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400349 ui_print("MD5 Error!\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400350 return false;
351 }
352 } else {
353 char filename[512];
354 int index = 0;
355
356 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400357 while (TWFunc::Path_Exists(filename) == true) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400358 sprintf(command, "cd '%s' && md5sum %s%03i > %s%03i.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), index, Backup_Filename.c_str(), index);
359 LOGI("MD5 command is: '%s'\n", command);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400360 if (system(command) != 0) {
361 ui_print("MD5 Error.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400362 return false;
363 }
364 index++;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400365 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy43d8b002012-09-17 16:00:01 -0400366 }
367 if (index == 0) {
368 LOGE("Backup file: '%s' not found!\n", filename);
369 return false;
370 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400371 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400372 }
373 return true;
374}
375
376bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folder, bool generate_md5, unsigned long long* img_bytes_remaining, unsigned long long* file_bytes_remaining, unsigned long *img_time, unsigned long *file_time) {
377 time_t start, stop;
378
379 if (Part == NULL)
380 return true;
381
382 time(&start);
383
384 if (Part->Backup(Backup_Folder)) {
385 time(&stop);
386 if (Part->Backup_Method == 1) {
387 *file_bytes_remaining -= Part->Backup_Size;
388 *file_time += (int) difftime(stop, start);
389 } else {
390 *img_bytes_remaining -= Part->Backup_Size;
391 *img_time += (int) difftime(stop, start);
392 }
393 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
394 } else {
395 return false;
396 }
397}
398
399int TWPartitionManager::Run_Backup(void) {
400 int check, do_md5, partition_count = 0;
401 string Backup_Folder, Backup_Name, Full_Backup_Path;
402 unsigned long long total_bytes = 0, file_bytes = 0, img_bytes = 0, free_space = 0, img_bytes_remaining, file_bytes_remaining;
403 unsigned long img_time = 0, file_time = 0;
404 TWPartition* backup_sys = NULL;
405 TWPartition* backup_data = NULL;
406 TWPartition* backup_cache = NULL;
407 TWPartition* backup_recovery = NULL;
408 TWPartition* backup_boot = NULL;
409 TWPartition* backup_andsec = NULL;
410 TWPartition* backup_sdext = NULL;
411 TWPartition* backup_sp1 = NULL;
412 TWPartition* backup_sp2 = NULL;
413 TWPartition* backup_sp3 = NULL;
414 TWPartition* storage = NULL;
415 struct tm *t;
416 time_t start, stop, seconds, total_start, total_stop;
417 seconds = time(0);
418 t = localtime(&seconds);
419
420 time(&total_start);
421
422 Update_System_Details();
423
424 if (!Mount_Current_Storage(true))
425 return false;
426
427 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400428 if (do_md5 == 0)
Dees_Troy43d8b002012-09-17 16:00:01 -0400429 do_md5 = true;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400430
Dees_Troy43d8b002012-09-17 16:00:01 -0400431 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
432 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
433 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
434 char timestamp[255];
435 sprintf(timestamp,"%04d-%02d-%02d--%02d-%02d-%02d",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
436 Backup_Name = timestamp;
437 }
438 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
439 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
440 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
441
442 ui_print("\n[BACKUP STARTED]\n");
443 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
444 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
445 LOGE("Failed to make backup folder.\n");
446 return false;
447 }
448
449 LOGI("Calculating backup details...\n");
450 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
451 if (check) {
452 backup_sys = Find_Partition_By_Path("/system");
453 if (backup_sys != NULL) {
454 partition_count++;
455 if (backup_sys->Backup_Method == 1)
456 file_bytes += backup_sys->Backup_Size;
457 else
458 img_bytes += backup_sys->Backup_Size;
459 } else {
460 LOGE("Unable to locate system partition.\n");
461 return false;
462 }
463 }
464 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
465 if (check) {
466 backup_data = Find_Partition_By_Path("/data");
467 if (backup_data != NULL) {
468 partition_count++;
469 if (backup_data->Backup_Method == 1)
470 file_bytes += backup_data->Backup_Size;
471 else
472 img_bytes += backup_data->Backup_Size;
473 } else {
474 LOGE("Unable to locate data partition.\n");
475 return false;
476 }
477 }
478 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
479 if (check) {
480 backup_cache = Find_Partition_By_Path("/cache");
481 if (backup_cache != NULL) {
482 partition_count++;
483 if (backup_cache->Backup_Method == 1)
484 file_bytes += backup_cache->Backup_Size;
485 else
486 img_bytes += backup_cache->Backup_Size;
487 } else {
488 LOGE("Unable to locate cache partition.\n");
489 return false;
490 }
491 }
492 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
493 if (check) {
494 backup_recovery = Find_Partition_By_Path("/recovery");
495 if (backup_recovery != NULL) {
496 partition_count++;
497 if (backup_recovery->Backup_Method == 1)
498 file_bytes += backup_recovery->Backup_Size;
499 else
500 img_bytes += backup_recovery->Backup_Size;
501 } else {
502 LOGE("Unable to locate recovery partition.\n");
503 return false;
504 }
505 }
506 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
507 if (check) {
508 backup_boot = Find_Partition_By_Path("/boot");
509 if (backup_boot != NULL) {
510 partition_count++;
511 if (backup_boot->Backup_Method == 1)
512 file_bytes += backup_boot->Backup_Size;
513 else
514 img_bytes += backup_boot->Backup_Size;
515 } else {
516 LOGE("Unable to locate boot partition.\n");
517 return false;
518 }
519 }
520 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
521 if (check) {
522 backup_andsec = Find_Partition_By_Path("/and-sec");
523 if (backup_andsec != NULL) {
524 partition_count++;
525 if (backup_andsec->Backup_Method == 1)
526 file_bytes += backup_andsec->Backup_Size;
527 else
528 img_bytes += backup_andsec->Backup_Size;
529 } else {
530 LOGE("Unable to locate android secure partition.\n");
531 return false;
532 }
533 }
534 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
535 if (check) {
536 backup_sdext = Find_Partition_By_Path("/sd-ext");
537 if (backup_sdext != NULL) {
538 partition_count++;
539 if (backup_sdext->Backup_Method == 1)
540 file_bytes += backup_sdext->Backup_Size;
541 else
542 img_bytes += backup_sdext->Backup_Size;
543 } else {
544 LOGE("Unable to locate sd-ext partition.\n");
545 return false;
546 }
547 }
548#ifdef SP1_NAME
549 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
550 if (check) {
551 backup_sp1 = Find_Partition_By_Path(SP1_NAME);
552 if (backup_sp1 != NULL) {
553 partition_count++;
554 if (backup_sp1->Backup_Method == 1)
555 file_bytes += backup_sp1->Backup_Size;
556 else
557 img_bytes += backup_sp1->Backup_Size;
558 } else {
559 LOGE("Unable to locate %s partition.\n", SP1_NAME);
560 return false;
561 }
562 }
563#endif
564#ifdef SP2_NAME
565 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
566 if (check) {
567 backup_sp2 = Find_Partition_By_Path(SP2_NAME);
568 if (backup_sp2 != NULL) {
569 partition_count++;
570 if (backup_sp2->Backup_Method == 1)
571 file_bytes += backup_sp2->Backup_Size;
572 else
573 img_bytes += backup_sp2->Backup_Size;
574 } else {
575 LOGE("Unable to locate %s partition.\n", SP2_NAME);
576 return false;
577 }
578 }
579#endif
580#ifdef SP3_NAME
581 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
582 if (check) {
583 backup_sp3 = Find_Partition_By_Path(SP3_NAME);
584 if (backup_sp3 != NULL) {
585 partition_count++;
586 if (backup_sp3->Backup_Method == 1)
587 file_bytes += backup_sp3->Backup_Size;
588 else
589 img_bytes += backup_sp3->Backup_Size;
590 } else {
591 LOGE("Unable to locate %s partition.\n", SP3_NAME);
592 return false;
593 }
594 }
595#endif
596
597 if (partition_count == 0) {
598 ui_print("No partitions selected for backup.\n");
599 return false;
600 }
601 total_bytes = file_bytes + img_bytes;
602 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
603 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
604 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
605 if (storage != NULL) {
606 free_space = storage->Free;
607 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
608 } else {
609 LOGE("Unable to locate storage device.\n");
610 return false;
611 }
612 if (free_space + (32 * 1024 * 1024) < total_bytes) {
613 // We require an extra 32MB just in case
614 LOGE("Not enough free space on storage.\n");
615 return false;
616 }
617 img_bytes_remaining = img_bytes;
618 file_bytes_remaining = file_bytes;
619
620 if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
621 return false;
622 if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
623 return false;
624 if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
625 return false;
626 if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
627 return false;
628 if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
629 return false;
630 if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
631 return false;
632 if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
633 return false;
634 if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
635 return false;
636 if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
637 return false;
638 if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
639 return false;
640
641 // Average BPS
642 if (img_time == 0)
643 img_time = 1;
644 if (file_time == 0)
645 file_time = 1;
646 unsigned long int img_bps = img_bytes / img_time;
647 unsigned long int file_bps = file_bytes / file_time;
648
649 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
650 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
651
652 time(&total_stop);
653 int total_time = (int) difftime(total_stop, total_start);
654 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
655 actual_backup_size /= (1024LLU * 1024LLU);
656
657 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
658 Update_System_Details();
659 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
660 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400661}
662
Dees_Troy4a2a1262012-09-18 09:33:47 -0400663bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name) {
664 time_t Start, Stop;
665 time(&Start);
666 if (!Part->Restore(Restore_Name))
667 return false;
668 time(&Stop);
669 ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
670 return true;
671}
672
Dees_Troy51a0e822012-09-05 15:24:24 -0400673int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400674 int check_md5, check, partition_count = 0;
675 TWPartition* restore_sys = NULL;
676 TWPartition* restore_data = NULL;
677 TWPartition* restore_cache = NULL;
678 TWPartition* restore_boot = NULL;
679 TWPartition* restore_andsec = NULL;
680 TWPartition* restore_sdext = NULL;
681 TWPartition* restore_sp1 = NULL;
682 TWPartition* restore_sp2 = NULL;
683 TWPartition* restore_sp3 = NULL;
684 time_t rStart, rStop;
685 time(&rStart);
Dees_Troy43d8b002012-09-17 16:00:01 -0400686
Dees_Troy4a2a1262012-09-18 09:33:47 -0400687 ui_print("\n[RESTORE STARTED]\n\n");
688 ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400689
Dees_Troy4a2a1262012-09-18 09:33:47 -0400690 if (!Mount_Current_Storage(true))
691 return false;
692
693 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
694 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
Dees_Troy63c8df72012-09-10 14:02:05 -0400695 if (check > 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400696 restore_sys = Find_Partition_By_Path("/system");
697 if (restore_sys == NULL) {
698 LOGE("Unable to locate system partition.\n");
699 return false;
700 }
701 partition_count++;
702 }
703 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
704 if (check > 0) {
705 restore_data = Find_Partition_By_Path("/data");
706 if (restore_data == NULL) {
707 LOGE("Unable to locate data partition.\n");
708 return false;
709 }
710 partition_count++;
711 }
712 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
713 if (check > 0) {
714 restore_cache = Find_Partition_By_Path("/cache");
715 if (restore_cache == NULL) {
716 LOGE("Unable to locate cache partition.\n");
717 return false;
718 }
719 partition_count++;
720 }
721 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
722 if (check > 0) {
723 restore_boot = Find_Partition_By_Path("/boot");
724 if (restore_boot == NULL) {
725 LOGE("Unable to locate boot partition.\n");
726 return false;
727 }
728 partition_count++;
729 }
730 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
731 if (check > 0) {
732 restore_andsec = Find_Partition_By_Path("/and-sec");
733 if (restore_andsec == NULL) {
734 LOGE("Unable to locate android secure partition.\n");
735 return false;
736 }
737 partition_count++;
738 }
739 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
740 if (check > 0) {
741 restore_sdext = Find_Partition_By_Path("/sd-ext");
742 if (restore_sdext == NULL) {
743 LOGE("Unable to locate sd-ext partition.\n");
744 return false;
745 }
746 partition_count++;
747 }
748#ifdef SP1_NAME
749 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
750 if (check > 0) {
751 restore_sp1 = Find_Partition_By_Path(SP1_NAME);
752 if (restore_sp1 == NULL) {
753 LOGE("Unable to locate %s partition.\n", SP1_NAME);
754 return false;
755 }
756 partition_count++;
757 }
758#endif
759#ifdef SP2_NAME
760 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
761 if (check > 0) {
762 restore_sp2 = Find_Partition_By_Path(SP2_NAME);
763 if (restore_sp2 == NULL) {
764 LOGE("Unable to locate %s partition.\n", SP2_NAME);
765 return false;
766 }
767 partition_count++;
768 }
769#endif
770#ifdef SP3_NAME
771 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
772 if (check > 0) {
773 restore_sp3 = Find_Partition_By_Path(SP3_NAME);
774 if (restore_sp3 == NULL) {
775 LOGE("Unable to locate %s partition.\n", SP3_NAME);
776 return false;
777 }
778 partition_count++;
779 }
780#endif
781
782 if (partition_count == 0) {
783 LOGE("No partitions selected for restore.\n");
784 return false;
785 }
786
787 if (check_md5 > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400788 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
Dees_Troy4a2a1262012-09-18 09:33:47 -0400789 ui_print("Verifying MD5...\n");
790 if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
791 return false;
792 if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
793 return false;
794 if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
795 return false;
796 if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
797 return false;
798 if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
799 return false;
800 if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
801 return false;
802 if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
803 return false;
804 if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
805 return false;
806 if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
807 return false;
808 ui_print("Done verifying MD5.\n");
809 } else
810 ui_print("Skipping MD5 check based on user setting.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400811
Dees_Troy4a2a1262012-09-18 09:33:47 -0400812 ui_print("Restoring %i partitions...\n", partition_count);
813 if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name))
814 return false;
815 if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name))
816 return false;
817 if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name))
818 return false;
819 if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name))
820 return false;
821 if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name))
822 return false;
823 if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name))
824 return false;
825 if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name))
826 return false;
827 if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name))
828 return false;
829 if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name))
830 return false;
Dees_Troy43d8b002012-09-17 16:00:01 -0400831
Dees_Troy43d8b002012-09-17 16:00:01 -0400832 Update_System_Details();
Dees_Troy4a2a1262012-09-18 09:33:47 -0400833 time(&rStop);
834 ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
Dees_Troy63c8df72012-09-10 14:02:05 -0400835 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400836}
837
838void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400839 // Start with the default values
840 int tw_restore_system = -1;
841 int tw_restore_data = -1;
842 int tw_restore_cache = -1;
843 int tw_restore_recovery = -1;
844 int tw_restore_boot = -1;
845 int tw_restore_andsec = -1;
846 int tw_restore_sdext = -1;
847 int tw_restore_sp1 = -1;
848 int tw_restore_sp2 = -1;
849 int tw_restore_sp3 = -1;
850 bool get_date = true;
851
852 DIR* d;
853 d = opendir(Restore_Name.c_str());
854 if (d == NULL)
855 {
856 LOGE("Error opening %s\n", Restore_Name.c_str());
857 return;
858 }
859
860 struct dirent* de;
861 while ((de = readdir(d)) != NULL)
862 {
863 // Strip off three components
864 char str[256];
865 char* label;
866 char* fstype = NULL;
867 char* extn = NULL;
868 char* ptr;
869
870 strcpy(str, de->d_name);
871 if (strlen(str) <= 2)
872 continue;
873
874 if (get_date) {
875 char file_path[255];
876 struct stat st;
877
878 strcpy(file_path, Restore_Name.c_str());
879 strcat(file_path, "/");
880 strcat(file_path, str);
881 stat(file_path, &st);
882 string backup_date = ctime((const time_t*)(&st.st_mtime));
883 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
884 get_date = false;
885 }
886
887 label = str;
888 ptr = label;
889 while (*ptr && *ptr != '.') ptr++;
890 if (*ptr == '.')
891 {
892 *ptr = 0x00;
893 ptr++;
894 fstype = ptr;
895 }
896 while (*ptr && *ptr != '.') ptr++;
897 if (*ptr == '.')
898 {
899 *ptr = 0x00;
900 ptr++;
901 extn = ptr;
902 }
903
904 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
905
906 TWPartition* Part = Find_Partition_By_Path(label);
907 if (Part == NULL)
908 {
909 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
910 continue;
911 }
912
913 Part->Backup_FileName = de->d_name;
914 if (strlen(extn) > 3) {
915 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
916 }
917
918 // Now, we just need to find the correct label
919 if (Part->Mount_Point == "/system")
920 tw_restore_system = 1;
921 if (Part->Mount_Point == "/data")
922 tw_restore_data = 1;
923 if (Part->Mount_Point == "/cache")
924 tw_restore_cache = 1;
925 if (Part->Mount_Point == "/recovery")
926 tw_restore_recovery = 1;
927 if (Part->Mount_Point == "/boot")
928 tw_restore_boot = 1;
929 if (Part->Mount_Point == "/.android_secure")
930 tw_restore_andsec = 1;
931 if (Part->Mount_Point == "/sd-ext")
932 tw_restore_sdext = 1;
933#ifdef SP1_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400934 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP1_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400935 tw_restore_sp1 = 1;
936#endif
937#ifdef SP2_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400938 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP2_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400939 tw_restore_sp2 = 1;
940#endif
941#ifdef SP3_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400942 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP3_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400943 tw_restore_sp3 = 1;
944#endif
945 }
946 closedir(d);
947
948 // Set the final values
949 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
950 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
951 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
952 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
953 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
954 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
955 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
956 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
957 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
958 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
959
Dees_Troy51a0e822012-09-05 15:24:24 -0400960 return;
961}
962
963int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400964 std::vector<TWPartition*>::iterator iter;
965 int ret = false;
966 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400967 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -0400968
969 // Iterate through all partitions
970 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400971 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400972 ret = (*iter)->Wipe();
973 found = true;
974 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
975 (*iter)->Wipe();
976 }
977 }
978 if (found) {
979 return ret;
980 } else
981 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
982 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400983}
984
985int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400986 TWPartition* Part = Find_Partition_By_Block(Block);
987
988 if (Part) {
989 if (Part->Has_SubPartition) {
990 std::vector<TWPartition*>::iterator subpart;
991
992 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
993 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
994 (*subpart)->Wipe();
995 }
996 return Part->Wipe();
997 } else
998 return Part->Wipe();
999 }
1000 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1001 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001002}
1003
1004int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001005 TWPartition* Part = Find_Partition_By_Name(Name);
1006
1007 if (Part) {
1008 if (Part->Has_SubPartition) {
1009 std::vector<TWPartition*>::iterator subpart;
1010
1011 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1012 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1013 (*subpart)->Wipe();
1014 }
1015 return Part->Wipe();
1016 } else
1017 return Part->Wipe();
1018 }
1019 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1020 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001021}
1022
1023int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001024 std::vector<TWPartition*>::iterator iter;
1025 int ret = true;
1026
1027 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001028 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001029 if (!(*iter)->Wipe())
1030 ret = false;
1031 }
1032 }
1033 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001034}
1035
Dees_Troy38bd7602012-09-14 13:33:53 -04001036int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1037 struct stat st;
1038
1039 if (!Mount_By_Path("/data", true))
1040 return false;
1041
1042 if (!Mount_By_Path("/cache", true))
1043 return false;
1044
1045 ui_print("\nWiping Dalvik Cache Directories...\n");
1046 __system("rm -rf /data/dalvik-cache");
1047 ui_print("Cleaned: /data/dalvik-cache...\n");
1048 __system("rm -rf /cache/dalvik-cache");
1049 ui_print("Cleaned: /cache/dalvik-cache...\n");
1050 __system("rm -rf /cache/dc");
1051 ui_print("Cleaned: /cache/dc\n");
1052
1053 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1054 if (sdext != NULL) {
1055 if (sdext->Is_Present && sdext->Mount(false)) {
1056 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
1057 __system("rm -rf /sd-ext/dalvik-cache");
1058 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1059 }
1060 }
1061 }
1062 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1063 return true;
1064}
1065
1066int TWPartitionManager::Wipe_Rotate_Data(void) {
1067 if (!Mount_By_Path("/data", true))
1068 return false;
1069
1070 __system("rm -r /data/misc/akmd*");
1071 __system("rm -r /data/misc/rild*");
1072 ui_print("Rotation data wiped.\n");
1073 return true;
1074}
1075
1076int TWPartitionManager::Wipe_Battery_Stats(void) {
1077 struct stat st;
1078
1079 if (!Mount_By_Path("/data", true))
1080 return false;
1081
1082 if (0 != stat("/data/system/batterystats.bin", &st)) {
1083 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1084 } else {
1085 remove("/data/system/batterystats.bin");
1086 ui_print("Cleared battery stats.\n");
1087 }
1088 return true;
1089}
1090
1091int TWPartitionManager::Format_Data(void) {
1092 TWPartition* dat = Find_Partition_By_Path("/data");
1093
1094 if (dat != NULL) {
1095 if (!dat->UnMount(true))
1096 return false;
1097
1098 return dat->Wipe_Encryption();
1099 } else {
1100 LOGE("Unable to locate /data.\n");
1101 return false;
1102 }
1103 return false;
1104}
1105
1106int TWPartitionManager::Wipe_Media_From_Data(void) {
1107 TWPartition* dat = Find_Partition_By_Path("/data");
1108
1109 if (dat != NULL) {
1110 if (!dat->Has_Data_Media) {
1111 LOGE("This device does not have /data/media\n");
1112 return false;
1113 }
1114 if (!dat->Mount(true))
1115 return false;
1116
1117 ui_print("Wiping internal storage -- /data/media...\n");
1118 __system("rm -rf /data/media");
1119 __system("cd /data && mkdir media && chmod 775 media");
1120 if (dat->Has_Data_Media) {
1121 dat->Recreate_Media_Folder();
1122 }
1123 return true;
1124 } else {
1125 LOGE("Unable to locate /data.\n");
1126 return false;
1127 }
1128 return false;
1129}
1130
Dees_Troy51a0e822012-09-05 15:24:24 -04001131void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001132 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001133 return;
1134}
1135
1136void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001137 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001138 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001139
Dees_Troy32c8eb82012-09-11 15:28:06 -04001140 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001141 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001142 if ((*iter)->Can_Be_Mounted) {
1143 (*iter)->Update_Size(true);
1144 if ((*iter)->Mount_Point == "/system") {
1145 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1146 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1147 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1148 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1149 } else if ((*iter)->Mount_Point == "/cache") {
1150 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1151 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1152 } else if ((*iter)->Mount_Point == "/sd-ext") {
1153 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1154 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1155 if ((*iter)->Backup_Size == 0) {
1156 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1157 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1158 } else
1159 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
1160 }
1161 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001162 }
Dees_Troy51127312012-09-08 13:08:49 -04001163 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1164 string current_storage_path = DataManager::GetCurrentStoragePath();
1165 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
1166 if (FreeStorage)
1167 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1168 else
1169 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -04001170 if (!Write_Fstab())
1171 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001172 return;
1173}
1174
1175int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001176#ifdef TW_INCLUDE_CRYPTO
1177 int ret_val, password_len;
1178 char crypto_blkdev[255], cPassword[255];
1179 size_t result;
1180
1181 property_set("ro.crypto.state", "encrypted");
1182#ifdef TW_INCLUDE_JB_CRYPTO
1183 // No extra flags needed
1184#else
1185 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1186 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1187 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1188 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1189 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1190 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1191#endif
1192 strcpy(cPassword, Password.c_str());
1193 if (cryptfs_check_passwd(cPassword) != 0) {
1194 LOGE("Failed to decrypt data.\n");
1195 return -1;
1196 }
1197 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1198 if (strcmp(crypto_blkdev, "error") == 0) {
1199 LOGE("Error retrieving decrypted data block device.\n");
1200 } else {
1201 TWPartition* dat = Find_Partition_By_Path("/data");
1202 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001203 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001204 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1205 dat->Is_Decrypted = true;
1206 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001207 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001208 // Sleep for a bit so that the device will be ready
1209 sleep(1);
1210 Update_System_Details();
1211 } else
1212 LOGE("Unable to locate data partition.\n");
1213 }
1214 return 0;
1215#else
1216 LOGE("No crypto support was compiled into this build.\n");
1217 return -1;
1218#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001219 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001220}
1221
Dees_Troy38bd7602012-09-14 13:33:53 -04001222int TWPartitionManager::Fix_Permissions(void) {
1223 if (!Mount_By_Path("/data", true))
1224 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001225
Dees_Troy38bd7602012-09-14 13:33:53 -04001226 if (!Mount_By_Path("/system", true))
1227 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001228
Dees_Troy38bd7602012-09-14 13:33:53 -04001229 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
1230 __system("./sbin/fix_permissions.sh");
1231 ui_print("Done.\n\n");
1232 return true;
Dees_Troy4a2a1262012-09-18 09:33:47 -04001233}