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
;
60 static int g_theme_id
= 0;
61 static int g_theme_num
= 0;
62 static theme_list
*g_theme_head
= NULL
;
63 static int g_theme_random
= vtoy_theme_random_boot_second
;
64 static char g_theme_single_file
[256];
66 static int ventoy_plugin_is_parent(const char *pat
, int patlen
, const char *isopath
)
70 if (isopath
[patlen
] == '/' && ventoy_strncmp(pat
, isopath
, patlen
) == 0 &&
71 grub_strchr(isopath
+ patlen
+ 1, '/') == NULL
)
78 if (pat
[0] == '/' && grub_strchr(isopath
+ 1, '/') == NULL
)
87 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
90 VTOY_JSON
*pNode
= NULL
;
91 VTOY_JSON
*pChild
= NULL
;
95 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
97 grub_printf("Not array type %d\n", json
->enDataType
);
101 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
103 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
105 pChild
= pNode
->pstChild
;
106 if (pChild
->enDataType
== JSON_TYPE_STRING
)
108 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
110 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
111 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
115 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
120 grub_printf("%s is NOT string type\n", pChild
->pcName
);
126 grub_printf("%s is not an object\n", pNode
->pcName
);
134 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
136 VTOY_JSON
*pNode
= NULL
;
137 VTOY_JSON
*pChild
= NULL
;
141 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
143 debug("Not array %d\n", json
->enDataType
);
147 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
149 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
151 pChild
= pNode
->pstChild
;
152 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
154 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
162 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
168 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
171 grub_printf("file: %s\n", value
);
174 exist
= ventoy_check_file_exist("%s%s", isodisk
, value
);
178 exist
= ventoy_check_file_exist("%s/ventoy/%s", isodisk
, value
);
183 grub_printf("Theme file %s does NOT exist\n", value
);
189 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
192 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
194 value
= node
->unData
.pcStrVal
;
195 grub_printf("file: %s\n", value
);
198 exist
= ventoy_check_file_exist("%s%s", isodisk
, value
);
202 exist
= ventoy_check_file_exist("%s/ventoy/%s", isodisk
, value
);
207 grub_printf("Theme file %s does NOT exist\n", value
);
212 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
215 grub_printf("random: %s\n", value
);
220 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
223 grub_printf("gfxmode: %s\n", value
);
226 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
229 grub_printf("display_mode: %s\n", value
);
232 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
235 grub_printf("serial_param %s\n", value
);
238 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
241 grub_printf("ventoy_left: %s\n", value
);
244 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
247 grub_printf("ventoy_top: %s\n", value
);
250 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
253 grub_printf("ventoy_color: %s\n", value
);
256 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
259 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
261 if (node
->enDataType
== JSON_TYPE_STRING
)
263 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
265 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
269 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
276 grub_printf("fonts NOT found\n");
282 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
287 VTOY_JSON
*node
= NULL
;
288 theme_list
*tail
= NULL
;
289 theme_list
*themenode
= NULL
;
291 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
296 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
300 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
303 if (ventoy_check_file_exist(filepath
) == 0)
305 debug("Theme file %s does not exist\n", filepath
);
309 debug("vtoy_theme %s\n", filepath
);
310 ventoy_env_export("vtoy_theme", filepath
);
311 grub_snprintf(g_theme_single_file
, sizeof(g_theme_single_file
), "%s", filepath
);
315 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
318 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
320 value
= node
->unData
.pcStrVal
;
323 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
327 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
330 if (ventoy_check_file_exist(filepath
) == 0)
335 themenode
= grub_zalloc(sizeof(theme_list
));
338 grub_snprintf(themenode
->theme
.path
, sizeof(themenode
->theme
.path
), "%s", filepath
);
341 tail
->next
= themenode
;
345 g_theme_head
= themenode
;
352 ventoy_env_export("vtoy_theme", "random");
353 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
356 if (grub_strcmp(value
, "boot_second") == 0)
358 g_theme_random
= vtoy_theme_random_boot_second
;
360 else if (grub_strcmp(value
, "boot_day") == 0)
362 g_theme_random
= vtoy_theme_random_boot_day
;
364 else if (grub_strcmp(value
, "boot_month") == 0)
366 g_theme_random
= vtoy_theme_random_boot_month
;
372 grub_snprintf(val
, sizeof(val
), "%d", g_theme_num
);
373 grub_env_set("VTOY_THEME_COUNT", val
);
374 grub_env_export("VTOY_THEME_COUNT");
377 vtoy_json_get_int(json
->pstChild
, "default_file", &g_theme_id
);
378 if (g_theme_id
> g_theme_num
|| g_theme_id
< 0)
384 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
387 debug("vtoy_gfxmode %s\n", value
);
388 ventoy_env_export("vtoy_gfxmode", value
);
391 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
394 debug("display_mode %s\n", value
);
395 ventoy_env_export("vtoy_display_mode", value
);
398 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
401 debug("serial_param %s\n", value
);
402 ventoy_env_export("vtoy_serial_param", value
);
405 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
408 ventoy_env_export("VTLE_LFT", value
);
411 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
414 ventoy_env_export("VTLE_TOP", value
);
417 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
420 ventoy_env_export("VTLE_CLR", value
);
423 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
426 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
428 if (node
->enDataType
== JSON_TYPE_STRING
&&
429 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
431 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
432 grub_font_load(filepath
);
440 static int ventoy_plugin_check_path(const char *path
, const char *file
)
444 grub_printf("%s is NOT begin with '/' \n", file
);
448 if (grub_strchr(file
, '\\'))
450 grub_printf("%s contains invalid '\\' \n", file
);
454 if (grub_strstr(file
, "//"))
456 grub_printf("%s contains invalid double slash\n", file
);
460 if (grub_strstr(file
, "../"))
462 grub_printf("%s contains invalid '../' \n", file
);
466 if (!ventoy_check_file_exist("%s%s", path
, file
))
468 grub_printf("%s%s does NOT exist\n", path
, file
);
475 static int ventoy_plugin_check_fullpath
486 VTOY_JSON
*node
= json
;
487 VTOY_JSON
*child
= NULL
;
491 if (0 == grub_strcmp(key
, node
->pcName
))
495 node
= node
->pstNext
;
503 if (JSON_TYPE_STRING
== node
->enDataType
)
506 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
507 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
509 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
511 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
513 if (JSON_TYPE_STRING
!= child
->enDataType
)
515 grub_printf("Non string json type\n");
519 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
520 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
531 static int ventoy_plugin_parse_fullpath
536 file_fullpath
**fullpath
,
542 VTOY_JSON
*node
= json
;
543 VTOY_JSON
*child
= NULL
;
544 file_fullpath
*path
= NULL
;
548 if (0 == grub_strcmp(key
, node
->pcName
))
552 node
= node
->pstNext
;
560 if (JSON_TYPE_STRING
== node
->enDataType
)
562 debug("%s is string type data\n", node
->pcName
);
564 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
566 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
570 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
573 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
579 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
581 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
583 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
585 debug("Invalid data type:%d\n", child
->enDataType
);
590 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
592 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
597 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
599 if (ventoy_check_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
601 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
615 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
621 const char *iso
= NULL
;
622 VTOY_JSON
*pNode
= NULL
;
624 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
626 grub_printf("Not array type %d\n", json
->enDataType
);
630 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
632 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
634 grub_printf("NOT object type\n");
637 if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image")) != NULL
)
639 pos
= grub_strchr(iso
, '*');
640 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
642 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
643 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
645 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
647 if (autosel
>= 0 && autosel
<= pathnum
)
649 grub_printf("autosel: %d [OK]\n", autosel
);
653 grub_printf("autosel: %d [FAIL]\n", autosel
);
657 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
661 grub_printf("timeout: %d [OK]\n", timeout
);
665 grub_printf("timeout: %d [FAIL]\n", timeout
);
671 grub_printf("image: %s [FAIL]\n", iso
);
674 else if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent")) != NULL
)
676 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
678 grub_printf("parent: %s [OK]\n", iso
);
679 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
681 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
683 if (autosel
>= 0 && autosel
<= pathnum
)
685 grub_printf("autosel: %d [OK]\n", autosel
);
689 grub_printf("autosel: %d [FAIL]\n", autosel
);
693 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
697 grub_printf("timeout: %d [OK]\n", timeout
);
701 grub_printf("timeout: %d [FAIL]\n", timeout
);
707 grub_printf("parent: %s [FAIL]\n", iso
);
712 grub_printf("image not found\n");
719 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
725 const char *iso
= NULL
;
726 VTOY_JSON
*pNode
= NULL
;
727 install_template
*node
= NULL
;
728 install_template
*next
= NULL
;
729 file_fullpath
*templatepath
= NULL
;
731 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
733 debug("Not array %d\n", json
->enDataType
);
737 if (g_install_template_head
)
739 for (node
= g_install_template_head
; node
; node
= next
)
742 grub_check_free(node
->templatepath
);
746 g_install_template_head
= NULL
;
749 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
751 type
= auto_install_type_file
;
752 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
755 type
= auto_install_type_parent
;
756 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
759 if (iso
&& iso
[0] == '/')
761 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
763 node
= grub_zalloc(sizeof(install_template
));
767 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
768 node
->templatepath
= templatepath
;
769 node
->templatenum
= pathnum
;
773 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
775 if (autosel
>= 0 && autosel
<= pathnum
)
777 node
->autosel
= autosel
;
781 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
785 node
->timeout
= timeout
;
789 if (g_install_template_head
)
791 node
->next
= g_install_template_head
;
794 g_install_template_head
= node
;
803 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
807 const char *iso
= NULL
;
808 VTOY_JSON
*pNode
= NULL
;
810 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
812 grub_printf("Not array type %d\n", json
->enDataType
);
816 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
818 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
820 grub_printf("NOT object type\n");
823 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
826 pos
= grub_strchr(iso
, '*');
827 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
829 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
830 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
834 grub_printf("image: %s [FAIL]\n", iso
);
839 grub_printf("image not found\n");
846 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
849 const char *iso
= NULL
;
850 VTOY_JSON
*pNode
= NULL
;
853 file_fullpath
*dudpath
= NULL
;
855 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
857 debug("Not array %d\n", json
->enDataType
);
863 for (node
= g_dud_head
; node
; node
= next
)
866 grub_check_free(node
->dudpath
);
873 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
875 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
876 if (iso
&& iso
[0] == '/')
878 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "dud", &dudpath
, &pathnum
))
880 node
= grub_zalloc(sizeof(dud
));
883 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
884 node
->dudpath
= dudpath
;
885 node
->dudnum
= pathnum
;
886 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
892 node
->next
= g_dud_head
;
909 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
916 vtoy_password tmpPwd
;
918 len
= (int)grub_strlen(pwdstr
);
921 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
925 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
927 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
929 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
930 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
932 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
936 for (i
= 0; i
< 16; i
++)
938 bytes
[0] = pwdstr
[4 + i
* 2];
939 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
942 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
944 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
948 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
952 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
954 else if ((len
- 4) > 32)
956 pos
= grub_strchr(pwdstr
+ 4, '#');
959 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
963 if (len
- 1 - (int)(long)(pos
- pwdstr
) != 32)
965 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
971 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
975 for (i
= 0; i
< 16; i
++)
977 bytes
[0] = pos
[i
* 2];
978 bytes
[1] = pos
[i
* 2 + 1];
981 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
983 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
987 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
992 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
996 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
1002 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
1008 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
1014 static int ventoy_plugin_get_pwd_type(const char *pwd
)
1019 for (i
= 0; pwd
&& i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
1021 grub_snprintf(pwdtype
, sizeof(pwdtype
), "%spwd", g_menu_prefix
[i
]);
1022 if (grub_strcmp(pwdtype
, pwd
) == 0)
1024 return img_type_start
+ i
;
1031 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
1034 const char *iso
= NULL
;
1035 const char *pwd
= NULL
;
1036 VTOY_JSON
*pNode
= NULL
;
1037 VTOY_JSON
*pCNode
= NULL
;
1038 menu_password
*node
= NULL
;
1039 menu_password
*tail
= NULL
;
1040 menu_password
*next
= NULL
;
1044 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1046 debug("Not object %d\n", json
->enDataType
);
1052 for (node
= g_pwd_head
; node
; node
= next
)
1061 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1063 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1065 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
1067 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1069 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, g_file_type_pwd
+ type
);
1071 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1073 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1075 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1080 type
= vtoy_menu_pwd_file
;
1081 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
1084 type
= vtoy_menu_pwd_parent
;
1085 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent");
1088 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1089 if (iso
&& pwd
&& iso
[0] == '/')
1091 node
= grub_zalloc(sizeof(menu_password
));
1095 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1097 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
1121 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
1125 const char *iso
= NULL
;
1126 const char *pwd
= NULL
;
1127 VTOY_JSON
*pNode
= NULL
;
1128 VTOY_JSON
*pCNode
= NULL
;
1130 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1132 grub_printf("Not object %d\n", json
->enDataType
);
1136 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1138 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1140 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1142 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
1146 grub_printf("Invalid bootpwd.\n");
1149 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1151 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1153 grub_printf("%s:<%s>\n", pNode
->pcName
, pNode
->unData
.pcStrVal
);
1157 grub_printf("Invalid pwd <%s>\n", pNode
->unData
.pcStrVal
);
1160 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1163 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1165 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1167 grub_printf("Not object %d\n", pCNode
->enDataType
);
1171 if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file")) != NULL
)
1173 pos
= grub_strchr(iso
, '*');
1174 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1176 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1178 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1180 grub_printf("file:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1181 grub_printf("pwd:<%s>\n\n", pwd
);
1185 grub_printf("Invalid password for <%s>\n", iso
);
1190 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1193 else if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent")) != NULL
)
1195 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
1197 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1198 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1200 grub_printf("dir:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1201 grub_printf("pwd:<%s>\n\n", pwd
);
1205 grub_printf("Invalid password for <%s>\n", iso
);
1210 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1215 grub_printf("No file item found in json.\n");
1224 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
1230 const char *iso
= NULL
;
1231 VTOY_JSON
*pNode
= NULL
;
1233 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1235 grub_printf("Not array type %d\n", json
->enDataType
);
1239 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1241 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
1243 grub_printf("NOT object type\n");
1246 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1249 pos
= grub_strchr(iso
, '*');
1250 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1252 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
1253 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
1255 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1257 if (autosel
>= 0 && autosel
<= pathnum
)
1259 grub_printf("autosel: %d [OK]\n", autosel
);
1263 grub_printf("autosel: %d [FAIL]\n", autosel
);
1267 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
1271 grub_printf("timeout: %d [OK]\n", timeout
);
1275 grub_printf("timeout: %d [FAIL]\n", timeout
);
1281 grub_printf("image: %s [FAIL]\n", iso
);
1286 grub_printf("image not found\n");
1293 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1298 const char *iso
= NULL
;
1299 VTOY_JSON
*pNode
= NULL
;
1300 persistence_config
*node
= NULL
;
1301 persistence_config
*next
= NULL
;
1302 file_fullpath
*backendpath
= NULL
;
1306 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1308 debug("Not array %d\n", json
->enDataType
);
1312 if (g_persistence_head
)
1314 for (node
= g_persistence_head
; node
; node
= next
)
1317 grub_check_free(node
->backendpath
);
1321 g_persistence_head
= NULL
;
1324 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1326 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1327 if (iso
&& iso
[0] == '/')
1329 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1331 node
= grub_zalloc(sizeof(persistence_config
));
1334 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1335 node
->backendpath
= backendpath
;
1336 node
->backendnum
= pathnum
;
1340 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1342 if (autosel
>= 0 && autosel
<= pathnum
)
1344 node
->autosel
= autosel
;
1348 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
1352 node
->timeout
= timeout
;
1356 if (g_persistence_head
)
1358 node
->next
= g_persistence_head
;
1361 g_persistence_head
= node
;
1370 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1373 const char *path
= NULL
;
1374 const char *alias
= NULL
;
1375 VTOY_JSON
*pNode
= NULL
;
1379 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1381 grub_printf("Not array %d\n", json
->enDataType
);
1385 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1387 type
= vtoy_alias_image_file
;
1388 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1391 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1392 type
= vtoy_alias_directory
;
1395 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1396 if (path
&& path
[0] == '/' && alias
)
1398 if (vtoy_alias_image_file
== type
)
1400 if (grub_strchr(path
, '*'))
1402 grub_printf("image: <%s> [ * ]\n", path
);
1404 else if (ventoy_check_file_exist("%s%s", isodisk
, path
))
1406 grub_printf("image: <%s> [ OK ]\n", path
);
1410 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1415 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1417 grub_printf("dir: <%s> [ OK ]\n", path
);
1421 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1425 grub_printf("alias: <%s>\n\n", alias
);
1432 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1435 const char *path
= NULL
;
1436 const char *alias
= NULL
;
1437 VTOY_JSON
*pNode
= NULL
;
1438 menu_alias
*node
= NULL
;
1439 menu_alias
*next
= NULL
;
1443 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1445 debug("Not array %d\n", json
->enDataType
);
1449 if (g_menu_alias_head
)
1451 for (node
= g_menu_alias_head
; node
; node
= next
)
1457 g_menu_alias_head
= NULL
;
1460 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1462 type
= vtoy_alias_image_file
;
1463 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1466 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1467 type
= vtoy_alias_directory
;
1470 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1471 if (path
&& path
[0] == '/' && alias
)
1473 node
= grub_zalloc(sizeof(menu_alias
));
1477 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1478 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1480 if (g_menu_alias_head
)
1482 node
->next
= g_menu_alias_head
;
1485 g_menu_alias_head
= node
;
1493 static int ventoy_plugin_menutip_check(VTOY_JSON
*json
, const char *isodisk
)
1496 const char *path
= NULL
;
1497 const char *tip
= NULL
;
1498 VTOY_JSON
*pNode
= NULL
;
1502 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1504 grub_printf("Not object %d\n", json
->enDataType
);
1508 tip
= vtoy_json_get_string_ex(json
->pstChild
, "left");
1511 grub_printf("left: <%s>\n", tip
);
1514 tip
= vtoy_json_get_string_ex(json
->pstChild
, "top");
1517 grub_printf("top: <%s>\n", tip
);
1520 tip
= vtoy_json_get_string_ex(json
->pstChild
, "color");
1523 grub_printf("color: <%s>\n", tip
);
1526 pNode
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "tips");
1527 for (pNode
= pNode
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1529 type
= vtoy_tip_image_file
;
1530 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1533 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1534 type
= vtoy_tip_directory
;
1537 if (path
&& path
[0] == '/')
1539 if (vtoy_tip_image_file
== type
)
1541 if (grub_strchr(path
, '*'))
1543 grub_printf("image: <%s> [ * ]\n", path
);
1545 else if (ventoy_check_file_exist("%s%s", isodisk
, path
))
1547 grub_printf("image: <%s> [ OK ]\n", path
);
1551 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1556 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1558 grub_printf("dir: <%s> [ OK ]\n", path
);
1562 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1566 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip");
1569 grub_printf("tip: <%s>\n", tip
);
1573 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip1");
1575 grub_printf("tip1: <%s>\n", tip
);
1577 grub_printf("tip1: <NULL>\n");
1579 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip2");
1581 grub_printf("tip2: <%s>\n", tip
);
1583 grub_printf("tip2: <NULL>\n");
1588 grub_printf("image: <%s> [ INVALID ]\n", path
);
1595 static int ventoy_plugin_menutip_entry(VTOY_JSON
*json
, const char *isodisk
)
1598 const char *path
= NULL
;
1599 const char *tip
= NULL
;
1600 VTOY_JSON
*pNode
= NULL
;
1601 menu_tip
*node
= NULL
;
1602 menu_tip
*next
= NULL
;
1606 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1608 debug("Not object %d\n", json
->enDataType
);
1612 pNode
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "tips");
1615 debug("Not tips found\n");
1619 if (g_menu_tip_head
)
1621 for (node
= g_menu_tip_head
; node
; node
= next
)
1627 g_menu_tip_head
= NULL
;
1630 tip
= vtoy_json_get_string_ex(json
->pstChild
, "left");
1633 grub_env_set("VTOY_TIP_LEFT", tip
);
1636 tip
= vtoy_json_get_string_ex(json
->pstChild
, "top");
1639 grub_env_set("VTOY_TIP_TOP", tip
);
1642 tip
= vtoy_json_get_string_ex(json
->pstChild
, "color");
1645 grub_env_set("VTOY_TIP_COLOR", tip
);
1648 for (pNode
= pNode
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1650 type
= vtoy_tip_image_file
;
1651 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1654 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1655 type
= vtoy_tip_directory
;
1658 if (path
&& path
[0] == '/')
1660 node
= grub_zalloc(sizeof(menu_tip
));
1664 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1666 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip");
1669 grub_snprintf(node
->tip1
, 1000, "%s", tip
);
1673 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip1");
1675 grub_snprintf(node
->tip1
, 1000, "%s", tip
);
1677 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip2");
1679 grub_snprintf(node
->tip2
, 1000, "%s", tip
);
1682 if (g_menu_tip_head
)
1684 node
->next
= g_menu_tip_head
;
1687 g_menu_tip_head
= node
;
1695 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1698 const char *path
= NULL
;
1699 const char *archive
= NULL
;
1700 VTOY_JSON
*pNode
= NULL
;
1704 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1706 grub_printf("Not array %d\n", json
->enDataType
);
1710 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1712 type
= injection_type_file
;
1713 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1716 type
= injection_type_parent
;
1717 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1720 grub_printf("image/parent not found\n");
1725 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1728 grub_printf("archive not found\n");
1732 if (type
== injection_type_file
)
1734 if (grub_strchr(path
, '*'))
1736 grub_printf("image: <%s> [*]\n", path
);
1740 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1745 grub_printf("parent: <%s> [%s]\n", path
,
1746 ventoy_is_dir_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1749 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1755 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1758 const char *path
= NULL
;
1759 const char *archive
= NULL
;
1760 VTOY_JSON
*pNode
= NULL
;
1761 injection_config
*node
= NULL
;
1762 injection_config
*next
= NULL
;
1766 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1768 debug("Not array %d\n", json
->enDataType
);
1772 if (g_injection_head
)
1774 for (node
= g_injection_head
; node
; node
= next
)
1780 g_injection_head
= NULL
;
1783 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1785 type
= injection_type_file
;
1786 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1789 type
= injection_type_parent
;
1790 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1793 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1794 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1796 node
= grub_zalloc(sizeof(injection_config
));
1800 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1801 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1803 if (g_injection_head
)
1805 node
->next
= g_injection_head
;
1808 g_injection_head
= node
;
1816 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1820 const char *key
= NULL
;
1821 const char *class = NULL
;
1822 VTOY_JSON
*pNode
= NULL
;
1823 menu_class
*tail
= NULL
;
1824 menu_class
*node
= NULL
;
1825 menu_class
*next
= NULL
;
1829 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1831 debug("Not array %d\n", json
->enDataType
);
1835 if (g_menu_class_head
)
1837 for (node
= g_menu_class_head
; node
; node
= next
)
1843 g_menu_class_head
= NULL
;
1846 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1849 type
= vtoy_class_image_file
;
1850 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1853 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1860 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1861 type
= vtoy_class_directory
;
1865 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1868 node
= grub_zalloc(sizeof(menu_class
));
1872 node
->parent
= parent
;
1873 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1874 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1876 if (g_menu_class_head
)
1882 g_menu_class_head
= node
;
1892 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1894 const char *name
= NULL
;
1895 const char *key
= NULL
;
1896 const char *class = NULL
;
1897 VTOY_JSON
*pNode
= NULL
;
1901 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1903 grub_printf("Not array %d\n", json
->enDataType
);
1907 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1910 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1914 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1918 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1922 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1925 grub_printf("%s: <%s>\n", name
, key
);
1926 grub_printf("class: <%s>\n\n", class);
1933 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1937 const char *key
= NULL
;
1938 const char *cfg
= NULL
;
1939 VTOY_JSON
*pNode
= NULL
;
1940 custom_boot
*tail
= NULL
;
1941 custom_boot
*node
= NULL
;
1942 custom_boot
*next
= NULL
;
1946 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1948 debug("Not array %d\n", json
->enDataType
);
1952 if (g_custom_boot_head
)
1954 for (node
= g_custom_boot_head
; node
; node
= next
)
1960 g_custom_boot_head
= NULL
;
1963 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1965 type
= vtoy_custom_boot_image_file
;
1966 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1969 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1970 type
= vtoy_custom_boot_directory
;
1973 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1976 node
= grub_zalloc(sizeof(custom_boot
));
1980 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1981 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1983 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
1985 if (g_custom_boot_head
)
1991 g_custom_boot_head
= node
;
2006 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
2010 const char *key
= NULL
;
2011 const char *cfg
= NULL
;
2012 VTOY_JSON
*pNode
= NULL
;
2016 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2018 grub_printf("Not array %d\n", json
->enDataType
);
2022 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2024 type
= vtoy_custom_boot_image_file
;
2025 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
2028 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
2029 type
= vtoy_custom_boot_directory
;
2032 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
2033 len
= (int)grub_strlen(cfg
);
2036 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
2038 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
2042 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
2043 grub_printf("vcfg: <%s>\n\n", cfg
);
2051 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
2054 const char *isof
= NULL
;
2055 const char *orgf
= NULL
;
2056 const char *newf
= NULL
;
2057 VTOY_JSON
*pNode
= NULL
;
2058 conf_replace
*tail
= NULL
;
2059 conf_replace
*node
= NULL
;
2060 conf_replace
*next
= NULL
;
2064 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2066 debug("Not array %d\n", json
->enDataType
);
2070 if (g_conf_replace_head
)
2072 for (node
= g_conf_replace_head
; node
; node
= next
)
2078 g_conf_replace_head
= NULL
;
2081 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2083 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
2084 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
2085 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
2086 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
2088 node
= grub_zalloc(sizeof(conf_replace
));
2091 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "img", &img
))
2096 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
2097 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
2098 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
2100 if (g_conf_replace_head
)
2106 g_conf_replace_head
= node
;
2116 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
2119 const char *isof
= NULL
;
2120 const char *orgf
= NULL
;
2121 const char *newf
= NULL
;
2122 VTOY_JSON
*pNode
= NULL
;
2123 grub_file_t file
= NULL
;
2128 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2130 grub_printf("Not array %d\n", json
->enDataType
);
2134 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2136 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
2137 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
2138 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
2139 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
2141 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
2143 grub_printf("iso:<%s> [OK]\n", isof
);
2145 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
2146 grub_script_execute_sourcecode(cmd
);
2148 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
2151 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
2153 grub_printf("org:<%s> [OK]\n", orgf
);
2157 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
2159 grub_file_close(file
);
2163 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
2166 grub_script_execute_sourcecode("loopback -d vtisocheck");
2168 else if (grub_strchr(isof
, '*'))
2170 grub_printf("iso:<%s> [*]\n", isof
);
2171 grub_printf("org:<%s>\n", orgf
);
2175 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
2176 grub_printf("org:<%s>\n", orgf
);
2179 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
2182 if (file
->size
> vtoy_max_replace_file_size
)
2184 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
2188 grub_printf("new1:<%s> [OK]\n", newf
);
2190 grub_file_close(file
);
2194 grub_printf("new:<%s> [NOT Exist]\n", newf
);
2197 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "img", &img
))
2199 grub_printf("img:<%d>\n", img
);
2209 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
2211 VTOY_JSON
*pNode
= NULL
;
2212 auto_memdisk
*node
= NULL
;
2213 auto_memdisk
*next
= NULL
;
2217 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2219 debug("Not array %d\n", json
->enDataType
);
2223 if (g_auto_memdisk_head
)
2225 for (node
= g_auto_memdisk_head
; node
; node
= next
)
2231 g_auto_memdisk_head
= NULL
;
2234 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2236 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2238 node
= grub_zalloc(sizeof(auto_memdisk
));
2241 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2243 if (g_auto_memdisk_head
)
2245 node
->next
= g_auto_memdisk_head
;
2248 g_auto_memdisk_head
= node
;
2256 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
2258 VTOY_JSON
*pNode
= NULL
;
2260 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2262 grub_printf("Not array %d\n", json
->enDataType
);
2266 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2268 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2270 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2272 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2274 grub_printf(" [*]\n");
2276 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2278 grub_printf(" [OK]\n");
2282 grub_printf(" [NOT EXIST]\n");
2290 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
2292 VTOY_JSON
*pNode
= NULL
;
2293 image_list
*node
= NULL
;
2294 image_list
*next
= NULL
;
2295 image_list
*tail
= NULL
;
2299 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2301 debug("Not array %d\n", json
->enDataType
);
2305 if (g_image_list_head
)
2307 for (node
= g_image_list_head
; node
; node
= next
)
2313 g_image_list_head
= NULL
;
2316 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
2318 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
2322 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
2325 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2327 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2329 node
= grub_zalloc(sizeof(image_list
));
2332 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2334 if (g_image_list_head
)
2340 g_image_list_head
= node
;
2350 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
2352 VTOY_JSON
*pNode
= NULL
;
2354 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2356 grub_printf("Not array %d\n", json
->enDataType
);
2360 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2362 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2364 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2366 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2368 grub_printf(" [*]\n");
2370 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2372 grub_printf(" [OK]\n");
2376 grub_printf(" [NOT EXIST]\n");
2384 static plugin_entry g_plugin_entries
[] =
2386 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
, 0 },
2387 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
, 0 },
2388 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
, 0 },
2389 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
, 0 },
2390 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
, 0 },
2391 { "menu_tip", ventoy_plugin_menutip_entry
, ventoy_plugin_menutip_check
, 0 },
2392 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
, 0 },
2393 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
, 0 },
2394 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
, 0 },
2395 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
, 0 },
2396 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
, 0 },
2397 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
, 0 },
2398 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
, 0 },
2399 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
, 0 },
2400 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
, 0 },
2403 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
2407 VTOY_JSON
*cur
= NULL
;
2409 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
2411 for (cur
= json
; cur
; cur
= cur
->pstNext
)
2413 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2415 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
2416 if (g_plugin_entries
[i
].flag
== 0 && grub_strcmp(key
, cur
->pcName
) == 0)
2418 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2419 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2420 g_plugin_entries
[i
].flag
= 1;
2427 for (cur
= json
; cur
; cur
= cur
->pstNext
)
2429 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2431 if (g_plugin_entries
[i
].flag
== 0 && grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0)
2433 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2434 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2435 g_plugin_entries
[i
].flag
= 1;
2444 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2449 grub_uint8_t
*code
= NULL
;
2451 VTOY_JSON
*json
= NULL
;
2456 grub_env_set("VTOY_TIP_LEFT", "10%");
2457 grub_env_set("VTOY_TIP_TOP", "80%+5");
2458 grub_env_set("VTOY_TIP_COLOR", "blue");
2459 grub_env_set("VTOY_TIP_ALIGN", "left");
2461 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2464 return GRUB_ERR_NONE
;
2467 debug("json configuration file size %d\n", (int)file
->size
);
2469 buf
= grub_malloc(file
->size
+ 1);
2472 grub_file_close(file
);
2476 buf
[file
->size
] = 0;
2477 grub_file_read(file
, buf
, file
->size
);
2478 grub_file_close(file
);
2480 json
= vtoy_json_create();
2486 code
= (grub_uint8_t
*)buf
;
2487 if (code
[0] == 0xef && code
[1] == 0xbb && code
[2] == 0xbf)
2489 offset
= 3; /* Skip UTF-8 BOM */
2491 else if ((code
[0] == 0xff && code
[1] == 0xfe) || (code
[0] == 0xfe && code
[1] == 0xff))
2493 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2494 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2496 grub_env_set("VTOY_PLUGIN_ENCODE_ERROR", "1");
2497 grub_env_export("VTOY_PLUGIN_ENCODE_ERROR");
2499 debug("Failed to parse json string %d\n", ret
);
2504 ret
= vtoy_json_parse(json
, buf
+ offset
);
2507 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2508 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2510 debug("Failed to parse json string %d\n", ret
);
2515 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
2517 vtoy_json_destroy(json
);
2521 if (g_boot_pwd
.type
)
2523 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
2524 if (ventoy_check_password(&g_boot_pwd
, 3))
2526 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
2533 if (g_menu_tip_head
)
2535 grub_env_set("VTOY_MENU_TIP_ENABLE", "1");
2539 grub_env_unset("VTOY_MENU_TIP_ENABLE");
2542 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2545 void ventoy_plugin_dump_injection(void)
2547 injection_config
*node
= NULL
;
2549 for (node
= g_injection_head
; node
; node
= node
->next
)
2551 grub_printf("\n%s:<%s>\n", (node
->type
== injection_type_file
) ? "IMAGE" : "PARENT", node
->isopath
);
2552 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
2559 void ventoy_plugin_dump_auto_install(void)
2562 install_template
*node
= NULL
;
2564 for (node
= g_install_template_head
; node
; node
= node
->next
)
2566 grub_printf("\n%s:<%s> <%d>\n",
2567 (node
->type
== auto_install_type_file
) ? "IMAGE" : "PARENT",
2568 node
->isopath
, node
->templatenum
);
2569 for (i
= 0; i
< node
->templatenum
; i
++)
2571 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
2578 void ventoy_plugin_dump_persistence(void)
2582 persistence_config
*node
= NULL
;
2583 ventoy_img_chunk_list chunk_list
;
2585 for (node
= g_persistence_head
; node
; node
= node
->next
)
2587 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
2589 for (i
= 0; i
< node
->backendnum
; i
++)
2591 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
2592 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
2595 grub_printf(" [ SUCCESS ]\n");
2596 grub_free(chunk_list
.chunk
);
2600 grub_printf(" [ FAILED ]\n");
2608 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
2611 install_template
*node
= NULL
;
2613 if (!g_install_template_head
)
2618 len
= (int)grub_strlen(isopath
);
2619 for (node
= g_install_template_head
; node
; node
= node
->next
)
2621 if (node
->type
== auto_install_type_file
)
2623 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2630 for (node
= g_install_template_head
; node
; node
= node
->next
)
2632 if (node
->type
== auto_install_type_parent
)
2634 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2644 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
2646 install_template
*node
= NULL
;
2648 node
= ventoy_plugin_find_install_template(isopath
);
2649 if ((!node
) || (!node
->templatepath
))
2654 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2659 return node
->templatepath
[node
->cursel
].path
;
2662 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2665 persistence_config
*node
= NULL
;
2667 if (!g_persistence_head
)
2672 len
= (int)grub_strlen(isopath
);
2673 for (node
= g_persistence_head
; node
; node
= node
->next
)
2675 if ((len
== node
->pathlen
) && (ventoy_strcmp(node
->isopath
, isopath
) == 0))
2684 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2689 grub_uint64_t start
= 0;
2690 grub_file_t file
= NULL
;
2691 persistence_config
*node
= NULL
;
2693 node
= ventoy_plugin_find_persistent(isopath
);
2694 if ((!node
) || (!node
->backendpath
))
2701 index
= node
->cursel
;
2704 if (index
< 0 || index
>= node
->backendnum
)
2709 path
= node
->backendpath
[index
].path
;
2711 if (node
->backendpath
[index
].vlnk_add
== 0)
2713 len
= grub_strlen(path
);
2714 if (len
> 9 && grub_strncmp(path
+ len
- 9, ".vlnk.dat", 9) == 0)
2716 ventoy_add_vlnk_file(NULL
, path
);
2717 node
->backendpath
[index
].vlnk_add
= 1;
2721 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, path
);
2724 debug("Failed to open file %s%s\n", g_iso_disk_name
, path
);
2728 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2729 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2730 if (NULL
== chunk_list
->chunk
)
2735 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2736 chunk_list
->cur_chunk
= 0;
2738 start
= file
->device
->disk
->partition
->start
;
2739 ventoy_get_block_list(file
, chunk_list
, start
);
2741 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2743 grub_free(chunk_list
->chunk
);
2744 chunk_list
->chunk
= NULL
;
2752 grub_file_close(file
);
2757 const char * ventoy_plugin_get_injection(const char *isopath
)
2760 injection_config
*node
= NULL
;
2762 if (!g_injection_head
)
2767 len
= (int)grub_strlen(isopath
);
2768 for (node
= g_injection_head
; node
; node
= node
->next
)
2770 if (node
->type
== injection_type_file
)
2772 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2774 return node
->archive
;
2779 for (node
= g_injection_head
; node
; node
= node
->next
)
2781 if (node
->type
== injection_type_parent
)
2783 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2785 return node
->archive
;
2793 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2796 menu_alias
*node
= NULL
;
2798 if (!g_menu_alias_head
)
2803 len
= (int)grub_strlen(isopath
);
2804 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2806 if (node
->type
== type
&& node
->pathlen
&&
2807 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2816 const menu_tip
* ventoy_plugin_get_menu_tip(int type
, const char *isopath
)
2819 menu_tip
*node
= NULL
;
2821 if (!g_menu_tip_head
)
2826 len
= (int)grub_strlen(isopath
);
2827 for (node
= g_menu_tip_head
; node
; node
= node
->next
)
2829 if (node
->type
== type
&& node
->pathlen
&&
2830 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2839 const char * ventoy_plugin_get_menu_class(int type
, const char *name
, const char *path
)
2843 menu_class
*node
= NULL
;
2845 if (!g_menu_class_head
)
2850 namelen
= (int)grub_strlen(name
);
2851 pathlen
= (int)grub_strlen(path
);
2853 if (vtoy_class_image_file
== type
)
2855 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2857 if (node
->type
!= type
)
2862 if (node
->parent
== 0)
2864 if ((node
->patlen
< namelen
) && grub_strstr(name
, node
->pattern
))
2871 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2873 if (node
->type
!= type
)
2880 if ((node
->patlen
< pathlen
) && ventoy_plugin_is_parent(node
->pattern
, node
->patlen
, path
))
2889 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2891 if (node
->type
== type
&& node
->patlen
== namelen
&& grub_strncmp(name
, node
->pattern
, namelen
) == 0)
2901 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2904 custom_boot
*node
= NULL
;
2906 node
= grub_zalloc(sizeof(custom_boot
));
2909 node
->type
= vtoy_custom_boot_image_file
;
2910 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2911 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2914 len
= node
->pathlen
- 5;
2915 node
->path
[len
] = 0;
2916 node
->pathlen
= len
;
2918 if (g_custom_boot_head
)
2920 node
->next
= g_custom_boot_head
;
2922 g_custom_boot_head
= node
;
2928 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2932 custom_boot
*node
= NULL
;
2934 if (!g_custom_boot_head
)
2939 len
= (int)grub_strlen(isopath
);
2941 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2943 if (node
->type
== vtoy_custom_boot_image_file
)
2945 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2952 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2953 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2955 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2957 if (isopath
[i
] == '/')
2974 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2976 custom_boot
*node
= NULL
;
2982 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2984 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
2985 node
->path
, node
->cfg
);
2991 int ventoy_plugin_check_memdisk(const char *isopath
)
2994 auto_memdisk
*node
= NULL
;
2996 if (!g_auto_memdisk_head
)
3001 len
= (int)grub_strlen(isopath
);
3002 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
3004 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
3013 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
3017 image_list
*node
= NULL
;
3019 if (!g_image_list_head
)
3024 len
= (int)grub_strlen(name
);
3026 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
3028 if (vtoy_class_directory
== type
)
3030 if (len
< node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
3037 if (len
== node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
3047 conf_replace
* ventoy_plugin_find_conf_replace(const char *iso
)
3052 if (!g_conf_replace_head
)
3057 len
= (int)grub_strlen(iso
);
3059 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
3061 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
3070 dud
* ventoy_plugin_find_dud(const char *iso
)
3080 len
= (int)grub_strlen(iso
);
3081 for (node
= g_dud_head
; node
; node
= node
->next
)
3083 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
3092 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
3098 for (i
= 0; i
< node
->dudnum
; i
++)
3100 if (node
->files
[i
].size
> 0)
3102 debug("file %d has been loaded\n", i
);
3106 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
3109 buf
= grub_malloc(file
->size
);
3112 grub_file_read(file
, buf
, file
->size
);
3113 node
->files
[i
].size
= (int)file
->size
;
3114 node
->files
[i
].buf
= buf
;
3116 grub_file_close(file
);
3123 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
3127 const char *pos
= NULL
;
3128 menu_password
*node
= NULL
;
3137 len
= (int)grub_strlen(isopath
);
3138 for (node
= g_pwd_head
; node
; node
= node
->next
)
3140 if (node
->type
== vtoy_menu_pwd_file
)
3142 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
3144 return &(node
->password
);
3149 for (node
= g_pwd_head
; node
; node
= node
->next
)
3151 if (node
->type
== vtoy_menu_pwd_parent
)
3153 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
3155 return &(node
->password
);
3163 if (*isopath
== '.')
3172 for (i
= 0; i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
3174 if (g_file_type_pwd
[i
].type
&& 0 == grub_strcasecmp(pos
+ 1, g_menu_prefix
[i
]))
3176 return g_file_type_pwd
+ i
;
3184 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3187 const vtoy_password
*pwd
= NULL
;
3192 pwd
= ventoy_plugin_get_password(args
[0]);
3195 if (0 == ventoy_check_password(pwd
, 1))
3213 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3220 VTOY_JSON
*node
= NULL
;
3221 VTOY_JSON
*json
= NULL
;
3230 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
3233 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
3234 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
3238 buf
= grub_malloc(file
->size
+ 1);
3241 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
3245 buf
[file
->size
] = 0;
3246 grub_file_read(file
, buf
, file
->size
);
3248 json
= vtoy_json_create();
3251 grub_printf("Failed to create json\n");
3255 ret
= vtoy_json_parse(json
, buf
);
3258 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
3262 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
3263 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
3265 if (grub_strcmp(node
->pcName
, key
) == 0)
3273 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
3275 if (grub_strcmp(node
->pcName
, args
[1]) == 0)
3283 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
3288 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
3290 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
3292 if (g_plugin_entries
[i
].checkfunc
)
3294 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
3301 check_free(file
, grub_file_close
);
3302 check_free(json
, vtoy_json_destroy
);
3303 grub_check_free(buf
);
3308 grub_err_t
ventoy_cmd_select_theme_cfg(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3314 theme_list
*node
= NULL
;
3320 if (g_theme_single_file
[0])
3325 if (g_theme_num
< 2)
3330 bufsize
= (g_theme_num
+ 1) * 1024;
3331 buf
= grub_malloc(bufsize
);
3337 for (node
= g_theme_head
; node
; node
= node
->next
)
3339 name
= grub_strstr(node
->theme
.path
, ")/");
3346 name
= node
->theme
.path
;
3349 pos
+= grub_snprintf(buf
+ pos
, bufsize
- pos
,
3350 "menuentry \"%s\" --class=debug_theme_item --class=debug_theme_select --class=F5tool {\n"
3351 "vt_set_theme_path \"%s\"\n"
3353 name
, node
->theme
.path
);
3356 pos
+= grub_snprintf(buf
+ pos
, bufsize
- pos
,
3357 "menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {\n"
3358 "echo 'Return ...'\n"
3361 grub_script_execute_sourcecode(buf
);
3367 grub_err_t
ventoy_cmd_set_theme(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3369 grub_uint32_t i
= 0;
3370 grub_uint32_t mod
= 0;
3371 theme_list
*node
= g_theme_head
;
3372 struct grub_datetime datetime
;
3378 if (g_theme_single_file
[0])
3380 debug("single theme %s\n", g_theme_single_file
);
3381 grub_env_set("theme", g_theme_single_file
);
3385 debug("g_theme_num = %d\n", g_theme_num
);
3387 if (g_theme_num
== 0)
3392 if (g_theme_id
> 0 && g_theme_id
<= g_theme_num
)
3394 for (i
= 0; i
< (grub_uint32_t
)(g_theme_id
- 1) && node
; i
++)
3399 grub_env_set("theme", node
->theme
.path
);
3403 grub_memset(&datetime
, 0, sizeof(datetime
));
3404 grub_get_datetime(&datetime
);
3406 if (g_theme_random
== vtoy_theme_random_boot_second
)
3408 grub_divmod32((grub_uint32_t
)datetime
.second
, (grub_uint32_t
)g_theme_num
, &mod
);
3410 else if (g_theme_random
== vtoy_theme_random_boot_day
)
3412 grub_divmod32((grub_uint32_t
)datetime
.day
, (grub_uint32_t
)g_theme_num
, &mod
);
3414 else if (g_theme_random
== vtoy_theme_random_boot_month
)
3416 grub_divmod32((grub_uint32_t
)datetime
.month
, (grub_uint32_t
)g_theme_num
, &mod
);
3419 debug("%04d/%02d/%02d %02d:%02d:%02d radom:%d mod:%d\n",
3420 datetime
.year
, datetime
.month
, datetime
.day
,
3421 datetime
.hour
, datetime
.minute
, datetime
.second
,
3422 g_theme_random
, mod
);
3424 for (i
= 0; i
< mod
&& node
; i
++)
3429 debug("random theme %s\n", node
->theme
.path
);
3430 grub_env_set("theme", node
->theme
.path
);
3434 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
3437 extern char g_ventoy_theme_path
[256];
3438 grub_err_t
ventoy_cmd_set_theme_path(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3445 g_ventoy_theme_path
[0] = 0;
3449 grub_snprintf(g_ventoy_theme_path
, sizeof(g_ventoy_theme_path
), "%s", args
[0]);
3452 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);