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/video.h>
39 #include <grub/ventoy.h>
40 #include "ventoy_def.h"
42 GRUB_MOD_LICENSE ("GPLv3+");
44 char g_arch_mode_suffix
[64];
45 static char g_iso_disk_name
[128];
46 static vtoy_password g_boot_pwd
;
47 static vtoy_password g_file_type_pwd
[img_type_max
];
48 static install_template
*g_install_template_head
= NULL
;
49 static dud
*g_dud_head
= NULL
;
50 static menu_password
*g_pwd_head
= NULL
;
51 static persistence_config
*g_persistence_head
= NULL
;
52 static menu_tip
*g_menu_tip_head
= NULL
;
53 static menu_alias
*g_menu_alias_head
= NULL
;
54 static menu_class
*g_menu_class_head
= NULL
;
55 static custom_boot
*g_custom_boot_head
= NULL
;
56 static injection_config
*g_injection_head
= NULL
;
57 static auto_memdisk
*g_auto_memdisk_head
= NULL
;
58 static image_list
*g_image_list_head
= NULL
;
59 static conf_replace
*g_conf_replace_head
= NULL
;
60 static VTOY_JSON
*g_menu_lang_json
= NULL
;
62 static int g_theme_id
= 0;
63 static int g_theme_res_fit
= 0;
64 static int g_theme_num
= 0;
65 static theme_list
*g_theme_head
= NULL
;
66 static int g_theme_random
= vtoy_theme_random_boot_second
;
67 static char g_theme_single_file
[256];
68 static char g_cur_menu_language
[32] = {0};
70 static int ventoy_plugin_is_parent(const char *pat
, int patlen
, const char *isopath
)
74 if (isopath
[patlen
] == '/' && ventoy_strncmp(pat
, isopath
, patlen
) == 0 &&
75 grub_strchr(isopath
+ patlen
+ 1, '/') == NULL
)
82 if (pat
[0] == '/' && grub_strchr(isopath
+ 1, '/') == NULL
)
91 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
94 VTOY_JSON
*pNode
= NULL
;
95 VTOY_JSON
*pChild
= NULL
;
99 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
101 grub_printf("Not array type %d\n", json
->enDataType
);
105 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
107 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
109 pChild
= pNode
->pstChild
;
110 if (pChild
->enDataType
== JSON_TYPE_STRING
)
112 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
114 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
115 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
119 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
124 grub_printf("%s is NOT string type\n", pChild
->pcName
);
130 grub_printf("%s is not an object\n", pNode
->pcName
);
138 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
140 VTOY_JSON
*pNode
= NULL
;
141 VTOY_JSON
*pChild
= NULL
;
145 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
147 debug("Not array %d\n", json
->enDataType
);
151 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
153 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
155 pChild
= pNode
->pstChild
;
156 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
158 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
166 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
172 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
175 grub_printf("file: %s\n", value
);
178 exist
= ventoy_check_file_exist("%s%s", isodisk
, value
);
182 exist
= ventoy_check_file_exist("%s/ventoy/%s", isodisk
, value
);
187 grub_printf("Theme file %s does NOT exist\n", value
);
193 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
196 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
198 value
= node
->unData
.pcStrVal
;
199 grub_printf("file: %s\n", value
);
202 exist
= ventoy_check_file_exist("%s%s", isodisk
, value
);
206 exist
= ventoy_check_file_exist("%s/ventoy/%s", isodisk
, value
);
211 grub_printf("Theme file %s does NOT exist\n", value
);
216 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
219 grub_printf("random: %s\n", value
);
224 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
227 grub_printf("gfxmode: %s\n", value
);
230 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
233 grub_printf("display_mode: %s\n", value
);
236 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
239 grub_printf("serial_param %s\n", value
);
242 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
245 grub_printf("ventoy_left: %s\n", value
);
248 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
251 grub_printf("ventoy_top: %s\n", value
);
254 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
257 grub_printf("ventoy_color: %s\n", value
);
260 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
263 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
265 if (node
->enDataType
== JSON_TYPE_STRING
)
267 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
269 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
273 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
280 grub_printf("fonts NOT found\n");
286 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
291 VTOY_JSON
*node
= NULL
;
292 theme_list
*tail
= NULL
;
293 theme_list
*themenode
= NULL
;
295 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
300 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
304 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
307 if (ventoy_check_file_exist(filepath
) == 0)
309 debug("Theme file %s does not exist\n", filepath
);
313 debug("vtoy_theme %s\n", filepath
);
314 ventoy_env_export("vtoy_theme", filepath
);
315 grub_snprintf(g_theme_single_file
, sizeof(g_theme_single_file
), "%s", filepath
);
319 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
322 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
324 value
= node
->unData
.pcStrVal
;
327 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
331 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
334 if (ventoy_check_file_exist(filepath
) == 0)
339 themenode
= grub_zalloc(sizeof(theme_list
));
342 grub_snprintf(themenode
->theme
.path
, sizeof(themenode
->theme
.path
), "%s", filepath
);
345 tail
->next
= themenode
;
349 g_theme_head
= themenode
;
356 ventoy_env_export("vtoy_theme", "random");
357 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
360 if (grub_strcmp(value
, "boot_second") == 0)
362 g_theme_random
= vtoy_theme_random_boot_second
;
364 else if (grub_strcmp(value
, "boot_day") == 0)
366 g_theme_random
= vtoy_theme_random_boot_day
;
368 else if (grub_strcmp(value
, "boot_month") == 0)
370 g_theme_random
= vtoy_theme_random_boot_month
;
376 grub_snprintf(val
, sizeof(val
), "%d", g_theme_num
);
377 grub_env_set("VTOY_THEME_COUNT", val
);
378 grub_env_export("VTOY_THEME_COUNT");
381 vtoy_json_get_int(json
->pstChild
, "default_file", &g_theme_id
);
384 vtoy_json_get_int(json
->pstChild
, "resolution_fit", &g_theme_res_fit
);
385 if (g_theme_res_fit
!= 1)
390 grub_snprintf(val
, sizeof(val
), "%d", g_theme_res_fit
);
391 ventoy_env_export("vtoy_res_fit", val
);
394 if (g_theme_id
> g_theme_num
|| g_theme_id
< 0)
400 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
403 debug("vtoy_gfxmode %s\n", value
);
404 ventoy_env_export("vtoy_gfxmode", value
);
407 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
410 debug("display_mode %s\n", value
);
411 ventoy_env_export("vtoy_display_mode", value
);
414 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
417 debug("serial_param %s\n", value
);
418 ventoy_env_export("vtoy_serial_param", value
);
421 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
424 ventoy_env_export(ventoy_left_key
, value
);
427 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
430 ventoy_env_export(ventoy_top_key
, value
);
433 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
436 ventoy_env_export(ventoy_color_key
, value
);
439 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
442 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
444 if (node
->enDataType
== JSON_TYPE_STRING
&&
445 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
447 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
448 grub_font_load(filepath
);
456 static int ventoy_plugin_check_path(const char *path
, const char *file
)
460 grub_printf("%s is NOT begin with '/' \n", file
);
464 if (grub_strchr(file
, '\\'))
466 grub_printf("%s contains invalid '\\' \n", file
);
470 if (grub_strstr(file
, "//"))
472 grub_printf("%s contains invalid double slash\n", file
);
476 if (grub_strstr(file
, "../"))
478 grub_printf("%s contains invalid '../' \n", file
);
482 if (!ventoy_check_file_exist("%s%s", path
, file
))
484 grub_printf("%s%s does NOT exist\n", path
, file
);
491 static int ventoy_plugin_check_fullpath
502 VTOY_JSON
*node
= json
;
503 VTOY_JSON
*child
= NULL
;
507 if (0 == grub_strcmp(key
, node
->pcName
))
511 node
= node
->pstNext
;
519 if (JSON_TYPE_STRING
== node
->enDataType
)
522 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
523 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
525 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
527 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
529 if (JSON_TYPE_STRING
!= child
->enDataType
)
531 grub_printf("Non string json type\n");
535 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
536 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
547 static int ventoy_plugin_parse_fullpath
552 file_fullpath
**fullpath
,
558 VTOY_JSON
*node
= json
;
559 VTOY_JSON
*child
= NULL
;
560 file_fullpath
*path
= NULL
;
564 if (0 == grub_strcmp(key
, node
->pcName
))
568 node
= node
->pstNext
;
576 if (JSON_TYPE_STRING
== node
->enDataType
)
578 debug("%s is string type data\n", node
->pcName
);
580 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
582 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
586 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
589 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
595 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
597 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
599 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
601 debug("Invalid data type:%d\n", child
->enDataType
);
606 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
608 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
613 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
615 if (ventoy_check_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
617 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
631 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
637 const char *iso
= NULL
;
638 VTOY_JSON
*pNode
= NULL
;
640 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
642 grub_printf("Not array type %d\n", json
->enDataType
);
646 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
648 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
650 grub_printf("NOT object type\n");
653 if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image")) != NULL
)
655 pos
= grub_strchr(iso
, '*');
656 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
658 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
659 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
661 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
663 if (autosel
>= 0 && autosel
<= pathnum
)
665 grub_printf("autosel: %d [OK]\n", autosel
);
669 grub_printf("autosel: %d [FAIL]\n", autosel
);
673 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
677 grub_printf("timeout: %d [OK]\n", timeout
);
681 grub_printf("timeout: %d [FAIL]\n", timeout
);
687 grub_printf("image: %s [FAIL]\n", iso
);
690 else if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent")) != NULL
)
692 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
694 grub_printf("parent: %s [OK]\n", iso
);
695 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
697 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
699 if (autosel
>= 0 && autosel
<= pathnum
)
701 grub_printf("autosel: %d [OK]\n", autosel
);
705 grub_printf("autosel: %d [FAIL]\n", autosel
);
709 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
713 grub_printf("timeout: %d [OK]\n", timeout
);
717 grub_printf("timeout: %d [FAIL]\n", timeout
);
723 grub_printf("parent: %s [FAIL]\n", iso
);
728 grub_printf("image not found\n");
735 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
741 const char *iso
= NULL
;
742 VTOY_JSON
*pNode
= NULL
;
743 install_template
*node
= NULL
;
744 install_template
*next
= NULL
;
745 file_fullpath
*templatepath
= NULL
;
747 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
749 debug("Not array %d\n", json
->enDataType
);
753 if (g_install_template_head
)
755 for (node
= g_install_template_head
; node
; node
= next
)
758 grub_check_free(node
->templatepath
);
762 g_install_template_head
= NULL
;
765 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
767 type
= auto_install_type_file
;
768 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
771 type
= auto_install_type_parent
;
772 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
775 if (iso
&& iso
[0] == '/')
777 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
779 node
= grub_zalloc(sizeof(install_template
));
783 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
784 node
->templatepath
= templatepath
;
785 node
->templatenum
= pathnum
;
789 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
791 if (autosel
>= 0 && autosel
<= pathnum
)
793 node
->autosel
= autosel
;
797 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
801 node
->timeout
= timeout
;
805 if (g_install_template_head
)
807 node
->next
= g_install_template_head
;
810 g_install_template_head
= node
;
819 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
823 const char *iso
= NULL
;
824 VTOY_JSON
*pNode
= NULL
;
826 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
828 grub_printf("Not array type %d\n", json
->enDataType
);
832 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
834 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
836 grub_printf("NOT object type\n");
839 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
842 pos
= grub_strchr(iso
, '*');
843 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
845 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
846 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
850 grub_printf("image: %s [FAIL]\n", iso
);
855 grub_printf("image not found\n");
862 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
865 const char *iso
= NULL
;
866 VTOY_JSON
*pNode
= NULL
;
869 file_fullpath
*dudpath
= NULL
;
871 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
873 debug("Not array %d\n", json
->enDataType
);
879 for (node
= g_dud_head
; node
; node
= next
)
882 grub_check_free(node
->dudpath
);
889 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
891 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
892 if (iso
&& iso
[0] == '/')
894 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "dud", &dudpath
, &pathnum
))
896 node
= grub_zalloc(sizeof(dud
));
899 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
900 node
->dudpath
= dudpath
;
901 node
->dudnum
= pathnum
;
902 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
908 node
->next
= g_dud_head
;
925 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
932 vtoy_password tmpPwd
;
934 len
= (int)grub_strlen(pwdstr
);
937 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
941 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
943 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
945 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
946 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
948 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
952 for (i
= 0; i
< 16; i
++)
954 bytes
[0] = pwdstr
[4 + i
* 2];
955 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
958 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
960 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
964 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
968 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
970 else if ((len
- 4) > 32)
972 pos
= grub_strchr(pwdstr
+ 4, '#');
975 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
979 if (len
- 1 - ((long)pos
- (long)pwdstr
) != 32)
981 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
987 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
991 for (i
= 0; i
< 16; i
++)
993 bytes
[0] = pos
[i
* 2];
994 bytes
[1] = pos
[i
* 2 + 1];
997 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
999 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
1003 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
1008 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
1012 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
1018 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
1024 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
1030 static int ventoy_plugin_get_pwd_type(const char *pwd
)
1035 for (i
= 0; pwd
&& i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
1037 grub_snprintf(pwdtype
, sizeof(pwdtype
), "%spwd", g_menu_prefix
[i
]);
1038 if (grub_strcmp(pwdtype
, pwd
) == 0)
1040 return img_type_start
+ i
;
1047 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
1050 const char *iso
= NULL
;
1051 const char *pwd
= NULL
;
1052 VTOY_JSON
*pNode
= NULL
;
1053 VTOY_JSON
*pCNode
= NULL
;
1054 menu_password
*node
= NULL
;
1055 menu_password
*tail
= NULL
;
1056 menu_password
*next
= NULL
;
1060 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1062 debug("Not object %d\n", json
->enDataType
);
1068 for (node
= g_pwd_head
; node
; node
= next
)
1077 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1079 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1081 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
1083 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1085 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, g_file_type_pwd
+ type
);
1087 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1089 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1091 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1096 type
= vtoy_menu_pwd_file
;
1097 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
1100 type
= vtoy_menu_pwd_parent
;
1101 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent");
1104 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1105 if (iso
&& pwd
&& iso
[0] == '/')
1107 node
= grub_zalloc(sizeof(menu_password
));
1111 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1113 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
1137 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
1141 const char *iso
= NULL
;
1142 const char *pwd
= NULL
;
1143 VTOY_JSON
*pNode
= NULL
;
1144 VTOY_JSON
*pCNode
= NULL
;
1146 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1148 grub_printf("Not object %d\n", json
->enDataType
);
1152 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1154 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1156 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1158 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
1162 grub_printf("Invalid bootpwd.\n");
1165 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1167 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1169 grub_printf("%s:<%s>\n", pNode
->pcName
, pNode
->unData
.pcStrVal
);
1173 grub_printf("Invalid pwd <%s>\n", pNode
->unData
.pcStrVal
);
1176 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1179 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1181 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1183 grub_printf("Not object %d\n", pCNode
->enDataType
);
1187 if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file")) != NULL
)
1189 pos
= grub_strchr(iso
, '*');
1190 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1192 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1194 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1196 grub_printf("file:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1197 grub_printf("pwd:<%s>\n\n", pwd
);
1201 grub_printf("Invalid password for <%s>\n", iso
);
1206 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1209 else if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent")) != NULL
)
1211 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
1213 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1214 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1216 grub_printf("dir:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1217 grub_printf("pwd:<%s>\n\n", pwd
);
1221 grub_printf("Invalid password for <%s>\n", iso
);
1226 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1231 grub_printf("No file item found in json.\n");
1240 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
1246 const char *iso
= NULL
;
1247 VTOY_JSON
*pNode
= NULL
;
1249 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1251 grub_printf("Not array type %d\n", json
->enDataType
);
1255 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1257 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
1259 grub_printf("NOT object type\n");
1262 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1265 pos
= grub_strchr(iso
, '*');
1266 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1268 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
1269 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
1271 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1273 if (autosel
>= 0 && autosel
<= pathnum
)
1275 grub_printf("autosel: %d [OK]\n", autosel
);
1279 grub_printf("autosel: %d [FAIL]\n", autosel
);
1283 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
1287 grub_printf("timeout: %d [OK]\n", timeout
);
1291 grub_printf("timeout: %d [FAIL]\n", timeout
);
1297 grub_printf("image: %s [FAIL]\n", iso
);
1302 grub_printf("image not found\n");
1309 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1314 const char *iso
= NULL
;
1315 VTOY_JSON
*pNode
= NULL
;
1316 persistence_config
*node
= NULL
;
1317 persistence_config
*next
= NULL
;
1318 file_fullpath
*backendpath
= NULL
;
1322 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1324 debug("Not array %d\n", json
->enDataType
);
1328 if (g_persistence_head
)
1330 for (node
= g_persistence_head
; node
; node
= next
)
1333 grub_check_free(node
->backendpath
);
1337 g_persistence_head
= NULL
;
1340 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1342 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1343 if (iso
&& iso
[0] == '/')
1345 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1347 node
= grub_zalloc(sizeof(persistence_config
));
1350 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1351 node
->backendpath
= backendpath
;
1352 node
->backendnum
= pathnum
;
1356 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1358 if (autosel
>= 0 && autosel
<= pathnum
)
1360 node
->autosel
= autosel
;
1364 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
1368 node
->timeout
= timeout
;
1372 if (g_persistence_head
)
1374 node
->next
= g_persistence_head
;
1377 g_persistence_head
= node
;
1386 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1389 const char *path
= NULL
;
1390 const char *alias
= NULL
;
1391 VTOY_JSON
*pNode
= NULL
;
1395 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1397 grub_printf("Not array %d\n", json
->enDataType
);
1401 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1403 type
= vtoy_alias_image_file
;
1404 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1407 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1408 type
= vtoy_alias_directory
;
1411 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1412 if (path
&& path
[0] == '/' && alias
)
1414 if (vtoy_alias_image_file
== type
)
1416 if (grub_strchr(path
, '*'))
1418 grub_printf("image: <%s> [ * ]\n", path
);
1420 else if (ventoy_check_file_exist("%s%s", isodisk
, path
))
1422 grub_printf("image: <%s> [ OK ]\n", path
);
1426 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1431 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1433 grub_printf("dir: <%s> [ OK ]\n", path
);
1437 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1441 grub_printf("alias: <%s>\n\n", alias
);
1448 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1451 const char *path
= NULL
;
1452 const char *alias
= NULL
;
1453 VTOY_JSON
*pNode
= NULL
;
1454 menu_alias
*node
= NULL
;
1455 menu_alias
*next
= NULL
;
1459 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1461 debug("Not array %d\n", json
->enDataType
);
1465 if (g_menu_alias_head
)
1467 for (node
= g_menu_alias_head
; node
; node
= next
)
1473 g_menu_alias_head
= NULL
;
1476 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1478 type
= vtoy_alias_image_file
;
1479 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1482 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1483 type
= vtoy_alias_directory
;
1486 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1487 if (path
&& path
[0] == '/' && alias
)
1489 node
= grub_zalloc(sizeof(menu_alias
));
1493 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1494 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1496 if (g_menu_alias_head
)
1498 node
->next
= g_menu_alias_head
;
1501 g_menu_alias_head
= node
;
1509 static int ventoy_plugin_menutip_check(VTOY_JSON
*json
, const char *isodisk
)
1512 const char *path
= NULL
;
1513 const char *tip
= NULL
;
1514 VTOY_JSON
*pNode
= NULL
;
1518 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1520 grub_printf("Not object %d\n", json
->enDataType
);
1524 tip
= vtoy_json_get_string_ex(json
->pstChild
, "left");
1527 grub_printf("left: <%s>\n", tip
);
1530 tip
= vtoy_json_get_string_ex(json
->pstChild
, "top");
1533 grub_printf("top: <%s>\n", tip
);
1536 tip
= vtoy_json_get_string_ex(json
->pstChild
, "color");
1539 grub_printf("color: <%s>\n", tip
);
1542 pNode
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "tips");
1543 for (pNode
= pNode
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1545 type
= vtoy_tip_image_file
;
1546 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1549 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1550 type
= vtoy_tip_directory
;
1553 if (path
&& path
[0] == '/')
1555 if (vtoy_tip_image_file
== type
)
1557 if (grub_strchr(path
, '*'))
1559 grub_printf("image: <%s> [ * ]\n", path
);
1561 else if (ventoy_check_file_exist("%s%s", isodisk
, path
))
1563 grub_printf("image: <%s> [ OK ]\n", path
);
1567 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1572 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1574 grub_printf("dir: <%s> [ OK ]\n", path
);
1578 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1582 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip");
1585 grub_printf("tip: <%s>\n", tip
);
1589 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip1");
1591 grub_printf("tip1: <%s>\n", tip
);
1593 grub_printf("tip1: <NULL>\n");
1595 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip2");
1597 grub_printf("tip2: <%s>\n", tip
);
1599 grub_printf("tip2: <NULL>\n");
1604 grub_printf("image: <%s> [ INVALID ]\n", path
);
1611 static int ventoy_plugin_menutip_entry(VTOY_JSON
*json
, const char *isodisk
)
1614 const char *path
= NULL
;
1615 const char *tip
= NULL
;
1616 VTOY_JSON
*pNode
= NULL
;
1617 menu_tip
*node
= NULL
;
1618 menu_tip
*next
= NULL
;
1622 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1624 debug("Not object %d\n", json
->enDataType
);
1628 pNode
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "tips");
1631 debug("Not tips found\n");
1635 if (g_menu_tip_head
)
1637 for (node
= g_menu_tip_head
; node
; node
= next
)
1643 g_menu_tip_head
= NULL
;
1646 tip
= vtoy_json_get_string_ex(json
->pstChild
, "left");
1649 grub_env_set("VTOY_TIP_LEFT", tip
);
1652 tip
= vtoy_json_get_string_ex(json
->pstChild
, "top");
1655 grub_env_set("VTOY_TIP_TOP", tip
);
1658 tip
= vtoy_json_get_string_ex(json
->pstChild
, "color");
1661 grub_env_set("VTOY_TIP_COLOR", tip
);
1664 for (pNode
= pNode
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1666 type
= vtoy_tip_image_file
;
1667 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1670 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1671 type
= vtoy_tip_directory
;
1674 if (path
&& path
[0] == '/')
1676 node
= grub_zalloc(sizeof(menu_tip
));
1680 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1682 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip");
1685 grub_snprintf(node
->tip1
, 1000, "%s", tip
);
1689 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip1");
1691 grub_snprintf(node
->tip1
, 1000, "%s", tip
);
1693 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip2");
1695 grub_snprintf(node
->tip2
, 1000, "%s", tip
);
1698 if (g_menu_tip_head
)
1700 node
->next
= g_menu_tip_head
;
1703 g_menu_tip_head
= node
;
1711 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1714 const char *path
= NULL
;
1715 const char *archive
= NULL
;
1716 VTOY_JSON
*pNode
= NULL
;
1720 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1722 grub_printf("Not array %d\n", json
->enDataType
);
1726 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1728 type
= injection_type_file
;
1729 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1732 type
= injection_type_parent
;
1733 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1736 grub_printf("image/parent not found\n");
1741 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1744 grub_printf("archive not found\n");
1748 if (type
== injection_type_file
)
1750 if (grub_strchr(path
, '*'))
1752 grub_printf("image: <%s> [*]\n", path
);
1756 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1761 grub_printf("parent: <%s> [%s]\n", path
,
1762 ventoy_is_dir_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1765 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1771 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1774 const char *path
= NULL
;
1775 const char *archive
= NULL
;
1776 VTOY_JSON
*pNode
= NULL
;
1777 injection_config
*node
= NULL
;
1778 injection_config
*next
= NULL
;
1782 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1784 debug("Not array %d\n", json
->enDataType
);
1788 if (g_injection_head
)
1790 for (node
= g_injection_head
; node
; node
= next
)
1796 g_injection_head
= NULL
;
1799 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1801 type
= injection_type_file
;
1802 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1805 type
= injection_type_parent
;
1806 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1809 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1810 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1812 node
= grub_zalloc(sizeof(injection_config
));
1816 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1817 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1819 if (g_injection_head
)
1821 node
->next
= g_injection_head
;
1824 g_injection_head
= node
;
1832 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1836 const char *key
= NULL
;
1837 const char *class = NULL
;
1838 VTOY_JSON
*pNode
= NULL
;
1839 menu_class
*tail
= NULL
;
1840 menu_class
*node
= NULL
;
1841 menu_class
*next
= NULL
;
1845 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1847 debug("Not array %d\n", json
->enDataType
);
1851 if (g_menu_class_head
)
1853 for (node
= g_menu_class_head
; node
; node
= next
)
1859 g_menu_class_head
= NULL
;
1862 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1865 type
= vtoy_class_image_file
;
1866 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1869 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1876 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1877 type
= vtoy_class_directory
;
1881 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1884 node
= grub_zalloc(sizeof(menu_class
));
1888 node
->parent
= parent
;
1889 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1890 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1892 if (g_menu_class_head
)
1898 g_menu_class_head
= node
;
1908 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1910 const char *name
= NULL
;
1911 const char *key
= NULL
;
1912 const char *class = NULL
;
1913 VTOY_JSON
*pNode
= NULL
;
1917 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1919 grub_printf("Not array %d\n", json
->enDataType
);
1923 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1926 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1930 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1934 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1938 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1941 grub_printf("%s: <%s>\n", name
, key
);
1942 grub_printf("class: <%s>\n\n", class);
1949 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1953 const char *key
= NULL
;
1954 const char *cfg
= NULL
;
1955 VTOY_JSON
*pNode
= NULL
;
1956 custom_boot
*tail
= NULL
;
1957 custom_boot
*node
= NULL
;
1958 custom_boot
*next
= NULL
;
1962 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1964 debug("Not array %d\n", json
->enDataType
);
1968 if (g_custom_boot_head
)
1970 for (node
= g_custom_boot_head
; node
; node
= next
)
1976 g_custom_boot_head
= NULL
;
1979 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1981 type
= vtoy_custom_boot_image_file
;
1982 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1985 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1986 type
= vtoy_custom_boot_directory
;
1989 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1992 node
= grub_zalloc(sizeof(custom_boot
));
1996 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1997 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1999 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
2001 if (g_custom_boot_head
)
2007 g_custom_boot_head
= node
;
2022 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
2026 const char *key
= NULL
;
2027 const char *cfg
= NULL
;
2028 VTOY_JSON
*pNode
= NULL
;
2032 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2034 grub_printf("Not array %d\n", json
->enDataType
);
2038 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2040 type
= vtoy_custom_boot_image_file
;
2041 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
2044 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
2045 type
= vtoy_custom_boot_directory
;
2048 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
2049 len
= (int)grub_strlen(cfg
);
2052 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
2054 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
2058 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
2059 grub_printf("vcfg: <%s>\n\n", cfg
);
2067 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
2070 const char *isof
= NULL
;
2071 const char *orgf
= NULL
;
2072 const char *newf
= NULL
;
2073 VTOY_JSON
*pNode
= NULL
;
2074 conf_replace
*tail
= NULL
;
2075 conf_replace
*node
= NULL
;
2076 conf_replace
*next
= NULL
;
2080 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2082 debug("Not array %d\n", json
->enDataType
);
2086 if (g_conf_replace_head
)
2088 for (node
= g_conf_replace_head
; node
; node
= next
)
2094 g_conf_replace_head
= NULL
;
2097 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2099 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
2100 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
2101 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
2102 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
2104 node
= grub_zalloc(sizeof(conf_replace
));
2107 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "img", &img
))
2112 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
2113 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
2114 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
2116 if (g_conf_replace_head
)
2122 g_conf_replace_head
= node
;
2132 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
2135 const char *isof
= NULL
;
2136 const char *orgf
= NULL
;
2137 const char *newf
= NULL
;
2138 VTOY_JSON
*pNode
= NULL
;
2139 grub_file_t file
= NULL
;
2144 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2146 grub_printf("Not array %d\n", json
->enDataType
);
2150 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2152 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
2153 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
2154 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
2155 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
2157 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
2159 grub_printf("iso:<%s> [OK]\n", isof
);
2161 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
2162 grub_script_execute_sourcecode(cmd
);
2164 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
2167 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
2169 grub_printf("org:<%s> [OK]\n", orgf
);
2173 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
2175 grub_file_close(file
);
2179 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
2182 grub_script_execute_sourcecode("loopback -d vtisocheck");
2184 else if (grub_strchr(isof
, '*'))
2186 grub_printf("iso:<%s> [*]\n", isof
);
2187 grub_printf("org:<%s>\n", orgf
);
2191 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
2192 grub_printf("org:<%s>\n", orgf
);
2195 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
2198 if (file
->size
> vtoy_max_replace_file_size
)
2200 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
2204 grub_printf("new1:<%s> [OK]\n", newf
);
2206 grub_file_close(file
);
2210 grub_printf("new:<%s> [NOT Exist]\n", newf
);
2213 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "img", &img
))
2215 grub_printf("img:<%d>\n", img
);
2225 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
2227 VTOY_JSON
*pNode
= NULL
;
2228 auto_memdisk
*node
= NULL
;
2229 auto_memdisk
*next
= NULL
;
2233 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2235 debug("Not array %d\n", json
->enDataType
);
2239 if (g_auto_memdisk_head
)
2241 for (node
= g_auto_memdisk_head
; node
; node
= next
)
2247 g_auto_memdisk_head
= NULL
;
2250 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2252 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2254 node
= grub_zalloc(sizeof(auto_memdisk
));
2257 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2259 if (g_auto_memdisk_head
)
2261 node
->next
= g_auto_memdisk_head
;
2264 g_auto_memdisk_head
= node
;
2272 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
2274 VTOY_JSON
*pNode
= NULL
;
2276 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2278 grub_printf("Not array %d\n", json
->enDataType
);
2282 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2284 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2286 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2288 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2290 grub_printf(" [*]\n");
2292 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2294 grub_printf(" [OK]\n");
2298 grub_printf(" [NOT EXIST]\n");
2306 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
2308 VTOY_JSON
*pNode
= NULL
;
2309 image_list
*node
= NULL
;
2310 image_list
*next
= NULL
;
2311 image_list
*tail
= NULL
;
2315 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2317 debug("Not array %d\n", json
->enDataType
);
2321 if (g_image_list_head
)
2323 for (node
= g_image_list_head
; node
; node
= next
)
2329 g_image_list_head
= NULL
;
2332 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
2334 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
2338 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
2341 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2343 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2345 node
= grub_zalloc(sizeof(image_list
));
2348 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2350 if (g_image_list_head
)
2356 g_image_list_head
= node
;
2366 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
2368 VTOY_JSON
*pNode
= NULL
;
2370 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2372 grub_printf("Not array %d\n", json
->enDataType
);
2376 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2378 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2380 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2382 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2384 grub_printf(" [*]\n");
2386 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2388 grub_printf(" [OK]\n");
2392 grub_printf(" [NOT EXIST]\n");
2400 static plugin_entry g_plugin_entries
[] =
2402 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
, 0 },
2403 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
, 0 },
2404 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
, 0 },
2405 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
, 0 },
2406 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
, 0 },
2407 { "menu_tip", ventoy_plugin_menutip_entry
, ventoy_plugin_menutip_check
, 0 },
2408 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
, 0 },
2409 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
, 0 },
2410 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
, 0 },
2411 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
, 0 },
2412 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
, 0 },
2413 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
, 0 },
2414 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
, 0 },
2415 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
, 0 },
2416 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
, 0 },
2419 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
2423 VTOY_JSON
*cur
= NULL
;
2425 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
2427 for (cur
= json
; cur
; cur
= cur
->pstNext
)
2429 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2431 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
2432 if (g_plugin_entries
[i
].flag
== 0 && grub_strcmp(key
, cur
->pcName
) == 0)
2434 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2435 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2436 g_plugin_entries
[i
].flag
= 1;
2443 for (cur
= json
; cur
; cur
= cur
->pstNext
)
2445 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2447 if (g_plugin_entries
[i
].flag
== 0 && grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0)
2449 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2450 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2451 g_plugin_entries
[i
].flag
= 1;
2460 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2465 grub_uint8_t
*code
= NULL
;
2467 VTOY_JSON
*json
= NULL
;
2472 grub_env_set("VTOY_TIP_LEFT", "10%");
2473 grub_env_set("VTOY_TIP_TOP", "80%+5");
2474 grub_env_set("VTOY_TIP_COLOR", "blue");
2475 grub_env_set("VTOY_TIP_ALIGN", "left");
2477 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2480 return GRUB_ERR_NONE
;
2483 debug("json configuration file size %d\n", (int)file
->size
);
2485 buf
= grub_malloc(file
->size
+ 1);
2488 grub_file_close(file
);
2492 buf
[file
->size
] = 0;
2493 grub_file_read(file
, buf
, file
->size
);
2494 grub_file_close(file
);
2496 json
= vtoy_json_create();
2502 code
= (grub_uint8_t
*)buf
;
2503 if (code
[0] == 0xef && code
[1] == 0xbb && code
[2] == 0xbf)
2505 offset
= 3; /* Skip UTF-8 BOM */
2507 else if ((code
[0] == 0xff && code
[1] == 0xfe) || (code
[0] == 0xfe && code
[1] == 0xff))
2509 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2510 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2512 grub_env_set("VTOY_PLUGIN_ENCODE_ERROR", "1");
2513 grub_env_export("VTOY_PLUGIN_ENCODE_ERROR");
2515 debug("Failed to parse json string %d\n", ret
);
2520 ret
= vtoy_json_parse(json
, buf
+ offset
);
2523 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2524 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2526 debug("Failed to parse json string %d\n", ret
);
2531 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
2533 vtoy_json_destroy(json
);
2537 if (g_boot_pwd
.type
)
2539 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
2540 if (ventoy_check_password(&g_boot_pwd
, 3))
2542 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
2549 if (g_menu_tip_head
)
2551 grub_env_set("VTOY_MENU_TIP_ENABLE", "1");
2555 grub_env_unset("VTOY_MENU_TIP_ENABLE");
2558 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2561 void ventoy_plugin_dump_injection(void)
2563 injection_config
*node
= NULL
;
2565 for (node
= g_injection_head
; node
; node
= node
->next
)
2567 grub_printf("\n%s:<%s>\n", (node
->type
== injection_type_file
) ? "IMAGE" : "PARENT", node
->isopath
);
2568 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
2575 void ventoy_plugin_dump_auto_install(void)
2578 install_template
*node
= NULL
;
2580 for (node
= g_install_template_head
; node
; node
= node
->next
)
2582 grub_printf("\n%s:<%s> <%d>\n",
2583 (node
->type
== auto_install_type_file
) ? "IMAGE" : "PARENT",
2584 node
->isopath
, node
->templatenum
);
2585 for (i
= 0; i
< node
->templatenum
; i
++)
2587 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
2594 void ventoy_plugin_dump_persistence(void)
2598 persistence_config
*node
= NULL
;
2599 ventoy_img_chunk_list chunk_list
;
2601 for (node
= g_persistence_head
; node
; node
= node
->next
)
2603 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
2605 for (i
= 0; i
< node
->backendnum
; i
++)
2607 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
2608 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
2611 grub_printf(" [ SUCCESS ]\n");
2612 grub_free(chunk_list
.chunk
);
2616 grub_printf(" [ FAILED ]\n");
2624 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
2627 install_template
*node
= NULL
;
2629 if (!g_install_template_head
)
2634 len
= (int)grub_strlen(isopath
);
2635 for (node
= g_install_template_head
; node
; node
= node
->next
)
2637 if (node
->type
== auto_install_type_file
)
2639 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2646 for (node
= g_install_template_head
; node
; node
= node
->next
)
2648 if (node
->type
== auto_install_type_parent
)
2650 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2660 char * ventoy_plugin_get_cur_install_template(const char *isopath
, install_template
**cur
)
2662 install_template
*node
= NULL
;
2669 node
= ventoy_plugin_find_install_template(isopath
);
2670 if ((!node
) || (!node
->templatepath
))
2675 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2685 return node
->templatepath
[node
->cursel
].path
;
2688 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2691 persistence_config
*node
= NULL
;
2693 if (!g_persistence_head
)
2698 len
= (int)grub_strlen(isopath
);
2699 for (node
= g_persistence_head
; node
; node
= node
->next
)
2701 if ((len
== node
->pathlen
) && (ventoy_strcmp(node
->isopath
, isopath
) == 0))
2710 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2715 grub_uint64_t start
= 0;
2716 grub_file_t file
= NULL
;
2717 persistence_config
*node
= NULL
;
2719 node
= ventoy_plugin_find_persistent(isopath
);
2720 if ((!node
) || (!node
->backendpath
))
2727 index
= node
->cursel
;
2730 if (index
< 0 || index
>= node
->backendnum
)
2735 path
= node
->backendpath
[index
].path
;
2737 if (node
->backendpath
[index
].vlnk_add
== 0)
2739 len
= grub_strlen(path
);
2740 if (len
> 9 && grub_strncmp(path
+ len
- 9, ".vlnk.dat", 9) == 0)
2742 ventoy_add_vlnk_file(NULL
, path
);
2743 node
->backendpath
[index
].vlnk_add
= 1;
2747 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, path
);
2750 debug("Failed to open file %s%s\n", g_iso_disk_name
, path
);
2754 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2755 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2756 if (NULL
== chunk_list
->chunk
)
2761 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2762 chunk_list
->cur_chunk
= 0;
2764 start
= file
->device
->disk
->partition
->start
;
2765 ventoy_get_block_list(file
, chunk_list
, start
);
2767 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2769 grub_free(chunk_list
->chunk
);
2770 chunk_list
->chunk
= NULL
;
2778 grub_file_close(file
);
2783 const char * ventoy_plugin_get_injection(const char *isopath
)
2786 injection_config
*node
= NULL
;
2788 if (!g_injection_head
)
2793 len
= (int)grub_strlen(isopath
);
2794 for (node
= g_injection_head
; node
; node
= node
->next
)
2796 if (node
->type
== injection_type_file
)
2798 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2800 return node
->archive
;
2805 for (node
= g_injection_head
; node
; node
= node
->next
)
2807 if (node
->type
== injection_type_parent
)
2809 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2811 return node
->archive
;
2819 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2822 menu_alias
*node
= NULL
;
2824 if (!g_menu_alias_head
)
2829 len
= (int)grub_strlen(isopath
);
2830 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2832 if (node
->type
== type
&& node
->pathlen
&&
2833 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2842 const menu_tip
* ventoy_plugin_get_menu_tip(int type
, const char *isopath
)
2845 menu_tip
*node
= NULL
;
2847 if (!g_menu_tip_head
)
2852 len
= (int)grub_strlen(isopath
);
2853 for (node
= g_menu_tip_head
; node
; node
= node
->next
)
2855 if (node
->type
== type
&& node
->pathlen
&&
2856 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2865 const char * ventoy_plugin_get_menu_class(int type
, const char *name
, const char *path
)
2869 menu_class
*node
= NULL
;
2871 if (!g_menu_class_head
)
2876 namelen
= (int)grub_strlen(name
);
2877 pathlen
= (int)grub_strlen(path
);
2879 if (vtoy_class_image_file
== type
)
2881 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2883 if (node
->type
!= type
)
2888 if (node
->parent
== 0)
2890 if ((node
->patlen
< namelen
) && grub_strstr(name
, node
->pattern
))
2897 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2899 if (node
->type
!= type
)
2906 if ((node
->patlen
< pathlen
) && ventoy_plugin_is_parent(node
->pattern
, node
->patlen
, path
))
2915 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2917 if (node
->type
== type
&& node
->patlen
== namelen
&& grub_strncmp(name
, node
->pattern
, namelen
) == 0)
2927 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2930 custom_boot
*node
= NULL
;
2932 node
= grub_zalloc(sizeof(custom_boot
));
2935 node
->type
= vtoy_custom_boot_image_file
;
2936 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2937 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2940 len
= node
->pathlen
- 5;
2941 node
->path
[len
] = 0;
2942 node
->pathlen
= len
;
2944 if (g_custom_boot_head
)
2946 node
->next
= g_custom_boot_head
;
2948 g_custom_boot_head
= node
;
2954 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2958 custom_boot
*node
= NULL
;
2960 if (!g_custom_boot_head
)
2965 len
= (int)grub_strlen(isopath
);
2967 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2969 if (node
->type
== vtoy_custom_boot_image_file
)
2971 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2978 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2979 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2981 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2983 if (isopath
[i
] == '/')
3000 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3002 custom_boot
*node
= NULL
;
3008 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
3010 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
3011 node
->path
, node
->cfg
);
3017 int ventoy_plugin_check_memdisk(const char *isopath
)
3020 auto_memdisk
*node
= NULL
;
3022 if (!g_auto_memdisk_head
)
3027 len
= (int)grub_strlen(isopath
);
3028 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
3030 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
3039 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
3043 image_list
*node
= NULL
;
3045 if (!g_image_list_head
)
3050 len
= (int)grub_strlen(name
);
3052 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
3054 if (vtoy_class_directory
== type
)
3056 if (len
< node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
3063 if (len
== node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
3073 int ventoy_plugin_find_conf_replace(const char *iso
, conf_replace
*nodes
[VTOY_MAX_CONF_REPLACE
])
3079 if (!g_conf_replace_head
)
3084 len
= (int)grub_strlen(iso
);
3086 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
3088 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
3091 if (n
>= VTOY_MAX_CONF_REPLACE
)
3101 dud
* ventoy_plugin_find_dud(const char *iso
)
3111 len
= (int)grub_strlen(iso
);
3112 for (node
= g_dud_head
; node
; node
= node
->next
)
3114 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
3123 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
3129 for (i
= 0; i
< node
->dudnum
; i
++)
3131 if (node
->files
[i
].size
> 0)
3133 debug("file %d has been loaded\n", i
);
3137 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
3140 buf
= grub_malloc(file
->size
);
3143 grub_file_read(file
, buf
, file
->size
);
3144 node
->files
[i
].size
= (int)file
->size
;
3145 node
->files
[i
].buf
= buf
;
3147 grub_file_close(file
);
3154 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
3158 const char *pos
= NULL
;
3159 menu_password
*node
= NULL
;
3168 len
= (int)grub_strlen(isopath
);
3169 for (node
= g_pwd_head
; node
; node
= node
->next
)
3171 if (node
->type
== vtoy_menu_pwd_file
)
3173 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
3175 return &(node
->password
);
3180 for (node
= g_pwd_head
; node
; node
= node
->next
)
3182 if (node
->type
== vtoy_menu_pwd_parent
)
3184 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
3186 return &(node
->password
);
3194 if (*isopath
== '.')
3203 for (i
= 0; i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
3205 if (g_file_type_pwd
[i
].type
&& 0 == grub_strcasecmp(pos
+ 1, g_menu_prefix
[i
]))
3207 return g_file_type_pwd
+ i
;
3215 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3218 const vtoy_password
*pwd
= NULL
;
3223 pwd
= ventoy_plugin_get_password(args
[0]);
3226 if (0 == ventoy_check_password(pwd
, 1))
3244 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3251 VTOY_JSON
*node
= NULL
;
3252 VTOY_JSON
*json
= NULL
;
3261 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
3264 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
3265 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
3269 buf
= grub_malloc(file
->size
+ 1);
3272 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
3276 buf
[file
->size
] = 0;
3277 grub_file_read(file
, buf
, file
->size
);
3279 json
= vtoy_json_create();
3282 grub_printf("Failed to create json\n");
3286 ret
= vtoy_json_parse(json
, buf
);
3289 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
3293 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
3294 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
3296 if (grub_strcmp(node
->pcName
, key
) == 0)
3304 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
3306 if (grub_strcmp(node
->pcName
, args
[1]) == 0)
3314 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
3319 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
3321 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
3323 if (g_plugin_entries
[i
].checkfunc
)
3325 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
3332 check_free(file
, grub_file_close
);
3333 check_free(json
, vtoy_json_destroy
);
3334 grub_check_free(buf
);
3339 grub_err_t
ventoy_cmd_select_theme_cfg(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3345 theme_list
*node
= NULL
;
3351 if (g_theme_single_file
[0])
3356 if (g_theme_num
< 2)
3361 bufsize
= (g_theme_num
+ 1) * 1024;
3362 buf
= grub_malloc(bufsize
);
3368 for (node
= g_theme_head
; node
; node
= node
->next
)
3370 name
= grub_strstr(node
->theme
.path
, ")/");
3377 name
= node
->theme
.path
;
3380 pos
+= grub_snprintf(buf
+ pos
, bufsize
- pos
,
3381 "menuentry \"%s\" --class=debug_theme_item --class=debug_theme_select --class=F5tool {\n"
3382 "vt_set_theme_path \"%s\"\n"
3384 name
, node
->theme
.path
);
3387 pos
+= grub_snprintf(buf
+ pos
, bufsize
- pos
,
3388 "menuentry \"$VTLANG_RETURN_PREVIOUS\" --class=vtoyret VTOY_RET {\n"
3389 "echo 'Return ...'\n"
3392 grub_script_execute_sourcecode(buf
);
3398 extern char g_ventoy_theme_path
[256];
3400 grub_err_t
ventoy_cmd_set_theme(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3402 grub_uint32_t i
= 0;
3403 grub_uint32_t mod
= 0;
3404 grub_uint32_t theme_num
= 0;
3405 theme_list
*node
= g_theme_head
;
3406 struct grub_datetime datetime
;
3407 struct grub_video_mode_info info
;
3409 char **pThemePath
= NULL
;
3415 if (g_theme_single_file
[0])
3417 debug("single theme %s\n", g_theme_single_file
);
3418 grub_env_set("theme", g_theme_single_file
);
3422 debug("g_theme_num = %d\n", g_theme_num
);
3424 if (g_theme_num
== 0)
3429 if (g_theme_id
> 0 && g_theme_id
<= g_theme_num
)
3431 for (i
= 0; i
< (grub_uint32_t
)(g_theme_id
- 1) && node
; i
++)
3436 grub_env_set("theme", node
->theme
.path
);
3440 pThemePath
= (char **)grub_zalloc(sizeof(char *) * g_theme_num
);
3446 if (g_theme_res_fit
)
3448 if (grub_video_get_info(&info
) == GRUB_ERR_NONE
)
3450 debug("get video info success %ux%u\n", info
.width
, info
.height
);
3451 grub_snprintf(buf
, sizeof(buf
), "%ux%u", info
.width
, info
.height
);
3452 for (node
= g_theme_head
; node
; node
= node
->next
)
3454 if (grub_strstr(node
->theme
.path
, buf
))
3456 pThemePath
[theme_num
++] = node
->theme
.path
;
3464 for (node
= g_theme_head
; node
; node
= node
->next
)
3466 pThemePath
[theme_num
++] = node
->theme
.path
;
3473 debug("Only 1 theme match, no need to random.\n");
3477 grub_memset(&datetime
, 0, sizeof(datetime
));
3478 grub_get_datetime(&datetime
);
3480 if (g_theme_random
== vtoy_theme_random_boot_second
)
3482 grub_divmod32((grub_uint32_t
)datetime
.second
, theme_num
, &mod
);
3484 else if (g_theme_random
== vtoy_theme_random_boot_day
)
3486 grub_divmod32((grub_uint32_t
)datetime
.day
, theme_num
, &mod
);
3488 else if (g_theme_random
== vtoy_theme_random_boot_month
)
3490 grub_divmod32((grub_uint32_t
)datetime
.month
, theme_num
, &mod
);
3493 debug("%04d/%02d/%02d %02d:%02d:%02d theme_num:%d mod:%d\n",
3494 datetime
.year
, datetime
.month
, datetime
.day
,
3495 datetime
.hour
, datetime
.minute
, datetime
.second
,
3499 if (argc
> 0 && grub_strcmp(args
[0], "switch") == 0)
3501 grub_snprintf(g_ventoy_theme_path
, sizeof(g_ventoy_theme_path
), "%s", pThemePath
[mod
]);
3505 debug("random theme %s\n", pThemePath
[mod
]);
3506 grub_env_set("theme", pThemePath
[mod
]);
3508 g_ventoy_menu_refresh
= 1;
3512 grub_check_free(pThemePath
);
3513 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
3516 grub_err_t
ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3523 g_ventoy_theme_path
[0] = 0;
3527 grub_snprintf(g_ventoy_theme_path
, sizeof(g_ventoy_theme_path
), "%s", args
[0]);
3530 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
3533 const char *ventoy_get_vmenu_title(const char *vMenu
)
3535 return vtoy_json_get_string_ex(g_menu_lang_json
->pstChild
, vMenu
);
3538 int ventoy_plugin_load_menu_lang(int init
, const char *lang
)
3541 grub_file_t file
= NULL
;
3544 if (grub_strcmp(lang
, g_cur_menu_language
) == 0)
3546 debug("Same menu lang %s\n", lang
);
3549 grub_snprintf(g_cur_menu_language
, sizeof(g_cur_menu_language
), "%s", lang
);
3551 debug("Load menu lang %s\n", g_cur_menu_language
);
3553 if (g_menu_lang_json
)
3555 vtoy_json_destroy(g_menu_lang_json
);
3556 g_menu_lang_json
= NULL
;
3559 g_menu_lang_json
= vtoy_json_create();
3560 if (!g_menu_lang_json
)
3565 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "(vt_menu_tarfs)/menu/%s.json", lang
);
3571 buf
= grub_malloc(file
->size
+ 1);
3574 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
3578 buf
[file
->size
] = 0;
3579 grub_file_read(file
, buf
, file
->size
);
3581 vtoy_json_parse(g_menu_lang_json
, buf
);
3583 if (g_default_menu_mode
== 0)
3585 grub_snprintf(g_ventoy_hotkey_tip
, sizeof(g_ventoy_hotkey_tip
), "%s", ventoy_get_vmenu_title("VTLANG_STR_HOTKEY_TREE"));
3589 grub_snprintf(g_ventoy_hotkey_tip
, sizeof(g_ventoy_hotkey_tip
), "%s", ventoy_get_vmenu_title("VTLANG_STR_HOTKEY_LIST"));
3594 ventoy_menu_push_key(GRUB_TERM_ESC
);
3595 ventoy_menu_push_key(GRUB_TERM_ESC
);
3596 g_ventoy_menu_refresh
= 1;
3602 check_free(file
, grub_file_close
);
3603 grub_check_free(buf
);
3608 grub_err_t
ventoy_cmd_cur_menu_lang(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3615 grub_env_set(args
[0], g_cur_menu_language
);
3619 grub_printf("%s\n", g_cur_menu_language
);
3620 grub_printf("%s\n", g_ventoy_hotkey_tip
);
3624 VENTOY_CMD_RETURN(0);