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