blob: 2e50641db58e2b8eefba11e9605e29d6092e6641 [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_Troy51a0e822012-09-05 15:24:24 -040030
31#include "variables.h"
32#include "common.h"
33#include "partitions.hpp"
Dees_Troy5bf43922012-09-07 16:07:55 -040034#include "data.hpp"
35
36#ifdef TW_INCLUDE_CRYPTO
37 #ifdef TW_INCLUDE_JB_CRYPTO
38 #include "crypto/jb/cryptfs.h"
39 #else
40 #include "crypto/ics/cryptfs.h"
41 #endif
42 #include "cutils/properties.h"
43#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040044
45int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -040046 FILE *fstabFile;
47 char fstab_line[MAX_FSTAB_LINE_LENGTH];
48
49 fstabFile = fopen(Fstab_Filename.c_str(), "rt");
50 if (fstabFile == NULL) {
51 LOGE("Critical Error: Unable to open fstab at '%s'.\n", Fstab_Filename.c_str());
52 return false;
53 }
54
55 while (fgets(fstab_line, sizeof(fstab_line), fstabFile) != NULL) {
56 if (fstab_line[0] != '/')
57 continue;
58
59 TWPartition* partition = new TWPartition();
60 string line(fstab_line);
61 if (partition->Process_Fstab_Line(line, Display_Error)) {
62 Partitions.push_back(partition);
63 } else {
64 delete partition;
65 }
66 }
67 fclose(fstabFile);
68 if (!Write_Fstab()) {
69 if (Display_Error)
70 LOGE("Error creating fstab\n");
71 else
72 LOGI("Error creating fstab\n");
73 }
74 return true;
75}
76
77int TWPartitionManager::Write_Fstab(void) {
78 FILE *fp;
79 std::vector<TWPartition*>::iterator iter;
80 string Line;
81
82 fp = fopen("/etc/fstab", "w");
83 if (fp == NULL) {
84 LOGI("Can not open /etc/fstab.\n");
85 return false;
86 }
87 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
88 if ((*iter)->Can_Be_Mounted && (*iter)->Is_Present) {
89 if ((*iter)->Is_Decrypted)
90 Line = (*iter)->Decrypted_Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
91 else
92 Line = (*iter)->Block_Device + " " + (*iter)->Mount_Point + " " + (*iter)->Current_File_System + " rw\n";
93 fputs(Line.c_str(), fp);
94 }
95 }
96 fclose(fp);
97 return true;
Dees_Troy51a0e822012-09-05 15:24:24 -040098}
99
100int TWPartitionManager::Mount_By_Path(string Path, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400101 std::vector<TWPartition*>::iterator iter;
102 int ret = false;
103 bool found = false;
104 string Local_Path = Path;
105
106 // Make sure that we have a leading slash
107 if (Local_Path.substr(0, 1) != "/")
108 Local_Path = "/" + Local_Path;
109
110 // Trim the path to get the root path only
111 size_t position = Local_Path.find("/", 2);
112 if (position != string::npos) {
113 Local_Path.resize(position);
114 }
115
116 // Iterate through all partitions
117 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
118 if ((*iter)->Mount_Point == Local_Path) {
119 ret = (*iter)->Mount(Display_Error);
120 found = true;
121 } else if ((*iter)->Is_SubPartition && (*iter)->SubPartition_Of == Local_Path)
122 (*iter)->Mount(Display_Error);
123 }
124 if (found) {
125 return ret;
126 } else if (Display_Error) {
127 LOGE("Unable to find partition for path '%s'\n", Local_Path.c_str());
128 } else {
129 LOGI("Unable to find partition for path '%s'\n", Local_Path.c_str());
130 }
131 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400132}
133
134int TWPartitionManager::Mount_By_Block(string Block, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400135 std::vector<TWPartition*>::iterator iter;
136
137 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
138 if ((*iter)->Block_Device == Block)
139 return (*iter)->Mount(Display_Error);
140 else if ((*iter)->Alternate_Block_Device == Block)
141 return (*iter)->Mount(Display_Error);
142 }
143 if (Display_Error)
144 LOGE("Unable to find partition for block '%s'\n", Block.c_str());
145 else
146 LOGI("Unable to find partition for block '%s'\n", Block.c_str());
147 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400148}
149
150int TWPartitionManager::Mount_By_Name(string Name, bool Display_Error) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400151 std::vector<TWPartition*>::iterator iter;
152
153 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
154 if ((*iter)->Display_Name == Name)
155 return (*iter)->Mount(Display_Error);
156 }
157 if (Display_Error)
158 LOGE("Unable to find partition for name '%s'\n", Name.c_str());
159 else
160 LOGI("Unable to find partition for name '%s'\n", Name.c_str());
161 return false;
Dees_Troy51a0e822012-09-05 15:24:24 -0400162 return 1;
163}
164
165int TWPartitionManager::UnMount_By_Path(string Path, bool Display_Error) {
166 LOGI("STUB TWPartitionManager::UnMount_By_Path, Path: '%s', Display_Error: %i\n", Path.c_str(), Display_Error);
167 return 1;
168}
169
170int TWPartitionManager::UnMount_By_Block(string Block, bool Display_Error) {
171 LOGI("STUB TWPartitionManager::UnMount_By_Block, Block: '%s', Display_Error: %i\n", Block.c_str(), Display_Error);
172 return 1;
173}
174
175int TWPartitionManager::UnMount_By_Name(string Name, bool Display_Error) {
176 LOGI("STUB TWPartitionManager::UnMount_By_Name, Name: '%s', Display_Error: %i\n", Name.c_str(), Display_Error);
177 return 1;
178}
179
180int TWPartitionManager::Is_Mounted_By_Path(string Path) {
181 LOGI("STUB TWPartitionManager::Is_Mounted_By_Path, Path: '%s'\n", Path.c_str());
182 return 1;
183}
184
185int TWPartitionManager::Is_Mounted_By_Block(string Block) {
186 LOGI("STUB TWPartitionManager::Is_Mounted_By_Block, Block: '%s'\n", Block.c_str());
187 return 1;
188}
189
190int TWPartitionManager::Is_Mounted_By_Name(string Name) {
191 LOGI("STUB TWPartitionManager::Is_Mounted_By_Name, Name: '%s'\n", Name.c_str());
192 return 1;
193}
194
Dees_Troy5bf43922012-09-07 16:07:55 -0400195int TWPartitionManager::Mount_Current_Storage(bool Display_Error) {
196 return Mount_By_Path(DataManager::GetCurrentStoragePath(), Display_Error);
Dees_Troy51a0e822012-09-05 15:24:24 -0400197}
198
Dees_Troy5bf43922012-09-07 16:07:55 -0400199int TWPartitionManager::Mount_Settings_Storage(bool Display_Error) {
200 return Mount_By_Path(DataManager::GetSettingsStoragePath(), Display_Error);
201}
202
203TWPartition* TWPartitionManager::Find_Partition_By_Path(string Path) {
204 std::vector<TWPartition*>::iterator iter;
205
206 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
207 if ((*iter)->Mount_Point == Path)
208 return (*iter);
209 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400210 return NULL;
211}
212
Dees_Troy5bf43922012-09-07 16:07:55 -0400213TWPartition* TWPartitionManager::Find_Partition_By_Block(string Block) {
Dees_Troy51a0e822012-09-05 15:24:24 -0400214 LOGI("STUB TWPartitionManager::Find_Partition_By_Block, Block: '%s'\n", Block.c_str());
215 return NULL;
Dees_Troy5bf43922012-09-07 16:07:55 -0400216}
217
218TWPartition* TWPartitionManager::Find_Partition_By_Name(string Name) {
219 LOGI("STUB TWPartitionManager::Find_Partition_By_Name, Name: '%s'\n", Name.c_str());
220 return NULL;
221}
Dees_Troy51a0e822012-09-05 15:24:24 -0400222
223int TWPartitionManager::Run_Backup(string Backup_Name) {
224 LOGI("STUB TWPartitionManager::Run_Backup, Backup_Name: '%s'\n", Backup_Name.c_str());
225 return 1;
226}
227
228int TWPartitionManager::Run_Restore(string Restore_Name) {
229 LOGI("STUB TWPartitionManager::Run_Restore, Restore_Name: '%s'\n", Restore_Name.c_str());
230 return 1;
231}
232
233void TWPartitionManager::Set_Restore_Files(string Restore_Name) {
234 LOGI("STUB TWPartitionManager::Set_Restore_Files\n");
235 return;
236}
237
238int TWPartitionManager::Wipe_By_Path(string Path) {
239 LOGI("STUB TWPartitionManager::Wipe_By_Path, Path: '%s'\n", Path.c_str());
240 return 1;
241}
242
243int TWPartitionManager::Wipe_By_Block(string Block) {
244 LOGI("STUB TWPartitionManager::Wipe_By_Block, Block: '%s'\n", Block.c_str());
245 return 1;
246}
247
248int TWPartitionManager::Wipe_By_Name(string Name) {
249 LOGI("STUB TWPartitionManager::Wipe_By_Name, Name: '%s'\n", Name.c_str());
250 return 1;
251}
252
253int TWPartitionManager::Factory_Reset(void) {
254 LOGI("STUB TWPartitionManager::Factory_Reset\n");
255 return 1;
256}
257
258void TWPartitionManager::Refresh_Sizes(void) {
259 LOGI("STUB TWPartitionManager::Refresh_Sizes\n");
260 return;
261}
262
263void TWPartitionManager::Update_System_Details(void) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400264 std::vector<TWPartition*>::iterator iter;
265
266 LOGI("Updating system details...\n");
267 for (iter = Partitions.begin(); iter != Partitions.end(); iter++) {
268 (*iter)->Check_FS_Type();
269 (*iter)->Update_Size(false);
270 }
271 if (!Write_Fstab())
272 LOGE("Error creating fstab\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400273 return;
274}
275
276int TWPartitionManager::Decrypt_Device(string Password) {
Dees_Troy5bf43922012-09-07 16:07:55 -0400277#ifdef TW_INCLUDE_CRYPTO
278 int ret_val, password_len;
279 char crypto_blkdev[255], cPassword[255];
280 size_t result;
281
282 property_set("ro.crypto.state", "encrypted");
283#ifdef TW_INCLUDE_JB_CRYPTO
284 // No extra flags needed
285#else
286 property_set("ro.crypto.fs_type", CRYPTO_FS_TYPE);
287 property_set("ro.crypto.fs_real_blkdev", CRYPTO_REAL_BLKDEV);
288 property_set("ro.crypto.fs_mnt_point", CRYPTO_MNT_POINT);
289 property_set("ro.crypto.fs_options", CRYPTO_FS_OPTIONS);
290 property_set("ro.crypto.fs_flags", CRYPTO_FS_FLAGS);
291 property_set("ro.crypto.keyfile.userdata", CRYPTO_KEY_LOC);
292#endif
293 strcpy(cPassword, Password.c_str());
294 if (cryptfs_check_passwd(cPassword) != 0) {
295 LOGE("Failed to decrypt data.\n");
296 return -1;
297 }
298 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "error");
299 if (strcmp(crypto_blkdev, "error") == 0) {
300 LOGE("Error retrieving decrypted data block device.\n");
301 } else {
302 TWPartition* dat = Find_Partition_By_Path("/data");
303 if (dat != NULL) {
304 DataManager::SetValue(TW_DATA_BLK_DEVICE, dat->Block_Device);
305 DataManager::SetValue(TW_IS_DECRYPTED, 1);
306 dat->Is_Decrypted = true;
307 dat->Decrypted_Block_Device = crypto_blkdev;
308 LOGI("Data successfully decrypted, new block device: '%s'\n", crypto_blkdev);
309 // Sleep for a bit so that the device will be ready
310 sleep(1);
311 Update_System_Details();
312 } else
313 LOGE("Unable to locate data partition.\n");
314 }
315 return 0;
316#else
317 LOGE("No crypto support was compiled into this build.\n");
318 return -1;
319#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400320 return 1;
321}