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_is_parent(const char *pat
, int patlen
, const char *isopath
)
63 if (isopath
[patlen
] == '/' && ventoy_strncmp(pat
, isopath
, patlen
) == 0 &&
64 grub_strchr(isopath
+ patlen
+ 1, '/') == NULL
)
71 if (pat
[0] == '/' && grub_strchr(isopath
+ 1, '/') == NULL
)
80 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
83 VTOY_JSON
*pNode
= NULL
;
84 VTOY_JSON
*pChild
= NULL
;
88 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
90 grub_printf("Not array type %d\n", json
->enDataType
);
94 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
96 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
98 pChild
= pNode
->pstChild
;
99 if (pChild
->enDataType
== JSON_TYPE_STRING
)
101 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
103 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
104 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
108 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
113 grub_printf("%s is NOT string type\n", pChild
->pcName
);
119 grub_printf("%s is not an object\n", pNode
->pcName
);
127 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
129 VTOY_JSON
*pNode
= NULL
;
130 VTOY_JSON
*pChild
= NULL
;
134 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
136 debug("Not array %d\n", json
->enDataType
);
140 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
142 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
144 pChild
= pNode
->pstChild
;
145 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
147 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
155 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
161 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
164 grub_printf("file: %s\n", value
);
167 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
171 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
176 grub_printf("Theme file %s does NOT exist\n", value
);
181 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
184 grub_printf("gfxmode: %s\n", value
);
187 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
190 grub_printf("display_mode: %s\n", value
);
193 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
196 grub_printf("serial_param %s\n", value
);
199 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
202 grub_printf("ventoy_left: %s\n", value
);
205 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
208 grub_printf("ventoy_top: %s\n", value
);
211 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
214 grub_printf("ventoy_color: %s\n", value
);
217 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
220 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
222 if (node
->enDataType
== JSON_TYPE_STRING
)
224 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
226 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
230 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
237 grub_printf("fonts NOT found\n");
243 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
249 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
254 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
258 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
261 if (ventoy_is_file_exist(filepath
) == 0)
263 debug("Theme file %s does not exist\n", filepath
);
267 debug("vtoy_theme %s\n", filepath
);
268 grub_env_set("vtoy_theme", filepath
);
271 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
274 debug("vtoy_gfxmode %s\n", value
);
275 grub_env_set("vtoy_gfxmode", value
);
278 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
281 debug("display_mode %s\n", value
);
282 grub_env_set("vtoy_display_mode", value
);
285 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
288 debug("serial_param %s\n", value
);
289 grub_env_set("vtoy_serial_param", value
);
292 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
295 grub_env_set("VTLE_LFT", value
);
298 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
301 grub_env_set("VTLE_TOP", value
);
304 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
307 grub_env_set("VTLE_CLR", value
);
310 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
313 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
315 if (node
->enDataType
== JSON_TYPE_STRING
&&
316 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
318 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
319 grub_font_load(filepath
);
327 static int ventoy_plugin_check_path(const char *path
, const char *file
)
331 grub_printf("%s is NOT begin with '/' \n", file
);
335 if (grub_strchr(file
, '\\'))
337 grub_printf("%s contains invalid '\\' \n", file
);
341 if (grub_strstr(file
, "//"))
343 grub_printf("%s contains invalid double slash\n", file
);
347 if (grub_strstr(file
, "../"))
349 grub_printf("%s contains invalid '../' \n", file
);
353 if (!ventoy_is_file_exist("%s%s", path
, file
))
355 grub_printf("%s%s does NOT exist\n", path
, file
);
362 static int ventoy_plugin_check_fullpath
373 VTOY_JSON
*node
= json
;
374 VTOY_JSON
*child
= NULL
;
378 if (0 == grub_strcmp(key
, node
->pcName
))
382 node
= node
->pstNext
;
390 if (JSON_TYPE_STRING
== node
->enDataType
)
393 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
394 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
396 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
398 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
400 if (JSON_TYPE_STRING
!= child
->enDataType
)
402 grub_printf("Non string json type\n");
406 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
407 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
418 static int ventoy_plugin_parse_fullpath
423 file_fullpath
**fullpath
,
429 VTOY_JSON
*node
= json
;
430 VTOY_JSON
*child
= NULL
;
431 file_fullpath
*path
= NULL
;
435 if (0 == grub_strcmp(key
, node
->pcName
))
439 node
= node
->pstNext
;
447 if (JSON_TYPE_STRING
== node
->enDataType
)
449 debug("%s is string type data\n", node
->pcName
);
451 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
453 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
457 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
460 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
466 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
468 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
470 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
472 debug("Invalid data type:%d\n", child
->enDataType
);
477 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
479 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
484 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
486 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
488 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
502 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
507 const char *iso
= NULL
;
508 VTOY_JSON
*pNode
= NULL
;
510 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
512 grub_printf("Not array type %d\n", json
->enDataType
);
516 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
518 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
520 grub_printf("NOT object type\n");
523 if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image")) != NULL
)
525 pos
= grub_strchr(iso
, '*');
526 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
528 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
529 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
531 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
533 if (autosel
>= 0 && autosel
<= pathnum
)
535 grub_printf("autosel: %d [OK]\n", autosel
);
539 grub_printf("autosel: %d [FAIL]\n", autosel
);
545 grub_printf("image: %s [FAIL]\n", iso
);
548 else if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent")) != NULL
)
550 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
552 grub_printf("parent: %s [OK]\n", iso
);
553 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
555 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
557 if (autosel
>= 0 && autosel
<= pathnum
)
559 grub_printf("autosel: %d [OK]\n", autosel
);
563 grub_printf("autosel: %d [FAIL]\n", autosel
);
569 grub_printf("parent: %s [FAIL]\n", iso
);
574 grub_printf("image not found\n");
581 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
586 const char *iso
= NULL
;
587 VTOY_JSON
*pNode
= NULL
;
588 install_template
*node
= NULL
;
589 install_template
*next
= NULL
;
590 file_fullpath
*templatepath
= NULL
;
592 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
594 debug("Not array %d\n", json
->enDataType
);
598 if (g_install_template_head
)
600 for (node
= g_install_template_head
; node
; node
= next
)
603 grub_check_free(node
->templatepath
);
607 g_install_template_head
= NULL
;
610 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
612 type
= auto_install_type_file
;
613 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
616 type
= auto_install_type_parent
;
617 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
620 if (iso
&& iso
[0] == '/')
622 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
624 node
= grub_zalloc(sizeof(install_template
));
628 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
629 node
->templatepath
= templatepath
;
630 node
->templatenum
= pathnum
;
633 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
635 if (autosel
>= 0 && autosel
<= pathnum
)
637 node
->autosel
= autosel
;
641 if (g_install_template_head
)
643 node
->next
= g_install_template_head
;
646 g_install_template_head
= node
;
655 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
659 const char *iso
= NULL
;
660 VTOY_JSON
*pNode
= NULL
;
662 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
664 grub_printf("Not array type %d\n", json
->enDataType
);
668 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
670 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
672 grub_printf("NOT object type\n");
675 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
678 pos
= grub_strchr(iso
, '*');
679 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
681 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
682 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
686 grub_printf("image: %s [FAIL]\n", iso
);
691 grub_printf("image not found\n");
698 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
701 const char *iso
= NULL
;
702 VTOY_JSON
*pNode
= NULL
;
705 file_fullpath
*dudpath
= NULL
;
707 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
709 debug("Not array %d\n", json
->enDataType
);
715 for (node
= g_dud_head
; node
; node
= next
)
718 grub_check_free(node
->dudpath
);
725 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
727 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
728 if (iso
&& iso
[0] == '/')
730 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "dud", &dudpath
, &pathnum
))
732 node
= grub_zalloc(sizeof(dud
));
735 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
736 node
->dudpath
= dudpath
;
737 node
->dudnum
= pathnum
;
738 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
744 node
->next
= g_dud_head
;
761 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
768 vtoy_password tmpPwd
;
770 len
= (int)grub_strlen(pwdstr
);
773 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
777 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
779 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
781 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
782 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
784 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
788 for (i
= 0; i
< 16; i
++)
790 bytes
[0] = pwdstr
[4 + i
* 2];
791 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
794 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
796 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
800 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
804 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
806 else if ((len
- 4) > 32)
808 pos
= grub_strchr(pwdstr
+ 4, '#');
811 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
815 if (len
- 1 - (int)(long)(pos
- pwdstr
) != 32)
817 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
823 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
827 for (i
= 0; i
< 16; i
++)
829 bytes
[0] = pos
[i
* 2];
830 bytes
[1] = pos
[i
* 2 + 1];
833 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
835 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
839 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
844 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
848 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
854 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
860 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
866 static int ventoy_plugin_get_pwd_type(const char *pwd
)
871 for (i
= 0; pwd
&& i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
873 grub_snprintf(pwdtype
, sizeof(pwdtype
), "%spwd", g_menu_prefix
[i
]);
874 if (grub_strcmp(pwdtype
, pwd
) == 0)
876 return img_type_start
+ i
;
883 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
886 const char *iso
= NULL
;
887 const char *pwd
= NULL
;
888 VTOY_JSON
*pNode
= NULL
;
889 VTOY_JSON
*pCNode
= NULL
;
890 menu_password
*node
= NULL
;
891 menu_password
*tail
= NULL
;
892 menu_password
*next
= NULL
;
896 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
898 debug("Not object %d\n", json
->enDataType
);
904 for (node
= g_pwd_head
; node
; node
= next
)
913 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
915 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
917 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
919 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
921 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, g_file_type_pwd
+ type
);
923 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
925 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
927 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
932 type
= vtoy_menu_pwd_file
;
933 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
936 type
= vtoy_menu_pwd_parent
;
937 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent");
940 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
941 if (iso
&& pwd
&& iso
[0] == '/')
943 node
= grub_zalloc(sizeof(menu_password
));
947 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
949 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
973 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
977 const char *iso
= NULL
;
978 const char *pwd
= NULL
;
979 VTOY_JSON
*pNode
= NULL
;
980 VTOY_JSON
*pCNode
= NULL
;
982 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
984 grub_printf("Not object %d\n", json
->enDataType
);
988 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
990 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
992 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
994 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
998 grub_printf("Invalid bootpwd.\n");
1001 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1003 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1005 grub_printf("%s:<%s>\n", pNode
->pcName
, pNode
->unData
.pcStrVal
);
1009 grub_printf("Invalid pwd <%s>\n", pNode
->unData
.pcStrVal
);
1012 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1015 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1017 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1019 grub_printf("Not object %d\n", pCNode
->enDataType
);
1023 if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file")) != NULL
)
1025 pos
= grub_strchr(iso
, '*');
1026 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1028 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1030 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1032 grub_printf("file:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1033 grub_printf("pwd:<%s>\n\n", pwd
);
1037 grub_printf("Invalid password for <%s>\n", iso
);
1042 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1045 else if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent")) != NULL
)
1047 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
1049 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1050 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1052 grub_printf("dir:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1053 grub_printf("pwd:<%s>\n\n", pwd
);
1057 grub_printf("Invalid password for <%s>\n", iso
);
1062 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1067 grub_printf("No file item found in json.\n");
1076 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
1081 const char *iso
= NULL
;
1082 VTOY_JSON
*pNode
= NULL
;
1084 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1086 grub_printf("Not array type %d\n", json
->enDataType
);
1090 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1092 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
1094 grub_printf("NOT object type\n");
1097 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1100 pos
= grub_strchr(iso
, '*');
1101 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1103 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
1104 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
1106 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1108 if (autosel
>= 0 && autosel
<= pathnum
)
1110 grub_printf("autosel: %d [OK]\n", autosel
);
1114 grub_printf("autosel: %d [FAIL]\n", autosel
);
1120 grub_printf("image: %s [FAIL]\n", iso
);
1125 grub_printf("image not found\n");
1132 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1136 const char *iso
= NULL
;
1137 VTOY_JSON
*pNode
= NULL
;
1138 persistence_config
*node
= NULL
;
1139 persistence_config
*next
= NULL
;
1140 file_fullpath
*backendpath
= NULL
;
1144 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1146 debug("Not array %d\n", json
->enDataType
);
1150 if (g_persistence_head
)
1152 for (node
= g_persistence_head
; node
; node
= next
)
1155 grub_check_free(node
->backendpath
);
1159 g_persistence_head
= NULL
;
1162 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1164 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1165 if (iso
&& iso
[0] == '/')
1167 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1169 node
= grub_zalloc(sizeof(persistence_config
));
1172 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1173 node
->backendpath
= backendpath
;
1174 node
->backendnum
= pathnum
;
1177 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1179 if (autosel
>= 0 && autosel
<= pathnum
)
1181 node
->autosel
= autosel
;
1185 if (g_persistence_head
)
1187 node
->next
= g_persistence_head
;
1190 g_persistence_head
= node
;
1199 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1202 const char *path
= NULL
;
1203 const char *alias
= NULL
;
1204 VTOY_JSON
*pNode
= NULL
;
1208 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1210 grub_printf("Not array %d\n", json
->enDataType
);
1214 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1216 type
= vtoy_alias_image_file
;
1217 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1220 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1221 type
= vtoy_alias_directory
;
1224 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1225 if (path
&& path
[0] == '/' && alias
)
1227 if (vtoy_alias_image_file
== type
)
1229 if (grub_strchr(path
, '*'))
1231 grub_printf("image: <%s> [ * ]\n", path
);
1233 else if (ventoy_is_file_exist("%s%s", isodisk
, path
))
1235 grub_printf("image: <%s> [ OK ]\n", path
);
1239 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1244 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1246 grub_printf("dir: <%s> [ OK ]\n", path
);
1250 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1254 grub_printf("alias: <%s>\n\n", alias
);
1261 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1264 const char *path
= NULL
;
1265 const char *alias
= NULL
;
1266 VTOY_JSON
*pNode
= NULL
;
1267 menu_alias
*node
= NULL
;
1268 menu_alias
*next
= NULL
;
1272 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1274 debug("Not array %d\n", json
->enDataType
);
1278 if (g_menu_alias_head
)
1280 for (node
= g_menu_alias_head
; node
; node
= next
)
1286 g_menu_alias_head
= NULL
;
1289 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1291 type
= vtoy_alias_image_file
;
1292 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1295 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1296 type
= vtoy_alias_directory
;
1299 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1300 if (path
&& path
[0] == '/' && alias
)
1302 node
= grub_zalloc(sizeof(menu_alias
));
1306 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1307 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1309 if (g_menu_alias_head
)
1311 node
->next
= g_menu_alias_head
;
1314 g_menu_alias_head
= node
;
1323 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1326 const char *path
= NULL
;
1327 const char *archive
= NULL
;
1328 VTOY_JSON
*pNode
= NULL
;
1332 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1334 grub_printf("Not array %d\n", json
->enDataType
);
1338 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1340 type
= injection_type_file
;
1341 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1344 type
= injection_type_parent
;
1345 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1348 grub_printf("image/parent not found\n");
1353 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1356 grub_printf("archive not found\n");
1360 if (type
== injection_type_file
)
1362 if (grub_strchr(path
, '*'))
1364 grub_printf("image: <%s> [*]\n", path
);
1368 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1373 grub_printf("parent: <%s> [%s]\n", path
,
1374 ventoy_is_dir_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1377 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1383 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1386 const char *path
= NULL
;
1387 const char *archive
= NULL
;
1388 VTOY_JSON
*pNode
= NULL
;
1389 injection_config
*node
= NULL
;
1390 injection_config
*next
= NULL
;
1394 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1396 debug("Not array %d\n", json
->enDataType
);
1400 if (g_injection_head
)
1402 for (node
= g_injection_head
; node
; node
= next
)
1408 g_injection_head
= NULL
;
1411 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1413 type
= injection_type_file
;
1414 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1417 type
= injection_type_parent
;
1418 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1421 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1422 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1424 node
= grub_zalloc(sizeof(injection_config
));
1428 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1429 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1431 if (g_injection_head
)
1433 node
->next
= g_injection_head
;
1436 g_injection_head
= node
;
1444 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1448 const char *key
= NULL
;
1449 const char *class = NULL
;
1450 VTOY_JSON
*pNode
= NULL
;
1451 menu_class
*tail
= NULL
;
1452 menu_class
*node
= NULL
;
1453 menu_class
*next
= NULL
;
1457 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1459 debug("Not array %d\n", json
->enDataType
);
1463 if (g_menu_class_head
)
1465 for (node
= g_menu_class_head
; node
; node
= next
)
1471 g_menu_class_head
= NULL
;
1474 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1477 type
= vtoy_class_image_file
;
1478 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1481 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1488 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1489 type
= vtoy_class_directory
;
1493 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1496 node
= grub_zalloc(sizeof(menu_class
));
1500 node
->parent
= parent
;
1501 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1502 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1504 if (g_menu_class_head
)
1510 g_menu_class_head
= node
;
1520 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1522 const char *name
= NULL
;
1523 const char *key
= NULL
;
1524 const char *class = NULL
;
1525 VTOY_JSON
*pNode
= NULL
;
1529 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1531 grub_printf("Not array %d\n", json
->enDataType
);
1535 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1538 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1542 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1546 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1550 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1553 grub_printf("%s: <%s>\n", name
, key
);
1554 grub_printf("class: <%s>\n\n", class);
1561 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1565 const char *key
= NULL
;
1566 const char *cfg
= NULL
;
1567 VTOY_JSON
*pNode
= NULL
;
1568 custom_boot
*tail
= NULL
;
1569 custom_boot
*node
= NULL
;
1570 custom_boot
*next
= NULL
;
1574 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1576 debug("Not array %d\n", json
->enDataType
);
1580 if (g_custom_boot_head
)
1582 for (node
= g_custom_boot_head
; node
; node
= next
)
1588 g_custom_boot_head
= NULL
;
1591 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1593 type
= vtoy_custom_boot_image_file
;
1594 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1597 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1598 type
= vtoy_custom_boot_directory
;
1601 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1604 node
= grub_zalloc(sizeof(custom_boot
));
1608 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1609 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1611 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
1613 if (g_custom_boot_head
)
1619 g_custom_boot_head
= node
;
1634 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
1638 const char *key
= NULL
;
1639 const char *cfg
= NULL
;
1640 VTOY_JSON
*pNode
= NULL
;
1644 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1646 grub_printf("Not array %d\n", json
->enDataType
);
1650 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1652 type
= vtoy_custom_boot_image_file
;
1653 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1656 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1657 type
= vtoy_custom_boot_directory
;
1660 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1661 len
= (int)grub_strlen(cfg
);
1664 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
1666 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
1670 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
1671 grub_printf("vcfg: <%s>\n\n", cfg
);
1679 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
1681 const char *isof
= NULL
;
1682 const char *orgf
= NULL
;
1683 const char *newf
= NULL
;
1684 VTOY_JSON
*pNode
= NULL
;
1685 conf_replace
*tail
= NULL
;
1686 conf_replace
*node
= NULL
;
1687 conf_replace
*next
= NULL
;
1691 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1693 debug("Not array %d\n", json
->enDataType
);
1697 if (g_conf_replace_head
)
1699 for (node
= g_conf_replace_head
; node
; node
= next
)
1705 g_conf_replace_head
= NULL
;
1708 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1710 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1711 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1712 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1713 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1715 node
= grub_zalloc(sizeof(conf_replace
));
1718 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
1719 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
1720 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
1722 if (g_conf_replace_head
)
1728 g_conf_replace_head
= node
;
1738 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
1740 const char *isof
= NULL
;
1741 const char *orgf
= NULL
;
1742 const char *newf
= NULL
;
1743 VTOY_JSON
*pNode
= NULL
;
1744 grub_file_t file
= NULL
;
1749 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1751 grub_printf("Not array %d\n", json
->enDataType
);
1755 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1757 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1758 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1759 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1760 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1762 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
1764 grub_printf("iso:<%s> [OK]\n", isof
);
1766 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
1767 grub_script_execute_sourcecode(cmd
);
1769 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
1772 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
1774 grub_printf("org:<%s> [OK]\n", orgf
);
1778 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
1780 grub_file_close(file
);
1784 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
1787 grub_script_execute_sourcecode("loopback -d vtisocheck");
1789 else if (grub_strchr(isof
, '*'))
1791 grub_printf("iso:<%s> [*]\n", isof
);
1792 grub_printf("org:<%s>\n", orgf
);
1796 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
1797 grub_printf("org:<%s>\n", orgf
);
1800 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
1803 if (file
->size
> vtoy_max_replace_file_size
)
1805 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
1809 grub_printf("new:<%s> [OK]\n", newf
);
1811 grub_file_close(file
);
1815 grub_printf("new:<%s> [NOT Exist]\n", newf
);
1824 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
1826 VTOY_JSON
*pNode
= NULL
;
1827 auto_memdisk
*node
= NULL
;
1828 auto_memdisk
*next
= NULL
;
1832 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1834 debug("Not array %d\n", json
->enDataType
);
1838 if (g_auto_memdisk_head
)
1840 for (node
= g_auto_memdisk_head
; node
; node
= next
)
1846 g_auto_memdisk_head
= NULL
;
1849 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1851 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1853 node
= grub_zalloc(sizeof(auto_memdisk
));
1856 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1858 if (g_auto_memdisk_head
)
1860 node
->next
= g_auto_memdisk_head
;
1863 g_auto_memdisk_head
= node
;
1871 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
1873 VTOY_JSON
*pNode
= NULL
;
1875 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1877 grub_printf("Not array %d\n", json
->enDataType
);
1881 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1883 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1885 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1887 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
1889 grub_printf(" [*]\n");
1891 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1893 grub_printf(" [OK]\n");
1897 grub_printf(" [NOT EXIST]\n");
1905 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
1907 VTOY_JSON
*pNode
= NULL
;
1908 image_list
*node
= NULL
;
1909 image_list
*next
= NULL
;
1910 image_list
*tail
= NULL
;
1914 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1916 debug("Not array %d\n", json
->enDataType
);
1920 if (g_image_list_head
)
1922 for (node
= g_image_list_head
; node
; node
= next
)
1928 g_image_list_head
= NULL
;
1931 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
1933 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
1937 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
1940 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1942 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1944 node
= grub_zalloc(sizeof(image_list
));
1947 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1949 if (g_image_list_head
)
1955 g_image_list_head
= node
;
1965 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
1967 VTOY_JSON
*pNode
= NULL
;
1969 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1971 grub_printf("Not array %d\n", json
->enDataType
);
1975 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1977 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1979 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1981 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
1983 grub_printf(" [*]\n");
1985 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1987 grub_printf(" [OK]\n");
1991 grub_printf(" [NOT EXIST]\n");
1999 static plugin_entry g_plugin_entries
[] =
2001 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
},
2002 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
},
2003 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
},
2004 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
},
2005 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
},
2006 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
},
2007 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
},
2008 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
},
2009 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
2010 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
2011 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
},
2012 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
},
2013 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
},
2014 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
},
2017 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
2021 VTOY_JSON
*cur
= json
;
2023 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
2027 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2029 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
2030 if (grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0 || grub_strcmp(key
, cur
->pcName
) == 0)
2032 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2033 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2044 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2049 VTOY_JSON
*json
= NULL
;
2054 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2057 return GRUB_ERR_NONE
;
2060 debug("json configuration file size %d\n", (int)file
->size
);
2062 buf
= grub_malloc(file
->size
+ 1);
2065 grub_file_close(file
);
2069 buf
[file
->size
] = 0;
2070 grub_file_read(file
, buf
, file
->size
);
2071 grub_file_close(file
);
2073 json
= vtoy_json_create();
2081 ret
= vtoy_json_parse(json
, buf
);
2084 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2085 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2087 debug("Failed to parse json string %d\n", ret
);
2092 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
2094 vtoy_json_destroy(json
);
2098 if (g_boot_pwd
.type
)
2100 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
2101 if (ventoy_check_password(&g_boot_pwd
, 3))
2103 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
2110 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2113 void ventoy_plugin_dump_injection(void)
2115 injection_config
*node
= NULL
;
2117 for (node
= g_injection_head
; node
; node
= node
->next
)
2119 grub_printf("\n%s:<%s>\n", (node
->type
== injection_type_file
) ? "IMAGE" : "PARENT", node
->isopath
);
2120 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
2127 void ventoy_plugin_dump_auto_install(void)
2130 install_template
*node
= NULL
;
2132 for (node
= g_install_template_head
; node
; node
= node
->next
)
2134 grub_printf("\n%s:<%s> <%d>\n",
2135 (node
->type
== auto_install_type_file
) ? "IMAGE" : "PARENT",
2136 node
->isopath
, node
->templatenum
);
2137 for (i
= 0; i
< node
->templatenum
; i
++)
2139 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
2146 void ventoy_plugin_dump_persistence(void)
2150 persistence_config
*node
= NULL
;
2151 ventoy_img_chunk_list chunk_list
;
2153 for (node
= g_persistence_head
; node
; node
= node
->next
)
2155 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
2157 for (i
= 0; i
< node
->backendnum
; i
++)
2159 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
2160 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
2163 grub_printf(" [ SUCCESS ]\n");
2164 grub_free(chunk_list
.chunk
);
2168 grub_printf(" [ FAILED ]\n");
2176 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
2179 install_template
*node
= NULL
;
2181 if (!g_install_template_head
)
2186 len
= (int)grub_strlen(isopath
);
2187 for (node
= g_install_template_head
; node
; node
= node
->next
)
2189 if (node
->type
== auto_install_type_file
)
2191 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2198 for (node
= g_install_template_head
; node
; node
= node
->next
)
2200 if (node
->type
== auto_install_type_parent
)
2202 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2212 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
2214 install_template
*node
= NULL
;
2216 node
= ventoy_plugin_find_install_template(isopath
);
2217 if ((!node
) || (!node
->templatepath
))
2222 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2227 return node
->templatepath
[node
->cursel
].path
;
2230 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2233 persistence_config
*node
= NULL
;
2235 if (!g_persistence_head
)
2240 len
= (int)grub_strlen(isopath
);
2241 for (node
= g_persistence_head
; node
; node
= node
->next
)
2243 if ((len
== node
->pathlen
) && (ventoy_strcmp(node
->isopath
, isopath
) == 0))
2252 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2255 grub_uint64_t start
= 0;
2256 grub_file_t file
= NULL
;
2257 persistence_config
*node
= NULL
;
2259 node
= ventoy_plugin_find_persistent(isopath
);
2260 if ((!node
) || (!node
->backendpath
))
2267 index
= node
->cursel
;
2270 if (index
< 0 || index
>= node
->backendnum
)
2275 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
2278 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
2282 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2283 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2284 if (NULL
== chunk_list
->chunk
)
2289 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2290 chunk_list
->cur_chunk
= 0;
2292 start
= file
->device
->disk
->partition
->start
;
2293 ventoy_get_block_list(file
, chunk_list
, start
);
2295 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2297 grub_free(chunk_list
->chunk
);
2298 chunk_list
->chunk
= NULL
;
2306 grub_file_close(file
);
2311 const char * ventoy_plugin_get_injection(const char *isopath
)
2314 injection_config
*node
= NULL
;
2316 if (!g_injection_head
)
2321 len
= (int)grub_strlen(isopath
);
2322 for (node
= g_injection_head
; node
; node
= node
->next
)
2324 if (node
->type
== injection_type_file
)
2326 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2328 return node
->archive
;
2333 for (node
= g_injection_head
; node
; node
= node
->next
)
2335 if (node
->type
== injection_type_parent
)
2337 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2339 return node
->archive
;
2347 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2350 menu_alias
*node
= NULL
;
2352 if (!g_menu_alias_head
)
2357 len
= (int)grub_strlen(isopath
);
2358 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2360 if (node
->type
== type
&& node
->pathlen
&&
2361 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2370 const char * ventoy_plugin_get_menu_class(int type
, const char *name
, const char *path
)
2374 menu_class
*node
= NULL
;
2376 if (!g_menu_class_head
)
2381 namelen
= (int)grub_strlen(name
);
2382 pathlen
= (int)grub_strlen(path
);
2384 if (vtoy_class_image_file
== type
)
2386 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2388 if (node
->type
!= type
)
2395 if ((node
->patlen
< pathlen
) && ventoy_plugin_is_parent(node
->pattern
, node
->patlen
, path
))
2402 if ((node
->patlen
< namelen
) && grub_strstr(name
, node
->pattern
))
2411 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2413 if (node
->type
== type
&& node
->patlen
== namelen
&& grub_strncmp(name
, node
->pattern
, namelen
) == 0)
2423 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2426 custom_boot
*node
= NULL
;
2428 node
= grub_zalloc(sizeof(custom_boot
));
2431 node
->type
= vtoy_custom_boot_image_file
;
2432 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2433 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2436 len
= node
->pathlen
- 5;
2437 node
->path
[len
] = 0;
2438 node
->pathlen
= len
;
2440 if (g_custom_boot_head
)
2442 node
->next
= g_custom_boot_head
;
2444 g_custom_boot_head
= node
;
2450 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2454 custom_boot
*node
= NULL
;
2456 if (!g_custom_boot_head
)
2461 len
= (int)grub_strlen(isopath
);
2463 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2465 if (node
->type
== vtoy_custom_boot_image_file
)
2467 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2474 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2475 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2477 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2479 if (isopath
[i
] == '/')
2496 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2498 custom_boot
*node
= NULL
;
2504 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2506 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
2507 node
->path
, node
->cfg
);
2513 int ventoy_plugin_check_memdisk(const char *isopath
)
2516 auto_memdisk
*node
= NULL
;
2518 if (!g_auto_memdisk_head
)
2523 len
= (int)grub_strlen(isopath
);
2524 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
2526 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2535 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
2539 image_list
*node
= NULL
;
2541 if (!g_image_list_head
)
2546 len
= (int)grub_strlen(name
);
2548 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
2550 if (vtoy_class_directory
== type
)
2552 if (len
< node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
2559 if (len
== node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
2569 conf_replace
* ventoy_plugin_find_conf_replace(const char *iso
)
2574 if (!g_conf_replace_head
)
2579 len
= (int)grub_strlen(iso
);
2581 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
2583 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
2592 dud
* ventoy_plugin_find_dud(const char *iso
)
2602 len
= (int)grub_strlen(iso
);
2603 for (node
= g_dud_head
; node
; node
= node
->next
)
2605 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
2614 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
2620 for (i
= 0; i
< node
->dudnum
; i
++)
2622 if (node
->files
[i
].size
> 0)
2624 debug("file %d has been loaded\n", i
);
2628 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
2631 buf
= grub_malloc(file
->size
);
2634 grub_file_read(file
, buf
, file
->size
);
2635 node
->files
[i
].size
= (int)file
->size
;
2636 node
->files
[i
].buf
= buf
;
2638 grub_file_close(file
);
2645 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
2649 const char *pos
= NULL
;
2650 menu_password
*node
= NULL
;
2659 len
= (int)grub_strlen(isopath
);
2660 for (node
= g_pwd_head
; node
; node
= node
->next
)
2662 if (node
->type
== vtoy_menu_pwd_file
)
2664 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2666 return &(node
->password
);
2671 for (node
= g_pwd_head
; node
; node
= node
->next
)
2673 if (node
->type
== vtoy_menu_pwd_parent
)
2675 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2677 return &(node
->password
);
2685 if (*isopath
== '.')
2694 for (i
= 0; i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
2696 if (g_file_type_pwd
[i
].type
&& 0 == grub_strcasecmp(pos
+ 1, g_menu_prefix
[i
]))
2698 return g_file_type_pwd
+ i
;
2706 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2709 const vtoy_password
*pwd
= NULL
;
2714 pwd
= ventoy_plugin_get_password(args
[0]);
2717 if (0 == ventoy_check_password(pwd
, 1))
2735 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2742 VTOY_JSON
*node
= NULL
;
2743 VTOY_JSON
*json
= NULL
;
2752 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2755 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
2756 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
2760 buf
= grub_malloc(file
->size
+ 1);
2763 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
2767 buf
[file
->size
] = 0;
2768 grub_file_read(file
, buf
, file
->size
);
2770 json
= vtoy_json_create();
2773 grub_printf("Failed to create json\n");
2777 ret
= vtoy_json_parse(json
, buf
);
2780 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
2784 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
2785 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
2787 if (grub_strcmp(node
->pcName
, args
[1]) == 0 || grub_strcmp(node
->pcName
, key
) == 0)
2795 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
2799 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2801 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
2803 if (g_plugin_entries
[i
].checkfunc
)
2805 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
2812 check_free(file
, grub_file_close
);
2813 check_free(json
, vtoy_json_destroy
);
2814 grub_check_free(buf
);