blob: 2bcbc271330c46df5350aa3b2468b89cfc267747 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001/* Partition Management classes for TWRP
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 *
17 * The code was written from scratch by Dees_Troy dees_troy at
18 * yahoo
19 *
20 * Copyright (c) 2012
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/stat.h>
27#include <sys/vfs.h>
28#include <unistd.h>
Dees_Troy5bf43922012-09-07 16:07:55 -040029#include <vector>
Dees_Troy63c8df72012-09-10 14:02:05 -040030#include <dirent.h>
31#include <time.h>
Dees_Troy8170a922012-09-18 15:40:25 -040032#include <errno.h>
33#include <fcntl.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040034
35#include "variables.h"
36#include "common.h"
37#include "partitions.hpp"
Dees_Troy5bf43922012-09-07 16:07:55 -040038#include "data.hpp"
Dees_Troy38bd7602012-09-14 13:33:53 -040039#include "twrp-functions.hpp"
40
Dees_Troy5bf43922012-09-07 16:07:55 -040041#ifdef TW_INCLUDE_CRYPTO
42 #ifdef TW_INCLUDE_JB_CRYPTO
43 #include "crypto/jb/cryptfs.h"
44 #else
45 #include "crypto/ics/cryptfs.h"
46 #endif
47 #include "cutils/properties.h"
48#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040049
50int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -040051 FILE *fstabFile;
52 char fstab_line[MAX_FSTAB_LINE_LENGTH];
53
54 fstabFile = fopen(Fstab_Filename.c_str(), "rt");
55 if (fstabFile == NULL) {
56 LOGE("Critical Error: Unable to open fstab at '%s'.\n", Fstab_Filename.c_str());
57 return false;
58 }
59
60 while (fgets(fstab_line, sizeof(fstab_line), fstabFile) != NULL) {
61 if (fstab_line[0] != '/')
62 continue;
63
Dees_Troy2a923582012-09-20 12:13:34 -040064 if (fstab_line[strlen(fstab_line) - 1] != '\n')
65 fstab_line[strlen(fstab_line)] = '\n';
66
Dees_Troy5bf43922012-09-07 16:07:55 -040067 TWPartition* partition = new TWPartition();
Dees_Troy2a923582012-09-20 12:13:34 -040068 string line = fstab_line;
69
Dees_Troy5bf43922012-09-07 16:07:55 -040070 if (partition->Process_Fstab_Line(line, Display_Error)) {
71 Partitions.push_back(partition);
72 } else {
73 delete partition;
74 }
75 }
76 fclose(fstabFile);
77 if (!Write_Fstab()) {
78 if (Display_Error)
79 LOGE("Error creating fstab\n");
80 else
81 LOGI("Error creating fstab\n");
82 }
Dees_Troy51127312012-09-08 13:08:49 -040083 Update_System_Details();
Dees_Troy5bf43922012-09-07 16:07:55 -040084 return true;
85}
86
87int TWPartitionManager::Write_Fstab(void) {
88 FILE *fp;
89 std::vector<TWPartition*>::iterator iter;
90 string Line;
91
92 fp = fopen("/etc/fstab", "w");
93 if (fp == NULL) {
Dees_Troy63c8df72012-09-10 14:02:05 -040094 LOGI("Can not open /etc/fstab.\n");
Dees_Troy5bf43922012-09-07 16:07:55 -040095 return false;
96 }
Dees_Troy63c8df72012-09-10 14:02:05 -040097 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -040098 if ((*iter)->Can_Be_Mounted) {
Dees_Troy38bd7602012-09-14 13:33:53 -040099 Line = (*iter)->Actual_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
Dees_Troy5bf43922012-09-07 16:07:55 -0400100 fputs(Line.c_str(), fp);
Dees_Troy51127312012-09-08 13:08:49 -0400101 // Handle subpartition tracking
102 if ((*iter)->Is_SubPartition) {
103 TWPartition* ParentPartition = Find_Partition_By_Path((*iter)->SubPartition_Of);
104 if (ParentPartition)
105 ParentPartition->Has_SubPartition = true;
106 else
107 LOGE("Unable to locate parent partition '%s' of '%s'\n", (*iter)->SubPartition_Of.c_str(), (*iter)->Mount_Point.c_str());
108 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400109 }
110 }
111 fclose(fp);
112 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400113}
114
Dees_Troy8170a922012-09-18 15:40:25 -0400115void TWPartitionManager::Output_Partition_Logging(void) {
116 std::vector<TWPartition*>::iterator iter;
117
118 printf("\n\nPartition Logs:\n");
119 for (iter = Partitions.begin(); iter != Partitions.end(); iter++)
120 Output_Partition((*iter));
121}
122
123void TWPartitionManager::Output_Partition(TWPartition* Part) {
124 unsigned long long mb = 1048576;
125
126 if (Part->Can_Be_Mounted) {
127 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));
128 if (Part->Can_Be_Wiped)
129 printf("Can_Be_Wiped ");
130 if (Part->Wipe_During_Factory_Reset)
131 printf("Wipe_During_Factory_Reset ");
132 if (Part->Wipe_Available_in_GUI)
133 printf("Wipe_Available_in_GUI ");
134 if (Part->Is_SubPartition)
135 printf("Is_SubPartition ");
136 if (Part->Has_SubPartition)
137 printf("Has_SubPartition ");
138 if (Part->Removable)
139 printf("Removable ");
140 if (Part->Is_Present)
141 printf("IsPresent ");
142 if (Part->Can_Be_Encrypted)
143 printf("Can_Be_Encrypted ");
144 if (Part->Is_Encrypted)
145 printf("Is_Encrypted ");
146 if (Part->Is_Decrypted)
147 printf("Is_Decrypted ");
148 if (Part->Has_Data_Media)
149 printf("Has_Data_Media ");
150 if (Part->Is_Storage)
151 printf("Is_Storage ");
152 printf("\n");
153 if (!Part->SubPartition_Of.empty())
154 printf(" SubPartition_Of: %s\n", Part->SubPartition_Of.c_str());
155 if (!Part->Symlink_Path.empty())
156 printf(" Symlink_Path: %s\n", Part->Symlink_Path.c_str());
157 if (!Part->Symlink_Mount_Point.empty())
158 printf(" Symlink_Mount_Point: %s\n", Part->Symlink_Mount_Point.c_str());
159 if (!Part->Primary_Block_Device.empty())
160 printf(" Primary_Block_Device: %s\n", Part->Primary_Block_Device.c_str());
161 if (!Part->Alternate_Block_Device.empty())
162 printf(" Alternate_Block_Device: %s\n", Part->Alternate_Block_Device.c_str());
163 if (!Part->Decrypted_Block_Device.empty())
164 printf(" Decrypted_Block_Device: %s\n", Part->Decrypted_Block_Device.c_str());
165 if (Part->Length != 0)
166 printf(" Length: %i\n", Part->Length);
167 if (!Part->Display_Name.empty())
168 printf(" Display_Name: %s\n", Part->Display_Name.c_str());
169 if (!Part->Backup_Name.empty())
170 printf(" Backup_Name: %s\n", Part->Backup_Name.c_str());
171 if (!Part->Backup_FileName.empty())
172 printf(" Backup_FileName: %s\n", Part->Backup_FileName.c_str());
173 if (!Part->MTD_Name.empty())
174 printf(" MTD_Name: %s\n", Part->MTD_Name.c_str());
175 if (!Part->Storage_Path.empty())
176 printf(" Storage_Path: %s\n", Part->Storage_Path.c_str());
177 if (!Part->Current_File_System.empty())
178 printf(" Current_File_System: %s\n", Part->Current_File_System.c_str());
179 if (!Part->Fstab_File_System.empty())
180 printf(" Fstab_File_System: %s\n", Part->Fstab_File_System.c_str());
181 if (Part->Format_Block_Size != 0)
182 printf(" Format_Block_Size: %i\n", Part->Format_Block_Size);
183 } else {
184 printf("%s | %s | Size: %iMB\n", Part->Mount_Point.c_str(), Part->Actual_Block_Device.c_str(), (int)(Part->Size / mb));
185 }
186 string back_meth = Part->Backup_Method_By_Name();
187 printf(" Backup_Method: %s\n\n", back_meth.c_str());
188}
189
Dees_Troy51a0e822012-09-05 15:24:24 -0400190int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400191 std::vector<TWPartition*>::iterator iter;
192 int ret = false;
193 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400194 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400195
Dees_Troy43d8b002012-09-17 16:00:01 -0400196 if (Local_Path == "/tmp")
197 return true;
198
Dees_Troy5bf43922012-09-07 16:07:55 -0400199 // Iterate through all partitions
200 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400201 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400202 ret = (*iter)->Mount(Display_Error);
203 found = true;
Dees_Troy51127312012-09-08 13:08:49 -0400204 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400205 (*iter)->Mount(Display_Error);
Dees_Troy51127312012-09-08 13:08:49 -0400206 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400207 }
208 if (found) {
209 return ret;
210 } else if (Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400211 LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400212 } else {
Dees_Troy51127312012-09-08 13:08:49 -0400213 LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400214 }
215 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400216}
217
218int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400219 TWPartition* Part = Find_Partition_By_Block(Block);
Dees_Troy5bf43922012-09-07 16:07:55 -0400220
Dees_Troy51127312012-09-08 13:08:49 -0400221 if (Part) {
222 if (Part->Has_SubPartition) {
223 std::vector<TWPartition*>::iterator subpart;
224
225 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
226 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
227 (*subpart)->Mount(Display_Error);
228 }
229 return Part->Mount(Display_Error);
230 } else
231 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400232 }
233 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400234 LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400235 else
Dees_Troy51127312012-09-08 13:08:49 -0400236 LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400237 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400238}
239
240int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400241 TWPartition* Part = Find_Partition_By_Name(Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400242
Dees_Troy51127312012-09-08 13:08:49 -0400243 if (Part) {
244 if (Part->Has_SubPartition) {
245 std::vector<TWPartition*>::iterator subpart;
246
247 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
248 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
249 (*subpart)->Mount(Display_Error);
250 }
251 return Part->Mount(Display_Error);
252 } else
253 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400254 }
255 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400256 LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400257 else
Dees_Troy51127312012-09-08 13:08:49 -0400258 LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400259 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400260}
261
262int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400263 std::vector<TWPartition*>::iterator iter;
264 int ret = false;
265 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400266 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy51127312012-09-08 13:08:49 -0400267
268 // Iterate through all partitions
269 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400270 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy51127312012-09-08 13:08:49 -0400271 ret = (*iter)->UnMount(Display_Error);
272 found = true;
273 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
274 (*iter)->UnMount(Display_Error);
275 }
276 }
277 if (found) {
278 return ret;
279 } else if (Display_Error) {
280 LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
281 } else {
282 LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
283 }
284 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400285}
286
287int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400288 TWPartition* Part = Find_Partition_By_Block(Block);
289
290 if (Part) {
291 if (Part->Has_SubPartition) {
292 std::vector<TWPartition*>::iterator subpart;
293
294 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
295 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
296 (*subpart)->UnMount(Display_Error);
297 }
298 return Part->UnMount(Display_Error);
299 } else
300 return Part->UnMount(Display_Error);
301 }
302 if (Display_Error)
303 LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
304 else
305 LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
306 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400307}
308
309int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400310 TWPartition* Part = Find_Partition_By_Name(Name);
311
312 if (Part) {
313 if (Part->Has_SubPartition) {
314 std::vector<TWPartition*>::iterator subpart;
315
316 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
317 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
318 (*subpart)->UnMount(Display_Error);
319 }
320 return Part->UnMount(Display_Error);
321 } else
322 return Part->UnMount(Display_Error);
323 }
324 if (Display_Error)
325 LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
326 else
327 LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
328 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400329}
330
331int TWPartitionManager::Is_Mounted_By_Path(string Path) {
Dees_Troy51127312012-09-08 13:08:49 -0400332 TWPartition* Part = Find_Partition_By_Path(Path);
333
334 if (Part)
335 return Part->Is_Mounted();
336 else
337 LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
338 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400339}
340
341int TWPartitionManager::Is_Mounted_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400342 TWPartition* Part = Find_Partition_By_Block(Block);
343
344 if (Part)
345 return Part->Is_Mounted();
346 else
347 LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
348 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400349}
350
351int TWPartitionManager::Is_Mounted_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400352 TWPartition* Part = Find_Partition_By_Name(Name);
353
354 if (Part)
355 return Part->Is_Mounted();
356 else
357 LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
358 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400359}
360
Dees_Troy5bf43922012-09-07 16:07:55 -0400361int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400362 string current_storage_path = DataManager::GetCurrentStoragePath();
363
364 if (Mount_By_Path(current_storage_path, Display_Error)) {
365 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
366 if (FreeStorage)
367 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
368 return true;
369 }
370 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400371}
372
Dees_Troy5bf43922012-09-07 16:07:55 -0400373int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
374 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
375}
376
377TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
378 std::vector<TWPartition*>::iterator iter;
Dees_Troy38bd7602012-09-14 13:33:53 -0400379 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400380
381 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400382 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
Dees_Troy5bf43922012-09-07 16:07:55 -0400383 return (*iter);
384 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400385 return NULL;
386}
387
Dees_Troy5bf43922012-09-07 16:07:55 -0400388TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400389 std::vector<TWPartition*>::iterator iter;
390
391 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400392 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 -0400393 return (*iter);
394 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400395 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400396}
397
398TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400399 std::vector<TWPartition*>::iterator iter;
400
401 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
402 if ((*iter)->Display_Name == Name)
403 return (*iter);
404 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400405 return NULL;
406}
Dees_Troy51a0e822012-09-05 15:24:24 -0400407
Dees_Troy43d8b002012-09-17 16:00:01 -0400408bool TWPartitionManager::Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename)
409{
410 char command[512];
411 string Full_File = Backup_Folder + Backup_Filename;
412
Dees_Troy4a2a1262012-09-18 09:33:47 -0400413 if (!generate_md5)
Dees_Troy43d8b002012-09-17 16:00:01 -0400414 return true;
Dees_Troy43d8b002012-09-17 16:00:01 -0400415
Dees_Troy4a2a1262012-09-18 09:33:47 -0400416 ui_print(" * Generating md5...");
Dees_Troy43d8b002012-09-17 16:00:01 -0400417
418 if (TWFunc::Path_Exists(Full_File)) {
419 sprintf(command, "cd '%s' && md5sum %s > %s.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), Backup_Filename.c_str());
420 LOGI("MD5 command is: '%s'\n", command);
421 if (system(command) == 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400422 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400423 return true;
424 } else {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400425 ui_print("MD5 Error!\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400426 return false;
427 }
428 } else {
429 char filename[512];
430 int index = 0;
431
432 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400433 while (TWFunc::Path_Exists(filename) == true) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400434 sprintf(command, "cd '%s' && md5sum %s%03i > %s%03i.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), index, Backup_Filename.c_str(), index);
435 LOGI("MD5 command is: '%s'\n", command);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400436 if (system(command) != 0) {
437 ui_print("MD5 Error.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400438 return false;
439 }
440 index++;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400441 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy43d8b002012-09-17 16:00:01 -0400442 }
443 if (index == 0) {
444 LOGE("Backup file: '%s' not found!\n", filename);
445 return false;
446 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400447 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400448 }
449 return true;
450}
451
452bool 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) {
453 time_t start, stop;
454
455 if (Part == NULL)
456 return true;
457
458 time(&start);
459
460 if (Part->Backup(Backup_Folder)) {
Dees_Troy8170a922012-09-18 15:40:25 -0400461 if (Part->Has_SubPartition) {
462 std::vector<TWPartition*>::iterator subpart;
463
464 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
465 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
466 if (!(*subpart)->Backup(Backup_Folder))
467 return false;
468 if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
469 return false;
470 }
471 }
472 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400473 time(&stop);
474 if (Part->Backup_Method == 1) {
475 *file_bytes_remaining -= Part->Backup_Size;
476 *file_time += (int) difftime(stop, start);
477 } else {
478 *img_bytes_remaining -= Part->Backup_Size;
479 *img_time += (int) difftime(stop, start);
480 }
481 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
482 } else {
483 return false;
484 }
485}
486
487int TWPartitionManager::Run_Backup(void) {
488 int check, do_md5, partition_count = 0;
489 string Backup_Folder, Backup_Name, Full_Backup_Path;
Dees_Troy8170a922012-09-18 15:40:25 -0400490 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 -0400491 unsigned long img_time = 0, file_time = 0;
492 TWPartition* backup_sys = NULL;
493 TWPartition* backup_data = NULL;
494 TWPartition* backup_cache = NULL;
495 TWPartition* backup_recovery = NULL;
496 TWPartition* backup_boot = NULL;
497 TWPartition* backup_andsec = NULL;
498 TWPartition* backup_sdext = NULL;
499 TWPartition* backup_sp1 = NULL;
500 TWPartition* backup_sp2 = NULL;
501 TWPartition* backup_sp3 = NULL;
502 TWPartition* storage = NULL;
Dees_Troy8170a922012-09-18 15:40:25 -0400503 std::vector<TWPartition*>::iterator subpart;
Dees_Troy43d8b002012-09-17 16:00:01 -0400504 struct tm *t;
505 time_t start, stop, seconds, total_start, total_stop;
506 seconds = time(0);
507 t = localtime(&seconds);
508
509 time(&total_start);
510
511 Update_System_Details();
512
513 if (!Mount_Current_Storage(true))
514 return false;
515
516 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400517 if (do_md5 == 0)
Dees_Troy43d8b002012-09-17 16:00:01 -0400518 do_md5 = true;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400519
Dees_Troy43d8b002012-09-17 16:00:01 -0400520 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
521 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
522 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
523 char timestamp[255];
524 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);
525 Backup_Name = timestamp;
526 }
527 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
528 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
529 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
530
531 ui_print("\n[BACKUP STARTED]\n");
532 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
533 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
534 LOGE("Failed to make backup folder.\n");
535 return false;
536 }
537
538 LOGI("Calculating backup details...\n");
539 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
540 if (check) {
541 backup_sys = Find_Partition_By_Path("/system");
542 if (backup_sys != NULL) {
543 partition_count++;
544 if (backup_sys->Backup_Method == 1)
545 file_bytes += backup_sys->Backup_Size;
546 else
547 img_bytes += backup_sys->Backup_Size;
548 } else {
549 LOGE("Unable to locate system partition.\n");
550 return false;
551 }
552 }
553 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
554 if (check) {
555 backup_data = Find_Partition_By_Path("/data");
556 if (backup_data != NULL) {
557 partition_count++;
Dees_Troy8170a922012-09-18 15:40:25 -0400558 subpart_size = 0;
559 if (backup_data->Has_SubPartition) {
560 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
561 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_data->Mount_Point)
562 subpart_size += (*subpart)->Backup_Size;
563 }
564 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400565 if (backup_data->Backup_Method == 1)
Dees_Troy8170a922012-09-18 15:40:25 -0400566 file_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400567 else
Dees_Troy8170a922012-09-18 15:40:25 -0400568 img_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400569 } else {
570 LOGE("Unable to locate data partition.\n");
571 return false;
572 }
573 }
574 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
575 if (check) {
576 backup_cache = Find_Partition_By_Path("/cache");
577 if (backup_cache != NULL) {
578 partition_count++;
579 if (backup_cache->Backup_Method == 1)
580 file_bytes += backup_cache->Backup_Size;
581 else
582 img_bytes += backup_cache->Backup_Size;
583 } else {
584 LOGE("Unable to locate cache partition.\n");
585 return false;
586 }
587 }
588 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
589 if (check) {
590 backup_recovery = Find_Partition_By_Path("/recovery");
591 if (backup_recovery != NULL) {
592 partition_count++;
593 if (backup_recovery->Backup_Method == 1)
594 file_bytes += backup_recovery->Backup_Size;
595 else
596 img_bytes += backup_recovery->Backup_Size;
597 } else {
598 LOGE("Unable to locate recovery partition.\n");
599 return false;
600 }
601 }
602 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
603 if (check) {
604 backup_boot = Find_Partition_By_Path("/boot");
605 if (backup_boot != NULL) {
606 partition_count++;
607 if (backup_boot->Backup_Method == 1)
608 file_bytes += backup_boot->Backup_Size;
609 else
610 img_bytes += backup_boot->Backup_Size;
611 } else {
612 LOGE("Unable to locate boot partition.\n");
613 return false;
614 }
615 }
616 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
617 if (check) {
618 backup_andsec = Find_Partition_By_Path("/and-sec");
619 if (backup_andsec != NULL) {
620 partition_count++;
621 if (backup_andsec->Backup_Method == 1)
622 file_bytes += backup_andsec->Backup_Size;
623 else
624 img_bytes += backup_andsec->Backup_Size;
625 } else {
626 LOGE("Unable to locate android secure partition.\n");
627 return false;
628 }
629 }
630 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
631 if (check) {
632 backup_sdext = Find_Partition_By_Path("/sd-ext");
633 if (backup_sdext != NULL) {
634 partition_count++;
635 if (backup_sdext->Backup_Method == 1)
636 file_bytes += backup_sdext->Backup_Size;
637 else
638 img_bytes += backup_sdext->Backup_Size;
639 } else {
640 LOGE("Unable to locate sd-ext partition.\n");
641 return false;
642 }
643 }
644#ifdef SP1_NAME
645 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
646 if (check) {
647 backup_sp1 = Find_Partition_By_Path(SP1_NAME);
648 if (backup_sp1 != NULL) {
649 partition_count++;
650 if (backup_sp1->Backup_Method == 1)
651 file_bytes += backup_sp1->Backup_Size;
652 else
653 img_bytes += backup_sp1->Backup_Size;
654 } else {
655 LOGE("Unable to locate %s partition.\n", SP1_NAME);
656 return false;
657 }
658 }
659#endif
660#ifdef SP2_NAME
661 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
662 if (check) {
663 backup_sp2 = Find_Partition_By_Path(SP2_NAME);
664 if (backup_sp2 != NULL) {
665 partition_count++;
666 if (backup_sp2->Backup_Method == 1)
667 file_bytes += backup_sp2->Backup_Size;
668 else
669 img_bytes += backup_sp2->Backup_Size;
670 } else {
671 LOGE("Unable to locate %s partition.\n", SP2_NAME);
672 return false;
673 }
674 }
675#endif
676#ifdef SP3_NAME
677 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
678 if (check) {
679 backup_sp3 = Find_Partition_By_Path(SP3_NAME);
680 if (backup_sp3 != NULL) {
681 partition_count++;
682 if (backup_sp3->Backup_Method == 1)
683 file_bytes += backup_sp3->Backup_Size;
684 else
685 img_bytes += backup_sp3->Backup_Size;
686 } else {
687 LOGE("Unable to locate %s partition.\n", SP3_NAME);
688 return false;
689 }
690 }
691#endif
692
693 if (partition_count == 0) {
694 ui_print("No partitions selected for backup.\n");
695 return false;
696 }
697 total_bytes = file_bytes + img_bytes;
698 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
699 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
700 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
701 if (storage != NULL) {
702 free_space = storage->Free;
703 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
704 } else {
705 LOGE("Unable to locate storage device.\n");
706 return false;
707 }
708 if (free_space + (32 * 1024 * 1024) < total_bytes) {
709 // We require an extra 32MB just in case
710 LOGE("Not enough free space on storage.\n");
711 return false;
712 }
713 img_bytes_remaining = img_bytes;
714 file_bytes_remaining = file_bytes;
715
716 if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
717 return false;
718 if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
719 return false;
720 if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
721 return false;
722 if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
723 return false;
724 if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
725 return false;
726 if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
727 return false;
728 if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
729 return false;
730 if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
731 return false;
732 if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
733 return false;
734 if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
735 return false;
736
737 // Average BPS
738 if (img_time == 0)
739 img_time = 1;
740 if (file_time == 0)
741 file_time = 1;
742 unsigned long int img_bps = img_bytes / img_time;
743 unsigned long int file_bps = file_bytes / file_time;
744
745 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
746 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
747
748 time(&total_stop);
749 int total_time = (int) difftime(total_stop, total_start);
750 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
751 actual_backup_size /= (1024LLU * 1024LLU);
752
753 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
754 Update_System_Details();
755 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
756 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400757}
758
Dees_Troy4a2a1262012-09-18 09:33:47 -0400759bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name) {
760 time_t Start, Stop;
761 time(&Start);
762 if (!Part->Restore(Restore_Name))
763 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400764 if (Part->Has_SubPartition) {
765 std::vector<TWPartition*>::iterator subpart;
766
767 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
768 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
769 if (!(*subpart)->Restore(Restore_Name))
770 return false;
771 }
772 }
773 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400774 time(&Stop);
775 ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
776 return true;
777}
778
Dees_Troy51a0e822012-09-05 15:24:24 -0400779int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400780 int check_md5, check, partition_count = 0;
781 TWPartition* restore_sys = NULL;
782 TWPartition* restore_data = NULL;
783 TWPartition* restore_cache = NULL;
784 TWPartition* restore_boot = NULL;
785 TWPartition* restore_andsec = NULL;
786 TWPartition* restore_sdext = NULL;
787 TWPartition* restore_sp1 = NULL;
788 TWPartition* restore_sp2 = NULL;
789 TWPartition* restore_sp3 = NULL;
790 time_t rStart, rStop;
791 time(&rStart);
Dees_Troy43d8b002012-09-17 16:00:01 -0400792
Dees_Troy4a2a1262012-09-18 09:33:47 -0400793 ui_print("\n[RESTORE STARTED]\n\n");
794 ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400795
Dees_Troy4a2a1262012-09-18 09:33:47 -0400796 if (!Mount_Current_Storage(true))
797 return false;
798
799 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
800 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
Dees_Troy63c8df72012-09-10 14:02:05 -0400801 if (check > 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400802 restore_sys = Find_Partition_By_Path("/system");
803 if (restore_sys == NULL) {
804 LOGE("Unable to locate system partition.\n");
805 return false;
806 }
807 partition_count++;
808 }
809 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
810 if (check > 0) {
811 restore_data = Find_Partition_By_Path("/data");
812 if (restore_data == NULL) {
813 LOGE("Unable to locate data partition.\n");
814 return false;
815 }
816 partition_count++;
817 }
818 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
819 if (check > 0) {
820 restore_cache = Find_Partition_By_Path("/cache");
821 if (restore_cache == NULL) {
822 LOGE("Unable to locate cache partition.\n");
823 return false;
824 }
825 partition_count++;
826 }
827 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
828 if (check > 0) {
829 restore_boot = Find_Partition_By_Path("/boot");
830 if (restore_boot == NULL) {
831 LOGE("Unable to locate boot partition.\n");
832 return false;
833 }
834 partition_count++;
835 }
836 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
837 if (check > 0) {
838 restore_andsec = Find_Partition_By_Path("/and-sec");
839 if (restore_andsec == NULL) {
840 LOGE("Unable to locate android secure partition.\n");
841 return false;
842 }
843 partition_count++;
844 }
845 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
846 if (check > 0) {
847 restore_sdext = Find_Partition_By_Path("/sd-ext");
848 if (restore_sdext == NULL) {
849 LOGE("Unable to locate sd-ext partition.\n");
850 return false;
851 }
852 partition_count++;
853 }
854#ifdef SP1_NAME
855 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
856 if (check > 0) {
857 restore_sp1 = Find_Partition_By_Path(SP1_NAME);
858 if (restore_sp1 == NULL) {
859 LOGE("Unable to locate %s partition.\n", SP1_NAME);
860 return false;
861 }
862 partition_count++;
863 }
864#endif
865#ifdef SP2_NAME
866 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
867 if (check > 0) {
868 restore_sp2 = Find_Partition_By_Path(SP2_NAME);
869 if (restore_sp2 == NULL) {
870 LOGE("Unable to locate %s partition.\n", SP2_NAME);
871 return false;
872 }
873 partition_count++;
874 }
875#endif
876#ifdef SP3_NAME
877 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
878 if (check > 0) {
879 restore_sp3 = Find_Partition_By_Path(SP3_NAME);
880 if (restore_sp3 == NULL) {
881 LOGE("Unable to locate %s partition.\n", SP3_NAME);
882 return false;
883 }
884 partition_count++;
885 }
886#endif
887
888 if (partition_count == 0) {
889 LOGE("No partitions selected for restore.\n");
890 return false;
891 }
892
893 if (check_md5 > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400894 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
Dees_Troy4a2a1262012-09-18 09:33:47 -0400895 ui_print("Verifying MD5...\n");
896 if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
897 return false;
898 if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
899 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400900 if (restore_data != NULL && restore_data->Has_SubPartition) {
901 std::vector<TWPartition*>::iterator subpart;
902
903 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
904 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_data->Mount_Point) {
905 if (!(*subpart)->Check_MD5(Restore_Name))
906 return false;
907 }
908 }
909 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400910 if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
911 return false;
912 if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
913 return false;
914 if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
915 return false;
916 if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
917 return false;
918 if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
919 return false;
920 if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
921 return false;
922 if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
923 return false;
924 ui_print("Done verifying MD5.\n");
925 } else
926 ui_print("Skipping MD5 check based on user setting.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400927
Dees_Troy4a2a1262012-09-18 09:33:47 -0400928 ui_print("Restoring %i partitions...\n", partition_count);
929 if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name))
930 return false;
931 if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name))
932 return false;
933 if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name))
934 return false;
935 if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name))
936 return false;
937 if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name))
938 return false;
939 if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name))
940 return false;
941 if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name))
942 return false;
943 if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name))
944 return false;
945 if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name))
946 return false;
Dees_Troy43d8b002012-09-17 16:00:01 -0400947
Dees_Troy43d8b002012-09-17 16:00:01 -0400948 Update_System_Details();
Dees_Troy4a2a1262012-09-18 09:33:47 -0400949 time(&rStop);
950 ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
Dees_Troy63c8df72012-09-10 14:02:05 -0400951 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400952}
953
954void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400955 // Start with the default values
956 int tw_restore_system = -1;
957 int tw_restore_data = -1;
958 int tw_restore_cache = -1;
959 int tw_restore_recovery = -1;
960 int tw_restore_boot = -1;
961 int tw_restore_andsec = -1;
962 int tw_restore_sdext = -1;
963 int tw_restore_sp1 = -1;
964 int tw_restore_sp2 = -1;
965 int tw_restore_sp3 = -1;
966 bool get_date = true;
967
968 DIR* d;
969 d = opendir(Restore_Name.c_str());
970 if (d == NULL)
971 {
972 LOGE("Error opening %s\n", Restore_Name.c_str());
973 return;
974 }
975
976 struct dirent* de;
977 while ((de = readdir(d)) != NULL)
978 {
979 // Strip off three components
980 char str[256];
981 char* label;
982 char* fstype = NULL;
983 char* extn = NULL;
984 char* ptr;
985
986 strcpy(str, de->d_name);
987 if (strlen(str) <= 2)
988 continue;
989
990 if (get_date) {
991 char file_path[255];
992 struct stat st;
993
994 strcpy(file_path, Restore_Name.c_str());
995 strcat(file_path, "/");
996 strcat(file_path, str);
997 stat(file_path, &st);
998 string backup_date = ctime((const time_t*)(&st.st_mtime));
999 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
1000 get_date = false;
1001 }
1002
1003 label = str;
1004 ptr = label;
1005 while (*ptr && *ptr != '.') ptr++;
1006 if (*ptr == '.')
1007 {
1008 *ptr = 0x00;
1009 ptr++;
1010 fstype = ptr;
1011 }
1012 while (*ptr && *ptr != '.') ptr++;
1013 if (*ptr == '.')
1014 {
1015 *ptr = 0x00;
1016 ptr++;
1017 extn = ptr;
1018 }
1019
1020 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
1021
1022 TWPartition* Part = Find_Partition_By_Path(label);
1023 if (Part == NULL)
1024 {
1025 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
1026 continue;
1027 }
1028
1029 Part->Backup_FileName = de->d_name;
1030 if (strlen(extn) > 3) {
1031 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
1032 }
1033
1034 // Now, we just need to find the correct label
1035 if (Part->Mount_Point == "/system")
1036 tw_restore_system = 1;
1037 if (Part->Mount_Point == "/data")
1038 tw_restore_data = 1;
1039 if (Part->Mount_Point == "/cache")
1040 tw_restore_cache = 1;
1041 if (Part->Mount_Point == "/recovery")
1042 tw_restore_recovery = 1;
1043 if (Part->Mount_Point == "/boot")
1044 tw_restore_boot = 1;
1045 if (Part->Mount_Point == "/.android_secure")
1046 tw_restore_andsec = 1;
1047 if (Part->Mount_Point == "/sd-ext")
1048 tw_restore_sdext = 1;
1049#ifdef SP1_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001050 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP1_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001051 tw_restore_sp1 = 1;
1052#endif
1053#ifdef SP2_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001054 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP2_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001055 tw_restore_sp2 = 1;
1056#endif
1057#ifdef SP3_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001058 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP3_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001059 tw_restore_sp3 = 1;
1060#endif
1061 }
1062 closedir(d);
1063
1064 // Set the final values
1065 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
1066 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
1067 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
1068 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
1069 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
1070 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
1071 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
1072 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
1073 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
1074 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
1075
Dees_Troy51a0e822012-09-05 15:24:24 -04001076 return;
1077}
1078
1079int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001080 std::vector<TWPartition*>::iterator iter;
1081 int ret = false;
1082 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -04001083 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -04001084
1085 // Iterate through all partitions
1086 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -04001087 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001088 ret = (*iter)->Wipe();
1089 found = true;
1090 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
1091 (*iter)->Wipe();
1092 }
1093 }
1094 if (found) {
1095 return ret;
1096 } else
1097 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
1098 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001099}
1100
1101int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001102 TWPartition* Part = Find_Partition_By_Block(Block);
1103
1104 if (Part) {
1105 if (Part->Has_SubPartition) {
1106 std::vector<TWPartition*>::iterator subpart;
1107
1108 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1109 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1110 (*subpart)->Wipe();
1111 }
1112 return Part->Wipe();
1113 } else
1114 return Part->Wipe();
1115 }
1116 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1117 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001118}
1119
1120int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001121 TWPartition* Part = Find_Partition_By_Name(Name);
1122
1123 if (Part) {
1124 if (Part->Has_SubPartition) {
1125 std::vector<TWPartition*>::iterator subpart;
1126
1127 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1128 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1129 (*subpart)->Wipe();
1130 }
1131 return Part->Wipe();
1132 } else
1133 return Part->Wipe();
1134 }
1135 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1136 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001137}
1138
1139int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001140 std::vector<TWPartition*>::iterator iter;
1141 int ret = true;
1142
1143 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001144 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001145 if (!(*iter)->Wipe())
1146 ret = false;
1147 }
1148 }
1149 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001150}
1151
Dees_Troy38bd7602012-09-14 13:33:53 -04001152int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1153 struct stat st;
1154
1155 if (!Mount_By_Path("/data", true))
1156 return false;
1157
1158 if (!Mount_By_Path("/cache", true))
1159 return false;
1160
1161 ui_print("\nWiping Dalvik Cache Directories...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001162 system("rm -rf /data/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001163 ui_print("Cleaned: /data/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001164 system("rm -rf /cache/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001165 ui_print("Cleaned: /cache/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001166 system("rm -rf /cache/dc");
Dees_Troy38bd7602012-09-14 13:33:53 -04001167 ui_print("Cleaned: /cache/dc\n");
1168
1169 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1170 if (sdext != NULL) {
1171 if (sdext->Is_Present && sdext->Mount(false)) {
1172 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001173 system("rm -rf /sd-ext/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001174 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1175 }
1176 }
1177 }
1178 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1179 return true;
1180}
1181
1182int TWPartitionManager::Wipe_Rotate_Data(void) {
1183 if (!Mount_By_Path("/data", true))
1184 return false;
1185
Dees_Troy8170a922012-09-18 15:40:25 -04001186 system("rm -r /data/misc/akmd*");
1187 system("rm -r /data/misc/rild*");
1188 system("rm -r /data/misc/rild*");
Dees_Troy38bd7602012-09-14 13:33:53 -04001189 ui_print("Rotation data wiped.\n");
1190 return true;
1191}
1192
1193int TWPartitionManager::Wipe_Battery_Stats(void) {
1194 struct stat st;
1195
1196 if (!Mount_By_Path("/data", true))
1197 return false;
1198
1199 if (0 != stat("/data/system/batterystats.bin", &st)) {
1200 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1201 } else {
1202 remove("/data/system/batterystats.bin");
1203 ui_print("Cleared battery stats.\n");
1204 }
1205 return true;
1206}
1207
1208int TWPartitionManager::Format_Data(void) {
1209 TWPartition* dat = Find_Partition_By_Path("/data");
1210
1211 if (dat != NULL) {
1212 if (!dat->UnMount(true))
1213 return false;
1214
1215 return dat->Wipe_Encryption();
1216 } else {
1217 LOGE("Unable to locate /data.\n");
1218 return false;
1219 }
1220 return false;
1221}
1222
1223int TWPartitionManager::Wipe_Media_From_Data(void) {
1224 TWPartition* dat = Find_Partition_By_Path("/data");
1225
1226 if (dat != NULL) {
1227 if (!dat->Has_Data_Media) {
1228 LOGE("This device does not have /data/media\n");
1229 return false;
1230 }
1231 if (!dat->Mount(true))
1232 return false;
1233
1234 ui_print("Wiping internal storage -- /data/media...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001235 system("rm -rf /data/media");
1236 system("cd /data && mkdir media && chmod 775 media");
Dees_Troy38bd7602012-09-14 13:33:53 -04001237 if (dat->Has_Data_Media) {
1238 dat->Recreate_Media_Folder();
1239 }
1240 return true;
1241 } else {
1242 LOGE("Unable to locate /data.\n");
1243 return false;
1244 }
1245 return false;
1246}
1247
Dees_Troy51a0e822012-09-05 15:24:24 -04001248void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001249 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001250 return;
1251}
1252
1253void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001254 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001255 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001256
Dees_Troy32c8eb82012-09-11 15:28:06 -04001257 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001258 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001259 if ((*iter)->Can_Be_Mounted) {
1260 (*iter)->Update_Size(true);
1261 if ((*iter)->Mount_Point == "/system") {
1262 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1263 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1264 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1265 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1266 } else if ((*iter)->Mount_Point == "/cache") {
1267 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1268 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1269 } else if ((*iter)->Mount_Point == "/sd-ext") {
1270 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1271 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1272 if ((*iter)->Backup_Size == 0) {
1273 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1274 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1275 } else
1276 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
Dees_Troy8170a922012-09-18 15:40:25 -04001277 } else if ((*iter)->Mount_Point == "/and-sec") {
1278 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1279 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1280 if ((*iter)->Backup_Size == 0) {
1281 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 0);
1282 DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
1283 } else
1284 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 1);
Dees_Troy51127312012-09-08 13:08:49 -04001285 }
1286 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001287 }
Dees_Troy51127312012-09-08 13:08:49 -04001288 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1289 string current_storage_path = DataManager::GetCurrentStoragePath();
1290 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
Dees_Troy8170a922012-09-18 15:40:25 -04001291 if (FreeStorage != NULL) {
1292 // Attempt to mount storage
1293 if (!FreeStorage->Mount(false)) {
1294 // We couldn't mount storage... check to see if we have dual storage
1295 int has_dual_storage;
1296 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual_storage);
1297 if (has_dual_storage == 1) {
1298 // We have dual storage, see if we're using the internal storage that should always be present
1299 if (current_storage_path == DataManager::GetSettingsStoragePath()) {
1300 // Not able to use internal, so error!
1301 LOGE("Unable to mount internal storage.\n");
1302 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1303 } else {
1304 // We were using external, flip to internal
1305 DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
1306 current_storage_path = DataManager::GetCurrentStoragePath();
1307 FreeStorage = Find_Partition_By_Path(current_storage_path);
1308 if (FreeStorage != NULL) {
1309 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1310 } else {
1311 LOGE("Unable to locate internal storage partition.\n");
1312 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1313 }
1314 }
1315 } else {
1316 // No dual storage and unable to mount storage, error!
1317 LOGE("Unable to mount storage.\n");
1318 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1319 }
1320 } else {
1321 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1322 }
1323 } else {
Dees_Troy51127312012-09-08 13:08:49 -04001324 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -04001325 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001326 if (!Write_Fstab())
1327 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001328 return;
1329}
1330
1331int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001332#ifdef TW_INCLUDE_CRYPTO
1333 int ret_val, password_len;
1334 char crypto_blkdev[255], cPassword[255];
1335 size_t result;
1336
1337 property_set("ro.crypto.state", "encrypted");
1338#ifdef TW_INCLUDE_JB_CRYPTO
1339 // No extra flags needed
1340#else
1341 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1342 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1343 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1344 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1345 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1346 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1347#endif
1348 strcpy(cPassword, Password.c_str());
1349 if (cryptfs_check_passwd(cPassword) != 0) {
1350 LOGE("Failed to decrypt data.\n");
1351 return -1;
1352 }
1353 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1354 if (strcmp(crypto_blkdev, "error") == 0) {
1355 LOGE("Error retrieving decrypted data block device.\n");
1356 } else {
1357 TWPartition* dat = Find_Partition_By_Path("/data");
1358 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001359 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001360 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1361 dat->Is_Decrypted = true;
1362 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001363 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001364 // Sleep for a bit so that the device will be ready
1365 sleep(1);
1366 Update_System_Details();
1367 } else
1368 LOGE("Unable to locate data partition.\n");
1369 }
1370 return 0;
1371#else
1372 LOGE("No crypto support was compiled into this build.\n");
1373 return -1;
1374#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001375 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001376}
1377
Dees_Troy38bd7602012-09-14 13:33:53 -04001378int TWPartitionManager::Fix_Permissions(void) {
1379 if (!Mount_By_Path("/data", true))
1380 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001381
Dees_Troy38bd7602012-09-14 13:33:53 -04001382 if (!Mount_By_Path("/system", true))
1383 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001384
Dees_Troy38bd7602012-09-14 13:33:53 -04001385 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001386 system("./sbin/fix_permissions.sh");
Dees_Troy38bd7602012-09-14 13:33:53 -04001387 ui_print("Done.\n\n");
1388 return true;
Dees_Troy4a2a1262012-09-18 09:33:47 -04001389}
Dees_Troy8170a922012-09-18 15:40:25 -04001390
1391//partial kangbang from system/vold
1392#ifndef CUSTOM_LUN_FILE
1393#define CUSTOM_LUN_FILE "/sys/devices/platform/usb_mass_storage/lun%d/file"
1394#endif
1395
1396int TWPartitionManager::usb_storage_enable(void) {
1397 int fd, has_dual, has_data_media;
1398 char lun_file[255];
1399 TWPartition* Part;
1400 string ext_path;
1401
1402 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual);
1403 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
1404 if (has_dual == 1 && has_data_media == 0) {
1405 Part = Find_Partition_By_Path(DataManager::GetSettingsStoragePath());
1406 if (Part == NULL) {
1407 LOGE("Unable to locate volume information.");
1408 return false;
1409 }
1410 if (!Part->UnMount(true))
1411 return false;
1412
1413 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1414 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1415 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1416 return false;
1417 }
1418
1419 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1420 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1421 close(fd);
1422 return false;
1423 }
1424 close(fd);
1425
1426 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1427 Part = Find_Partition_By_Path(ext_path);
1428 if (Part == NULL) {
1429 LOGE("Unable to locate volume information.\n");
1430 return false;
1431 }
1432 if (!Part->UnMount(true))
1433 return false;
1434
1435 sprintf(lun_file, CUSTOM_LUN_FILE, 1);
1436 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1437 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1438 return false;
1439 }
1440
1441 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1442 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1443 close(fd);
1444 return false;
1445 }
1446 close(fd);
1447 } else {
1448 if (has_data_media == 0)
1449 ext_path = DataManager::GetCurrentStoragePath();
1450 else
1451 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1452
1453 Part = Find_Partition_By_Path(ext_path);
1454 if (Part == NULL) {
1455 LOGE("Unable to locate volume information.\n");
1456 return false;
1457 }
1458 if (!Part->UnMount(true))
1459 return false;
1460
1461 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1462
1463 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1464 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1465 return false;
1466 }
1467
1468 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1469 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1470 close(fd);
1471 return false;
1472 }
1473 close(fd);
1474 }
1475 return true;
1476}
1477
1478int TWPartitionManager::usb_storage_disable(void) {
1479 int fd, index;
1480 char lun_file[255];
1481
1482 for (index=0; index<2; index++) {
1483 sprintf(lun_file, CUSTOM_LUN_FILE, index);
1484
1485 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1486 if (index == 0)
1487 LOGE("Unable to open ums lunfile '%s': (%s)", lun_file, strerror(errno));
1488 return false;
1489 }
1490
1491 char ch = 0;
1492 if (write(fd, &ch, 1) < 0) {
1493 if (index == 0)
1494 LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
1495 close(fd);
1496 return false;
1497 }
1498
1499 close(fd);
1500 }
1501 Mount_By_Path(DataManager::GetSettingsStoragePath(), true);
1502 Mount_By_Path(DataManager::GetCurrentStoragePath(), true);
1503 return true;
Dees_Troy812660f2012-09-20 09:55:17 -04001504}
1505
1506void TWPartitionManager::Mount_All_Storage(void) {
1507 std::vector<TWPartition*>::iterator iter;
1508
1509 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
1510 if ((*iter)->Is_Storage)
1511 (*iter)->Mount(false);
1512 }
Dees_Troy8170a922012-09-18 15:40:25 -04001513}