blob: a16678307db03649871cdf659c9e519c85d46fb7 [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
337 if (!generate_md5) {
338 LOGI("MD5 disabled\n");
339 return true;
340 }
341
342 ui_print(" * Generating md5...\n");
343
344 if (TWFunc::Path_Exists(Full_File)) {
345 sprintf(command, "cd '%s' && md5sum %s > %s.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), Backup_Filename.c_str());
346 LOGI("MD5 command is: '%s'\n", command);
347 if (system(command) == 0) {
348 ui_print("....MD5 Created.\n");
349 return true;
350 } else {
351 ui_print("....MD5 Error.\n");
352 return false;
353 }
354 } else {
355 char filename[512];
356 int index = 0;
357
358 sprintf(filename, "%s%03i", Full_File.c_str(), index);
359 while (TWFunc::Path_Exists(filename)) {
360 sprintf(command, "cd '%s' && md5sum %s%03i > %s%03i.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), index, Backup_Filename.c_str(), index);
361 LOGI("MD5 command is: '%s'\n", command);
362 if (system(command) == 0) {
363 ui_print("....MD5 Created.\n");
364 } else {
365 ui_print("....MD5 Error.\n");
366 return false;
367 }
368 index++;
369 }
370 if (index == 0) {
371 LOGE("Backup file: '%s' not found!\n", filename);
372 return false;
373 }
374 }
375 return true;
376}
377
378bool 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) {
379 time_t start, stop;
380
381 if (Part == NULL)
382 return true;
383
384 time(&start);
385
386 if (Part->Backup(Backup_Folder)) {
387 time(&stop);
388 if (Part->Backup_Method == 1) {
389 *file_bytes_remaining -= Part->Backup_Size;
390 *file_time += (int) difftime(stop, start);
391 } else {
392 *img_bytes_remaining -= Part->Backup_Size;
393 *img_time += (int) difftime(stop, start);
394 }
395 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
396 } else {
397 return false;
398 }
399}
400
401int TWPartitionManager::Run_Backup(void) {
402 int check, do_md5, partition_count = 0;
403 string Backup_Folder, Backup_Name, Full_Backup_Path;
404 unsigned long long total_bytes = 0, file_bytes = 0, img_bytes = 0, free_space = 0, img_bytes_remaining, file_bytes_remaining;
405 unsigned long img_time = 0, file_time = 0;
406 TWPartition* backup_sys = NULL;
407 TWPartition* backup_data = NULL;
408 TWPartition* backup_cache = NULL;
409 TWPartition* backup_recovery = NULL;
410 TWPartition* backup_boot = NULL;
411 TWPartition* backup_andsec = NULL;
412 TWPartition* backup_sdext = NULL;
413 TWPartition* backup_sp1 = NULL;
414 TWPartition* backup_sp2 = NULL;
415 TWPartition* backup_sp3 = NULL;
416 TWPartition* storage = NULL;
417 struct tm *t;
418 time_t start, stop, seconds, total_start, total_stop;
419 seconds = time(0);
420 t = localtime(&seconds);
421
422 time(&total_start);
423
424 Update_System_Details();
425
426 if (!Mount_Current_Storage(true))
427 return false;
428
429 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
430 if (do_md5 != 0) {
431 LOGI("MD5 creation enabled.\n");
432 do_md5 = true;
433 }
434 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
435 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
436 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
437 char timestamp[255];
438 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);
439 Backup_Name = timestamp;
440 }
441 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
442 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
443 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
444
445 ui_print("\n[BACKUP STARTED]\n");
446 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
447 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
448 LOGE("Failed to make backup folder.\n");
449 return false;
450 }
451
452 LOGI("Calculating backup details...\n");
453 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
454 if (check) {
455 backup_sys = Find_Partition_By_Path("/system");
456 if (backup_sys != NULL) {
457 partition_count++;
458 if (backup_sys->Backup_Method == 1)
459 file_bytes += backup_sys->Backup_Size;
460 else
461 img_bytes += backup_sys->Backup_Size;
462 } else {
463 LOGE("Unable to locate system partition.\n");
464 return false;
465 }
466 }
467 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
468 if (check) {
469 backup_data = Find_Partition_By_Path("/data");
470 if (backup_data != NULL) {
471 partition_count++;
472 if (backup_data->Backup_Method == 1)
473 file_bytes += backup_data->Backup_Size;
474 else
475 img_bytes += backup_data->Backup_Size;
476 } else {
477 LOGE("Unable to locate data partition.\n");
478 return false;
479 }
480 }
481 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
482 if (check) {
483 backup_cache = Find_Partition_By_Path("/cache");
484 if (backup_cache != NULL) {
485 partition_count++;
486 if (backup_cache->Backup_Method == 1)
487 file_bytes += backup_cache->Backup_Size;
488 else
489 img_bytes += backup_cache->Backup_Size;
490 } else {
491 LOGE("Unable to locate cache partition.\n");
492 return false;
493 }
494 }
495 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
496 if (check) {
497 backup_recovery = Find_Partition_By_Path("/recovery");
498 if (backup_recovery != NULL) {
499 partition_count++;
500 if (backup_recovery->Backup_Method == 1)
501 file_bytes += backup_recovery->Backup_Size;
502 else
503 img_bytes += backup_recovery->Backup_Size;
504 } else {
505 LOGE("Unable to locate recovery partition.\n");
506 return false;
507 }
508 }
509 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
510 if (check) {
511 backup_boot = Find_Partition_By_Path("/boot");
512 if (backup_boot != NULL) {
513 partition_count++;
514 if (backup_boot->Backup_Method == 1)
515 file_bytes += backup_boot->Backup_Size;
516 else
517 img_bytes += backup_boot->Backup_Size;
518 } else {
519 LOGE("Unable to locate boot partition.\n");
520 return false;
521 }
522 }
523 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
524 if (check) {
525 backup_andsec = Find_Partition_By_Path("/and-sec");
526 if (backup_andsec != NULL) {
527 partition_count++;
528 if (backup_andsec->Backup_Method == 1)
529 file_bytes += backup_andsec->Backup_Size;
530 else
531 img_bytes += backup_andsec->Backup_Size;
532 } else {
533 LOGE("Unable to locate android secure partition.\n");
534 return false;
535 }
536 }
537 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
538 if (check) {
539 backup_sdext = Find_Partition_By_Path("/sd-ext");
540 if (backup_sdext != NULL) {
541 partition_count++;
542 if (backup_sdext->Backup_Method == 1)
543 file_bytes += backup_sdext->Backup_Size;
544 else
545 img_bytes += backup_sdext->Backup_Size;
546 } else {
547 LOGE("Unable to locate sd-ext partition.\n");
548 return false;
549 }
550 }
551#ifdef SP1_NAME
552 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
553 if (check) {
554 backup_sp1 = Find_Partition_By_Path(SP1_NAME);
555 if (backup_sp1 != NULL) {
556 partition_count++;
557 if (backup_sp1->Backup_Method == 1)
558 file_bytes += backup_sp1->Backup_Size;
559 else
560 img_bytes += backup_sp1->Backup_Size;
561 } else {
562 LOGE("Unable to locate %s partition.\n", SP1_NAME);
563 return false;
564 }
565 }
566#endif
567#ifdef SP2_NAME
568 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
569 if (check) {
570 backup_sp2 = Find_Partition_By_Path(SP2_NAME);
571 if (backup_sp2 != NULL) {
572 partition_count++;
573 if (backup_sp2->Backup_Method == 1)
574 file_bytes += backup_sp2->Backup_Size;
575 else
576 img_bytes += backup_sp2->Backup_Size;
577 } else {
578 LOGE("Unable to locate %s partition.\n", SP2_NAME);
579 return false;
580 }
581 }
582#endif
583#ifdef SP3_NAME
584 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
585 if (check) {
586 backup_sp3 = Find_Partition_By_Path(SP3_NAME);
587 if (backup_sp3 != NULL) {
588 partition_count++;
589 if (backup_sp3->Backup_Method == 1)
590 file_bytes += backup_sp3->Backup_Size;
591 else
592 img_bytes += backup_sp3->Backup_Size;
593 } else {
594 LOGE("Unable to locate %s partition.\n", SP3_NAME);
595 return false;
596 }
597 }
598#endif
599
600 if (partition_count == 0) {
601 ui_print("No partitions selected for backup.\n");
602 return false;
603 }
604 total_bytes = file_bytes + img_bytes;
605 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
606 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
607 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
608 if (storage != NULL) {
609 free_space = storage->Free;
610 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
611 } else {
612 LOGE("Unable to locate storage device.\n");
613 return false;
614 }
615 if (free_space + (32 * 1024 * 1024) < total_bytes) {
616 // We require an extra 32MB just in case
617 LOGE("Not enough free space on storage.\n");
618 return false;
619 }
620 img_bytes_remaining = img_bytes;
621 file_bytes_remaining = file_bytes;
622
623 if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
624 return false;
625 if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
626 return false;
627 if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
628 return false;
629 if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
630 return false;
631 if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
632 return false;
633 if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
634 return false;
635 if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
636 return false;
637 if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
638 return false;
639 if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
640 return false;
641 if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
642 return false;
643
644 // Average BPS
645 if (img_time == 0)
646 img_time = 1;
647 if (file_time == 0)
648 file_time = 1;
649 unsigned long int img_bps = img_bytes / img_time;
650 unsigned long int file_bps = file_bytes / file_time;
651
652 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
653 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
654
655 time(&total_stop);
656 int total_time = (int) difftime(total_stop, total_start);
657 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
658 actual_backup_size /= (1024LLU * 1024LLU);
659
660 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
661 Update_System_Details();
662 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
663 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400664}
665
666int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400667 int check, restore_sys, restore_data, restore_cache, restore_boot, restore_andsec, restore_sdext, restore_sp1, restore_sp2, restore_sp3;
Dees_Troy63c8df72012-09-10 14:02:05 -0400668 TWPartition* Part;
Dees_Troy43d8b002012-09-17 16:00:01 -0400669
670 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check);
671 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, restore_sys);
672 DataManager::GetValue(TW_RESTORE_DATA_VAR, restore_data);
673 DataManager::GetValue(TW_RESTORE_CACHE_VAR, restore_cache);
674 DataManager::GetValue(TW_RESTORE_BOOT_VAR, restore_boot);
675 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, restore_andsec);
676 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, restore_sdext);
677 DataManager::GetValue(TW_RESTORE_SP1_VAR, restore_sp1);
678 DataManager::GetValue(TW_RESTORE_SP2_VAR, restore_sp2);
679 DataManager::GetValue(TW_RESTORE_SP3_VAR, restore_sp3);
680
Dees_Troy63c8df72012-09-10 14:02:05 -0400681 if (check > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400682 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
683 if (restore_sys > 0) {
684 Part = Find_Partition_By_Path("/system");
685 if (Part) {
686 if (!Part->Check_MD5(Restore_Name))
687 return false;
688 } else
689 LOGE("Restore: Unable to locate system partition.\n");
690 }
691
692 if (restore_data > 0) {
693 Part = Find_Partition_By_Path("/data");
694 if (Part) {
695 if (!Part->Check_MD5(Restore_Name))
696 return false;
697 } else
698 LOGE("Restore: Unable to locate data partition.\n");
699 }
700
701 if (restore_cache > 0) {
702 Part = Find_Partition_By_Path("/cache");
703 if (Part) {
704 if (!Part->Check_MD5(Restore_Name))
705 return false;
706 } else
707 LOGE("Restore: Unable to locate cache partition.\n");
708 }
709
710 if (restore_boot > 0) {
711 Part = Find_Partition_By_Path("/boot");
712 if (Part) {
713 if (!Part->Check_MD5(Restore_Name))
714 return false;
715 } else
716 LOGE("Restore: Unable to locate boot partition.\n");
717 }
718
719 if (restore_andsec > 0) {
720 Part = Find_Partition_By_Path("/.android_secure");
721 if (Part) {
722 if (!Part->Check_MD5(Restore_Name))
723 return false;
724 } else
725 LOGE("Restore: Unable to locate android_secure partition.\n");
726 }
727
728 if (restore_sdext > 0) {
729 Part = Find_Partition_By_Path("/sd-ext");
730 if (Part) {
731 if (!Part->Check_MD5(Restore_Name))
732 return false;
733 } else
734 LOGE("Restore: Unable to locate sd-ext partition.\n");
735 }
736#ifdef SP1_NAME
737 if (restore_sp1 > 0) {
738 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP1_NAME));
739 if (Part) {
740 if (!Part->Check_MD5(Restore_Name))
741 return false;
742 } else
743 LOGE("Restore: Unable to locate %s partition.\n", SP1_NAME);
744 }
745#endif
746#ifdef SP2_NAME
747 if (restore_sp2 > 0) {
748 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP2_NAME));
749 if (Part) {
750 if (!Part->Check_MD5(Restore_Name))
751 return false;
752 } else
753 LOGE("Restore: Unable to locate %s partition.\n", SP2_NAME);
754 }
755#endif
756#ifdef SP3_NAME
757 if (restore_sp3 > 0) {
758 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP3_NAME));
759 if (Part) {
760 if (!Part->Check_MD5(Restore_Name))
761 return false;
762 } else
763 LOGE("Restore: Unable to locate %s partition.\n", SP3_NAME);
764 }
765#endif
766 }
767
768 if (restore_sys > 0) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400769 Part = Find_Partition_By_Path("/system");
770 if (Part) {
771 if (!Part->Restore(Restore_Name))
772 return false;
773 } else
774 LOGE("Restore: Unable to locate system partition.\n");
775 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400776
777 if (restore_data > 0) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400778 Part = Find_Partition_By_Path("/data");
779 if (Part) {
780 if (!Part->Restore(Restore_Name))
781 return false;
782 } else
783 LOGE("Restore: Unable to locate data partition.\n");
784 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400785
786 if (restore_cache > 0) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400787 Part = Find_Partition_By_Path("/cache");
788 if (Part) {
789 if (!Part->Restore(Restore_Name))
790 return false;
791 } else
792 LOGE("Restore: Unable to locate cache partition.\n");
793 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400794
795 if (restore_boot > 0) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400796 Part = Find_Partition_By_Path("/boot");
797 if (Part) {
798 if (!Part->Restore(Restore_Name))
799 return false;
800 } else
801 LOGE("Restore: Unable to locate boot partition.\n");
802 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400803
804 if (restore_andsec > 0) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400805 Part = Find_Partition_By_Path("/.android_secure");
806 if (Part) {
807 if (!Part->Restore(Restore_Name))
808 return false;
809 } else
810 LOGE("Restore: Unable to locate android_secure partition.\n");
811 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400812
813 if (restore_sdext > 0) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400814 Part = Find_Partition_By_Path("/sd-ext");
815 if (Part) {
816 if (!Part->Restore(Restore_Name))
817 return false;
818 } else
819 LOGE("Restore: Unable to locate sd-ext partition.\n");
820 }
821#ifdef SP1_NAME
Dees_Troy43d8b002012-09-17 16:00:01 -0400822 if (restore_sp1 > 0) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400823 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP1_NAME));
Dees_Troy63c8df72012-09-10 14:02:05 -0400824 if (Part) {
825 if (!Part->Restore(Restore_Name))
826 return false;
827 } else
828 LOGE("Restore: Unable to locate %s partition.\n", SP1_NAME);
829 }
830#endif
831#ifdef SP2_NAME
Dees_Troy43d8b002012-09-17 16:00:01 -0400832 if (restore_sp2 > 0) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400833 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP2_NAME));
Dees_Troy63c8df72012-09-10 14:02:05 -0400834 if (Part) {
835 if (!Part->Restore(Restore_Name))
836 return false;
837 } else
838 LOGE("Restore: Unable to locate %s partition.\n", SP2_NAME);
839 }
840#endif
841#ifdef SP3_NAME
Dees_Troy43d8b002012-09-17 16:00:01 -0400842 if (restore_sp3 > 0) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400843 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP3_NAME));
Dees_Troy63c8df72012-09-10 14:02:05 -0400844 if (Part) {
845 if (!Part->Restore(Restore_Name))
846 return false;
847 } else
848 LOGE("Restore: Unable to locate %s partition.\n", SP3_NAME);
849 }
850#endif
Dees_Troy43d8b002012-09-17 16:00:01 -0400851 Update_System_Details();
Dees_Troy63c8df72012-09-10 14:02:05 -0400852 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400853}
854
855void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400856 // Start with the default values
857 int tw_restore_system = -1;
858 int tw_restore_data = -1;
859 int tw_restore_cache = -1;
860 int tw_restore_recovery = -1;
861 int tw_restore_boot = -1;
862 int tw_restore_andsec = -1;
863 int tw_restore_sdext = -1;
864 int tw_restore_sp1 = -1;
865 int tw_restore_sp2 = -1;
866 int tw_restore_sp3 = -1;
867 bool get_date = true;
868
869 DIR* d;
870 d = opendir(Restore_Name.c_str());
871 if (d == NULL)
872 {
873 LOGE("Error opening %s\n", Restore_Name.c_str());
874 return;
875 }
876
877 struct dirent* de;
878 while ((de = readdir(d)) != NULL)
879 {
880 // Strip off three components
881 char str[256];
882 char* label;
883 char* fstype = NULL;
884 char* extn = NULL;
885 char* ptr;
886
887 strcpy(str, de->d_name);
888 if (strlen(str) <= 2)
889 continue;
890
891 if (get_date) {
892 char file_path[255];
893 struct stat st;
894
895 strcpy(file_path, Restore_Name.c_str());
896 strcat(file_path, "/");
897 strcat(file_path, str);
898 stat(file_path, &st);
899 string backup_date = ctime((const time_t*)(&st.st_mtime));
900 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
901 get_date = false;
902 }
903
904 label = str;
905 ptr = label;
906 while (*ptr && *ptr != '.') ptr++;
907 if (*ptr == '.')
908 {
909 *ptr = 0x00;
910 ptr++;
911 fstype = ptr;
912 }
913 while (*ptr && *ptr != '.') ptr++;
914 if (*ptr == '.')
915 {
916 *ptr = 0x00;
917 ptr++;
918 extn = ptr;
919 }
920
921 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
922
923 TWPartition* Part = Find_Partition_By_Path(label);
924 if (Part == NULL)
925 {
926 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
927 continue;
928 }
929
930 Part->Backup_FileName = de->d_name;
931 if (strlen(extn) > 3) {
932 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
933 }
934
935 // Now, we just need to find the correct label
936 if (Part->Mount_Point == "/system")
937 tw_restore_system = 1;
938 if (Part->Mount_Point == "/data")
939 tw_restore_data = 1;
940 if (Part->Mount_Point == "/cache")
941 tw_restore_cache = 1;
942 if (Part->Mount_Point == "/recovery")
943 tw_restore_recovery = 1;
944 if (Part->Mount_Point == "/boot")
945 tw_restore_boot = 1;
946 if (Part->Mount_Point == "/.android_secure")
947 tw_restore_andsec = 1;
948 if (Part->Mount_Point == "/sd-ext")
949 tw_restore_sdext = 1;
950#ifdef SP1_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400951 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP1_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400952 tw_restore_sp1 = 1;
953#endif
954#ifdef SP2_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400955 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP2_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400956 tw_restore_sp2 = 1;
957#endif
958#ifdef SP3_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400959 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP3_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400960 tw_restore_sp3 = 1;
961#endif
962 }
963 closedir(d);
964
965 // Set the final values
966 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
967 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
968 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
969 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
970 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
971 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
972 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
973 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
974 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
975 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
976
Dees_Troy51a0e822012-09-05 15:24:24 -0400977 return;
978}
979
980int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400981 std::vector<TWPartition*>::iterator iter;
982 int ret = false;
983 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400984 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -0400985
986 // Iterate through all partitions
987 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400988 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400989 ret = (*iter)->Wipe();
990 found = true;
991 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
992 (*iter)->Wipe();
993 }
994 }
995 if (found) {
996 return ret;
997 } else
998 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
999 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001000}
1001
1002int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001003 TWPartition* Part = Find_Partition_By_Block(Block);
1004
1005 if (Part) {
1006 if (Part->Has_SubPartition) {
1007 std::vector<TWPartition*>::iterator subpart;
1008
1009 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1010 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1011 (*subpart)->Wipe();
1012 }
1013 return Part->Wipe();
1014 } else
1015 return Part->Wipe();
1016 }
1017 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1018 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001019}
1020
1021int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001022 TWPartition* Part = Find_Partition_By_Name(Name);
1023
1024 if (Part) {
1025 if (Part->Has_SubPartition) {
1026 std::vector<TWPartition*>::iterator subpart;
1027
1028 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1029 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1030 (*subpart)->Wipe();
1031 }
1032 return Part->Wipe();
1033 } else
1034 return Part->Wipe();
1035 }
1036 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1037 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001038}
1039
1040int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001041 std::vector<TWPartition*>::iterator iter;
1042 int ret = true;
1043
1044 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001045 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001046 if (!(*iter)->Wipe())
1047 ret = false;
1048 }
1049 }
1050 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001051}
1052
Dees_Troy38bd7602012-09-14 13:33:53 -04001053int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1054 struct stat st;
1055
1056 if (!Mount_By_Path("/data", true))
1057 return false;
1058
1059 if (!Mount_By_Path("/cache", true))
1060 return false;
1061
1062 ui_print("\nWiping Dalvik Cache Directories...\n");
1063 __system("rm -rf /data/dalvik-cache");
1064 ui_print("Cleaned: /data/dalvik-cache...\n");
1065 __system("rm -rf /cache/dalvik-cache");
1066 ui_print("Cleaned: /cache/dalvik-cache...\n");
1067 __system("rm -rf /cache/dc");
1068 ui_print("Cleaned: /cache/dc\n");
1069
1070 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1071 if (sdext != NULL) {
1072 if (sdext->Is_Present && sdext->Mount(false)) {
1073 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
1074 __system("rm -rf /sd-ext/dalvik-cache");
1075 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1076 }
1077 }
1078 }
1079 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1080 return true;
1081}
1082
1083int TWPartitionManager::Wipe_Rotate_Data(void) {
1084 if (!Mount_By_Path("/data", true))
1085 return false;
1086
1087 __system("rm -r /data/misc/akmd*");
1088 __system("rm -r /data/misc/rild*");
1089 ui_print("Rotation data wiped.\n");
1090 return true;
1091}
1092
1093int TWPartitionManager::Wipe_Battery_Stats(void) {
1094 struct stat st;
1095
1096 if (!Mount_By_Path("/data", true))
1097 return false;
1098
1099 if (0 != stat("/data/system/batterystats.bin", &st)) {
1100 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1101 } else {
1102 remove("/data/system/batterystats.bin");
1103 ui_print("Cleared battery stats.\n");
1104 }
1105 return true;
1106}
1107
1108int TWPartitionManager::Format_Data(void) {
1109 TWPartition* dat = Find_Partition_By_Path("/data");
1110
1111 if (dat != NULL) {
1112 if (!dat->UnMount(true))
1113 return false;
1114
1115 return dat->Wipe_Encryption();
1116 } else {
1117 LOGE("Unable to locate /data.\n");
1118 return false;
1119 }
1120 return false;
1121}
1122
1123int TWPartitionManager::Wipe_Media_From_Data(void) {
1124 TWPartition* dat = Find_Partition_By_Path("/data");
1125
1126 if (dat != NULL) {
1127 if (!dat->Has_Data_Media) {
1128 LOGE("This device does not have /data/media\n");
1129 return false;
1130 }
1131 if (!dat->Mount(true))
1132 return false;
1133
1134 ui_print("Wiping internal storage -- /data/media...\n");
1135 __system("rm -rf /data/media");
1136 __system("cd /data && mkdir media && chmod 775 media");
1137 if (dat->Has_Data_Media) {
1138 dat->Recreate_Media_Folder();
1139 }
1140 return true;
1141 } else {
1142 LOGE("Unable to locate /data.\n");
1143 return false;
1144 }
1145 return false;
1146}
1147
Dees_Troy51a0e822012-09-05 15:24:24 -04001148void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001149 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001150 return;
1151}
1152
1153void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001154 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001155 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001156
Dees_Troy32c8eb82012-09-11 15:28:06 -04001157 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001158 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001159 if ((*iter)->Can_Be_Mounted) {
1160 (*iter)->Update_Size(true);
1161 if ((*iter)->Mount_Point == "/system") {
1162 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1163 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1164 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1165 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1166 } else if ((*iter)->Mount_Point == "/cache") {
1167 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1168 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1169 } else if ((*iter)->Mount_Point == "/sd-ext") {
1170 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1171 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1172 if ((*iter)->Backup_Size == 0) {
1173 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1174 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1175 } else
1176 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
1177 }
1178 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001179 }
Dees_Troy51127312012-09-08 13:08:49 -04001180 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1181 string current_storage_path = DataManager::GetCurrentStoragePath();
1182 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
1183 if (FreeStorage)
1184 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1185 else
1186 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -04001187 if (!Write_Fstab())
1188 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001189 return;
1190}
1191
1192int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001193#ifdef TW_INCLUDE_CRYPTO
1194 int ret_val, password_len;
1195 char crypto_blkdev[255], cPassword[255];
1196 size_t result;
1197
1198 property_set("ro.crypto.state", "encrypted");
1199#ifdef TW_INCLUDE_JB_CRYPTO
1200 // No extra flags needed
1201#else
1202 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1203 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1204 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1205 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1206 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1207 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1208#endif
1209 strcpy(cPassword, Password.c_str());
1210 if (cryptfs_check_passwd(cPassword) != 0) {
1211 LOGE("Failed to decrypt data.\n");
1212 return -1;
1213 }
1214 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1215 if (strcmp(crypto_blkdev, "error") == 0) {
1216 LOGE("Error retrieving decrypted data block device.\n");
1217 } else {
1218 TWPartition* dat = Find_Partition_By_Path("/data");
1219 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001220 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001221 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1222 dat->Is_Decrypted = true;
1223 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001224 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001225 // Sleep for a bit so that the device will be ready
1226 sleep(1);
1227 Update_System_Details();
1228 } else
1229 LOGE("Unable to locate data partition.\n");
1230 }
1231 return 0;
1232#else
1233 LOGE("No crypto support was compiled into this build.\n");
1234 return -1;
1235#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001236 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001237}
1238
Dees_Troy38bd7602012-09-14 13:33:53 -04001239int TWPartitionManager::Fix_Permissions(void) {
1240 if (!Mount_By_Path("/data", true))
1241 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001242
Dees_Troy38bd7602012-09-14 13:33:53 -04001243 if (!Mount_By_Path("/system", true))
1244 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001245
Dees_Troy38bd7602012-09-14 13:33:53 -04001246 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
1247 __system("./sbin/fix_permissions.sh");
1248 ui_print("Done.\n\n");
1249 return true;
1250}