blob: 21752a0cb29acd07940ab2f37e9b7cd04bf9a093 [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"
37
38#ifdef TW_INCLUDE_CRYPTO
39 #ifdef TW_INCLUDE_JB_CRYPTO
40 #include "crypto/jb/cryptfs.h"
41 #else
42 #include "crypto/ics/cryptfs.h"
43 #endif
44 #include "cutils/properties.h"
45#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040046
47int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -040048 FILE *fstabFile;
49 char fstab_line[MAX_FSTAB_LINE_LENGTH];
50
51 fstabFile = fopen(Fstab_Filename.c_str(), "rt");
52 if (fstabFile == NULL) {
53 LOGE("Critical Error: Unable to open fstab at '%s'.\n", Fstab_Filename.c_str());
54 return false;
55 }
56
57 while (fgets(fstab_line, sizeof(fstab_line), fstabFile) != NULL) {
58 if (fstab_line[0] != '/')
59 continue;
60
61 TWPartition* partition = new TWPartition();
62 string line(fstab_line);
63 if (partition->Process_Fstab_Line(line, Display_Error)) {
64 Partitions.push_back(partition);
65 } else {
66 delete partition;
67 }
68 }
69 fclose(fstabFile);
70 if (!Write_Fstab()) {
71 if (Display_Error)
72 LOGE("Error creating fstab\n");
73 else
74 LOGI("Error creating fstab\n");
75 }
Dees_Troy51127312012-09-08 13:08:49 -040076 Update_System_Details();
Dees_Troy5bf43922012-09-07 16:07:55 -040077 return true;
78}
79
80int TWPartitionManager::Write_Fstab(void) {
81 FILE *fp;
82 std::vector<TWPartition*>::iterator iter;
83 string Line;
84
85 fp = fopen("/etc/fstab", "w");
86 if (fp == NULL) {
Dees_Troy63c8df72012-09-10 14:02:05 -040087 LOGI("Can not open /etc/fstab.\n");
Dees_Troy5bf43922012-09-07 16:07:55 -040088 return false;
89 }
Dees_Troy63c8df72012-09-10 14:02:05 -040090 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -040091 if ((*iter)->Can_Be_Mounted) {
Dees_Troy5bf43922012-09-07 16:07:55 -040092 if ((*iter)->Is_Decrypted)
93 Line = (*iter)->Decrypted_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
94 else
95 Line = (*iter)->Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
96 fputs(Line.c_str(), fp);
Dees_Troy51127312012-09-08 13:08:49 -040097 // Handle subpartition tracking
98 if ((*iter)->Is_SubPartition) {
99 TWPartition* ParentPartition = Find_Partition_By_Path((*iter)->SubPartition_Of);
100 if (ParentPartition)
101 ParentPartition->Has_SubPartition = true;
102 else
103 LOGE("Unable to locate parent partition '%s' of '%s'\n", (*iter)->SubPartition_Of.c_str(), (*iter)->Mount_Point.c_str());
104 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400105 }
106 }
107 fclose(fp);
108 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400109}
110
111int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400112 std::vector<TWPartition*>::iterator iter;
113 int ret = false;
114 bool found = false;
Dees_Troy51127312012-09-08 13:08:49 -0400115 string Local_Path = Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400116
117 // Iterate through all partitions
118 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400119 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400120 ret = (*iter)->Mount(Display_Error);
121 found = true;
Dees_Troy51127312012-09-08 13:08:49 -0400122 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400123 (*iter)->Mount(Display_Error);
Dees_Troy51127312012-09-08 13:08:49 -0400124 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400125 }
126 if (found) {
127 return ret;
128 } else if (Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400129 LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400130 } else {
Dees_Troy51127312012-09-08 13:08:49 -0400131 LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400132 }
133 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400134}
135
136int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400137 TWPartition* Part = Find_Partition_By_Block(Block);
Dees_Troy5bf43922012-09-07 16:07:55 -0400138
Dees_Troy51127312012-09-08 13:08:49 -0400139 if (Part) {
140 if (Part->Has_SubPartition) {
141 std::vector<TWPartition*>::iterator subpart;
142
143 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
144 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
145 (*subpart)->Mount(Display_Error);
146 }
147 return Part->Mount(Display_Error);
148 } else
149 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400150 }
151 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400152 LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400153 else
Dees_Troy51127312012-09-08 13:08:49 -0400154 LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400155 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400156}
157
158int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400159 TWPartition* Part = Find_Partition_By_Name(Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400160
Dees_Troy51127312012-09-08 13:08:49 -0400161 if (Part) {
162 if (Part->Has_SubPartition) {
163 std::vector<TWPartition*>::iterator subpart;
164
165 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
166 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
167 (*subpart)->Mount(Display_Error);
168 }
169 return Part->Mount(Display_Error);
170 } else
171 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400172 }
173 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400174 LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400175 else
Dees_Troy51127312012-09-08 13:08:49 -0400176 LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400177 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400178}
179
180int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400181 std::vector<TWPartition*>::iterator iter;
182 int ret = false;
183 bool found = false;
184 string Local_Path = Get_Root_Path(Path);
185
186 // Iterate through all partitions
187 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400188 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy51127312012-09-08 13:08:49 -0400189 ret = (*iter)->UnMount(Display_Error);
190 found = true;
191 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
192 (*iter)->UnMount(Display_Error);
193 }
194 }
195 if (found) {
196 return ret;
197 } else if (Display_Error) {
198 LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
199 } else {
200 LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
201 }
202 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400203}
204
205int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400206 TWPartition* Part = Find_Partition_By_Block(Block);
207
208 if (Part) {
209 if (Part->Has_SubPartition) {
210 std::vector<TWPartition*>::iterator subpart;
211
212 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
213 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
214 (*subpart)->UnMount(Display_Error);
215 }
216 return Part->UnMount(Display_Error);
217 } else
218 return Part->UnMount(Display_Error);
219 }
220 if (Display_Error)
221 LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
222 else
223 LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
224 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400225}
226
227int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400228 TWPartition* Part = Find_Partition_By_Name(Name);
229
230 if (Part) {
231 if (Part->Has_SubPartition) {
232 std::vector<TWPartition*>::iterator subpart;
233
234 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
235 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
236 (*subpart)->UnMount(Display_Error);
237 }
238 return Part->UnMount(Display_Error);
239 } else
240 return Part->UnMount(Display_Error);
241 }
242 if (Display_Error)
243 LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
244 else
245 LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
246 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400247}
248
249int TWPartitionManager::Is_Mounted_By_Path(string Path) {
Dees_Troy51127312012-09-08 13:08:49 -0400250 TWPartition* Part = Find_Partition_By_Path(Path);
251
252 if (Part)
253 return Part->Is_Mounted();
254 else
255 LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
256 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400257}
258
259int TWPartitionManager::Is_Mounted_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400260 TWPartition* Part = Find_Partition_By_Block(Block);
261
262 if (Part)
263 return Part->Is_Mounted();
264 else
265 LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
266 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400267}
268
269int TWPartitionManager::Is_Mounted_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400270 TWPartition* Part = Find_Partition_By_Name(Name);
271
272 if (Part)
273 return Part->Is_Mounted();
274 else
275 LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
276 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400277}
278
Dees_Troy5bf43922012-09-07 16:07:55 -0400279int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400280 string current_storage_path = DataManager::GetCurrentStoragePath();
281
282 if (Mount_By_Path(current_storage_path, Display_Error)) {
283 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
284 if (FreeStorage)
285 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
286 return true;
287 }
288 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400289}
290
Dees_Troy5bf43922012-09-07 16:07:55 -0400291int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
292 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
293}
294
295TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
296 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -0400297 string Local_Path = Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400298
299 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400300 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
Dees_Troy5bf43922012-09-07 16:07:55 -0400301 return (*iter);
302 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400303 return NULL;
304}
305
Dees_Troy5bf43922012-09-07 16:07:55 -0400306TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400307 std::vector<TWPartition*>::iterator iter;
308
309 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
310 if ((*iter)->Block_Device == Block || (*iter)->Alternate_Block_Device == Block || ((*iter)->Is_Decrypted && (*iter)->Decrypted_Block_Device == Block))
311 return (*iter);
312 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400313 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400314}
315
316TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400317 std::vector<TWPartition*>::iterator iter;
318
319 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
320 if ((*iter)->Display_Name == Name)
321 return (*iter);
322 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400323 return NULL;
324}
Dees_Troy51a0e822012-09-05 15:24:24 -0400325
326int TWPartitionManager::Run_Backup(string Backup_Name) {
327 LOGI("STUB TWPartitionManager::Run_Backup, Backup_Name: '%s'\n", Backup_Name.c_str());
328 return 1;
329}
330
331int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400332 int check;
333 TWPartition* Part;
334
335 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
336 if (check > 0) {
337 Part = Find_Partition_By_Path("/system");
338 if (Part) {
339 if (!Part->Restore(Restore_Name))
340 return false;
341 } else
342 LOGE("Restore: Unable to locate system partition.\n");
343 }
344 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
345 if (check > 0) {
346 Part = Find_Partition_By_Path("/data");
347 if (Part) {
348 if (!Part->Restore(Restore_Name))
349 return false;
350 } else
351 LOGE("Restore: Unable to locate data partition.\n");
352 }
353 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
354 if (check > 0) {
355 Part = Find_Partition_By_Path("/cache");
356 if (Part) {
357 if (!Part->Restore(Restore_Name))
358 return false;
359 } else
360 LOGE("Restore: Unable to locate cache partition.\n");
361 }
362 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
363 if (check > 0) {
364 Part = Find_Partition_By_Path("/boot");
365 if (Part) {
366 if (!Part->Restore(Restore_Name))
367 return false;
368 } else
369 LOGE("Restore: Unable to locate boot partition.\n");
370 }
371 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
372 if (check > 0) {
373 Part = Find_Partition_By_Path("/.android_secure");
374 if (Part) {
375 if (!Part->Restore(Restore_Name))
376 return false;
377 } else
378 LOGE("Restore: Unable to locate android_secure partition.\n");
379 }
380 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
381 if (check > 0) {
382 Part = Find_Partition_By_Path("/sd-ext");
383 if (Part) {
384 if (!Part->Restore(Restore_Name))
385 return false;
386 } else
387 LOGE("Restore: Unable to locate sd-ext partition.\n");
388 }
389#ifdef SP1_NAME
390 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
391 if (check > 0) {
392 Part = Find_Partition_By_Path(Get_Root_Path(SP1_NAME));
393 if (Part) {
394 if (!Part->Restore(Restore_Name))
395 return false;
396 } else
397 LOGE("Restore: Unable to locate %s partition.\n", SP1_NAME);
398 }
399#endif
400#ifdef SP2_NAME
401 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
402 if (check > 0) {
403 Part = Find_Partition_By_Path(Get_Root_Path(SP2_NAME));
404 if (Part) {
405 if (!Part->Restore(Restore_Name))
406 return false;
407 } else
408 LOGE("Restore: Unable to locate %s partition.\n", SP2_NAME);
409 }
410#endif
411#ifdef SP3_NAME
412 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
413 if (check > 0) {
414 Part = Find_Partition_By_Path(Get_Root_Path(SP3_NAME));
415 if (Part) {
416 if (!Part->Restore(Restore_Name))
417 return false;
418 } else
419 LOGE("Restore: Unable to locate %s partition.\n", SP3_NAME);
420 }
421#endif
422 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400423}
424
425void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400426 // Start with the default values
427 int tw_restore_system = -1;
428 int tw_restore_data = -1;
429 int tw_restore_cache = -1;
430 int tw_restore_recovery = -1;
431 int tw_restore_boot = -1;
432 int tw_restore_andsec = -1;
433 int tw_restore_sdext = -1;
434 int tw_restore_sp1 = -1;
435 int tw_restore_sp2 = -1;
436 int tw_restore_sp3 = -1;
437 bool get_date = true;
438
439 DIR* d;
440 d = opendir(Restore_Name.c_str());
441 if (d == NULL)
442 {
443 LOGE("Error opening %s\n", Restore_Name.c_str());
444 return;
445 }
446
447 struct dirent* de;
448 while ((de = readdir(d)) != NULL)
449 {
450 // Strip off three components
451 char str[256];
452 char* label;
453 char* fstype = NULL;
454 char* extn = NULL;
455 char* ptr;
456
457 strcpy(str, de->d_name);
458 if (strlen(str) <= 2)
459 continue;
460
461 if (get_date) {
462 char file_path[255];
463 struct stat st;
464
465 strcpy(file_path, Restore_Name.c_str());
466 strcat(file_path, "/");
467 strcat(file_path, str);
468 stat(file_path, &st);
469 string backup_date = ctime((const time_t*)(&st.st_mtime));
470 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
471 get_date = false;
472 }
473
474 label = str;
475 ptr = label;
476 while (*ptr && *ptr != '.') ptr++;
477 if (*ptr == '.')
478 {
479 *ptr = 0x00;
480 ptr++;
481 fstype = ptr;
482 }
483 while (*ptr && *ptr != '.') ptr++;
484 if (*ptr == '.')
485 {
486 *ptr = 0x00;
487 ptr++;
488 extn = ptr;
489 }
490
491 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
492
493 TWPartition* Part = Find_Partition_By_Path(label);
494 if (Part == NULL)
495 {
496 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
497 continue;
498 }
499
500 Part->Backup_FileName = de->d_name;
501 if (strlen(extn) > 3) {
502 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
503 }
504
505 // Now, we just need to find the correct label
506 if (Part->Mount_Point == "/system")
507 tw_restore_system = 1;
508 if (Part->Mount_Point == "/data")
509 tw_restore_data = 1;
510 if (Part->Mount_Point == "/cache")
511 tw_restore_cache = 1;
512 if (Part->Mount_Point == "/recovery")
513 tw_restore_recovery = 1;
514 if (Part->Mount_Point == "/boot")
515 tw_restore_boot = 1;
516 if (Part->Mount_Point == "/.android_secure")
517 tw_restore_andsec = 1;
518 if (Part->Mount_Point == "/sd-ext")
519 tw_restore_sdext = 1;
520#ifdef SP1_NAME
521 if (Part->Mount_Point == Get_Root_Path(SP1_Name))
522 tw_restore_sp1 = 1;
523#endif
524#ifdef SP2_NAME
525 if (Part->Mount_Point == Get_Root_Path(SP2_Name))
526 tw_restore_sp2 = 1;
527#endif
528#ifdef SP3_NAME
529 if (Part->Mount_Point == Get_Root_Path(SP3_Name))
530 tw_restore_sp3 = 1;
531#endif
532 }
533 closedir(d);
534
535 // Set the final values
536 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
537 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
538 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
539 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
540 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
541 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
542 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
543 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
544 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
545 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
546
Dees_Troy51a0e822012-09-05 15:24:24 -0400547 return;
548}
549
550int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400551 std::vector<TWPartition*>::iterator iter;
552 int ret = false;
553 bool found = false;
554 string Local_Path = Get_Root_Path(Path);
555
556 // Iterate through all partitions
557 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400558 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400559 ret = (*iter)->Wipe();
560 found = true;
561 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
562 (*iter)->Wipe();
563 }
564 }
565 if (found) {
566 return ret;
567 } else
568 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
569 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400570}
571
572int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400573 TWPartition* Part = Find_Partition_By_Block(Block);
574
575 if (Part) {
576 if (Part->Has_SubPartition) {
577 std::vector<TWPartition*>::iterator subpart;
578
579 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
580 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
581 (*subpart)->Wipe();
582 }
583 return Part->Wipe();
584 } else
585 return Part->Wipe();
586 }
587 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
588 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400589}
590
591int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400592 TWPartition* Part = Find_Partition_By_Name(Name);
593
594 if (Part) {
595 if (Part->Has_SubPartition) {
596 std::vector<TWPartition*>::iterator subpart;
597
598 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
599 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
600 (*subpart)->Wipe();
601 }
602 return Part->Wipe();
603 } else
604 return Part->Wipe();
605 }
606 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
607 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400608}
609
610int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400611 std::vector<TWPartition*>::iterator iter;
612 int ret = true;
613
614 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
615 if ((*iter)->Wipe_During_Factory_Reset) {
616 if (!(*iter)->Wipe())
617 ret = false;
618 }
619 }
620 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -0400621}
622
623void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -0400624 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -0400625 return;
626}
627
628void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400629 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -0400630 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -0400631
Dees_Troy32c8eb82012-09-11 15:28:06 -0400632 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -0400633 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -0400634 if ((*iter)->Can_Be_Mounted) {
635 (*iter)->Update_Size(true);
636 if ((*iter)->Mount_Point == "/system") {
637 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
638 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
639 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
640 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
641 } else if ((*iter)->Mount_Point == "/cache") {
642 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
643 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
644 } else if ((*iter)->Mount_Point == "/sd-ext") {
645 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
646 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
647 if ((*iter)->Backup_Size == 0) {
648 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
649 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
650 } else
651 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
652 }
653 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400654 }
Dees_Troy51127312012-09-08 13:08:49 -0400655 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
656 string current_storage_path = DataManager::GetCurrentStoragePath();
657 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
658 if (FreeStorage)
659 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
660 else
661 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400662 if (!Write_Fstab())
663 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400664 return;
665}
666
667int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400668#ifdef TW_INCLUDE_CRYPTO
669 int ret_val, password_len;
670 char crypto_blkdev[255], cPassword[255];
671 size_t result;
672
673 property_set("ro.crypto.state", "encrypted");
674#ifdef TW_INCLUDE_JB_CRYPTO
675 // No extra flags needed
676#else
677 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
678 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
679 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
680 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
681 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
682 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
683#endif
684 strcpy(cPassword, Password.c_str());
685 if (cryptfs_check_passwd(cPassword) != 0) {
686 LOGE("Failed to decrypt data.\n");
687 return -1;
688 }
689 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
690 if (strcmp(crypto_blkdev, "error") == 0) {
691 LOGE("Error retrieving decrypted data block device.\n");
692 } else {
693 TWPartition* dat = Find_Partition_By_Path("/data");
694 if (dat != NULL) {
695 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Block_Device);
696 DataManager::SetValue(TW_IS_DECRYPTED, 1);
697 dat->Is_Decrypted = true;
698 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -0400699 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -0400700 // Sleep for a bit so that the device will be ready
701 sleep(1);
702 Update_System_Details();
703 } else
704 LOGE("Unable to locate data partition.\n");
705 }
706 return 0;
707#else
708 LOGE("No crypto support was compiled into this build.\n");
709 return -1;
710#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400711 return 1;
Dees_Troy51127312012-09-08 13:08:49 -0400712}
713
714string TWPartitionManager::Get_Root_Path(string Path) {
715 string Local_Path = Path;
716
717 // Make sure that we have a leading slash
718 if (Local_Path.substr(0, 1) != "/")
719 Local_Path = "/" + Local_Path;
720
721 // Trim the path to get the root path only
722 size_t position = Local_Path.find("/", 2);
723 if (position != string::npos) {
724 Local_Path.resize(position);
725 }
726 return Local_Path;
727}