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 install_template
*g_install_template_head
= NULL
;
47 static dud
*g_dud_head
= NULL
;
48 static menu_password
*g_pwd_head
= NULL
;
49 static persistence_config
*g_persistence_head
= NULL
;
50 static menu_alias
*g_menu_alias_head
= NULL
;
51 static menu_class
*g_menu_class_head
= NULL
;
52 static custom_boot
*g_custom_boot_head
= NULL
;
53 static injection_config
*g_injection_head
= NULL
;
54 static auto_memdisk
*g_auto_memdisk_head
= NULL
;
55 static image_list
*g_image_list_head
= NULL
;
56 static conf_replace
*g_conf_replace_head
= NULL
;
58 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
61 VTOY_JSON
*pNode
= NULL
;
62 VTOY_JSON
*pChild
= NULL
;
66 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
68 grub_printf("Not array type %d\n", json
->enDataType
);
72 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
74 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
76 pChild
= pNode
->pstChild
;
77 if (pChild
->enDataType
== JSON_TYPE_STRING
)
79 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
81 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
82 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
86 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
91 grub_printf("%s is NOT string type\n", pChild
->pcName
);
97 grub_printf("%s is not an object\n", pNode
->pcName
);
105 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
107 VTOY_JSON
*pNode
= NULL
;
108 VTOY_JSON
*pChild
= NULL
;
112 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
114 debug("Not array %d\n", json
->enDataType
);
118 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
120 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
122 pChild
= pNode
->pstChild
;
123 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
125 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
133 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
139 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
142 grub_printf("file: %s\n", value
);
145 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
149 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
154 grub_printf("Theme file %s does NOT exist\n", value
);
159 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
162 grub_printf("gfxmode: %s\n", value
);
165 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
168 grub_printf("display_mode: %s\n", value
);
171 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
174 grub_printf("serial_param %s\n", value
);
177 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
180 grub_printf("ventoy_left: %s\n", value
);
183 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
186 grub_printf("ventoy_top: %s\n", value
);
189 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
192 grub_printf("ventoy_color: %s\n", value
);
195 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
198 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
200 if (node
->enDataType
== JSON_TYPE_STRING
)
202 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
204 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
208 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
215 grub_printf("fonts NOT found\n");
221 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
227 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
232 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
236 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
239 if (ventoy_is_file_exist(filepath
) == 0)
241 debug("Theme file %s does not exist\n", filepath
);
245 debug("vtoy_theme %s\n", filepath
);
246 grub_env_set("vtoy_theme", filepath
);
249 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
252 debug("vtoy_gfxmode %s\n", value
);
253 grub_env_set("vtoy_gfxmode", value
);
256 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
259 debug("display_mode %s\n", value
);
260 grub_env_set("vtoy_display_mode", value
);
263 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
266 debug("serial_param %s\n", value
);
267 grub_env_set("vtoy_serial_param", value
);
270 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
273 grub_env_set("VTLE_LFT", value
);
276 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
279 grub_env_set("VTLE_TOP", value
);
282 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
285 grub_env_set("VTLE_CLR", value
);
288 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
291 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
293 if (node
->enDataType
== JSON_TYPE_STRING
&&
294 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
296 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
297 grub_font_load(filepath
);
305 static int ventoy_plugin_check_path(const char *path
, const char *file
)
309 grub_printf("%s is NOT begin with '/' \n", file
);
313 if (grub_strchr(file
, '\\'))
315 grub_printf("%s contains invalid '\\' \n", file
);
319 if (grub_strstr(file
, "//"))
321 grub_printf("%s contains invalid double slash\n", file
);
325 if (grub_strstr(file
, "../"))
327 grub_printf("%s contains invalid '../' \n", file
);
331 if (!ventoy_is_file_exist("%s%s", path
, file
))
333 grub_printf("%s%s does NOT exist\n", path
, file
);
340 static int ventoy_plugin_check_fullpath
351 VTOY_JSON
*node
= json
;
352 VTOY_JSON
*child
= NULL
;
356 if (0 == grub_strcmp(key
, node
->pcName
))
360 node
= node
->pstNext
;
368 if (JSON_TYPE_STRING
== node
->enDataType
)
371 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
372 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
374 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
376 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
378 if (JSON_TYPE_STRING
!= child
->enDataType
)
380 grub_printf("Non string json type\n");
384 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
385 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
396 static int ventoy_plugin_parse_fullpath
401 file_fullpath
**fullpath
,
407 VTOY_JSON
*node
= json
;
408 VTOY_JSON
*child
= NULL
;
409 file_fullpath
*path
= NULL
;
413 if (0 == grub_strcmp(key
, node
->pcName
))
417 node
= node
->pstNext
;
425 if (JSON_TYPE_STRING
== node
->enDataType
)
427 debug("%s is string type data\n", node
->pcName
);
429 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
431 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
435 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
438 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
444 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
446 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
448 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
450 debug("Invalid data type:%d\n", child
->enDataType
);
455 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
457 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
462 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
464 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
466 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
480 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
485 const char *iso
= NULL
;
486 VTOY_JSON
*pNode
= NULL
;
488 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
490 grub_printf("Not array type %d\n", json
->enDataType
);
494 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
496 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
498 grub_printf("NOT object type\n");
501 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
504 pos
= grub_strchr(iso
, '*');
505 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
507 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
508 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
510 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
512 if (autosel
>= 0 && autosel
<= pathnum
)
514 grub_printf("autosel: %d [OK]\n", autosel
);
518 grub_printf("autosel: %d [FAIL]\n", autosel
);
524 grub_printf("image: %s [FAIL]\n", iso
);
529 grub_printf("image not found\n");
536 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
540 const char *iso
= NULL
;
541 VTOY_JSON
*pNode
= NULL
;
542 install_template
*node
= NULL
;
543 install_template
*next
= NULL
;
544 file_fullpath
*templatepath
= NULL
;
546 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
548 debug("Not array %d\n", json
->enDataType
);
552 if (g_install_template_head
)
554 for (node
= g_install_template_head
; node
; node
= next
)
557 grub_check_free(node
->templatepath
);
561 g_install_template_head
= NULL
;
564 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
566 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
567 if (iso
&& iso
[0] == '/')
569 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
571 node
= grub_zalloc(sizeof(install_template
));
574 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
575 node
->templatepath
= templatepath
;
576 node
->templatenum
= pathnum
;
579 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
581 if (autosel
>= 0 && autosel
<= pathnum
)
583 node
->autosel
= autosel
;
587 if (g_install_template_head
)
589 node
->next
= g_install_template_head
;
592 g_install_template_head
= node
;
601 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
605 const char *iso
= NULL
;
606 VTOY_JSON
*pNode
= NULL
;
608 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
610 grub_printf("Not array type %d\n", json
->enDataType
);
614 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
616 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
618 grub_printf("NOT object type\n");
621 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
624 pos
= grub_strchr(iso
, '*');
625 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
627 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
628 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
632 grub_printf("image: %s [FAIL]\n", iso
);
637 grub_printf("image not found\n");
644 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
647 const char *iso
= NULL
;
648 VTOY_JSON
*pNode
= NULL
;
651 file_fullpath
*dudpath
= NULL
;
653 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
655 debug("Not array %d\n", json
->enDataType
);
661 for (node
= g_dud_head
; node
; node
= next
)
664 grub_check_free(node
->dudpath
);
671 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
673 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
674 if (iso
&& iso
[0] == '/')
676 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "dud", &dudpath
, &pathnum
))
678 node
= grub_zalloc(sizeof(dud
));
681 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
682 node
->dudpath
= dudpath
;
683 node
->dudnum
= pathnum
;
684 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
690 node
->next
= g_dud_head
;
707 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
714 vtoy_password tmpPwd
;
716 len
= (int)grub_strlen(pwdstr
);
719 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
723 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
725 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
727 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
728 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
730 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
734 for (i
= 0; i
< 16; i
++)
736 bytes
[0] = pwdstr
[4 + i
* 2];
737 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
740 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
742 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
746 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
750 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
752 else if ((len
- 4) > 32)
754 pos
= grub_strchr(pwdstr
+ 4, '#');
757 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
761 if (len
- 1 - (int)(long)(pos
- pwdstr
) != 32)
763 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
769 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
773 for (i
= 0; i
< 16; i
++)
775 bytes
[0] = pos
[i
* 2];
776 bytes
[1] = pos
[i
* 2 + 1];
779 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
781 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
785 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
790 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
794 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
800 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
806 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
812 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
814 const char *iso
= NULL
;
815 const char *pwd
= NULL
;
816 VTOY_JSON
*pNode
= NULL
;
817 VTOY_JSON
*pCNode
= NULL
;
818 menu_password
*node
= NULL
;
819 menu_password
*tail
= NULL
;
820 menu_password
*next
= NULL
;
824 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
826 debug("Not object %d\n", json
->enDataType
);
832 for (node
= g_pwd_head
; node
; node
= next
)
841 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
843 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
845 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
847 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
849 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
851 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
856 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
857 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
858 if (iso
&& pwd
&& iso
[0] == '/')
860 node
= grub_zalloc(sizeof(menu_password
));
863 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
865 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
889 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
892 const char *iso
= NULL
;
893 const char *pwd
= NULL
;
894 VTOY_JSON
*pNode
= NULL
;
895 VTOY_JSON
*pCNode
= NULL
;
897 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
899 grub_printf("Not object %d\n", json
->enDataType
);
903 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
905 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
907 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
909 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
913 grub_printf("Invalid bootpwd.\n");
916 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
919 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
921 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
923 grub_printf("Not object %d\n", pCNode
->enDataType
);
927 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
930 pos
= grub_strchr(iso
, '*');
931 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
933 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
935 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
937 grub_printf("file:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
938 grub_printf("pwd:<%s>\n\n", pwd
);
942 grub_printf("Invalid password for <%s>\n", iso
);
947 grub_printf("<%s%s> not found\n", isodisk
, iso
);
952 grub_printf("No file item found in json.\n");
961 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
966 const char *iso
= NULL
;
967 VTOY_JSON
*pNode
= NULL
;
969 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
971 grub_printf("Not array type %d\n", json
->enDataType
);
975 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
977 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
979 grub_printf("NOT object type\n");
982 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
985 pos
= grub_strchr(iso
, '*');
986 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
988 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
989 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
991 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
993 if (autosel
>= 0 && autosel
<= pathnum
)
995 grub_printf("autosel: %d [OK]\n", autosel
);
999 grub_printf("autosel: %d [FAIL]\n", autosel
);
1005 grub_printf("image: %s [FAIL]\n", iso
);
1010 grub_printf("image not found\n");
1017 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1021 const char *iso
= NULL
;
1022 VTOY_JSON
*pNode
= NULL
;
1023 persistence_config
*node
= NULL
;
1024 persistence_config
*next
= NULL
;
1025 file_fullpath
*backendpath
= NULL
;
1029 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1031 debug("Not array %d\n", json
->enDataType
);
1035 if (g_persistence_head
)
1037 for (node
= g_persistence_head
; node
; node
= next
)
1040 grub_check_free(node
->backendpath
);
1044 g_persistence_head
= NULL
;
1047 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1049 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1050 if (iso
&& iso
[0] == '/')
1052 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1054 node
= grub_zalloc(sizeof(persistence_config
));
1057 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1058 node
->backendpath
= backendpath
;
1059 node
->backendnum
= pathnum
;
1062 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1064 if (autosel
>= 0 && autosel
<= pathnum
)
1066 node
->autosel
= autosel
;
1070 if (g_persistence_head
)
1072 node
->next
= g_persistence_head
;
1075 g_persistence_head
= node
;
1084 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1087 const char *path
= NULL
;
1088 const char *alias
= NULL
;
1089 VTOY_JSON
*pNode
= NULL
;
1093 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1095 grub_printf("Not array %d\n", json
->enDataType
);
1099 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1101 type
= vtoy_alias_image_file
;
1102 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1105 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1106 type
= vtoy_alias_directory
;
1109 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1110 if (path
&& path
[0] == '/' && alias
)
1112 if (vtoy_alias_image_file
== type
)
1114 if (grub_strchr(path
, '*'))
1116 grub_printf("image: <%s> [ * ]\n", path
);
1118 else if (ventoy_is_file_exist("%s%s", isodisk
, path
))
1120 grub_printf("image: <%s> [ OK ]\n", path
);
1124 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1129 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1131 grub_printf("dir: <%s> [ OK ]\n", path
);
1135 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1139 grub_printf("alias: <%s>\n\n", alias
);
1146 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1149 const char *path
= NULL
;
1150 const char *alias
= NULL
;
1151 VTOY_JSON
*pNode
= NULL
;
1152 menu_alias
*node
= NULL
;
1153 menu_alias
*next
= NULL
;
1157 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1159 debug("Not array %d\n", json
->enDataType
);
1163 if (g_menu_alias_head
)
1165 for (node
= g_menu_alias_head
; node
; node
= next
)
1171 g_menu_alias_head
= NULL
;
1174 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1176 type
= vtoy_alias_image_file
;
1177 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1180 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1181 type
= vtoy_alias_directory
;
1184 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1185 if (path
&& path
[0] == '/' && alias
)
1187 node
= grub_zalloc(sizeof(menu_alias
));
1191 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1192 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1194 if (g_menu_alias_head
)
1196 node
->next
= g_menu_alias_head
;
1199 g_menu_alias_head
= node
;
1208 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1210 const char *path
= NULL
;
1211 const char *archive
= NULL
;
1212 VTOY_JSON
*pNode
= NULL
;
1216 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1218 grub_printf("Not array %d\n", json
->enDataType
);
1222 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1224 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1227 grub_printf("image not found\n");
1231 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1234 grub_printf("archive not found\n");
1238 if (grub_strchr(path
, '*'))
1240 grub_printf("image: <%s> [*]\n", path
);
1244 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1247 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1253 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1255 const char *path
= NULL
;
1256 const char *archive
= NULL
;
1257 VTOY_JSON
*pNode
= NULL
;
1258 injection_config
*node
= NULL
;
1259 injection_config
*next
= NULL
;
1263 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1265 debug("Not array %d\n", json
->enDataType
);
1269 if (g_injection_head
)
1271 for (node
= g_injection_head
; node
; node
= next
)
1277 g_injection_head
= NULL
;
1280 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1282 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1283 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1284 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1286 node
= grub_zalloc(sizeof(injection_config
));
1289 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1290 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1292 if (g_injection_head
)
1294 node
->next
= g_injection_head
;
1297 g_injection_head
= node
;
1305 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1309 const char *key
= NULL
;
1310 const char *class = NULL
;
1311 VTOY_JSON
*pNode
= NULL
;
1312 menu_class
*tail
= NULL
;
1313 menu_class
*node
= NULL
;
1314 menu_class
*next
= NULL
;
1318 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1320 debug("Not array %d\n", json
->enDataType
);
1324 if (g_menu_class_head
)
1326 for (node
= g_menu_class_head
; node
; node
= next
)
1332 g_menu_class_head
= NULL
;
1335 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1338 type
= vtoy_class_image_file
;
1339 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1342 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1349 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1350 type
= vtoy_class_directory
;
1354 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1357 node
= grub_zalloc(sizeof(menu_class
));
1361 node
->parent
= parent
;
1362 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1363 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1365 if (g_menu_class_head
)
1371 g_menu_class_head
= node
;
1381 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1383 const char *name
= NULL
;
1384 const char *key
= NULL
;
1385 const char *class = NULL
;
1386 VTOY_JSON
*pNode
= NULL
;
1390 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1392 grub_printf("Not array %d\n", json
->enDataType
);
1396 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1399 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1403 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1407 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1411 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1414 grub_printf("%s: <%s>\n", name
, key
);
1415 grub_printf("class: <%s>\n\n", class);
1422 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1426 const char *key
= NULL
;
1427 const char *cfg
= NULL
;
1428 VTOY_JSON
*pNode
= NULL
;
1429 custom_boot
*tail
= NULL
;
1430 custom_boot
*node
= NULL
;
1431 custom_boot
*next
= NULL
;
1435 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1437 debug("Not array %d\n", json
->enDataType
);
1441 if (g_custom_boot_head
)
1443 for (node
= g_custom_boot_head
; node
; node
= next
)
1449 g_custom_boot_head
= NULL
;
1452 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1454 type
= vtoy_custom_boot_image_file
;
1455 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1458 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1459 type
= vtoy_custom_boot_directory
;
1462 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1465 node
= grub_zalloc(sizeof(custom_boot
));
1469 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1470 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1472 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
1474 if (g_custom_boot_head
)
1480 g_custom_boot_head
= node
;
1495 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
1499 const char *key
= NULL
;
1500 const char *cfg
= NULL
;
1501 VTOY_JSON
*pNode
= NULL
;
1505 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1507 grub_printf("Not array %d\n", json
->enDataType
);
1511 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1513 type
= vtoy_custom_boot_image_file
;
1514 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1517 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1518 type
= vtoy_custom_boot_directory
;
1521 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1522 len
= (int)grub_strlen(cfg
);
1525 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
1527 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
1531 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
1532 grub_printf("vcfg: <%s>\n\n", cfg
);
1540 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
1542 const char *isof
= NULL
;
1543 const char *orgf
= NULL
;
1544 const char *newf
= NULL
;
1545 VTOY_JSON
*pNode
= NULL
;
1546 conf_replace
*tail
= NULL
;
1547 conf_replace
*node
= NULL
;
1548 conf_replace
*next
= NULL
;
1552 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1554 debug("Not array %d\n", json
->enDataType
);
1558 if (g_conf_replace_head
)
1560 for (node
= g_conf_replace_head
; node
; node
= next
)
1566 g_conf_replace_head
= NULL
;
1569 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1571 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1572 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1573 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1574 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1576 node
= grub_zalloc(sizeof(conf_replace
));
1579 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
1580 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
1581 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
1583 if (g_conf_replace_head
)
1589 g_conf_replace_head
= node
;
1599 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
1601 const char *isof
= NULL
;
1602 const char *orgf
= NULL
;
1603 const char *newf
= NULL
;
1604 VTOY_JSON
*pNode
= NULL
;
1605 grub_file_t file
= NULL
;
1610 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1612 grub_printf("Not array %d\n", json
->enDataType
);
1616 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1618 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1619 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1620 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1621 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1623 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
1625 grub_printf("iso:<%s> [OK]\n", isof
);
1627 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
1628 grub_script_execute_sourcecode(cmd
);
1630 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
1633 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
1635 grub_printf("org:<%s> [OK]\n", orgf
);
1639 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
1641 grub_file_close(file
);
1645 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
1648 grub_script_execute_sourcecode("loopback -d vtisocheck");
1650 else if (grub_strchr(isof
, '*'))
1652 grub_printf("iso:<%s> [*]\n", isof
);
1653 grub_printf("org:<%s>\n", orgf
);
1657 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
1658 grub_printf("org:<%s>\n", orgf
);
1661 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
1664 if (file
->size
> vtoy_max_replace_file_size
)
1666 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
1670 grub_printf("new:<%s> [OK]\n", newf
);
1672 grub_file_close(file
);
1676 grub_printf("new:<%s> [NOT Exist]\n", newf
);
1685 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
1687 VTOY_JSON
*pNode
= NULL
;
1688 auto_memdisk
*node
= NULL
;
1689 auto_memdisk
*next
= NULL
;
1693 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1695 debug("Not array %d\n", json
->enDataType
);
1699 if (g_auto_memdisk_head
)
1701 for (node
= g_auto_memdisk_head
; node
; node
= next
)
1707 g_auto_memdisk_head
= NULL
;
1710 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1712 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1714 node
= grub_zalloc(sizeof(auto_memdisk
));
1717 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1719 if (g_auto_memdisk_head
)
1721 node
->next
= g_auto_memdisk_head
;
1724 g_auto_memdisk_head
= node
;
1732 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
1734 VTOY_JSON
*pNode
= NULL
;
1736 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1738 grub_printf("Not array %d\n", json
->enDataType
);
1742 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1744 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1746 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1748 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
1750 grub_printf(" [*]\n");
1752 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1754 grub_printf(" [OK]\n");
1758 grub_printf(" [NOT EXIST]\n");
1766 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
1768 VTOY_JSON
*pNode
= NULL
;
1769 image_list
*node
= NULL
;
1770 image_list
*next
= NULL
;
1771 image_list
*tail
= NULL
;
1775 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1777 debug("Not array %d\n", json
->enDataType
);
1781 if (g_image_list_head
)
1783 for (node
= g_image_list_head
; node
; node
= next
)
1789 g_image_list_head
= NULL
;
1792 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
1794 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
1798 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
1801 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1803 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1805 node
= grub_zalloc(sizeof(image_list
));
1808 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1810 if (g_image_list_head
)
1816 g_image_list_head
= node
;
1826 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
1828 VTOY_JSON
*pNode
= NULL
;
1830 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1832 grub_printf("Not array %d\n", json
->enDataType
);
1836 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1838 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1840 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1842 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
1844 grub_printf(" [*]\n");
1846 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1848 grub_printf(" [OK]\n");
1852 grub_printf(" [NOT EXIST]\n");
1860 static plugin_entry g_plugin_entries
[] =
1862 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
},
1863 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
},
1864 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
},
1865 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
},
1866 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
},
1867 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
},
1868 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
},
1869 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
},
1870 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
1871 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
1872 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
},
1873 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
},
1874 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
},
1875 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
},
1878 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
1882 VTOY_JSON
*cur
= json
;
1884 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
1888 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
1890 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
1891 if (grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0 || grub_strcmp(key
, cur
->pcName
) == 0)
1893 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
1894 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
1905 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1910 VTOY_JSON
*json
= NULL
;
1915 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
1918 return GRUB_ERR_NONE
;
1921 debug("json configuration file size %d\n", (int)file
->size
);
1923 buf
= grub_malloc(file
->size
+ 1);
1926 grub_file_close(file
);
1930 buf
[file
->size
] = 0;
1931 grub_file_read(file
, buf
, file
->size
);
1932 grub_file_close(file
);
1934 json
= vtoy_json_create();
1942 ret
= vtoy_json_parse(json
, buf
);
1945 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
1946 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
1948 debug("Failed to parse json string %d\n", ret
);
1953 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
1955 vtoy_json_destroy(json
);
1959 if (g_boot_pwd
.type
)
1961 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
1962 if (ventoy_check_password(&g_boot_pwd
, 3))
1964 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
1971 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1974 void ventoy_plugin_dump_injection(void)
1976 injection_config
*node
= NULL
;
1978 for (node
= g_injection_head
; node
; node
= node
->next
)
1980 grub_printf("\nIMAGE:<%s>\n", node
->isopath
);
1981 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
1988 void ventoy_plugin_dump_auto_install(void)
1991 install_template
*node
= NULL
;
1993 for (node
= g_install_template_head
; node
; node
= node
->next
)
1995 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->templatenum
);
1996 for (i
= 0; i
< node
->templatenum
; i
++)
1998 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
2005 void ventoy_plugin_dump_persistence(void)
2009 persistence_config
*node
= NULL
;
2010 ventoy_img_chunk_list chunk_list
;
2012 for (node
= g_persistence_head
; node
; node
= node
->next
)
2014 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
2016 for (i
= 0; i
< node
->backendnum
; i
++)
2018 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
2019 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
2022 grub_printf(" [ SUCCESS ]\n");
2023 grub_free(chunk_list
.chunk
);
2027 grub_printf(" [ FAILED ]\n");
2035 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
2038 install_template
*node
= NULL
;
2040 if (!g_install_template_head
)
2045 len
= (int)grub_strlen(isopath
);
2046 for (node
= g_install_template_head
; node
; node
= node
->next
)
2048 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2057 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
2059 install_template
*node
= NULL
;
2061 node
= ventoy_plugin_find_install_template(isopath
);
2062 if ((!node
) || (!node
->templatepath
))
2067 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2072 return node
->templatepath
[node
->cursel
].path
;
2075 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2078 persistence_config
*node
= NULL
;
2080 if (!g_persistence_head
)
2085 len
= (int)grub_strlen(isopath
);
2086 for (node
= g_persistence_head
; node
; node
= node
->next
)
2088 if ((len
== node
->pathlen
) && (ventoy_strcmp(node
->isopath
, isopath
) == 0))
2097 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2100 grub_uint64_t start
= 0;
2101 grub_file_t file
= NULL
;
2102 persistence_config
*node
= NULL
;
2104 node
= ventoy_plugin_find_persistent(isopath
);
2105 if ((!node
) || (!node
->backendpath
))
2112 index
= node
->cursel
;
2115 if (index
< 0 || index
>= node
->backendnum
)
2120 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
2123 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
2127 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2128 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2129 if (NULL
== chunk_list
->chunk
)
2134 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2135 chunk_list
->cur_chunk
= 0;
2137 start
= file
->device
->disk
->partition
->start
;
2138 ventoy_get_block_list(file
, chunk_list
, start
);
2140 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2142 grub_free(chunk_list
->chunk
);
2143 chunk_list
->chunk
= NULL
;
2151 grub_file_close(file
);
2156 const char * ventoy_plugin_get_injection(const char *isopath
)
2159 injection_config
*node
= NULL
;
2161 if (!g_injection_head
)
2166 len
= (int)grub_strlen(isopath
);
2167 for (node
= g_injection_head
; node
; node
= node
->next
)
2169 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2171 return node
->archive
;
2178 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2181 menu_alias
*node
= NULL
;
2183 if (!g_menu_alias_head
)
2188 len
= (int)grub_strlen(isopath
);
2189 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2191 if (node
->type
== type
&& node
->pathlen
&&
2192 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2201 const char * ventoy_plugin_get_menu_class(int type
, const char *name
, const char *path
)
2204 menu_class
*node
= NULL
;
2206 if (!g_menu_class_head
)
2211 if (vtoy_class_image_file
== type
)
2213 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2215 if (node
->type
!= type
)
2222 len
= (int)grub_strlen(path
);
2223 if ((node
->patlen
< len
) && (path
[node
->patlen
] == '/') &&
2224 (grub_strncmp(path
, node
->pattern
, node
->patlen
) == 0))
2231 len
= (int)grub_strlen(name
);
2232 if ((node
->patlen
< len
) && grub_strstr(name
, node
->pattern
))
2241 len
= (int)grub_strlen(name
);
2242 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2244 if (node
->type
== type
&& node
->patlen
== len
&& grub_strncmp(name
, node
->pattern
, len
) == 0)
2254 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2257 custom_boot
*node
= NULL
;
2259 node
= grub_zalloc(sizeof(custom_boot
));
2262 node
->type
= vtoy_custom_boot_image_file
;
2263 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2264 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2267 len
= node
->pathlen
- 5;
2268 node
->path
[len
] = 0;
2269 node
->pathlen
= len
;
2271 if (g_custom_boot_head
)
2273 node
->next
= g_custom_boot_head
;
2275 g_custom_boot_head
= node
;
2281 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2285 custom_boot
*node
= NULL
;
2287 if (!g_custom_boot_head
)
2292 len
= (int)grub_strlen(isopath
);
2294 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2296 if (node
->type
== vtoy_custom_boot_image_file
)
2298 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2305 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2306 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2308 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2310 if (isopath
[i
] == '/')
2327 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2329 custom_boot
*node
= NULL
;
2335 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2337 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
2338 node
->path
, node
->cfg
);
2344 int ventoy_plugin_check_memdisk(const char *isopath
)
2347 auto_memdisk
*node
= NULL
;
2349 if (!g_auto_memdisk_head
)
2354 len
= (int)grub_strlen(isopath
);
2355 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
2357 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2366 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
2370 image_list
*node
= NULL
;
2372 if (!g_image_list_head
)
2377 len
= (int)grub_strlen(name
);
2379 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
2381 if (vtoy_class_directory
== type
)
2383 if (len
< node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
2390 if (len
== node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
2400 conf_replace
* ventoy_plugin_find_conf_replace(const char *iso
)
2405 if (!g_conf_replace_head
)
2410 len
= (int)grub_strlen(iso
);
2412 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
2414 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
2423 dud
* ventoy_plugin_find_dud(const char *iso
)
2433 len
= (int)grub_strlen(iso
);
2434 for (node
= g_dud_head
; node
; node
= node
->next
)
2436 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
2445 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
2451 for (i
= 0; i
< node
->dudnum
; i
++)
2453 if (node
->files
[i
].size
> 0)
2455 debug("file %d has been loaded\n", i
);
2459 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
2462 buf
= grub_malloc(file
->size
);
2465 grub_file_read(file
, buf
, file
->size
);
2466 node
->files
[i
].size
= (int)file
->size
;
2467 node
->files
[i
].buf
= buf
;
2469 grub_file_close(file
);
2476 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
2479 menu_password
*node
= NULL
;
2481 if ((!g_pwd_head
) || (!isopath
))
2486 len
= (int)grub_strlen(isopath
);
2487 for (node
= g_pwd_head
; node
; node
= node
->next
)
2489 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2491 return &(node
->password
);
2498 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2501 const vtoy_password
*pwd
= NULL
;
2506 pwd
= ventoy_plugin_get_password(args
[0]);
2509 if (0 == ventoy_check_password(pwd
, 1))
2527 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2534 VTOY_JSON
*node
= NULL
;
2535 VTOY_JSON
*json
= NULL
;
2544 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2547 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
2548 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
2552 buf
= grub_malloc(file
->size
+ 1);
2555 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
2559 buf
[file
->size
] = 0;
2560 grub_file_read(file
, buf
, file
->size
);
2562 json
= vtoy_json_create();
2565 grub_printf("Failed to create json\n");
2569 ret
= vtoy_json_parse(json
, buf
);
2572 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
2576 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
2577 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
2579 if (grub_strcmp(node
->pcName
, args
[1]) == 0 || grub_strcmp(node
->pcName
, key
) == 0)
2587 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
2591 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2593 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
2595 if (g_plugin_entries
[i
].checkfunc
)
2597 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
2604 check_free(file
, grub_file_close
);
2605 check_free(json
, vtoy_json_destroy
);
2606 grub_check_free(buf
);