blob: 7ff5e8e05ca5822e27847eaa4324bf627004b8f7 [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
120 // Iterate through all partitions
121 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400122 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400123 ret = (*iter)->Mount(Display_Error);
124 found = true;
Dees_Troy51127312012-09-08 13:08:49 -0400125 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400126 (*iter)->Mount(Display_Error);
Dees_Troy51127312012-09-08 13:08:49 -0400127 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400128 }
129 if (found) {
130 return ret;
131 } else if (Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400132 LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400133 } else {
Dees_Troy51127312012-09-08 13:08:49 -0400134 LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400135 }
136 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400137}
138
139int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400140 TWPartition* Part = Find_Partition_By_Block(Block);
Dees_Troy5bf43922012-09-07 16:07:55 -0400141
Dees_Troy51127312012-09-08 13:08:49 -0400142 if (Part) {
143 if (Part->Has_SubPartition) {
144 std::vector<TWPartition*>::iterator subpart;
145
146 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
147 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
148 (*subpart)->Mount(Display_Error);
149 }
150 return Part->Mount(Display_Error);
151 } else
152 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400153 }
154 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400155 LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400156 else
Dees_Troy51127312012-09-08 13:08:49 -0400157 LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400158 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400159}
160
161int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400162 TWPartition* Part = Find_Partition_By_Name(Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400163
Dees_Troy51127312012-09-08 13:08:49 -0400164 if (Part) {
165 if (Part->Has_SubPartition) {
166 std::vector<TWPartition*>::iterator subpart;
167
168 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
169 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
170 (*subpart)->Mount(Display_Error);
171 }
172 return Part->Mount(Display_Error);
173 } else
174 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400175 }
176 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400177 LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400178 else
Dees_Troy51127312012-09-08 13:08:49 -0400179 LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400180 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400181}
182
183int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400184 std::vector<TWPartition*>::iterator iter;
185 int ret = false;
186 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400187 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy51127312012-09-08 13:08:49 -0400188
189 // Iterate through all partitions
190 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400191 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy51127312012-09-08 13:08:49 -0400192 ret = (*iter)->UnMount(Display_Error);
193 found = true;
194 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
195 (*iter)->UnMount(Display_Error);
196 }
197 }
198 if (found) {
199 return ret;
200 } else if (Display_Error) {
201 LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
202 } else {
203 LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
204 }
205 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400206}
207
208int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400209 TWPartition* Part = Find_Partition_By_Block(Block);
210
211 if (Part) {
212 if (Part->Has_SubPartition) {
213 std::vector<TWPartition*>::iterator subpart;
214
215 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
216 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
217 (*subpart)->UnMount(Display_Error);
218 }
219 return Part->UnMount(Display_Error);
220 } else
221 return Part->UnMount(Display_Error);
222 }
223 if (Display_Error)
224 LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
225 else
226 LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
227 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400228}
229
230int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400231 TWPartition* Part = Find_Partition_By_Name(Name);
232
233 if (Part) {
234 if (Part->Has_SubPartition) {
235 std::vector<TWPartition*>::iterator subpart;
236
237 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
238 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
239 (*subpart)->UnMount(Display_Error);
240 }
241 return Part->UnMount(Display_Error);
242 } else
243 return Part->UnMount(Display_Error);
244 }
245 if (Display_Error)
246 LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
247 else
248 LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
249 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400250}
251
252int TWPartitionManager::Is_Mounted_By_Path(string Path) {
Dees_Troy51127312012-09-08 13:08:49 -0400253 TWPartition* Part = Find_Partition_By_Path(Path);
254
255 if (Part)
256 return Part->Is_Mounted();
257 else
258 LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
259 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400260}
261
262int TWPartitionManager::Is_Mounted_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400263 TWPartition* Part = Find_Partition_By_Block(Block);
264
265 if (Part)
266 return Part->Is_Mounted();
267 else
268 LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
269 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400270}
271
272int TWPartitionManager::Is_Mounted_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400273 TWPartition* Part = Find_Partition_By_Name(Name);
274
275 if (Part)
276 return Part->Is_Mounted();
277 else
278 LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
279 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400280}
281
Dees_Troy5bf43922012-09-07 16:07:55 -0400282int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400283 string current_storage_path = DataManager::GetCurrentStoragePath();
284
285 if (Mount_By_Path(current_storage_path, Display_Error)) {
286 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
287 if (FreeStorage)
288 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
289 return true;
290 }
291 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400292}
293
Dees_Troy5bf43922012-09-07 16:07:55 -0400294int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
295 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
296}
297
298TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
299 std::vector<TWPartition*>::iterator iter;
Dees_Troy38bd7602012-09-14 13:33:53 -0400300 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400301
302 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400303 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
Dees_Troy5bf43922012-09-07 16:07:55 -0400304 return (*iter);
305 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400306 return NULL;
307}
308
Dees_Troy5bf43922012-09-07 16:07:55 -0400309TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400310 std::vector<TWPartition*>::iterator iter;
311
312 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400313 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 -0400314 return (*iter);
315 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400316 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400317}
318
319TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400320 std::vector<TWPartition*>::iterator iter;
321
322 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
323 if ((*iter)->Display_Name == Name)
324 return (*iter);
325 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400326 return NULL;
327}
Dees_Troy51a0e822012-09-05 15:24:24 -0400328
329int TWPartitionManager::Run_Backup(string Backup_Name) {
330 LOGI("STUB TWPartitionManager::Run_Backup, Backup_Name: '%s'\n", Backup_Name.c_str());
331 return 1;
332}
333
334int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400335 int check;
336 TWPartition* Part;
Dees_Troy38bd7602012-09-14 13:33:53 -0400337LOGE("TO DO: Check MD5 of all partitions before restoring ANY partitions.\n");
Dees_Troy63c8df72012-09-10 14:02:05 -0400338 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
339 if (check > 0) {
340 Part = Find_Partition_By_Path("/system");
341 if (Part) {
342 if (!Part->Restore(Restore_Name))
343 return false;
344 } else
345 LOGE("Restore: Unable to locate system partition.\n");
346 }
347 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
348 if (check > 0) {
349 Part = Find_Partition_By_Path("/data");
350 if (Part) {
351 if (!Part->Restore(Restore_Name))
352 return false;
353 } else
354 LOGE("Restore: Unable to locate data partition.\n");
355 }
356 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
357 if (check > 0) {
358 Part = Find_Partition_By_Path("/cache");
359 if (Part) {
360 if (!Part->Restore(Restore_Name))
361 return false;
362 } else
363 LOGE("Restore: Unable to locate cache partition.\n");
364 }
365 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
366 if (check > 0) {
367 Part = Find_Partition_By_Path("/boot");
368 if (Part) {
369 if (!Part->Restore(Restore_Name))
370 return false;
371 } else
372 LOGE("Restore: Unable to locate boot partition.\n");
373 }
374 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
375 if (check > 0) {
376 Part = Find_Partition_By_Path("/.android_secure");
377 if (Part) {
378 if (!Part->Restore(Restore_Name))
379 return false;
380 } else
381 LOGE("Restore: Unable to locate android_secure partition.\n");
382 }
383 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
384 if (check > 0) {
385 Part = Find_Partition_By_Path("/sd-ext");
386 if (Part) {
387 if (!Part->Restore(Restore_Name))
388 return false;
389 } else
390 LOGE("Restore: Unable to locate sd-ext partition.\n");
391 }
392#ifdef SP1_NAME
393 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
394 if (check > 0) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400395 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP1_NAME));
Dees_Troy63c8df72012-09-10 14:02:05 -0400396 if (Part) {
397 if (!Part->Restore(Restore_Name))
398 return false;
399 } else
400 LOGE("Restore: Unable to locate %s partition.\n", SP1_NAME);
401 }
402#endif
403#ifdef SP2_NAME
404 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
405 if (check > 0) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400406 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP2_NAME));
Dees_Troy63c8df72012-09-10 14:02:05 -0400407 if (Part) {
408 if (!Part->Restore(Restore_Name))
409 return false;
410 } else
411 LOGE("Restore: Unable to locate %s partition.\n", SP2_NAME);
412 }
413#endif
414#ifdef SP3_NAME
415 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
416 if (check > 0) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400417 Part = Find_Partition_By_Path(TWFunc::Get_Root_Path(SP3_NAME));
Dees_Troy63c8df72012-09-10 14:02:05 -0400418 if (Part) {
419 if (!Part->Restore(Restore_Name))
420 return false;
421 } else
422 LOGE("Restore: Unable to locate %s partition.\n", SP3_NAME);
423 }
424#endif
425 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400426}
427
428void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400429 // Start with the default values
430 int tw_restore_system = -1;
431 int tw_restore_data = -1;
432 int tw_restore_cache = -1;
433 int tw_restore_recovery = -1;
434 int tw_restore_boot = -1;
435 int tw_restore_andsec = -1;
436 int tw_restore_sdext = -1;
437 int tw_restore_sp1 = -1;
438 int tw_restore_sp2 = -1;
439 int tw_restore_sp3 = -1;
440 bool get_date = true;
441
442 DIR* d;
443 d = opendir(Restore_Name.c_str());
444 if (d == NULL)
445 {
446 LOGE("Error opening %s\n", Restore_Name.c_str());
447 return;
448 }
449
450 struct dirent* de;
451 while ((de = readdir(d)) != NULL)
452 {
453 // Strip off three components
454 char str[256];
455 char* label;
456 char* fstype = NULL;
457 char* extn = NULL;
458 char* ptr;
459
460 strcpy(str, de->d_name);
461 if (strlen(str) <= 2)
462 continue;
463
464 if (get_date) {
465 char file_path[255];
466 struct stat st;
467
468 strcpy(file_path, Restore_Name.c_str());
469 strcat(file_path, "/");
470 strcat(file_path, str);
471 stat(file_path, &st);
472 string backup_date = ctime((const time_t*)(&st.st_mtime));
473 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
474 get_date = false;
475 }
476
477 label = str;
478 ptr = label;
479 while (*ptr && *ptr != '.') ptr++;
480 if (*ptr == '.')
481 {
482 *ptr = 0x00;
483 ptr++;
484 fstype = ptr;
485 }
486 while (*ptr && *ptr != '.') ptr++;
487 if (*ptr == '.')
488 {
489 *ptr = 0x00;
490 ptr++;
491 extn = ptr;
492 }
493
494 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
495
496 TWPartition* Part = Find_Partition_By_Path(label);
497 if (Part == NULL)
498 {
499 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
500 continue;
501 }
502
503 Part->Backup_FileName = de->d_name;
504 if (strlen(extn) > 3) {
505 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
506 }
507
508 // Now, we just need to find the correct label
509 if (Part->Mount_Point == "/system")
510 tw_restore_system = 1;
511 if (Part->Mount_Point == "/data")
512 tw_restore_data = 1;
513 if (Part->Mount_Point == "/cache")
514 tw_restore_cache = 1;
515 if (Part->Mount_Point == "/recovery")
516 tw_restore_recovery = 1;
517 if (Part->Mount_Point == "/boot")
518 tw_restore_boot = 1;
519 if (Part->Mount_Point == "/.android_secure")
520 tw_restore_andsec = 1;
521 if (Part->Mount_Point == "/sd-ext")
522 tw_restore_sdext = 1;
523#ifdef SP1_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400524 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP1_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400525 tw_restore_sp1 = 1;
526#endif
527#ifdef SP2_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400528 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP2_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400529 tw_restore_sp2 = 1;
530#endif
531#ifdef SP3_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -0400532 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP3_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -0400533 tw_restore_sp3 = 1;
534#endif
535 }
536 closedir(d);
537
538 // Set the final values
539 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
540 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
541 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
542 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
543 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
544 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
545 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
546 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
547 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
548 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
549
Dees_Troy51a0e822012-09-05 15:24:24 -0400550 return;
551}
552
553int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400554 std::vector<TWPartition*>::iterator iter;
555 int ret = false;
556 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400557 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -0400558
559 // Iterate through all partitions
560 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400561 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400562 ret = (*iter)->Wipe();
563 found = true;
564 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
565 (*iter)->Wipe();
566 }
567 }
568 if (found) {
569 return ret;
570 } else
571 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
572 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400573}
574
575int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400576 TWPartition* Part = Find_Partition_By_Block(Block);
577
578 if (Part) {
579 if (Part->Has_SubPartition) {
580 std::vector<TWPartition*>::iterator subpart;
581
582 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
583 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
584 (*subpart)->Wipe();
585 }
586 return Part->Wipe();
587 } else
588 return Part->Wipe();
589 }
590 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
591 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400592}
593
594int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400595 TWPartition* Part = Find_Partition_By_Name(Name);
596
597 if (Part) {
598 if (Part->Has_SubPartition) {
599 std::vector<TWPartition*>::iterator subpart;
600
601 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
602 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
603 (*subpart)->Wipe();
604 }
605 return Part->Wipe();
606 } else
607 return Part->Wipe();
608 }
609 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
610 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400611}
612
613int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400614 std::vector<TWPartition*>::iterator iter;
615 int ret = true;
616
617 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400618 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400619 if (!(*iter)->Wipe())
620 ret = false;
621 }
622 }
623 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400624}
625
Dees_Troy38bd7602012-09-14 13:33:53 -0400626int TWPartitionManager::Wipe_Dalvik_Cache(void) {
627 struct stat st;
628
629 if (!Mount_By_Path("/data", true))
630 return false;
631
632 if (!Mount_By_Path("/cache", true))
633 return false;
634
635 ui_print("\nWiping Dalvik Cache Directories...\n");
636 __system("rm -rf /data/dalvik-cache");
637 ui_print("Cleaned: /data/dalvik-cache...\n");
638 __system("rm -rf /cache/dalvik-cache");
639 ui_print("Cleaned: /cache/dalvik-cache...\n");
640 __system("rm -rf /cache/dc");
641 ui_print("Cleaned: /cache/dc\n");
642
643 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
644 if (sdext != NULL) {
645 if (sdext->Is_Present && sdext->Mount(false)) {
646 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
647 __system("rm -rf /sd-ext/dalvik-cache");
648 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
649 }
650 }
651 }
652 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
653 return true;
654}
655
656int TWPartitionManager::Wipe_Rotate_Data(void) {
657 if (!Mount_By_Path("/data", true))
658 return false;
659
660 __system("rm -r /data/misc/akmd*");
661 __system("rm -r /data/misc/rild*");
662 ui_print("Rotation data wiped.\n");
663 return true;
664}
665
666int TWPartitionManager::Wipe_Battery_Stats(void) {
667 struct stat st;
668
669 if (!Mount_By_Path("/data", true))
670 return false;
671
672 if (0 != stat("/data/system/batterystats.bin", &st)) {
673 ui_print("No Battery Stats Found. No Need To Wipe.\n");
674 } else {
675 remove("/data/system/batterystats.bin");
676 ui_print("Cleared battery stats.\n");
677 }
678 return true;
679}
680
681int TWPartitionManager::Format_Data(void) {
682 TWPartition* dat = Find_Partition_By_Path("/data");
683
684 if (dat != NULL) {
685 if (!dat->UnMount(true))
686 return false;
687
688 return dat->Wipe_Encryption();
689 } else {
690 LOGE("Unable to locate /data.\n");
691 return false;
692 }
693 return false;
694}
695
696int TWPartitionManager::Wipe_Media_From_Data(void) {
697 TWPartition* dat = Find_Partition_By_Path("/data");
698
699 if (dat != NULL) {
700 if (!dat->Has_Data_Media) {
701 LOGE("This device does not have /data/media\n");
702 return false;
703 }
704 if (!dat->Mount(true))
705 return false;
706
707 ui_print("Wiping internal storage -- /data/media...\n");
708 __system("rm -rf /data/media");
709 __system("cd /data && mkdir media && chmod 775 media");
710 if (dat->Has_Data_Media) {
711 dat->Recreate_Media_Folder();
712 }
713 return true;
714 } else {
715 LOGE("Unable to locate /data.\n");
716 return false;
717 }
718 return false;
719}
720
Dees_Troy51a0e822012-09-05 15:24:24 -0400721void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -0400722 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -0400723 return;
724}
725
726void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400727 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -0400728 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -0400729
Dees_Troy32c8eb82012-09-11 15:28:06 -0400730 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -0400731 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -0400732 if ((*iter)->Can_Be_Mounted) {
733 (*iter)->Update_Size(true);
734 if ((*iter)->Mount_Point == "/system") {
735 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
736 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
737 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
738 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
739 } else if ((*iter)->Mount_Point == "/cache") {
740 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
741 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
742 } else if ((*iter)->Mount_Point == "/sd-ext") {
743 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
744 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
745 if ((*iter)->Backup_Size == 0) {
746 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
747 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
748 } else
749 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
750 }
751 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400752 }
Dees_Troy51127312012-09-08 13:08:49 -0400753 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
754 string current_storage_path = DataManager::GetCurrentStoragePath();
755 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
756 if (FreeStorage)
757 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
758 else
759 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400760 if (!Write_Fstab())
761 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400762 return;
763}
764
765int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400766#ifdef TW_INCLUDE_CRYPTO
767 int ret_val, password_len;
768 char crypto_blkdev[255], cPassword[255];
769 size_t result;
770
771 property_set("ro.crypto.state", "encrypted");
772#ifdef TW_INCLUDE_JB_CRYPTO
773 // No extra flags needed
774#else
775 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
776 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
777 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
778 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
779 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
780 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
781#endif
782 strcpy(cPassword, Password.c_str());
783 if (cryptfs_check_passwd(cPassword) != 0) {
784 LOGE("Failed to decrypt data.\n");
785 return -1;
786 }
787 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
788 if (strcmp(crypto_blkdev, "error") == 0) {
789 LOGE("Error retrieving decrypted data block device.\n");
790 } else {
791 TWPartition* dat = Find_Partition_By_Path("/data");
792 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400793 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -0400794 DataManager::SetValue(TW_IS_DECRYPTED, 1);
795 dat->Is_Decrypted = true;
796 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -0400797 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -0400798 // Sleep for a bit so that the device will be ready
799 sleep(1);
800 Update_System_Details();
801 } else
802 LOGE("Unable to locate data partition.\n");
803 }
804 return 0;
805#else
806 LOGE("No crypto support was compiled into this build.\n");
807 return -1;
808#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400809 return 1;
Dees_Troy51127312012-09-08 13:08:49 -0400810}
811
Dees_Troy38bd7602012-09-14 13:33:53 -0400812int TWPartitionManager::Fix_Permissions(void) {
813 if (!Mount_By_Path("/data", true))
814 return false;
Dees_Troy51127312012-09-08 13:08:49 -0400815
Dees_Troy38bd7602012-09-14 13:33:53 -0400816 if (!Mount_By_Path("/system", true))
817 return false;
Dees_Troy51127312012-09-08 13:08:49 -0400818
Dees_Troy38bd7602012-09-14 13:33:53 -0400819 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
820 __system("./sbin/fix_permissions.sh");
821 ui_print("Done.\n\n");
822 return true;
823}