blob: 739db522b47efcccce34bd2d89a988d172effafb [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_Troyc51f1f92012-09-20 15:32:13 -0400424 ui_print(" * Generating md5...\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400425
426 if (TWFunc::Path_Exists(Full_File)) {
427 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 -0400428 if (system(command) == 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400429 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400430 return true;
431 } else {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400432 ui_print("MD5 Error!\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400433 return false;
434 }
435 } else {
436 char filename[512];
437 int index = 0;
438
439 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400440 while (TWFunc::Path_Exists(filename) == true) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400441 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 -0400442 if (system(command) != 0) {
443 ui_print("MD5 Error.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400444 return false;
445 }
446 index++;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400447 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy43d8b002012-09-17 16:00:01 -0400448 }
449 if (index == 0) {
450 LOGE("Backup file: '%s' not found!\n", filename);
451 return false;
452 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400453 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400454 }
455 return true;
456}
457
Dees_Troy093b7642012-09-21 15:59:38 -0400458bool 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 -0400459 time_t start, stop;
Dees_Troy093b7642012-09-21 15:59:38 -0400460 int img_bps, file_bps;
461 unsigned long total_time, remain_time, section_time;
462 int use_compression, backup_time;
463 float pos;
Dees_Troy43d8b002012-09-17 16:00:01 -0400464
465 if (Part == NULL)
466 return true;
467
Dees_Troy093b7642012-09-21 15:59:38 -0400468 DataManager::GetValue(TW_BACKUP_AVG_IMG_RATE, img_bps);
469
470 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
471 if (use_compression)
472 DataManager::GetValue(TW_BACKUP_AVG_FILE_COMP_RATE, file_bps);
473 else
474 DataManager::GetValue(TW_BACKUP_AVG_FILE_RATE, file_bps);
475
476 // We know the speed for both, how far into the whole backup are we, based on time
477 total_time = (*img_bytes / (unsigned long)img_bps) + (*file_bytes / (unsigned long)file_bps);
478 remain_time = (*img_bytes_remaining / (unsigned long)img_bps) + (*file_bytes_remaining / (unsigned long)file_bps);
479
480 pos = (total_time - remain_time) / (float) total_time;
481 ui->SetProgress(pos);
482
483 LOGI("Estimated Total time: %lu Estimated remaining time: %lu\n", total_time, remain_time);
484
485 // And get the time
486 if (Part->Backup_Method == 1)
487 section_time = Part->Backup_Size / file_bps;
488 else
489 section_time = Part->Backup_Size / img_bps;
490
491 // Set the position
492 pos = section_time / (float) total_time;
493 ui->ShowProgress(pos, section_time);
494
Dees_Troy43d8b002012-09-17 16:00:01 -0400495 time(&start);
496
497 if (Part->Backup(Backup_Folder)) {
Dees_Troy8170a922012-09-18 15:40:25 -0400498 if (Part->Has_SubPartition) {
499 std::vector<TWPartition*>::iterator subpart;
500
501 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
502 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
503 if (!(*subpart)->Backup(Backup_Folder))
504 return false;
505 if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
506 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400507 if (Part->Backup_Method == 1) {
508 *file_bytes_remaining -= (*subpart)->Backup_Size;
509 } else {
510 *img_bytes_remaining -= (*subpart)->Backup_Size;
511 }
Dees_Troy8170a922012-09-18 15:40:25 -0400512 }
513 }
514 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400515 time(&stop);
Dees_Troy093b7642012-09-21 15:59:38 -0400516 backup_time = (int) difftime(stop, start);
517 LOGI("Partition Backup time: %d\n", backup_time);
Dees_Troy43d8b002012-09-17 16:00:01 -0400518 if (Part->Backup_Method == 1) {
519 *file_bytes_remaining -= Part->Backup_Size;
Dees_Troy093b7642012-09-21 15:59:38 -0400520 *file_time += backup_time;
Dees_Troy43d8b002012-09-17 16:00:01 -0400521 } else {
522 *img_bytes_remaining -= Part->Backup_Size;
Dees_Troy093b7642012-09-21 15:59:38 -0400523 *img_time += backup_time;
Dees_Troy43d8b002012-09-17 16:00:01 -0400524 }
525 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
526 } else {
527 return false;
528 }
529}
530
531int TWPartitionManager::Run_Backup(void) {
532 int check, do_md5, partition_count = 0;
533 string Backup_Folder, Backup_Name, Full_Backup_Path;
Dees_Troy8170a922012-09-18 15:40:25 -0400534 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 -0400535 unsigned long img_time = 0, file_time = 0;
536 TWPartition* backup_sys = NULL;
537 TWPartition* backup_data = NULL;
538 TWPartition* backup_cache = NULL;
539 TWPartition* backup_recovery = NULL;
540 TWPartition* backup_boot = NULL;
541 TWPartition* backup_andsec = NULL;
542 TWPartition* backup_sdext = NULL;
543 TWPartition* backup_sp1 = NULL;
544 TWPartition* backup_sp2 = NULL;
545 TWPartition* backup_sp3 = NULL;
546 TWPartition* storage = NULL;
Dees_Troy8170a922012-09-18 15:40:25 -0400547 std::vector<TWPartition*>::iterator subpart;
Dees_Troy43d8b002012-09-17 16:00:01 -0400548 struct tm *t;
549 time_t start, stop, seconds, total_start, total_stop;
550 seconds = time(0);
551 t = localtime(&seconds);
552
553 time(&total_start);
554
555 Update_System_Details();
556
557 if (!Mount_Current_Storage(true))
558 return false;
559
560 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400561 if (do_md5 == 0)
Dees_Troy43d8b002012-09-17 16:00:01 -0400562 do_md5 = true;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400563
Dees_Troy43d8b002012-09-17 16:00:01 -0400564 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
565 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
566 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
567 char timestamp[255];
568 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);
569 Backup_Name = timestamp;
570 }
571 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
572 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
573 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
574
575 ui_print("\n[BACKUP STARTED]\n");
576 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
577 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
578 LOGE("Failed to make backup folder.\n");
579 return false;
580 }
581
582 LOGI("Calculating backup details...\n");
583 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
584 if (check) {
585 backup_sys = Find_Partition_By_Path("/system");
586 if (backup_sys != NULL) {
587 partition_count++;
588 if (backup_sys->Backup_Method == 1)
589 file_bytes += backup_sys->Backup_Size;
590 else
591 img_bytes += backup_sys->Backup_Size;
592 } else {
593 LOGE("Unable to locate system partition.\n");
594 return false;
595 }
596 }
597 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
598 if (check) {
599 backup_data = Find_Partition_By_Path("/data");
600 if (backup_data != NULL) {
601 partition_count++;
Dees_Troy8170a922012-09-18 15:40:25 -0400602 subpart_size = 0;
603 if (backup_data->Has_SubPartition) {
604 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
605 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_data->Mount_Point)
606 subpart_size += (*subpart)->Backup_Size;
607 }
608 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400609 if (backup_data->Backup_Method == 1)
Dees_Troy8170a922012-09-18 15:40:25 -0400610 file_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400611 else
Dees_Troy8170a922012-09-18 15:40:25 -0400612 img_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400613 } else {
614 LOGE("Unable to locate data partition.\n");
615 return false;
616 }
617 }
618 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
619 if (check) {
620 backup_cache = Find_Partition_By_Path("/cache");
621 if (backup_cache != NULL) {
622 partition_count++;
623 if (backup_cache->Backup_Method == 1)
624 file_bytes += backup_cache->Backup_Size;
625 else
626 img_bytes += backup_cache->Backup_Size;
627 } else {
628 LOGE("Unable to locate cache partition.\n");
629 return false;
630 }
631 }
632 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
633 if (check) {
634 backup_recovery = Find_Partition_By_Path("/recovery");
635 if (backup_recovery != NULL) {
636 partition_count++;
637 if (backup_recovery->Backup_Method == 1)
638 file_bytes += backup_recovery->Backup_Size;
639 else
640 img_bytes += backup_recovery->Backup_Size;
641 } else {
642 LOGE("Unable to locate recovery partition.\n");
643 return false;
644 }
645 }
646 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
647 if (check) {
648 backup_boot = Find_Partition_By_Path("/boot");
649 if (backup_boot != NULL) {
650 partition_count++;
651 if (backup_boot->Backup_Method == 1)
652 file_bytes += backup_boot->Backup_Size;
653 else
654 img_bytes += backup_boot->Backup_Size;
655 } else {
656 LOGE("Unable to locate boot partition.\n");
657 return false;
658 }
659 }
660 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
661 if (check) {
662 backup_andsec = Find_Partition_By_Path("/and-sec");
663 if (backup_andsec != NULL) {
664 partition_count++;
665 if (backup_andsec->Backup_Method == 1)
666 file_bytes += backup_andsec->Backup_Size;
667 else
668 img_bytes += backup_andsec->Backup_Size;
669 } else {
670 LOGE("Unable to locate android secure partition.\n");
671 return false;
672 }
673 }
674 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
675 if (check) {
676 backup_sdext = Find_Partition_By_Path("/sd-ext");
677 if (backup_sdext != NULL) {
678 partition_count++;
679 if (backup_sdext->Backup_Method == 1)
680 file_bytes += backup_sdext->Backup_Size;
681 else
682 img_bytes += backup_sdext->Backup_Size;
683 } else {
684 LOGE("Unable to locate sd-ext partition.\n");
685 return false;
686 }
687 }
688#ifdef SP1_NAME
689 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
690 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400691 backup_sp1 = Find_Partition_By_Path(EXPAND(SP1_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400692 if (backup_sp1 != NULL) {
693 partition_count++;
694 if (backup_sp1->Backup_Method == 1)
695 file_bytes += backup_sp1->Backup_Size;
696 else
697 img_bytes += backup_sp1->Backup_Size;
698 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400699 LOGE("Unable to locate %s partition.\n", EXPAND(SP1_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400700 return false;
701 }
702 }
703#endif
704#ifdef SP2_NAME
705 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
706 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400707 backup_sp2 = Find_Partition_By_Path(EXPAND(SP2_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400708 if (backup_sp2 != NULL) {
709 partition_count++;
710 if (backup_sp2->Backup_Method == 1)
711 file_bytes += backup_sp2->Backup_Size;
712 else
713 img_bytes += backup_sp2->Backup_Size;
714 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400715 LOGE("Unable to locate %s partition.\n", EXPAND(SP2_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400716 return false;
717 }
718 }
719#endif
720#ifdef SP3_NAME
721 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
722 if (check) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400723 backup_sp3 = Find_Partition_By_Path(EXPAND(SP3_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400724 if (backup_sp3 != NULL) {
725 partition_count++;
726 if (backup_sp3->Backup_Method == 1)
727 file_bytes += backup_sp3->Backup_Size;
728 else
729 img_bytes += backup_sp3->Backup_Size;
730 } else {
Dees_Troyab10ee22012-09-21 14:27:30 -0400731 LOGE("Unable to locate %s partition.\n", EXPAND(SP3_NAME));
Dees_Troy43d8b002012-09-17 16:00:01 -0400732 return false;
733 }
734 }
735#endif
736
737 if (partition_count == 0) {
738 ui_print("No partitions selected for backup.\n");
739 return false;
740 }
741 total_bytes = file_bytes + img_bytes;
742 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
743 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
744 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
745 if (storage != NULL) {
746 free_space = storage->Free;
747 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
748 } else {
749 LOGE("Unable to locate storage device.\n");
750 return false;
751 }
752 if (free_space + (32 * 1024 * 1024) < total_bytes) {
753 // We require an extra 32MB just in case
754 LOGE("Not enough free space on storage.\n");
755 return false;
756 }
757 img_bytes_remaining = img_bytes;
758 file_bytes_remaining = file_bytes;
759
Dees_Troy093b7642012-09-21 15:59:38 -0400760 ui->SetProgress(0.0);
761
762 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 -0400763 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400764 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 -0400765 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400766 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 -0400767 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400768 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 -0400769 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400770 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 -0400771 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400772 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 -0400773 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400774 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 -0400775 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400776 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 -0400777 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400778 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 -0400779 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400780 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 -0400781 return false;
782
783 // Average BPS
784 if (img_time == 0)
785 img_time = 1;
786 if (file_time == 0)
787 file_time = 1;
Dees_Troy093b7642012-09-21 15:59:38 -0400788 int img_bps = (int)img_bytes / (int)img_time;
789 int file_bps = (int)file_bytes / (int)file_time;
Dees_Troy43d8b002012-09-17 16:00:01 -0400790
791 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
792 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
793
794 time(&total_stop);
795 int total_time = (int) difftime(total_stop, total_start);
796 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
797 actual_backup_size /= (1024LLU * 1024LLU);
798
Dees_Troy093b7642012-09-21 15:59:38 -0400799 int prev_img_bps, prev_file_bps, use_compression;
800 DataManager::GetValue(TW_BACKUP_AVG_IMG_RATE, prev_img_bps);
801 img_bps += (prev_img_bps * 4);
802 img_bps /= 5;
803
804 DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
805 if (use_compression)
806 DataManager::GetValue(TW_BACKUP_AVG_FILE_COMP_RATE, prev_file_bps);
807 else
808 DataManager::GetValue(TW_BACKUP_AVG_FILE_RATE, prev_file_bps);
809 file_bps += (prev_file_bps * 4);
810 file_bps /= 5;
811
812 DataManager::SetValue(TW_BACKUP_AVG_IMG_RATE, img_bps);
813 if (use_compression)
814 DataManager::SetValue(TW_BACKUP_AVG_FILE_COMP_RATE, file_bps);
815 else
816 DataManager::SetValue(TW_BACKUP_AVG_FILE_RATE, file_bps);
817
Dees_Troy43d8b002012-09-17 16:00:01 -0400818 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
819 Update_System_Details();
820 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
821 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400822}
823
Dees_Troy093b7642012-09-21 15:59:38 -0400824bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name, int partition_count) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400825 time_t Start, Stop;
826 time(&Start);
Dees_Troy093b7642012-09-21 15:59:38 -0400827 ui->ShowProgress(1.0 / (float)partition_count, 150);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400828 if (!Part->Restore(Restore_Name))
829 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400830 if (Part->Has_SubPartition) {
831 std::vector<TWPartition*>::iterator subpart;
832
833 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
834 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
835 if (!(*subpart)->Restore(Restore_Name))
836 return false;
837 }
838 }
839 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400840 time(&Stop);
841 ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
842 return true;
843}
844
Dees_Troy51a0e822012-09-05 15:24:24 -0400845int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400846 int check_md5, check, partition_count = 0;
847 TWPartition* restore_sys = NULL;
848 TWPartition* restore_data = NULL;
849 TWPartition* restore_cache = NULL;
850 TWPartition* restore_boot = NULL;
851 TWPartition* restore_andsec = NULL;
852 TWPartition* restore_sdext = NULL;
853 TWPartition* restore_sp1 = NULL;
854 TWPartition* restore_sp2 = NULL;
855 TWPartition* restore_sp3 = NULL;
856 time_t rStart, rStop;
857 time(&rStart);
Dees_Troy43d8b002012-09-17 16:00:01 -0400858
Dees_Troy4a2a1262012-09-18 09:33:47 -0400859 ui_print("\n[RESTORE STARTED]\n\n");
860 ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400861
Dees_Troy4a2a1262012-09-18 09:33:47 -0400862 if (!Mount_Current_Storage(true))
863 return false;
864
865 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
866 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
Dees_Troy63c8df72012-09-10 14:02:05 -0400867 if (check > 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400868 restore_sys = Find_Partition_By_Path("/system");
869 if (restore_sys == NULL) {
870 LOGE("Unable to locate system partition.\n");
871 return false;
872 }
873 partition_count++;
874 }
875 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
876 if (check > 0) {
877 restore_data = Find_Partition_By_Path("/data");
878 if (restore_data == NULL) {
879 LOGE("Unable to locate data partition.\n");
880 return false;
881 }
882 partition_count++;
883 }
884 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
885 if (check > 0) {
886 restore_cache = Find_Partition_By_Path("/cache");
887 if (restore_cache == NULL) {
888 LOGE("Unable to locate cache partition.\n");
889 return false;
890 }
891 partition_count++;
892 }
893 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
894 if (check > 0) {
895 restore_boot = Find_Partition_By_Path("/boot");
896 if (restore_boot == NULL) {
897 LOGE("Unable to locate boot partition.\n");
898 return false;
899 }
900 partition_count++;
901 }
902 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
903 if (check > 0) {
904 restore_andsec = Find_Partition_By_Path("/and-sec");
905 if (restore_andsec == NULL) {
906 LOGE("Unable to locate android secure partition.\n");
907 return false;
908 }
909 partition_count++;
910 }
911 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
912 if (check > 0) {
913 restore_sdext = Find_Partition_By_Path("/sd-ext");
914 if (restore_sdext == NULL) {
915 LOGE("Unable to locate sd-ext partition.\n");
916 return false;
917 }
918 partition_count++;
919 }
920#ifdef SP1_NAME
921 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
922 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400923 restore_sp1 = Find_Partition_By_Path(EXPAND(SP1_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400924 if (restore_sp1 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400925 LOGE("Unable to locate %s partition.\n", EXPAND(SP1_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400926 return false;
927 }
928 partition_count++;
929 }
930#endif
931#ifdef SP2_NAME
932 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
933 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400934 restore_sp2 = Find_Partition_By_Path(EXPAND(SP2_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400935 if (restore_sp2 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400936 LOGE("Unable to locate %s partition.\n", EXPAND(SP2_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400937 return false;
938 }
939 partition_count++;
940 }
941#endif
942#ifdef SP3_NAME
943 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
944 if (check > 0) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400945 restore_sp3 = Find_Partition_By_Path(EXPAND(SP3_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400946 if (restore_sp3 == NULL) {
Dees_Troyab10ee22012-09-21 14:27:30 -0400947 LOGE("Unable to locate %s partition.\n", EXPAND(SP3_NAME));
Dees_Troy4a2a1262012-09-18 09:33:47 -0400948 return false;
949 }
950 partition_count++;
951 }
952#endif
953
954 if (partition_count == 0) {
955 LOGE("No partitions selected for restore.\n");
956 return false;
957 }
958
959 if (check_md5 > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400960 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
Dees_Troy4a2a1262012-09-18 09:33:47 -0400961 ui_print("Verifying MD5...\n");
962 if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
963 return false;
964 if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
965 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400966 if (restore_data != NULL && restore_data->Has_SubPartition) {
967 std::vector<TWPartition*>::iterator subpart;
968
969 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
970 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_data->Mount_Point) {
971 if (!(*subpart)->Check_MD5(Restore_Name))
972 return false;
973 }
974 }
975 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400976 if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
977 return false;
978 if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
979 return false;
980 if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
981 return false;
982 if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
983 return false;
984 if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
985 return false;
986 if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
987 return false;
988 if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
989 return false;
990 ui_print("Done verifying MD5.\n");
991 } else
992 ui_print("Skipping MD5 check based on user setting.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400993
Dees_Troy4a2a1262012-09-18 09:33:47 -0400994 ui_print("Restoring %i partitions...\n", partition_count);
Dees_Troy093b7642012-09-21 15:59:38 -0400995 ui->SetProgress(0.0);
996 if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -0400997 return false;
Dees_Troy093b7642012-09-21 15:59:38 -0400998 if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -0400999 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001000 if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001001 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001002 if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001003 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001004 if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001005 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001006 if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001007 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001008 if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001009 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001010 if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001011 return false;
Dees_Troy093b7642012-09-21 15:59:38 -04001012 if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name, partition_count))
Dees_Troy4a2a1262012-09-18 09:33:47 -04001013 return false;
Dees_Troy43d8b002012-09-17 16:00:01 -04001014
Dees_Troy43d8b002012-09-17 16:00:01 -04001015 Update_System_Details();
Dees_Troy4a2a1262012-09-18 09:33:47 -04001016 time(&rStop);
1017 ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
Dees_Troy63c8df72012-09-10 14:02:05 -04001018 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -04001019}
1020
1021void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001022 // Start with the default values
1023 int tw_restore_system = -1;
1024 int tw_restore_data = -1;
1025 int tw_restore_cache = -1;
1026 int tw_restore_recovery = -1;
1027 int tw_restore_boot = -1;
1028 int tw_restore_andsec = -1;
1029 int tw_restore_sdext = -1;
1030 int tw_restore_sp1 = -1;
1031 int tw_restore_sp2 = -1;
1032 int tw_restore_sp3 = -1;
1033 bool get_date = true;
1034
1035 DIR* d;
1036 d = opendir(Restore_Name.c_str());
1037 if (d == NULL)
1038 {
1039 LOGE("Error opening %s\n", Restore_Name.c_str());
1040 return;
1041 }
1042
1043 struct dirent* de;
1044 while ((de = readdir(d)) != NULL)
1045 {
1046 // Strip off three components
1047 char str[256];
1048 char* label;
1049 char* fstype = NULL;
1050 char* extn = NULL;
1051 char* ptr;
1052
1053 strcpy(str, de->d_name);
1054 if (strlen(str) <= 2)
1055 continue;
1056
1057 if (get_date) {
1058 char file_path[255];
1059 struct stat st;
1060
1061 strcpy(file_path, Restore_Name.c_str());
1062 strcat(file_path, "/");
1063 strcat(file_path, str);
1064 stat(file_path, &st);
1065 string backup_date = ctime((const time_t*)(&st.st_mtime));
1066 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
1067 get_date = false;
1068 }
1069
1070 label = str;
1071 ptr = label;
1072 while (*ptr && *ptr != '.') ptr++;
1073 if (*ptr == '.')
1074 {
1075 *ptr = 0x00;
1076 ptr++;
1077 fstype = ptr;
1078 }
1079 while (*ptr && *ptr != '.') ptr++;
1080 if (*ptr == '.')
1081 {
1082 *ptr = 0x00;
1083 ptr++;
1084 extn = ptr;
1085 }
1086
1087 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
1088
1089 TWPartition* Part = Find_Partition_By_Path(label);
1090 if (Part == NULL)
1091 {
1092 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
1093 continue;
1094 }
1095
1096 Part->Backup_FileName = de->d_name;
1097 if (strlen(extn) > 3) {
1098 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
1099 }
1100
1101 // Now, we just need to find the correct label
Dees_Troye58d5262012-09-21 12:27:57 -04001102 if (Part->Backup_Path == "/system")
Dees_Troy63c8df72012-09-10 14:02:05 -04001103 tw_restore_system = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001104 if (Part->Backup_Path == "/data")
Dees_Troy63c8df72012-09-10 14:02:05 -04001105 tw_restore_data = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001106 if (Part->Backup_Path == "/cache")
Dees_Troy63c8df72012-09-10 14:02:05 -04001107 tw_restore_cache = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001108 if (Part->Backup_Path == "/recovery")
Dees_Troy63c8df72012-09-10 14:02:05 -04001109 tw_restore_recovery = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001110 if (Part->Backup_Path == "/boot")
Dees_Troy63c8df72012-09-10 14:02:05 -04001111 tw_restore_boot = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001112 if (Part->Backup_Path == "/and-sec")
Dees_Troy63c8df72012-09-10 14:02:05 -04001113 tw_restore_andsec = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001114 if (Part->Backup_Path == "/sd-ext")
Dees_Troy63c8df72012-09-10 14:02:05 -04001115 tw_restore_sdext = 1;
1116#ifdef SP1_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001117 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP1_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001118 tw_restore_sp1 = 1;
1119#endif
1120#ifdef SP2_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001121 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP2_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001122 tw_restore_sp2 = 1;
1123#endif
1124#ifdef SP3_NAME
Dees_Troyab10ee22012-09-21 14:27:30 -04001125 if (Part->Backup_Path == TWFunc::Get_Root_Path(EXPAND(SP3_NAME)))
Dees_Troy63c8df72012-09-10 14:02:05 -04001126 tw_restore_sp3 = 1;
1127#endif
1128 }
1129 closedir(d);
1130
1131 // Set the final values
1132 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
1133 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
1134 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
1135 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
1136 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
1137 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
1138 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
1139 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
1140 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
1141 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
1142
Dees_Troy51a0e822012-09-05 15:24:24 -04001143 return;
1144}
1145
1146int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001147 std::vector<TWPartition*>::iterator iter;
1148 int ret = false;
1149 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -04001150 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -04001151
1152 // Iterate through all partitions
1153 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -04001154 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troye58d5262012-09-21 12:27:57 -04001155 if (Path == "/and-sec")
1156 ret = (*iter)->Wipe_AndSec();
1157 else
1158 ret = (*iter)->Wipe();
Dees_Troy63c8df72012-09-10 14:02:05 -04001159 found = true;
1160 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
1161 (*iter)->Wipe();
1162 }
1163 }
1164 if (found) {
1165 return ret;
1166 } else
1167 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
1168 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001169}
1170
1171int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001172 TWPartition* Part = Find_Partition_By_Block(Block);
1173
1174 if (Part) {
1175 if (Part->Has_SubPartition) {
1176 std::vector<TWPartition*>::iterator subpart;
1177
1178 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1179 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1180 (*subpart)->Wipe();
1181 }
1182 return Part->Wipe();
1183 } else
1184 return Part->Wipe();
1185 }
1186 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1187 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001188}
1189
1190int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001191 TWPartition* Part = Find_Partition_By_Name(Name);
1192
1193 if (Part) {
1194 if (Part->Has_SubPartition) {
1195 std::vector<TWPartition*>::iterator subpart;
1196
1197 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1198 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1199 (*subpart)->Wipe();
1200 }
1201 return Part->Wipe();
1202 } else
1203 return Part->Wipe();
1204 }
1205 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1206 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001207}
1208
1209int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001210 std::vector<TWPartition*>::iterator iter;
1211 int ret = true;
1212
1213 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001214 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001215 if (!(*iter)->Wipe())
1216 ret = false;
1217 }
1218 }
1219 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001220}
1221
Dees_Troy38bd7602012-09-14 13:33:53 -04001222int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1223 struct stat st;
1224
1225 if (!Mount_By_Path("/data", true))
1226 return false;
1227
1228 if (!Mount_By_Path("/cache", true))
1229 return false;
1230
1231 ui_print("\nWiping Dalvik Cache Directories...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001232 system("rm -rf /data/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001233 ui_print("Cleaned: /data/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001234 system("rm -rf /cache/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001235 ui_print("Cleaned: /cache/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001236 system("rm -rf /cache/dc");
Dees_Troy38bd7602012-09-14 13:33:53 -04001237 ui_print("Cleaned: /cache/dc\n");
1238
1239 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1240 if (sdext != NULL) {
1241 if (sdext->Is_Present && sdext->Mount(false)) {
1242 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001243 system("rm -rf /sd-ext/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001244 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1245 }
1246 }
1247 }
1248 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1249 return true;
1250}
1251
1252int TWPartitionManager::Wipe_Rotate_Data(void) {
1253 if (!Mount_By_Path("/data", true))
1254 return false;
1255
Dees_Troy8170a922012-09-18 15:40:25 -04001256 system("rm -r /data/misc/akmd*");
1257 system("rm -r /data/misc/rild*");
1258 system("rm -r /data/misc/rild*");
Dees_Troy38bd7602012-09-14 13:33:53 -04001259 ui_print("Rotation data wiped.\n");
1260 return true;
1261}
1262
1263int TWPartitionManager::Wipe_Battery_Stats(void) {
1264 struct stat st;
1265
1266 if (!Mount_By_Path("/data", true))
1267 return false;
1268
1269 if (0 != stat("/data/system/batterystats.bin", &st)) {
1270 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1271 } else {
1272 remove("/data/system/batterystats.bin");
1273 ui_print("Cleared battery stats.\n");
1274 }
1275 return true;
1276}
1277
1278int TWPartitionManager::Format_Data(void) {
1279 TWPartition* dat = Find_Partition_By_Path("/data");
1280
1281 if (dat != NULL) {
1282 if (!dat->UnMount(true))
1283 return false;
1284
1285 return dat->Wipe_Encryption();
1286 } else {
1287 LOGE("Unable to locate /data.\n");
1288 return false;
1289 }
1290 return false;
1291}
1292
1293int TWPartitionManager::Wipe_Media_From_Data(void) {
1294 TWPartition* dat = Find_Partition_By_Path("/data");
1295
1296 if (dat != NULL) {
1297 if (!dat->Has_Data_Media) {
1298 LOGE("This device does not have /data/media\n");
1299 return false;
1300 }
1301 if (!dat->Mount(true))
1302 return false;
1303
1304 ui_print("Wiping internal storage -- /data/media...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001305 system("rm -rf /data/media");
1306 system("cd /data && mkdir media && chmod 775 media");
Dees_Troy38bd7602012-09-14 13:33:53 -04001307 if (dat->Has_Data_Media) {
1308 dat->Recreate_Media_Folder();
1309 }
1310 return true;
1311 } else {
1312 LOGE("Unable to locate /data.\n");
1313 return false;
1314 }
1315 return false;
1316}
1317
Dees_Troy51a0e822012-09-05 15:24:24 -04001318void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001319 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001320 return;
1321}
1322
1323void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001324 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001325 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001326
Dees_Troy32c8eb82012-09-11 15:28:06 -04001327 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001328 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001329 if ((*iter)->Can_Be_Mounted) {
1330 (*iter)->Update_Size(true);
1331 if ((*iter)->Mount_Point == "/system") {
1332 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1333 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1334 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1335 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1336 } else if ((*iter)->Mount_Point == "/cache") {
1337 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1338 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1339 } else if ((*iter)->Mount_Point == "/sd-ext") {
1340 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1341 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1342 if ((*iter)->Backup_Size == 0) {
1343 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1344 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1345 } else
1346 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
Dees_Troye58d5262012-09-21 12:27:57 -04001347 } else if ((*iter)->Has_Android_Secure) {
Dees_Troy8170a922012-09-18 15:40:25 -04001348 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
Dees_Troye58d5262012-09-21 12:27:57 -04001349 DataManager::SetValue(TW_BACKUP_ANDSEC_SIZE, backup_display_size);
Dees_Troy8170a922012-09-18 15:40:25 -04001350 if ((*iter)->Backup_Size == 0) {
1351 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 0);
1352 DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
1353 } else
1354 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 1);
Dees_Troy51127312012-09-08 13:08:49 -04001355 }
Dees_Troyab10ee22012-09-21 14:27:30 -04001356#ifdef SP1_NAME
1357 if ((*iter)->Backup_Name == EXPAND(SP1_NAME)) {
1358 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1359 DataManager::SetValue(TW_BACKUP_SP1_SIZE, backup_display_size);
1360 }
1361#endif
1362#ifdef SP2_NAME
1363 if ((*iter)->Backup_Name == EXPAND(SP2_NAME)) {
1364 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1365 DataManager::SetValue(TW_BACKUP_SP2_SIZE, backup_display_size);
1366 }
1367#endif
1368#ifdef SP3_NAME
1369 if ((*iter)->Backup_Name == EXPAND(SP3_NAME)) {
1370 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1371 DataManager::SetValue(TW_BACKUP_SP3_SIZE, backup_display_size);
1372 }
1373#endif
Dees_Troy51127312012-09-08 13:08:49 -04001374 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001375 }
Dees_Troy51127312012-09-08 13:08:49 -04001376 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1377 string current_storage_path = DataManager::GetCurrentStoragePath();
1378 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
Dees_Troy8170a922012-09-18 15:40:25 -04001379 if (FreeStorage != NULL) {
1380 // Attempt to mount storage
1381 if (!FreeStorage->Mount(false)) {
1382 // We couldn't mount storage... check to see if we have dual storage
1383 int has_dual_storage;
1384 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual_storage);
1385 if (has_dual_storage == 1) {
1386 // We have dual storage, see if we're using the internal storage that should always be present
1387 if (current_storage_path == DataManager::GetSettingsStoragePath()) {
Dees_Troyab10ee22012-09-21 14:27:30 -04001388 if (!FreeStorage->Is_Encrypted) {
1389 // Not able to use internal, so error!
1390 LOGE("Unable to mount internal storage.\n");
1391 }
Dees_Troy8170a922012-09-18 15:40:25 -04001392 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1393 } else {
1394 // We were using external, flip to internal
1395 DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
1396 current_storage_path = DataManager::GetCurrentStoragePath();
1397 FreeStorage = Find_Partition_By_Path(current_storage_path);
1398 if (FreeStorage != NULL) {
1399 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1400 } else {
1401 LOGE("Unable to locate internal storage partition.\n");
1402 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1403 }
1404 }
1405 } else {
1406 // No dual storage and unable to mount storage, error!
1407 LOGE("Unable to mount storage.\n");
1408 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1409 }
1410 } else {
1411 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1412 }
1413 } else {
Dees_Troy51127312012-09-08 13:08:49 -04001414 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -04001415 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001416 if (!Write_Fstab())
1417 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001418 return;
1419}
1420
1421int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001422#ifdef TW_INCLUDE_CRYPTO
1423 int ret_val, password_len;
1424 char crypto_blkdev[255], cPassword[255];
1425 size_t result;
1426
1427 property_set("ro.crypto.state", "encrypted");
1428#ifdef TW_INCLUDE_JB_CRYPTO
1429 // No extra flags needed
1430#else
1431 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1432 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1433 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1434 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1435 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1436 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1437#endif
1438 strcpy(cPassword, Password.c_str());
1439 if (cryptfs_check_passwd(cPassword) != 0) {
1440 LOGE("Failed to decrypt data.\n");
1441 return -1;
1442 }
1443 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1444 if (strcmp(crypto_blkdev, "error") == 0) {
1445 LOGE("Error retrieving decrypted data block device.\n");
1446 } else {
1447 TWPartition* dat = Find_Partition_By_Path("/data");
1448 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001449 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001450 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1451 dat->Is_Decrypted = true;
1452 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001453 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001454 // Sleep for a bit so that the device will be ready
1455 sleep(1);
1456 Update_System_Details();
1457 } else
1458 LOGE("Unable to locate data partition.\n");
1459 }
1460 return 0;
1461#else
1462 LOGE("No crypto support was compiled into this build.\n");
1463 return -1;
1464#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001465 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001466}
1467
Dees_Troy38bd7602012-09-14 13:33:53 -04001468int TWPartitionManager::Fix_Permissions(void) {
1469 if (!Mount_By_Path("/data", true))
1470 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001471
Dees_Troy38bd7602012-09-14 13:33:53 -04001472 if (!Mount_By_Path("/system", true))
1473 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001474
Dees_Troy38bd7602012-09-14 13:33:53 -04001475 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001476 system("./sbin/fix_permissions.sh");
Dees_Troy38bd7602012-09-14 13:33:53 -04001477 ui_print("Done.\n\n");
1478 return true;
Dees_Troy4a2a1262012-09-18 09:33:47 -04001479}
Dees_Troy8170a922012-09-18 15:40:25 -04001480
1481//partial kangbang from system/vold
1482#ifndef CUSTOM_LUN_FILE
1483#define CUSTOM_LUN_FILE "/sys/devices/platform/usb_mass_storage/lun%d/file"
1484#endif
1485
1486int TWPartitionManager::usb_storage_enable(void) {
1487 int fd, has_dual, has_data_media;
1488 char lun_file[255];
1489 TWPartition* Part;
1490 string ext_path;
1491
1492 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual);
1493 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
1494 if (has_dual == 1 && has_data_media == 0) {
1495 Part = Find_Partition_By_Path(DataManager::GetSettingsStoragePath());
1496 if (Part == NULL) {
1497 LOGE("Unable to locate volume information.");
1498 return false;
1499 }
1500 if (!Part->UnMount(true))
1501 return false;
1502
1503 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1504 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1505 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1506 return false;
1507 }
1508
1509 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1510 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1511 close(fd);
1512 return false;
1513 }
1514 close(fd);
1515
1516 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1517 Part = Find_Partition_By_Path(ext_path);
1518 if (Part == NULL) {
1519 LOGE("Unable to locate volume information.\n");
1520 return false;
1521 }
1522 if (!Part->UnMount(true))
1523 return false;
1524
1525 sprintf(lun_file, CUSTOM_LUN_FILE, 1);
1526 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1527 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1528 return false;
1529 }
1530
1531 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1532 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1533 close(fd);
1534 return false;
1535 }
1536 close(fd);
1537 } else {
1538 if (has_data_media == 0)
1539 ext_path = DataManager::GetCurrentStoragePath();
1540 else
1541 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1542
1543 Part = Find_Partition_By_Path(ext_path);
1544 if (Part == NULL) {
1545 LOGE("Unable to locate volume information.\n");
1546 return false;
1547 }
1548 if (!Part->UnMount(true))
1549 return false;
1550
1551 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1552
1553 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1554 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1555 return false;
1556 }
1557
1558 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1559 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1560 close(fd);
1561 return false;
1562 }
1563 close(fd);
1564 }
1565 return true;
1566}
1567
1568int TWPartitionManager::usb_storage_disable(void) {
1569 int fd, index;
1570 char lun_file[255];
1571
1572 for (index=0; index<2; index++) {
1573 sprintf(lun_file, CUSTOM_LUN_FILE, index);
1574
1575 if ((fd = open(lun_file, O_WRONLY)) < 0) {
Dees_Troye58d5262012-09-21 12:27:57 -04001576 Mount_All_Storage();
1577 Update_System_Details();
1578 if (index == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001579 LOGE("Unable to open ums lunfile '%s': (%s)", lun_file, strerror(errno));
Dees_Troye58d5262012-09-21 12:27:57 -04001580 return false;
1581 } else
1582 return true;
Dees_Troy8170a922012-09-18 15:40:25 -04001583 }
1584
1585 char ch = 0;
1586 if (write(fd, &ch, 1) < 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001587 close(fd);
Dees_Troye58d5262012-09-21 12:27:57 -04001588 Mount_All_Storage();
1589 Update_System_Details();
1590 if (index == 0) {
1591 LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
1592 return false;
1593 } else
1594 return true;
Dees_Troy8170a922012-09-18 15:40:25 -04001595 }
1596
1597 close(fd);
1598 }
Dees_Troye58d5262012-09-21 12:27:57 -04001599 Mount_All_Storage();
1600 Update_System_Details();
Dees_Troy8170a922012-09-18 15:40:25 -04001601 return true;
Dees_Troy812660f2012-09-20 09:55:17 -04001602}
1603
1604void TWPartitionManager::Mount_All_Storage(void) {
1605 std::vector<TWPartition*>::iterator iter;
1606
1607 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
1608 if ((*iter)->Is_Storage)
1609 (*iter)->Mount(false);
1610 }
Dees_Troy8170a922012-09-18 15:40:25 -04001611}