1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include <grub/types.h>
21 #include <grub/misc.h>
25 #include <grub/disk.h>
26 #include <grub/device.h>
27 #include <grub/term.h>
28 #include <grub/partition.h>
29 #include <grub/file.h>
30 #include <grub/normal.h>
31 #include <grub/extcmd.h>
32 #include <grub/datetime.h>
33 #include <grub/i18n.h>
35 #include <grub/crypto.h>
36 #include <grub/time.h>
37 #include <grub/font.h>
38 #include <grub/ventoy.h>
39 #include "ventoy_def.h"
41 GRUB_MOD_LICENSE ("GPLv3+");
43 char g_arch_mode_suffix
[64];
44 static char g_iso_disk_name
[128];
45 static vtoy_password g_boot_pwd
;
46 static vtoy_password g_file_type_pwd
[img_type_max
];
47 static install_template
*g_install_template_head
= NULL
;
48 static dud
*g_dud_head
= NULL
;
49 static menu_password
*g_pwd_head
= NULL
;
50 static persistence_config
*g_persistence_head
= NULL
;
51 static menu_tip
*g_menu_tip_head
= NULL
;
52 static menu_alias
*g_menu_alias_head
= NULL
;
53 static menu_class
*g_menu_class_head
= NULL
;
54 static custom_boot
*g_custom_boot_head
= NULL
;
55 static injection_config
*g_injection_head
= NULL
;
56 static auto_memdisk
*g_auto_memdisk_head
= NULL
;
57 static image_list
*g_image_list_head
= NULL
;
58 static conf_replace
*g_conf_replace_head
= NULL
;
59 static VTOY_JSON
*g_menu_lang_json
= NULL
;
61 static int g_theme_id
= 0;
62 static int g_theme_num
= 0;
63 static theme_list
*g_theme_head
= NULL
;
64 static int g_theme_random
= vtoy_theme_random_boot_second
;
65 static char g_theme_single_file
[256];
66 static char g_cur_menu_language
[32] = {0};
68 static int ventoy_plugin_is_parent(const char *pat
, int patlen
, const char *isopath
)
72 if (isopath
[patlen
] == '/' && ventoy_strncmp(pat
, isopath
, patlen
) == 0 &&
73 grub_strchr(isopath
+ patlen
+ 1, '/') == NULL
)
80 if (pat
[0] == '/' && grub_strchr(isopath
+ 1, '/') == NULL
)
89 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
92 VTOY_JSON
*pNode
= NULL
;
93 VTOY_JSON
*pChild
= NULL
;
97 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
99 grub_printf("Not array type %d\n", json
->enDataType
);
103 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
105 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
107 pChild
= pNode
->pstChild
;
108 if (pChild
->enDataType
== JSON_TYPE_STRING
)
110 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
112 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
113 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
117 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
122 grub_printf("%s is NOT string type\n", pChild
->pcName
);
128 grub_printf("%s is not an object\n", pNode
->pcName
);
136 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
138 VTOY_JSON
*pNode
= NULL
;
139 VTOY_JSON
*pChild
= NULL
;
143 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
145 debug("Not array %d\n", json
->enDataType
);
149 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
151 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
153 pChild
= pNode
->pstChild
;
154 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
156 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
164 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
170 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
173 grub_printf("file: %s\n", value
);
176 exist
= ventoy_check_file_exist("%s%s", isodisk
, value
);
180 exist
= ventoy_check_file_exist("%s/ventoy/%s", isodisk
, value
);
185 grub_printf("Theme file %s does NOT exist\n", value
);
191 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
194 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
196 value
= node
->unData
.pcStrVal
;
197 grub_printf("file: %s\n", value
);
200 exist
= ventoy_check_file_exist("%s%s", isodisk
, value
);
204 exist
= ventoy_check_file_exist("%s/ventoy/%s", isodisk
, value
);
209 grub_printf("Theme file %s does NOT exist\n", value
);
214 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
217 grub_printf("random: %s\n", value
);
222 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
225 grub_printf("gfxmode: %s\n", value
);
228 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
231 grub_printf("display_mode: %s\n", value
);
234 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
237 grub_printf("serial_param %s\n", value
);
240 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
243 grub_printf("ventoy_left: %s\n", value
);
246 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
249 grub_printf("ventoy_top: %s\n", value
);
252 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
255 grub_printf("ventoy_color: %s\n", value
);
258 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
261 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
263 if (node
->enDataType
== JSON_TYPE_STRING
)
265 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
267 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
271 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
278 grub_printf("fonts NOT found\n");
284 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
289 VTOY_JSON
*node
= NULL
;
290 theme_list
*tail
= NULL
;
291 theme_list
*themenode
= NULL
;
293 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
298 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
302 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
305 if (ventoy_check_file_exist(filepath
) == 0)
307 debug("Theme file %s does not exist\n", filepath
);
311 debug("vtoy_theme %s\n", filepath
);
312 ventoy_env_export("vtoy_theme", filepath
);
313 grub_snprintf(g_theme_single_file
, sizeof(g_theme_single_file
), "%s", filepath
);
317 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
320 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
322 value
= node
->unData
.pcStrVal
;
325 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
329 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
332 if (ventoy_check_file_exist(filepath
) == 0)
337 themenode
= grub_zalloc(sizeof(theme_list
));
340 grub_snprintf(themenode
->theme
.path
, sizeof(themenode
->theme
.path
), "%s", filepath
);
343 tail
->next
= themenode
;
347 g_theme_head
= themenode
;
354 ventoy_env_export("vtoy_theme", "random");
355 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
358 if (grub_strcmp(value
, "boot_second") == 0)
360 g_theme_random
= vtoy_theme_random_boot_second
;
362 else if (grub_strcmp(value
, "boot_day") == 0)
364 g_theme_random
= vtoy_theme_random_boot_day
;
366 else if (grub_strcmp(value
, "boot_month") == 0)
368 g_theme_random
= vtoy_theme_random_boot_month
;
374 grub_snprintf(val
, sizeof(val
), "%d", g_theme_num
);
375 grub_env_set("VTOY_THEME_COUNT", val
);
376 grub_env_export("VTOY_THEME_COUNT");
379 vtoy_json_get_int(json
->pstChild
, "default_file", &g_theme_id
);
380 if (g_theme_id
> g_theme_num
|| g_theme_id
< 0)
386 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
389 debug("vtoy_gfxmode %s\n", value
);
390 ventoy_env_export("vtoy_gfxmode", value
);
393 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
396 debug("display_mode %s\n", value
);
397 ventoy_env_export("vtoy_display_mode", value
);
400 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
403 debug("serial_param %s\n", value
);
404 ventoy_env_export("vtoy_serial_param", value
);
407 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
410 ventoy_env_export("VTLE_LFT", value
);
413 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
416 ventoy_env_export("VTLE_TOP", value
);
419 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
422 ventoy_env_export("VTLE_CLR", value
);
425 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
428 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
430 if (node
->enDataType
== JSON_TYPE_STRING
&&
431 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
433 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
434 grub_font_load(filepath
);
442 static int ventoy_plugin_check_path(const char *path
, const char *file
)
446 grub_printf("%s is NOT begin with '/' \n", file
);
450 if (grub_strchr(file
, '\\'))
452 grub_printf("%s contains invalid '\\' \n", file
);
456 if (grub_strstr(file
, "//"))
458 grub_printf("%s contains invalid double slash\n", file
);
462 if (grub_strstr(file
, "../"))
464 grub_printf("%s contains invalid '../' \n", file
);
468 if (!ventoy_check_file_exist("%s%s", path
, file
))
470 grub_printf("%s%s does NOT exist\n", path
, file
);
477 static int ventoy_plugin_check_fullpath
488 VTOY_JSON
*node
= json
;
489 VTOY_JSON
*child
= NULL
;
493 if (0 == grub_strcmp(key
, node
->pcName
))
497 node
= node
->pstNext
;
505 if (JSON_TYPE_STRING
== node
->enDataType
)
508 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
509 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
511 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
513 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
515 if (JSON_TYPE_STRING
!= child
->enDataType
)
517 grub_printf("Non string json type\n");
521 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
522 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
533 static int ventoy_plugin_parse_fullpath
538 file_fullpath
**fullpath
,
544 VTOY_JSON
*node
= json
;
545 VTOY_JSON
*child
= NULL
;
546 file_fullpath
*path
= NULL
;
550 if (0 == grub_strcmp(key
, node
->pcName
))
554 node
= node
->pstNext
;
562 if (JSON_TYPE_STRING
== node
->enDataType
)
564 debug("%s is string type data\n", node
->pcName
);
566 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
568 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
572 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
575 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
581 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
583 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
585 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
587 debug("Invalid data type:%d\n", child
->enDataType
);
592 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
594 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
599 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
601 if (ventoy_check_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
603 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
617 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
623 const char *iso
= NULL
;
624 VTOY_JSON
*pNode
= NULL
;
626 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
628 grub_printf("Not array type %d\n", json
->enDataType
);
632 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
634 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
636 grub_printf("NOT object type\n");
639 if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image")) != NULL
)
641 pos
= grub_strchr(iso
, '*');
642 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
644 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
645 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
647 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
649 if (autosel
>= 0 && autosel
<= pathnum
)
651 grub_printf("autosel: %d [OK]\n", autosel
);
655 grub_printf("autosel: %d [FAIL]\n", autosel
);
659 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
663 grub_printf("timeout: %d [OK]\n", timeout
);
667 grub_printf("timeout: %d [FAIL]\n", timeout
);
673 grub_printf("image: %s [FAIL]\n", iso
);
676 else if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent")) != NULL
)
678 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
680 grub_printf("parent: %s [OK]\n", iso
);
681 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
683 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
685 if (autosel
>= 0 && autosel
<= pathnum
)
687 grub_printf("autosel: %d [OK]\n", autosel
);
691 grub_printf("autosel: %d [FAIL]\n", autosel
);
695 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
699 grub_printf("timeout: %d [OK]\n", timeout
);
703 grub_printf("timeout: %d [FAIL]\n", timeout
);
709 grub_printf("parent: %s [FAIL]\n", iso
);
714 grub_printf("image not found\n");
721 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
727 const char *iso
= NULL
;
728 VTOY_JSON
*pNode
= NULL
;
729 install_template
*node
= NULL
;
730 install_template
*next
= NULL
;
731 file_fullpath
*templatepath
= NULL
;
733 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
735 debug("Not array %d\n", json
->enDataType
);
739 if (g_install_template_head
)
741 for (node
= g_install_template_head
; node
; node
= next
)
744 grub_check_free(node
->templatepath
);
748 g_install_template_head
= NULL
;
751 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
753 type
= auto_install_type_file
;
754 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
757 type
= auto_install_type_parent
;
758 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
761 if (iso
&& iso
[0] == '/')
763 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
765 node
= grub_zalloc(sizeof(install_template
));
769 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
770 node
->templatepath
= templatepath
;
771 node
->templatenum
= pathnum
;
775 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
777 if (autosel
>= 0 && autosel
<= pathnum
)
779 node
->autosel
= autosel
;
783 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
787 node
->timeout
= timeout
;
791 if (g_install_template_head
)
793 node
->next
= g_install_template_head
;
796 g_install_template_head
= node
;
805 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
809 const char *iso
= NULL
;
810 VTOY_JSON
*pNode
= NULL
;
812 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
814 grub_printf("Not array type %d\n", json
->enDataType
);
818 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
820 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
822 grub_printf("NOT object type\n");
825 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
828 pos
= grub_strchr(iso
, '*');
829 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
831 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
832 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
836 grub_printf("image: %s [FAIL]\n", iso
);
841 grub_printf("image not found\n");
848 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
851 const char *iso
= NULL
;
852 VTOY_JSON
*pNode
= NULL
;
855 file_fullpath
*dudpath
= NULL
;
857 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
859 debug("Not array %d\n", json
->enDataType
);
865 for (node
= g_dud_head
; node
; node
= next
)
868 grub_check_free(node
->dudpath
);
875 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
877 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
878 if (iso
&& iso
[0] == '/')
880 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "dud", &dudpath
, &pathnum
))
882 node
= grub_zalloc(sizeof(dud
));
885 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
886 node
->dudpath
= dudpath
;
887 node
->dudnum
= pathnum
;
888 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
894 node
->next
= g_dud_head
;
911 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
918 vtoy_password tmpPwd
;
920 len
= (int)grub_strlen(pwdstr
);
923 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
927 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
929 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
931 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
932 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
934 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
938 for (i
= 0; i
< 16; i
++)
940 bytes
[0] = pwdstr
[4 + i
* 2];
941 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
944 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
946 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
950 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
954 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
956 else if ((len
- 4) > 32)
958 pos
= grub_strchr(pwdstr
+ 4, '#');
961 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
965 if (len
- 1 - ((long)pos
- (long)pwdstr
) != 32)
967 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
973 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
977 for (i
= 0; i
< 16; i
++)
979 bytes
[0] = pos
[i
* 2];
980 bytes
[1] = pos
[i
* 2 + 1];
983 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
985 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
989 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
994 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
998 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
1004 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
1010 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
1016 static int ventoy_plugin_get_pwd_type(const char *pwd
)
1021 for (i
= 0; pwd
&& i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
1023 grub_snprintf(pwdtype
, sizeof(pwdtype
), "%spwd", g_menu_prefix
[i
]);
1024 if (grub_strcmp(pwdtype
, pwd
) == 0)
1026 return img_type_start
+ i
;
1033 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
1036 const char *iso
= NULL
;
1037 const char *pwd
= NULL
;
1038 VTOY_JSON
*pNode
= NULL
;
1039 VTOY_JSON
*pCNode
= NULL
;
1040 menu_password
*node
= NULL
;
1041 menu_password
*tail
= NULL
;
1042 menu_password
*next
= NULL
;
1046 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1048 debug("Not object %d\n", json
->enDataType
);
1054 for (node
= g_pwd_head
; node
; node
= next
)
1063 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1065 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1067 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
1069 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1071 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, g_file_type_pwd
+ type
);
1073 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1075 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1077 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1082 type
= vtoy_menu_pwd_file
;
1083 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
1086 type
= vtoy_menu_pwd_parent
;
1087 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent");
1090 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1091 if (iso
&& pwd
&& iso
[0] == '/')
1093 node
= grub_zalloc(sizeof(menu_password
));
1097 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1099 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
1123 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
1127 const char *iso
= NULL
;
1128 const char *pwd
= NULL
;
1129 VTOY_JSON
*pNode
= NULL
;
1130 VTOY_JSON
*pCNode
= NULL
;
1132 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1134 grub_printf("Not object %d\n", json
->enDataType
);
1138 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1140 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1142 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1144 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
1148 grub_printf("Invalid bootpwd.\n");
1151 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1153 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1155 grub_printf("%s:<%s>\n", pNode
->pcName
, pNode
->unData
.pcStrVal
);
1159 grub_printf("Invalid pwd <%s>\n", pNode
->unData
.pcStrVal
);
1162 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1165 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1167 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1169 grub_printf("Not object %d\n", pCNode
->enDataType
);
1173 if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file")) != NULL
)
1175 pos
= grub_strchr(iso
, '*');
1176 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1178 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1180 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1182 grub_printf("file:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1183 grub_printf("pwd:<%s>\n\n", pwd
);
1187 grub_printf("Invalid password for <%s>\n", iso
);
1192 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1195 else if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent")) != NULL
)
1197 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
1199 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1200 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1202 grub_printf("dir:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1203 grub_printf("pwd:<%s>\n\n", pwd
);
1207 grub_printf("Invalid password for <%s>\n", iso
);
1212 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1217 grub_printf("No file item found in json.\n");
1226 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
1232 const char *iso
= NULL
;
1233 VTOY_JSON
*pNode
= NULL
;
1235 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1237 grub_printf("Not array type %d\n", json
->enDataType
);
1241 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1243 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
1245 grub_printf("NOT object type\n");
1248 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1251 pos
= grub_strchr(iso
, '*');
1252 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1254 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
1255 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
1257 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1259 if (autosel
>= 0 && autosel
<= pathnum
)
1261 grub_printf("autosel: %d [OK]\n", autosel
);
1265 grub_printf("autosel: %d [FAIL]\n", autosel
);
1269 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
1273 grub_printf("timeout: %d [OK]\n", timeout
);
1277 grub_printf("timeout: %d [FAIL]\n", timeout
);
1283 grub_printf("image: %s [FAIL]\n", iso
);
1288 grub_printf("image not found\n");
1295 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1300 const char *iso
= NULL
;
1301 VTOY_JSON
*pNode
= NULL
;
1302 persistence_config
*node
= NULL
;
1303 persistence_config
*next
= NULL
;
1304 file_fullpath
*backendpath
= NULL
;
1308 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1310 debug("Not array %d\n", json
->enDataType
);
1314 if (g_persistence_head
)
1316 for (node
= g_persistence_head
; node
; node
= next
)
1319 grub_check_free(node
->backendpath
);
1323 g_persistence_head
= NULL
;
1326 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1328 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1329 if (iso
&& iso
[0] == '/')
1331 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1333 node
= grub_zalloc(sizeof(persistence_config
));
1336 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1337 node
->backendpath
= backendpath
;
1338 node
->backendnum
= pathnum
;
1342 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1344 if (autosel
>= 0 && autosel
<= pathnum
)
1346 node
->autosel
= autosel
;
1350 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
1354 node
->timeout
= timeout
;
1358 if (g_persistence_head
)
1360 node
->next
= g_persistence_head
;
1363 g_persistence_head
= node
;
1372 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1375 const char *path
= NULL
;
1376 const char *alias
= NULL
;
1377 VTOY_JSON
*pNode
= NULL
;
1381 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1383 grub_printf("Not array %d\n", json
->enDataType
);
1387 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1389 type
= vtoy_alias_image_file
;
1390 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1393 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1394 type
= vtoy_alias_directory
;
1397 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1398 if (path
&& path
[0] == '/' && alias
)
1400 if (vtoy_alias_image_file
== type
)
1402 if (grub_strchr(path
, '*'))
1404 grub_printf("image: <%s> [ * ]\n", path
);
1406 else if (ventoy_check_file_exist("%s%s", isodisk
, path
))
1408 grub_printf("image: <%s> [ OK ]\n", path
);
1412 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1417 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1419 grub_printf("dir: <%s> [ OK ]\n", path
);
1423 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1427 grub_printf("alias: <%s>\n\n", alias
);
1434 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1437 const char *path
= NULL
;
1438 const char *alias
= NULL
;
1439 VTOY_JSON
*pNode
= NULL
;
1440 menu_alias
*node
= NULL
;
1441 menu_alias
*next
= NULL
;
1445 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1447 debug("Not array %d\n", json
->enDataType
);
1451 if (g_menu_alias_head
)
1453 for (node
= g_menu_alias_head
; node
; node
= next
)
1459 g_menu_alias_head
= NULL
;
1462 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1464 type
= vtoy_alias_image_file
;
1465 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1468 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1469 type
= vtoy_alias_directory
;
1472 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1473 if (path
&& path
[0] == '/' && alias
)
1475 node
= grub_zalloc(sizeof(menu_alias
));
1479 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1480 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1482 if (g_menu_alias_head
)
1484 node
->next
= g_menu_alias_head
;
1487 g_menu_alias_head
= node
;
1495 static int ventoy_plugin_menutip_check(VTOY_JSON
*json
, const char *isodisk
)
1498 const char *path
= NULL
;
1499 const char *tip
= NULL
;
1500 VTOY_JSON
*pNode
= NULL
;
1504 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1506 grub_printf("Not object %d\n", json
->enDataType
);
1510 tip
= vtoy_json_get_string_ex(json
->pstChild
, "left");
1513 grub_printf("left: <%s>\n", tip
);
1516 tip
= vtoy_json_get_string_ex(json
->pstChild
, "top");
1519 grub_printf("top: <%s>\n", tip
);
1522 tip
= vtoy_json_get_string_ex(json
->pstChild
, "color");
1525 grub_printf("color: <%s>\n", tip
);
1528 pNode
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "tips");
1529 for (pNode
= pNode
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1531 type
= vtoy_tip_image_file
;
1532 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1535 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1536 type
= vtoy_tip_directory
;
1539 if (path
&& path
[0] == '/')
1541 if (vtoy_tip_image_file
== type
)
1543 if (grub_strchr(path
, '*'))
1545 grub_printf("image: <%s> [ * ]\n", path
);
1547 else if (ventoy_check_file_exist("%s%s", isodisk
, path
))
1549 grub_printf("image: <%s> [ OK ]\n", path
);
1553 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1558 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1560 grub_printf("dir: <%s> [ OK ]\n", path
);
1564 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1568 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip");
1571 grub_printf("tip: <%s>\n", tip
);
1575 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip1");
1577 grub_printf("tip1: <%s>\n", tip
);
1579 grub_printf("tip1: <NULL>\n");
1581 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip2");
1583 grub_printf("tip2: <%s>\n", tip
);
1585 grub_printf("tip2: <NULL>\n");
1590 grub_printf("image: <%s> [ INVALID ]\n", path
);
1597 static int ventoy_plugin_menutip_entry(VTOY_JSON
*json
, const char *isodisk
)
1600 const char *path
= NULL
;
1601 const char *tip
= NULL
;
1602 VTOY_JSON
*pNode
= NULL
;
1603 menu_tip
*node
= NULL
;
1604 menu_tip
*next
= NULL
;
1608 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1610 debug("Not object %d\n", json
->enDataType
);
1614 pNode
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "tips");
1617 debug("Not tips found\n");
1621 if (g_menu_tip_head
)
1623 for (node
= g_menu_tip_head
; node
; node
= next
)
1629 g_menu_tip_head
= NULL
;
1632 tip
= vtoy_json_get_string_ex(json
->pstChild
, "left");
1635 grub_env_set("VTOY_TIP_LEFT", tip
);
1638 tip
= vtoy_json_get_string_ex(json
->pstChild
, "top");
1641 grub_env_set("VTOY_TIP_TOP", tip
);
1644 tip
= vtoy_json_get_string_ex(json
->pstChild
, "color");
1647 grub_env_set("VTOY_TIP_COLOR", tip
);
1650 for (pNode
= pNode
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1652 type
= vtoy_tip_image_file
;
1653 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1656 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1657 type
= vtoy_tip_directory
;
1660 if (path
&& path
[0] == '/')
1662 node
= grub_zalloc(sizeof(menu_tip
));
1666 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1668 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip");
1671 grub_snprintf(node
->tip1
, 1000, "%s", tip
);
1675 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip1");
1677 grub_snprintf(node
->tip1
, 1000, "%s", tip
);
1679 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip2");
1681 grub_snprintf(node
->tip2
, 1000, "%s", tip
);
1684 if (g_menu_tip_head
)
1686 node
->next
= g_menu_tip_head
;
1689 g_menu_tip_head
= node
;
1697 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1700 const char *path
= NULL
;
1701 const char *archive
= NULL
;
1702 VTOY_JSON
*pNode
= NULL
;
1706 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1708 grub_printf("Not array %d\n", json
->enDataType
);
1712 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1714 type
= injection_type_file
;
1715 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1718 type
= injection_type_parent
;
1719 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1722 grub_printf("image/parent not found\n");
1727 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1730 grub_printf("archive not found\n");
1734 if (type
== injection_type_file
)
1736 if (grub_strchr(path
, '*'))
1738 grub_printf("image: <%s> [*]\n", path
);
1742 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1747 grub_printf("parent: <%s> [%s]\n", path
,
1748 ventoy_is_dir_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1751 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1757 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1760 const char *path
= NULL
;
1761 const char *archive
= NULL
;
1762 VTOY_JSON
*pNode
= NULL
;
1763 injection_config
*node
= NULL
;
1764 injection_config
*next
= NULL
;
1768 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1770 debug("Not array %d\n", json
->enDataType
);
1774 if (g_injection_head
)
1776 for (node
= g_injection_head
; node
; node
= next
)
1782 g_injection_head
= NULL
;
1785 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1787 type
= injection_type_file
;
1788 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1791 type
= injection_type_parent
;
1792 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1795 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1796 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1798 node
= grub_zalloc(sizeof(injection_config
));
1802 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1803 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1805 if (g_injection_head
)
1807 node
->next
= g_injection_head
;
1810 g_injection_head
= node
;
1818 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1822 const char *key
= NULL
;
1823 const char *class = NULL
;
1824 VTOY_JSON
*pNode
= NULL
;
1825 menu_class
*tail
= NULL
;
1826 menu_class
*node
= NULL
;
1827 menu_class
*next
= NULL
;
1831 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1833 debug("Not array %d\n", json
->enDataType
);
1837 if (g_menu_class_head
)
1839 for (node
= g_menu_class_head
; node
; node
= next
)
1845 g_menu_class_head
= NULL
;
1848 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1851 type
= vtoy_class_image_file
;
1852 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1855 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1862 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1863 type
= vtoy_class_directory
;
1867 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1870 node
= grub_zalloc(sizeof(menu_class
));
1874 node
->parent
= parent
;
1875 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1876 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1878 if (g_menu_class_head
)
1884 g_menu_class_head
= node
;
1894 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1896 const char *name
= NULL
;
1897 const char *key
= NULL
;
1898 const char *class = NULL
;
1899 VTOY_JSON
*pNode
= NULL
;
1903 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1905 grub_printf("Not array %d\n", json
->enDataType
);
1909 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1912 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1916 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1920 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1924 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1927 grub_printf("%s: <%s>\n", name
, key
);
1928 grub_printf("class: <%s>\n\n", class);
1935 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1939 const char *key
= NULL
;
1940 const char *cfg
= NULL
;
1941 VTOY_JSON
*pNode
= NULL
;
1942 custom_boot
*tail
= NULL
;
1943 custom_boot
*node
= NULL
;
1944 custom_boot
*next
= NULL
;
1948 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1950 debug("Not array %d\n", json
->enDataType
);
1954 if (g_custom_boot_head
)
1956 for (node
= g_custom_boot_head
; node
; node
= next
)
1962 g_custom_boot_head
= NULL
;
1965 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1967 type
= vtoy_custom_boot_image_file
;
1968 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1971 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1972 type
= vtoy_custom_boot_directory
;
1975 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1978 node
= grub_zalloc(sizeof(custom_boot
));
1982 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1983 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1985 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
1987 if (g_custom_boot_head
)
1993 g_custom_boot_head
= node
;
2008 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
2012 const char *key
= NULL
;
2013 const char *cfg
= NULL
;
2014 VTOY_JSON
*pNode
= NULL
;
2018 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2020 grub_printf("Not array %d\n", json
->enDataType
);
2024 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2026 type
= vtoy_custom_boot_image_file
;
2027 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
2030 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
2031 type
= vtoy_custom_boot_directory
;
2034 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
2035 len
= (int)grub_strlen(cfg
);
2038 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
2040 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
2044 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
2045 grub_printf("vcfg: <%s>\n\n", cfg
);
2053 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
2056 const char *isof
= NULL
;
2057 const char *orgf
= NULL
;
2058 const char *newf
= NULL
;
2059 VTOY_JSON
*pNode
= NULL
;
2060 conf_replace
*tail
= NULL
;
2061 conf_replace
*node
= NULL
;
2062 conf_replace
*next
= NULL
;
2066 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2068 debug("Not array %d\n", json
->enDataType
);
2072 if (g_conf_replace_head
)
2074 for (node
= g_conf_replace_head
; node
; node
= next
)
2080 g_conf_replace_head
= NULL
;
2083 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2085 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
2086 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
2087 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
2088 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
2090 node
= grub_zalloc(sizeof(conf_replace
));
2093 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "img", &img
))
2098 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
2099 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
2100 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
2102 if (g_conf_replace_head
)
2108 g_conf_replace_head
= node
;
2118 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
2121 const char *isof
= NULL
;
2122 const char *orgf
= NULL
;
2123 const char *newf
= NULL
;
2124 VTOY_JSON
*pNode
= NULL
;
2125 grub_file_t file
= NULL
;
2130 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2132 grub_printf("Not array %d\n", json
->enDataType
);
2136 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2138 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
2139 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
2140 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
2141 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
2143 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
2145 grub_printf("iso:<%s> [OK]\n", isof
);
2147 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
2148 grub_script_execute_sourcecode(cmd
);
2150 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
2153 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
2155 grub_printf("org:<%s> [OK]\n", orgf
);
2159 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
2161 grub_file_close(file
);
2165 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
2168 grub_script_execute_sourcecode("loopback -d vtisocheck");
2170 else if (grub_strchr(isof
, '*'))
2172 grub_printf("iso:<%s> [*]\n", isof
);
2173 grub_printf("org:<%s>\n", orgf
);
2177 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
2178 grub_printf("org:<%s>\n", orgf
);
2181 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
2184 if (file
->size
> vtoy_max_replace_file_size
)
2186 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
2190 grub_printf("new1:<%s> [OK]\n", newf
);
2192 grub_file_close(file
);
2196 grub_printf("new:<%s> [NOT Exist]\n", newf
);
2199 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "img", &img
))
2201 grub_printf("img:<%d>\n", img
);
2211 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
2213 VTOY_JSON
*pNode
= NULL
;
2214 auto_memdisk
*node
= NULL
;
2215 auto_memdisk
*next
= NULL
;
2219 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2221 debug("Not array %d\n", json
->enDataType
);
2225 if (g_auto_memdisk_head
)
2227 for (node
= g_auto_memdisk_head
; node
; node
= next
)
2233 g_auto_memdisk_head
= NULL
;
2236 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2238 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2240 node
= grub_zalloc(sizeof(auto_memdisk
));
2243 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2245 if (g_auto_memdisk_head
)
2247 node
->next
= g_auto_memdisk_head
;
2250 g_auto_memdisk_head
= node
;
2258 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
2260 VTOY_JSON
*pNode
= NULL
;
2262 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2264 grub_printf("Not array %d\n", json
->enDataType
);
2268 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2270 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2272 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2274 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2276 grub_printf(" [*]\n");
2278 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2280 grub_printf(" [OK]\n");
2284 grub_printf(" [NOT EXIST]\n");
2292 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
2294 VTOY_JSON
*pNode
= NULL
;
2295 image_list
*node
= NULL
;
2296 image_list
*next
= NULL
;
2297 image_list
*tail
= NULL
;
2301 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2303 debug("Not array %d\n", json
->enDataType
);
2307 if (g_image_list_head
)
2309 for (node
= g_image_list_head
; node
; node
= next
)
2315 g_image_list_head
= NULL
;
2318 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
2320 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
2324 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
2327 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2329 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2331 node
= grub_zalloc(sizeof(image_list
));
2334 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2336 if (g_image_list_head
)
2342 g_image_list_head
= node
;
2352 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
2354 VTOY_JSON
*pNode
= NULL
;
2356 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2358 grub_printf("Not array %d\n", json
->enDataType
);
2362 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2364 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2366 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2368 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2370 grub_printf(" [*]\n");
2372 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2374 grub_printf(" [OK]\n");
2378 grub_printf(" [NOT EXIST]\n");
2386 static plugin_entry g_plugin_entries
[] =
2388 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
, 0 },
2389 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
, 0 },
2390 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
, 0 },
2391 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
, 0 },
2392 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
, 0 },
2393 { "menu_tip", ventoy_plugin_menutip_entry
, ventoy_plugin_menutip_check
, 0 },
2394 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
, 0 },
2395 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
, 0 },
2396 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
, 0 },
2397 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
, 0 },
2398 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
, 0 },
2399 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
, 0 },
2400 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
, 0 },
2401 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
, 0 },
2402 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
, 0 },
2405 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
2409 VTOY_JSON
*cur
= NULL
;
2411 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
2413 for (cur
= json
; cur
; cur
= cur
->pstNext
)
2415 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2417 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
2418 if (g_plugin_entries
[i
].flag
== 0 && grub_strcmp(key
, cur
->pcName
) == 0)
2420 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2421 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2422 g_plugin_entries
[i
].flag
= 1;
2429 for (cur
= json
; cur
; cur
= cur
->pstNext
)
2431 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2433 if (g_plugin_entries
[i
].flag
== 0 && grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0)
2435 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2436 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2437 g_plugin_entries
[i
].flag
= 1;
2446 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2451 grub_uint8_t
*code
= NULL
;
2453 VTOY_JSON
*json
= NULL
;
2458 grub_env_set("VTOY_TIP_LEFT", "10%");
2459 grub_env_set("VTOY_TIP_TOP", "80%+5");
2460 grub_env_set("VTOY_TIP_COLOR", "blue");
2461 grub_env_set("VTOY_TIP_ALIGN", "left");
2463 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2466 return GRUB_ERR_NONE
;
2469 debug("json configuration file size %d\n", (int)file
->size
);
2471 buf
= grub_malloc(file
->size
+ 1);
2474 grub_file_close(file
);
2478 buf
[file
->size
] = 0;
2479 grub_file_read(file
, buf
, file
->size
);
2480 grub_file_close(file
);
2482 json
= vtoy_json_create();
2488 code
= (grub_uint8_t
*)buf
;
2489 if (code
[0] == 0xef && code
[1] == 0xbb && code
[2] == 0xbf)
2491 offset
= 3; /* Skip UTF-8 BOM */
2493 else if ((code
[0] == 0xff && code
[1] == 0xfe) || (code
[0] == 0xfe && code
[1] == 0xff))
2495 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2496 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2498 grub_env_set("VTOY_PLUGIN_ENCODE_ERROR", "1");
2499 grub_env_export("VTOY_PLUGIN_ENCODE_ERROR");
2501 debug("Failed to parse json string %d\n", ret
);
2506 ret
= vtoy_json_parse(json
, buf
+ offset
);
2509 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2510 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2512 debug("Failed to parse json string %d\n", ret
);
2517 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
2519 vtoy_json_destroy(json
);
2523 if (g_boot_pwd
.type
)
2525 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
2526 if (ventoy_check_password(&g_boot_pwd
, 3))
2528 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
2535 if (g_menu_tip_head
)
2537 grub_env_set("VTOY_MENU_TIP_ENABLE", "1");
2541 grub_env_unset("VTOY_MENU_TIP_ENABLE");
2544 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2547 void ventoy_plugin_dump_injection(void)
2549 injection_config
*node
= NULL
;
2551 for (node
= g_injection_head
; node
; node
= node
->next
)
2553 grub_printf("\n%s:<%s>\n", (node
->type
== injection_type_file
) ? "IMAGE" : "PARENT", node
->isopath
);
2554 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
2561 void ventoy_plugin_dump_auto_install(void)
2564 install_template
*node
= NULL
;
2566 for (node
= g_install_template_head
; node
; node
= node
->next
)
2568 grub_printf("\n%s:<%s> <%d>\n",
2569 (node
->type
== auto_install_type_file
) ? "IMAGE" : "PARENT",
2570 node
->isopath
, node
->templatenum
);
2571 for (i
= 0; i
< node
->templatenum
; i
++)
2573 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
2580 void ventoy_plugin_dump_persistence(void)
2584 persistence_config
*node
= NULL
;
2585 ventoy_img_chunk_list chunk_list
;
2587 for (node
= g_persistence_head
; node
; node
= node
->next
)
2589 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
2591 for (i
= 0; i
< node
->backendnum
; i
++)
2593 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
2594 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
2597 grub_printf(" [ SUCCESS ]\n");
2598 grub_free(chunk_list
.chunk
);
2602 grub_printf(" [ FAILED ]\n");
2610 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
2613 install_template
*node
= NULL
;
2615 if (!g_install_template_head
)
2620 len
= (int)grub_strlen(isopath
);
2621 for (node
= g_install_template_head
; node
; node
= node
->next
)
2623 if (node
->type
== auto_install_type_file
)
2625 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2632 for (node
= g_install_template_head
; node
; node
= node
->next
)
2634 if (node
->type
== auto_install_type_parent
)
2636 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2646 char * ventoy_plugin_get_cur_install_template(const char *isopath
, install_template
**cur
)
2648 install_template
*node
= NULL
;
2655 node
= ventoy_plugin_find_install_template(isopath
);
2656 if ((!node
) || (!node
->templatepath
))
2661 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2671 return node
->templatepath
[node
->cursel
].path
;
2674 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2677 persistence_config
*node
= NULL
;
2679 if (!g_persistence_head
)
2684 len
= (int)grub_strlen(isopath
);
2685 for (node
= g_persistence_head
; node
; node
= node
->next
)
2687 if ((len
== node
->pathlen
) && (ventoy_strcmp(node
->isopath
, isopath
) == 0))
2696 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2701 grub_uint64_t start
= 0;
2702 grub_file_t file
= NULL
;
2703 persistence_config
*node
= NULL
;
2705 node
= ventoy_plugin_find_persistent(isopath
);
2706 if ((!node
) || (!node
->backendpath
))
2713 index
= node
->cursel
;
2716 if (index
< 0 || index
>= node
->backendnum
)
2721 path
= node
->backendpath
[index
].path
;
2723 if (node
->backendpath
[index
].vlnk_add
== 0)
2725 len
= grub_strlen(path
);
2726 if (len
> 9 && grub_strncmp(path
+ len
- 9, ".vlnk.dat", 9) == 0)
2728 ventoy_add_vlnk_file(NULL
, path
);
2729 node
->backendpath
[index
].vlnk_add
= 1;
2733 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, path
);
2736 debug("Failed to open file %s%s\n", g_iso_disk_name
, path
);
2740 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2741 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2742 if (NULL
== chunk_list
->chunk
)
2747 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2748 chunk_list
->cur_chunk
= 0;
2750 start
= file
->device
->disk
->partition
->start
;
2751 ventoy_get_block_list(file
, chunk_list
, start
);
2753 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2755 grub_free(chunk_list
->chunk
);
2756 chunk_list
->chunk
= NULL
;
2764 grub_file_close(file
);
2769 const char * ventoy_plugin_get_injection(const char *isopath
)
2772 injection_config
*node
= NULL
;
2774 if (!g_injection_head
)
2779 len
= (int)grub_strlen(isopath
);
2780 for (node
= g_injection_head
; node
; node
= node
->next
)
2782 if (node
->type
== injection_type_file
)
2784 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2786 return node
->archive
;
2791 for (node
= g_injection_head
; node
; node
= node
->next
)
2793 if (node
->type
== injection_type_parent
)
2795 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2797 return node
->archive
;
2805 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2808 menu_alias
*node
= NULL
;
2810 if (!g_menu_alias_head
)
2815 len
= (int)grub_strlen(isopath
);
2816 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2818 if (node
->type
== type
&& node
->pathlen
&&
2819 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2828 const menu_tip
* ventoy_plugin_get_menu_tip(int type
, const char *isopath
)
2831 menu_tip
*node
= NULL
;
2833 if (!g_menu_tip_head
)
2838 len
= (int)grub_strlen(isopath
);
2839 for (node
= g_menu_tip_head
; node
; node
= node
->next
)
2841 if (node
->type
== type
&& node
->pathlen
&&
2842 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2851 const char * ventoy_plugin_get_menu_class(int type
, const char *name
, const char *path
)
2855 menu_class
*node
= NULL
;
2857 if (!g_menu_class_head
)
2862 namelen
= (int)grub_strlen(name
);
2863 pathlen
= (int)grub_strlen(path
);
2865 if (vtoy_class_image_file
== type
)
2867 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2869 if (node
->type
!= type
)
2874 if (node
->parent
== 0)
2876 if ((node
->patlen
< namelen
) && grub_strstr(name
, node
->pattern
))
2883 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2885 if (node
->type
!= type
)
2892 if ((node
->patlen
< pathlen
) && ventoy_plugin_is_parent(node
->pattern
, node
->patlen
, path
))
2901 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2903 if (node
->type
== type
&& node
->patlen
== namelen
&& grub_strncmp(name
, node
->pattern
, namelen
) == 0)
2913 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2916 custom_boot
*node
= NULL
;
2918 node
= grub_zalloc(sizeof(custom_boot
));
2921 node
->type
= vtoy_custom_boot_image_file
;
2922 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2923 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2926 len
= node
->pathlen
- 5;
2927 node
->path
[len
] = 0;
2928 node
->pathlen
= len
;
2930 if (g_custom_boot_head
)
2932 node
->next
= g_custom_boot_head
;
2934 g_custom_boot_head
= node
;
2940 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2944 custom_boot
*node
= NULL
;
2946 if (!g_custom_boot_head
)
2951 len
= (int)grub_strlen(isopath
);
2953 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2955 if (node
->type
== vtoy_custom_boot_image_file
)
2957 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2964 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2965 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2967 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2969 if (isopath
[i
] == '/')
2986 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2988 custom_boot
*node
= NULL
;
2994 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2996 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
2997 node
->path
, node
->cfg
);
3003 int ventoy_plugin_check_memdisk(const char *isopath
)
3006 auto_memdisk
*node
= NULL
;
3008 if (!g_auto_memdisk_head
)
3013 len
= (int)grub_strlen(isopath
);
3014 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
3016 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
3025 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
3029 image_list
*node
= NULL
;
3031 if (!g_image_list_head
)
3036 len
= (int)grub_strlen(name
);
3038 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
3040 if (vtoy_class_directory
== type
)
3042 if (len
< node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
3049 if (len
== node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
3059 int ventoy_plugin_find_conf_replace(const char *iso
, conf_replace
*nodes
[VTOY_MAX_CONF_REPLACE
])
3065 if (!g_conf_replace_head
)
3070 len
= (int)grub_strlen(iso
);
3072 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
3074 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
3077 if (n
>= VTOY_MAX_CONF_REPLACE
)
3087 dud
* ventoy_plugin_find_dud(const char *iso
)
3097 len
= (int)grub_strlen(iso
);
3098 for (node
= g_dud_head
; node
; node
= node
->next
)
3100 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
3109 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
3115 for (i
= 0; i
< node
->dudnum
; i
++)
3117 if (node
->files
[i
].size
> 0)
3119 debug("file %d has been loaded\n", i
);
3123 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
3126 buf
= grub_malloc(file
->size
);
3129 grub_file_read(file
, buf
, file
->size
);
3130 node
->files
[i
].size
= (int)file
->size
;
3131 node
->files
[i
].buf
= buf
;
3133 grub_file_close(file
);
3140 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
3144 const char *pos
= NULL
;
3145 menu_password
*node
= NULL
;
3154 len
= (int)grub_strlen(isopath
);
3155 for (node
= g_pwd_head
; node
; node
= node
->next
)
3157 if (node
->type
== vtoy_menu_pwd_file
)
3159 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
3161 return &(node
->password
);
3166 for (node
= g_pwd_head
; node
; node
= node
->next
)
3168 if (node
->type
== vtoy_menu_pwd_parent
)
3170 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
3172 return &(node
->password
);
3180 if (*isopath
== '.')
3189 for (i
= 0; i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
3191 if (g_file_type_pwd
[i
].type
&& 0 == grub_strcasecmp(pos
+ 1, g_menu_prefix
[i
]))
3193 return g_file_type_pwd
+ i
;
3201 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3204 const vtoy_password
*pwd
= NULL
;
3209 pwd
= ventoy_plugin_get_password(args
[0]);
3212 if (0 == ventoy_check_password(pwd
, 1))
3230 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3237 VTOY_JSON
*node
= NULL
;
3238 VTOY_JSON
*json
= NULL
;
3247 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
3250 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
3251 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
3255 buf
= grub_malloc(file
->size
+ 1);
3258 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
3262 buf
[file
->size
] = 0;
3263 grub_file_read(file
, buf
, file
->size
);
3265 json
= vtoy_json_create();
3268 grub_printf("Failed to create json\n");
3272 ret
= vtoy_json_parse(json
, buf
);
3275 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
3279 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
3280 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
3282 if (grub_strcmp(node
->pcName
, key
) == 0)
3290 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
3292 if (grub_strcmp(node
->pcName
, args
[1]) == 0)
3300 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
3305 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
3307 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
3309 if (g_plugin_entries
[i
].checkfunc
)
3311 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
3318 check_free(file
, grub_file_close
);
3319 check_free(json
, vtoy_json_destroy
);
3320 grub_check_free(buf
);
3325 grub_err_t
ventoy_cmd_select_theme_cfg(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3331 theme_list
*node
= NULL
;
3337 if (g_theme_single_file
[0])
3342 if (g_theme_num
< 2)
3347 bufsize
= (g_theme_num
+ 1) * 1024;
3348 buf
= grub_malloc(bufsize
);
3354 for (node
= g_theme_head
; node
; node
= node
->next
)
3356 name
= grub_strstr(node
->theme
.path
, ")/");
3363 name
= node
->theme
.path
;
3366 pos
+= grub_snprintf(buf
+ pos
, bufsize
- pos
,
3367 "menuentry \"%s\" --class=debug_theme_item --class=debug_theme_select --class=F5tool {\n"
3368 "vt_set_theme_path \"%s\"\n"
3370 name
, node
->theme
.path
);
3373 pos
+= grub_snprintf(buf
+ pos
, bufsize
- pos
,
3374 "menuentry '@VTMENU_RETURN_PREVIOUS' --class=vtoyret VTOY_RET {\n"
3375 "echo 'Return ...'\n"
3378 grub_script_execute_sourcecode(buf
);
3384 grub_err_t
ventoy_cmd_set_theme(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3386 grub_uint32_t i
= 0;
3387 grub_uint32_t mod
= 0;
3388 theme_list
*node
= g_theme_head
;
3389 struct grub_datetime datetime
;
3395 if (g_theme_single_file
[0])
3397 debug("single theme %s\n", g_theme_single_file
);
3398 grub_env_set("theme", g_theme_single_file
);
3402 debug("g_theme_num = %d\n", g_theme_num
);
3404 if (g_theme_num
== 0)
3409 if (g_theme_id
> 0 && g_theme_id
<= g_theme_num
)
3411 for (i
= 0; i
< (grub_uint32_t
)(g_theme_id
- 1) && node
; i
++)
3416 grub_env_set("theme", node
->theme
.path
);
3420 grub_memset(&datetime
, 0, sizeof(datetime
));
3421 grub_get_datetime(&datetime
);
3423 if (g_theme_random
== vtoy_theme_random_boot_second
)
3425 grub_divmod32((grub_uint32_t
)datetime
.second
, (grub_uint32_t
)g_theme_num
, &mod
);
3427 else if (g_theme_random
== vtoy_theme_random_boot_day
)
3429 grub_divmod32((grub_uint32_t
)datetime
.day
, (grub_uint32_t
)g_theme_num
, &mod
);
3431 else if (g_theme_random
== vtoy_theme_random_boot_month
)
3433 grub_divmod32((grub_uint32_t
)datetime
.month
, (grub_uint32_t
)g_theme_num
, &mod
);
3436 debug("%04d/%02d/%02d %02d:%02d:%02d radom:%d mod:%d\n",
3437 datetime
.year
, datetime
.month
, datetime
.day
,
3438 datetime
.hour
, datetime
.minute
, datetime
.second
,
3439 g_theme_random
, mod
);
3441 for (i
= 0; i
< mod
&& node
; i
++)
3446 debug("random theme %s\n", node
->theme
.path
);
3447 grub_env_set("theme", node
->theme
.path
);
3451 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
3454 extern char g_ventoy_theme_path
[256];
3455 grub_err_t
ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3462 g_ventoy_theme_path
[0] = 0;
3466 grub_snprintf(g_ventoy_theme_path
, sizeof(g_ventoy_theme_path
), "%s", args
[0]);
3469 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
3472 const char *ventoy_get_vmenu_title(const char *vMenu
)
3474 return vtoy_json_get_string_ex(g_menu_lang_json
->pstChild
, vMenu
);
3477 int ventoy_plugin_load_menu_lang(const char *lang
)
3480 grub_file_t file
= NULL
;
3483 if (grub_strcmp(lang
, g_cur_menu_language
) == 0)
3485 debug("Same menu lang %s\n", lang
);
3488 grub_snprintf(g_cur_menu_language
, sizeof(g_cur_menu_language
), "%s", lang
);
3490 debug("Load menu lang %s\n", g_cur_menu_language
);
3492 if (g_menu_lang_json
)
3494 vtoy_json_destroy(g_menu_lang_json
);
3495 g_menu_lang_json
= NULL
;
3498 g_menu_lang_json
= vtoy_json_create();
3499 if (!g_menu_lang_json
)
3504 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "(vt_menu_tarfs)/menu/%s.json", lang
);
3510 buf
= grub_malloc(file
->size
+ 1);
3513 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
3517 buf
[file
->size
] = 0;
3518 grub_file_read(file
, buf
, file
->size
);
3520 vtoy_json_parse(g_menu_lang_json
, buf
);
3522 if (g_default_menu_mode
== 0)
3524 grub_snprintf(g_ventoy_hotkey_tip
, sizeof(g_ventoy_hotkey_tip
), "%s", ventoy_get_vmenu_title("VTMENU_STR_HOTKEY_TREE"));
3528 grub_snprintf(g_ventoy_hotkey_tip
, sizeof(g_ventoy_hotkey_tip
), "%s", ventoy_get_vmenu_title("VTMENU_STR_HOTKEY_LIST"));
3531 ventoy_menu_push_key(GRUB_TERM_ESC
);
3532 ventoy_menu_push_key(GRUB_TERM_ESC
);
3533 g_ventoy_menu_refresh
= 1;
3538 check_free(file
, grub_file_close
);
3539 grub_check_free(buf
);
3544 grub_err_t
ventoy_cmd_cur_menu_lang(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3551 grub_env_set(args
[0], g_cur_menu_language
);
3555 grub_printf("%s\n", g_cur_menu_language
);
3556 grub_printf("%s\n", g_ventoy_hotkey_tip
);
3560 VENTOY_CMD_RETURN(0);