blob: df67bb52c1c2f60c66235c017de89e7e6b138ddb [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"
Dees_Troy093b7642012-09-21 15:59:38 -040037#include "ui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040038#include "partitions.hpp"
Dees_Troy5bf43922012-09-07 16:07:55 -040039#include "data.hpp"
Dees_Troy38bd7602012-09-14 13:33:53 -040040#include "twrp-functions.hpp"
41
Dees_Troy5bf43922012-09-07 16:07:55 -040042#ifdef TW_INCLUDE_CRYPTO
43 #ifdef TW_INCLUDE_JB_CRYPTO
44 #include "crypto/jb/cryptfs.h"
45 #else
46 #include "crypto/ics/cryptfs.h"
47 #endif
48 #include "cutils/properties.h"
49#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040050
Dees_Troy093b7642012-09-21 15:59:38 -040051extern RecoveryUI* ui;
52
Dees_Troy51a0e822012-09-05 15:24:24 -040053int 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
Dees_Troy2a923582012-09-20 12:13:34 -040067 if (fstab_line[strlen(fstab_line) - 1] != '\n')
68 fstab_line[strlen(fstab_line)] = '\n';
69
Dees_Troy5bf43922012-09-07 16:07:55 -040070 TWPartition* partition = new TWPartition();
Dees_Troy2a923582012-09-20 12:13:34 -040071 string line = fstab_line;
Dees_Troyab10ee22012-09-21 14:27:30 -040072 memset(fstab_line, 0, sizeof(fstab_line));
Dees_Troy2a923582012-09-20 12:13:34 -040073
Dees_Troy5bf43922012-09-07 16:07:55 -040074 if (partition->Process_Fstab_Line(line, Display_Error)) {
75 Partitions.push_back(partition);
76 } else {
77 delete partition;
78 }
79 }
80 fclose(fstabFile);
81 if (!Write_Fstab()) {
82 if (Display_Error)
83 LOGE("Error creating fstab\n");
84 else
85 LOGI("Error creating fstab\n");
86 }
Dees_Troy51127312012-09-08 13:08:49 -040087 Update_System_Details();
Dees_Troy5bf43922012-09-07 16:07:55 -040088 return true;
89}
90
91int TWPartitionManager::Write_Fstab(void) {
92 FILE *fp;
93 std::vector<TWPartition*>::iterator iter;
94 string Line;
95
96 fp = fopen("/etc/fstab", "w");
97 if (fp == NULL) {
Dees_Troy63c8df72012-09-10 14:02:05 -040098 LOGI("Can not open /etc/fstab.\n");
Dees_Troy5bf43922012-09-07 16:07:55 -040099 return false;
100 }
Dees_Troy63c8df72012-09-10 14:02:05 -0400101 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -0400102 if ((*iter)->Can_Be_Mounted) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400103 Line = (*iter)->Actual_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
Dees_Troy5bf43922012-09-07 16:07:55 -0400104 fputs(Line.c_str(), fp);
Dees_Troy51127312012-09-08 13:08:49 -0400105 // Handle subpartition tracking
106 if ((*iter)->Is_SubPartition) {
107 TWPartition* ParentPartition = Find_Partition_By_Path((*iter)->SubPartition_Of);
108 if (ParentPartition)
109 ParentPartition->Has_SubPartition = true;
110 else
111 LOGE("Unable to locate parent partition '%s' of '%s'\n", (*iter)->SubPartition_Of.c_str(), (*iter)->Mount_Point.c_str());
112 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400113 }
114 }
115 fclose(fp);
116 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400117}
118
Dees_Troy8170a922012-09-18 15:40:25 -0400119void TWPartitionManager::Output_Partition_Logging(void) {
120 std::vector<TWPartition*>::iterator iter;
121
122 printf("\n\nPartition Logs:\n");
123 for (iter = Partitions.begin(); iter != Partitions.end(); iter++)
124 Output_Partition((*iter));
125}
126
127void TWPartitionManager::Output_Partition(TWPartition* Part) {
128 unsigned long long mb = 1048576;
129
130 if (Part->Can_Be_Mounted) {
131 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));
132 if (Part->Can_Be_Wiped)
133 printf("Can_Be_Wiped ");
134 if (Part->Wipe_During_Factory_Reset)
135 printf("Wipe_During_Factory_Reset ");
136 if (Part->Wipe_Available_in_GUI)
137 printf("Wipe_Available_in_GUI ");
138 if (Part->Is_SubPartition)
139 printf("Is_SubPartition ");
140 if (Part->Has_SubPartition)
141 printf("Has_SubPartition ");
142 if (Part->Removable)
143 printf("Removable ");
144 if (Part->Is_Present)
145 printf("IsPresent ");
146 if (Part->Can_Be_Encrypted)
147 printf("Can_Be_Encrypted ");
148 if (Part->Is_Encrypted)
149 printf("Is_Encrypted ");
150 if (Part->Is_Decrypted)
151 printf("Is_Decrypted ");
152 if (Part->Has_Data_Media)
153 printf("Has_Data_Media ");
Dees_Troye58d5262012-09-21 12:27:57 -0400154 if (Part->Has_Android_Secure)
155 printf("Has_Android_Secure ");
Dees_Troy8170a922012-09-18 15:40:25 -0400156 if (Part->Is_Storage)
157 printf("Is_Storage ");
158 printf("\n");
159 if (!Part->SubPartition_Of.empty())
160 printf(" SubPartition_Of: %s\n", Part->SubPartition_Of.c_str());
161 if (!Part->Symlink_Path.empty())
162 printf(" Symlink_Path: %s\n", Part->Symlink_Path.c_str());
163 if (!Part->Symlink_Mount_Point.empty())
164 printf(" Symlink_Mount_Point: %s\n", Part->Symlink_Mount_Point.c_str());
165 if (!Part->Primary_Block_Device.empty())
166 printf(" Primary_Block_Device: %s\n", Part->Primary_Block_Device.c_str());
167 if (!Part->Alternate_Block_Device.empty())
168 printf(" Alternate_Block_Device: %s\n", Part->Alternate_Block_Device.c_str());
169 if (!Part->Decrypted_Block_Device.empty())
170 printf(" Decrypted_Block_Device: %s\n", Part->Decrypted_Block_Device.c_str());
171 if (Part->Length != 0)
172 printf(" Length: %i\n", Part->Length);
173 if (!Part->Display_Name.empty())
174 printf(" Display_Name: %s\n", Part->Display_Name.c_str());
Dees_Troye58d5262012-09-21 12:27:57 -0400175 if (!Part->Backup_Path.empty())
176 printf(" Backup_Path: %s\n", Part->Backup_Path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -0400177 if (!Part->Backup_Name.empty())
178 printf(" Backup_Name: %s\n", Part->Backup_Name.c_str());
179 if (!Part->Backup_FileName.empty())
180 printf(" Backup_FileName: %s\n", Part->Backup_FileName.c_str());
181 if (!Part->MTD_Name.empty())
182 printf(" MTD_Name: %s\n", Part->MTD_Name.c_str());
183 if (!Part->Storage_Path.empty())
184 printf(" Storage_Path: %s\n", Part->Storage_Path.c_str());
185 if (!Part->Current_File_System.empty())
186 printf(" Current_File_System: %s\n", Part->Current_File_System.c_str());
187 if (!Part->Fstab_File_System.empty())
188 printf(" Fstab_File_System: %s\n", Part->Fstab_File_System.c_str());
189 if (Part->Format_Block_Size != 0)
190 printf(" Format_Block_Size: %i\n", Part->Format_Block_Size);
191 } else {
192 printf("%s | %s | Size: %iMB\n", Part->Mount_Point.c_str(), Part->Actual_Block_Device.c_str(), (int)(Part->Size / mb));
193 }
194 string back_meth = Part->Backup_Method_By_Name();
195 printf(" Backup_Method: %s\n\n", back_meth.c_str());
196}
197
Dees_Troy51a0e822012-09-05 15:24:24 -0400198int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400199 std::vector<TWPartition*>::iterator iter;
200 int ret = false;
201 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400202 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400203
Dees_Troy43d8b002012-09-17 16:00:01 -0400204 if (Local_Path == "/tmp")
205 return true;
206
Dees_Troy5bf43922012-09-07 16:07:55 -0400207 // Iterate through all partitions
208 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400209 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400210 ret = (*iter)->Mount(Display_Error);
211 found = true;
Dees_Troy51127312012-09-08 13:08:49 -0400212 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400213 (*iter)->Mount(Display_Error);
Dees_Troy51127312012-09-08 13:08:49 -0400214 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400215 }
216 if (found) {
217 return ret;
218 } else if (Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400219 LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400220 } else {
Dees_Troy51127312012-09-08 13:08:49 -0400221 LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400222 }
223 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400224}
225
226int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400227 TWPartition* Part = Find_Partition_By_Block(Block);
Dees_Troy5bf43922012-09-07 16:07:55 -0400228
Dees_Troy51127312012-09-08 13:08:49 -0400229 if (Part) {
230 if (Part->Has_SubPartition) {
231 std::vector<TWPartition*>::iterator subpart;
232
233 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
234 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
235 (*subpart)->Mount(Display_Error);
236 }
237 return Part->Mount(Display_Error);
238 } else
239 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400240 }
241 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400242 LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400243 else
Dees_Troy51127312012-09-08 13:08:49 -0400244 LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400245 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400246}
247
248int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400249 TWPartition* Part = Find_Partition_By_Name(Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400250
Dees_Troy51127312012-09-08 13:08:49 -0400251 if (Part) {
252 if (Part->Has_SubPartition) {
253 std::vector<TWPartition*>::iterator subpart;
254
255 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
256 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
257 (*subpart)->Mount(Display_Error);
258 }
259 return Part->Mount(Display_Error);
260 } else
261 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400262 }
263 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400264 LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400265 else
Dees_Troy51127312012-09-08 13:08:49 -0400266 LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400267 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400268}
269
270int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400271 std::vector<TWPartition*>::iterator iter;
272 int ret = false;
273 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400274 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy51127312012-09-08 13:08:49 -0400275
276 // Iterate through all partitions
277 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400278 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy51127312012-09-08 13:08:49 -0400279 ret = (*iter)->UnMount(Display_Error);
280 found = true;
281 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
282 (*iter)->UnMount(Display_Error);
283 }
284 }
285 if (found) {
286 return ret;
287 } else if (Display_Error) {
288 LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
289 } else {
290 LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
291 }
292 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400293}
294
295int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400296 TWPartition* Part = Find_Partition_By_Block(Block);
297
298 if (Part) {
299 if (Part->Has_SubPartition) {
300 std::vector<TWPartition*>::iterator subpart;
301
302 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
303 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
304 (*subpart)->UnMount(Display_Error);
305 }
306 return Part->UnMount(Display_Error);
307 } else
308 return Part->UnMount(Display_Error);
309 }
310 if (Display_Error)
311 LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
312 else
313 LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
314 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400315}
316
317int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400318 TWPartition* Part = Find_Partition_By_Name(Name);
319
320 if (Part) {
321 if (Part->Has_SubPartition) {
322 std::vector<TWPartition*>::iterator subpart;
323
324 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
325 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
326 (*subpart)->UnMount(Display_Error);
327 }
328 return Part->UnMount(Display_Error);
329 } else
330 return Part->UnMount(Display_Error);
331 }
332 if (Display_Error)
333 LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
334 else
335 LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
336 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400337}
338
339int TWPartitionManager::Is_Mounted_By_Path(string Path) {
Dees_Troy51127312012-09-08 13:08:49 -0400340 TWPartition* Part = Find_Partition_By_Path(Path);
341
342 if (Part)
343 return Part->Is_Mounted();
344 else
345 LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
346 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400347}
348
349int TWPartitionManager::Is_Mounted_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400350 TWPartition* Part = Find_Partition_By_Block(Block);
351
352 if (Part)
353 return Part->Is_Mounted();
354 else
355 LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
356 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400357}
358
359int TWPartitionManager::Is_Mounted_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400360 TWPartition* Part = Find_Partition_By_Name(Name);
361
362 if (Part)
363 return Part->Is_Mounted();
364 else
365 LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
366 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400367}
368
Dees_Troy5bf43922012-09-07 16:07:55 -0400369int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400370 string current_storage_path = DataManager::GetCurrentStoragePath();
371
372 if (Mount_By_Path(current_storage_path, Display_Error)) {
373 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
374 if (FreeStorage)
375 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
376 return true;
377 }
378 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400379}
380
Dees_Troy5bf43922012-09-07 16:07:55 -0400381int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
382 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
383}
384
385TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
386 std::vector<TWPartition*>::iterator iter;
Dees_Troy38bd7602012-09-14 13:33:53 -0400387 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400388
389 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400390 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
Dees_Troy5bf43922012-09-07 16:07:55 -0400391 return (*iter);
392 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400393 return NULL;
394}
395
Dees_Troy5bf43922012-09-07 16:07:55 -0400396TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400397 std::vector<TWPartition*>::iterator iter;
398
399 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400400 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 -0400401 return (*iter);
402 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400403 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400404}
405
406TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400407 std::vector<TWPartition*>::iterator iter;
408
409 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
410 if ((*iter)->Display_Name == Name)
411 return (*iter);
412 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400413 return NULL;
414}
Dees_Troy51a0e822012-09-05 15:24:24 -0400415
Dees_Troy43d8b002012-09-17 16:00:01 -0400416bool TWPartitionManager::Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename)
417{
418 char command[512];
419 string Full_File = Backup_Folder + Backup_Filename;
420
Dees_Troy4a2a1262012-09-18 09:33:47 -0400421 if (!generate_md5)
Dees_Troy43d8b002012-09-17 16:00:01 -0400422 return true;
Dees_Troy43d8b002012-09-17 16:00:01 -0400423
Dees_Troyb46a6842012-09-25 11:06:46 -0400424 TWFunc::GUI_Operation_Text(TW_GENERATE_MD5_TEXT, "Generating MD5");
Dees_Troyc51f1f92012-09-20 15:32:13 -0400425 ui_print(" * Generating md5...\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400426
427 if (TWFunc::Path_Exists(Full_File)) {
428 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 -0400429 if (system(command) == 0) {
Dees_Troyc5865ab2012-09-24 15:08:04 -0400430 ui_print(" * MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400431 return true;
432 } else {
Dees_Troyc5865ab2012-09-24 15:08:04 -0400433 ui_print(" * MD5 Error!\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400434 return false;
435 }
436 } else {
437 char filename[512];
438 int index = 0;
439
440 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400441 while (TWFunc::Path_Exists(filename) == true) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400442 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 -0400443 if (system(command) != 0) {
Dees_Troyc5865ab2012-09-24 15:08:04 -0400444 ui_print(" * MD5 Error.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400445 return false;
446 }
447 index++;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400448 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy43d8b002012-09-17 16:00:01 -0400449 }
450 if (index == 0) {
451 LOGE("Backup file: '%s' not found!\n", filename);
452 return false;
453 }
Dees_Troyc5865ab2012-09-24 15:08:04 -0400454 ui_print(" * MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400455 }
456 return true;
457}
458
Dees_Troy093b7642012-09-21 15:59:38 -0400459bool 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, unsigned long long *img_bytes, unsigned long long *file_bytes) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400460 time_t start, stop;
Dees_Troy093b7642012-09-21 15:59:38 -0400461 int img_bps, file_bps;
462 unsigned long total_time, remain_time, section_time;
463 int use_compression, backup_time;
464 float pos;
Dees_Troy43d8b002012-09-17 16:00:01 -0400465
466 if (Part == NULL)
467 return true;
468
Dees_Troy093b7642012-09-21 15:59:38 -0400469 DataManager::GetValue(TW_BACKUP_AVG_IMG_RATE, img_bps);
470
471 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
472 if (use_compression)
473 DataManager::GetValue(TW_BACKUP_AVG_FILE_COMP_RATE, file_bps);
474 else
475 DataManager::GetValue(TW_BACKUP_AVG_FILE_RATE, file_bps);
476
477 // We know the speed for both, how far into the whole backup are we, based on time
478 total_time = (*img_bytes / (unsigned long)img_bps) + (*file_bytes / (unsigned long)file_bps);
479 remain_time = (*img_bytes_remaining / (unsigned long)img_bps) + (*file_bytes_remaining / (unsigned long)file_bps);
480
481 pos = (total_time - remain_time) / (float) total_time;
482 ui->SetProgress(pos);
483
484 LOGI("Estimated Total time: %lu Estimated remaining time: %lu\n", total_time, remain_time);
485
486 // And get the time
487 if (Part->Backup_Method == 1)
488 section_time = Part->Backup_Size / file_bps;
489 else
490 section_time = Part->Backup_Size / img_bps;
491
492 // Set the position
493 pos = section_time / (float) total_time;
494 ui->ShowProgress(pos, section_time);
495
Dees_Troy43d8b002012-09-17 16:00:01 -0400496 time(&start);
497
498 if (Part->Backup(Backup_Folder)) {
Dees_Troy8170a922012-09-18 15:40:25 -0400499 if (Part->Has_SubPartition) {
500 std::vector<TWPartition*>::iterator subpart;
501
502 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
503 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
504 if (!(*subpart)->Backup(Backup_Folder))
505 return false;
506 if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
507 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400508 if (Part->Backup_Method == 1) {
509 *file_bytes_remaining -= (*subpart)->Backup_Size;
510 } else {
511 *img_bytes_remaining -= (*subpart)->Backup_Size;
512 }
Dees_Troy8170a922012-09-18 15:40:25 -0400513 }
514 }
515 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400516 time(&stop);
Dees_Troy093b7642012-09-21 15:59:38 -0400517 backup_time = (int) difftime(stop, start);
518 LOGI("Partition Backup time: %d\n", backup_time);
Dees_Troy43d8b002012-09-17 16:00:01 -0400519 if (Part->Backup_Method == 1) {
520 *file_bytes_remaining -= Part->Backup_Size;
Dees_Troy093b7642012-09-21 15:59:38 -0400521 *file_time += backup_time;
Dees_Troy43d8b002012-09-17 16:00:01 -0400522 } else {
523 *img_bytes_remaining -= Part->Backup_Size;
Dees_Troy093b7642012-09-21 15:59:38 -0400524 *img_time += backup_time;
Dees_Troy43d8b002012-09-17 16:00:01 -0400525 }
526 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
527 } else {
528 return false;
529 }
530}
531
532int TWPartitionManager::Run_Backup(void) {
533 int check, do_md5, partition_count = 0;
534 string Backup_Folder, Backup_Name, Full_Backup_Path;
Dees_Troy8170a922012-09-18 15:40:25 -0400535 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 -0400536 unsigned long img_time = 0, file_time = 0;
537 TWPartition* backup_sys = NULL;
538 TWPartition* backup_data = NULL;
539 TWPartition* backup_cache = NULL;
540 TWPartition* backup_recovery = NULL;
541 TWPartition* backup_boot = NULL;
542 TWPartition* backup_andsec = NULL;
543 TWPartition* backup_sdext = NULL;
544 TWPartition* backup_sp1 = NULL;
545 TWPartition* backup_sp2 = NULL;
546 TWPartition* backup_sp3 = NULL;
547 TWPartition* storage = NULL;
Dees_Troy8170a922012-09-18 15:40:25 -0400548 std::vector<TWPartition*>::iterator subpart;
Dees_Troy43d8b002012-09-17 16:00:01 -0400549 struct tm *t;
550 time_t start, stop, seconds, total_start, total_stop;
551 seconds = time(0);
552 t = localtime(&seconds);
553
554 time(&total_start);
555
556 Update_System_Details();
557
558 if (!Mount_Current_Storage(true))
559 return false;
560
561 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400562 if (do_md5 == 0)
Dees_Troy43d8b002012-09-17 16:00:01 -0400563 do_md5 = true;
Dees_Troyc5865ab2012-09-24 15:08:04 -0400564 else
565 do_md5 = false;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400566
Dees_Troy43d8b002012-09-17 16:00:01 -0400567 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
568 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
569 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
570 char timestamp[255];
571 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);
572 Backup_Name = timestamp;
573 }
574 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
575 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
576 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
577
578 ui_print("\n[BACKUP STARTED]\n");
579 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
580 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
581 LOGE("Failed to make backup folder.\n");
582 return false;
583 }
584
585 LOGI("Calculating backup details...\n");
586 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
587 if (check) {
588 backup_sys = Find_Partition_By_Path("/system");
589 if (backup_sys != NULL) {
590 partition_count++;
591 if (backup_sys->Backup_Method == 1)
592 file_bytes += backup_sys->Backup_Size;
593 else
594 img_bytes += backup_sys->Backup_Size;
595 } else {
596 LOGE("Unable to locate system partition.\n");
597 return false;
598 }
599 }
600 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
601 if (check) {
602 backup_data = Find_Partition_By_Path("/data");
603 if (backup_data != NULL) {
604 partition_count++;
Dees_Troy8170a922012-09-18 15:40:25 -0400605 subpart_size = 0;
606 if (backup_data->Has_SubPartition) {
607 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
608 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_data->Mount_Point)
609 subpart_size += (*subpart)->Backup_Size;
610 }
611 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400612 if (backup_data->Backup_Method == 1)
Dees_Troy8170a922012-09-18 15:40:25 -0400613 file_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400614 else
Dees_Troy8170a922012-09-18 15:40:25 -0400615 img_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400616 } else {
617 LOGE("Unable to locate data partition.\n");
618 return false;
619 }
620 }
621 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
622 if (check) {
623 backup_cache = Find_Partition_By_Path("/cache");
624 if (backup_cache != NULL) {
625 partition_count++;
626 if (backup_cache->Backup_Method == 1)
627 file_bytes += backup_cache->Backup_Size;
628 else
629 img_bytes += backup_cache->Backup_Size;
630 } else {
631 LOGE("Unable to locate cache partition.\n");
632 return false;
633 }
634 }
635 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
636 if (check) {
637 backup_recovery = Find_Partition_By_Path("/recovery");
638 if (backup_recovery != NULL) {
639 partition_count++;
640 if (backup_recovery->Backup_Method == 1)
641 file_bytes += backup_recovery->Backup_Size;
642 else
643 img_bytes += backup_recovery->Backup_Size;
644 } else {
645 LOGE("Unable to locate recovery partition.\n");
646 return false;
647 }
648 }
649 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
650 if (check) {
651 backup_boot = Find_Partition_By_Path("/boot");
652 if (backup_boot != NULL) {
653 partition_count++;
654 if (backup_boot->Backup_Method == 1)
655 file_bytes += backup_boot->Backup_Size;
656 else
657 img_bytes += backup_boot->Backup_Size;
658 } else {
659 LOGE("Unable to locate boot partition.\n");
660 return false;
661 }
662 }
663 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
664 if (check) {
665 backup_andsec = Find_Partition_By_Path("/and-sec");
666 if (backup_andsec != NULL) {
667 partition_count++;
668 if (backup_andsec->Backup_Method == 1)
669 file_bytes += backup_andsec->Backup_Size;
670 else
671 img_bytes += backup_andsec->Backup_Size;
672 } else {
673 LOGE("Unable to locate android secure partition.\n");
674 return false;
675 }
676 }
677 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
678 if (check) {
679 backup_sdext = Find_Partition_By_Path("/sd-ext");
680 if (backup_sdext != NULL) {
681 partition_count++;
682 if (backup_sdext->Backup_Method == 1)
683 file_bytes += backup_sdext->Backup_Size;
684 else
685 img_bytes += backup_sdext->Backup_Size;
686 } else {
687 LOGE("Unable to locate sd-ext partition.\n");
688 return false;
689 }
690 }
691#ifdef SP1_NAME
692 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
693 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400694 backup_sp1 = Find_Partition_By_Path(EXPAND(SP1_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400695 if (backup_sp1 != NULL) {
696 partition_count++;
697 if (backup_sp1->Backup_Method == 1)
698 file_bytes += backup_sp1->Backup_Size;
699 else
700 img_bytes += backup_sp1->Backup_Size;
701 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400702 LOGE("Unable to locate %s partition.\n", EXPAND(SP1_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400703 return false;
704 }
705 }
706#endif
707#ifdef SP2_NAME
708 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
709 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400710 backup_sp2 = Find_Partition_By_Path(EXPAND(SP2_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400711 if (backup_sp2 != NULL) {
712 partition_count++;
713 if (backup_sp2->Backup_Method == 1)
714 file_bytes += backup_sp2->Backup_Size;
715 else
716 img_bytes += backup_sp2->Backup_Size;
717 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400718 LOGE("Unable to locate %s partition.\n", EXPAND(SP2_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400719 return false;
720 }
721 }
722#endif
723#ifdef SP3_NAME
724 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
725 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400726 backup_sp3 = Find_Partition_By_Path(EXPAND(SP3_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400727 if (backup_sp3 != NULL) {
728 partition_count++;
729 if (backup_sp3->Backup_Method == 1)
730 file_bytes += backup_sp3->Backup_Size;
731 else
732 img_bytes += backup_sp3->Backup_Size;
733 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400734 LOGE("Unable to locate %s partition.\n", EXPAND(SP3_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400735 return false;
736 }
737 }
738#endif
739
740 if (partition_count == 0) {
741 ui_print("No partitions selected for backup.\n");
742 return false;
743 }
744 total_bytes = file_bytes + img_bytes;
745 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
746 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
747 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
748 if (storage != NULL) {
749 free_space = storage->Free;
750 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
751 } else {
752 LOGE("Unable to locate storage device.\n");
753 return false;
754 }
755 if (free_space + (32 * 1024 * 1024) < total_bytes) {
756 // We require an extra 32MB just in case
757 LOGE("Not enough free space on storage.\n");
758 return false;
759 }
760 img_bytes_remaining = img_bytes;
761 file_bytes_remaining = file_bytes;
762
Dees_Troy093b7642012-09-21 15:59:38 -0400763 ui->SetProgress(0.0);
764
765 if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400766 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400767 if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400768 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400769 if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400770 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400771 if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400772 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400773 if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400774 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400775 if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400776 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400777 if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400778 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400779 if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400780 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400781 if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400782 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400783 if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time, &img_bytes, &file_bytes))
Dees_Troy43d8b002012-09-17 16:00:01 -0400784 return false;
785
786 // Average BPS
787 if (img_time == 0)
788 img_time = 1;
789 if (file_time == 0)
790 file_time = 1;
Dees_Troy093b7642012-09-21 15:59:38 -0400791 int img_bps = (int)img_bytes / (int)img_time;
792 int file_bps = (int)file_bytes / (int)file_time;
Dees_Troy43d8b002012-09-17 16:00:01 -0400793
794 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
795 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
796
797 time(&total_stop);
798 int total_time = (int) difftime(total_stop, total_start);
799 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
800 actual_backup_size /= (1024LLU * 1024LLU);
801
Dees_Troy093b7642012-09-21 15:59:38 -0400802 int prev_img_bps, prev_file_bps, use_compression;
803 DataManager::GetValue(TW_BACKUP_AVG_IMG_RATE, prev_img_bps);
804 img_bps += (prev_img_bps * 4);
805 img_bps /= 5;
806
807 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
808 if (use_compression)
809 DataManager::GetValue(TW_BACKUP_AVG_FILE_COMP_RATE, prev_file_bps);
810 else
811 DataManager::GetValue(TW_BACKUP_AVG_FILE_RATE, prev_file_bps);
812 file_bps += (prev_file_bps * 4);
813 file_bps /= 5;
814
815 DataManager::SetValue(TW_BACKUP_AVG_IMG_RATE, img_bps);
816 if (use_compression)
817 DataManager::SetValue(TW_BACKUP_AVG_FILE_COMP_RATE, file_bps);
818 else
819 DataManager::SetValue(TW_BACKUP_AVG_FILE_RATE, file_bps);
820
Dees_Troy43d8b002012-09-17 16:00:01 -0400821 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
822 Update_System_Details();
823 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
824 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400825}
826
Dees_Troy093b7642012-09-21 15:59:38 -0400827bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name, int partition_count) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400828 time_t Start, Stop;
829 time(&Start);
Dees_Troy093b7642012-09-21 15:59:38 -0400830 ui->ShowProgress(1.0 / (float)partition_count, 150);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400831 if (!Part->Restore(Restore_Name))
832 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400833 if (Part->Has_SubPartition) {
834 std::vector<TWPartition*>::iterator subpart;
835
836 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
837 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
838 if (!(*subpart)->Restore(Restore_Name))
839 return false;
840 }
841 }
842 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400843 time(&Stop);
844 ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
845 return true;
846}
847
Dees_Troy51a0e822012-09-05 15:24:24 -0400848int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400849 int check_md5, check, partition_count = 0;
850 TWPartition* restore_sys = NULL;
851 TWPartition* restore_data = NULL;
852 TWPartition* restore_cache = NULL;
853 TWPartition* restore_boot = NULL;
854 TWPartition* restore_andsec = NULL;
855 TWPartition* restore_sdext = NULL;
856 TWPartition* restore_sp1 = NULL;
857 TWPartition* restore_sp2 = NULL;
858 TWPartition* restore_sp3 = NULL;
859 time_t rStart, rStop;
860 time(&rStart);
Dees_Troy43d8b002012-09-17 16:00:01 -0400861
Dees_Troy4a2a1262012-09-18 09:33:47 -0400862 ui_print("\n[RESTORE STARTED]\n\n");
863 ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400864
Dees_Troy4a2a1262012-09-18 09:33:47 -0400865 if (!Mount_Current_Storage(true))
866 return false;
867
868 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
869 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
Dees_Troy63c8df72012-09-10 14:02:05 -0400870 if (check > 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400871 restore_sys = Find_Partition_By_Path("/system");
872 if (restore_sys == NULL) {
873 LOGE("Unable to locate system partition.\n");
874 return false;
875 }
876 partition_count++;
877 }
878 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
879 if (check > 0) {
880 restore_data = Find_Partition_By_Path("/data");
881 if (restore_data == NULL) {
882 LOGE("Unable to locate data partition.\n");
883 return false;
884 }
885 partition_count++;
886 }
887 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
888 if (check > 0) {
889 restore_cache = Find_Partition_By_Path("/cache");
890 if (restore_cache == NULL) {
891 LOGE("Unable to locate cache partition.\n");
892 return false;
893 }
894 partition_count++;
895 }
896 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
897 if (check > 0) {
898 restore_boot = Find_Partition_By_Path("/boot");
899 if (restore_boot == NULL) {
900 LOGE("Unable to locate boot partition.\n");
901 return false;
902 }
903 partition_count++;
904 }
905 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
906 if (check > 0) {
907 restore_andsec = Find_Partition_By_Path("/and-sec");
908 if (restore_andsec == NULL) {
909 LOGE("Unable to locate android secure partition.\n");
910 return false;
911 }
912 partition_count++;
913 }
914 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
915 if (check > 0) {
916 restore_sdext = Find_Partition_By_Path("/sd-ext");
917 if (restore_sdext == NULL) {
918 LOGE("Unable to locate sd-ext partition.\n");
919 return false;
920 }
921 partition_count++;
922 }
923#ifdef SP1_NAME
924 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
925 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400926 restore_sp1 = Find_Partition_By_Path(EXPAND(SP1_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400927 if (restore_sp1 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400928 LOGE("Unable to locate %s partition.\n", EXPAND(SP1_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400929 return false;
930 }
931 partition_count++;
932 }
933#endif
934#ifdef SP2_NAME
935 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
936 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400937 restore_sp2 = Find_Partition_By_Path(EXPAND(SP2_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400938 if (restore_sp2 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400939 LOGE("Unable to locate %s partition.\n", EXPAND(SP2_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400940 return false;
941 }
942 partition_count++;
943 }
944#endif
945#ifdef SP3_NAME
946 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
947 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400948 restore_sp3 = Find_Partition_By_Path(EXPAND(SP3_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400949 if (restore_sp3 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400950 LOGE("Unable to locate %s partition.\n", EXPAND(SP3_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400951 return false;
952 }
953 partition_count++;
954 }
955#endif
956
957 if (partition_count == 0) {
958 LOGE("No partitions selected for restore.\n");
959 return false;
960 }
961
962 if (check_md5 > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400963 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
Dees_Troyb46a6842012-09-25 11:06:46 -0400964 TWFunc::GUI_Operation_Text(TW_VERIFY_MD5_TEXT, "Verifying MD5");
Dees_Troy4a2a1262012-09-18 09:33:47 -0400965 ui_print("Verifying MD5...\n");
966 if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
967 return false;
968 if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
969 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400970 if (restore_data != NULL && restore_data->Has_SubPartition) {
971 std::vector<TWPartition*>::iterator subpart;
972
973 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
974 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_data->Mount_Point) {
975 if (!(*subpart)->Check_MD5(Restore_Name))
976 return false;
977 }
978 }
979 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400980 if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
981 return false;
982 if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
983 return false;
984 if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
985 return false;
986 if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
987 return false;
988 if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
989 return false;
990 if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
991 return false;
992 if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
993 return false;
994 ui_print("Done verifying MD5.\n");
995 } else
996 ui_print("Skipping MD5 check based on user setting.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400997
Dees_Troy4a2a1262012-09-18 09:33:47 -0400998 ui_print("Restoring %i partitions...\n", partition_count);
Dees_Troy093b7642012-09-21 15:59:38 -0400999 ui->SetProgress(0.0);
1000 if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001001 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001002 if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001003 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001004 if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001005 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001006 if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001007 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001008 if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001009 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001010 if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001011 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001012 if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001013 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001014 if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001015 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001016 if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001017 return false;
Dees_Troy43d8b002012-09-17 16:00:01 -04001018
Dees_Troyb46a6842012-09-25 11:06:46 -04001019 TWFunc::GUI_Operation_Text(TW_UPDATE_SYSTEM_DETAILS_TEXT, "Updating System Details");
Dees_Troy43d8b002012-09-17 16:00:01 -04001020 Update_System_Details();
Dees_Troy4a2a1262012-09-18 09:33:47 -04001021 time(&rStop);
1022 ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
Dees_Troy63c8df72012-09-10 14:02:05 -04001023 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -04001024}
1025
1026void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001027 // Start with the default values
1028 int tw_restore_system = -1;
1029 int tw_restore_data = -1;
1030 int tw_restore_cache = -1;
1031 int tw_restore_recovery = -1;
1032 int tw_restore_boot = -1;
1033 int tw_restore_andsec = -1;
1034 int tw_restore_sdext = -1;
1035 int tw_restore_sp1 = -1;
1036 int tw_restore_sp2 = -1;
1037 int tw_restore_sp3 = -1;
1038 bool get_date = true;
1039
1040 DIR* d;
1041 d = opendir(Restore_Name.c_str());
1042 if (d == NULL)
1043 {
1044 LOGE("Error opening %s\n", Restore_Name.c_str());
1045 return;
1046 }
1047
1048 struct dirent* de;
1049 while ((de = readdir(d)) != NULL)
1050 {
1051 // Strip off three components
1052 char str[256];
1053 char* label;
1054 char* fstype = NULL;
1055 char* extn = NULL;
1056 char* ptr;
1057
1058 strcpy(str, de->d_name);
1059 if (strlen(str) <= 2)
1060 continue;
1061
1062 if (get_date) {
1063 char file_path[255];
1064 struct stat st;
1065
1066 strcpy(file_path, Restore_Name.c_str());
1067 strcat(file_path, "/");
1068 strcat(file_path, str);
1069 stat(file_path, &st);
1070 string backup_date = ctime((const time_t*)(&st.st_mtime));
1071 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
1072 get_date = false;
1073 }
1074
1075 label = str;
1076 ptr = label;
1077 while (*ptr && *ptr != '.') ptr++;
1078 if (*ptr == '.')
1079 {
1080 *ptr = 0x00;
1081 ptr++;
1082 fstype = ptr;
1083 }
1084 while (*ptr && *ptr != '.') ptr++;
1085 if (*ptr == '.')
1086 {
1087 *ptr = 0x00;
1088 ptr++;
1089 extn = ptr;
1090 }
1091
1092 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
1093
1094 TWPartition* Part = Find_Partition_By_Path(label);
1095 if (Part == NULL)
1096 {
1097 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
1098 continue;
1099 }
1100
1101 Part->Backup_FileName = de->d_name;
1102 if (strlen(extn) > 3) {
1103 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
1104 }
1105
1106 // Now, we just need to find the correct label
Dees_Troye58d5262012-09-21 12:27:57 -04001107 if (Part->Backup_Path == "/system")
Dees_Troy63c8df72012-09-10 14:02:05 -04001108 tw_restore_system = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001109 if (Part->Backup_Path == "/data")
Dees_Troy63c8df72012-09-10 14:02:05 -04001110 tw_restore_data = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001111 if (Part->Backup_Path == "/cache")
Dees_Troy63c8df72012-09-10 14:02:05 -04001112 tw_restore_cache = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001113 if (Part->Backup_Path == "/recovery")
Dees_Troy63c8df72012-09-10 14:02:05 -04001114 tw_restore_recovery = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001115 if (Part->Backup_Path == "/boot")
Dees_Troy63c8df72012-09-10 14:02:05 -04001116 tw_restore_boot = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001117 if (Part->Backup_Path == "/and-sec")
Dees_Troy63c8df72012-09-10 14:02:05 -04001118 tw_restore_andsec = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001119 if (Part->Backup_Path == "/sd-ext")
Dees_Troy63c8df72012-09-10 14:02:05 -04001120 tw_restore_sdext = 1;
1121#ifdef SP1_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001122 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP1_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001123 tw_restore_sp1 = 1;
1124#endif
1125#ifdef SP2_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001126 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP2_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001127 tw_restore_sp2 = 1;
1128#endif
1129#ifdef SP3_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001130 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP3_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001131 tw_restore_sp3 = 1;
1132#endif
1133 }
1134 closedir(d);
1135
1136 // Set the final values
1137 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
1138 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
1139 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
1140 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
1141 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
1142 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
1143 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
1144 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
1145 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
1146 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
1147
Dees_Troy51a0e822012-09-05 15:24:24 -04001148 return;
1149}
1150
1151int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001152 std::vector<TWPartition*>::iterator iter;
1153 int ret = false;
1154 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -04001155 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -04001156
1157 // Iterate through all partitions
1158 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -04001159 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troye58d5262012-09-21 12:27:57 -04001160 if (Path == "/and-sec")
1161 ret = (*iter)->Wipe_AndSec();
1162 else
1163 ret = (*iter)->Wipe();
Dees_Troy63c8df72012-09-10 14:02:05 -04001164 found = true;
1165 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
1166 (*iter)->Wipe();
1167 }
1168 }
1169 if (found) {
1170 return ret;
1171 } else
1172 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
1173 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001174}
1175
1176int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001177 TWPartition* Part = Find_Partition_By_Block(Block);
1178
1179 if (Part) {
1180 if (Part->Has_SubPartition) {
1181 std::vector<TWPartition*>::iterator subpart;
1182
1183 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1184 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1185 (*subpart)->Wipe();
1186 }
1187 return Part->Wipe();
1188 } else
1189 return Part->Wipe();
1190 }
1191 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1192 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001193}
1194
1195int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001196 TWPartition* Part = Find_Partition_By_Name(Name);
1197
1198 if (Part) {
1199 if (Part->Has_SubPartition) {
1200 std::vector<TWPartition*>::iterator subpart;
1201
1202 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1203 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1204 (*subpart)->Wipe();
1205 }
1206 return Part->Wipe();
1207 } else
1208 return Part->Wipe();
1209 }
1210 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1211 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001212}
1213
1214int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001215 std::vector<TWPartition*>::iterator iter;
1216 int ret = true;
1217
1218 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001219 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001220 if (!(*iter)->Wipe())
1221 ret = false;
1222 }
1223 }
1224 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001225}
1226
Dees_Troy38bd7602012-09-14 13:33:53 -04001227int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1228 struct stat st;
1229
1230 if (!Mount_By_Path("/data", true))
1231 return false;
1232
1233 if (!Mount_By_Path("/cache", true))
1234 return false;
1235
1236 ui_print("\nWiping Dalvik Cache Directories...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001237 system("rm -rf /data/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001238 ui_print("Cleaned: /data/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001239 system("rm -rf /cache/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001240 ui_print("Cleaned: /cache/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001241 system("rm -rf /cache/dc");
Dees_Troy38bd7602012-09-14 13:33:53 -04001242 ui_print("Cleaned: /cache/dc\n");
1243
1244 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1245 if (sdext != NULL) {
1246 if (sdext->Is_Present && sdext->Mount(false)) {
1247 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001248 system("rm -rf /sd-ext/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001249 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1250 }
1251 }
1252 }
1253 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1254 return true;
1255}
1256
1257int TWPartitionManager::Wipe_Rotate_Data(void) {
1258 if (!Mount_By_Path("/data", true))
1259 return false;
1260
Dees_Troy8170a922012-09-18 15:40:25 -04001261 system("rm -r /data/misc/akmd*");
1262 system("rm -r /data/misc/rild*");
1263 system("rm -r /data/misc/rild*");
Dees_Troy38bd7602012-09-14 13:33:53 -04001264 ui_print("Rotation data wiped.\n");
1265 return true;
1266}
1267
1268int TWPartitionManager::Wipe_Battery_Stats(void) {
1269 struct stat st;
1270
1271 if (!Mount_By_Path("/data", true))
1272 return false;
1273
1274 if (0 != stat("/data/system/batterystats.bin", &st)) {
1275 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1276 } else {
1277 remove("/data/system/batterystats.bin");
1278 ui_print("Cleared battery stats.\n");
1279 }
1280 return true;
1281}
1282
1283int TWPartitionManager::Format_Data(void) {
1284 TWPartition* dat = Find_Partition_By_Path("/data");
1285
1286 if (dat != NULL) {
1287 if (!dat->UnMount(true))
1288 return false;
1289
1290 return dat->Wipe_Encryption();
1291 } else {
1292 LOGE("Unable to locate /data.\n");
1293 return false;
1294 }
1295 return false;
1296}
1297
1298int TWPartitionManager::Wipe_Media_From_Data(void) {
1299 TWPartition* dat = Find_Partition_By_Path("/data");
1300
1301 if (dat != NULL) {
1302 if (!dat->Has_Data_Media) {
1303 LOGE("This device does not have /data/media\n");
1304 return false;
1305 }
1306 if (!dat->Mount(true))
1307 return false;
1308
1309 ui_print("Wiping internal storage -- /data/media...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001310 system("rm -rf /data/media");
1311 system("cd /data && mkdir media && chmod 775 media");
Dees_Troy38bd7602012-09-14 13:33:53 -04001312 if (dat->Has_Data_Media) {
1313 dat->Recreate_Media_Folder();
1314 }
1315 return true;
1316 } else {
1317 LOGE("Unable to locate /data.\n");
1318 return false;
1319 }
1320 return false;
1321}
1322
Dees_Troy51a0e822012-09-05 15:24:24 -04001323void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001324 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001325 return;
1326}
1327
1328void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001329 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001330 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001331
Dees_Troy32c8eb82012-09-11 15:28:06 -04001332 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001333 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001334 if ((*iter)->Can_Be_Mounted) {
1335 (*iter)->Update_Size(true);
1336 if ((*iter)->Mount_Point == "/system") {
1337 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1338 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1339 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1340 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1341 } else if ((*iter)->Mount_Point == "/cache") {
1342 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1343 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1344 } else if ((*iter)->Mount_Point == "/sd-ext") {
1345 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1346 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1347 if ((*iter)->Backup_Size == 0) {
1348 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1349 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1350 } else
1351 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
Dees_Troye58d5262012-09-21 12:27:57 -04001352 } else if ((*iter)->Has_Android_Secure) {
Dees_Troy8170a922012-09-18 15:40:25 -04001353 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
Dees_Troye58d5262012-09-21 12:27:57 -04001354 DataManager::SetValue(TW_BACKUP_ANDSEC_SIZE, backup_display_size);
Dees_Troy8170a922012-09-18 15:40:25 -04001355 if ((*iter)->Backup_Size == 0) {
1356 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 0);
1357 DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
1358 } else
1359 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 1);
Dees_Troy51127312012-09-08 13:08:49 -04001360 }
Dees_Troyab10ee22012-09-21 14:27:30 -04001361#ifdef SP1_NAME
1362 if ((*iter)->Backup_Name == EXPAND(SP1_NAME)) {
1363 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1364 DataManager::SetValue(TW_BACKUP_SP1_SIZE, backup_display_size);
1365 }
1366#endif
1367#ifdef SP2_NAME
1368 if ((*iter)->Backup_Name == EXPAND(SP2_NAME)) {
1369 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1370 DataManager::SetValue(TW_BACKUP_SP2_SIZE, backup_display_size);
1371 }
1372#endif
1373#ifdef SP3_NAME
1374 if ((*iter)->Backup_Name == EXPAND(SP3_NAME)) {
1375 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1376 DataManager::SetValue(TW_BACKUP_SP3_SIZE, backup_display_size);
1377 }
1378#endif
Dees_Troy51127312012-09-08 13:08:49 -04001379 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001380 }
Dees_Troy51127312012-09-08 13:08:49 -04001381 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1382 string current_storage_path = DataManager::GetCurrentStoragePath();
1383 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
Dees_Troy8170a922012-09-18 15:40:25 -04001384 if (FreeStorage != NULL) {
1385 // Attempt to mount storage
1386 if (!FreeStorage->Mount(false)) {
1387 // We couldn't mount storage... check to see if we have dual storage
1388 int has_dual_storage;
1389 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual_storage);
1390 if (has_dual_storage == 1) {
1391 // We have dual storage, see if we're using the internal storage that should always be present
1392 if (current_storage_path == DataManager::GetSettingsStoragePath()) {
Dees_Troyab10ee22012-09-21 14:27:30 -04001393 if (!FreeStorage->Is_Encrypted) {
1394 // Not able to use internal, so error!
1395 LOGE("Unable to mount internal storage.\n");
1396 }
Dees_Troy8170a922012-09-18 15:40:25 -04001397 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1398 } else {
1399 // We were using external, flip to internal
1400 DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
1401 current_storage_path = DataManager::GetCurrentStoragePath();
1402 FreeStorage = Find_Partition_By_Path(current_storage_path);
1403 if (FreeStorage != NULL) {
1404 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1405 } else {
1406 LOGE("Unable to locate internal storage partition.\n");
1407 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1408 }
1409 }
1410 } else {
1411 // No dual storage and unable to mount storage, error!
1412 LOGE("Unable to mount storage.\n");
1413 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1414 }
1415 } else {
1416 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1417 }
1418 } else {
Dees_Troy51127312012-09-08 13:08:49 -04001419 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -04001420 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001421 if (!Write_Fstab())
1422 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001423 return;
1424}
1425
1426int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001427#ifdef TW_INCLUDE_CRYPTO
1428 int ret_val, password_len;
1429 char crypto_blkdev[255], cPassword[255];
1430 size_t result;
1431
1432 property_set("ro.crypto.state", "encrypted");
1433#ifdef TW_INCLUDE_JB_CRYPTO
1434 // No extra flags needed
1435#else
1436 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1437 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1438 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1439 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1440 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1441 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1442#endif
1443 strcpy(cPassword, Password.c_str());
1444 if (cryptfs_check_passwd(cPassword) != 0) {
1445 LOGE("Failed to decrypt data.\n");
1446 return -1;
1447 }
1448 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1449 if (strcmp(crypto_blkdev, "error") == 0) {
1450 LOGE("Error retrieving decrypted data block device.\n");
1451 } else {
1452 TWPartition* dat = Find_Partition_By_Path("/data");
1453 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001454 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001455 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1456 dat->Is_Decrypted = true;
1457 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001458 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001459 // Sleep for a bit so that the device will be ready
1460 sleep(1);
1461 Update_System_Details();
1462 } else
1463 LOGE("Unable to locate data partition.\n");
1464 }
1465 return 0;
1466#else
1467 LOGE("No crypto support was compiled into this build.\n");
1468 return -1;
1469#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001470 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001471}
1472
Dees_Troy38bd7602012-09-14 13:33:53 -04001473int TWPartitionManager::Fix_Permissions(void) {
1474 if (!Mount_By_Path("/data", true))
1475 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001476
Dees_Troy38bd7602012-09-14 13:33:53 -04001477 if (!Mount_By_Path("/system", true))
1478 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001479
Dees_Troy38bd7602012-09-14 13:33:53 -04001480 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001481 system("./sbin/fix_permissions.sh");
Dees_Troy38bd7602012-09-14 13:33:53 -04001482 ui_print("Done.\n\n");
1483 return true;
Dees_Troy4a2a1262012-09-18 09:33:47 -04001484}
Dees_Troy8170a922012-09-18 15:40:25 -04001485
1486//partial kangbang from system/vold
1487#ifndef CUSTOM_LUN_FILE
1488#define CUSTOM_LUN_FILE "/sys/devices/platform/usb_mass_storage/lun%d/file"
1489#endif
1490
1491int TWPartitionManager::usb_storage_enable(void) {
1492 int fd, has_dual, has_data_media;
1493 char lun_file[255];
1494 TWPartition* Part;
1495 string ext_path;
1496
1497 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual);
1498 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
1499 if (has_dual == 1 && has_data_media == 0) {
1500 Part = Find_Partition_By_Path(DataManager::GetSettingsStoragePath());
1501 if (Part == NULL) {
1502 LOGE("Unable to locate volume information.");
1503 return false;
1504 }
1505 if (!Part->UnMount(true))
1506 return false;
1507
1508 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1509 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1510 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1511 return false;
1512 }
1513
1514 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1515 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1516 close(fd);
1517 return false;
1518 }
1519 close(fd);
1520
1521 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1522 Part = Find_Partition_By_Path(ext_path);
1523 if (Part == NULL) {
1524 LOGE("Unable to locate volume information.\n");
1525 return false;
1526 }
1527 if (!Part->UnMount(true))
1528 return false;
1529
1530 sprintf(lun_file, CUSTOM_LUN_FILE, 1);
1531 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1532 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1533 return false;
1534 }
1535
1536 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1537 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1538 close(fd);
1539 return false;
1540 }
1541 close(fd);
1542 } else {
1543 if (has_data_media == 0)
1544 ext_path = DataManager::GetCurrentStoragePath();
1545 else
1546 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1547
1548 Part = Find_Partition_By_Path(ext_path);
1549 if (Part == NULL) {
1550 LOGE("Unable to locate volume information.\n");
1551 return false;
1552 }
1553 if (!Part->UnMount(true))
1554 return false;
1555
1556 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1557
1558 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1559 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1560 return false;
1561 }
1562
1563 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1564 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1565 close(fd);
1566 return false;
1567 }
1568 close(fd);
1569 }
1570 return true;
1571}
1572
1573int TWPartitionManager::usb_storage_disable(void) {
1574 int fd, index;
1575 char lun_file[255];
1576
1577 for (index=0; index<2; index++) {
1578 sprintf(lun_file, CUSTOM_LUN_FILE, index);
1579
1580 if ((fd = open(lun_file, O_WRONLY)) < 0) {
Dees_Troye58d5262012-09-21 12:27:57 -04001581 Mount_All_Storage();
1582 Update_System_Details();
1583 if (index == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001584 LOGE("Unable to open ums lunfile '%s': (%s)", lun_file, strerror(errno));
Dees_Troye58d5262012-09-21 12:27:57 -04001585 return false;
1586 } else
1587 return true;
Dees_Troy8170a922012-09-18 15:40:25 -04001588 }
1589
1590 char ch = 0;
1591 if (write(fd, &ch, 1) < 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001592 close(fd);
Dees_Troye58d5262012-09-21 12:27:57 -04001593 Mount_All_Storage();
1594 Update_System_Details();
1595 if (index == 0) {
1596 LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
1597 return false;
1598 } else
1599 return true;
Dees_Troy8170a922012-09-18 15:40:25 -04001600 }
1601
1602 close(fd);
1603 }
Dees_Troye58d5262012-09-21 12:27:57 -04001604 Mount_All_Storage();
1605 Update_System_Details();
Dees_Troy8170a922012-09-18 15:40:25 -04001606 return true;
Dees_Troy812660f2012-09-20 09:55:17 -04001607}
1608
1609void TWPartitionManager::Mount_All_Storage(void) {
1610 std::vector<TWPartition*>::iterator iter;
1611
1612 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
1613 if ((*iter)->Is_Storage)
1614 (*iter)->Mount(false);
1615 }
Dees_Troy8170a922012-09-18 15:40:25 -04001616}