blob: 2e0219e019a0739671a76ab7aad442363bd70e2c [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_Troyc51f1f92012-09-20 15:32:13 -0400416 ui_print(" * Generating md5...\n");
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());
Dees_Troy43d8b002012-09-17 16:00:01 -0400420 if (system(command) == 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400421 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400422 return true;
423 } else {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400424 ui_print("MD5 Error!\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400425 return false;
426 }
427 } else {
428 char filename[512];
429 int index = 0;
430
431 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400432 while (TWFunc::Path_Exists(filename) == true) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400433 sprintf(command, "cd '%s' && md5sum %s%03i > %s%03i.md5",Backup_Folder.c_str(), Backup_Filename.c_str(), index, Backup_Filename.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400434 if (system(command) != 0) {
435 ui_print("MD5 Error.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400436 return false;
437 }
438 index++;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400439 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy43d8b002012-09-17 16:00:01 -0400440 }
441 if (index == 0) {
442 LOGE("Backup file: '%s' not found!\n", filename);
443 return false;
444 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400445 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400446 }
447 return true;
448}
449
450bool 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) {
451 time_t start, stop;
452
453 if (Part == NULL)
454 return true;
455
456 time(&start);
457
458 if (Part->Backup(Backup_Folder)) {
Dees_Troy8170a922012-09-18 15:40:25 -0400459 if (Part->Has_SubPartition) {
460 std::vector<TWPartition*>::iterator subpart;
461
462 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
463 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
464 if (!(*subpart)->Backup(Backup_Folder))
465 return false;
466 if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
467 return false;
468 }
469 }
470 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400471 time(&stop);
472 if (Part->Backup_Method == 1) {
473 *file_bytes_remaining -= Part->Backup_Size;
474 *file_time += (int) difftime(stop, start);
475 } else {
476 *img_bytes_remaining -= Part->Backup_Size;
477 *img_time += (int) difftime(stop, start);
478 }
479 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
480 } else {
481 return false;
482 }
483}
484
485int TWPartitionManager::Run_Backup(void) {
486 int check, do_md5, partition_count = 0;
487 string Backup_Folder, Backup_Name, Full_Backup_Path;
Dees_Troy8170a922012-09-18 15:40:25 -0400488 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 -0400489 unsigned long img_time = 0, file_time = 0;
490 TWPartition* backup_sys = NULL;
491 TWPartition* backup_data = NULL;
492 TWPartition* backup_cache = NULL;
493 TWPartition* backup_recovery = NULL;
494 TWPartition* backup_boot = NULL;
495 TWPartition* backup_andsec = NULL;
496 TWPartition* backup_sdext = NULL;
497 TWPartition* backup_sp1 = NULL;
498 TWPartition* backup_sp2 = NULL;
499 TWPartition* backup_sp3 = NULL;
500 TWPartition* storage = NULL;
Dees_Troy8170a922012-09-18 15:40:25 -0400501 std::vector<TWPartition*>::iterator subpart;
Dees_Troy43d8b002012-09-17 16:00:01 -0400502 struct tm *t;
503 time_t start, stop, seconds, total_start, total_stop;
504 seconds = time(0);
505 t = localtime(&seconds);
506
507 time(&total_start);
508
509 Update_System_Details();
510
511 if (!Mount_Current_Storage(true))
512 return false;
513
514 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400515 if (do_md5 == 0)
Dees_Troy43d8b002012-09-17 16:00:01 -0400516 do_md5 = true;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400517
Dees_Troy43d8b002012-09-17 16:00:01 -0400518 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
519 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
520 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
521 char timestamp[255];
522 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);
523 Backup_Name = timestamp;
524 }
525 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
526 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
527 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
528
529 ui_print("\n[BACKUP STARTED]\n");
530 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
531 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
532 LOGE("Failed to make backup folder.\n");
533 return false;
534 }
535
536 LOGI("Calculating backup details...\n");
537 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
538 if (check) {
539 backup_sys = Find_Partition_By_Path("/system");
540 if (backup_sys != NULL) {
541 partition_count++;
542 if (backup_sys->Backup_Method == 1)
543 file_bytes += backup_sys->Backup_Size;
544 else
545 img_bytes += backup_sys->Backup_Size;
546 } else {
547 LOGE("Unable to locate system partition.\n");
548 return false;
549 }
550 }
551 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
552 if (check) {
553 backup_data = Find_Partition_By_Path("/data");
554 if (backup_data != NULL) {
555 partition_count++;
Dees_Troy8170a922012-09-18 15:40:25 -0400556 subpart_size = 0;
557 if (backup_data->Has_SubPartition) {
558 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
559 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_data->Mount_Point)
560 subpart_size += (*subpart)->Backup_Size;
561 }
562 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400563 if (backup_data->Backup_Method == 1)
Dees_Troy8170a922012-09-18 15:40:25 -0400564 file_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400565 else
Dees_Troy8170a922012-09-18 15:40:25 -0400566 img_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400567 } else {
568 LOGE("Unable to locate data partition.\n");
569 return false;
570 }
571 }
572 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
573 if (check) {
574 backup_cache = Find_Partition_By_Path("/cache");
575 if (backup_cache != NULL) {
576 partition_count++;
577 if (backup_cache->Backup_Method == 1)
578 file_bytes += backup_cache->Backup_Size;
579 else
580 img_bytes += backup_cache->Backup_Size;
581 } else {
582 LOGE("Unable to locate cache partition.\n");
583 return false;
584 }
585 }
586 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
587 if (check) {
588 backup_recovery = Find_Partition_By_Path("/recovery");
589 if (backup_recovery != NULL) {
590 partition_count++;
591 if (backup_recovery->Backup_Method == 1)
592 file_bytes += backup_recovery->Backup_Size;
593 else
594 img_bytes += backup_recovery->Backup_Size;
595 } else {
596 LOGE("Unable to locate recovery partition.\n");
597 return false;
598 }
599 }
600 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
601 if (check) {
602 backup_boot = Find_Partition_By_Path("/boot");
603 if (backup_boot != NULL) {
604 partition_count++;
605 if (backup_boot->Backup_Method == 1)
606 file_bytes += backup_boot->Backup_Size;
607 else
608 img_bytes += backup_boot->Backup_Size;
609 } else {
610 LOGE("Unable to locate boot partition.\n");
611 return false;
612 }
613 }
614 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
615 if (check) {
616 backup_andsec = Find_Partition_By_Path("/and-sec");
617 if (backup_andsec != NULL) {
618 partition_count++;
619 if (backup_andsec->Backup_Method == 1)
620 file_bytes += backup_andsec->Backup_Size;
621 else
622 img_bytes += backup_andsec->Backup_Size;
623 } else {
624 LOGE("Unable to locate android secure partition.\n");
625 return false;
626 }
627 }
628 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
629 if (check) {
630 backup_sdext = Find_Partition_By_Path("/sd-ext");
631 if (backup_sdext != NULL) {
632 partition_count++;
633 if (backup_sdext->Backup_Method == 1)
634 file_bytes += backup_sdext->Backup_Size;
635 else
636 img_bytes += backup_sdext->Backup_Size;
637 } else {
638 LOGE("Unable to locate sd-ext partition.\n");
639 return false;
640 }
641 }
642#ifdef SP1_NAME
643 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
644 if (check) {
645 backup_sp1 = Find_Partition_By_Path(SP1_NAME);
646 if (backup_sp1 != NULL) {
647 partition_count++;
648 if (backup_sp1->Backup_Method == 1)
649 file_bytes += backup_sp1->Backup_Size;
650 else
651 img_bytes += backup_sp1->Backup_Size;
652 } else {
653 LOGE("Unable to locate %s partition.\n", SP1_NAME);
654 return false;
655 }
656 }
657#endif
658#ifdef SP2_NAME
659 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
660 if (check) {
661 backup_sp2 = Find_Partition_By_Path(SP2_NAME);
662 if (backup_sp2 != NULL) {
663 partition_count++;
664 if (backup_sp2->Backup_Method == 1)
665 file_bytes += backup_sp2->Backup_Size;
666 else
667 img_bytes += backup_sp2->Backup_Size;
668 } else {
669 LOGE("Unable to locate %s partition.\n", SP2_NAME);
670 return false;
671 }
672 }
673#endif
674#ifdef SP3_NAME
675 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
676 if (check) {
677 backup_sp3 = Find_Partition_By_Path(SP3_NAME);
678 if (backup_sp3 != NULL) {
679 partition_count++;
680 if (backup_sp3->Backup_Method == 1)
681 file_bytes += backup_sp3->Backup_Size;
682 else
683 img_bytes += backup_sp3->Backup_Size;
684 } else {
685 LOGE("Unable to locate %s partition.\n", SP3_NAME);
686 return false;
687 }
688 }
689#endif
690
691 if (partition_count == 0) {
692 ui_print("No partitions selected for backup.\n");
693 return false;
694 }
695 total_bytes = file_bytes + img_bytes;
696 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
697 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
698 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
699 if (storage != NULL) {
700 free_space = storage->Free;
701 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
702 } else {
703 LOGE("Unable to locate storage device.\n");
704 return false;
705 }
706 if (free_space + (32 * 1024 * 1024) < total_bytes) {
707 // We require an extra 32MB just in case
708 LOGE("Not enough free space on storage.\n");
709 return false;
710 }
711 img_bytes_remaining = img_bytes;
712 file_bytes_remaining = file_bytes;
713
714 if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
715 return false;
716 if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
717 return false;
718 if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
719 return false;
720 if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
721 return false;
722 if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
723 return false;
724 if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
725 return false;
726 if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
727 return false;
728 if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
729 return false;
730 if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
731 return false;
732 if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
733 return false;
734
735 // Average BPS
736 if (img_time == 0)
737 img_time = 1;
738 if (file_time == 0)
739 file_time = 1;
740 unsigned long int img_bps = img_bytes / img_time;
741 unsigned long int file_bps = file_bytes / file_time;
742
743 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
744 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
745
746 time(&total_stop);
747 int total_time = (int) difftime(total_stop, total_start);
748 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
749 actual_backup_size /= (1024LLU * 1024LLU);
750
751 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
752 Update_System_Details();
753 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
754 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400755}
756
Dees_Troy4a2a1262012-09-18 09:33:47 -0400757bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name) {
758 time_t Start, Stop;
759 time(&Start);
760 if (!Part->Restore(Restore_Name))
761 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400762 if (Part->Has_SubPartition) {
763 std::vector<TWPartition*>::iterator subpart;
764
765 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
766 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
767 if (!(*subpart)->Restore(Restore_Name))
768 return false;
769 }
770 }
771 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400772 time(&Stop);
773 ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
774 return true;
775}
776
Dees_Troy51a0e822012-09-05 15:24:24 -0400777int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400778 int check_md5, check, partition_count = 0;
779 TWPartition* restore_sys = NULL;
780 TWPartition* restore_data = NULL;
781 TWPartition* restore_cache = NULL;
782 TWPartition* restore_boot = NULL;
783 TWPartition* restore_andsec = NULL;
784 TWPartition* restore_sdext = NULL;
785 TWPartition* restore_sp1 = NULL;
786 TWPartition* restore_sp2 = NULL;
787 TWPartition* restore_sp3 = NULL;
788 time_t rStart, rStop;
789 time(&rStart);
Dees_Troy43d8b002012-09-17 16:00:01 -0400790
Dees_Troy4a2a1262012-09-18 09:33:47 -0400791 ui_print("\n[RESTORE STARTED]\n\n");
792 ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400793
Dees_Troy4a2a1262012-09-18 09:33:47 -0400794 if (!Mount_Current_Storage(true))
795 return false;
796
797 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
798 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
Dees_Troy63c8df72012-09-10 14:02:05 -0400799 if (check > 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400800 restore_sys = Find_Partition_By_Path("/system");
801 if (restore_sys == NULL) {
802 LOGE("Unable to locate system partition.\n");
803 return false;
804 }
805 partition_count++;
806 }
807 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
808 if (check > 0) {
809 restore_data = Find_Partition_By_Path("/data");
810 if (restore_data == NULL) {
811 LOGE("Unable to locate data partition.\n");
812 return false;
813 }
814 partition_count++;
815 }
816 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
817 if (check > 0) {
818 restore_cache = Find_Partition_By_Path("/cache");
819 if (restore_cache == NULL) {
820 LOGE("Unable to locate cache partition.\n");
821 return false;
822 }
823 partition_count++;
824 }
825 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
826 if (check > 0) {
827 restore_boot = Find_Partition_By_Path("/boot");
828 if (restore_boot == NULL) {
829 LOGE("Unable to locate boot partition.\n");
830 return false;
831 }
832 partition_count++;
833 }
834 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
835 if (check > 0) {
836 restore_andsec = Find_Partition_By_Path("/and-sec");
837 if (restore_andsec == NULL) {
838 LOGE("Unable to locate android secure partition.\n");
839 return false;
840 }
841 partition_count++;
842 }
843 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
844 if (check > 0) {
845 restore_sdext = Find_Partition_By_Path("/sd-ext");
846 if (restore_sdext == NULL) {
847 LOGE("Unable to locate sd-ext partition.\n");
848 return false;
849 }
850 partition_count++;
851 }
852#ifdef SP1_NAME
853 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
854 if (check > 0) {
855 restore_sp1 = Find_Partition_By_Path(SP1_NAME);
856 if (restore_sp1 == NULL) {
857 LOGE("Unable to locate %s partition.\n", SP1_NAME);
858 return false;
859 }
860 partition_count++;
861 }
862#endif
863#ifdef SP2_NAME
864 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
865 if (check > 0) {
866 restore_sp2 = Find_Partition_By_Path(SP2_NAME);
867 if (restore_sp2 == NULL) {
868 LOGE("Unable to locate %s partition.\n", SP2_NAME);
869 return false;
870 }
871 partition_count++;
872 }
873#endif
874#ifdef SP3_NAME
875 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
876 if (check > 0) {
877 restore_sp3 = Find_Partition_By_Path(SP3_NAME);
878 if (restore_sp3 == NULL) {
879 LOGE("Unable to locate %s partition.\n", SP3_NAME);
880 return false;
881 }
882 partition_count++;
883 }
884#endif
885
886 if (partition_count == 0) {
887 LOGE("No partitions selected for restore.\n");
888 return false;
889 }
890
891 if (check_md5 > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400892 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
Dees_Troy4a2a1262012-09-18 09:33:47 -0400893 ui_print("Verifying MD5...\n");
894 if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
895 return false;
896 if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
897 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400898 if (restore_data != NULL && restore_data->Has_SubPartition) {
899 std::vector<TWPartition*>::iterator subpart;
900
901 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
902 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_data->Mount_Point) {
903 if (!(*subpart)->Check_MD5(Restore_Name))
904 return false;
905 }
906 }
907 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400908 if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
909 return false;
910 if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
911 return false;
912 if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
913 return false;
914 if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
915 return false;
916 if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
917 return false;
918 if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
919 return false;
920 if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
921 return false;
922 ui_print("Done verifying MD5.\n");
923 } else
924 ui_print("Skipping MD5 check based on user setting.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400925
Dees_Troy4a2a1262012-09-18 09:33:47 -0400926 ui_print("Restoring %i partitions...\n", partition_count);
927 if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name))
928 return false;
929 if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name))
930 return false;
931 if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name))
932 return false;
933 if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name))
934 return false;
935 if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name))
936 return false;
937 if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name))
938 return false;
939 if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name))
940 return false;
941 if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name))
942 return false;
943 if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name))
944 return false;
Dees_Troy43d8b002012-09-17 16:00:01 -0400945
Dees_Troy43d8b002012-09-17 16:00:01 -0400946 Update_System_Details();
Dees_Troy4a2a1262012-09-18 09:33:47 -0400947 time(&rStop);
948 ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
Dees_Troy63c8df72012-09-10 14:02:05 -0400949 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400950}
951
952void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400953 // Start with the default values
954 int tw_restore_system = -1;
955 int tw_restore_data = -1;
956 int tw_restore_cache = -1;
957 int tw_restore_recovery = -1;
958 int tw_restore_boot = -1;
959 int tw_restore_andsec = -1;
960 int tw_restore_sdext = -1;
961 int tw_restore_sp1 = -1;
962 int tw_restore_sp2 = -1;
963 int tw_restore_sp3 = -1;
964 bool get_date = true;
965
966 DIR* d;
967 d = opendir(Restore_Name.c_str());
968 if (d == NULL)
969 {
970 LOGE("Error opening %s\n", Restore_Name.c_str());
971 return;
972 }
973
974 struct dirent* de;
975 while ((de = readdir(d)) != NULL)
976 {
977 // Strip off three components
978 char str[256];
979 char* label;
980 char* fstype = NULL;
981 char* extn = NULL;
982 char* ptr;
983
984 strcpy(str, de->d_name);
985 if (strlen(str) <= 2)
986 continue;
987
988 if (get_date) {
989 char file_path[255];
990 struct stat st;
991
992 strcpy(file_path, Restore_Name.c_str());
993 strcat(file_path, "/");
994 strcat(file_path, str);
995 stat(file_path, &st);
996 string backup_date = ctime((const time_t*)(&st.st_mtime));
997 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
998 get_date = false;
999 }
1000
1001 label = str;
1002 ptr = label;
1003 while (*ptr && *ptr != '.') ptr++;
1004 if (*ptr == '.')
1005 {
1006 *ptr = 0x00;
1007 ptr++;
1008 fstype = ptr;
1009 }
1010 while (*ptr && *ptr != '.') ptr++;
1011 if (*ptr == '.')
1012 {
1013 *ptr = 0x00;
1014 ptr++;
1015 extn = ptr;
1016 }
1017
1018 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
1019
1020 TWPartition* Part = Find_Partition_By_Path(label);
1021 if (Part == NULL)
1022 {
1023 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
1024 continue;
1025 }
1026
1027 Part->Backup_FileName = de->d_name;
1028 if (strlen(extn) > 3) {
1029 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
1030 }
1031
1032 // Now, we just need to find the correct label
1033 if (Part->Mount_Point == "/system")
1034 tw_restore_system = 1;
1035 if (Part->Mount_Point == "/data")
1036 tw_restore_data = 1;
1037 if (Part->Mount_Point == "/cache")
1038 tw_restore_cache = 1;
1039 if (Part->Mount_Point == "/recovery")
1040 tw_restore_recovery = 1;
1041 if (Part->Mount_Point == "/boot")
1042 tw_restore_boot = 1;
1043 if (Part->Mount_Point == "/.android_secure")
1044 tw_restore_andsec = 1;
1045 if (Part->Mount_Point == "/sd-ext")
1046 tw_restore_sdext = 1;
1047#ifdef SP1_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001048 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP1_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001049 tw_restore_sp1 = 1;
1050#endif
1051#ifdef SP2_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001052 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP2_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001053 tw_restore_sp2 = 1;
1054#endif
1055#ifdef SP3_NAME
Dees_Troy38bd7602012-09-14 13:33:53 -04001056 if (Part->Mount_Point == TWFunc::Get_Root_Path(SP3_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001057 tw_restore_sp3 = 1;
1058#endif
1059 }
1060 closedir(d);
1061
1062 // Set the final values
1063 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
1064 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
1065 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
1066 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
1067 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
1068 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
1069 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
1070 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
1071 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
1072 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
1073
Dees_Troy51a0e822012-09-05 15:24:24 -04001074 return;
1075}
1076
1077int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001078 std::vector<TWPartition*>::iterator iter;
1079 int ret = false;
1080 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -04001081 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -04001082
1083 // Iterate through all partitions
1084 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -04001085 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001086 ret = (*iter)->Wipe();
1087 found = true;
1088 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
1089 (*iter)->Wipe();
1090 }
1091 }
1092 if (found) {
1093 return ret;
1094 } else
1095 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
1096 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001097}
1098
1099int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001100 TWPartition* Part = Find_Partition_By_Block(Block);
1101
1102 if (Part) {
1103 if (Part->Has_SubPartition) {
1104 std::vector<TWPartition*>::iterator subpart;
1105
1106 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1107 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1108 (*subpart)->Wipe();
1109 }
1110 return Part->Wipe();
1111 } else
1112 return Part->Wipe();
1113 }
1114 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1115 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001116}
1117
1118int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001119 TWPartition* Part = Find_Partition_By_Name(Name);
1120
1121 if (Part) {
1122 if (Part->Has_SubPartition) {
1123 std::vector<TWPartition*>::iterator subpart;
1124
1125 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1126 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1127 (*subpart)->Wipe();
1128 }
1129 return Part->Wipe();
1130 } else
1131 return Part->Wipe();
1132 }
1133 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1134 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001135}
1136
1137int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001138 std::vector<TWPartition*>::iterator iter;
1139 int ret = true;
1140
1141 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001142 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001143 if (!(*iter)->Wipe())
1144 ret = false;
1145 }
1146 }
1147 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001148}
1149
Dees_Troy38bd7602012-09-14 13:33:53 -04001150int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1151 struct stat st;
1152
1153 if (!Mount_By_Path("/data", true))
1154 return false;
1155
1156 if (!Mount_By_Path("/cache", true))
1157 return false;
1158
1159 ui_print("\nWiping Dalvik Cache Directories...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001160 system("rm -rf /data/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001161 ui_print("Cleaned: /data/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001162 system("rm -rf /cache/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001163 ui_print("Cleaned: /cache/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001164 system("rm -rf /cache/dc");
Dees_Troy38bd7602012-09-14 13:33:53 -04001165 ui_print("Cleaned: /cache/dc\n");
1166
1167 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1168 if (sdext != NULL) {
1169 if (sdext->Is_Present && sdext->Mount(false)) {
1170 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001171 system("rm -rf /sd-ext/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001172 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1173 }
1174 }
1175 }
1176 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1177 return true;
1178}
1179
1180int TWPartitionManager::Wipe_Rotate_Data(void) {
1181 if (!Mount_By_Path("/data", true))
1182 return false;
1183
Dees_Troy8170a922012-09-18 15:40:25 -04001184 system("rm -r /data/misc/akmd*");
1185 system("rm -r /data/misc/rild*");
1186 system("rm -r /data/misc/rild*");
Dees_Troy38bd7602012-09-14 13:33:53 -04001187 ui_print("Rotation data wiped.\n");
1188 return true;
1189}
1190
1191int TWPartitionManager::Wipe_Battery_Stats(void) {
1192 struct stat st;
1193
1194 if (!Mount_By_Path("/data", true))
1195 return false;
1196
1197 if (0 != stat("/data/system/batterystats.bin", &st)) {
1198 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1199 } else {
1200 remove("/data/system/batterystats.bin");
1201 ui_print("Cleared battery stats.\n");
1202 }
1203 return true;
1204}
1205
1206int TWPartitionManager::Format_Data(void) {
1207 TWPartition* dat = Find_Partition_By_Path("/data");
1208
1209 if (dat != NULL) {
1210 if (!dat->UnMount(true))
1211 return false;
1212
1213 return dat->Wipe_Encryption();
1214 } else {
1215 LOGE("Unable to locate /data.\n");
1216 return false;
1217 }
1218 return false;
1219}
1220
1221int TWPartitionManager::Wipe_Media_From_Data(void) {
1222 TWPartition* dat = Find_Partition_By_Path("/data");
1223
1224 if (dat != NULL) {
1225 if (!dat->Has_Data_Media) {
1226 LOGE("This device does not have /data/media\n");
1227 return false;
1228 }
1229 if (!dat->Mount(true))
1230 return false;
1231
1232 ui_print("Wiping internal storage -- /data/media...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001233 system("rm -rf /data/media");
1234 system("cd /data && mkdir media && chmod 775 media");
Dees_Troy38bd7602012-09-14 13:33:53 -04001235 if (dat->Has_Data_Media) {
1236 dat->Recreate_Media_Folder();
1237 }
1238 return true;
1239 } else {
1240 LOGE("Unable to locate /data.\n");
1241 return false;
1242 }
1243 return false;
1244}
1245
Dees_Troy51a0e822012-09-05 15:24:24 -04001246void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001247 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001248 return;
1249}
1250
1251void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001252 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001253 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001254
Dees_Troy32c8eb82012-09-11 15:28:06 -04001255 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001256 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001257 if ((*iter)->Can_Be_Mounted) {
1258 (*iter)->Update_Size(true);
1259 if ((*iter)->Mount_Point == "/system") {
1260 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1261 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1262 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1263 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1264 } else if ((*iter)->Mount_Point == "/cache") {
1265 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1266 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1267 } else if ((*iter)->Mount_Point == "/sd-ext") {
1268 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1269 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1270 if ((*iter)->Backup_Size == 0) {
1271 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1272 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1273 } else
1274 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
Dees_Troy8170a922012-09-18 15:40:25 -04001275 } else if ((*iter)->Mount_Point == "/and-sec") {
1276 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1277 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1278 if ((*iter)->Backup_Size == 0) {
1279 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 0);
1280 DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
1281 } else
1282 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 1);
Dees_Troy51127312012-09-08 13:08:49 -04001283 }
1284 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001285 }
Dees_Troy51127312012-09-08 13:08:49 -04001286 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1287 string current_storage_path = DataManager::GetCurrentStoragePath();
1288 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
Dees_Troy8170a922012-09-18 15:40:25 -04001289 if (FreeStorage != NULL) {
1290 // Attempt to mount storage
1291 if (!FreeStorage->Mount(false)) {
1292 // We couldn't mount storage... check to see if we have dual storage
1293 int has_dual_storage;
1294 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual_storage);
1295 if (has_dual_storage == 1) {
1296 // We have dual storage, see if we're using the internal storage that should always be present
1297 if (current_storage_path == DataManager::GetSettingsStoragePath()) {
1298 // Not able to use internal, so error!
1299 LOGE("Unable to mount internal storage.\n");
1300 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1301 } else {
1302 // We were using external, flip to internal
1303 DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
1304 current_storage_path = DataManager::GetCurrentStoragePath();
1305 FreeStorage = Find_Partition_By_Path(current_storage_path);
1306 if (FreeStorage != NULL) {
1307 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1308 } else {
1309 LOGE("Unable to locate internal storage partition.\n");
1310 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1311 }
1312 }
1313 } else {
1314 // No dual storage and unable to mount storage, error!
1315 LOGE("Unable to mount storage.\n");
1316 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1317 }
1318 } else {
1319 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1320 }
1321 } else {
Dees_Troy51127312012-09-08 13:08:49 -04001322 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -04001323 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001324 if (!Write_Fstab())
1325 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001326 return;
1327}
1328
1329int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001330#ifdef TW_INCLUDE_CRYPTO
1331 int ret_val, password_len;
1332 char crypto_blkdev[255], cPassword[255];
1333 size_t result;
1334
1335 property_set("ro.crypto.state", "encrypted");
1336#ifdef TW_INCLUDE_JB_CRYPTO
1337 // No extra flags needed
1338#else
1339 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1340 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1341 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1342 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1343 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1344 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1345#endif
1346 strcpy(cPassword, Password.c_str());
1347 if (cryptfs_check_passwd(cPassword) != 0) {
1348 LOGE("Failed to decrypt data.\n");
1349 return -1;
1350 }
1351 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1352 if (strcmp(crypto_blkdev, "error") == 0) {
1353 LOGE("Error retrieving decrypted data block device.\n");
1354 } else {
1355 TWPartition* dat = Find_Partition_By_Path("/data");
1356 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001357 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001358 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1359 dat->Is_Decrypted = true;
1360 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001361 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001362 // Sleep for a bit so that the device will be ready
1363 sleep(1);
1364 Update_System_Details();
1365 } else
1366 LOGE("Unable to locate data partition.\n");
1367 }
1368 return 0;
1369#else
1370 LOGE("No crypto support was compiled into this build.\n");
1371 return -1;
1372#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001373 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001374}
1375
Dees_Troy38bd7602012-09-14 13:33:53 -04001376int TWPartitionManager::Fix_Permissions(void) {
1377 if (!Mount_By_Path("/data", true))
1378 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001379
Dees_Troy38bd7602012-09-14 13:33:53 -04001380 if (!Mount_By_Path("/system", true))
1381 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001382
Dees_Troy38bd7602012-09-14 13:33:53 -04001383 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001384 system("./sbin/fix_permissions.sh");
Dees_Troy38bd7602012-09-14 13:33:53 -04001385 ui_print("Done.\n\n");
1386 return true;
Dees_Troy4a2a1262012-09-18 09:33:47 -04001387}
Dees_Troy8170a922012-09-18 15:40:25 -04001388
1389//partial kangbang from system/vold
1390#ifndef CUSTOM_LUN_FILE
1391#define CUSTOM_LUN_FILE "/sys/devices/platform/usb_mass_storage/lun%d/file"
1392#endif
1393
1394int TWPartitionManager::usb_storage_enable(void) {
1395 int fd, has_dual, has_data_media;
1396 char lun_file[255];
1397 TWPartition* Part;
1398 string ext_path;
1399
1400 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual);
1401 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
1402 if (has_dual == 1 && has_data_media == 0) {
1403 Part = Find_Partition_By_Path(DataManager::GetSettingsStoragePath());
1404 if (Part == NULL) {
1405 LOGE("Unable to locate volume information.");
1406 return false;
1407 }
1408 if (!Part->UnMount(true))
1409 return false;
1410
1411 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1412 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1413 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1414 return false;
1415 }
1416
1417 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1418 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1419 close(fd);
1420 return false;
1421 }
1422 close(fd);
1423
1424 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1425 Part = Find_Partition_By_Path(ext_path);
1426 if (Part == NULL) {
1427 LOGE("Unable to locate volume information.\n");
1428 return false;
1429 }
1430 if (!Part->UnMount(true))
1431 return false;
1432
1433 sprintf(lun_file, CUSTOM_LUN_FILE, 1);
1434 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1435 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1436 return false;
1437 }
1438
1439 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1440 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1441 close(fd);
1442 return false;
1443 }
1444 close(fd);
1445 } else {
1446 if (has_data_media == 0)
1447 ext_path = DataManager::GetCurrentStoragePath();
1448 else
1449 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1450
1451 Part = Find_Partition_By_Path(ext_path);
1452 if (Part == NULL) {
1453 LOGE("Unable to locate volume information.\n");
1454 return false;
1455 }
1456 if (!Part->UnMount(true))
1457 return false;
1458
1459 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1460
1461 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1462 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1463 return false;
1464 }
1465
1466 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1467 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1468 close(fd);
1469 return false;
1470 }
1471 close(fd);
1472 }
1473 return true;
1474}
1475
1476int TWPartitionManager::usb_storage_disable(void) {
1477 int fd, index;
1478 char lun_file[255];
1479
1480 for (index=0; index<2; index++) {
1481 sprintf(lun_file, CUSTOM_LUN_FILE, index);
1482
1483 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1484 if (index == 0)
1485 LOGE("Unable to open ums lunfile '%s': (%s)", lun_file, strerror(errno));
1486 return false;
1487 }
1488
1489 char ch = 0;
1490 if (write(fd, &ch, 1) < 0) {
1491 if (index == 0)
1492 LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
1493 close(fd);
1494 return false;
1495 }
1496
1497 close(fd);
1498 }
1499 Mount_By_Path(DataManager::GetSettingsStoragePath(), true);
1500 Mount_By_Path(DataManager::GetCurrentStoragePath(), true);
1501 return true;
Dees_Troy812660f2012-09-20 09:55:17 -04001502}
1503
1504void TWPartitionManager::Mount_All_Storage(void) {
1505 std::vector<TWPartition*>::iterator iter;
1506
1507 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
1508 if ((*iter)->Is_Storage)
1509 (*iter)->Mount(false);
1510 }
Dees_Troy8170a922012-09-18 15:40:25 -04001511}