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_alias
*g_menu_alias_head
= NULL
;
52 static menu_class
*g_menu_class_head
= NULL
;
53 static custom_boot
*g_custom_boot_head
= NULL
;
54 static injection_config
*g_injection_head
= NULL
;
55 static auto_memdisk
*g_auto_memdisk_head
= NULL
;
56 static image_list
*g_image_list_head
= NULL
;
57 static conf_replace
*g_conf_replace_head
= NULL
;
59 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
62 VTOY_JSON
*pNode
= NULL
;
63 VTOY_JSON
*pChild
= NULL
;
67 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
69 grub_printf("Not array type %d\n", json
->enDataType
);
73 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
75 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
77 pChild
= pNode
->pstChild
;
78 if (pChild
->enDataType
== JSON_TYPE_STRING
)
80 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
82 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
83 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
87 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
92 grub_printf("%s is NOT string type\n", pChild
->pcName
);
98 grub_printf("%s is not an object\n", pNode
->pcName
);
106 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
108 VTOY_JSON
*pNode
= NULL
;
109 VTOY_JSON
*pChild
= NULL
;
113 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
115 debug("Not array %d\n", json
->enDataType
);
119 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
121 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
123 pChild
= pNode
->pstChild
;
124 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
126 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
134 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
140 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
143 grub_printf("file: %s\n", value
);
146 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
150 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
155 grub_printf("Theme file %s does NOT exist\n", value
);
160 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
163 grub_printf("gfxmode: %s\n", value
);
166 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
169 grub_printf("display_mode: %s\n", value
);
172 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
175 grub_printf("serial_param %s\n", value
);
178 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
181 grub_printf("ventoy_left: %s\n", value
);
184 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
187 grub_printf("ventoy_top: %s\n", value
);
190 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
193 grub_printf("ventoy_color: %s\n", value
);
196 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
199 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
201 if (node
->enDataType
== JSON_TYPE_STRING
)
203 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
205 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
209 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
216 grub_printf("fonts NOT found\n");
222 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
228 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
233 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
237 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
240 if (ventoy_is_file_exist(filepath
) == 0)
242 debug("Theme file %s does not exist\n", filepath
);
246 debug("vtoy_theme %s\n", filepath
);
247 grub_env_set("vtoy_theme", filepath
);
250 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
253 debug("vtoy_gfxmode %s\n", value
);
254 grub_env_set("vtoy_gfxmode", value
);
257 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
260 debug("display_mode %s\n", value
);
261 grub_env_set("vtoy_display_mode", value
);
264 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
267 debug("serial_param %s\n", value
);
268 grub_env_set("vtoy_serial_param", value
);
271 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
274 grub_env_set("VTLE_LFT", value
);
277 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
280 grub_env_set("VTLE_TOP", value
);
283 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
286 grub_env_set("VTLE_CLR", value
);
289 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
292 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
294 if (node
->enDataType
== JSON_TYPE_STRING
&&
295 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
297 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
298 grub_font_load(filepath
);
306 static int ventoy_plugin_check_path(const char *path
, const char *file
)
310 grub_printf("%s is NOT begin with '/' \n", file
);
314 if (grub_strchr(file
, '\\'))
316 grub_printf("%s contains invalid '\\' \n", file
);
320 if (grub_strstr(file
, "//"))
322 grub_printf("%s contains invalid double slash\n", file
);
326 if (grub_strstr(file
, "../"))
328 grub_printf("%s contains invalid '../' \n", file
);
332 if (!ventoy_is_file_exist("%s%s", path
, file
))
334 grub_printf("%s%s does NOT exist\n", path
, file
);
341 static int ventoy_plugin_check_fullpath
352 VTOY_JSON
*node
= json
;
353 VTOY_JSON
*child
= NULL
;
357 if (0 == grub_strcmp(key
, node
->pcName
))
361 node
= node
->pstNext
;
369 if (JSON_TYPE_STRING
== node
->enDataType
)
372 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
373 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
375 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
377 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
379 if (JSON_TYPE_STRING
!= child
->enDataType
)
381 grub_printf("Non string json type\n");
385 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
386 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
397 static int ventoy_plugin_parse_fullpath
402 file_fullpath
**fullpath
,
408 VTOY_JSON
*node
= json
;
409 VTOY_JSON
*child
= NULL
;
410 file_fullpath
*path
= NULL
;
414 if (0 == grub_strcmp(key
, node
->pcName
))
418 node
= node
->pstNext
;
426 if (JSON_TYPE_STRING
== node
->enDataType
)
428 debug("%s is string type data\n", node
->pcName
);
430 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
432 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
436 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
439 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
445 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
447 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
449 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
451 debug("Invalid data type:%d\n", child
->enDataType
);
456 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
458 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
463 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
465 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
467 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
481 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
486 const char *iso
= NULL
;
487 VTOY_JSON
*pNode
= NULL
;
489 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
491 grub_printf("Not array type %d\n", json
->enDataType
);
495 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
497 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
499 grub_printf("NOT object type\n");
502 if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image")) != NULL
)
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
);
527 else if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent")) != NULL
)
529 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
531 grub_printf("parent: %s [OK]\n", iso
);
532 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
534 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
536 if (autosel
>= 0 && autosel
<= pathnum
)
538 grub_printf("autosel: %d [OK]\n", autosel
);
542 grub_printf("autosel: %d [FAIL]\n", autosel
);
548 grub_printf("parent: %s [FAIL]\n", iso
);
553 grub_printf("image not found\n");
560 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
565 const char *iso
= NULL
;
566 VTOY_JSON
*pNode
= NULL
;
567 install_template
*node
= NULL
;
568 install_template
*next
= NULL
;
569 file_fullpath
*templatepath
= NULL
;
571 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
573 debug("Not array %d\n", json
->enDataType
);
577 if (g_install_template_head
)
579 for (node
= g_install_template_head
; node
; node
= next
)
582 grub_check_free(node
->templatepath
);
586 g_install_template_head
= NULL
;
589 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
591 type
= auto_install_type_file
;
592 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
595 type
= auto_install_type_parent
;
596 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
599 if (iso
&& iso
[0] == '/')
601 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
603 node
= grub_zalloc(sizeof(install_template
));
607 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
608 node
->templatepath
= templatepath
;
609 node
->templatenum
= pathnum
;
612 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
614 if (autosel
>= 0 && autosel
<= pathnum
)
616 node
->autosel
= autosel
;
620 if (g_install_template_head
)
622 node
->next
= g_install_template_head
;
625 g_install_template_head
= node
;
634 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
638 const char *iso
= NULL
;
639 VTOY_JSON
*pNode
= NULL
;
641 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
643 grub_printf("Not array type %d\n", json
->enDataType
);
647 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
649 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
651 grub_printf("NOT object type\n");
654 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
657 pos
= grub_strchr(iso
, '*');
658 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
660 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
661 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
665 grub_printf("image: %s [FAIL]\n", iso
);
670 grub_printf("image not found\n");
677 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
680 const char *iso
= NULL
;
681 VTOY_JSON
*pNode
= NULL
;
684 file_fullpath
*dudpath
= NULL
;
686 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
688 debug("Not array %d\n", json
->enDataType
);
694 for (node
= g_dud_head
; node
; node
= next
)
697 grub_check_free(node
->dudpath
);
704 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
706 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
707 if (iso
&& iso
[0] == '/')
709 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "dud", &dudpath
, &pathnum
))
711 node
= grub_zalloc(sizeof(dud
));
714 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
715 node
->dudpath
= dudpath
;
716 node
->dudnum
= pathnum
;
717 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
723 node
->next
= g_dud_head
;
740 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
747 vtoy_password tmpPwd
;
749 len
= (int)grub_strlen(pwdstr
);
752 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
756 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
758 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
760 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
761 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
763 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
767 for (i
= 0; i
< 16; i
++)
769 bytes
[0] = pwdstr
[4 + i
* 2];
770 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
773 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
775 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
779 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
783 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
785 else if ((len
- 4) > 32)
787 pos
= grub_strchr(pwdstr
+ 4, '#');
790 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
794 if (len
- 1 - (int)(long)(pos
- pwdstr
) != 32)
796 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
802 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
806 for (i
= 0; i
< 16; i
++)
808 bytes
[0] = pos
[i
* 2];
809 bytes
[1] = pos
[i
* 2 + 1];
812 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
814 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
818 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
823 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
827 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
833 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
839 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
845 static int ventoy_plugin_get_pwd_type(const char *pwd
)
850 for (i
= 0; pwd
&& i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
852 grub_snprintf(pwdtype
, sizeof(pwdtype
), "%spwd", g_menu_prefix
[i
]);
853 if (grub_strcmp(pwdtype
, pwd
) == 0)
855 return img_type_start
+ i
;
862 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
865 const char *iso
= NULL
;
866 const char *pwd
= NULL
;
867 VTOY_JSON
*pNode
= NULL
;
868 VTOY_JSON
*pCNode
= NULL
;
869 menu_password
*node
= NULL
;
870 menu_password
*tail
= NULL
;
871 menu_password
*next
= NULL
;
875 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
877 debug("Not object %d\n", json
->enDataType
);
883 for (node
= g_pwd_head
; node
; node
= next
)
892 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
894 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
896 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
898 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
900 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, g_file_type_pwd
+ type
);
902 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
904 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
906 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
911 type
= vtoy_menu_pwd_file
;
912 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
915 type
= vtoy_menu_pwd_parent
;
916 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent");
919 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
920 if (iso
&& pwd
&& iso
[0] == '/')
922 node
= grub_zalloc(sizeof(menu_password
));
926 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
928 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
952 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
956 const char *iso
= NULL
;
957 const char *pwd
= NULL
;
958 VTOY_JSON
*pNode
= NULL
;
959 VTOY_JSON
*pCNode
= NULL
;
961 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
963 grub_printf("Not object %d\n", json
->enDataType
);
967 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
969 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
971 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
973 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
977 grub_printf("Invalid bootpwd.\n");
980 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
982 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
984 grub_printf("%s:<%s>\n", pNode
->pcName
, pNode
->unData
.pcStrVal
);
988 grub_printf("Invalid pwd <%s>\n", pNode
->unData
.pcStrVal
);
991 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
994 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
996 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
998 grub_printf("Not object %d\n", pCNode
->enDataType
);
1002 if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file")) != NULL
)
1004 pos
= grub_strchr(iso
, '*');
1005 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1007 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1009 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1011 grub_printf("file:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1012 grub_printf("pwd:<%s>\n\n", pwd
);
1016 grub_printf("Invalid password for <%s>\n", iso
);
1021 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1024 else if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent")) != NULL
)
1026 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
1028 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1029 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1031 grub_printf("dir:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1032 grub_printf("pwd:<%s>\n\n", pwd
);
1036 grub_printf("Invalid password for <%s>\n", iso
);
1041 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1046 grub_printf("No file item found in json.\n");
1055 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
1060 const char *iso
= NULL
;
1061 VTOY_JSON
*pNode
= NULL
;
1063 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1065 grub_printf("Not array type %d\n", json
->enDataType
);
1069 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1071 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
1073 grub_printf("NOT object type\n");
1076 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1079 pos
= grub_strchr(iso
, '*');
1080 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1082 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
1083 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
1085 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1087 if (autosel
>= 0 && autosel
<= pathnum
)
1089 grub_printf("autosel: %d [OK]\n", autosel
);
1093 grub_printf("autosel: %d [FAIL]\n", autosel
);
1099 grub_printf("image: %s [FAIL]\n", iso
);
1104 grub_printf("image not found\n");
1111 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1115 const char *iso
= NULL
;
1116 VTOY_JSON
*pNode
= NULL
;
1117 persistence_config
*node
= NULL
;
1118 persistence_config
*next
= NULL
;
1119 file_fullpath
*backendpath
= NULL
;
1123 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1125 debug("Not array %d\n", json
->enDataType
);
1129 if (g_persistence_head
)
1131 for (node
= g_persistence_head
; node
; node
= next
)
1134 grub_check_free(node
->backendpath
);
1138 g_persistence_head
= NULL
;
1141 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1143 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1144 if (iso
&& iso
[0] == '/')
1146 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1148 node
= grub_zalloc(sizeof(persistence_config
));
1151 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1152 node
->backendpath
= backendpath
;
1153 node
->backendnum
= pathnum
;
1156 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1158 if (autosel
>= 0 && autosel
<= pathnum
)
1160 node
->autosel
= autosel
;
1164 if (g_persistence_head
)
1166 node
->next
= g_persistence_head
;
1169 g_persistence_head
= node
;
1178 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1181 const char *path
= NULL
;
1182 const char *alias
= NULL
;
1183 VTOY_JSON
*pNode
= NULL
;
1187 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1189 grub_printf("Not array %d\n", json
->enDataType
);
1193 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1195 type
= vtoy_alias_image_file
;
1196 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1199 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1200 type
= vtoy_alias_directory
;
1203 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1204 if (path
&& path
[0] == '/' && alias
)
1206 if (vtoy_alias_image_file
== type
)
1208 if (grub_strchr(path
, '*'))
1210 grub_printf("image: <%s> [ * ]\n", path
);
1212 else if (ventoy_is_file_exist("%s%s", isodisk
, path
))
1214 grub_printf("image: <%s> [ OK ]\n", path
);
1218 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1223 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1225 grub_printf("dir: <%s> [ OK ]\n", path
);
1229 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1233 grub_printf("alias: <%s>\n\n", alias
);
1240 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1243 const char *path
= NULL
;
1244 const char *alias
= NULL
;
1245 VTOY_JSON
*pNode
= NULL
;
1246 menu_alias
*node
= NULL
;
1247 menu_alias
*next
= NULL
;
1251 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1253 debug("Not array %d\n", json
->enDataType
);
1257 if (g_menu_alias_head
)
1259 for (node
= g_menu_alias_head
; node
; node
= next
)
1265 g_menu_alias_head
= NULL
;
1268 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1270 type
= vtoy_alias_image_file
;
1271 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1274 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1275 type
= vtoy_alias_directory
;
1278 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1279 if (path
&& path
[0] == '/' && alias
)
1281 node
= grub_zalloc(sizeof(menu_alias
));
1285 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1286 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1288 if (g_menu_alias_head
)
1290 node
->next
= g_menu_alias_head
;
1293 g_menu_alias_head
= node
;
1302 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1305 const char *path
= NULL
;
1306 const char *archive
= NULL
;
1307 VTOY_JSON
*pNode
= NULL
;
1311 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1313 grub_printf("Not array %d\n", json
->enDataType
);
1317 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1319 type
= injection_type_file
;
1320 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1323 type
= injection_type_parent
;
1324 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1327 grub_printf("image/parent not found\n");
1332 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1335 grub_printf("archive not found\n");
1339 if (type
== injection_type_file
)
1341 if (grub_strchr(path
, '*'))
1343 grub_printf("image: <%s> [*]\n", path
);
1347 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1352 grub_printf("parent: <%s> [%s]\n", path
,
1353 ventoy_is_dir_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1356 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1362 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1365 const char *path
= NULL
;
1366 const char *archive
= NULL
;
1367 VTOY_JSON
*pNode
= NULL
;
1368 injection_config
*node
= NULL
;
1369 injection_config
*next
= NULL
;
1373 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1375 debug("Not array %d\n", json
->enDataType
);
1379 if (g_injection_head
)
1381 for (node
= g_injection_head
; node
; node
= next
)
1387 g_injection_head
= NULL
;
1390 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1392 type
= injection_type_file
;
1393 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1396 type
= injection_type_parent
;
1397 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1400 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1401 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1403 node
= grub_zalloc(sizeof(injection_config
));
1407 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1408 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1410 if (g_injection_head
)
1412 node
->next
= g_injection_head
;
1415 g_injection_head
= node
;
1423 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1427 const char *key
= NULL
;
1428 const char *class = NULL
;
1429 VTOY_JSON
*pNode
= NULL
;
1430 menu_class
*tail
= NULL
;
1431 menu_class
*node
= NULL
;
1432 menu_class
*next
= NULL
;
1436 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1438 debug("Not array %d\n", json
->enDataType
);
1442 if (g_menu_class_head
)
1444 for (node
= g_menu_class_head
; node
; node
= next
)
1450 g_menu_class_head
= NULL
;
1453 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1456 type
= vtoy_class_image_file
;
1457 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1460 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1467 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1468 type
= vtoy_class_directory
;
1472 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1475 node
= grub_zalloc(sizeof(menu_class
));
1479 node
->parent
= parent
;
1480 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1481 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1483 if (g_menu_class_head
)
1489 g_menu_class_head
= node
;
1499 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1501 const char *name
= NULL
;
1502 const char *key
= NULL
;
1503 const char *class = NULL
;
1504 VTOY_JSON
*pNode
= NULL
;
1508 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1510 grub_printf("Not array %d\n", json
->enDataType
);
1514 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1517 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1521 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1525 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1529 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1532 grub_printf("%s: <%s>\n", name
, key
);
1533 grub_printf("class: <%s>\n\n", class);
1540 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1544 const char *key
= NULL
;
1545 const char *cfg
= NULL
;
1546 VTOY_JSON
*pNode
= NULL
;
1547 custom_boot
*tail
= NULL
;
1548 custom_boot
*node
= NULL
;
1549 custom_boot
*next
= NULL
;
1553 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1555 debug("Not array %d\n", json
->enDataType
);
1559 if (g_custom_boot_head
)
1561 for (node
= g_custom_boot_head
; node
; node
= next
)
1567 g_custom_boot_head
= NULL
;
1570 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1572 type
= vtoy_custom_boot_image_file
;
1573 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1576 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1577 type
= vtoy_custom_boot_directory
;
1580 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1583 node
= grub_zalloc(sizeof(custom_boot
));
1587 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1588 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1590 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
1592 if (g_custom_boot_head
)
1598 g_custom_boot_head
= node
;
1613 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
1617 const char *key
= NULL
;
1618 const char *cfg
= NULL
;
1619 VTOY_JSON
*pNode
= NULL
;
1623 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1625 grub_printf("Not array %d\n", json
->enDataType
);
1629 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1631 type
= vtoy_custom_boot_image_file
;
1632 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1635 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1636 type
= vtoy_custom_boot_directory
;
1639 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1640 len
= (int)grub_strlen(cfg
);
1643 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
1645 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
1649 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
1650 grub_printf("vcfg: <%s>\n\n", cfg
);
1658 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
1660 const char *isof
= NULL
;
1661 const char *orgf
= NULL
;
1662 const char *newf
= NULL
;
1663 VTOY_JSON
*pNode
= NULL
;
1664 conf_replace
*tail
= NULL
;
1665 conf_replace
*node
= NULL
;
1666 conf_replace
*next
= NULL
;
1670 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1672 debug("Not array %d\n", json
->enDataType
);
1676 if (g_conf_replace_head
)
1678 for (node
= g_conf_replace_head
; node
; node
= next
)
1684 g_conf_replace_head
= NULL
;
1687 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1689 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1690 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1691 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1692 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1694 node
= grub_zalloc(sizeof(conf_replace
));
1697 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
1698 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
1699 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
1701 if (g_conf_replace_head
)
1707 g_conf_replace_head
= node
;
1717 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
1719 const char *isof
= NULL
;
1720 const char *orgf
= NULL
;
1721 const char *newf
= NULL
;
1722 VTOY_JSON
*pNode
= NULL
;
1723 grub_file_t file
= NULL
;
1728 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1730 grub_printf("Not array %d\n", json
->enDataType
);
1734 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1736 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1737 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1738 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1739 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1741 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
1743 grub_printf("iso:<%s> [OK]\n", isof
);
1745 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
1746 grub_script_execute_sourcecode(cmd
);
1748 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
1751 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
1753 grub_printf("org:<%s> [OK]\n", orgf
);
1757 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
1759 grub_file_close(file
);
1763 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
1766 grub_script_execute_sourcecode("loopback -d vtisocheck");
1768 else if (grub_strchr(isof
, '*'))
1770 grub_printf("iso:<%s> [*]\n", isof
);
1771 grub_printf("org:<%s>\n", orgf
);
1775 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
1776 grub_printf("org:<%s>\n", orgf
);
1779 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
1782 if (file
->size
> vtoy_max_replace_file_size
)
1784 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
1788 grub_printf("new:<%s> [OK]\n", newf
);
1790 grub_file_close(file
);
1794 grub_printf("new:<%s> [NOT Exist]\n", newf
);
1803 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
1805 VTOY_JSON
*pNode
= NULL
;
1806 auto_memdisk
*node
= NULL
;
1807 auto_memdisk
*next
= NULL
;
1811 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1813 debug("Not array %d\n", json
->enDataType
);
1817 if (g_auto_memdisk_head
)
1819 for (node
= g_auto_memdisk_head
; node
; node
= next
)
1825 g_auto_memdisk_head
= NULL
;
1828 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1830 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1832 node
= grub_zalloc(sizeof(auto_memdisk
));
1835 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1837 if (g_auto_memdisk_head
)
1839 node
->next
= g_auto_memdisk_head
;
1842 g_auto_memdisk_head
= node
;
1850 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
1852 VTOY_JSON
*pNode
= NULL
;
1854 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1856 grub_printf("Not array %d\n", json
->enDataType
);
1860 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1862 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1864 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1866 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
1868 grub_printf(" [*]\n");
1870 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1872 grub_printf(" [OK]\n");
1876 grub_printf(" [NOT EXIST]\n");
1884 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
1886 VTOY_JSON
*pNode
= NULL
;
1887 image_list
*node
= NULL
;
1888 image_list
*next
= NULL
;
1889 image_list
*tail
= NULL
;
1893 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1895 debug("Not array %d\n", json
->enDataType
);
1899 if (g_image_list_head
)
1901 for (node
= g_image_list_head
; node
; node
= next
)
1907 g_image_list_head
= NULL
;
1910 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
1912 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
1916 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
1919 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1921 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1923 node
= grub_zalloc(sizeof(image_list
));
1926 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1928 if (g_image_list_head
)
1934 g_image_list_head
= node
;
1944 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
1946 VTOY_JSON
*pNode
= NULL
;
1948 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1950 grub_printf("Not array %d\n", json
->enDataType
);
1954 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1956 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1958 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1960 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
1962 grub_printf(" [*]\n");
1964 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1966 grub_printf(" [OK]\n");
1970 grub_printf(" [NOT EXIST]\n");
1978 static plugin_entry g_plugin_entries
[] =
1980 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
},
1981 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
},
1982 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
},
1983 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
},
1984 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
},
1985 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
},
1986 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
},
1987 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
},
1988 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
1989 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
1990 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
},
1991 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
},
1992 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
},
1993 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
},
1996 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
2000 VTOY_JSON
*cur
= json
;
2002 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
2006 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2008 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
2009 if (grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0 || grub_strcmp(key
, cur
->pcName
) == 0)
2011 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2012 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2023 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2028 VTOY_JSON
*json
= NULL
;
2033 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2036 return GRUB_ERR_NONE
;
2039 debug("json configuration file size %d\n", (int)file
->size
);
2041 buf
= grub_malloc(file
->size
+ 1);
2044 grub_file_close(file
);
2048 buf
[file
->size
] = 0;
2049 grub_file_read(file
, buf
, file
->size
);
2050 grub_file_close(file
);
2052 json
= vtoy_json_create();
2060 ret
= vtoy_json_parse(json
, buf
);
2063 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2064 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2066 debug("Failed to parse json string %d\n", ret
);
2071 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
2073 vtoy_json_destroy(json
);
2077 if (g_boot_pwd
.type
)
2079 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
2080 if (ventoy_check_password(&g_boot_pwd
, 3))
2082 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
2089 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2092 void ventoy_plugin_dump_injection(void)
2094 injection_config
*node
= NULL
;
2096 for (node
= g_injection_head
; node
; node
= node
->next
)
2098 grub_printf("\n%s:<%s>\n", (node
->type
== injection_type_file
) ? "IMAGE" : "PARENT", node
->isopath
);
2099 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
2106 void ventoy_plugin_dump_auto_install(void)
2109 install_template
*node
= NULL
;
2111 for (node
= g_install_template_head
; node
; node
= node
->next
)
2113 grub_printf("\n%s:<%s> <%d>\n",
2114 (node
->type
== auto_install_type_file
) ? "IMAGE" : "PARENT",
2115 node
->isopath
, node
->templatenum
);
2116 for (i
= 0; i
< node
->templatenum
; i
++)
2118 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
2125 void ventoy_plugin_dump_persistence(void)
2129 persistence_config
*node
= NULL
;
2130 ventoy_img_chunk_list chunk_list
;
2132 for (node
= g_persistence_head
; node
; node
= node
->next
)
2134 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
2136 for (i
= 0; i
< node
->backendnum
; i
++)
2138 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
2139 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
2142 grub_printf(" [ SUCCESS ]\n");
2143 grub_free(chunk_list
.chunk
);
2147 grub_printf(" [ FAILED ]\n");
2155 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
2158 install_template
*node
= NULL
;
2160 if (!g_install_template_head
)
2165 len
= (int)grub_strlen(isopath
);
2166 for (node
= g_install_template_head
; node
; node
= node
->next
)
2168 if (node
->type
== auto_install_type_file
)
2170 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2177 for (node
= g_install_template_head
; node
; node
= node
->next
)
2179 if (node
->type
== auto_install_type_parent
)
2181 if (node
->pathlen
< len
&& (isopath
[node
->pathlen
] == '/') &&
2182 ventoy_strncmp(node
->isopath
, isopath
, node
->pathlen
) == 0)
2192 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
2194 install_template
*node
= NULL
;
2196 node
= ventoy_plugin_find_install_template(isopath
);
2197 if ((!node
) || (!node
->templatepath
))
2202 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2207 return node
->templatepath
[node
->cursel
].path
;
2210 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2213 persistence_config
*node
= NULL
;
2215 if (!g_persistence_head
)
2220 len
= (int)grub_strlen(isopath
);
2221 for (node
= g_persistence_head
; node
; node
= node
->next
)
2223 if ((len
== node
->pathlen
) && (ventoy_strcmp(node
->isopath
, isopath
) == 0))
2232 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2235 grub_uint64_t start
= 0;
2236 grub_file_t file
= NULL
;
2237 persistence_config
*node
= NULL
;
2239 node
= ventoy_plugin_find_persistent(isopath
);
2240 if ((!node
) || (!node
->backendpath
))
2247 index
= node
->cursel
;
2250 if (index
< 0 || index
>= node
->backendnum
)
2255 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
2258 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
2262 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2263 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2264 if (NULL
== chunk_list
->chunk
)
2269 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2270 chunk_list
->cur_chunk
= 0;
2272 start
= file
->device
->disk
->partition
->start
;
2273 ventoy_get_block_list(file
, chunk_list
, start
);
2275 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2277 grub_free(chunk_list
->chunk
);
2278 chunk_list
->chunk
= NULL
;
2286 grub_file_close(file
);
2291 const char * ventoy_plugin_get_injection(const char *isopath
)
2294 injection_config
*node
= NULL
;
2296 if (!g_injection_head
)
2301 len
= (int)grub_strlen(isopath
);
2302 for (node
= g_injection_head
; node
; node
= node
->next
)
2304 if (node
->type
== injection_type_file
)
2306 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2308 return node
->archive
;
2313 for (node
= g_injection_head
; node
; node
= node
->next
)
2315 if (node
->type
== injection_type_parent
)
2317 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2318 ventoy_strncmp(node
->isopath
, isopath
, node
->pathlen
) == 0)
2320 return node
->archive
;
2328 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2331 menu_alias
*node
= NULL
;
2333 if (!g_menu_alias_head
)
2338 len
= (int)grub_strlen(isopath
);
2339 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2341 if (node
->type
== type
&& node
->pathlen
&&
2342 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2351 const char * ventoy_plugin_get_menu_class(int type
, const char *name
, const char *path
)
2354 menu_class
*node
= NULL
;
2356 if (!g_menu_class_head
)
2361 if (vtoy_class_image_file
== type
)
2363 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2365 if (node
->type
!= type
)
2372 len
= (int)grub_strlen(path
);
2373 if ((node
->patlen
< len
) && (path
[node
->patlen
] == '/') &&
2374 (grub_strncmp(path
, node
->pattern
, node
->patlen
) == 0))
2381 len
= (int)grub_strlen(name
);
2382 if ((node
->patlen
< len
) && grub_strstr(name
, node
->pattern
))
2391 len
= (int)grub_strlen(name
);
2392 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2394 if (node
->type
== type
&& node
->patlen
== len
&& grub_strncmp(name
, node
->pattern
, len
) == 0)
2404 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2407 custom_boot
*node
= NULL
;
2409 node
= grub_zalloc(sizeof(custom_boot
));
2412 node
->type
= vtoy_custom_boot_image_file
;
2413 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2414 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2417 len
= node
->pathlen
- 5;
2418 node
->path
[len
] = 0;
2419 node
->pathlen
= len
;
2421 if (g_custom_boot_head
)
2423 node
->next
= g_custom_boot_head
;
2425 g_custom_boot_head
= node
;
2431 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2435 custom_boot
*node
= NULL
;
2437 if (!g_custom_boot_head
)
2442 len
= (int)grub_strlen(isopath
);
2444 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2446 if (node
->type
== vtoy_custom_boot_image_file
)
2448 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2455 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2456 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2458 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2460 if (isopath
[i
] == '/')
2477 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2479 custom_boot
*node
= NULL
;
2485 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2487 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
2488 node
->path
, node
->cfg
);
2494 int ventoy_plugin_check_memdisk(const char *isopath
)
2497 auto_memdisk
*node
= NULL
;
2499 if (!g_auto_memdisk_head
)
2504 len
= (int)grub_strlen(isopath
);
2505 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
2507 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2516 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
2520 image_list
*node
= NULL
;
2522 if (!g_image_list_head
)
2527 len
= (int)grub_strlen(name
);
2529 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
2531 if (vtoy_class_directory
== type
)
2533 if (len
< node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
2540 if (len
== node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
2550 conf_replace
* ventoy_plugin_find_conf_replace(const char *iso
)
2555 if (!g_conf_replace_head
)
2560 len
= (int)grub_strlen(iso
);
2562 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
2564 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
2573 dud
* ventoy_plugin_find_dud(const char *iso
)
2583 len
= (int)grub_strlen(iso
);
2584 for (node
= g_dud_head
; node
; node
= node
->next
)
2586 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
2595 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
2601 for (i
= 0; i
< node
->dudnum
; i
++)
2603 if (node
->files
[i
].size
> 0)
2605 debug("file %d has been loaded\n", i
);
2609 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
2612 buf
= grub_malloc(file
->size
);
2615 grub_file_read(file
, buf
, file
->size
);
2616 node
->files
[i
].size
= (int)file
->size
;
2617 node
->files
[i
].buf
= buf
;
2619 grub_file_close(file
);
2626 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
2630 const char *pos
= NULL
;
2631 menu_password
*node
= NULL
;
2640 len
= (int)grub_strlen(isopath
);
2641 for (node
= g_pwd_head
; node
; node
= node
->next
)
2643 if (node
->type
== vtoy_menu_pwd_file
)
2645 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2647 return &(node
->password
);
2652 for (node
= g_pwd_head
; node
; node
= node
->next
)
2654 if (node
->type
== vtoy_menu_pwd_parent
)
2656 if (node
->pathlen
< len
&& (isopath
[node
->pathlen
] == '/') &&
2657 ventoy_strncmp(node
->isopath
, isopath
, node
->pathlen
) == 0)
2659 return &(node
->password
);
2667 if (*isopath
== '.')
2676 for (i
= 0; i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
2678 if (g_file_type_pwd
[i
].type
&& 0 == grub_strcasecmp(pos
+ 1, g_menu_prefix
[i
]))
2680 return g_file_type_pwd
+ i
;
2688 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2691 const vtoy_password
*pwd
= NULL
;
2696 pwd
= ventoy_plugin_get_password(args
[0]);
2699 if (0 == ventoy_check_password(pwd
, 1))
2717 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2724 VTOY_JSON
*node
= NULL
;
2725 VTOY_JSON
*json
= NULL
;
2734 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2737 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
2738 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
2742 buf
= grub_malloc(file
->size
+ 1);
2745 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
2749 buf
[file
->size
] = 0;
2750 grub_file_read(file
, buf
, file
->size
);
2752 json
= vtoy_json_create();
2755 grub_printf("Failed to create json\n");
2759 ret
= vtoy_json_parse(json
, buf
);
2762 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
2766 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
2767 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
2769 if (grub_strcmp(node
->pcName
, args
[1]) == 0 || grub_strcmp(node
->pcName
, key
) == 0)
2777 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
2781 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2783 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
2785 if (g_plugin_entries
[i
].checkfunc
)
2787 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
2794 check_free(file
, grub_file_close
);
2795 check_free(json
, vtoy_json_destroy
);
2796 grub_check_free(buf
);