blob: b2bbf8e8e1ea8f91d978d61a1501f3115e51fed2 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001/* Partition Management classes for TWRP
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 *
17 * The code was written from scratch by Dees_Troy dees_troy at
18 * yahoo
19 *
20 * Copyright (c) 2012
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/stat.h>
27#include <sys/vfs.h>
28#include <unistd.h>
Dees_Troy5bf43922012-09-07 16:07:55 -040029#include <vector>
Dees_Troy63c8df72012-09-10 14:02:05 -040030#include <dirent.h>
31#include <time.h>
Dees_Troy8170a922012-09-18 15:40:25 -040032#include <errno.h>
33#include <fcntl.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040034
35#include "variables.h"
36#include "common.h"
37#include "partitions.hpp"
Dees_Troy5bf43922012-09-07 16:07:55 -040038#include "data.hpp"
Dees_Troy38bd7602012-09-14 13:33:53 -040039#include "twrp-functions.hpp"
40
Dees_Troy5bf43922012-09-07 16:07:55 -040041#ifdef TW_INCLUDE_CRYPTO
42 #ifdef TW_INCLUDE_JB_CRYPTO
43 #include "crypto/jb/cryptfs.h"
44 #else
45 #include "crypto/ics/cryptfs.h"
46 #endif
47 #include "cutils/properties.h"
48#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040049
50int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -040051 FILE *fstabFile;
52 char fstab_line[MAX_FSTAB_LINE_LENGTH];
53
54 fstabFile = fopen(Fstab_Filename.c_str(), "rt");
55 if (fstabFile == NULL) {
56 LOGE("Critical Error: Unable to open fstab at '%s'.\n", Fstab_Filename.c_str());
57 return false;
58 }
59
60 while (fgets(fstab_line, sizeof(fstab_line), fstabFile) != NULL) {
61 if (fstab_line[0] != '/')
62 continue;
63
64 TWPartition* partition = new TWPartition();
65 string line(fstab_line);
66 if (partition->Process_Fstab_Line(line, Display_Error)) {
67 Partitions.push_back(partition);
68 } else {
69 delete partition;
70 }
71 }
72 fclose(fstabFile);
73 if (!Write_Fstab()) {
74 if (Display_Error)
75 LOGE("Error creating fstab\n");
76 else
77 LOGI("Error creating fstab\n");
78 }
Dees_Troy51127312012-09-08 13:08:49 -040079 Update_System_Details();
Dees_Troy5bf43922012-09-07 16:07:55 -040080 return true;
81}
82
83int TWPartitionManager::Write_Fstab(void) {
84 FILE *fp;
85 std::vector<TWPartition*>::iterator iter;
86 string Line;
87
88 fp = fopen("/etc/fstab", "w");
89 if (fp == NULL) {
Dees_Troy63c8df72012-09-10 14:02:05 -040090 LOGI("Can not open /etc/fstab.\n");
Dees_Troy5bf43922012-09-07 16:07:55 -040091 return false;
92 }
Dees_Troy63c8df72012-09-10 14:02:05 -040093 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -040094 if ((*iter)->Can_Be_Mounted) {
Dees_Troy38bd7602012-09-14 13:33:53 -040095 Line = (*iter)->Actual_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
Dees_Troy5bf43922012-09-07 16:07:55 -040096 fputs(Line.c_str(), fp);
Dees_Troy51127312012-09-08 13:08:49 -040097 // Handle subpartition tracking
98 if ((*iter)->Is_SubPartition) {
99 TWPartition* ParentPartition = Find_Partition_By_Path((*iter)->SubPartition_Of);
100 if (ParentPartition)
101 ParentPartition->Has_SubPartition = true;
102 else
103 LOGE("Unable to locate parent partition '%s' of '%s'\n", (*iter)->SubPartition_Of.c_str(), (*iter)->Mount_Point.c_str());
104 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400105 }
106 }
107 fclose(fp);
108 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400109}
110
Dees_Troy8170a922012-09-18 15:40:25 -0400111void TWPartitionManager::Output_Partition_Logging(void) {
112 std::vector<TWPartition*>::iterator iter;
113
114 printf("\n\nPartition Logs:\n");
115 for (iter = Partitions.begin(); iter != Partitions.end(); iter++)
116 Output_Partition((*iter));
117}
118
119void TWPartitionManager::Output_Partition(TWPartition* Part) {
120 unsigned long long mb = 1048576;
121
122 if (Part->Can_Be_Mounted) {
123 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));
124 if (Part->Can_Be_Wiped)
125 printf("Can_Be_Wiped ");
126 if (Part->Wipe_During_Factory_Reset)
127 printf("Wipe_During_Factory_Reset ");
128 if (Part->Wipe_Available_in_GUI)
129 printf("Wipe_Available_in_GUI ");
130 if (Part->Is_SubPartition)
131 printf("Is_SubPartition ");
132 if (Part->Has_SubPartition)
133 printf("Has_SubPartition ");
134 if (Part->Removable)
135 printf("Removable ");
136 if (Part->Is_Present)
137 printf("IsPresent ");
138 if (Part->Can_Be_Encrypted)
139 printf("Can_Be_Encrypted ");
140 if (Part->Is_Encrypted)
141 printf("Is_Encrypted ");
142 if (Part->Is_Decrypted)
143 printf("Is_Decrypted ");
144 if (Part->Has_Data_Media)
145 printf("Has_Data_Media ");
146 if (Part->Is_Storage)
147 printf("Is_Storage ");
148 printf("\n");
149 if (!Part->SubPartition_Of.empty())
150 printf(" SubPartition_Of: %s\n", Part->SubPartition_Of.c_str());
151 if (!Part->Symlink_Path.empty())
152 printf(" Symlink_Path: %s\n", Part->Symlink_Path.c_str());
153 if (!Part->Symlink_Mount_Point.empty())
154 printf(" Symlink_Mount_Point: %s\n", Part->Symlink_Mount_Point.c_str());
155 if (!Part->Primary_Block_Device.empty())
156 printf(" Primary_Block_Device: %s\n", Part->Primary_Block_Device.c_str());
157 if (!Part->Alternate_Block_Device.empty())
158 printf(" Alternate_Block_Device: %s\n", Part->Alternate_Block_Device.c_str());
159 if (!Part->Decrypted_Block_Device.empty())
160 printf(" Decrypted_Block_Device: %s\n", Part->Decrypted_Block_Device.c_str());
161 if (Part->Length != 0)
162 printf(" Length: %i\n", Part->Length);
163 if (!Part->Display_Name.empty())
164 printf(" Display_Name: %s\n", Part->Display_Name.c_str());
165 if (!Part->Backup_Name.empty())
166 printf(" Backup_Name: %s\n", Part->Backup_Name.c_str());
167 if (!Part->Backup_FileName.empty())
168 printf(" Backup_FileName: %s\n", Part->Backup_FileName.c_str());
169 if (!Part->MTD_Name.empty())
170 printf(" MTD_Name: %s\n", Part->MTD_Name.c_str());
171 if (!Part->Storage_Path.empty())
172 printf(" Storage_Path: %s\n", Part->Storage_Path.c_str());
173 if (!Part->Current_File_System.empty())
174 printf(" Current_File_System: %s\n", Part->Current_File_System.c_str());
175 if (!Part->Fstab_File_System.empty())
176 printf(" Fstab_File_System: %s\n", Part->Fstab_File_System.c_str());
177 if (Part->Format_Block_Size != 0)
178 printf(" Format_Block_Size: %i\n", Part->Format_Block_Size);
179 } else {
180 printf("%s | %s | Size: %iMB\n", Part->Mount_Point.c_str(), Part->Actual_Block_Device.c_str(), (int)(Part->Size / mb));
181 }
182 string back_meth = Part->Backup_Method_By_Name();
183 printf(" Backup_Method: %s\n\n", back_meth.c_str());
184}
185
Dees_Troy51a0e822012-09-05 15:24:24 -0400186int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400187 std::vector<TWPartition*>::iterator iter;
188 int ret = false;
189 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400190 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400191
Dees_Troy43d8b002012-09-17 16:00:01 -0400192 if (Local_Path == "/tmp")
193 return true;
194
Dees_Troy5bf43922012-09-07 16:07:55 -0400195 // Iterate through all partitions
196 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400197 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400198 ret = (*iter)->Mount(Display_Error);
199 found = true;
Dees_Troy51127312012-09-08 13:08:49 -0400200 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400201 (*iter)->Mount(Display_Error);
Dees_Troy51127312012-09-08 13:08:49 -0400202 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400203 }
204 if (found) {
205 return ret;
206 } else if (Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400207 LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400208 } else {
Dees_Troy51127312012-09-08 13:08:49 -0400209 LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400210 }
211 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400212}
213
214int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400215 TWPartition* Part = Find_Partition_By_Block(Block);
Dees_Troy5bf43922012-09-07 16:07:55 -0400216
Dees_Troy51127312012-09-08 13:08:49 -0400217 if (Part) {
218 if (Part->Has_SubPartition) {
219 std::vector<TWPartition*>::iterator subpart;
220
221 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
222 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
223 (*subpart)->Mount(Display_Error);
224 }
225 return Part->Mount(Display_Error);
226 } else
227 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400228 }
229 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400230 LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400231 else
Dees_Troy51127312012-09-08 13:08:49 -0400232 LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400233 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400234}
235
236int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400237 TWPartition* Part = Find_Partition_By_Name(Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400238
Dees_Troy51127312012-09-08 13:08:49 -0400239 if (Part) {
240 if (Part->Has_SubPartition) {
241 std::vector<TWPartition*>::iterator subpart;
242
243 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
244 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
245 (*subpart)->Mount(Display_Error);
246 }
247 return Part->Mount(Display_Error);
248 } else
249 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400250 }
251 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400252 LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400253 else
Dees_Troy51127312012-09-08 13:08:49 -0400254 LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400255 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400256}
257
258int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400259 std::vector<TWPartition*>::iterator iter;
260 int ret = false;
261 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400262 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy51127312012-09-08 13:08:49 -0400263
264 // Iterate through all partitions
265 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400266 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy51127312012-09-08 13:08:49 -0400267 ret = (*iter)->UnMount(Display_Error);
268 found = true;
269 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
270 (*iter)->UnMount(Display_Error);
271 }
272 }
273 if (found) {
274 return ret;
275 } else if (Display_Error) {
276 LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
277 } else {
278 LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
279 }
280 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400281}
282
283int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400284 TWPartition* Part = Find_Partition_By_Block(Block);
285
286 if (Part) {
287 if (Part->Has_SubPartition) {
288 std::vector<TWPartition*>::iterator subpart;
289
290 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
291 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
292 (*subpart)->UnMount(Display_Error);
293 }
294 return Part->UnMount(Display_Error);
295 } else
296 return Part->UnMount(Display_Error);
297 }
298 if (Display_Error)
299 LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
300 else
301 LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
302 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400303}
304
305int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400306 TWPartition* Part = Find_Partition_By_Name(Name);
307
308 if (Part) {
309 if (Part->Has_SubPartition) {
310 std::vector<TWPartition*>::iterator subpart;
311
312 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
313 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
314 (*subpart)->UnMount(Display_Error);
315 }
316 return Part->UnMount(Display_Error);
317 } else
318 return Part->UnMount(Display_Error);
319 }
320 if (Display_Error)
321 LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
322 else
323 LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
324 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400325}
326
327int TWPartitionManager::Is_Mounted_By_Path(string Path) {
Dees_Troy51127312012-09-08 13:08:49 -0400328 TWPartition* Part = Find_Partition_By_Path(Path);
329
330 if (Part)
331 return Part->Is_Mounted();
332 else
333 LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
334 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400335}
336
337int TWPartitionManager::Is_Mounted_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400338 TWPartition* Part = Find_Partition_By_Block(Block);
339
340 if (Part)
341 return Part->Is_Mounted();
342 else
343 LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
344 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400345}
346
347int TWPartitionManager::Is_Mounted_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400348 TWPartition* Part = Find_Partition_By_Name(Name);
349
350 if (Part)
351 return Part->Is_Mounted();
352 else
353 LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
354 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400355}
356
Dees_Troy5bf43922012-09-07 16:07:55 -0400357int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400358 string current_storage_path = DataManager::GetCurrentStoragePath();
359
360 if (Mount_By_Path(current_storage_path, Display_Error)) {
361 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
362 if (FreeStorage)
363 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
364 return true;
365 }
366 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400367}
368
Dees_Troy5bf43922012-09-07 16:07:55 -0400369int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
370 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
371}
372
373TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
374 std::vector<TWPartition*>::iterator iter;
Dees_Troy38bd7602012-09-14 13:33:53 -0400375 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400376
377 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400378 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
Dees_Troy5bf43922012-09-07 16:07:55 -0400379 return (*iter);
380 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400381 return NULL;
382}
383
Dees_Troy5bf43922012-09-07 16:07:55 -0400384TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400385 std::vector<TWPartition*>::iterator iter;
386
387 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400388 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 -0400389 return (*iter);
390 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400391 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400392}
393
394TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400395 std::vector<TWPartition*>::iterator iter;
396
397 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
398 if ((*iter)->Display_Name == Name)
399 return (*iter);
400 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400401 return NULL;
402}
Dees_Troy51a0e822012-09-05 15:24:24 -0400403
Dees_Troy43d8b002012-09-17 16:00:01 -0400404bool TWPartitionManager::Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename)
405{
406 char command[512];
407 string Full_File = Backup_Folder + Backup_Filename;
408
Dees_Troy4a2a1262012-09-18 09:33:47 -0400409 if (!generate_md5)
Dees_Troy43d8b002012-09-17 16:00:01 -0400410 return true;
Dees_Troy43d8b002012-09-17 16:00:01 -0400411
Dees_Troy4a2a1262012-09-18 09:33:47 -0400412 ui_print(" * Generating md5...");
Dees_Troy43d8b002012-09-17 16:00:01 -0400413
414 if (TWFunc::Path_Exists(Full_File)) {
415 sprintf(command, "cd '%s' && md5sum %s > %s.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), Backup_Filename.c_str());
416 LOGI("MD5 command is: '%s'\n", command);
417 if (system(command) == 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400418 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400419 return true;
420 } else {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400421 ui_print("MD5 Error!\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400422 return false;
423 }
424 } else {
425 char filename[512];
426 int index = 0;
427
428 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400429 while (TWFunc::Path_Exists(filename) == true) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400430 sprintf(command, "cd '%s' && md5sum %s%03i > %s%03i.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), index, Backup_Filename.c_str(), index);
431 LOGI("MD5 command is: '%s'\n", command);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400432 if (system(command) != 0) {
433 ui_print("MD5 Error.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400434 return false;
435 }
436 index++;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400437 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy43d8b002012-09-17 16:00:01 -0400438 }
439 if (index == 0) {
440 LOGE("Backup file: '%s' not found!\n", filename);
441 return false;
442 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400443 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400444 }
445 return true;
446}
447
448bool 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) {
449 time_t start, stop;
450
451 if (Part == NULL)
452 return true;
453
454 time(&start);
455
456 if (Part->Backup(Backup_Folder)) {
Dees_Troy8170a922012-09-18 15:40:25 -0400457 if (Part->Has_SubPartition) {
458 std::vector<TWPartition*>::iterator subpart;
459
460 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
461 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
462 if (!(*subpart)->Backup(Backup_Folder))
463 return false;
464 if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
465 return false;
466 }
467 }
468 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400469 time(&stop);
470 if (Part->Backup_Method == 1) {
471 *file_bytes_remaining -= Part->Backup_Size;
472 *file_time += (int) difftime(stop, start);
473 } else {
474 *img_bytes_remaining -= Part->Backup_Size;
475 *img_time += (int) difftime(stop, start);
476 }
477 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
478 } else {
479 return false;
480 }
481}
482
483int TWPartitionManager::Run_Backup(void) {
484 int check, do_md5, partition_count = 0;
485 string Backup_Folder, Backup_Name, Full_Backup_Path;
Dees_Troy8170a922012-09-18 15:40:25 -0400486 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 -0400487 unsigned long img_time = 0, file_time = 0;
488 TWPartition* backup_sys = NULL;
489 TWPartition* backup_data = NULL;
490 TWPartition* backup_cache = NULL;
491 TWPartition* backup_recovery = NULL;
492 TWPartition* backup_boot = NULL;
493 TWPartition* backup_andsec = NULL;
494 TWPartition* backup_sdext = NULL;
495 TWPartition* backup_sp1 = NULL;
496 TWPartition* backup_sp2 = NULL;
497 TWPartition* backup_sp3 = NULL;
498 TWPartition* storage = NULL;
Dees_Troy8170a922012-09-18 15:40:25 -0400499 std::vector<TWPartition*>::iterator subpart;
Dees_Troy43d8b002012-09-17 16:00:01 -0400500 struct tm *t;
501 time_t start, stop, seconds, total_start, total_stop;
502 seconds = time(0);
503 t = localtime(&seconds);
504
505 time(&total_start);
506
507 Update_System_Details();
508
509 if (!Mount_Current_Storage(true))
510 return false;
511
512 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400513 if (do_md5 == 0)
Dees_Troy43d8b002012-09-17 16:00:01 -0400514 do_md5 = true;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400515
Dees_Troy43d8b002012-09-17 16:00:01 -0400516 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
517 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
518 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
519 char timestamp[255];
520 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);
521 Backup_Name = timestamp;
522 }
523 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
524 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
525 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
526
527 ui_print("\n[BACKUP STARTED]\n");
528 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
529 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
530 LOGE("Failed to make backup folder.\n");
531 return false;
532 }
533
534 LOGI("Calculating backup details...\n");
535 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
536 if (check) {
537 backup_sys = Find_Partition_By_Path("/system");
538 if (backup_sys != NULL) {
539 partition_count++;
540 if (backup_sys->Backup_Method == 1)
541 file_bytes += backup_sys->Backup_Size;
542 else
543 img_bytes += backup_sys->Backup_Size;
544 } else {
545 LOGE("Unable to locate system partition.\n");
546 return false;
547 }
548 }
549 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
550 if (check) {
551 backup_data = Find_Partition_By_Path("/data");
552 if (backup_data != NULL) {
553 partition_count++;
Dees_Troy8170a922012-09-18 15:40:25 -0400554 subpart_size = 0;
555 if (backup_data->Has_SubPartition) {
556 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
557 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_data->Mount_Point)
558 subpart_size += (*subpart)->Backup_Size;
559 }
560 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400561 if (backup_data->Backup_Method == 1)
Dees_Troy8170a922012-09-18 15:40:25 -0400562 file_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400563 else
Dees_Troy8170a922012-09-18 15:40:25 -0400564 img_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400565 } else {
566 LOGE("Unable to locate data partition.\n");
567 return false;
568 }
569 }
570 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
571 if (check) {
572 backup_cache = Find_Partition_By_Path("/cache");
573 if (backup_cache != NULL) {
574 partition_count++;
575 if (backup_cache->Backup_Method == 1)
576 file_bytes += backup_cache->Backup_Size;
577 else
578 img_bytes += backup_cache->Backup_Size;
579 } else {
580 LOGE("Unable to locate cache partition.\n");
581 return false;
582 }
583 }
584 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
585 if (check) {
586 backup_recovery = Find_Partition_By_Path("/recovery");
587 if (backup_recovery != NULL) {
588 partition_count++;
589 if (backup_recovery->Backup_Method == 1)
590 file_bytes += backup_recovery->Backup_Size;
591 else
592 img_bytes += backup_recovery->Backup_Size;
593 } else {
594 LOGE("Unable to locate recovery partition.\n");
595 return false;
596 }
597 }
598 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
599 if (check) {
600 backup_boot = Find_Partition_By_Path("/boot");
601 if (backup_boot != NULL) {
602 partition_count++;
603 if (backup_boot->Backup_Method == 1)
604 file_bytes += backup_boot->Backup_Size;
605 else
606 img_bytes += backup_boot->Backup_Size;
607 } else {
608 LOGE("Unable to locate boot partition.\n");
609 return false;
610 }
611 }
612 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
613 if (check) {
614 backup_andsec = Find_Partition_By_Path("/and-sec");
615 if (backup_andsec != NULL) {
616 partition_count++;
617 if (backup_andsec->Backup_Method == 1)
618 file_bytes += backup_andsec->Backup_Size;
619 else
620 img_bytes += backup_andsec->Backup_Size;
621 } else {
622 LOGE("Unable to locate android secure partition.\n");
623 return false;
624 }
625 }
626 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
627 if (check) {
628 backup_sdext = Find_Partition_By_Path("/sd-ext");
629 if (backup_sdext != NULL) {
630 partition_count++;
631 if (backup_sdext->Backup_Method == 1)
632 file_bytes += backup_sdext->Backup_Size;
633 else
634 img_bytes += backup_sdext->Backup_Size;
635 } else {
636 LOGE("Unable to locate sd-ext partition.\n");
637 return false;
638 }
639 }
640#ifdef SP1_NAME
641 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
642 if (check) {
643 backup_sp1 = Find_Partition_By_Path(SP1_NAME);
644 if (backup_sp1 != NULL) {
645 partition_count++;
646 if (backup_sp1->Backup_Method == 1)
647 file_bytes += backup_sp1->Backup_Size;
648 else
649 img_bytes += backup_sp1->Backup_Size;
650 } else {
651 LOGE("Unable to locate %s partition.\n", SP1_NAME);
652 return false;
653 }
654 }
655#endif
656#ifdef SP2_NAME
657 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
658 if (check) {
659 backup_sp2 = Find_Partition_By_Path(SP2_NAME);
660 if (backup_sp2 != NULL) {
661 partition_count++;
662 if (backup_sp2->Backup_Method == 1)
663 file_bytes += backup_sp2->Backup_Size;
664 else
665 img_bytes += backup_sp2->Backup_Size;
666 } else {
667 LOGE("Unable to locate %s partition.\n", SP2_NAME);
668 return false;
669 }
670 }
671#endif
672#ifdef SP3_NAME
673 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
674 if (check) {
675 backup_sp3 = Find_Partition_By_Path(SP3_NAME);
676 if (backup_sp3 != NULL) {
677 partition_count++;
678 if (backup_sp3->Backup_Method == 1)
679 file_bytes += backup_sp3->Backup_Size;
680 else
681 img_bytes += backup_sp3->Backup_Size;
682 } else {
683 LOGE("Unable to locate %s partition.\n", SP3_NAME);
684 return false;
685 }
686 }
687#endif
688
689 if (partition_count == 0) {
690 ui_print("No partitions selected for backup.\n");
691 return false;
692 }
693 total_bytes = file_bytes + img_bytes;
694 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
695 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
696 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
697 if (storage != NULL) {
698 free_space = storage->Free;
699 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
700 } else {
701 LOGE("Unable to locate storage device.\n");
702 return false;
703 }
704 if (free_space + (32 * 1024 * 1024) < total_bytes) {
705 // We require an extra 32MB just in case
706 LOGE("Not enough free space on storage.\n");
707 return false;
708 }
709 img_bytes_remaining = img_bytes;
710 file_bytes_remaining = file_bytes;
711
712 if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
713 return false;
714 if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
715 return false;
716 if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
717 return false;
718 if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
719 return false;
720 if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
721 return false;
722 if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
723 return false;
724 if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
725 return false;
726 if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
727 return false;
728 if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
729 return false;
730 if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
731 return false;
732
733 // Average BPS
734 if (img_time == 0)
735 img_time = 1;
736 if (file_time == 0)
737 file_time = 1;
738 unsigned long int img_bps = img_bytes / img_time;
739 unsigned long int file_bps = file_bytes / file_time;
740
741 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
742 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
743
744 time(&total_stop);
745 int total_time = (int) difftime(total_stop, total_start);
746 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
747 actual_backup_size /= (1024LLU * 1024LLU);
748
749 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
750 Update_System_Details();
751 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
752 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400753}
754
Dees_Troy4a2a1262012-09-18 09:33:47 -0400755bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name) {
756 time_t Start, Stop;
757 time(&Start);
758 if (!Part->Restore(Restore_Name))
759 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400760 if (Part->Has_SubPartition) {
761 std::vector<TWPartition*>::iterator subpart;
762
763 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
764 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
765 if (!(*subpart)->Restore(Restore_Name))
766 return false;
767 }
768 }
769 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400770 time(&Stop);
771 ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
772 return true;
773}
774
Dees_Troy51a0e822012-09-05 15:24:24 -0400775int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400776 int check_md5, check, partition_count = 0;
777 TWPartition* restore_sys = NULL;
778 TWPartition* restore_data = NULL;
779 TWPartition* restore_cache = NULL;
780 TWPartition* restore_boot = NULL;
781 TWPartition* restore_andsec = NULL;
782 TWPartition* restore_sdext = NULL;
783 TWPartition* restore_sp1 = NULL;
784 TWPartition* restore_sp2 = NULL;
785 TWPartition* restore_sp3 = NULL;
786 time_t rStart, rStop;
787 time(&rStart);
Dees_Troy43d8b002012-09-17 16:00:01 -0400788
Dees_Troy4a2a1262012-09-18 09:33:47 -0400789 ui_print("\n[RESTORE STARTED]\n\n");
790 ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400791
Dees_Troy4a2a1262012-09-18 09:33:47 -0400792 if (!Mount_Current_Storage(true))
793 return false;
794
795 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
796 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
Dees_Troy63c8df72012-09-10 14:02:05 -0400797 if (check > 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400798 restore_sys = Find_Partition_By_Path("/system");
799 if (restore_sys == NULL) {
800 LOGE("Unable to locate system partition.\n");
801 return false;
802 }
803 partition_count++;
804 }
805 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
806 if (check > 0) {
807 restore_data = Find_Partition_By_Path("/data");
808 if (restore_data == NULL) {
809 LOGE("Unable to locate data partition.\n");
810 return false;
811 }
812 partition_count++;
813 }
814 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
815 if (check > 0) {
816 restore_cache = Find_Partition_By_Path("/cache");
817 if (restore_cache == NULL) {
818 LOGE("Unable to locate cache partition.\n");
819 return false;
820 }
821 partition_count++;
822 }
823 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
824 if (check > 0) {
825 restore_boot = Find_Partition_By_Path("/boot");
826 if (restore_boot == NULL) {
827 LOGE("Unable to locate boot partition.\n");
828 return false;
829 }
830 partition_count++;
831 }
832 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
833 if (check > 0) {
834 restore_andsec = Find_Partition_By_Path("/and-sec");
835 if (restore_andsec == NULL) {
836 LOGE("Unable to locate android secure partition.\n");
837 return false;
838 }
839 partition_count++;
840 }
841 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
842 if (check > 0) {
843 restore_sdext = Find_Partition_By_Path("/sd-ext");
844 if (restore_sdext == NULL) {
845 LOGE("Unable to locate sd-ext partition.\n");
846 return false;
847 }
848 partition_count++;
849 }
850#ifdef SP1_NAME
851 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
852 if (check > 0) {
853 restore_sp1 = Find_Partition_By_Path(SP1_NAME);
854 if (restore_sp1 == NULL) {
855 LOGE("Unable to locate %s partition.\n", SP1_NAME);
856 return false;
857 }
858 partition_count++;
859 }
860#endif
861#ifdef SP2_NAME
862 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
863 if (check > 0) {
864 restore_sp2 = Find_Partition_By_Path(SP2_NAME);
865 if (restore_sp2 == NULL) {
866 LOGE("Unable to locate %s partition.\n", SP2_NAME);
867 return false;
868 }
869 partition_count++;
870 }
871#endif
872#ifdef SP3_NAME
873 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
874 if (check > 0) {
875 restore_sp3 = Find_Partition_By_Path(SP3_NAME);
876 if (restore_sp3 == NULL) {
877 LOGE("Unable to locate %s partition.\n", SP3_NAME);
878 return false;
879 }
880 partition_count++;
881 }
882#endif
883
884 if (partition_count == 0) {
885 LOGE("No partitions selected for restore.\n");
886 return false;
887 }
888
889 if (check_md5 > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400890 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
Dees_Troy4a2a1262012-09-18 09:33:47 -0400891 ui_print("Verifying MD5...\n");
892 if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
893 return false;
894 if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
895 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400896 if (restore_data != NULL && restore_data->Has_SubPartition) {
897 std::vector<TWPartition*>::iterator subpart;
898
899 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
900 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_data->Mount_Point) {
901 if (!(*subpart)->Check_MD5(Restore_Name))
902 return false;
903 }
904 }
905 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400906 if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
907 return false;
908 if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
909 return false;
910 if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
911 return false;
912 if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
913 return false;
914 if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
915 return false;
916 if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
917 return false;
918 if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
919 return false;
920 ui_print("Done verifying MD5.\n");
921 } else
922 ui_print("Skipping MD5 check based on user setting.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400923
Dees_Troy4a2a1262012-09-18 09:33:47 -0400924 ui_print("Restoring %i partitions...\n", partition_count);
925 if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name))
926 return false;
927 if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name))
928 return false;
929 if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name))
930 return false;
931 if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name))
932 return false;
933 if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name))
934 return false;
935 if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name))
936 return false;
937 if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name))
938 return false;
939 if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name))
940 return false;
941 if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name))
942 return false;
Dees_Troy43d8b002012-09-17 16:00:01 -0400943
Dees_Troy43d8b002012-09-17 16:00:01 -0400944 Update_System_Details();
Dees_Troy4a2a1262012-09-18 09:33:47 -0400945 time(&rStop);
946 ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
Dees_Troy63c8df72012-09-10 14:02:05 -0400947 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400948}
949
950void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400951 // Start with the default values
952 int tw_restore_system = -1;
953 int tw_restore_data = -1;
954 int tw_restore_cache = -1;
955 int tw_restore_recovery = -1;
956 int tw_restore_boot = -1;
957 int tw_restore_andsec = -1;
958 int tw_restore_sdext = -1;
959 int tw_restore_sp1 = -1;
960 int tw_restore_sp2 = -1;
961 int tw_restore_sp3 = -1;
962 bool get_date = true;
963
964 DIR* d;
965 d = opendir(Restore_Name.c_str());
966 if (d == NULL)
967 {
968 LOGE("Error opening %s\n", Restore_Name.c_str());
969 return;
970 }
971
972 struct dirent* de;
973 while ((de = readdir(d)) != NULL)
974 {
975 // Strip off three components
976 char str[256];
977 char* label;
978 char* fstype = NULL;
979 char* extn = NULL;
980 char* ptr;
981
982 strcpy(str, de->d_name);
983 if (strlen(str) <= 2)
984 continue;
985
986 if (get_date) {
987 char file_path[255];
988 struct stat st;
989
990 strcpy(file_path, Restore_Name.c_str());
991 strcat(file_path, "/");
992 strcat(file_path, str);
993 stat(file_path, &st);
994 string backup_date = ctime((const time_t*)(&st.st_mtime));
995 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
996 get_date = false;
997 }
998
999 label = str;
1000 ptr = label;
1001 while (*ptr && *ptr != '.') ptr++;
1002 if (*ptr == '.')
1003 {
1004 *ptr = 0x00;
1005 ptr++;
1006 fstype = ptr;
1007 }
1008 while (*ptr && *ptr != '.') ptr++;
1009 if (*ptr == '.')
1010 {
1011 *ptr = 0x00;
1012 ptr++;
1013 extn = ptr;
1014 }
1015
1016 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
1017
1018 TWPartition* Part = Find_Partition_By_Path(label);
1019 if (Part == NULL)
1020 {
1021 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
1022 continue;
1023 }
1024
1025 Part->Backup_FileName = de->d_name;
1026 if (strlen(extn) > 3) {
1027 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
1028 }
1029
1030 // Now, we just need to find the correct label
1031 if (Part->Mount_Point == "/system")
1032 tw_restore_system = 1;
1033 if (Part->Mount_Point == "/data")
1034 tw_restore_data = 1;
1035 if (Part->Mount_Point == "/cache")
1036 tw_restore_cache = 1;
1037 if (Part->Mount_Point == "/recovery")
1038 tw_restore_recovery = 1;
1039 if (Part->Mount_Point == "/boot")
1040 tw_restore_boot = 1;
1041 if (Part->Mount_Point == "/.android_secure")
1042 tw_restore_andsec = 1;
1043 if (Part->Mount_Point == "/sd-ext")
1044 tw_restore_sdext = 1;
1045#ifdef SP1_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001046 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP1_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001047 tw_restore_sp1 = 1;
1048#endif
1049#ifdef SP2_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001050 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP2_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001051 tw_restore_sp2 = 1;
1052#endif
1053#ifdef SP3_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001054 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP3_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001055 tw_restore_sp3 = 1;
1056#endif
1057 }
1058 closedir(d);
1059
1060 // Set the final values
1061 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
1062 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
1063 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
1064 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
1065 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
1066 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
1067 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
1068 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
1069 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
1070 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
1071
Dees_Troy51a0e822012-09-05 15:24:24 -04001072 return;
1073}
1074
1075int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001076 std::vector<TWPartition*>::iterator iter;
1077 int ret = false;
1078 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -04001079 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -04001080
1081 // Iterate through all partitions
1082 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -04001083 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001084 ret = (*iter)->Wipe();
1085 found = true;
1086 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
1087 (*iter)->Wipe();
1088 }
1089 }
1090 if (found) {
1091 return ret;
1092 } else
1093 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
1094 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001095}
1096
1097int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001098 TWPartition* Part = Find_Partition_By_Block(Block);
1099
1100 if (Part) {
1101 if (Part->Has_SubPartition) {
1102 std::vector<TWPartition*>::iterator subpart;
1103
1104 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1105 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1106 (*subpart)->Wipe();
1107 }
1108 return Part->Wipe();
1109 } else
1110 return Part->Wipe();
1111 }
1112 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1113 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001114}
1115
1116int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001117 TWPartition* Part = Find_Partition_By_Name(Name);
1118
1119 if (Part) {
1120 if (Part->Has_SubPartition) {
1121 std::vector<TWPartition*>::iterator subpart;
1122
1123 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1124 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1125 (*subpart)->Wipe();
1126 }
1127 return Part->Wipe();
1128 } else
1129 return Part->Wipe();
1130 }
1131 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1132 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001133}
1134
1135int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001136 std::vector<TWPartition*>::iterator iter;
1137 int ret = true;
1138
1139 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001140 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001141 if (!(*iter)->Wipe())
1142 ret = false;
1143 }
1144 }
1145 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001146}
1147
Dees_Troy38bd7602012-09-14 13:33:53 -04001148int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1149 struct stat st;
1150
1151 if (!Mount_By_Path("/data", true))
1152 return false;
1153
1154 if (!Mount_By_Path("/cache", true))
1155 return false;
1156
1157 ui_print("\nWiping Dalvik Cache Directories...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001158 system("rm -rf /data/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001159 ui_print("Cleaned: /data/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001160 system("rm -rf /cache/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001161 ui_print("Cleaned: /cache/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001162 system("rm -rf /cache/dc");
Dees_Troy38bd7602012-09-14 13:33:53 -04001163 ui_print("Cleaned: /cache/dc\n");
1164
1165 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1166 if (sdext != NULL) {
1167 if (sdext->Is_Present && sdext->Mount(false)) {
1168 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001169 system("rm -rf /sd-ext/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001170 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1171 }
1172 }
1173 }
1174 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1175 return true;
1176}
1177
1178int TWPartitionManager::Wipe_Rotate_Data(void) {
1179 if (!Mount_By_Path("/data", true))
1180 return false;
1181
Dees_Troy8170a922012-09-18 15:40:25 -04001182 system("rm -r /data/misc/akmd*");
1183 system("rm -r /data/misc/rild*");
1184 system("rm -r /data/misc/rild*");
Dees_Troy38bd7602012-09-14 13:33:53 -04001185 ui_print("Rotation data wiped.\n");
1186 return true;
1187}
1188
1189int TWPartitionManager::Wipe_Battery_Stats(void) {
1190 struct stat st;
1191
1192 if (!Mount_By_Path("/data", true))
1193 return false;
1194
1195 if (0 != stat("/data/system/batterystats.bin", &st)) {
1196 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1197 } else {
1198 remove("/data/system/batterystats.bin");
1199 ui_print("Cleared battery stats.\n");
1200 }
1201 return true;
1202}
1203
1204int TWPartitionManager::Format_Data(void) {
1205 TWPartition* dat = Find_Partition_By_Path("/data");
1206
1207 if (dat != NULL) {
1208 if (!dat->UnMount(true))
1209 return false;
1210
1211 return dat->Wipe_Encryption();
1212 } else {
1213 LOGE("Unable to locate /data.\n");
1214 return false;
1215 }
1216 return false;
1217}
1218
1219int TWPartitionManager::Wipe_Media_From_Data(void) {
1220 TWPartition* dat = Find_Partition_By_Path("/data");
1221
1222 if (dat != NULL) {
1223 if (!dat->Has_Data_Media) {
1224 LOGE("This device does not have /data/media\n");
1225 return false;
1226 }
1227 if (!dat->Mount(true))
1228 return false;
1229
1230 ui_print("Wiping internal storage -- /data/media...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001231 system("rm -rf /data/media");
1232 system("cd /data && mkdir media && chmod 775 media");
Dees_Troy38bd7602012-09-14 13:33:53 -04001233 if (dat->Has_Data_Media) {
1234 dat->Recreate_Media_Folder();
1235 }
1236 return true;
1237 } else {
1238 LOGE("Unable to locate /data.\n");
1239 return false;
1240 }
1241 return false;
1242}
1243
Dees_Troy51a0e822012-09-05 15:24:24 -04001244void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001245 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001246 return;
1247}
1248
1249void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001250 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001251 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001252
Dees_Troy32c8eb82012-09-11 15:28:06 -04001253 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001254 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001255 if ((*iter)->Can_Be_Mounted) {
1256 (*iter)->Update_Size(true);
1257 if ((*iter)->Mount_Point == "/system") {
1258 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1259 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1260 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1261 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1262 } else if ((*iter)->Mount_Point == "/cache") {
1263 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1264 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1265 } else if ((*iter)->Mount_Point == "/sd-ext") {
1266 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1267 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1268 if ((*iter)->Backup_Size == 0) {
1269 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1270 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1271 } else
1272 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
Dees_Troy8170a922012-09-18 15:40:25 -04001273 } else if ((*iter)->Mount_Point == "/and-sec") {
1274 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1275 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1276 if ((*iter)->Backup_Size == 0) {
1277 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 0);
1278 DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
1279 } else
1280 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 1);
Dees_Troy51127312012-09-08 13:08:49 -04001281 }
1282 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001283 }
Dees_Troy51127312012-09-08 13:08:49 -04001284 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1285 string current_storage_path = DataManager::GetCurrentStoragePath();
1286 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
Dees_Troy8170a922012-09-18 15:40:25 -04001287 if (FreeStorage != NULL) {
1288 // Attempt to mount storage
1289 if (!FreeStorage->Mount(false)) {
1290 // We couldn't mount storage... check to see if we have dual storage
1291 int has_dual_storage;
1292 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual_storage);
1293 if (has_dual_storage == 1) {
1294 // We have dual storage, see if we're using the internal storage that should always be present
1295 if (current_storage_path == DataManager::GetSettingsStoragePath()) {
1296 // Not able to use internal, so error!
1297 LOGE("Unable to mount internal storage.\n");
1298 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1299 } else {
1300 // We were using external, flip to internal
1301 DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
1302 current_storage_path = DataManager::GetCurrentStoragePath();
1303 FreeStorage = Find_Partition_By_Path(current_storage_path);
1304 if (FreeStorage != NULL) {
1305 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1306 } else {
1307 LOGE("Unable to locate internal storage partition.\n");
1308 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1309 }
1310 }
1311 } else {
1312 // No dual storage and unable to mount storage, error!
1313 LOGE("Unable to mount storage.\n");
1314 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1315 }
1316 } else {
1317 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1318 }
1319 } else {
Dees_Troy51127312012-09-08 13:08:49 -04001320 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -04001321 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001322 if (!Write_Fstab())
1323 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001324 return;
1325}
1326
1327int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001328#ifdef TW_INCLUDE_CRYPTO
1329 int ret_val, password_len;
1330 char crypto_blkdev[255], cPassword[255];
1331 size_t result;
1332
1333 property_set("ro.crypto.state", "encrypted");
1334#ifdef TW_INCLUDE_JB_CRYPTO
1335 // No extra flags needed
1336#else
1337 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1338 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1339 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1340 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1341 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1342 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1343#endif
1344 strcpy(cPassword, Password.c_str());
1345 if (cryptfs_check_passwd(cPassword) != 0) {
1346 LOGE("Failed to decrypt data.\n");
1347 return -1;
1348 }
1349 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1350 if (strcmp(crypto_blkdev, "error") == 0) {
1351 LOGE("Error retrieving decrypted data block device.\n");
1352 } else {
1353 TWPartition* dat = Find_Partition_By_Path("/data");
1354 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001355 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001356 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1357 dat->Is_Decrypted = true;
1358 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001359 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001360 // Sleep for a bit so that the device will be ready
1361 sleep(1);
1362 Update_System_Details();
1363 } else
1364 LOGE("Unable to locate data partition.\n");
1365 }
1366 return 0;
1367#else
1368 LOGE("No crypto support was compiled into this build.\n");
1369 return -1;
1370#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001371 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001372}
1373
Dees_Troy38bd7602012-09-14 13:33:53 -04001374int TWPartitionManager::Fix_Permissions(void) {
1375 if (!Mount_By_Path("/data", true))
1376 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001377
Dees_Troy38bd7602012-09-14 13:33:53 -04001378 if (!Mount_By_Path("/system", true))
1379 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001380
Dees_Troy38bd7602012-09-14 13:33:53 -04001381 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001382 system("./sbin/fix_permissions.sh");
Dees_Troy38bd7602012-09-14 13:33:53 -04001383 ui_print("Done.\n\n");
1384 return true;
Dees_Troy4a2a1262012-09-18 09:33:47 -04001385}
Dees_Troy8170a922012-09-18 15:40:25 -04001386
1387//partial kangbang from system/vold
1388#ifndef CUSTOM_LUN_FILE
1389#define CUSTOM_LUN_FILE "/sys/devices/platform/usb_mass_storage/lun%d/file"
1390#endif
1391
1392int TWPartitionManager::usb_storage_enable(void) {
1393 int fd, has_dual, has_data_media;
1394 char lun_file[255];
1395 TWPartition* Part;
1396 string ext_path;
1397
1398 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual);
1399 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
1400 if (has_dual == 1 && has_data_media == 0) {
1401 Part = Find_Partition_By_Path(DataManager::GetSettingsStoragePath());
1402 if (Part == NULL) {
1403 LOGE("Unable to locate volume information.");
1404 return false;
1405 }
1406 if (!Part->UnMount(true))
1407 return false;
1408
1409 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1410 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1411 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1412 return false;
1413 }
1414
1415 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1416 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1417 close(fd);
1418 return false;
1419 }
1420 close(fd);
1421
1422 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1423 Part = Find_Partition_By_Path(ext_path);
1424 if (Part == NULL) {
1425 LOGE("Unable to locate volume information.\n");
1426 return false;
1427 }
1428 if (!Part->UnMount(true))
1429 return false;
1430
1431 sprintf(lun_file, CUSTOM_LUN_FILE, 1);
1432 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1433 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1434 return false;
1435 }
1436
1437 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1438 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1439 close(fd);
1440 return false;
1441 }
1442 close(fd);
1443 } else {
1444 if (has_data_media == 0)
1445 ext_path = DataManager::GetCurrentStoragePath();
1446 else
1447 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1448
1449 Part = Find_Partition_By_Path(ext_path);
1450 if (Part == NULL) {
1451 LOGE("Unable to locate volume information.\n");
1452 return false;
1453 }
1454 if (!Part->UnMount(true))
1455 return false;
1456
1457 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1458
1459 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1460 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1461 return false;
1462 }
1463
1464 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1465 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1466 close(fd);
1467 return false;
1468 }
1469 close(fd);
1470 }
1471 return true;
1472}
1473
1474int TWPartitionManager::usb_storage_disable(void) {
1475 int fd, index;
1476 char lun_file[255];
1477
1478 for (index=0; index<2; index++) {
1479 sprintf(lun_file, CUSTOM_LUN_FILE, index);
1480
1481 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1482 if (index == 0)
1483 LOGE("Unable to open ums lunfile '%s': (%s)", lun_file, strerror(errno));
1484 return false;
1485 }
1486
1487 char ch = 0;
1488 if (write(fd, &ch, 1) < 0) {
1489 if (index == 0)
1490 LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
1491 close(fd);
1492 return false;
1493 }
1494
1495 close(fd);
1496 }
1497 Mount_By_Path(DataManager::GetSettingsStoragePath(), true);
1498 Mount_By_Path(DataManager::GetCurrentStoragePath(), true);
1499 return true;
1500}