blob: 968507274ef464112f610e8c370bcdbd04ab768e [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 ");
Dees_Troye58d5262012-09-21 12:27:57 -0400150 if (Part->Has_Android_Secure)
151 printf("Has_Android_Secure ");
Dees_Troy8170a922012-09-18 15:40:25 -0400152 if (Part->Is_Storage)
153 printf("Is_Storage ");
154 printf("\n");
155 if (!Part->SubPartition_Of.empty())
156 printf(" SubPartition_Of: %s\n", Part->SubPartition_Of.c_str());
157 if (!Part->Symlink_Path.empty())
158 printf(" Symlink_Path: %s\n", Part->Symlink_Path.c_str());
159 if (!Part->Symlink_Mount_Point.empty())
160 printf(" Symlink_Mount_Point: %s\n", Part->Symlink_Mount_Point.c_str());
161 if (!Part->Primary_Block_Device.empty())
162 printf(" Primary_Block_Device: %s\n", Part->Primary_Block_Device.c_str());
163 if (!Part->Alternate_Block_Device.empty())
164 printf(" Alternate_Block_Device: %s\n", Part->Alternate_Block_Device.c_str());
165 if (!Part->Decrypted_Block_Device.empty())
166 printf(" Decrypted_Block_Device: %s\n", Part->Decrypted_Block_Device.c_str());
167 if (Part->Length != 0)
168 printf(" Length: %i\n", Part->Length);
169 if (!Part->Display_Name.empty())
170 printf(" Display_Name: %s\n", Part->Display_Name.c_str());
Dees_Troye58d5262012-09-21 12:27:57 -0400171 if (!Part->Backup_Path.empty())
172 printf(" Backup_Path: %s\n", Part->Backup_Path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -0400173 if (!Part->Backup_Name.empty())
174 printf(" Backup_Name: %s\n", Part->Backup_Name.c_str());
175 if (!Part->Backup_FileName.empty())
176 printf(" Backup_FileName: %s\n", Part->Backup_FileName.c_str());
177 if (!Part->MTD_Name.empty())
178 printf(" MTD_Name: %s\n", Part->MTD_Name.c_str());
179 if (!Part->Storage_Path.empty())
180 printf(" Storage_Path: %s\n", Part->Storage_Path.c_str());
181 if (!Part->Current_File_System.empty())
182 printf(" Current_File_System: %s\n", Part->Current_File_System.c_str());
183 if (!Part->Fstab_File_System.empty())
184 printf(" Fstab_File_System: %s\n", Part->Fstab_File_System.c_str());
185 if (Part->Format_Block_Size != 0)
186 printf(" Format_Block_Size: %i\n", Part->Format_Block_Size);
187 } else {
188 printf("%s | %s | Size: %iMB\n", Part->Mount_Point.c_str(), Part->Actual_Block_Device.c_str(), (int)(Part->Size / mb));
189 }
190 string back_meth = Part->Backup_Method_By_Name();
191 printf(" Backup_Method: %s\n\n", back_meth.c_str());
192}
193
Dees_Troy51a0e822012-09-05 15:24:24 -0400194int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400195 std::vector<TWPartition*>::iterator iter;
196 int ret = false;
197 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400198 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400199
Dees_Troy43d8b002012-09-17 16:00:01 -0400200 if (Local_Path == "/tmp")
201 return true;
202
Dees_Troy5bf43922012-09-07 16:07:55 -0400203 // Iterate through all partitions
204 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400205 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400206 ret = (*iter)->Mount(Display_Error);
207 found = true;
Dees_Troy51127312012-09-08 13:08:49 -0400208 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400209 (*iter)->Mount(Display_Error);
Dees_Troy51127312012-09-08 13:08:49 -0400210 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400211 }
212 if (found) {
213 return ret;
214 } else if (Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400215 LOGE("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400216 } else {
Dees_Troy51127312012-09-08 13:08:49 -0400217 LOGI("Mount: Unable to find partition for path '%s'\n", Local_Path.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400218 }
219 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400220}
221
222int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400223 TWPartition* Part = Find_Partition_By_Block(Block);
Dees_Troy5bf43922012-09-07 16:07:55 -0400224
Dees_Troy51127312012-09-08 13:08:49 -0400225 if (Part) {
226 if (Part->Has_SubPartition) {
227 std::vector<TWPartition*>::iterator subpart;
228
229 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
230 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
231 (*subpart)->Mount(Display_Error);
232 }
233 return Part->Mount(Display_Error);
234 } else
235 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400236 }
237 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400238 LOGE("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400239 else
Dees_Troy51127312012-09-08 13:08:49 -0400240 LOGI("Mount: Unable to find partition for block '%s'\n", Block.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400241 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400242}
243
244int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400245 TWPartition* Part = Find_Partition_By_Name(Name);
Dees_Troy5bf43922012-09-07 16:07:55 -0400246
Dees_Troy51127312012-09-08 13:08:49 -0400247 if (Part) {
248 if (Part->Has_SubPartition) {
249 std::vector<TWPartition*>::iterator subpart;
250
251 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
252 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
253 (*subpart)->Mount(Display_Error);
254 }
255 return Part->Mount(Display_Error);
256 } else
257 return Part->Mount(Display_Error);
Dees_Troy5bf43922012-09-07 16:07:55 -0400258 }
259 if (Display_Error)
Dees_Troy51127312012-09-08 13:08:49 -0400260 LOGE("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400261 else
Dees_Troy51127312012-09-08 13:08:49 -0400262 LOGI("Mount: Unable to find partition for name '%s'\n", Name.c_str());
Dees_Troy5bf43922012-09-07 16:07:55 -0400263 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400264}
265
266int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400267 std::vector<TWPartition*>::iterator iter;
268 int ret = false;
269 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -0400270 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy51127312012-09-08 13:08:49 -0400271
272 // Iterate through all partitions
273 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400274 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troy51127312012-09-08 13:08:49 -0400275 ret = (*iter)->UnMount(Display_Error);
276 found = true;
277 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
278 (*iter)->UnMount(Display_Error);
279 }
280 }
281 if (found) {
282 return ret;
283 } else if (Display_Error) {
284 LOGE("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
285 } else {
286 LOGI("UnMount: Unable to find partition for path '%s'\n", Local_Path.c_str());
287 }
288 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400289}
290
291int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400292 TWPartition* Part = Find_Partition_By_Block(Block);
293
294 if (Part) {
295 if (Part->Has_SubPartition) {
296 std::vector<TWPartition*>::iterator subpart;
297
298 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
299 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
300 (*subpart)->UnMount(Display_Error);
301 }
302 return Part->UnMount(Display_Error);
303 } else
304 return Part->UnMount(Display_Error);
305 }
306 if (Display_Error)
307 LOGE("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
308 else
309 LOGI("UnMount: Unable to find partition for block '%s'\n", Block.c_str());
310 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400311}
312
313int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400314 TWPartition* Part = Find_Partition_By_Name(Name);
315
316 if (Part) {
317 if (Part->Has_SubPartition) {
318 std::vector<TWPartition*>::iterator subpart;
319
320 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
321 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
322 (*subpart)->UnMount(Display_Error);
323 }
324 return Part->UnMount(Display_Error);
325 } else
326 return Part->UnMount(Display_Error);
327 }
328 if (Display_Error)
329 LOGE("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
330 else
331 LOGI("UnMount: Unable to find partition for name '%s'\n", Name.c_str());
332 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400333}
334
335int TWPartitionManager::Is_Mounted_By_Path(string Path) {
Dees_Troy51127312012-09-08 13:08:49 -0400336 TWPartition* Part = Find_Partition_By_Path(Path);
337
338 if (Part)
339 return Part->Is_Mounted();
340 else
341 LOGI("Is_Mounted: Unable to find partition for path '%s'\n", Path.c_str());
342 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400343}
344
345int TWPartitionManager::Is_Mounted_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400346 TWPartition* Part = Find_Partition_By_Block(Block);
347
348 if (Part)
349 return Part->Is_Mounted();
350 else
351 LOGI("Is_Mounted: Unable to find partition for block '%s'\n", Block.c_str());
352 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400353}
354
355int TWPartitionManager::Is_Mounted_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400356 TWPartition* Part = Find_Partition_By_Name(Name);
357
358 if (Part)
359 return Part->Is_Mounted();
360 else
361 LOGI("Is_Mounted: Unable to find partition for name '%s'\n", Name.c_str());
362 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400363}
364
Dees_Troy5bf43922012-09-07 16:07:55 -0400365int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
Dees_Troy51127312012-09-08 13:08:49 -0400366 string current_storage_path = DataManager::GetCurrentStoragePath();
367
368 if (Mount_By_Path(current_storage_path, Display_Error)) {
369 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
370 if (FreeStorage)
371 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
372 return true;
373 }
374 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400375}
376
Dees_Troy5bf43922012-09-07 16:07:55 -0400377int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
378 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
379}
380
381TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
382 std::vector<TWPartition*>::iterator iter;
Dees_Troy38bd7602012-09-14 13:33:53 -0400383 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy5bf43922012-09-07 16:07:55 -0400384
385 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -0400386 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path))
Dees_Troy5bf43922012-09-07 16:07:55 -0400387 return (*iter);
388 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400389 return NULL;
390}
391
Dees_Troy5bf43922012-09-07 16:07:55 -0400392TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51127312012-09-08 13:08:49 -0400393 std::vector<TWPartition*>::iterator iter;
394
395 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -0400396 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 -0400397 return (*iter);
398 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400399 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400400}
401
402TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
Dees_Troy51127312012-09-08 13:08:49 -0400403 std::vector<TWPartition*>::iterator iter;
404
405 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
406 if ((*iter)->Display_Name == Name)
407 return (*iter);
408 }
Dees_Troy5bf43922012-09-07 16:07:55 -0400409 return NULL;
410}
Dees_Troy51a0e822012-09-05 15:24:24 -0400411
Dees_Troy43d8b002012-09-17 16:00:01 -0400412bool TWPartitionManager::Make_MD5(bool generate_md5, string Backup_Folder, string Backup_Filename)
413{
414 char command[512];
415 string Full_File = Backup_Folder + Backup_Filename;
416
Dees_Troy4a2a1262012-09-18 09:33:47 -0400417 if (!generate_md5)
Dees_Troy43d8b002012-09-17 16:00:01 -0400418 return true;
Dees_Troy43d8b002012-09-17 16:00:01 -0400419
Dees_Troyc51f1f92012-09-20 15:32:13 -0400420 ui_print(" * Generating md5...\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400421
422 if (TWFunc::Path_Exists(Full_File)) {
423 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 -0400424 if (system(command) == 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400425 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400426 return true;
427 } else {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400428 ui_print("MD5 Error!\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400429 return false;
430 }
431 } else {
432 char filename[512];
433 int index = 0;
434
435 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400436 while (TWFunc::Path_Exists(filename) == true) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400437 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 -0400438 if (system(command) != 0) {
439 ui_print("MD5 Error.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400440 return false;
441 }
442 index++;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400443 sprintf(filename, "%s%03i", Full_File.c_str(), index);
Dees_Troy43d8b002012-09-17 16:00:01 -0400444 }
445 if (index == 0) {
446 LOGE("Backup file: '%s' not found!\n", filename);
447 return false;
448 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400449 ui_print("MD5 Created.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400450 }
451 return true;
452}
453
454bool 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) {
455 time_t start, stop;
456
457 if (Part == NULL)
458 return true;
459
460 time(&start);
461
462 if (Part->Backup(Backup_Folder)) {
Dees_Troy8170a922012-09-18 15:40:25 -0400463 if (Part->Has_SubPartition) {
464 std::vector<TWPartition*>::iterator subpart;
465
466 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
467 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
468 if (!(*subpart)->Backup(Backup_Folder))
469 return false;
470 if (!Make_MD5(generate_md5, Backup_Folder, (*subpart)->Backup_FileName))
471 return false;
472 }
473 }
474 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400475 time(&stop);
476 if (Part->Backup_Method == 1) {
477 *file_bytes_remaining -= Part->Backup_Size;
478 *file_time += (int) difftime(stop, start);
479 } else {
480 *img_bytes_remaining -= Part->Backup_Size;
481 *img_time += (int) difftime(stop, start);
482 }
483 return Make_MD5(generate_md5, Backup_Folder, Part->Backup_FileName);
484 } else {
485 return false;
486 }
487}
488
489int TWPartitionManager::Run_Backup(void) {
490 int check, do_md5, partition_count = 0;
491 string Backup_Folder, Backup_Name, Full_Backup_Path;
Dees_Troy8170a922012-09-18 15:40:25 -0400492 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 -0400493 unsigned long img_time = 0, file_time = 0;
494 TWPartition* backup_sys = NULL;
495 TWPartition* backup_data = NULL;
496 TWPartition* backup_cache = NULL;
497 TWPartition* backup_recovery = NULL;
498 TWPartition* backup_boot = NULL;
499 TWPartition* backup_andsec = NULL;
500 TWPartition* backup_sdext = NULL;
501 TWPartition* backup_sp1 = NULL;
502 TWPartition* backup_sp2 = NULL;
503 TWPartition* backup_sp3 = NULL;
504 TWPartition* storage = NULL;
Dees_Troy8170a922012-09-18 15:40:25 -0400505 std::vector<TWPartition*>::iterator subpart;
Dees_Troy43d8b002012-09-17 16:00:01 -0400506 struct tm *t;
507 time_t start, stop, seconds, total_start, total_stop;
508 seconds = time(0);
509 t = localtime(&seconds);
510
511 time(&total_start);
512
513 Update_System_Details();
514
515 if (!Mount_Current_Storage(true))
516 return false;
517
518 DataManager::GetValue(TW_SKIP_MD5_GENERATE_VAR, do_md5);
Dees_Troy4a2a1262012-09-18 09:33:47 -0400519 if (do_md5 == 0)
Dees_Troy43d8b002012-09-17 16:00:01 -0400520 do_md5 = true;
Dees_Troy4a2a1262012-09-18 09:33:47 -0400521
Dees_Troy43d8b002012-09-17 16:00:01 -0400522 DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder);
523 DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
524 if (Backup_Name == "(Current Date)" || Backup_Name == "0") {
525 char timestamp[255];
526 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);
527 Backup_Name = timestamp;
528 }
529 LOGI("Backup Name is: '%s'\n", Backup_Name.c_str());
530 Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/";
531 LOGI("Full_Backup_Path is: '%s'\n", Full_Backup_Path.c_str());
532
533 ui_print("\n[BACKUP STARTED]\n");
534 ui_print(" * Backup Folder: %s\n", Full_Backup_Path.c_str());
535 if (!TWFunc::Recursive_Mkdir(Full_Backup_Path)) {
536 LOGE("Failed to make backup folder.\n");
537 return false;
538 }
539
540 LOGI("Calculating backup details...\n");
541 DataManager::GetValue(TW_BACKUP_SYSTEM_VAR, check);
542 if (check) {
543 backup_sys = Find_Partition_By_Path("/system");
544 if (backup_sys != NULL) {
545 partition_count++;
546 if (backup_sys->Backup_Method == 1)
547 file_bytes += backup_sys->Backup_Size;
548 else
549 img_bytes += backup_sys->Backup_Size;
550 } else {
551 LOGE("Unable to locate system partition.\n");
552 return false;
553 }
554 }
555 DataManager::GetValue(TW_BACKUP_DATA_VAR, check);
556 if (check) {
557 backup_data = Find_Partition_By_Path("/data");
558 if (backup_data != NULL) {
559 partition_count++;
Dees_Troy8170a922012-09-18 15:40:25 -0400560 subpart_size = 0;
561 if (backup_data->Has_SubPartition) {
562 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
563 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == backup_data->Mount_Point)
564 subpart_size += (*subpart)->Backup_Size;
565 }
566 }
Dees_Troy43d8b002012-09-17 16:00:01 -0400567 if (backup_data->Backup_Method == 1)
Dees_Troy8170a922012-09-18 15:40:25 -0400568 file_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400569 else
Dees_Troy8170a922012-09-18 15:40:25 -0400570 img_bytes += backup_data->Backup_Size + subpart_size;
Dees_Troy43d8b002012-09-17 16:00:01 -0400571 } else {
572 LOGE("Unable to locate data partition.\n");
573 return false;
574 }
575 }
576 DataManager::GetValue(TW_BACKUP_CACHE_VAR, check);
577 if (check) {
578 backup_cache = Find_Partition_By_Path("/cache");
579 if (backup_cache != NULL) {
580 partition_count++;
581 if (backup_cache->Backup_Method == 1)
582 file_bytes += backup_cache->Backup_Size;
583 else
584 img_bytes += backup_cache->Backup_Size;
585 } else {
586 LOGE("Unable to locate cache partition.\n");
587 return false;
588 }
589 }
590 DataManager::GetValue(TW_BACKUP_RECOVERY_VAR, check);
591 if (check) {
592 backup_recovery = Find_Partition_By_Path("/recovery");
593 if (backup_recovery != NULL) {
594 partition_count++;
595 if (backup_recovery->Backup_Method == 1)
596 file_bytes += backup_recovery->Backup_Size;
597 else
598 img_bytes += backup_recovery->Backup_Size;
599 } else {
600 LOGE("Unable to locate recovery partition.\n");
601 return false;
602 }
603 }
604 DataManager::GetValue(TW_BACKUP_BOOT_VAR, check);
605 if (check) {
606 backup_boot = Find_Partition_By_Path("/boot");
607 if (backup_boot != NULL) {
608 partition_count++;
609 if (backup_boot->Backup_Method == 1)
610 file_bytes += backup_boot->Backup_Size;
611 else
612 img_bytes += backup_boot->Backup_Size;
613 } else {
614 LOGE("Unable to locate boot partition.\n");
615 return false;
616 }
617 }
618 DataManager::GetValue(TW_BACKUP_ANDSEC_VAR, check);
619 if (check) {
620 backup_andsec = Find_Partition_By_Path("/and-sec");
621 if (backup_andsec != NULL) {
622 partition_count++;
623 if (backup_andsec->Backup_Method == 1)
624 file_bytes += backup_andsec->Backup_Size;
625 else
626 img_bytes += backup_andsec->Backup_Size;
627 } else {
628 LOGE("Unable to locate android secure partition.\n");
629 return false;
630 }
631 }
632 DataManager::GetValue(TW_BACKUP_SDEXT_VAR, check);
633 if (check) {
634 backup_sdext = Find_Partition_By_Path("/sd-ext");
635 if (backup_sdext != NULL) {
636 partition_count++;
637 if (backup_sdext->Backup_Method == 1)
638 file_bytes += backup_sdext->Backup_Size;
639 else
640 img_bytes += backup_sdext->Backup_Size;
641 } else {
642 LOGE("Unable to locate sd-ext partition.\n");
643 return false;
644 }
645 }
646#ifdef SP1_NAME
647 DataManager::GetValue(TW_BACKUP_SP1_VAR, check);
648 if (check) {
649 backup_sp1 = Find_Partition_By_Path(SP1_NAME);
650 if (backup_sp1 != NULL) {
651 partition_count++;
652 if (backup_sp1->Backup_Method == 1)
653 file_bytes += backup_sp1->Backup_Size;
654 else
655 img_bytes += backup_sp1->Backup_Size;
656 } else {
657 LOGE("Unable to locate %s partition.\n", SP1_NAME);
658 return false;
659 }
660 }
661#endif
662#ifdef SP2_NAME
663 DataManager::GetValue(TW_BACKUP_SP2_VAR, check);
664 if (check) {
665 backup_sp2 = Find_Partition_By_Path(SP2_NAME);
666 if (backup_sp2 != NULL) {
667 partition_count++;
668 if (backup_sp2->Backup_Method == 1)
669 file_bytes += backup_sp2->Backup_Size;
670 else
671 img_bytes += backup_sp2->Backup_Size;
672 } else {
673 LOGE("Unable to locate %s partition.\n", SP2_NAME);
674 return false;
675 }
676 }
677#endif
678#ifdef SP3_NAME
679 DataManager::GetValue(TW_BACKUP_SP3_VAR, check);
680 if (check) {
681 backup_sp3 = Find_Partition_By_Path(SP3_NAME);
682 if (backup_sp3 != NULL) {
683 partition_count++;
684 if (backup_sp3->Backup_Method == 1)
685 file_bytes += backup_sp3->Backup_Size;
686 else
687 img_bytes += backup_sp3->Backup_Size;
688 } else {
689 LOGE("Unable to locate %s partition.\n", SP3_NAME);
690 return false;
691 }
692 }
693#endif
694
695 if (partition_count == 0) {
696 ui_print("No partitions selected for backup.\n");
697 return false;
698 }
699 total_bytes = file_bytes + img_bytes;
700 ui_print(" * Total number of partitions to back up: %d\n", partition_count);
701 ui_print(" * Total size of all data: %lluMB\n", total_bytes / 1024 / 1024);
702 storage = Find_Partition_By_Path(DataManager::GetCurrentStoragePath());
703 if (storage != NULL) {
704 free_space = storage->Free;
705 ui_print(" * Available space: %lluMB\n", free_space / 1024 / 1024);
706 } else {
707 LOGE("Unable to locate storage device.\n");
708 return false;
709 }
710 if (free_space + (32 * 1024 * 1024) < total_bytes) {
711 // We require an extra 32MB just in case
712 LOGE("Not enough free space on storage.\n");
713 return false;
714 }
715 img_bytes_remaining = img_bytes;
716 file_bytes_remaining = file_bytes;
717
718 if (!Backup_Partition(backup_sys, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
719 return false;
720 if (!Backup_Partition(backup_data, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
721 return false;
722 if (!Backup_Partition(backup_cache, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
723 return false;
724 if (!Backup_Partition(backup_recovery, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
725 return false;
726 if (!Backup_Partition(backup_boot, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
727 return false;
728 if (!Backup_Partition(backup_andsec, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
729 return false;
730 if (!Backup_Partition(backup_sdext, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
731 return false;
732 if (!Backup_Partition(backup_sp1, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
733 return false;
734 if (!Backup_Partition(backup_sp2, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
735 return false;
736 if (!Backup_Partition(backup_sp3, Full_Backup_Path, do_md5, &img_bytes_remaining, &file_bytes_remaining, &img_time, &file_time))
737 return false;
738
739 // Average BPS
740 if (img_time == 0)
741 img_time = 1;
742 if (file_time == 0)
743 file_time = 1;
744 unsigned long int img_bps = img_bytes / img_time;
745 unsigned long int file_bps = file_bytes / file_time;
746
747 ui_print("Average backup rate for file systems: %lu MB/sec\n", (file_bps / (1024 * 1024)));
748 ui_print("Average backup rate for imaged drives: %lu MB/sec\n", (img_bps / (1024 * 1024)));
749
750 time(&total_stop);
751 int total_time = (int) difftime(total_stop, total_start);
752 unsigned long long actual_backup_size = TWFunc::Get_Folder_Size(Full_Backup_Path, true);
753 actual_backup_size /= (1024LLU * 1024LLU);
754
755 ui_print("[%llu MB TOTAL BACKED UP]\n", actual_backup_size);
756 Update_System_Details();
757 ui_print("[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end
758 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400759}
760
Dees_Troy4a2a1262012-09-18 09:33:47 -0400761bool TWPartitionManager::Restore_Partition(TWPartition* Part, string Restore_Name) {
762 time_t Start, Stop;
763 time(&Start);
764 if (!Part->Restore(Restore_Name))
765 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400766 if (Part->Has_SubPartition) {
767 std::vector<TWPartition*>::iterator subpart;
768
769 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
770 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) {
771 if (!(*subpart)->Restore(Restore_Name))
772 return false;
773 }
774 }
775 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400776 time(&Stop);
777 ui_print("[%s done (%d seconds)]\n\n", Part->Display_Name.c_str(), (int)difftime(Stop, Start));
778 return true;
779}
780
Dees_Troy51a0e822012-09-05 15:24:24 -0400781int TWPartitionManager::Run_Restore(string Restore_Name) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400782 int check_md5, check, partition_count = 0;
783 TWPartition* restore_sys = NULL;
784 TWPartition* restore_data = NULL;
785 TWPartition* restore_cache = NULL;
786 TWPartition* restore_boot = NULL;
787 TWPartition* restore_andsec = NULL;
788 TWPartition* restore_sdext = NULL;
789 TWPartition* restore_sp1 = NULL;
790 TWPartition* restore_sp2 = NULL;
791 TWPartition* restore_sp3 = NULL;
792 time_t rStart, rStop;
793 time(&rStart);
Dees_Troy43d8b002012-09-17 16:00:01 -0400794
Dees_Troy4a2a1262012-09-18 09:33:47 -0400795 ui_print("\n[RESTORE STARTED]\n\n");
796 ui_print("Restore folder: '%s'\n", Restore_Name.c_str());
Dees_Troy43d8b002012-09-17 16:00:01 -0400797
Dees_Troy4a2a1262012-09-18 09:33:47 -0400798 if (!Mount_Current_Storage(true))
799 return false;
800
801 DataManager::GetValue(TW_SKIP_MD5_CHECK_VAR, check_md5);
802 DataManager::GetValue(TW_RESTORE_SYSTEM_VAR, check);
Dees_Troy63c8df72012-09-10 14:02:05 -0400803 if (check > 0) {
Dees_Troy4a2a1262012-09-18 09:33:47 -0400804 restore_sys = Find_Partition_By_Path("/system");
805 if (restore_sys == NULL) {
806 LOGE("Unable to locate system partition.\n");
807 return false;
808 }
809 partition_count++;
810 }
811 DataManager::GetValue(TW_RESTORE_DATA_VAR, check);
812 if (check > 0) {
813 restore_data = Find_Partition_By_Path("/data");
814 if (restore_data == NULL) {
815 LOGE("Unable to locate data partition.\n");
816 return false;
817 }
818 partition_count++;
819 }
820 DataManager::GetValue(TW_RESTORE_CACHE_VAR, check);
821 if (check > 0) {
822 restore_cache = Find_Partition_By_Path("/cache");
823 if (restore_cache == NULL) {
824 LOGE("Unable to locate cache partition.\n");
825 return false;
826 }
827 partition_count++;
828 }
829 DataManager::GetValue(TW_RESTORE_BOOT_VAR, check);
830 if (check > 0) {
831 restore_boot = Find_Partition_By_Path("/boot");
832 if (restore_boot == NULL) {
833 LOGE("Unable to locate boot partition.\n");
834 return false;
835 }
836 partition_count++;
837 }
838 DataManager::GetValue(TW_RESTORE_ANDSEC_VAR, check);
839 if (check > 0) {
840 restore_andsec = Find_Partition_By_Path("/and-sec");
841 if (restore_andsec == NULL) {
842 LOGE("Unable to locate android secure partition.\n");
843 return false;
844 }
845 partition_count++;
846 }
847 DataManager::GetValue(TW_RESTORE_SDEXT_VAR, check);
848 if (check > 0) {
849 restore_sdext = Find_Partition_By_Path("/sd-ext");
850 if (restore_sdext == NULL) {
851 LOGE("Unable to locate sd-ext partition.\n");
852 return false;
853 }
854 partition_count++;
855 }
856#ifdef SP1_NAME
857 DataManager::GetValue(TW_RESTORE_SP1_VAR, check);
858 if (check > 0) {
859 restore_sp1 = Find_Partition_By_Path(SP1_NAME);
860 if (restore_sp1 == NULL) {
861 LOGE("Unable to locate %s partition.\n", SP1_NAME);
862 return false;
863 }
864 partition_count++;
865 }
866#endif
867#ifdef SP2_NAME
868 DataManager::GetValue(TW_RESTORE_SP2_VAR, check);
869 if (check > 0) {
870 restore_sp2 = Find_Partition_By_Path(SP2_NAME);
871 if (restore_sp2 == NULL) {
872 LOGE("Unable to locate %s partition.\n", SP2_NAME);
873 return false;
874 }
875 partition_count++;
876 }
877#endif
878#ifdef SP3_NAME
879 DataManager::GetValue(TW_RESTORE_SP3_VAR, check);
880 if (check > 0) {
881 restore_sp3 = Find_Partition_By_Path(SP3_NAME);
882 if (restore_sp3 == NULL) {
883 LOGE("Unable to locate %s partition.\n", SP3_NAME);
884 return false;
885 }
886 partition_count++;
887 }
888#endif
889
890 if (partition_count == 0) {
891 LOGE("No partitions selected for restore.\n");
892 return false;
893 }
894
895 if (check_md5 > 0) {
Dees_Troy43d8b002012-09-17 16:00:01 -0400896 // Check MD5 files first before restoring to ensure that all of them match before starting a restore
Dees_Troy4a2a1262012-09-18 09:33:47 -0400897 ui_print("Verifying MD5...\n");
898 if (restore_sys != NULL && !restore_sys->Check_MD5(Restore_Name))
899 return false;
900 if (restore_data != NULL && !restore_data->Check_MD5(Restore_Name))
901 return false;
Dees_Troy8170a922012-09-18 15:40:25 -0400902 if (restore_data != NULL && restore_data->Has_SubPartition) {
903 std::vector<TWPartition*>::iterator subpart;
904
905 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
906 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == restore_data->Mount_Point) {
907 if (!(*subpart)->Check_MD5(Restore_Name))
908 return false;
909 }
910 }
911 }
Dees_Troy4a2a1262012-09-18 09:33:47 -0400912 if (restore_cache != NULL && !restore_cache->Check_MD5(Restore_Name))
913 return false;
914 if (restore_boot != NULL && !restore_boot->Check_MD5(Restore_Name))
915 return false;
916 if (restore_andsec != NULL && !restore_andsec->Check_MD5(Restore_Name))
917 return false;
918 if (restore_sdext != NULL && !restore_sdext->Check_MD5(Restore_Name))
919 return false;
920 if (restore_sp1 != NULL && !restore_sp1->Check_MD5(Restore_Name))
921 return false;
922 if (restore_sp2 != NULL && !restore_sp2->Check_MD5(Restore_Name))
923 return false;
924 if (restore_sp3 != NULL && !restore_sp3->Check_MD5(Restore_Name))
925 return false;
926 ui_print("Done verifying MD5.\n");
927 } else
928 ui_print("Skipping MD5 check based on user setting.\n");
Dees_Troy43d8b002012-09-17 16:00:01 -0400929
Dees_Troy4a2a1262012-09-18 09:33:47 -0400930 ui_print("Restoring %i partitions...\n", partition_count);
931 if (restore_sys != NULL && !Restore_Partition(restore_sys, Restore_Name))
932 return false;
933 if (restore_data != NULL && !Restore_Partition(restore_data, Restore_Name))
934 return false;
935 if (restore_cache != NULL && !Restore_Partition(restore_cache, Restore_Name))
936 return false;
937 if (restore_boot != NULL && !Restore_Partition(restore_boot, Restore_Name))
938 return false;
939 if (restore_andsec != NULL && !Restore_Partition(restore_andsec, Restore_Name))
940 return false;
941 if (restore_sdext != NULL && !Restore_Partition(restore_sdext, Restore_Name))
942 return false;
943 if (restore_sp1 != NULL && !Restore_Partition(restore_sp1, Restore_Name))
944 return false;
945 if (restore_sp2 != NULL && !Restore_Partition(restore_sp2, Restore_Name))
946 return false;
947 if (restore_sp3 != NULL && !Restore_Partition(restore_sp3, Restore_Name))
948 return false;
Dees_Troy43d8b002012-09-17 16:00:01 -0400949
Dees_Troy43d8b002012-09-17 16:00:01 -0400950 Update_System_Details();
Dees_Troy4a2a1262012-09-18 09:33:47 -0400951 time(&rStop);
952 ui_print("[RESTORE COMPLETED IN %d SECONDS]\n\n",(int)difftime(rStop,rStart));
Dees_Troy63c8df72012-09-10 14:02:05 -0400953 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -0400954}
955
956void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -0400957 // Start with the default values
958 int tw_restore_system = -1;
959 int tw_restore_data = -1;
960 int tw_restore_cache = -1;
961 int tw_restore_recovery = -1;
962 int tw_restore_boot = -1;
963 int tw_restore_andsec = -1;
964 int tw_restore_sdext = -1;
965 int tw_restore_sp1 = -1;
966 int tw_restore_sp2 = -1;
967 int tw_restore_sp3 = -1;
968 bool get_date = true;
969
970 DIR* d;
971 d = opendir(Restore_Name.c_str());
972 if (d == NULL)
973 {
974 LOGE("Error opening %s\n", Restore_Name.c_str());
975 return;
976 }
977
978 struct dirent* de;
979 while ((de = readdir(d)) != NULL)
980 {
981 // Strip off three components
982 char str[256];
983 char* label;
984 char* fstype = NULL;
985 char* extn = NULL;
986 char* ptr;
987
988 strcpy(str, de->d_name);
989 if (strlen(str) <= 2)
990 continue;
991
992 if (get_date) {
993 char file_path[255];
994 struct stat st;
995
996 strcpy(file_path, Restore_Name.c_str());
997 strcat(file_path, "/");
998 strcat(file_path, str);
999 stat(file_path, &st);
1000 string backup_date = ctime((const time_t*)(&st.st_mtime));
1001 DataManager::SetValue(TW_RESTORE_FILE_DATE, backup_date);
1002 get_date = false;
1003 }
1004
1005 label = str;
1006 ptr = label;
1007 while (*ptr && *ptr != '.') ptr++;
1008 if (*ptr == '.')
1009 {
1010 *ptr = 0x00;
1011 ptr++;
1012 fstype = ptr;
1013 }
1014 while (*ptr && *ptr != '.') ptr++;
1015 if (*ptr == '.')
1016 {
1017 *ptr = 0x00;
1018 ptr++;
1019 extn = ptr;
1020 }
1021
1022 if (extn == NULL || (strlen(extn) >= 3 && strncmp(extn, "win", 3) != 0)) continue;
1023
1024 TWPartition* Part = Find_Partition_By_Path(label);
1025 if (Part == NULL)
1026 {
1027 LOGE(" Unable to locate partition by backup name: '%s'\n", label);
1028 continue;
1029 }
1030
1031 Part->Backup_FileName = de->d_name;
1032 if (strlen(extn) > 3) {
1033 Part->Backup_FileName.resize(Part->Backup_FileName.size() - strlen(extn) + 3);
1034 }
1035
1036 // Now, we just need to find the correct label
Dees_Troye58d5262012-09-21 12:27:57 -04001037 if (Part->Backup_Path == "/system")
Dees_Troy63c8df72012-09-10 14:02:05 -04001038 tw_restore_system = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001039 if (Part->Backup_Path == "/data")
Dees_Troy63c8df72012-09-10 14:02:05 -04001040 tw_restore_data = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001041 if (Part->Backup_Path == "/cache")
Dees_Troy63c8df72012-09-10 14:02:05 -04001042 tw_restore_cache = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001043 if (Part->Backup_Path == "/recovery")
Dees_Troy63c8df72012-09-10 14:02:05 -04001044 tw_restore_recovery = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001045 if (Part->Backup_Path == "/boot")
Dees_Troy63c8df72012-09-10 14:02:05 -04001046 tw_restore_boot = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001047 if (Part->Backup_Path == "/and-sec")
Dees_Troy63c8df72012-09-10 14:02:05 -04001048 tw_restore_andsec = 1;
Dees_Troye58d5262012-09-21 12:27:57 -04001049 if (Part->Backup_Path == "/sd-ext")
Dees_Troy63c8df72012-09-10 14:02:05 -04001050 tw_restore_sdext = 1;
1051#ifdef SP1_NAME
Dees_Troye58d5262012-09-21 12:27:57 -04001052 if (Part->Backup_Path == TWFunc::Get_Root_Path(SP1_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001053 tw_restore_sp1 = 1;
1054#endif
1055#ifdef SP2_NAME
Dees_Troye58d5262012-09-21 12:27:57 -04001056 if (Part->Backup_Path == TWFunc::Get_Root_Path(SP2_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001057 tw_restore_sp2 = 1;
1058#endif
1059#ifdef SP3_NAME
Dees_Troye58d5262012-09-21 12:27:57 -04001060 if (Part->Backup_Path == TWFunc::Get_Root_Path(SP3_Name))
Dees_Troy63c8df72012-09-10 14:02:05 -04001061 tw_restore_sp3 = 1;
1062#endif
1063 }
1064 closedir(d);
1065
1066 // Set the final values
1067 DataManager::SetValue(TW_RESTORE_SYSTEM_VAR, tw_restore_system);
1068 DataManager::SetValue(TW_RESTORE_DATA_VAR, tw_restore_data);
1069 DataManager::SetValue(TW_RESTORE_CACHE_VAR, tw_restore_cache);
1070 DataManager::SetValue(TW_RESTORE_RECOVERY_VAR, tw_restore_recovery);
1071 DataManager::SetValue(TW_RESTORE_BOOT_VAR, tw_restore_boot);
1072 DataManager::SetValue(TW_RESTORE_ANDSEC_VAR, tw_restore_andsec);
1073 DataManager::SetValue(TW_RESTORE_SDEXT_VAR, tw_restore_sdext);
1074 DataManager::SetValue(TW_RESTORE_SP1_VAR, tw_restore_sp1);
1075 DataManager::SetValue(TW_RESTORE_SP2_VAR, tw_restore_sp2);
1076 DataManager::SetValue(TW_RESTORE_SP3_VAR, tw_restore_sp3);
1077
Dees_Troy51a0e822012-09-05 15:24:24 -04001078 return;
1079}
1080
1081int TWPartitionManager::Wipe_By_Path(string Path) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001082 std::vector<TWPartition*>::iterator iter;
1083 int ret = false;
1084 bool found = false;
Dees_Troy38bd7602012-09-14 13:33:53 -04001085 string Local_Path = TWFunc::Get_Root_Path(Path);
Dees_Troy63c8df72012-09-10 14:02:05 -04001086
1087 // Iterate through all partitions
1088 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy657c3092012-09-10 20:32:10 -04001089 if ((*iter)->Mount_Point == Local_Path || (!(*iter)->Symlink_Mount_Point.empty() && (*iter)->Symlink_Mount_Point == Local_Path)) {
Dees_Troye58d5262012-09-21 12:27:57 -04001090 if (Path == "/and-sec")
1091 ret = (*iter)->Wipe_AndSec();
1092 else
1093 ret = (*iter)->Wipe();
Dees_Troy63c8df72012-09-10 14:02:05 -04001094 found = true;
1095 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path) {
1096 (*iter)->Wipe();
1097 }
1098 }
1099 if (found) {
1100 return ret;
1101 } else
1102 LOGE("Wipe: Unable to find partition for path '%s'\n", Local_Path.c_str());
1103 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001104}
1105
1106int TWPartitionManager::Wipe_By_Block(string Block) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001107 TWPartition* Part = Find_Partition_By_Block(Block);
1108
1109 if (Part) {
1110 if (Part->Has_SubPartition) {
1111 std::vector<TWPartition*>::iterator subpart;
1112
1113 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1114 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1115 (*subpart)->Wipe();
1116 }
1117 return Part->Wipe();
1118 } else
1119 return Part->Wipe();
1120 }
1121 LOGE("Wipe: Unable to find partition for block '%s'\n", Block.c_str());
1122 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001123}
1124
1125int TWPartitionManager::Wipe_By_Name(string Name) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001126 TWPartition* Part = Find_Partition_By_Name(Name);
1127
1128 if (Part) {
1129 if (Part->Has_SubPartition) {
1130 std::vector<TWPartition*>::iterator subpart;
1131
1132 for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
1133 if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point)
1134 (*subpart)->Wipe();
1135 }
1136 return Part->Wipe();
1137 } else
1138 return Part->Wipe();
1139 }
1140 LOGE("Wipe: Unable to find partition for name '%s'\n", Name.c_str());
1141 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -04001142}
1143
1144int TWPartitionManager::Factory_Reset(void) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001145 std::vector<TWPartition*>::iterator iter;
1146 int ret = true;
1147
1148 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001149 if ((*iter)->Wipe_During_Factory_Reset && (*iter)->Is_Present) {
Dees_Troy63c8df72012-09-10 14:02:05 -04001150 if (!(*iter)->Wipe())
1151 ret = false;
1152 }
1153 }
1154 return ret;
Dees_Troy51a0e822012-09-05 15:24:24 -04001155}
1156
Dees_Troy38bd7602012-09-14 13:33:53 -04001157int TWPartitionManager::Wipe_Dalvik_Cache(void) {
1158 struct stat st;
1159
1160 if (!Mount_By_Path("/data", true))
1161 return false;
1162
1163 if (!Mount_By_Path("/cache", true))
1164 return false;
1165
1166 ui_print("\nWiping Dalvik Cache Directories...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001167 system("rm -rf /data/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001168 ui_print("Cleaned: /data/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001169 system("rm -rf /cache/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001170 ui_print("Cleaned: /cache/dalvik-cache...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001171 system("rm -rf /cache/dc");
Dees_Troy38bd7602012-09-14 13:33:53 -04001172 ui_print("Cleaned: /cache/dc\n");
1173
1174 TWPartition* sdext = Find_Partition_By_Path("/sd-ext");
1175 if (sdext != NULL) {
1176 if (sdext->Is_Present && sdext->Mount(false)) {
1177 if (stat("/sd-ext/dalvik-cache", &st) == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001178 system("rm -rf /sd-ext/dalvik-cache");
Dees_Troy38bd7602012-09-14 13:33:53 -04001179 ui_print("Cleaned: /sd-ext/dalvik-cache...\n");
1180 }
1181 }
1182 }
1183 ui_print("-- Dalvik Cache Directories Wipe Complete!\n\n");
1184 return true;
1185}
1186
1187int TWPartitionManager::Wipe_Rotate_Data(void) {
1188 if (!Mount_By_Path("/data", true))
1189 return false;
1190
Dees_Troy8170a922012-09-18 15:40:25 -04001191 system("rm -r /data/misc/akmd*");
1192 system("rm -r /data/misc/rild*");
1193 system("rm -r /data/misc/rild*");
Dees_Troy38bd7602012-09-14 13:33:53 -04001194 ui_print("Rotation data wiped.\n");
1195 return true;
1196}
1197
1198int TWPartitionManager::Wipe_Battery_Stats(void) {
1199 struct stat st;
1200
1201 if (!Mount_By_Path("/data", true))
1202 return false;
1203
1204 if (0 != stat("/data/system/batterystats.bin", &st)) {
1205 ui_print("No Battery Stats Found. No Need To Wipe.\n");
1206 } else {
1207 remove("/data/system/batterystats.bin");
1208 ui_print("Cleared battery stats.\n");
1209 }
1210 return true;
1211}
1212
1213int TWPartitionManager::Format_Data(void) {
1214 TWPartition* dat = Find_Partition_By_Path("/data");
1215
1216 if (dat != NULL) {
1217 if (!dat->UnMount(true))
1218 return false;
1219
1220 return dat->Wipe_Encryption();
1221 } else {
1222 LOGE("Unable to locate /data.\n");
1223 return false;
1224 }
1225 return false;
1226}
1227
1228int TWPartitionManager::Wipe_Media_From_Data(void) {
1229 TWPartition* dat = Find_Partition_By_Path("/data");
1230
1231 if (dat != NULL) {
1232 if (!dat->Has_Data_Media) {
1233 LOGE("This device does not have /data/media\n");
1234 return false;
1235 }
1236 if (!dat->Mount(true))
1237 return false;
1238
1239 ui_print("Wiping internal storage -- /data/media...\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001240 system("rm -rf /data/media");
1241 system("cd /data && mkdir media && chmod 775 media");
Dees_Troy38bd7602012-09-14 13:33:53 -04001242 if (dat->Has_Data_Media) {
1243 dat->Recreate_Media_Folder();
1244 }
1245 return true;
1246 } else {
1247 LOGE("Unable to locate /data.\n");
1248 return false;
1249 }
1250 return false;
1251}
1252
Dees_Troy51a0e822012-09-05 15:24:24 -04001253void TWPartitionManager::Refresh_Sizes(void) {
Dees_Troy51127312012-09-08 13:08:49 -04001254 Update_System_Details();
Dees_Troy51a0e822012-09-05 15:24:24 -04001255 return;
1256}
1257
1258void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001259 std::vector<TWPartition*>::iterator iter;
Dees_Troy51127312012-09-08 13:08:49 -04001260 int data_size = 0;
Dees_Troy5bf43922012-09-07 16:07:55 -04001261
Dees_Troy32c8eb82012-09-11 15:28:06 -04001262 ui_print("Updating partition details...\n");
Dees_Troy5bf43922012-09-07 16:07:55 -04001263 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
Dees_Troy51127312012-09-08 13:08:49 -04001264 if ((*iter)->Can_Be_Mounted) {
1265 (*iter)->Update_Size(true);
1266 if ((*iter)->Mount_Point == "/system") {
1267 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1268 DataManager::SetValue(TW_BACKUP_SYSTEM_SIZE, backup_display_size);
1269 } else if ((*iter)->Mount_Point == "/data" || (*iter)->Mount_Point == "/datadata") {
1270 data_size += (int)((*iter)->Backup_Size / 1048576LLU);
1271 } else if ((*iter)->Mount_Point == "/cache") {
1272 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1273 DataManager::SetValue(TW_BACKUP_CACHE_SIZE, backup_display_size);
1274 } else if ((*iter)->Mount_Point == "/sd-ext") {
1275 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
1276 DataManager::SetValue(TW_BACKUP_SDEXT_SIZE, backup_display_size);
1277 if ((*iter)->Backup_Size == 0) {
1278 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 0);
1279 DataManager::SetValue(TW_BACKUP_SDEXT_VAR, 0);
1280 } else
1281 DataManager::SetValue(TW_HAS_SDEXT_PARTITION, 1);
Dees_Troye58d5262012-09-21 12:27:57 -04001282 } else if ((*iter)->Has_Android_Secure) {
Dees_Troy8170a922012-09-18 15:40:25 -04001283 int backup_display_size = (int)((*iter)->Backup_Size / 1048576LLU);
Dees_Troye58d5262012-09-21 12:27:57 -04001284 DataManager::SetValue(TW_BACKUP_ANDSEC_SIZE, backup_display_size);
Dees_Troy8170a922012-09-18 15:40:25 -04001285 if ((*iter)->Backup_Size == 0) {
1286 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 0);
1287 DataManager::SetValue(TW_BACKUP_ANDSEC_VAR, 0);
1288 } else
1289 DataManager::SetValue(TW_HAS_ANDROID_SECURE, 1);
Dees_Troy51127312012-09-08 13:08:49 -04001290 }
1291 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001292 }
Dees_Troy51127312012-09-08 13:08:49 -04001293 DataManager::SetValue(TW_BACKUP_DATA_SIZE, data_size);
1294 string current_storage_path = DataManager::GetCurrentStoragePath();
1295 TWPartition* FreeStorage = Find_Partition_By_Path(current_storage_path);
Dees_Troy8170a922012-09-18 15:40:25 -04001296 if (FreeStorage != NULL) {
1297 // Attempt to mount storage
1298 if (!FreeStorage->Mount(false)) {
1299 // We couldn't mount storage... check to see if we have dual storage
1300 int has_dual_storage;
1301 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual_storage);
1302 if (has_dual_storage == 1) {
1303 // We have dual storage, see if we're using the internal storage that should always be present
1304 if (current_storage_path == DataManager::GetSettingsStoragePath()) {
1305 // Not able to use internal, so error!
1306 LOGE("Unable to mount internal storage.\n");
1307 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1308 } else {
1309 // We were using external, flip to internal
1310 DataManager::SetValue(TW_USE_EXTERNAL_STORAGE, 0);
1311 current_storage_path = DataManager::GetCurrentStoragePath();
1312 FreeStorage = Find_Partition_By_Path(current_storage_path);
1313 if (FreeStorage != NULL) {
1314 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1315 } else {
1316 LOGE("Unable to locate internal storage partition.\n");
1317 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1318 }
1319 }
1320 } else {
1321 // No dual storage and unable to mount storage, error!
1322 LOGE("Unable to mount storage.\n");
1323 DataManager::SetValue(TW_STORAGE_FREE_SIZE, 0);
1324 }
1325 } else {
1326 DataManager::SetValue(TW_STORAGE_FREE_SIZE, (int)(FreeStorage->Free / 1048576LLU));
1327 }
1328 } else {
Dees_Troy51127312012-09-08 13:08:49 -04001329 LOGI("Unable to find storage partition '%s'.\n", current_storage_path.c_str());
Dees_Troy8170a922012-09-18 15:40:25 -04001330 }
Dees_Troy5bf43922012-09-07 16:07:55 -04001331 if (!Write_Fstab())
1332 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -04001333 return;
1334}
1335
1336int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -04001337#ifdef TW_INCLUDE_CRYPTO
1338 int ret_val, password_len;
1339 char crypto_blkdev[255], cPassword[255];
1340 size_t result;
1341
1342 property_set("ro.crypto.state", "encrypted");
1343#ifdef TW_INCLUDE_JB_CRYPTO
1344 // No extra flags needed
1345#else
1346 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
1347 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
1348 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
1349 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
1350 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
1351 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
1352#endif
1353 strcpy(cPassword, Password.c_str());
1354 if (cryptfs_check_passwd(cPassword) != 0) {
1355 LOGE("Failed to decrypt data.\n");
1356 return -1;
1357 }
1358 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
1359 if (strcmp(crypto_blkdev, "error") == 0) {
1360 LOGE("Error retrieving decrypted data block device.\n");
1361 } else {
1362 TWPartition* dat = Find_Partition_By_Path("/data");
1363 if (dat != NULL) {
Dees_Troy38bd7602012-09-14 13:33:53 -04001364 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Primary_Block_Device);
Dees_Troy5bf43922012-09-07 16:07:55 -04001365 DataManager::SetValue(TW_IS_DECRYPTED, 1);
1366 dat->Is_Decrypted = true;
1367 dat->Decrypted_Block_Device = crypto_blkdev;
Dees_Troy32c8eb82012-09-11 15:28:06 -04001368 ui_print("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
Dees_Troy5bf43922012-09-07 16:07:55 -04001369 // Sleep for a bit so that the device will be ready
1370 sleep(1);
1371 Update_System_Details();
1372 } else
1373 LOGE("Unable to locate data partition.\n");
1374 }
1375 return 0;
1376#else
1377 LOGE("No crypto support was compiled into this build.\n");
1378 return -1;
1379#endif
Dees_Troy51a0e822012-09-05 15:24:24 -04001380 return 1;
Dees_Troy51127312012-09-08 13:08:49 -04001381}
1382
Dees_Troy38bd7602012-09-14 13:33:53 -04001383int TWPartitionManager::Fix_Permissions(void) {
1384 if (!Mount_By_Path("/data", true))
1385 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001386
Dees_Troy38bd7602012-09-14 13:33:53 -04001387 if (!Mount_By_Path("/system", true))
1388 return false;
Dees_Troy51127312012-09-08 13:08:49 -04001389
Dees_Troy38bd7602012-09-14 13:33:53 -04001390 ui_print("Fixing Permissions\nThis may take a few minutes.\n");
Dees_Troy8170a922012-09-18 15:40:25 -04001391 system("./sbin/fix_permissions.sh");
Dees_Troy38bd7602012-09-14 13:33:53 -04001392 ui_print("Done.\n\n");
1393 return true;
Dees_Troy4a2a1262012-09-18 09:33:47 -04001394}
Dees_Troy8170a922012-09-18 15:40:25 -04001395
1396//partial kangbang from system/vold
1397#ifndef CUSTOM_LUN_FILE
1398#define CUSTOM_LUN_FILE "/sys/devices/platform/usb_mass_storage/lun%d/file"
1399#endif
1400
1401int TWPartitionManager::usb_storage_enable(void) {
1402 int fd, has_dual, has_data_media;
1403 char lun_file[255];
1404 TWPartition* Part;
1405 string ext_path;
1406
1407 DataManager::GetValue(TW_HAS_DUAL_STORAGE, has_dual);
1408 DataManager::GetValue(TW_HAS_DATA_MEDIA, has_data_media);
1409 if (has_dual == 1 && has_data_media == 0) {
1410 Part = Find_Partition_By_Path(DataManager::GetSettingsStoragePath());
1411 if (Part == NULL) {
1412 LOGE("Unable to locate volume information.");
1413 return false;
1414 }
1415 if (!Part->UnMount(true))
1416 return false;
1417
1418 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1419 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1420 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1421 return false;
1422 }
1423
1424 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1425 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1426 close(fd);
1427 return false;
1428 }
1429 close(fd);
1430
1431 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1432 Part = Find_Partition_By_Path(ext_path);
1433 if (Part == NULL) {
1434 LOGE("Unable to locate volume information.\n");
1435 return false;
1436 }
1437 if (!Part->UnMount(true))
1438 return false;
1439
1440 sprintf(lun_file, CUSTOM_LUN_FILE, 1);
1441 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1442 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1443 return false;
1444 }
1445
1446 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1447 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1448 close(fd);
1449 return false;
1450 }
1451 close(fd);
1452 } else {
1453 if (has_data_media == 0)
1454 ext_path = DataManager::GetCurrentStoragePath();
1455 else
1456 DataManager::GetValue(TW_EXTERNAL_PATH, ext_path);
1457
1458 Part = Find_Partition_By_Path(ext_path);
1459 if (Part == NULL) {
1460 LOGE("Unable to locate volume information.\n");
1461 return false;
1462 }
1463 if (!Part->UnMount(true))
1464 return false;
1465
1466 sprintf(lun_file, CUSTOM_LUN_FILE, 0);
1467
1468 if ((fd = open(lun_file, O_WRONLY)) < 0) {
1469 LOGE("Unable to open ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1470 return false;
1471 }
1472
1473 if (write(fd, Part->Actual_Block_Device.c_str(), Part->Actual_Block_Device.size()) < 0) {
1474 LOGE("Unable to write to ums lunfile '%s': (%s)\n", lun_file, strerror(errno));
1475 close(fd);
1476 return false;
1477 }
1478 close(fd);
1479 }
1480 return true;
1481}
1482
1483int TWPartitionManager::usb_storage_disable(void) {
1484 int fd, index;
1485 char lun_file[255];
1486
1487 for (index=0; index<2; index++) {
1488 sprintf(lun_file, CUSTOM_LUN_FILE, index);
1489
1490 if ((fd = open(lun_file, O_WRONLY)) < 0) {
Dees_Troye58d5262012-09-21 12:27:57 -04001491 Mount_All_Storage();
1492 Update_System_Details();
1493 if (index == 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001494 LOGE("Unable to open ums lunfile '%s': (%s)", lun_file, strerror(errno));
Dees_Troye58d5262012-09-21 12:27:57 -04001495 return false;
1496 } else
1497 return true;
Dees_Troy8170a922012-09-18 15:40:25 -04001498 }
1499
1500 char ch = 0;
1501 if (write(fd, &ch, 1) < 0) {
Dees_Troy8170a922012-09-18 15:40:25 -04001502 close(fd);
Dees_Troye58d5262012-09-21 12:27:57 -04001503 Mount_All_Storage();
1504 Update_System_Details();
1505 if (index == 0) {
1506 LOGE("Unable to write to ums lunfile '%s': (%s)", lun_file, strerror(errno));
1507 return false;
1508 } else
1509 return true;
Dees_Troy8170a922012-09-18 15:40:25 -04001510 }
1511
1512 close(fd);
1513 }
Dees_Troye58d5262012-09-21 12:27:57 -04001514 Mount_All_Storage();
1515 Update_System_Details();
Dees_Troy8170a922012-09-18 15:40:25 -04001516 return true;
Dees_Troy812660f2012-09-20 09:55:17 -04001517}
1518
1519void TWPartitionManager::Mount_All_Storage(void) {
1520 std::vector<TWPartition*>::iterator iter;
1521
1522 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
1523 if ((*iter)->Is_Storage)
1524 (*iter)->Mount(false);
1525 }
Dees_Troy8170a922012-09-18 15:40:25 -04001526}