Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/nyx/nyx_gui/frontend/gui_tools.c
1476 views
1
/*
2
* Copyright (c) 2018 naehrwert
3
* Copyright (c) 2018-2024 CTCaer
4
*
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms and conditions of the GNU General Public License,
7
* version 2, as published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
#include <stdlib.h>
19
20
#include <bdk.h>
21
22
#include "gui.h"
23
#include "gui_tools.h"
24
#include "gui_tools_partition_manager.h"
25
#include "gui_emmc_tools.h"
26
#include "fe_emummc_tools.h"
27
#include "../config.h"
28
#include "../hos/pkg1.h"
29
#include "../hos/pkg2.h"
30
#include "../hos/hos.h"
31
#include <libs/fatfs/ff.h>
32
33
extern volatile boot_cfg_t *b_cfg;
34
extern hekate_config h_cfg;
35
extern nyx_config n_cfg;
36
37
lv_obj_t *ums_mbox;
38
39
extern char *emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t *storage);
40
41
static lv_obj_t *_create_container(lv_obj_t *parent)
42
{
43
static lv_style_t h_style;
44
lv_style_copy(&h_style, &lv_style_transp);
45
h_style.body.padding.inner = 0;
46
h_style.body.padding.hor = LV_DPI - (LV_DPI / 4);
47
h_style.body.padding.ver = LV_DPI / 6;
48
49
lv_obj_t *h1 = lv_cont_create(parent, NULL);
50
lv_cont_set_style(h1, &h_style);
51
lv_cont_set_fit(h1, false, true);
52
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 4);
53
lv_obj_set_click(h1, false);
54
lv_cont_set_layout(h1, LV_LAYOUT_OFF);
55
56
return h1;
57
}
58
59
bool get_set_autorcm_status(bool toggle)
60
{
61
u32 sector;
62
u8 corr_mod0, mod1;
63
bool enabled = false;
64
65
if (h_cfg.t210b01)
66
return false;
67
68
emmc_initialize(false);
69
70
u8 *tempbuf = (u8 *)malloc(0x200);
71
emmc_set_partition(EMMC_BOOT0);
72
sdmmc_storage_read(&emmc_storage, 0x200 / EMMC_BLOCKSIZE, 1, tempbuf);
73
74
// Get the correct RSA modulus byte masks.
75
nx_emmc_get_autorcm_masks(&corr_mod0, &mod1);
76
77
// Check if 2nd byte of modulus is correct.
78
if (tempbuf[0x11] != mod1)
79
goto out;
80
81
if (tempbuf[0x10] != corr_mod0)
82
enabled = true;
83
84
// Toggle autorcm status if requested.
85
if (toggle)
86
{
87
// Iterate BCTs.
88
for (u32 i = 0; i < 4; i++)
89
{
90
sector = (0x200 + (0x4000 * i)) / EMMC_BLOCKSIZE; // 0x4000 bct + 0x200 offset.
91
sdmmc_storage_read(&emmc_storage, sector, 1, tempbuf);
92
93
if (!enabled)
94
tempbuf[0x10] = 0;
95
else
96
tempbuf[0x10] = corr_mod0;
97
sdmmc_storage_write(&emmc_storage, sector, 1, tempbuf);
98
}
99
enabled = !enabled;
100
}
101
102
// Check if RCM is patched and protect from a possible brick.
103
if (enabled && h_cfg.rcm_patched && hw_get_chip_id() != GP_HIDREV_MAJOR_T210B01)
104
{
105
// Iterate BCTs.
106
for (u32 i = 0; i < 4; i++)
107
{
108
sector = (0x200 + (0x4000 * i)) / EMMC_BLOCKSIZE; // 0x4000 bct + 0x200 offset.
109
sdmmc_storage_read(&emmc_storage, sector, 1, tempbuf);
110
111
// Check if 2nd byte of modulus is correct.
112
if (tempbuf[0x11] != mod1)
113
continue;
114
115
// If AutoRCM is enabled, disable it.
116
if (tempbuf[0x10] != corr_mod0)
117
{
118
tempbuf[0x10] = corr_mod0;
119
120
sdmmc_storage_write(&emmc_storage, sector, 1, tempbuf);
121
}
122
}
123
124
enabled = false;
125
}
126
127
out:
128
free(tempbuf);
129
emmc_end();
130
131
h_cfg.autorcm_enabled = enabled;
132
133
return enabled;
134
}
135
136
static lv_res_t _create_mbox_autorcm_status(lv_obj_t *btn)
137
{
138
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
139
lv_obj_set_style(dark_bg, &mbox_darken);
140
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
141
142
static const char * mbox_btn_map[] = { "\251", "\222OK", "\251", "" };
143
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
144
lv_mbox_set_recolor_text(mbox, true);
145
146
bool enabled = get_set_autorcm_status(true);
147
148
if (enabled)
149
{
150
lv_mbox_set_text(mbox,
151
"AutoRCM is now #C7EA46 ENABLED!#\n\n"
152
"You can now automatically enter RCM by only pressing #FF8000 POWER#.\n"
153
"Use the AutoRCM button here again if you want to remove it later on.");
154
}
155
else
156
{
157
lv_mbox_set_text(mbox,
158
"AutoRCM is now #FF8000 DISABLED!#\n\n"
159
"The boot process is now normal and you need the #FF8000 VOL+# + #FF8000 HOME# (jig) combo to enter RCM.\n");
160
}
161
162
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
163
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
164
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
165
lv_obj_set_top(mbox, true);
166
167
if (enabled)
168
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
169
else
170
lv_btn_set_state(btn, LV_BTN_STATE_REL);
171
nyx_generic_onoff_toggle(btn);
172
173
return LV_RES_OK;
174
}
175
176
static lv_res_t _create_mbox_hid(usb_ctxt_t *usbs)
177
{
178
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
179
lv_obj_set_style(dark_bg, &mbox_darken);
180
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
181
182
static const char *mbox_btn_map[] = { "\251", "\262Close", "\251", "" };
183
static const char *mbox_btn_map2[] = { "\251", "\222Close", "\251", "" };
184
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
185
lv_mbox_set_recolor_text(mbox, true);
186
187
char *txt_buf = malloc(SZ_4K);
188
189
s_printf(txt_buf, "#FF8000 HID Emulation#\n\n#C7EA46 Device:# ");
190
191
if (usbs->type == USB_HID_GAMEPAD)
192
strcat(txt_buf, "Gamepad");
193
else
194
strcat(txt_buf, "Touchpad");
195
196
lv_mbox_set_text(mbox, txt_buf);
197
free(txt_buf);
198
199
lv_obj_t *lbl_status = lv_label_create(mbox, NULL);
200
lv_label_set_recolor(lbl_status, true);
201
lv_label_set_text(lbl_status, " ");
202
usbs->label = (void *)lbl_status;
203
204
lv_obj_t *lbl_tip = lv_label_create(mbox, NULL);
205
lv_label_set_recolor(lbl_tip, true);
206
lv_label_set_static_text(lbl_tip, "Note: To end it, press #C7EA46 L3# + #C7EA46 HOME# or remove the cable.");
207
lv_obj_set_style(lbl_tip, &hint_small_style);
208
209
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
210
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
211
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
212
lv_obj_set_top(mbox, true);
213
214
usb_device_gadget_hid(usbs);
215
216
lv_mbox_add_btns(mbox, mbox_btn_map2, mbox_action);
217
218
return LV_RES_OK;
219
}
220
221
static lv_res_t _create_mbox_ums(usb_ctxt_t *usbs)
222
{
223
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
224
lv_obj_set_style(dark_bg, &mbox_darken);
225
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
226
227
static const char *mbox_btn_map[] = { "\251", "\262Close", "\251", "" };
228
static const char *mbox_btn_map2[] = { "\251", "\222Close", "\251", "" };
229
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
230
lv_mbox_set_recolor_text(mbox, true);
231
232
char *txt_buf = malloc(SZ_4K);
233
234
s_printf(txt_buf, "#FF8000 USB Mass Storage#\n\n#C7EA46 Device:# ");
235
236
if (usbs->type == MMC_SD)
237
{
238
switch (usbs->partition)
239
{
240
case 0:
241
strcat(txt_buf, "SD Card");
242
break;
243
case EMMC_GPP + 1:
244
strcat(txt_buf, "emuMMC GPP");
245
break;
246
case EMMC_BOOT0 + 1:
247
strcat(txt_buf, "emuMMC BOOT0");
248
break;
249
case EMMC_BOOT1 + 1:
250
strcat(txt_buf, "emuMMC BOOT1");
251
break;
252
}
253
}
254
else
255
{
256
switch (usbs->partition)
257
{
258
case EMMC_GPP + 1:
259
strcat(txt_buf, "eMMC GPP");
260
break;
261
case EMMC_BOOT0 + 1:
262
strcat(txt_buf, "eMMC BOOT0");
263
break;
264
case EMMC_BOOT1 + 1:
265
strcat(txt_buf, "eMMC BOOT1");
266
break;
267
}
268
}
269
270
lv_mbox_set_text(mbox, txt_buf);
271
free(txt_buf);
272
273
lv_obj_t *lbl_status = lv_label_create(mbox, NULL);
274
lv_label_set_recolor(lbl_status, true);
275
lv_label_set_text(lbl_status, " ");
276
usbs->label = (void *)lbl_status;
277
278
lv_obj_t *lbl_tip = lv_label_create(mbox, NULL);
279
lv_label_set_recolor(lbl_tip, true);
280
if (!usbs->ro)
281
{
282
if (usbs->type == MMC_SD)
283
{
284
lv_label_set_static_text(lbl_tip,
285
"Note: To end it, #C7EA46 safely eject# from inside the OS.\n"
286
" #FFDD00 DO NOT remove the cable!#");
287
}
288
else
289
{
290
lv_label_set_static_text(lbl_tip,
291
"Note: To end it, #C7EA46 safely eject# from inside the OS.\n"
292
" #FFDD00 If it's not mounted, you might need to remove the cable!#");
293
}
294
}
295
else
296
{
297
lv_label_set_static_text(lbl_tip,
298
"Note: To end it, #C7EA46 safely eject# from inside the OS\n"
299
" or by removing the cable!#");
300
}
301
lv_obj_set_style(lbl_tip, &hint_small_style);
302
303
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
304
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
305
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
306
lv_obj_set_top(mbox, true);
307
308
// Dim backlight.
309
display_backlight_brightness(20, 1000);
310
311
usb_device_gadget_ums(usbs);
312
313
// Restore backlight.
314
display_backlight_brightness(h_cfg.backlight - 20, 1000);
315
316
lv_mbox_add_btns(mbox, mbox_btn_map2, mbox_action);
317
318
ums_mbox = dark_bg;
319
320
return LV_RES_OK;
321
}
322
323
static lv_res_t _create_mbox_ums_error(int error)
324
{
325
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
326
lv_obj_set_style(dark_bg, &mbox_darken);
327
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
328
329
static const char *mbox_btn_map[] = { "\251", "\222OK", "\251", "" };
330
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
331
lv_mbox_set_recolor_text(mbox, true);
332
333
switch (error)
334
{
335
case 1:
336
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Error mounting SD Card!#");
337
break;
338
case 2:
339
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 No emuMMC found active!#");
340
break;
341
case 3:
342
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Active emuMMC is not partition based!#");
343
break;
344
}
345
346
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
347
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
348
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
349
lv_obj_set_top(mbox, true);
350
351
return LV_RES_OK;
352
}
353
354
static void usb_gadget_set_text(void *lbl, const char *text)
355
{
356
lv_label_set_text((lv_obj_t *)lbl, text);
357
manual_system_maintenance(true);
358
}
359
360
static lv_res_t _action_hid_jc(lv_obj_t *btn)
361
{
362
// Reduce BPMP, RAM and backlight and power off SDMMC1 to conserve power.
363
sd_end();
364
minerva_change_freq(FREQ_800);
365
bpmp_clk_rate_relaxed(true);
366
display_backlight_brightness(10, 1000);
367
368
usb_ctxt_t usbs;
369
usbs.type = USB_HID_GAMEPAD;
370
usbs.system_maintenance = &manual_system_maintenance;
371
usbs.set_text = &usb_gadget_set_text;
372
373
_create_mbox_hid(&usbs);
374
375
// Restore BPMP, RAM and backlight.
376
minerva_change_freq(FREQ_1600);
377
bpmp_clk_rate_relaxed(false);
378
display_backlight_brightness(h_cfg.backlight - 20, 1000);
379
380
return LV_RES_OK;
381
}
382
383
/*
384
static lv_res_t _action_hid_touch(lv_obj_t *btn)
385
{
386
// Reduce BPMP, RAM and backlight and power off SDMMC1 to conserve power.
387
sd_end();
388
minerva_change_freq(FREQ_800);
389
bpmp_clk_rate_relaxed(true);
390
display_backlight_brightness(10, 1000);
391
392
usb_ctxt_t usbs;
393
usbs.type = USB_HID_TOUCHPAD;
394
usbs.system_maintenance = &manual_system_maintenance;
395
usbs.set_text = &usb_gadget_set_text;
396
397
_create_mbox_hid(&usbs);
398
399
// Restore BPMP, RAM and backlight.
400
minerva_change_freq(FREQ_1600);
401
bpmp_clk_rate_relaxed(false);
402
display_backlight_brightness(h_cfg.backlight - 20, 1000);
403
404
return LV_RES_OK;
405
}
406
*/
407
408
static bool usb_msc_emmc_read_only;
409
lv_res_t action_ums_sd(lv_obj_t *btn)
410
{
411
usb_ctxt_t usbs;
412
usbs.type = MMC_SD;
413
usbs.partition = 0;
414
usbs.offset = 0;
415
usbs.sectors = 0;
416
usbs.ro = 0;
417
usbs.system_maintenance = &manual_system_maintenance;
418
usbs.set_text = &usb_gadget_set_text;
419
420
_create_mbox_ums(&usbs);
421
422
return LV_RES_OK;
423
}
424
425
static lv_res_t _action_ums_emmc_boot0(lv_obj_t *btn)
426
{
427
if (!nyx_emmc_check_battery_enough())
428
return LV_RES_OK;
429
430
usb_ctxt_t usbs;
431
usbs.type = MMC_EMMC;
432
usbs.partition = EMMC_BOOT0 + 1;
433
usbs.offset = 0;
434
usbs.sectors = 0;
435
usbs.ro = usb_msc_emmc_read_only;
436
usbs.system_maintenance = &manual_system_maintenance;
437
usbs.set_text = &usb_gadget_set_text;
438
439
_create_mbox_ums(&usbs);
440
441
return LV_RES_OK;
442
}
443
444
static lv_res_t _action_ums_emmc_boot1(lv_obj_t *btn)
445
{
446
if (!nyx_emmc_check_battery_enough())
447
return LV_RES_OK;
448
449
usb_ctxt_t usbs;
450
usbs.type = MMC_EMMC;
451
usbs.partition = EMMC_BOOT1 + 1;
452
usbs.offset = 0;
453
usbs.sectors = 0;
454
usbs.ro = usb_msc_emmc_read_only;
455
usbs.system_maintenance = &manual_system_maintenance;
456
usbs.set_text = &usb_gadget_set_text;
457
458
_create_mbox_ums(&usbs);
459
460
return LV_RES_OK;
461
}
462
463
static lv_res_t _action_ums_emmc_gpp(lv_obj_t *btn)
464
{
465
if (!nyx_emmc_check_battery_enough())
466
return LV_RES_OK;
467
468
usb_ctxt_t usbs;
469
usbs.type = MMC_EMMC;
470
usbs.partition = EMMC_GPP + 1;
471
usbs.offset = 0;
472
usbs.sectors = 0;
473
usbs.ro = usb_msc_emmc_read_only;
474
usbs.system_maintenance = &manual_system_maintenance;
475
usbs.set_text = &usb_gadget_set_text;
476
477
_create_mbox_ums(&usbs);
478
479
return LV_RES_OK;
480
}
481
482
static lv_res_t _action_ums_emuemmc_boot0(lv_obj_t *btn)
483
{
484
if (!nyx_emmc_check_battery_enough())
485
return LV_RES_OK;
486
487
usb_ctxt_t usbs;
488
489
int error = !sd_mount();
490
if (!error)
491
{
492
emummc_cfg_t emu_info;
493
load_emummc_cfg(&emu_info);
494
495
error = 2;
496
if (emu_info.enabled)
497
{
498
error = 3;
499
if (emu_info.sector)
500
{
501
error = 0;
502
usbs.offset = emu_info.sector;
503
}
504
}
505
506
if (emu_info.path)
507
free(emu_info.path);
508
if (emu_info.nintendo_path)
509
free(emu_info.nintendo_path);
510
}
511
sd_unmount();
512
513
if (error)
514
_create_mbox_ums_error(error);
515
else
516
{
517
usbs.type = MMC_SD;
518
usbs.partition = EMMC_BOOT0 + 1;
519
usbs.sectors = 0x2000; // Forced 4MB.
520
usbs.ro = usb_msc_emmc_read_only;
521
usbs.system_maintenance = &manual_system_maintenance;
522
usbs.set_text = &usb_gadget_set_text;
523
_create_mbox_ums(&usbs);
524
}
525
526
return LV_RES_OK;
527
}
528
529
static lv_res_t _action_ums_emuemmc_boot1(lv_obj_t *btn)
530
{
531
if (!nyx_emmc_check_battery_enough())
532
return LV_RES_OK;
533
534
usb_ctxt_t usbs;
535
536
int error = !sd_mount();
537
if (!error)
538
{
539
emummc_cfg_t emu_info;
540
load_emummc_cfg(&emu_info);
541
542
error = 2;
543
if (emu_info.enabled)
544
{
545
error = 3;
546
if (emu_info.sector)
547
{
548
error = 0;
549
usbs.offset = emu_info.sector + 0x2000;
550
}
551
}
552
553
if (emu_info.path)
554
free(emu_info.path);
555
if (emu_info.nintendo_path)
556
free(emu_info.nintendo_path);
557
}
558
sd_unmount();
559
560
if (error)
561
_create_mbox_ums_error(error);
562
else
563
{
564
usbs.type = MMC_SD;
565
usbs.partition = EMMC_BOOT1 + 1;
566
usbs.sectors = 0x2000; // Forced 4MB.
567
usbs.ro = usb_msc_emmc_read_only;
568
usbs.system_maintenance = &manual_system_maintenance;
569
usbs.set_text = &usb_gadget_set_text;
570
_create_mbox_ums(&usbs);
571
}
572
573
return LV_RES_OK;
574
}
575
576
static lv_res_t _action_ums_emuemmc_gpp(lv_obj_t *btn)
577
{
578
if (!nyx_emmc_check_battery_enough())
579
return LV_RES_OK;
580
581
usb_ctxt_t usbs;
582
583
int error = !sd_mount();
584
if (!error)
585
{
586
emummc_cfg_t emu_info;
587
load_emummc_cfg(&emu_info);
588
589
error = 2;
590
if (emu_info.enabled)
591
{
592
error = 3;
593
if (emu_info.sector)
594
{
595
error = 1;
596
usbs.offset = emu_info.sector + 0x4000;
597
598
u8 *gpt = malloc(SD_BLOCKSIZE);
599
if (sdmmc_storage_read(&sd_storage, usbs.offset + 1, 1, gpt))
600
{
601
if (!memcmp(gpt, "EFI PART", 8))
602
{
603
error = 0;
604
usbs.sectors = *(u32 *)(gpt + 0x20) + 1; // Backup LBA + 1.
605
}
606
}
607
}
608
}
609
610
if (emu_info.path)
611
free(emu_info.path);
612
if (emu_info.nintendo_path)
613
free(emu_info.nintendo_path);
614
}
615
sd_unmount();
616
617
if (error)
618
_create_mbox_ums_error(error);
619
else
620
{
621
usbs.type = MMC_SD;
622
usbs.partition = EMMC_GPP + 1;
623
usbs.ro = usb_msc_emmc_read_only;
624
usbs.system_maintenance = &manual_system_maintenance;
625
usbs.set_text = &usb_gadget_set_text;
626
_create_mbox_ums(&usbs);
627
}
628
629
return LV_RES_OK;
630
}
631
632
void nyx_run_ums(void *param)
633
{
634
u32 *cfg = (u32 *)param;
635
636
u8 type = (*cfg) >> 24;
637
*cfg = *cfg & (~NYX_CFG_EXTRA);
638
639
// Disable read only flag.
640
usb_msc_emmc_read_only = false;
641
642
switch (type)
643
{
644
case NYX_UMS_SD_CARD:
645
action_ums_sd(NULL);
646
break;
647
case NYX_UMS_EMMC_BOOT0:
648
_action_ums_emmc_boot0(NULL);
649
break;
650
case NYX_UMS_EMMC_BOOT1:
651
_action_ums_emmc_boot1(NULL);
652
break;
653
case NYX_UMS_EMMC_GPP:
654
_action_ums_emmc_gpp(NULL);
655
break;
656
case NYX_UMS_EMUMMC_BOOT0:
657
_action_ums_emuemmc_boot0(NULL);
658
break;
659
case NYX_UMS_EMUMMC_BOOT1:
660
_action_ums_emuemmc_boot1(NULL);
661
break;
662
case NYX_UMS_EMUMMC_GPP:
663
_action_ums_emuemmc_gpp(NULL);
664
break;
665
}
666
}
667
668
static lv_res_t _emmc_read_only_toggle(lv_obj_t *btn)
669
{
670
nyx_generic_onoff_toggle(btn);
671
672
usb_msc_emmc_read_only = lv_btn_get_state(btn) & LV_BTN_STATE_TGL_REL ? 1 : 0;
673
674
return LV_RES_OK;
675
}
676
677
static lv_res_t _create_window_usb_tools(lv_obj_t *parent)
678
{
679
lv_obj_t *win = nyx_create_standard_window(SYMBOL_USB" USB Tools");
680
681
static lv_style_t h_style;
682
lv_style_copy(&h_style, &lv_style_transp);
683
h_style.body.padding.inner = 0;
684
h_style.body.padding.hor = LV_DPI - (LV_DPI / 4);
685
h_style.body.padding.ver = LV_DPI / 9;
686
687
// Create USB Mass Storage container.
688
lv_obj_t *h1 = lv_cont_create(win, NULL);
689
lv_cont_set_style(h1, &h_style);
690
lv_cont_set_fit(h1, false, true);
691
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 5);
692
lv_obj_set_click(h1, false);
693
lv_cont_set_layout(h1, LV_LAYOUT_OFF);
694
695
lv_obj_t *label_sep = lv_label_create(h1, NULL);
696
lv_label_set_static_text(label_sep, "");
697
698
lv_obj_t *label_txt = lv_label_create(h1, NULL);
699
lv_label_set_static_text(label_txt, "USB Mass Storage");
700
lv_obj_set_style(label_txt, lv_theme_get_current()->label.prim);
701
lv_obj_align(label_txt, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI * 3 / 10);
702
703
lv_obj_t *line_sep = lv_line_create(h1, NULL);
704
static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 4)) * 2, 0} };
705
lv_line_set_points(line_sep, line_pp, 2);
706
lv_line_set_style(line_sep, lv_theme_get_current()->line.decor);
707
lv_obj_align(line_sep, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
708
709
// Create SD UMS button.
710
lv_obj_t *btn1 = lv_btn_create(h1, NULL);
711
lv_obj_t *label_btn = lv_label_create(btn1, NULL);
712
lv_btn_set_fit(btn1, true, true);
713
lv_label_set_static_text(label_btn, SYMBOL_SD" SD Card");
714
715
lv_obj_align(btn1, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
716
lv_btn_set_action(btn1, LV_BTN_ACTION_CLICK, action_ums_sd);
717
718
lv_obj_t *label_txt2 = lv_label_create(h1, NULL);
719
lv_label_set_recolor(label_txt2, true);
720
lv_label_set_static_text(label_txt2,
721
"Allows you to mount the SD Card to a PC/Phone.\n"
722
"#C7EA46 All operating systems are supported. Access is# #FF8000 Read/Write.#");
723
724
lv_obj_set_style(label_txt2, &hint_small_style);
725
lv_obj_align(label_txt2, btn1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
726
727
// Create RAW GPP button.
728
lv_obj_t *btn_gpp = lv_btn_create(h1, btn1);
729
label_btn = lv_label_create(btn_gpp, NULL);
730
lv_label_set_static_text(label_btn, SYMBOL_CHIP" eMMC RAW GPP");
731
lv_obj_align(btn_gpp, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
732
lv_btn_set_action(btn_gpp, LV_BTN_ACTION_CLICK, _action_ums_emmc_gpp);
733
734
// Create BOOT0 button.
735
lv_obj_t *btn_boot0 = lv_btn_create(h1, btn1);
736
label_btn = lv_label_create(btn_boot0, NULL);
737
lv_label_set_static_text(label_btn, "BOOT0");
738
lv_obj_align(btn_boot0, btn_gpp, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 10, 0);
739
lv_btn_set_action(btn_boot0, LV_BTN_ACTION_CLICK, _action_ums_emmc_boot0);
740
741
// Create BOOT1 button.
742
lv_obj_t *btn_boot1 = lv_btn_create(h1, btn1);
743
label_btn = lv_label_create(btn_boot1, NULL);
744
lv_label_set_static_text(label_btn, "BOOT1");
745
lv_obj_align(btn_boot1, btn_boot0, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 10, 0);
746
lv_btn_set_action(btn_boot1, LV_BTN_ACTION_CLICK, _action_ums_emmc_boot1);
747
748
// Create emuMMC RAW GPP button.
749
lv_obj_t *btn_emu_gpp = lv_btn_create(h1, btn1);
750
label_btn = lv_label_create(btn_emu_gpp, NULL);
751
lv_label_set_static_text(label_btn, SYMBOL_MODULES_ALT" emu RAW GPP");
752
lv_obj_align(btn_emu_gpp, btn_gpp, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
753
lv_btn_set_action(btn_emu_gpp, LV_BTN_ACTION_CLICK, _action_ums_emuemmc_gpp);
754
755
// Create emuMMC BOOT0 button.
756
lv_obj_t *btn_emu_boot0 = lv_btn_create(h1, btn1);
757
label_btn = lv_label_create(btn_emu_boot0, NULL);
758
lv_label_set_static_text(label_btn, "BOOT0");
759
lv_obj_align(btn_emu_boot0, btn_boot0, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
760
lv_btn_set_action(btn_emu_boot0, LV_BTN_ACTION_CLICK, _action_ums_emuemmc_boot0);
761
762
// Create emuMMC BOOT1 button.
763
lv_obj_t *btn_emu_boot1 = lv_btn_create(h1, btn1);
764
label_btn = lv_label_create(btn_emu_boot1, NULL);
765
lv_label_set_static_text(label_btn, "BOOT1");
766
lv_obj_align(btn_emu_boot1, btn_boot1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
767
lv_btn_set_action(btn_emu_boot1, LV_BTN_ACTION_CLICK, _action_ums_emuemmc_boot1);
768
769
label_txt2 = lv_label_create(h1, NULL);
770
lv_label_set_recolor(label_txt2, true);
771
lv_label_set_static_text(label_txt2,
772
"Allows you to mount the eMMC/emuMMC.\n"
773
"#C7EA46 Default access is# #FF8000 read-only.#");
774
lv_obj_set_style(label_txt2, &hint_small_style);
775
lv_obj_align(label_txt2, btn_emu_gpp, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
776
777
lv_obj_t *h_write = lv_cont_create(win, NULL);
778
lv_cont_set_style(h_write, &h_style);
779
lv_cont_set_fit(h_write, false, true);
780
lv_obj_set_width(h_write, (LV_HOR_RES / 9) * 2);
781
lv_obj_set_click(h_write, false);
782
lv_cont_set_layout(h_write, LV_LAYOUT_OFF);
783
lv_obj_align(h_write, label_txt2, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 10, 0);
784
785
// Create read/write access button.
786
lv_obj_t *btn_write_access = lv_btn_create(h_write, NULL);
787
nyx_create_onoff_button(lv_theme_get_current(), h_write,
788
btn_write_access, SYMBOL_EDIT" Read-Only", _emmc_read_only_toggle, false);
789
if (!n_cfg.ums_emmc_rw)
790
lv_btn_set_state(btn_write_access, LV_BTN_STATE_TGL_REL);
791
_emmc_read_only_toggle(btn_write_access);
792
793
// Create USB Input Devices container.
794
lv_obj_t *h2 = lv_cont_create(win, NULL);
795
lv_cont_set_style(h2, &h_style);
796
lv_cont_set_fit(h2, false, true);
797
lv_obj_set_width(h2, (LV_HOR_RES / 9) * 3);
798
lv_obj_set_click(h2, false);
799
lv_cont_set_layout(h2, LV_LAYOUT_OFF);
800
lv_obj_align(h2, h1, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI * 17 / 29, 0);
801
802
label_sep = lv_label_create(h2, NULL);
803
lv_label_set_static_text(label_sep, "");
804
805
lv_obj_t *label_txt3 = lv_label_create(h2, NULL);
806
lv_label_set_static_text(label_txt3, "USB Input Devices");
807
lv_obj_set_style(label_txt3, lv_theme_get_current()->label.prim);
808
lv_obj_align(label_txt3, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI * 4 / 21);
809
810
line_sep = lv_line_create(h2, line_sep);
811
lv_obj_align(line_sep, label_txt3, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
812
813
// Create Gamepad button.
814
lv_obj_t *btn3 = lv_btn_create(h2, NULL);
815
label_btn = lv_label_create(btn3, NULL);
816
lv_btn_set_fit(btn3, true, true);
817
lv_label_set_static_text(label_btn, SYMBOL_CIRCUIT" Gamepad");
818
lv_obj_align(btn3, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
819
lv_btn_set_action(btn3, LV_BTN_ACTION_CLICK, _action_hid_jc);
820
821
lv_obj_t *label_txt4 = lv_label_create(h2, NULL);
822
lv_label_set_recolor(label_txt4, true);
823
lv_label_set_static_text(label_txt4,
824
"Plug-in the Joy-Con and convert the device\n"
825
"into a gamepad for PC or Phone.\n"
826
"#C7EA46 Needs both Joy-Con in order to function.#");
827
828
lv_obj_set_style(label_txt4, &hint_small_style);
829
lv_obj_align(label_txt4, btn3, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
830
/*
831
// Create Touchpad button.
832
lv_obj_t *btn4 = lv_btn_create(h2, btn1);
833
label_btn = lv_label_create(btn4, NULL);
834
lv_label_set_static_text(label_btn, SYMBOL_KEYBOARD" Touchpad");
835
lv_obj_align(btn4, label_txt4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
836
lv_btn_set_action(btn4, LV_BTN_ACTION_CLICK, _action_hid_touch);
837
lv_btn_set_state(btn4, LV_BTN_STATE_INA);
838
839
label_txt4 = lv_label_create(h2, NULL);
840
lv_label_set_recolor(label_txt4, true);
841
lv_label_set_static_text(label_txt4,
842
"Control the PC via the device\'s touchscreen.\n"
843
"#C7EA46 Two fingers tap acts like a# #FF8000 Right click##C7EA46 .#\n");
844
lv_obj_set_style(label_txt4, &hint_small_style);
845
lv_obj_align(label_txt4, btn4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
846
*/
847
return LV_RES_OK;
848
}
849
850
static int _fix_attributes(lv_obj_t *lb_val, char *path, u32 *total)
851
{
852
FRESULT res;
853
DIR dir;
854
u32 dirLength = 0;
855
static FILINFO fno;
856
857
// Open directory.
858
res = f_opendir(&dir, path);
859
if (res != FR_OK)
860
return res;
861
862
dirLength = strlen(path);
863
864
// Hard limit path to 1024 characters. Do not result to error.
865
if (dirLength > 1024)
866
{
867
total[2]++;
868
goto out;
869
}
870
871
for (;;)
872
{
873
// Clear file or folder path.
874
path[dirLength] = 0;
875
876
// Read a directory item.
877
res = f_readdir(&dir, &fno);
878
879
// Break on error or end of dir.
880
if (res != FR_OK || fno.fname[0] == 0)
881
break;
882
883
// Set new directory or file.
884
memcpy(&path[dirLength], "/", 1);
885
strcpy(&path[dirLength + 1], fno.fname);
886
887
// Is it a directory?
888
if (fno.fattrib & AM_DIR)
889
{
890
// Check if it's a HOS single file folder.
891
strcat(path, "/00");
892
bool is_hos_special = !f_stat(path, NULL);
893
path[strlen(path) - 3] = 0;
894
895
// Set archive bit to HOS single file folders.
896
if (is_hos_special)
897
{
898
if (!(fno.fattrib & AM_ARC))
899
{
900
if (!f_chmod(path, AM_ARC, AM_ARC))
901
total[0]++;
902
else
903
total[3]++;
904
}
905
}
906
else if (fno.fattrib & AM_ARC) // If not, clear the archive bit.
907
{
908
if (!f_chmod(path, 0, AM_ARC))
909
total[1]++;
910
else
911
total[3]++;
912
}
913
914
lv_label_set_text(lb_val, path);
915
manual_system_maintenance(true);
916
917
// Enter the directory.
918
res = _fix_attributes(lb_val, path, total);
919
if (res != FR_OK)
920
break;
921
}
922
}
923
924
out:
925
f_closedir(&dir);
926
927
return res;
928
}
929
930
static lv_res_t _create_window_unset_abit_tool(lv_obj_t *btn)
931
{
932
lv_obj_t *win = nyx_create_standard_window(SYMBOL_COPY" Fix Archive Bit (All folders)");
933
934
// Disable buttons.
935
nyx_window_toggle_buttons(win, true);
936
937
lv_obj_t *desc = lv_cont_create(win, NULL);
938
lv_obj_set_size(desc, LV_HOR_RES * 10 / 11, LV_VER_RES - (LV_DPI * 11 / 7) * 4);
939
940
lv_obj_t * lb_desc = lv_label_create(desc, NULL);
941
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
942
lv_label_set_recolor(lb_desc, true);
943
944
if (!sd_mount())
945
{
946
lv_label_set_text(lb_desc, "#FFDD00 Failed to init SD!#");
947
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
948
}
949
else
950
{
951
lv_label_set_text(lb_desc, "#00DDFF Traversing all SD card files!#\nThis may take some time...");
952
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
953
954
lv_obj_t *val = lv_cont_create(win, NULL);
955
lv_obj_set_size(val, LV_HOR_RES * 10 / 11, LV_VER_RES - (LV_DPI * 11 / 7) * 4);
956
957
lv_obj_t * lb_val = lv_label_create(val, lb_desc);
958
959
char *path = malloc(0x1000);
960
path[0] = 0;
961
962
lv_label_set_text(lb_val, "");
963
lv_obj_set_width(lb_val, lv_obj_get_width(val));
964
lv_obj_align(val, desc, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
965
966
u32 total[4] = { 0 };
967
_fix_attributes(lb_val, path, total);
968
969
sd_unmount();
970
971
lv_obj_t *desc2 = lv_cont_create(win, NULL);
972
lv_obj_set_size(desc2, LV_HOR_RES * 10 / 11, LV_VER_RES - (LV_DPI * 11 / 7) * 4);
973
lv_obj_t * lb_desc2 = lv_label_create(desc2, lb_desc);
974
975
char *txt_buf = (char *)malloc(0x500);
976
977
if (!total[0] && !total[1])
978
s_printf(txt_buf, "#96FF00 Done! No change was needed.#");
979
else
980
s_printf(txt_buf, "#96FF00 Done! Archive bits fixed:# #FF8000 %d unset and %d set!#", total[1], total[0]);
981
982
// Check errors.
983
if (total[2] || total[3])
984
{
985
s_printf(txt_buf, "\n\n#FFDD00 Errors: folder accesses: %d, arc bit fixes: %d!#\n"
986
"#FFDD00 Filesystem should be checked for errors.#",
987
total[2], total[3]);
988
}
989
990
lv_label_set_text(lb_desc2, txt_buf);
991
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc2));
992
lv_obj_align(desc2, val, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 0);
993
994
free(path);
995
}
996
997
// Enable buttons.
998
nyx_window_toggle_buttons(win, false);
999
1000
return LV_RES_OK;
1001
}
1002
1003
static lv_res_t _create_mbox_fix_touchscreen(lv_obj_t *btn)
1004
{
1005
int res = 0;
1006
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
1007
lv_obj_set_style(dark_bg, &mbox_darken);
1008
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
1009
1010
static const char *mbox_btn_map[] = { "\251", "\222OK", "\251", "" };
1011
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
1012
lv_mbox_set_recolor_text(mbox, true);
1013
1014
char *txt_buf = malloc(SZ_16K);
1015
strcpy(txt_buf, "#FF8000 Don't touch the screen!#\n\nThe tuning process will start in ");
1016
u32 text_idx = strlen(txt_buf);
1017
lv_mbox_set_text(mbox, txt_buf);
1018
1019
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);
1020
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
1021
lv_obj_set_top(mbox, true);
1022
1023
lv_mbox_set_text(mbox,
1024
"#FFDD00 Warning: Only run this if you really have issues!#\n\n"
1025
"Press #FF8000 POWER# to Continue.\nPress #FF8000 VOL# to abort.");
1026
manual_system_maintenance(true);
1027
1028
if (!(btn_wait() & BTN_POWER))
1029
goto out;
1030
1031
manual_system_maintenance(true);
1032
lv_mbox_set_text(mbox, txt_buf);
1033
1034
u32 seconds = 5;
1035
while (seconds)
1036
{
1037
s_printf(txt_buf + text_idx, "%d seconds...", seconds);
1038
lv_mbox_set_text(mbox, txt_buf);
1039
manual_system_maintenance(true);
1040
msleep(1000);
1041
seconds--;
1042
}
1043
1044
u8 err[2];
1045
if (!touch_panel_ito_test(err))
1046
goto ito_failed;
1047
1048
if (!err[0] && !err[1])
1049
{
1050
res = touch_execute_autotune();
1051
if (res)
1052
goto out;
1053
}
1054
else
1055
{
1056
touch_sense_enable();
1057
1058
s_printf(txt_buf, "#FFFF00 ITO Test: ");
1059
switch (err[0])
1060
{
1061
case ITO_FORCE_OPEN:
1062
strcat(txt_buf, "Force Open");
1063
break;
1064
case ITO_SENSE_OPEN:
1065
strcat(txt_buf, "Sense Open");
1066
break;
1067
case ITO_FORCE_SHRT_GND:
1068
strcat(txt_buf, "Force Short to GND");
1069
break;
1070
case ITO_SENSE_SHRT_GND:
1071
strcat(txt_buf, "Sense Short to GND");
1072
break;
1073
case ITO_FORCE_SHRT_VCM:
1074
strcat(txt_buf, "Force Short to VDD");
1075
break;
1076
case ITO_SENSE_SHRT_VCM:
1077
strcat(txt_buf, "Sense Short to VDD");
1078
break;
1079
case ITO_FORCE_SHRT_FORCE:
1080
strcat(txt_buf, "Force Short to Force");
1081
break;
1082
case ITO_SENSE_SHRT_SENSE:
1083
strcat(txt_buf, "Sense Short to Sense");
1084
break;
1085
case ITO_F2E_SENSE:
1086
strcat(txt_buf, "Force Short to Sense");
1087
break;
1088
case ITO_FPC_FORCE_OPEN:
1089
strcat(txt_buf, "FPC Force Open");
1090
break;
1091
case ITO_FPC_SENSE_OPEN:
1092
strcat(txt_buf, "FPC Sense Open");
1093
break;
1094
default:
1095
strcat(txt_buf, "Unknown");
1096
break;
1097
1098
}
1099
s_printf(txt_buf + strlen(txt_buf), " (%d), Chn: %d#\n\n", err[0], err[1]);
1100
strcat(txt_buf, "#FFFF00 The touchscreen calibration failed!");
1101
lv_mbox_set_text(mbox, txt_buf);
1102
goto out2;
1103
}
1104
1105
ito_failed:
1106
touch_sense_enable();
1107
1108
out:
1109
if (res)
1110
lv_mbox_set_text(mbox, "#C7EA46 The touchscreen calibration finished!");
1111
else
1112
lv_mbox_set_text(mbox, "#FFFF00 The touchscreen calibration failed!");
1113
1114
out2:
1115
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
1116
1117
free(txt_buf);
1118
1119
return LV_RES_OK;
1120
}
1121
1122
static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
1123
{
1124
lv_obj_t *win = nyx_create_standard_window(SYMBOL_MODULES" Dump package1/2");
1125
1126
// Disable buttons.
1127
nyx_window_toggle_buttons(win, true);
1128
1129
lv_obj_t *desc = lv_cont_create(win, NULL);
1130
lv_obj_set_size(desc, LV_HOR_RES * 10 / 11, LV_VER_RES - (LV_DPI * 12 / 7));
1131
1132
lv_obj_t * lb_desc = lv_label_create(desc, NULL);
1133
lv_obj_set_style(lb_desc, &monospace_text);
1134
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
1135
lv_label_set_recolor(lb_desc, true);
1136
lv_obj_set_width(lb_desc, lv_obj_get_width(desc));
1137
1138
if (!sd_mount())
1139
{
1140
lv_label_set_text(lb_desc, "#FFDD00 Failed to init SD!#");
1141
1142
goto out_end;
1143
}
1144
1145
char path[128];
1146
1147
u8 kb = 0;
1148
u8 *pkg1 = (u8 *)zalloc(SZ_256K);
1149
u8 *warmboot = (u8 *)zalloc(SZ_256K);
1150
u8 *secmon = (u8 *)zalloc(SZ_256K);
1151
u8 *loader = (u8 *)zalloc(SZ_256K);
1152
u8 *pkg2 = NULL;
1153
1154
char *txt_buf = (char *)malloc(SZ_16K);
1155
1156
if (!emmc_initialize(false))
1157
{
1158
lv_label_set_text(lb_desc, "#FFDD00 Failed to init eMMC!#");
1159
1160
goto out_free;
1161
}
1162
1163
emmc_set_partition(EMMC_BOOT0);
1164
1165
// Read package1.
1166
static const u32 BOOTLOADER_SIZE = SZ_256K;
1167
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
1168
static const u32 HOS_KEYBLOBS_OFFSET = 0x180000;
1169
1170
char *build_date = malloc(32);
1171
u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header.
1172
sdmmc_storage_read(&emmc_storage, BOOTLOADER_MAIN_OFFSET / EMMC_BLOCKSIZE, BOOTLOADER_SIZE / EMMC_BLOCKSIZE, pkg1);
1173
1174
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1 + pk1_offset, build_date);
1175
1176
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n\n", build_date);
1177
free(build_date);
1178
lv_label_set_text(lb_desc, txt_buf);
1179
manual_system_maintenance(true);
1180
1181
// Dump package1 in its encrypted state.
1182
emmcsn_path_impl(path, "/pkg1", "pkg1_enc.bin", &emmc_storage);
1183
bool res = sd_save_to_file(pkg1, BOOTLOADER_SIZE, path);
1184
1185
// Exit if unknown.
1186
if (!pkg1_id)
1187
{
1188
strcat(txt_buf, "#FFDD00 Unknown pkg1 version!#");
1189
lv_label_set_text(lb_desc, txt_buf);
1190
manual_system_maintenance(true);
1191
1192
if (!res)
1193
{
1194
strcat(txt_buf, "\nEncrypted pkg1 dumped to pkg1_enc.bin");
1195
lv_label_set_text(lb_desc, txt_buf);
1196
manual_system_maintenance(true);
1197
}
1198
1199
goto out_free;
1200
}
1201
1202
kb = pkg1_id->kb;
1203
1204
tsec_ctxt_t tsec_ctxt = {0};
1205
tsec_ctxt.fw = (void *)(pkg1 + pkg1_id->tsec_off);
1206
tsec_ctxt.pkg1 = (void *)pkg1;
1207
tsec_ctxt.pkg11_off = pkg1_id->pkg11_off;
1208
1209
// Read keyblob.
1210
u8 *keyblob = (u8 *)zalloc(EMMC_BLOCKSIZE);
1211
sdmmc_storage_read(&emmc_storage, HOS_KEYBLOBS_OFFSET / EMMC_BLOCKSIZE + kb, 1, keyblob);
1212
1213
// Decrypt.
1214
hos_keygen(keyblob, kb, &tsec_ctxt);
1215
free(keyblob);
1216
1217
if (h_cfg.t210b01 || kb <= HOS_KB_VERSION_600)
1218
{
1219
if (!pkg1_decrypt(pkg1_id, pkg1))
1220
{
1221
strcat(txt_buf, "#FFDD00 Pkg1 decryption failed!#\n");
1222
if (h_cfg.t210b01)
1223
strcat(txt_buf, "#FFDD00 Is BEK missing?#\n");
1224
lv_label_set_text(lb_desc, txt_buf);
1225
goto out_free;
1226
}
1227
}
1228
1229
if (h_cfg.t210b01 || kb <= HOS_KB_VERSION_620)
1230
{
1231
pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1 + pk1_offset);
1232
pk11_hdr_t *hdr_pk11 = (pk11_hdr_t *)(pkg1 + pk1_offset + pkg1_id->pkg11_off + 0x20);
1233
1234
// Display info.
1235
s_printf(txt_buf + strlen(txt_buf),
1236
"#C7EA46 NX Bootloader size: #0x%05X\n"
1237
"#C7EA46 Secure monitor addr: #0x%05X\n"
1238
"#C7EA46 Secure monitor size: #0x%05X\n"
1239
"#C7EA46 Warmboot addr: #0x%05X\n"
1240
"#C7EA46 Warmboot size: #0x%05X\n\n",
1241
hdr_pk11->ldr_size, pkg1_id->secmon_base, hdr_pk11->sm_size, pkg1_id->warmboot_base, hdr_pk11->wb_size);
1242
1243
lv_label_set_text(lb_desc, txt_buf);
1244
manual_system_maintenance(true);
1245
1246
// Dump package1.1.
1247
emmcsn_path_impl(path, "/pkg1", "pkg1_decr.bin", &emmc_storage);
1248
if (sd_save_to_file(pkg1, SZ_256K, path))
1249
goto out_free;
1250
strcat(txt_buf, "pkg1 dumped to pkg1_decr.bin\n");
1251
lv_label_set_text(lb_desc, txt_buf);
1252
manual_system_maintenance(true);
1253
1254
// Dump nxbootloader.
1255
emmcsn_path_impl(path, "/pkg1", "nxloader.bin", &emmc_storage);
1256
if (sd_save_to_file(loader, hdr_pk11->ldr_size, path))
1257
goto out_free;
1258
strcat(txt_buf, "NX Bootloader dumped to nxloader.bin\n");
1259
lv_label_set_text(lb_desc, txt_buf);
1260
manual_system_maintenance(true);
1261
1262
// Dump secmon.
1263
emmcsn_path_impl(path, "/pkg1", "secmon.bin", &emmc_storage);
1264
if (sd_save_to_file(secmon, hdr_pk11->sm_size, path))
1265
goto out_free;
1266
strcat(txt_buf, "Secure Monitor dumped to secmon.bin\n");
1267
lv_label_set_text(lb_desc, txt_buf);
1268
manual_system_maintenance(true);
1269
1270
// Dump warmboot.
1271
emmcsn_path_impl(path, "/pkg1", "warmboot.bin", &emmc_storage);
1272
if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path))
1273
goto out_free;
1274
// If T210B01, save a copy of decrypted warmboot binary also.
1275
if (h_cfg.t210b01)
1276
{
1277
1278
se_aes_iv_clear(13);
1279
se_aes_crypt_cbc(13, DECRYPT, warmboot + 0x330, hdr_pk11->wb_size - 0x330,
1280
warmboot + 0x330, hdr_pk11->wb_size - 0x330);
1281
emmcsn_path_impl(path, "/pkg1", "warmboot_dec.bin", &emmc_storage);
1282
if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path))
1283
goto out_free;
1284
}
1285
strcat(txt_buf, "Warmboot dumped to warmboot.bin\n\n");
1286
lv_label_set_text(lb_desc, txt_buf);
1287
manual_system_maintenance(true);
1288
}
1289
1290
// Dump package2.1.
1291
emmc_set_partition(EMMC_GPP);
1292
// Parse eMMC GPT.
1293
LIST_INIT(gpt);
1294
emmc_gpt_parse(&gpt);
1295
// Find package2 partition.
1296
emmc_part_t *pkg2_part = emmc_part_find(&gpt, "BCPKG2-1-Normal-Main");
1297
if (!pkg2_part)
1298
goto out;
1299
1300
// Read in package2 header and get package2 real size.
1301
u8 *tmp = (u8 *)malloc(EMMC_BLOCKSIZE);
1302
emmc_part_read(pkg2_part, 0x4000 / EMMC_BLOCKSIZE, 1, tmp);
1303
u32 *hdr_pkg2_raw = (u32 *)(tmp + 0x100);
1304
u32 pkg2_size = hdr_pkg2_raw[0] ^ hdr_pkg2_raw[2] ^ hdr_pkg2_raw[3];
1305
free(tmp);
1306
// Read in package2.
1307
u32 pkg2_size_aligned = ALIGN(pkg2_size, EMMC_BLOCKSIZE);
1308
pkg2 = malloc(pkg2_size_aligned);
1309
emmc_part_read(pkg2_part, 0x4000 / EMMC_BLOCKSIZE,
1310
pkg2_size_aligned / EMMC_BLOCKSIZE, pkg2);
1311
1312
// Dump encrypted package2.
1313
emmcsn_path_impl(path, "/pkg2", "pkg2_encr.bin", &emmc_storage);
1314
res = sd_save_to_file(pkg2, pkg2_size, path);
1315
1316
// Decrypt package2 and parse KIP1 blobs in INI1 section.
1317
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(pkg2, kb);
1318
if (!pkg2_hdr)
1319
{
1320
strcat(txt_buf, "#FFDD00 Pkg2 decryption failed!#");
1321
lv_label_set_text(lb_desc, txt_buf);
1322
manual_system_maintenance(true);
1323
1324
if (!res)
1325
{
1326
strcat(txt_buf, "\npkg2 encrypted dumped to pkg2_encr.bin\n");
1327
lv_label_set_text(lb_desc, txt_buf);
1328
manual_system_maintenance(true);
1329
}
1330
1331
// Clear EKS slot, in case something went wrong with tsec keygen.
1332
hos_eks_clear(kb);
1333
1334
goto out;
1335
}
1336
1337
// Display info.
1338
s_printf(txt_buf + strlen(txt_buf),
1339
"#C7EA46 Kernel size: #0x%05X\n"
1340
"#C7EA46 INI1 size: #0x%05X\n\n",
1341
pkg2_hdr->sec_size[PKG2_SEC_KERNEL], pkg2_hdr->sec_size[PKG2_SEC_INI1]);
1342
1343
lv_label_set_text(lb_desc, txt_buf);
1344
manual_system_maintenance(true);
1345
1346
// Dump pkg2.1.
1347
emmcsn_path_impl(path, "/pkg2", "pkg2_decr.bin", &emmc_storage);
1348
if (sd_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1], path))
1349
goto out;
1350
strcat(txt_buf, "pkg2 dumped to pkg2_decr.bin\n");
1351
lv_label_set_text(lb_desc, txt_buf);
1352
manual_system_maintenance(true);
1353
1354
// Dump kernel.
1355
emmcsn_path_impl(path, "/pkg2", "kernel.bin", &emmc_storage);
1356
if (sd_save_to_file(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL], path))
1357
goto out;
1358
strcat(txt_buf, "Kernel dumped to kernel.bin\n");
1359
lv_label_set_text(lb_desc, txt_buf);
1360
manual_system_maintenance(true);
1361
1362
// Dump INI1.
1363
u32 ini1_off = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
1364
u32 ini1_size = pkg2_hdr->sec_size[PKG2_SEC_INI1];
1365
if (!ini1_size)
1366
{
1367
pkg2_get_newkern_info(pkg2_hdr->data);
1368
ini1_off = pkg2_newkern_ini1_start;
1369
ini1_size = pkg2_newkern_ini1_end - pkg2_newkern_ini1_start;
1370
}
1371
1372
if (!ini1_off)
1373
{
1374
strcat(txt_buf, "#FFDD00 Failed to dump INI1 and kips!#\n");
1375
goto out;
1376
}
1377
1378
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)(pkg2_hdr->data + ini1_off);
1379
emmcsn_path_impl(path, "/pkg2", "ini1.bin", &emmc_storage);
1380
if (sd_save_to_file(ini1, ini1_size, path))
1381
goto out;
1382
1383
strcat(txt_buf, "INI1 dumped to ini1.bin\n\n");
1384
lv_label_set_text(lb_desc, txt_buf);
1385
manual_system_maintenance(true);
1386
1387
char filename[32];
1388
u8 *ptr = (u8 *)ini1;
1389
ptr += sizeof(pkg2_ini1_t);
1390
1391
// Dump all kips.
1392
u8 *kip_buffer = (u8 *)malloc(SZ_4M);
1393
1394
for (u32 i = 0; i < ini1->num_procs; i++)
1395
{
1396
pkg2_kip1_t *kip1 = (pkg2_kip1_t *)ptr;
1397
u32 kip1_size = pkg2_calc_kip1_size(kip1);
1398
1399
s_printf(filename, "%s.kip1", kip1->name);
1400
if ((u32)kip1 % 8)
1401
{
1402
memcpy(kip_buffer, kip1, kip1_size);
1403
kip1 = (pkg2_kip1_t *)kip_buffer;
1404
}
1405
1406
emmcsn_path_impl(path, "/pkg2/ini1", filename, &emmc_storage);
1407
if (sd_save_to_file(kip1, kip1_size, path))
1408
{
1409
free(kip_buffer);
1410
goto out;
1411
}
1412
1413
s_printf(txt_buf + strlen(txt_buf), "%s kip dumped to %s.kip1\n", kip1->name, kip1->name);
1414
lv_label_set_text(lb_desc, txt_buf);
1415
manual_system_maintenance(true);
1416
1417
ptr += kip1_size;
1418
}
1419
free(kip_buffer);
1420
1421
out:
1422
emmc_gpt_free(&gpt);
1423
out_free:
1424
free(pkg1);
1425
free(secmon);
1426
free(warmboot);
1427
free(loader);
1428
free(pkg2);
1429
free(txt_buf);
1430
emmc_end();
1431
sd_unmount();
1432
1433
if (kb >= HOS_KB_VERSION_620)
1434
se_aes_key_clear(8);
1435
out_end:
1436
// Enable buttons.
1437
nyx_window_toggle_buttons(win, false);
1438
1439
return LV_RES_OK;
1440
}
1441
1442
static void _create_tab_tools_emmc_pkg12(lv_theme_t *th, lv_obj_t *parent)
1443
{
1444
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
1445
1446
// Create Backup & Restore container.
1447
lv_obj_t *h1 = _create_container(parent);
1448
1449
lv_obj_t *label_sep = lv_label_create(h1, NULL);
1450
lv_label_set_static_text(label_sep, "");
1451
1452
lv_obj_t *label_txt = lv_label_create(h1, NULL);
1453
lv_label_set_static_text(label_txt, "Backup & Restore");
1454
lv_obj_set_style(label_txt, th->label.prim);
1455
lv_obj_align(label_txt, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI * 3 / 10);
1456
1457
lv_obj_t *line_sep = lv_line_create(h1, NULL);
1458
static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 4)) * 2, 0} };
1459
lv_line_set_points(line_sep, line_pp, 2);
1460
lv_line_set_style(line_sep, th->line.decor);
1461
lv_obj_align(line_sep, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
1462
1463
// Create Backup eMMC button.
1464
lv_obj_t *btn = lv_btn_create(h1, NULL);
1465
if (hekate_bg)
1466
{
1467
lv_btn_set_style(btn, LV_BTN_STYLE_REL, &btn_transp_rel);
1468
lv_btn_set_style(btn, LV_BTN_STYLE_PR, &btn_transp_pr);
1469
}
1470
lv_obj_t *label_btn = lv_label_create(btn, NULL);
1471
lv_btn_set_fit(btn, true, true);
1472
lv_label_set_static_text(label_btn, SYMBOL_UPLOAD" Backup eMMC");
1473
lv_obj_align(btn, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1474
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, create_window_backup_restore_tool);
1475
1476
lv_obj_t *label_txt2 = lv_label_create(h1, NULL);
1477
lv_label_set_recolor(label_txt2, true);
1478
lv_label_set_static_text(label_txt2,
1479
"Allows you to backup the eMMC partitions individually or as\n"
1480
"a whole raw image to the SD card.\n"
1481
"#C7EA46 Supports SD cards from# #FF8000 4GB# #C7EA46 and up. #"
1482
"#FF8000 FAT32# #C7EA46 and ##FF8000 exFAT##C7EA46 .#");
1483
lv_obj_set_style(label_txt2, &hint_small_style);
1484
lv_obj_align(label_txt2, btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
1485
1486
// Create Restore eMMC button.
1487
lv_obj_t *btn2 = lv_btn_create(h1, btn);
1488
label_btn = lv_label_create(btn2, NULL);
1489
lv_label_set_static_text(label_btn, SYMBOL_DOWNLOAD" Restore eMMC");
1490
lv_obj_align(btn2, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
1491
lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, create_window_backup_restore_tool);
1492
1493
label_txt2 = lv_label_create(h1, NULL);
1494
lv_label_set_recolor(label_txt2, true);
1495
lv_label_set_static_text(label_txt2,
1496
"Allows you to restore the eMMC/emuMMC partitions individually\n"
1497
"or as a whole raw image from the SD card.\n"
1498
"#C7EA46 Supports SD cards from# #FF8000 4GB# #C7EA46 and up. #"
1499
"#FF8000 FAT32# #C7EA46 and ##FF8000 exFAT##C7EA46 .#");
1500
lv_obj_set_style(label_txt2, &hint_small_style);
1501
lv_obj_align(label_txt2, btn2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
1502
1503
// Create Misc container.
1504
lv_obj_t *h2 = _create_container(parent);
1505
lv_obj_align(h2, h1, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
1506
1507
label_sep = lv_label_create(h2, NULL);
1508
lv_label_set_static_text(label_sep, "");
1509
1510
lv_obj_t *label_txt3 = lv_label_create(h2, NULL);
1511
lv_label_set_static_text(label_txt3, "SD Partitions & USB");
1512
lv_obj_set_style(label_txt3, th->label.prim);
1513
lv_obj_align(label_txt3, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI * 3 / 10);
1514
1515
line_sep = lv_line_create(h2, line_sep);
1516
lv_obj_align(line_sep, label_txt3, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
1517
1518
// Create Partition SD Card button.
1519
lv_obj_t *btn3 = lv_btn_create(h2, NULL);
1520
if (hekate_bg)
1521
{
1522
lv_btn_set_style(btn3, LV_BTN_STYLE_REL, &btn_transp_rel);
1523
lv_btn_set_style(btn3, LV_BTN_STYLE_PR, &btn_transp_pr);
1524
}
1525
label_btn = lv_label_create(btn3, NULL);
1526
lv_btn_set_fit(btn3, true, true);
1527
lv_label_set_static_text(label_btn, SYMBOL_SD" Partition SD Card");
1528
lv_obj_align(btn3, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1529
lv_btn_set_action(btn3, LV_BTN_ACTION_CLICK, create_window_partition_manager);
1530
1531
lv_obj_t *label_txt4 = lv_label_create(h2, NULL);
1532
lv_label_set_recolor(label_txt4, true);
1533
lv_label_set_static_text(label_txt4,
1534
"Allows you to partition the SD Card for using it with #C7EA46 emuMMC#,\n"
1535
"#C7EA46 Android# and #C7EA46 Linux#. You can also flash Linux and Android.\n");
1536
lv_obj_set_style(label_txt4, &hint_small_style);
1537
lv_obj_align(label_txt4, btn3, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
1538
1539
label_sep = lv_label_create(h2, NULL);
1540
lv_label_set_static_text(label_sep, "");
1541
lv_obj_align(label_sep, label_txt4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI * 11 / 7);
1542
1543
// Create USB Tools button.
1544
lv_obj_t *btn4 = lv_btn_create(h2, btn3);
1545
label_btn = lv_label_create(btn4, NULL);
1546
lv_label_set_static_text(label_btn, SYMBOL_USB" USB Tools");
1547
lv_obj_align(btn4, label_txt4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
1548
lv_btn_set_action(btn4, LV_BTN_ACTION_CLICK, _create_window_usb_tools);
1549
1550
label_txt4 = lv_label_create(h2, NULL);
1551
lv_label_set_recolor(label_txt4, true);
1552
lv_label_set_static_text(label_txt4,
1553
"#C7EA46 USB mass storage#, #C7EA46 gamepad# and other USB tools.\n"
1554
"Mass storage can mount SD, eMMC and emuMMC. The\n"
1555
"gamepad transforms the Switch into an input device.#");
1556
lv_obj_set_style(label_txt4, &hint_small_style);
1557
lv_obj_align(label_txt4, btn4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
1558
}
1559
1560
static void _create_tab_tools_arc_autorcm(lv_theme_t *th, lv_obj_t *parent)
1561
{
1562
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
1563
1564
// Create Misc container.
1565
lv_obj_t *h1 = _create_container(parent);
1566
1567
lv_obj_t *label_sep = lv_label_create(h1, NULL);
1568
lv_label_set_static_text(label_sep, "");
1569
1570
lv_obj_t *label_txt = lv_label_create(h1, NULL);
1571
lv_label_set_static_text(label_txt, "Misc");
1572
lv_obj_set_style(label_txt, th->label.prim);
1573
lv_obj_align(label_txt, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI * 3 / 10);
1574
1575
lv_obj_t *line_sep = lv_line_create(h1, NULL);
1576
static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 4)) * 2, 0} };
1577
lv_line_set_points(line_sep, line_pp, 2);
1578
lv_line_set_style(line_sep, th->line.decor);
1579
lv_obj_align(line_sep, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
1580
1581
// Create fix archive bit button.
1582
lv_obj_t *btn = lv_btn_create(h1, NULL);
1583
if (hekate_bg)
1584
{
1585
lv_btn_set_style(btn, LV_BTN_STYLE_REL, &btn_transp_rel);
1586
lv_btn_set_style(btn, LV_BTN_STYLE_PR, &btn_transp_pr);
1587
}
1588
lv_obj_t *label_btn = lv_label_create(btn, NULL);
1589
lv_btn_set_fit(btn, true, true);
1590
lv_label_set_static_text(label_btn, SYMBOL_DIRECTORY" Fix Archive Bit");
1591
lv_obj_align(btn, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1592
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _create_window_unset_abit_tool);
1593
1594
lv_obj_t *label_txt2 = lv_label_create(h1, NULL);
1595
lv_label_set_recolor(label_txt2, true);
1596
lv_label_set_static_text(label_txt2,
1597
"Allows you to fix the archive bit for all folders including\n"
1598
"the root and emuMMC \'Nintendo\' folders.\n"
1599
"#C7EA46 It sets the archive bit to folders named with ##FF8000 .[ext]#\n"
1600
"#FF8000 Use that option when you have corruption messages.#");
1601
lv_obj_set_style(label_txt2, &hint_small_style);
1602
lv_obj_align(label_txt2, btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
1603
1604
// Create Fix touch calibration button.
1605
lv_obj_t *btn2 = lv_btn_create(h1, btn);
1606
label_btn = lv_label_create(btn2, NULL);
1607
lv_label_set_static_text(label_btn, SYMBOL_KEYBOARD" Calibrate Touchscreen");
1608
lv_obj_align(btn2, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
1609
lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, _create_mbox_fix_touchscreen);
1610
1611
label_txt2 = lv_label_create(h1, NULL);
1612
lv_label_set_recolor(label_txt2, true);
1613
lv_label_set_static_text(label_txt2,
1614
"Allows you to calibrate the touchscreen module.\n"
1615
"#FF8000 This fixes any issues with touchscreen in Nyx and HOS.#");
1616
lv_obj_set_style(label_txt2, &hint_small_style);
1617
lv_obj_align(label_txt2, btn2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
1618
1619
// Create Others container.
1620
lv_obj_t *h2 = _create_container(parent);
1621
lv_obj_align(h2, h1, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
1622
1623
label_sep = lv_label_create(h2, NULL);
1624
lv_label_set_static_text(label_sep, "");
1625
1626
lv_obj_t *label_txt3 = lv_label_create(h2, NULL);
1627
lv_label_set_static_text(label_txt3, "Others");
1628
lv_obj_set_style(label_txt3, th->label.prim);
1629
lv_obj_align(label_txt3, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI * 3 / 10);
1630
1631
line_sep = lv_line_create(h2, line_sep);
1632
lv_obj_align(line_sep, label_txt3, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
1633
1634
// Create AutoRCM On/Off button.
1635
lv_obj_t *btn3 = lv_btn_create(h2, NULL);
1636
if (hekate_bg)
1637
{
1638
lv_btn_set_style(btn3, LV_BTN_STYLE_REL, &btn_transp_rel);
1639
lv_btn_set_style(btn3, LV_BTN_STYLE_PR, &btn_transp_pr);
1640
lv_btn_set_style(btn3, LV_BTN_STYLE_TGL_REL, &btn_transp_tgl_rel);
1641
lv_btn_set_style(btn3, LV_BTN_STYLE_TGL_PR, &btn_transp_tgl_pr);
1642
}
1643
label_btn = lv_label_create(btn3, NULL);
1644
lv_btn_set_fit(btn3, true, true);
1645
lv_label_set_recolor(label_btn, true);
1646
lv_label_set_text(label_btn, SYMBOL_REFRESH" AutoRCM #00FFC9 ON #");
1647
lv_obj_align(btn3, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1648
lv_btn_set_action(btn3, LV_BTN_ACTION_CLICK, _create_mbox_autorcm_status);
1649
1650
// Set default state for AutoRCM and lock it out if patched unit.
1651
if (get_set_autorcm_status(false))
1652
lv_btn_set_state(btn3, LV_BTN_STATE_TGL_REL);
1653
else
1654
lv_btn_set_state(btn3, LV_BTN_STATE_REL);
1655
nyx_generic_onoff_toggle(btn3);
1656
1657
if (h_cfg.rcm_patched)
1658
{
1659
lv_obj_set_click(btn3, false);
1660
lv_btn_set_state(btn3, LV_BTN_STATE_INA);
1661
}
1662
autorcm_btn = btn3;
1663
1664
char *txt_buf = (char *)malloc(SZ_4K);
1665
1666
s_printf(txt_buf,
1667
"Allows you to enter RCM without using #C7EA46 VOL+# & #C7EA46 HOME# (jig).\n"
1668
"#FF8000 It can restore all versions of AutoRCM whenever requested.#\n"
1669
"#FF3C28 This corrupts the BCT and you can't boot without a custom#\n"
1670
"#FF3C28 bootloader.#");
1671
1672
if (h_cfg.rcm_patched)
1673
strcat(txt_buf, " #FF8000 This is disabled because this unit is patched!#");
1674
1675
lv_obj_t *label_txt4 = lv_label_create(h2, NULL);
1676
lv_label_set_recolor(label_txt4, true);
1677
lv_label_set_text(label_txt4, txt_buf);
1678
free(txt_buf);
1679
1680
lv_obj_set_style(label_txt4, &hint_small_style);
1681
lv_obj_align(label_txt4, btn3, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
1682
1683
label_sep = lv_label_create(h2, NULL);
1684
lv_label_set_static_text(label_sep, "");
1685
lv_obj_align(label_sep, label_txt4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI * 11 / 7);
1686
1687
// Create Dump Package1/2 button.
1688
lv_obj_t *btn4 = lv_btn_create(h2, btn);
1689
label_btn = lv_label_create(btn4, NULL);
1690
lv_label_set_static_text(label_btn, SYMBOL_MODULES" Dump Package1/2");
1691
lv_obj_align(btn4, label_txt4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2);
1692
lv_btn_set_action(btn4, LV_BTN_ACTION_CLICK, _create_window_dump_pk12_tool);
1693
1694
label_txt2 = lv_label_create(h2, NULL);
1695
lv_label_set_recolor(label_txt2, true);
1696
lv_label_set_static_text(label_txt2,
1697
"Allows you to dump and decrypt pkg1 and pkg2 and further\n"
1698
"split it up into their individual parts. It also dumps the kip1.");
1699
lv_obj_set_style(label_txt2, &hint_small_style);
1700
lv_obj_align(label_txt2, btn4, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3);
1701
}
1702
1703
void create_tab_tools(lv_theme_t *th, lv_obj_t *parent)
1704
{
1705
lv_obj_t *tv = lv_tabview_create(parent, NULL);
1706
1707
lv_obj_set_size(tv, LV_HOR_RES, 572);
1708
1709
static lv_style_t tabview_style;
1710
lv_style_copy(&tabview_style, th->tabview.btn.rel);
1711
tabview_style.body.padding.ver = LV_DPI / 8;
1712
1713
lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_REL, &tabview_style);
1714
if (hekate_bg)
1715
{
1716
lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_PR, &tabview_btn_pr);
1717
lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_TGL_PR, &tabview_btn_tgl_pr);
1718
}
1719
1720
lv_tabview_set_sliding(tv, false);
1721
lv_tabview_set_btns_pos(tv, LV_TABVIEW_BTNS_POS_BOTTOM);
1722
1723
lv_obj_t *tab1= lv_tabview_add_tab(tv, "eMMC "SYMBOL_DOT" SD Partitions "SYMBOL_DOT" USB");
1724
lv_obj_t *tab2 = lv_tabview_add_tab(tv, "Arch bit "SYMBOL_DOT" RCM "SYMBOL_DOT" Touch "SYMBOL_DOT" Pkg1/2");
1725
1726
lv_obj_t *line_sep = lv_line_create(tv, NULL);
1727
static const lv_point_t line_pp[] = { {0, 0}, { 0, LV_DPI / 4} };
1728
lv_line_set_points(line_sep, line_pp, 2);
1729
lv_line_set_style(line_sep, lv_theme_get_current()->line.decor);
1730
lv_obj_align(line_sep, tv, LV_ALIGN_IN_BOTTOM_MID, -1, -LV_DPI * 2 / 12);
1731
1732
_create_tab_tools_emmc_pkg12(th, tab1);
1733
_create_tab_tools_arc_autorcm(th, tab2);
1734
1735
lv_tabview_set_tab_act(tv, 0, false);
1736
}
1737
1738