blob: a42c3030812130c20410672fd6e922dc42892f55 [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_Troy8170a922012-09-18 15:40:25 -040032#include <errno.h>
33#include <fcntl.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040034
35#include "variables.h"
36#include "common.h"
37#include "partitions.hpp"
Dees_Troy5bf43922012-09-07 16:07:55 -040038#include "data.hpp"
Dees_Troy38bd7602012-09-14 13:33:53 -040039#include "twrp-functions.hpp"
40
Dees_Troy5bf43922012-09-07 16:07:55 -040041#ifdef TW_INCLUDE_CRYPTO
42 #ifdef TW_INCLUDE_JB_CRYPTO
43 #include "crypto/jb/cryptfs.h"
44 #else
45 #include "crypto/ics/cryptfs.h"
46 #endif
47 #include "cutils/properties.h"
48#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040049
50int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -040051 FILE *fstabFile;
52 char fstab_line[MAX_FSTAB_LINE_LENGTH];
53
54 fstabFile = fopen(Fstab_Filename.c_str(), "rt");
55 if (fstabFile == NULL) {
56 LOGE("Critical Error: Unable to open fstab at '%s'.\n", Fstab_Filename.c_str());
57 return false;
58 }
59
60 while (fgets(fstab_line, sizeof(fstab_line), fstabFile) != NULL) {
61 if (fstab_line[0] != '/')
62 continue;
63
Dees_Troy2a923582012-09-20 12:13:34 -040064 if (fstab_line[strlen(fstab_line) - 1] != '\n')
65 fstab_line[strlen(fstab_line)] = '\n';
66
Dees_Troy5bf43922012-09-07 16:07:55 -040067 TWPartition* partition = new TWPartition();
Dees_Troy2a923582012-09-20 12:13:34 -040068 string line = fstab_line;
Dees_Troyab10ee22012-09-21 14:27:30 -040069 memset(fstab_line, 0, sizeof(fstab_line));
Dees_Troy2a923582012-09-20 12:13:34 -040070
Dees_Troy5bf43922012-09-07 16:07:55 -040071 if (partition->Process_Fstab_Line(line, Display_Error)) {
72 Partitions.push_back(partition);
73 } else {
74 delete partition;
75 }
76 }
77 fclose(fstabFile);
78 if (!Write_Fstab()) {
79 if (Display_Error)
80 LOGE("Error creating fstab\n");
81 else
82 LOGI("Error creating fstab\n");
83 }
Dees_Troy51127312012-09-08 13:08:49 -040084 Update_System_Details();
Dees_Troy5bf43922012-09-07 16:07:55 -040085 return true;
86}
87
88int TWPartitionManager::Write_Fstab(void) {
89 FILE *fp;
90 std::vector<TWPartition*>::iterator iter;
91 string Line;
92
93 fp = fopen("/etc/fstab", "w");
94 if (fp == NULL) {
Dees_Troy63c8df72012-09-10 14:02:05 -040095 LOGI("Can not open /etc/fstab.\n");
Dees_Troy5bf43922012-09-07 16:07:55 -040096 return false;
97 }
Dees_Troy63c8df72012-09-10 14:02:05 -040098 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -040099 if ((*iter)->Can_Be_Mounted) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400100 Line = (*iter)->Actual_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
Dees_Troy5bf43922012-09-07 16:07:55 -0400101 fputs(Line.c_str(), fp);
Dees_Troy51127312012-09-08 13:08:49 -0400102 // Handle subpartition tracking
103 if ((*iter)->Is_SubPartition) {
104 TWPartition* ParentPartition = Find_Partition_By_Path((*iter)->SubPartition_Of);
105 if (ParentPartition)
106 ParentPartition->Has_SubPartition = true;
107 else
108 LOGE("Unable to locate parent partition '%s' of '%s'\n", (*iter)->SubPartition_Of.c_str(), (*iter)->Mount_Point.c_str());
109 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400110 }
111 }
112 fclose(fp);
113 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400114}
115
Dees_Troy8170a922012-09-18 15:40:25 -0400116void TWPartitionManager::Output_Partition_Logging(void) {
117 std::vector<TWPartition*>::iterator iter;
118
119 printf("\n\nPartition Logs:\n");
120 for (iter = Partitions.begin(); iter != Partitions.end(); iter++)
121 Output_Partition((*iter));
122}
123
124void TWPartitionManager::Output_Partition(TWPartition* Part) {
125 unsigned long long mb = 1048576;
126
127 if (Part->Can_Be_Mounted) {
128 printf("%s | %s | Size: %iMB Used: %iMB Free: %iMB Backup Size: %iMB\n Flags: ", Part->Mount_Point.c_str(), Part->Actual_Block_Device.c_str(), (int)(Part->Size / mb), (int)(Part->Used / mb), (int)(Part->Free / mb), (int)(Part->Backup_Size / mb));
129 if (Part->Can_Be_Wiped)
130 printf("Can_Be_Wiped ");
131 if (Part->Wipe_During_Factory_Reset)
132 printf("Wipe_During_Factory_Reset ");
133 if (Part->Wipe_Available_in_GUI)
134 printf("Wipe_Available_in_GUI ");
135 if (Part->Is_SubPartition)
136 printf("Is_SubPartition ");
137 if (Part->Has_SubPartition)
138 printf("Has_SubPartition ");
139 if (Part->Removable)
140 printf("Removable ");
141 if (Part->Is_Present)
142 printf("IsPresent ");
143 if (Part->Can_Be_Encrypted)
144 printf("Can_Be_Encrypted ");
145 if (Part->Is_Encrypted)
146 printf("Is_Encrypted ");
147 if (Part->Is_Decrypted)
148 printf("Is_Decrypted ");
149 if (Part->Has_Data_Media)
150 printf("Has_Data_Media ");
Dees_Troye58d5262012-09-21 12:27:57 -0400151 if (Part->Has_Android_Secure)
152 printf("Has_Android_Secure ");
Dees_Troy8170a922012-09-18 15:40:25 -0400153 if (Part->Is_Storage)
154 printf("Is_Storage ");
155 printf("\n");
156 if (!Part->SubPartition_Of.empty())
157 printf(" SubPartition_Of: %s\n", Part->SubPartition_Of.c_str());
158 if (!Part->Symlink_Path.empty())
159 printf(" Symlink_Path: %s\n", Part->Symlink_Path.c_str());
160 if (!Part->Symlink_Mount_Point.empty())
161 printf(" Symlink_Mount_Point: %s\n", Part->Symlink_Mount_Point.c_str());
162 if (!Part->Primary_Block_Device.empty())
163 printf(" Primary_Block_Device: %s\n", Part->Primary_Block_Device.c_str());
164 if (!Part->Alternate_Block_Device.empty())
165 printf(" Alternate_Block_Device: %s\n", Part->Alternate_Block_Device.c_str());
166 if (!Part->Decrypted_Block_Device.empty())
167 printf(" Decrypted_Block_Device: %s\n", Part->Decrypted_Block_Device.c_str());
168 if (Part->Length != 0)
169 printf(" Length: %i\n", Part->Length);
170 if (!Part->Display_Name.empty())
171 printf(" Display_Name: %s\n", Part->Display_Name.c_str());
Dees_Troye58d5262012-09-21 12:27:57 -0400172 if (!Part->Backup_Path.empty())
173 printf(" Backup_Path: %s\n", Part->Backup_Path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -0400174 if (!Part->Backup_Name.empty())
175 printf(" Backup_Name: %s\n", Part->Backup_Name.c_str());
176 if (!Part->Backup_FileName.empty())
177 printf(" Backup_FileName: %s\n", Part->Backup_FileName.c_str());
178 if (!Part->MTD_Name.empty())
179 printf(" MTD_Name: %s\n", Part->MTD_Name.c_str());
180 if (!Part->Storage_Path.empty())
181 printf(" Storage_Path: %s\n", Part->Storage_Path.c_str());
182 if (!Part->Current_File_System.empty())
183 printf(" Current_File_System: %s\n", Part->Current_File_System.c_str());
184 if (!Part->Fstab_File_System.empty())
185 printf(" Fstab_File_System: %s\n", Part->Fstab_File_System.c_str());
186 if (Part->Format_Block_Size != 0)
187 printf(" Format_Block_Size: %i\n", Part->Format_Block_Size);
188 } else {
189 printf("%s | %s | Size: %iMB\n", Part->Mount_Point.c_str(), Part->Actual_Block_Device.c_str(), (int)(Part->Size / mb));
190 }
191 string back_meth = Part->Backup_Method_By_Name();
192 printf(" Backup_Method: %s\n\n", back_meth.c_str());
193}
194
Dees_Troy51a0e822012-09-05 15:24:24 -0400195int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400196 std::vector<TWPartition*>::iterator iter;
197 int ret = false;
198 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400199 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400200
Dees_Troy43d8b002012-09-17 16:00:01 -0400201 if (Local_Path == "/tmp")
202 return true;
203
Dees_Troy5bf43922012-09-07 16:07:55 -0400204 // Iterate through all partitions
205 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400206 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400207 ret = (*iter)->Mount(Display_Error);
208 found = true;
Dees_Troy51127312012-09-08 13:08:49 -0400209 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400210 (*iter)->Mount(Display_Error);
Dees_Troy51127312012-09-08 13:08:49 -0400211 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400212 }
213 if (found) {
214 return ret;
215 } else if (Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400216 LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400217 } else {
Dees_Troy51127312012-09-08 13:08:49 -0400218 LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400219 }
220 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400221}
222
223int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400224 TWPartition* Part = Find_Partition_By_Block(Block);
Dees_Troy5bf43922012-09-07 16:07:55 -0400225
Dees_Troy51127312012-09-08 13:08:49 -0400226 if (Part) {
227 if (Part->Has_SubPartition) {
228 std::vector<TWPartition*>::iterator subpart;
229
230 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
231 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
232 (*subpart)->Mount(Display_Error);
233 }
234 return Part->Mount(Display_Error);
235 } else
236 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400237 }
238 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400239 LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400240 else
Dees_Troy51127312012-09-08 13:08:49 -0400241 LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400242 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400243}
244
245int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400246 TWPartition* Part = Find_Partition_By_Name(Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400247
Dees_Troy51127312012-09-08 13:08:49 -0400248 if (Part) {
249 if (Part->Has_SubPartition) {
250 std::vector<TWPartition*>::iterator subpart;
251
252 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
253 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
254 (*subpart)->Mount(Display_Error);
255 }
256 return Part->Mount(Display_Error);
257 } else
258 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400259 }
260 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400261 LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400262 else
Dees_Troy51127312012-09-08 13:08:49 -0400263 LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400264 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400265}
266
267int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400268 std::vector<TWPartition*>::iterator iter;
269 int ret = false;
270 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400271 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy51127312012-09-08 13:08:49 -0400272
273 // Iterate through all partitions
274 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400275 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy51127312012-09-08 13:08:49 -0400276 ret = (*iter)->UnMount(Display_Error);
277 found = true;
278 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
279 (*iter)->UnMount(Display_Error);
280 }
281 }
282 if (found) {
283 return ret;
284 } else if (Display_Error) {
285 LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
286 } else {
287 LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
288 }
289 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400290}
291
292int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400293 TWPartition* Part = Find_Partition_By_Block(Block);
294
295 if (Part) {
296 if (Part->Has_SubPartition) {
297 std::vector<TWPartition*>::iterator subpart;
298
299 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
300 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
301 (*subpart)->UnMount(Display_Error);
302 }
303 return Part->UnMount(Display_Error);
304 } else
305 return Part->UnMount(Display_Error);
306 }
307 if (Display_Error)
308 LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
309 else
310 LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
311 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400312}
313
314int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400315 TWPartition* Part = Find_Partition_By_Name(Name);
316
317 if (Part) {
318 if (Part->Has_SubPartition) {
319 std::vector<TWPartition*>::iterator subpart;
320
321 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
322 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
323 (*subpart)->UnMount(Display_Error);
324 }
325 return Part->UnMount(Display_Error);
326 } else
327 return Part->UnMount(Display_Error);
328 }
329 if (Display_Error)
330 LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
331 else
332 LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
333 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400334}
335
336int TWPartitionManager::Is_Mounted_By_Path(string Path) {
Dees_Troy51127312012-09-08 13:08:49 -0400337 TWPartition* Part = Find_Partition_By_Path(Path);
338
339 if (Part)
340 return Part->Is_Mounted();
341 else
342 LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
343 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400344}
345
346int TWPartitionManager::Is_Mounted_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400347 TWPartition* Part = Find_Partition_By_Block(Block);
348
349 if (Part)
350 return Part->Is_Mounted();
351 else
352 LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
353 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400354}
355
356int TWPartitionManager::Is_Mounted_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400357 TWPartition* Part = Find_Partition_By_Name(Name);
358
359 if (Part)
360 return Part->Is_Mounted();
361 else
362 LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
363 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400364}
365
Dees_Troy5bf43922012-09-07 16:07:55 -0400366int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400367 string current_storage_path = DataManager::GetCurrentStoragePath();
368
369 if (Mount_By_Path(current_storage_path, Display_Error)) {
370 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
371 if (FreeStorage)
372 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
373 return true;
374 }
375 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400376}
377
Dees_Troy5bf43922012-09-07 16:07:55 -0400378int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
379 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
380}
381
382TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
383 std::vector<TWPartition*>::iterator iter;
Dees_Troy38bd7602012-09-14 13:33:53 -0400384 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400385
386 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400387 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
Dees_Troy5bf43922012-09-07 16:07:55 -0400388 return (*iter);
389 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400390 return NULL;
391}
392
Dees_Troy5bf43922012-09-07 16:07:55 -0400393TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400394 std::vector<TWPartition*>::iterator iter;
395
396 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400397 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 -0400398 return (*iter);
399 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400400 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400401}
402
403TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400404 std::vector<TWPartition*>::iterator iter;
405
406 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
407 if ((*iter)->Display_Name == Name)
408 return (*iter);
409 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400410 return NULL;
411}
Dees_Troy51a0e822012-09-05 15:24:24 -0400412
Dees_Troy43d8b002012-09-17 16:00:01 -0400413bool TWPartitionManager::Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename)
414{
415 char command[512];
416 string Full_File = Backup_Folder + Backup_Filename;
417
Dees_Troy4a2a1262012-09-18 09:33:47 -0400418 if (!generate_md5)
Dees_Troy43d8b002012-09-17 16:00:01 -0400419 return true;
Dees_Troy43d8b002012-09-17 16:00:01 -0400420
Dees_Troyc51f1f92012-09-20 15:32:13 -0400421 ui_print(" * Generating md5...\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400422
423 if (TWFunc::Path_Exists(Full_File)) {
424 sprintf(command, "cd '%s' && md5sum %s > %s.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), Backup_Filename.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400425 if (system(command) == 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400426 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400427 return true;
428 } else {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400429 ui_print("MD5 Error!\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400430 return false;
431 }
432 } else {
433 char filename[512];
434 int index = 0;
435
436 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400437 while (TWFunc::Path_Exists(filename) == true) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400438 sprintf(command, "cd '%s' && md5sum %s%03i > %s%03i.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), index, Backup_Filename.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400439 if (system(command) != 0) {
440 ui_print("MD5 Error.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400441 return false;
442 }
443 index++;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400444 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy43d8b002012-09-17 16:00:01 -0400445 }
446 if (index == 0) {
447 LOGE("Backup file: '%s' not found!\n", filename);
448 return false;
449 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400450 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400451 }
452 return true;
453}
454
455bool 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) {
456 time_t start, stop;
457
458 if (Part == NULL)
459 return true;
460
461 time(&start);
462
463 if (Part->Backup(Backup_Folder)) {
Dees_Troy8170a922012-09-18 15:40:25 -0400464 if (Part->Has_SubPartition) {
465 std::vector<TWPartition*>::iterator subpart;
466
467 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
468 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
469 if (!(*subpart)->Backup(Backup_Folder))
470 return false;
471 if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
472 return false;
473 }
474 }
475 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400476 time(&stop);
477 if (Part->Backup_Method == 1) {
478 *file_bytes_remaining -= Part->Backup_Size;
479 *file_time += (int) difftime(stop, start);
480 } else {
481 *img_bytes_remaining -= Part->Backup_Size;
482 *img_time += (int) difftime(stop, start);
483 }
484 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
485 } else {
486 return false;
487 }
488}
489
490int TWPartitionManager::Run_Backup(void) {
491 int check, do_md5, partition_count = 0;
492 string Backup_Folder, Backup_Name, Full_Backup_Path;
Dees_Troy8170a922012-09-18 15:40:25 -0400493 unsigned long long total_bytes = 0, file_bytes = 0, img_bytes = 0, free_space = 0, img_bytes_remaining, file_bytes_remaining, subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400494 unsigned long img_time = 0, file_time = 0;
495 TWPartition* backup_sys = NULL;
496 TWPartition* backup_data = NULL;
497 TWPartition* backup_cache = NULL;
498 TWPartition* backup_recovery = NULL;
499 TWPartition* backup_boot = NULL;
500 TWPartition* backup_andsec = NULL;
501 TWPartition* backup_sdext = NULL;
502 TWPartition* backup_sp1 = NULL;
503 TWPartition* backup_sp2 = NULL;
504 TWPartition* backup_sp3 = NULL;
505 TWPartition* storage = NULL;
Dees_Troy8170a922012-09-18 15:40:25 -0400506 std::vector<TWPartition*>::iterator subpart;
Dees_Troy43d8b002012-09-17 16:00:01 -0400507 struct tm *t;
508 time_t start, stop, seconds, total_start, total_stop;
509 seconds = time(0);
510 t = localtime(&seconds);
511
512 time(&total_start);
513
514 Update_System_Details();
515
516 if (!Mount_Current_Storage(true))
517 return false;
518
519 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400520 if (do_md5 == 0)
Dees_Troy43d8b002012-09-17 16:00:01 -0400521 do_md5 = true;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400522
Dees_Troy43d8b002012-09-17 16:00:01 -0400523 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
524 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
525 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
526 char timestamp[255];
527 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);
528 Backup_Name = timestamp;
529 }
530 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
531 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
532 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
533
534 ui_print("\n[BACKUP STARTED]\n");
535 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
536 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
537 LOGE("Failed to make backup folder.\n");
538 return false;
539 }
540
541 LOGI("Calculating backup details...\n");
542 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
543 if (check) {
544 backup_sys = Find_Partition_By_Path("/system");
545 if (backup_sys != NULL) {
546 partition_count++;
547 if (backup_sys->Backup_Method == 1)
548 file_bytes += backup_sys->Backup_Size;
549 else
550 img_bytes += backup_sys->Backup_Size;
551 } else {
552 LOGE("Unable to locate system partition.\n");
553 return false;
554 }
555 }
556 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
557 if (check) {
558 backup_data = Find_Partition_By_Path("/data");
559 if (backup_data != NULL) {
560 partition_count++;
Dees_Troy8170a922012-09-18 15:40:25 -0400561 subpart_size = 0;
562 if (backup_data->Has_SubPartition) {
563 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
564 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_data->Mount_Point)
565 subpart_size += (*subpart)->Backup_Size;
566 }
567 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400568 if (backup_data->Backup_Method == 1)
Dees_Troy8170a922012-09-18 15:40:25 -0400569 file_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400570 else
Dees_Troy8170a922012-09-18 15:40:25 -0400571 img_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400572 } else {
573 LOGE("Unable to locate data partition.\n");
574 return false;
575 }
576 }
577 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
578 if (check) {
579 backup_cache = Find_Partition_By_Path("/cache");
580 if (backup_cache != NULL) {
581 partition_count++;
582 if (backup_cache->Backup_Method == 1)
583 file_bytes += backup_cache->Backup_Size;
584 else
585 img_bytes += backup_cache->Backup_Size;
586 } else {
587 LOGE("Unable to locate cache partition.\n");
588 return false;
589 }
590 }
591 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
592 if (check) {
593 backup_recovery = Find_Partition_By_Path("/recovery");
594 if (backup_recovery != NULL) {
595 partition_count++;
596 if (backup_recovery->Backup_Method == 1)
597 file_bytes += backup_recovery->Backup_Size;
598 else
599 img_bytes += backup_recovery->Backup_Size;
600 } else {
601 LOGE("Unable to locate recovery partition.\n");
602 return false;
603 }
604 }
605 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
606 if (check) {
607 backup_boot = Find_Partition_By_Path("/boot");
608 if (backup_boot != NULL) {
609 partition_count++;
610 if (backup_boot->Backup_Method == 1)
611 file_bytes += backup_boot->Backup_Size;
612 else
613 img_bytes += backup_boot->Backup_Size;
614 } else {
615 LOGE("Unable to locate boot partition.\n");
616 return false;
617 }
618 }
619 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
620 if (check) {
621 backup_andsec = Find_Partition_By_Path("/and-sec");
622 if (backup_andsec != NULL) {
623 partition_count++;
624 if (backup_andsec->Backup_Method == 1)
625 file_bytes += backup_andsec->Backup_Size;
626 else
627 img_bytes += backup_andsec->Backup_Size;
628 } else {
629 LOGE("Unable to locate android secure partition.\n");
630 return false;
631 }
632 }
633 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
634 if (check) {
635 backup_sdext = Find_Partition_By_Path("/sd-ext");
636 if (backup_sdext != NULL) {
637 partition_count++;
638 if (backup_sdext->Backup_Method == 1)
639 file_bytes += backup_sdext->Backup_Size;
640 else
641 img_bytes += backup_sdext->Backup_Size;
642 } else {
643 LOGE("Unable to locate sd-ext partition.\n");
644 return false;
645 }
646 }
647#ifdef SP1_NAME
648 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
649 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400650 backup_sp1 = Find_Partition_By_Path(EXPAND(SP1_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400651 if (backup_sp1 != NULL) {
652 partition_count++;
653 if (backup_sp1->Backup_Method == 1)
654 file_bytes += backup_sp1->Backup_Size;
655 else
656 img_bytes += backup_sp1->Backup_Size;
657 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400658 LOGE("Unable to locate %s partition.\n", EXPAND(SP1_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400659 return false;
660 }
661 }
662#endif
663#ifdef SP2_NAME
664 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
665 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400666 backup_sp2 = Find_Partition_By_Path(EXPAND(SP2_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400667 if (backup_sp2 != NULL) {
668 partition_count++;
669 if (backup_sp2->Backup_Method == 1)
670 file_bytes += backup_sp2->Backup_Size;
671 else
672 img_bytes += backup_sp2->Backup_Size;
673 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400674 LOGE("Unable to locate %s partition.\n", EXPAND(SP2_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400675 return false;
676 }
677 }
678#endif
679#ifdef SP3_NAME
680 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
681 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400682 backup_sp3 = Find_Partition_By_Path(EXPAND(SP3_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400683 if (backup_sp3 != NULL) {
684 partition_count++;
685 if (backup_sp3->Backup_Method == 1)
686 file_bytes += backup_sp3->Backup_Size;
687 else
688 img_bytes += backup_sp3->Backup_Size;
689 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400690 LOGE("Unable to locate %s partition.\n", EXPAND(SP3_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400691 return false;
692 }
693 }
694#endif
695
696 if (partition_count == 0) {
697 ui_print("No partitions selected for backup.\n");
698 return false;
699 }
700 total_bytes = file_bytes + img_bytes;
701 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
702 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
703 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
704 if (storage != NULL) {
705 free_space = storage->Free;
706 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
707 } else {
708 LOGE("Unable to locate storage device.\n");
709 return false;
710 }
711 if (free_space + (32 * 1024 * 1024) < total_bytes) {
712 // We require an extra 32MB just in case
713 LOGE("Not enough free space on storage.\n");
714 return false;
715 }
716 img_bytes_remaining = img_bytes;
717 file_bytes_remaining = file_bytes;
718
719 if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
720 return false;
721 if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
722 return false;
723 if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
724 return false;
725 if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
726 return false;
727 if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
728 return false;
729 if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
730 return false;
731 if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
732 return false;
733 if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
734 return false;
735 if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
736 return false;
737 if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
738 return false;
739
740 // Average BPS
741 if (img_time == 0)
742 img_time = 1;
743 if (file_time == 0)
744 file_time = 1;
745 unsigned long int img_bps = img_bytes / img_time;
746 unsigned long int file_bps = file_bytes / file_time;
747
748 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
749 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
750
751 time(&total_stop);
752 int total_time = (int) difftime(total_stop, total_start);
753 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
754 actual_backup_size /= (1024LLU * 1024LLU);
755
756 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
757 Update_System_Details();
758 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
759 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400760}
761
Dees_Troy4a2a1262012-09-18 09:33:47 -0400762bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name) {
763 time_t Start, Stop;
764 time(&Start);
765 if (!Part->Restore(Restore_Name))
766 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400767 if (Part->Has_SubPartition) {
768 std::vector<TWPartition*>::iterator subpart;
769
770 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
771 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
772 if (!(*subpart)->Restore(Restore_Name))
773 return false;
774 }
775 }
776 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400777 time(&Stop);
778 ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
779 return true;
780}
781
Dees_Troy51a0e822012-09-05 15:24:24 -0400782int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400783 int check_md5, check, partition_count = 0;
784 TWPartition* restore_sys = NULL;
785 TWPartition* restore_data = NULL;
786 TWPartition* restore_cache = NULL;
787 TWPartition* restore_boot = NULL;
788 TWPartition* restore_andsec = NULL;
789 TWPartition* restore_sdext = NULL;
790 TWPartition* restore_sp1 = NULL;
791 TWPartition* restore_sp2 = NULL;
792 TWPartition* restore_sp3 = NULL;
793 time_t rStart, rStop;
794 time(&rStart);
Dees_Troy43d8b002012-09-17 16:00:01 -0400795
Dees_Troy4a2a1262012-09-18 09:33:47 -0400796 ui_print("\n[RESTORE STARTED]\n\n");
797 ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400798
Dees_Troy4a2a1262012-09-18 09:33:47 -0400799 if (!Mount_Current_Storage(true))
800 return false;
801
802 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
803 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
Dees_Troy63c8df72012-09-10 14:02:05 -0400804 if (check > 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400805 restore_sys = Find_Partition_By_Path("/system");
806 if (restore_sys == NULL) {
807 LOGE("Unable to locate system partition.\n");
808 return false;
809 }
810 partition_count++;
811 }
812 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
813 if (check > 0) {
814 restore_data = Find_Partition_By_Path("/data");
815 if (restore_data == NULL) {
816 LOGE("Unable to locate data partition.\n");
817 return false;
818 }
819 partition_count++;
820 }
821 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
822 if (check > 0) {
823 restore_cache = Find_Partition_By_Path("/cache");
824 if (restore_cache == NULL) {
825 LOGE("Unable to locate cache partition.\n");
826 return false;
827 }
828 partition_count++;
829 }
830 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
831 if (check > 0) {
832 restore_boot = Find_Partition_By_Path("/boot");
833 if (restore_boot == NULL) {
834 LOGE("Unable to locate boot partition.\n");
835 return false;
836 }
837 partition_count++;
838 }
839 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
840 if (check > 0) {
841 restore_andsec = Find_Partition_By_Path("/and-sec");
842 if (restore_andsec == NULL) {
843 LOGE("Unable to locate android secure partition.\n");
844 return false;
845 }
846 partition_count++;
847 }
848 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
849 if (check > 0) {
850 restore_sdext = Find_Partition_By_Path("/sd-ext");
851 if (restore_sdext == NULL) {
852 LOGE("Unable to locate sd-ext partition.\n");
853 return false;
854 }
855 partition_count++;
856 }
857#ifdef SP1_NAME
858 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
859 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400860 restore_sp1 = Find_Partition_By_Path(EXPAND(SP1_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400861 if (restore_sp1 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400862 LOGE("Unable to locate %s partition.\n", EXPAND(SP1_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400863 return false;
864 }
865 partition_count++;
866 }
867#endif
868#ifdef SP2_NAME
869 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
870 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400871 restore_sp2 = Find_Partition_By_Path(EXPAND(SP2_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400872 if (restore_sp2 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400873 LOGE("Unable to locate %s partition.\n", EXPAND(SP2_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400874 return false;
875 }
876 partition_count++;
877 }
878#endif
879#ifdef SP3_NAME
880 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
881 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400882 restore_sp3 = Find_Partition_By_Path(EXPAND(SP3_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400883 if (restore_sp3 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400884 LOGE("Unable to locate %s partition.\n", EXPAND(SP3_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400885 return false;
886 }
887 partition_count++;
888 }
889#endif
890
891 if (partition_count == 0) {
892 LOGE("No partitions selected for restore.\n");
893 return false;
894 }
895
896 if (check_md5 > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400897 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
Dees_Troy4a2a1262012-09-18 09:33:47 -0400898 ui_print("Verifying MD5...\n");
899 if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
900 return false;
901 if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
902 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400903 if (restore_data != NULL && restore_data->Has_SubPartition) {
904 std::vector<TWPartition*>::iterator subpart;
905
906 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
907 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_data->Mount_Point) {
908 if (!(*subpart)->Check_MD5(Restore_Name))
909 return false;
910 }
911 }
912 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400913 if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
914 return false;
915 if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
916 return false;
917 if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
918 return false;
919 if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
920 return false;
921 if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
922 return false;
923 if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
924 return false;
925 if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
926 return false;
927 ui_print("Done verifying MD5.\n");
928 } else
929 ui_print("Skipping MD5 check based on user setting.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400930
Dees_Troy4a2a1262012-09-18 09:33:47 -0400931 ui_print("Restoring %i partitions...\n", partition_count);
932 if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name))
933 return false;
934 if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name))
935 return false;
936 if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name))
937 return false;
938 if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name))
939 return false;
940 if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name))
941 return false;
942 if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name))
943 return false;
944 if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name))
945 return false;
946 if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name))
947 return false;
948 if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name))
949 return false;
Dees_Troy43d8b002012-09-17 16:00:01 -0400950
Dees_Troy43d8b002012-09-17 16:00:01 -0400951 Update_System_Details();
Dees_Troy4a2a1262012-09-18 09:33:47 -0400952 time(&rStop);
953 ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
Dees_Troy63c8df72012-09-10 14:02:05 -0400954 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400955}
956
957void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400958 // Start with the default values
959 int tw_restore_system = -1;
960 int tw_restore_data = -1;
961 int tw_restore_cache = -1;
962 int tw_restore_recovery = -1;
963 int tw_restore_boot = -1;
964 int tw_restore_andsec = -1;
965 int tw_restore_sdext = -1;
966 int tw_restore_sp1 = -1;
967 int tw_restore_sp2 = -1;
968 int tw_restore_sp3 = -1;
969 bool get_date = true;
970
971 DIR* d;
972 d = opendir(Restore_Name.c_str());
973 if (d == NULL)
974 {
975 LOGE("Error opening %s\n", Restore_Name.c_str());
976 return;
977 }
978
979 struct dirent* de;
980 while ((de = readdir(d)) != NULL)
981 {
982 // Strip off three components
983 char str[256];
984 char* label;
985 char* fstype = NULL;
986 char* extn = NULL;
987 char* ptr;
988
989 strcpy(str, de->d_name);
990 if (strlen(str) <= 2)
991 continue;
992
993 if (get_date) {
994 char file_path[255];
995 struct stat st;
996
997 strcpy(file_path, Restore_Name.c_str());
998 strcat(file_path, "/");
999 strcat(file_path, str);
1000 stat(file_path, &st);
1001 string backup_date = ctime((const time_t*)(&st.st_mtime));
1002 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
1003 get_date = false;
1004 }
1005
1006 label = str;
1007 ptr = label;
1008 while (*ptr && *ptr != '.') ptr++;
1009 if (*ptr == '.')
1010 {
1011 *ptr = 0x00;
1012 ptr++;
1013 fstype = ptr;
1014 }
1015 while (*ptr && *ptr != '.') ptr++;
1016 if (*ptr == '.')
1017 {
1018 *ptr = 0x00;
1019 ptr++;
1020 extn = ptr;
1021 }
1022
1023 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
1024
1025 TWPartition* Part = Find_Partition_By_Path(label);
1026 if (Part == NULL)
1027 {
1028 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
1029 continue;
1030 }
1031
1032 Part->Backup_FileName = de->d_name;
1033 if (strlen(extn) > 3) {
1034 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
1035 }
1036
1037 // Now, we just need to find the correct label
Dees_Troye58d5262012-09-21 12:27:57 -04001038 if (Part->Backup_Path == "/system")
Dees_Troy63c8df72012-09-10 14:02:05 -04001039 tw_restore_system = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001040 if (Part->Backup_Path == "/data")
Dees_Troy63c8df72012-09-10 14:02:05 -04001041 tw_restore_data = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001042 if (Part->Backup_Path == "/cache")
Dees_Troy63c8df72012-09-10 14:02:05 -04001043 tw_restore_cache = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001044 if (Part->Backup_Path == "/recovery")
Dees_Troy63c8df72012-09-10 14:02:05 -04001045 tw_restore_recovery = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001046 if (Part->Backup_Path == "/boot")
Dees_Troy63c8df72012-09-10 14:02:05 -04001047 tw_restore_boot = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001048 if (Part->Backup_Path == "/and-sec")
Dees_Troy63c8df72012-09-10 14:02:05 -04001049 tw_restore_andsec = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001050 if (Part->Backup_Path == "/sd-ext")
Dees_Troy63c8df72012-09-10 14:02:05 -04001051 tw_restore_sdext = 1;
1052#ifdef SP1_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001053 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP1_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001054 tw_restore_sp1 = 1;
1055#endif
1056#ifdef SP2_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001057 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP2_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001058 tw_restore_sp2 = 1;
1059#endif
1060#ifdef SP3_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001061 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP3_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001062 tw_restore_sp3 = 1;
1063#endif
1064 }
1065 closedir(d);
1066
1067 // Set the final values
1068 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
1069 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
1070 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
1071 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
1072 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
1073 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
1074 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
1075 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
1076 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
1077 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
1078
Dees_Troy51a0e822012-09-05 15:24:24 -04001079 return;
1080}
1081
1082int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001083 std::vector<TWPartition*>::iterator iter;
1084 int ret = false;
1085 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -04001086 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -04001087
1088 // Iterate through all partitions
1089 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -04001090 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troye58d5262012-09-21 12:27:57 -04001091 if (Path == "/and-sec")
1092 ret = (*iter)->Wipe_AndSec();
1093 else
1094 ret = (*iter)->Wipe();
Dees_Troy63c8df72012-09-10 14:02:05 -04001095 found = true;
1096 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
1097 (*iter)->Wipe();
1098 }
1099 }
1100 if (found) {
1101 return ret;
1102 } else
1103 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
1104 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001105}
1106
1107int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001108 TWPartition* Part = Find_Partition_By_Block(Block);
1109
1110 if (Part) {
1111 if (Part->Has_SubPartition) {
1112 std::vector<TWPartition*>::iterator subpart;
1113
1114 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1115 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1116 (*subpart)->Wipe();
1117 }
1118 return Part->Wipe();
1119 } else
1120 return Part->Wipe();
1121 }
1122 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1123 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001124}
1125
1126int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001127 TWPartition* Part = Find_Partition_By_Name(Name);
1128
1129 if (Part) {
1130 if (Part->Has_SubPartition) {
1131 std::vector<TWPartition*>::iterator subpart;
1132
1133 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1134 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1135 (*subpart)->Wipe();
1136 }
1137 return Part->Wipe();
1138 } else
1139 return Part->Wipe();
1140 }
1141 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1142 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001143}
1144
1145int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001146 std::vector<TWPartition*>::iterator iter;
1147 int ret = true;
1148
1149 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001150 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001151 if (!(*iter)->Wipe())
1152 ret = false;
1153 }
1154 }
1155 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001156}
1157
Dees_Troy38bd7602012-09-14 13:33:53 -04001158int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1159 struct stat st;
1160
1161 if (!Mount_By_Path("/data", true))
1162 return false;
1163
1164 if (!Mount_By_Path("/cache", true))
1165 return false;
1166
1167 ui_print("\nWiping Dalvik Cache Directories...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001168 system("rm -rf /data/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001169 ui_print("Cleaned: /data/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001170 system("rm -rf /cache/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001171 ui_print("Cleaned: /cache/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001172 system("rm -rf /cache/dc");
Dees_Troy38bd7602012-09-14 13:33:53 -04001173 ui_print("Cleaned: /cache/dc\n");
1174
1175 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1176 if (sdext != NULL) {
1177 if (sdext->Is_Present && sdext->Mount(false)) {
1178 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001179 system("rm -rf /sd-ext/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001180 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1181 }
1182 }
1183 }
1184 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1185 return true;
1186}
1187
1188int TWPartitionManager::Wipe_Rotate_Data(void) {
1189 if (!Mount_By_Path("/data", true))
1190 return false;
1191
Dees_Troy8170a922012-09-18 15:40:25 -04001192 system("rm -r /data/misc/akmd*");
1193 system("rm -r /data/misc/rild*");
1194 system("rm -r /data/misc/rild*");
Dees_Troy38bd7602012-09-14 13:33:53 -04001195 ui_print("Rotation data wiped.\n");
1196 return true;
1197}
1198
1199int TWPartitionManager::Wipe_Battery_Stats(void) {
1200 struct stat st;
1201
1202 if (!Mount_By_Path("/data", true))
1203 return false;
1204
1205 if (0 != stat("/data/system/batterystats.bin", &st)) {
1206 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1207 } else {
1208 remove("/data/system/batterystats.bin");
1209 ui_print("Cleared battery stats.\n");
1210 }
1211 return true;
1212}
1213
1214int TWPartitionManager::Format_Data(void) {
1215 TWPartition* dat = Find_Partition_By_Path("/data");
1216
1217 if (dat != NULL) {
1218 if (!dat->UnMount(true))
1219 return false;
1220
1221 return dat->Wipe_Encryption();
1222 } else {
1223 LOGE("Unable to locate /data.\n");
1224 return false;
1225 }
1226 return false;
1227}
1228
1229int TWPartitionManager::Wipe_Media_From_Data(void) {
1230 TWPartition* dat = Find_Partition_By_Path("/data");
1231
1232 if (dat != NULL) {
1233 if (!dat->Has_Data_Media) {
1234 LOGE("This device does not have /data/media\n");
1235 return false;
1236 }
1237 if (!dat->Mount(true))
1238 return false;
1239
1240 ui_print("Wiping internal storage -- /data/media...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001241 system("rm -rf /data/media");
1242 system("cd /data && mkdir media && chmod 775 media");
Dees_Troy38bd7602012-09-14 13:33:53 -04001243 if (dat->Has_Data_Media) {
1244 dat->Recreate_Media_Folder();
1245 }
1246 return true;
1247 } else {
1248 LOGE("Unable to locate /data.\n");
1249 return false;
1250 }
1251 return false;
1252}
1253
Dees_Troy51a0e822012-09-05 15:24:24 -04001254void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001255 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001256 return;
1257}
1258
1259void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001260 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001261 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001262
Dees_Troy32c8eb82012-09-11 15:28:06 -04001263 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001264 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001265 if ((*iter)->Can_Be_Mounted) {
1266 (*iter)->Update_Size(true);
1267 if ((*iter)->Mount_Point == "/system") {
1268 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1269 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1270 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1271 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1272 } else if ((*iter)->Mount_Point == "/cache") {
1273 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1274 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1275 } else if ((*iter)->Mount_Point == "/sd-ext") {
1276 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1277 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1278 if ((*iter)->Backup_Size == 0) {
1279 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1280 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1281 } else
1282 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
Dees_Troye58d5262012-09-21 12:27:57 -04001283 } else if ((*iter)->Has_Android_Secure) {
Dees_Troy8170a922012-09-18 15:40:25 -04001284 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
Dees_Troye58d5262012-09-21 12:27:57 -04001285 DataManager::SetValue(TW_BACKUP_ANDSEC_SIZE, backup_display_size);
Dees_Troy8170a922012-09-18 15:40:25 -04001286 if ((*iter)->Backup_Size == 0) {
1287 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 0);
1288 DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
1289 } else
1290 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 1);
Dees_Troy51127312012-09-08 13:08:49 -04001291 }
Dees_Troyab10ee22012-09-21 14:27:30 -04001292#ifdef SP1_NAME
1293 if ((*iter)->Backup_Name == EXPAND(SP1_NAME)) {
1294 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1295 DataManager::SetValue(TW_BACKUP_SP1_SIZE, backup_display_size);
1296 }
1297#endif
1298#ifdef SP2_NAME
1299 if ((*iter)->Backup_Name == EXPAND(SP2_NAME)) {
1300 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1301 DataManager::SetValue(TW_BACKUP_SP2_SIZE, backup_display_size);
1302 }
1303#endif
1304#ifdef SP3_NAME
1305 if ((*iter)->Backup_Name == EXPAND(SP3_NAME)) {
1306 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1307 DataManager::SetValue(TW_BACKUP_SP3_SIZE, backup_display_size);
1308 }
1309#endif
Dees_Troy51127312012-09-08 13:08:49 -04001310 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001311 }
Dees_Troy51127312012-09-08 13:08:49 -04001312 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1313 string current_storage_path = DataManager::GetCurrentStoragePath();
1314 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
Dees_Troy8170a922012-09-18 15:40:25 -04001315 if (FreeStorage != NULL) {
1316 // Attempt to mount storage
1317 if (!FreeStorage->Mount(false)) {
1318 // We couldn't mount storage... check to see if we have dual storage
1319 int has_dual_storage;
1320 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual_storage);
1321 if (has_dual_storage == 1) {
1322 // We have dual storage, see if we're using the internal storage that should always be present
1323 if (current_storage_path == DataManager::GetSettingsStoragePath()) {
Dees_Troyab10ee22012-09-21 14:27:30 -04001324 if (!FreeStorage->Is_Encrypted) {
1325 // Not able to use internal, so error!
1326 LOGE("Unable to mount internal storage.\n");
1327 }
Dees_Troy8170a922012-09-18 15:40:25 -04001328 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1329 } else {
1330 // We were using external, flip to internal
1331 DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
1332 current_storage_path = DataManager::GetCurrentStoragePath();
1333 FreeStorage = Find_Partition_By_Path(current_storage_path);
1334 if (FreeStorage != NULL) {
1335 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1336 } else {
1337 LOGE("Unable to locate internal storage partition.\n");
1338 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1339 }
1340 }
1341 } else {
1342 // No dual storage and unable to mount storage, error!
1343 LOGE("Unable to mount storage.\n");
1344 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1345 }
1346 } else {
1347 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1348 }
1349 } else {
Dees_Troy51127312012-09-08 13:08:49 -04001350 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -04001351 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001352 if (!Write_Fstab())
1353 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001354 return;
1355}
1356
1357int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001358#ifdef TW_INCLUDE_CRYPTO
1359 int ret_val, password_len;
1360 char crypto_blkdev[255], cPassword[255];
1361 size_t result;
1362
1363 property_set("ro.crypto.state", "encrypted");
1364#ifdef TW_INCLUDE_JB_CRYPTO
1365 // No extra flags needed
1366#else
1367 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1368 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1369 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1370 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1371 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1372 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1373#endif
1374 strcpy(cPassword, Password.c_str());
1375 if (cryptfs_check_passwd(cPassword) != 0) {
1376 LOGE("Failed to decrypt data.\n");
1377 return -1;
1378 }
1379 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1380 if (strcmp(crypto_blkdev, "error") == 0) {
1381 LOGE("Error retrieving decrypted data block device.\n");
1382 } else {
1383 TWPartition* dat = Find_Partition_By_Path("/data");
1384 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001385 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001386 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1387 dat->Is_Decrypted = true;
1388 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001389 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001390 // Sleep for a bit so that the device will be ready
1391 sleep(1);
1392 Update_System_Details();
1393 } else
1394 LOGE("Unable to locate data partition.\n");
1395 }
1396 return 0;
1397#else
1398 LOGE("No crypto support was compiled into this build.\n");
1399 return -1;
1400#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001401 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001402}
1403
Dees_Troy38bd7602012-09-14 13:33:53 -04001404int TWPartitionManager::Fix_Permissions(void) {
1405 if (!Mount_By_Path("/data", true))
1406 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001407
Dees_Troy38bd7602012-09-14 13:33:53 -04001408 if (!Mount_By_Path("/system", true))
1409 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001410
Dees_Troy38bd7602012-09-14 13:33:53 -04001411 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001412 system("./sbin/fix_permissions.sh");
Dees_Troy38bd7602012-09-14 13:33:53 -04001413 ui_print("Done.\n\n");
1414 return true;
Dees_Troy4a2a1262012-09-18 09:33:47 -04001415}
Dees_Troy8170a922012-09-18 15:40:25 -04001416
1417//partial kangbang from system/vold
1418#ifndef CUSTOM_LUN_FILE
1419#define CUSTOM_LUN_FILE "/sys/devices/platform/usb_mass_storage/lun%d/file"
1420#endif
1421
1422int TWPartitionManager::usb_storage_enable(void) {
1423 int fd, has_dual, has_data_media;
1424 char lun_file[255];
1425 TWPartition* Part;
1426 string ext_path;
1427
1428 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual);
1429 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
1430 if (has_dual == 1 && has_data_media == 0) {
1431 Part = Find_Partition_By_Path(DataManager::GetSettingsStoragePath());
1432 if (Part == NULL) {
1433 LOGE("Unable to locate volume information.");
1434 return false;
1435 }
1436 if (!Part->UnMount(true))
1437 return false;
1438
1439 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1440 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1441 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1442 return false;
1443 }
1444
1445 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1446 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1447 close(fd);
1448 return false;
1449 }
1450 close(fd);
1451
1452 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1453 Part = Find_Partition_By_Path(ext_path);
1454 if (Part == NULL) {
1455 LOGE("Unable to locate volume information.\n");
1456 return false;
1457 }
1458 if (!Part->UnMount(true))
1459 return false;
1460
1461 sprintf(lun_file, CUSTOM_LUN_FILE, 1);
1462 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1463 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1464 return false;
1465 }
1466
1467 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1468 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1469 close(fd);
1470 return false;
1471 }
1472 close(fd);
1473 } else {
1474 if (has_data_media == 0)
1475 ext_path = DataManager::GetCurrentStoragePath();
1476 else
1477 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1478
1479 Part = Find_Partition_By_Path(ext_path);
1480 if (Part == NULL) {
1481 LOGE("Unable to locate volume information.\n");
1482 return false;
1483 }
1484 if (!Part->UnMount(true))
1485 return false;
1486
1487 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1488
1489 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1490 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1491 return false;
1492 }
1493
1494 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1495 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1496 close(fd);
1497 return false;
1498 }
1499 close(fd);
1500 }
1501 return true;
1502}
1503
1504int TWPartitionManager::usb_storage_disable(void) {
1505 int fd, index;
1506 char lun_file[255];
1507
1508 for (index=0; index<2; index++) {
1509 sprintf(lun_file, CUSTOM_LUN_FILE, index);
1510
1511 if ((fd = open(lun_file, O_WRONLY)) < 0) {
Dees_Troye58d5262012-09-21 12:27:57 -04001512 Mount_All_Storage();
1513 Update_System_Details();
1514 if (index == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001515 LOGE("Unable to open ums lunfile '%s': (%s)", lun_file, strerror(errno));
Dees_Troye58d5262012-09-21 12:27:57 -04001516 return false;
1517 } else
1518 return true;
Dees_Troy8170a922012-09-18 15:40:25 -04001519 }
1520
1521 char ch = 0;
1522 if (write(fd, &ch, 1) < 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001523 close(fd);
Dees_Troye58d5262012-09-21 12:27:57 -04001524 Mount_All_Storage();
1525 Update_System_Details();
1526 if (index == 0) {
1527 LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
1528 return false;
1529 } else
1530 return true;
Dees_Troy8170a922012-09-18 15:40:25 -04001531 }
1532
1533 close(fd);
1534 }
Dees_Troye58d5262012-09-21 12:27:57 -04001535 Mount_All_Storage();
1536 Update_System_Details();
Dees_Troy8170a922012-09-18 15:40:25 -04001537 return true;
Dees_Troy812660f2012-09-20 09:55:17 -04001538}
1539
1540void TWPartitionManager::Mount_All_Storage(void) {
1541 std::vector<TWPartition*>::iterator iter;
1542
1543 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
1544 if ((*iter)->Is_Storage)
1545 (*iter)->Mount(false);
1546 }
Dees_Troy8170a922012-09-18 15:40:25 -04001547}