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 g_theme_num
= 0;
60 static theme_list
*g_theme_head
= NULL
;
61 static int g_theme_random
= vtoy_theme_random_boot_second
;
62 static char g_theme_single_file
[256];
64 static int ventoy_plugin_is_parent(const char *pat
, int patlen
, const char *isopath
)
68 if (isopath
[patlen
] == '/' && ventoy_strncmp(pat
, isopath
, patlen
) == 0 &&
69 grub_strchr(isopath
+ patlen
+ 1, '/') == NULL
)
76 if (pat
[0] == '/' && grub_strchr(isopath
+ 1, '/') == NULL
)
85 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
88 VTOY_JSON
*pNode
= NULL
;
89 VTOY_JSON
*pChild
= NULL
;
93 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
95 grub_printf("Not array type %d\n", json
->enDataType
);
99 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
101 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
103 pChild
= pNode
->pstChild
;
104 if (pChild
->enDataType
== JSON_TYPE_STRING
)
106 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
108 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
109 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
113 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
118 grub_printf("%s is NOT string type\n", pChild
->pcName
);
124 grub_printf("%s is not an object\n", pNode
->pcName
);
132 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
134 VTOY_JSON
*pNode
= NULL
;
135 VTOY_JSON
*pChild
= NULL
;
139 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
141 debug("Not array %d\n", json
->enDataType
);
145 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
147 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
149 pChild
= pNode
->pstChild
;
150 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
152 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
160 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
166 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
169 grub_printf("file: %s\n", value
);
172 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
176 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
181 grub_printf("Theme file %s does NOT exist\n", value
);
187 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
190 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
192 value
= node
->unData
.pcStrVal
;
193 grub_printf("file: %s\n", value
);
196 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
200 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
205 grub_printf("Theme file %s does NOT exist\n", value
);
210 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
213 grub_printf("random: %s\n", value
);
218 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
221 grub_printf("gfxmode: %s\n", value
);
224 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
227 grub_printf("display_mode: %s\n", value
);
230 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
233 grub_printf("serial_param %s\n", value
);
236 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
239 grub_printf("ventoy_left: %s\n", value
);
242 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
245 grub_printf("ventoy_top: %s\n", value
);
248 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
251 grub_printf("ventoy_color: %s\n", value
);
254 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
257 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
259 if (node
->enDataType
== JSON_TYPE_STRING
)
261 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
263 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
267 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
274 grub_printf("fonts NOT found\n");
280 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
284 VTOY_JSON
*node
= NULL
;
285 theme_list
*tail
= NULL
;
286 theme_list
*themenode
= NULL
;
288 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
293 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
297 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
300 if (ventoy_check_file_exist(filepath
) == 0)
302 debug("Theme file %s does not exist\n", filepath
);
306 debug("vtoy_theme %s\n", filepath
);
307 grub_env_set("vtoy_theme", filepath
);
308 grub_snprintf(g_theme_single_file
, sizeof(g_theme_single_file
), "%s", filepath
);
312 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
315 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
317 value
= node
->unData
.pcStrVal
;
320 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
324 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
327 if (ventoy_check_file_exist(filepath
) == 0)
332 themenode
= grub_zalloc(sizeof(theme_list
));
335 grub_snprintf(themenode
->theme
.path
, sizeof(themenode
->theme
.path
), "%s", filepath
);
338 tail
->next
= themenode
;
342 g_theme_head
= themenode
;
349 grub_env_set("vtoy_theme", "random");
350 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
353 if (grub_strcmp(value
, "boot_second") == 0)
355 g_theme_random
= vtoy_theme_random_boot_second
;
357 else if (grub_strcmp(value
, "boot_day") == 0)
359 g_theme_random
= vtoy_theme_random_boot_day
;
361 else if (grub_strcmp(value
, "boot_month") == 0)
363 g_theme_random
= vtoy_theme_random_boot_month
;
369 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
372 debug("vtoy_gfxmode %s\n", value
);
373 grub_env_set("vtoy_gfxmode", value
);
376 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
379 debug("display_mode %s\n", value
);
380 grub_env_set("vtoy_display_mode", value
);
383 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
386 debug("serial_param %s\n", value
);
387 grub_env_set("vtoy_serial_param", value
);
390 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
393 grub_env_set("VTLE_LFT", value
);
396 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
399 grub_env_set("VTLE_TOP", value
);
402 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
405 grub_env_set("VTLE_CLR", value
);
408 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
411 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
413 if (node
->enDataType
== JSON_TYPE_STRING
&&
414 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
416 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
417 grub_font_load(filepath
);
425 static int ventoy_plugin_check_path(const char *path
, const char *file
)
429 grub_printf("%s is NOT begin with '/' \n", file
);
433 if (grub_strchr(file
, '\\'))
435 grub_printf("%s contains invalid '\\' \n", file
);
439 if (grub_strstr(file
, "//"))
441 grub_printf("%s contains invalid double slash\n", file
);
445 if (grub_strstr(file
, "../"))
447 grub_printf("%s contains invalid '../' \n", file
);
451 if (!ventoy_is_file_exist("%s%s", path
, file
))
453 grub_printf("%s%s does NOT exist\n", path
, file
);
460 static int ventoy_plugin_check_fullpath
471 VTOY_JSON
*node
= json
;
472 VTOY_JSON
*child
= NULL
;
476 if (0 == grub_strcmp(key
, node
->pcName
))
480 node
= node
->pstNext
;
488 if (JSON_TYPE_STRING
== node
->enDataType
)
491 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
492 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
494 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
496 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
498 if (JSON_TYPE_STRING
!= child
->enDataType
)
500 grub_printf("Non string json type\n");
504 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
505 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
516 static int ventoy_plugin_parse_fullpath
521 file_fullpath
**fullpath
,
527 VTOY_JSON
*node
= json
;
528 VTOY_JSON
*child
= NULL
;
529 file_fullpath
*path
= NULL
;
533 if (0 == grub_strcmp(key
, node
->pcName
))
537 node
= node
->pstNext
;
545 if (JSON_TYPE_STRING
== node
->enDataType
)
547 debug("%s is string type data\n", node
->pcName
);
549 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
551 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
555 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
558 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
564 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
566 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
568 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
570 debug("Invalid data type:%d\n", child
->enDataType
);
575 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
577 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
582 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
584 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
586 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
600 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
605 const char *iso
= NULL
;
606 VTOY_JSON
*pNode
= NULL
;
608 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
610 grub_printf("Not array type %d\n", json
->enDataType
);
614 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
616 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
618 grub_printf("NOT object type\n");
621 if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image")) != NULL
)
623 pos
= grub_strchr(iso
, '*');
624 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
626 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
627 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
629 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
631 if (autosel
>= 0 && autosel
<= pathnum
)
633 grub_printf("autosel: %d [OK]\n", autosel
);
637 grub_printf("autosel: %d [FAIL]\n", autosel
);
643 grub_printf("image: %s [FAIL]\n", iso
);
646 else if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent")) != NULL
)
648 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
650 grub_printf("parent: %s [OK]\n", iso
);
651 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
653 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
655 if (autosel
>= 0 && autosel
<= pathnum
)
657 grub_printf("autosel: %d [OK]\n", autosel
);
661 grub_printf("autosel: %d [FAIL]\n", autosel
);
667 grub_printf("parent: %s [FAIL]\n", iso
);
672 grub_printf("image not found\n");
679 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
684 const char *iso
= NULL
;
685 VTOY_JSON
*pNode
= NULL
;
686 install_template
*node
= NULL
;
687 install_template
*next
= NULL
;
688 file_fullpath
*templatepath
= NULL
;
690 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
692 debug("Not array %d\n", json
->enDataType
);
696 if (g_install_template_head
)
698 for (node
= g_install_template_head
; node
; node
= next
)
701 grub_check_free(node
->templatepath
);
705 g_install_template_head
= NULL
;
708 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
710 type
= auto_install_type_file
;
711 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
714 type
= auto_install_type_parent
;
715 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
718 if (iso
&& iso
[0] == '/')
720 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
722 node
= grub_zalloc(sizeof(install_template
));
726 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
727 node
->templatepath
= templatepath
;
728 node
->templatenum
= pathnum
;
731 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
733 if (autosel
>= 0 && autosel
<= pathnum
)
735 node
->autosel
= autosel
;
739 if (g_install_template_head
)
741 node
->next
= g_install_template_head
;
744 g_install_template_head
= node
;
753 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
757 const char *iso
= NULL
;
758 VTOY_JSON
*pNode
= NULL
;
760 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
762 grub_printf("Not array type %d\n", json
->enDataType
);
766 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
768 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
770 grub_printf("NOT object type\n");
773 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
776 pos
= grub_strchr(iso
, '*');
777 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
779 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
780 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
784 grub_printf("image: %s [FAIL]\n", iso
);
789 grub_printf("image not found\n");
796 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
799 const char *iso
= NULL
;
800 VTOY_JSON
*pNode
= NULL
;
803 file_fullpath
*dudpath
= NULL
;
805 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
807 debug("Not array %d\n", json
->enDataType
);
813 for (node
= g_dud_head
; node
; node
= next
)
816 grub_check_free(node
->dudpath
);
823 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
825 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
826 if (iso
&& iso
[0] == '/')
828 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "dud", &dudpath
, &pathnum
))
830 node
= grub_zalloc(sizeof(dud
));
833 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
834 node
->dudpath
= dudpath
;
835 node
->dudnum
= pathnum
;
836 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
842 node
->next
= g_dud_head
;
859 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
866 vtoy_password tmpPwd
;
868 len
= (int)grub_strlen(pwdstr
);
871 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
875 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
877 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
879 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
880 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
882 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
886 for (i
= 0; i
< 16; i
++)
888 bytes
[0] = pwdstr
[4 + i
* 2];
889 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
892 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
894 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
898 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
902 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
904 else if ((len
- 4) > 32)
906 pos
= grub_strchr(pwdstr
+ 4, '#');
909 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
913 if (len
- 1 - (int)(long)(pos
- pwdstr
) != 32)
915 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
921 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
925 for (i
= 0; i
< 16; i
++)
927 bytes
[0] = pos
[i
* 2];
928 bytes
[1] = pos
[i
* 2 + 1];
931 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
933 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
937 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
942 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
946 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
952 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
958 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
964 static int ventoy_plugin_get_pwd_type(const char *pwd
)
969 for (i
= 0; pwd
&& i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
971 grub_snprintf(pwdtype
, sizeof(pwdtype
), "%spwd", g_menu_prefix
[i
]);
972 if (grub_strcmp(pwdtype
, pwd
) == 0)
974 return img_type_start
+ i
;
981 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
984 const char *iso
= NULL
;
985 const char *pwd
= NULL
;
986 VTOY_JSON
*pNode
= NULL
;
987 VTOY_JSON
*pCNode
= NULL
;
988 menu_password
*node
= NULL
;
989 menu_password
*tail
= NULL
;
990 menu_password
*next
= NULL
;
994 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
996 debug("Not object %d\n", json
->enDataType
);
1002 for (node
= g_pwd_head
; node
; node
= next
)
1011 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1013 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1015 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
1017 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1019 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, g_file_type_pwd
+ type
);
1021 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1023 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1025 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1030 type
= vtoy_menu_pwd_file
;
1031 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
1034 type
= vtoy_menu_pwd_parent
;
1035 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent");
1038 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1039 if (iso
&& pwd
&& iso
[0] == '/')
1041 node
= grub_zalloc(sizeof(menu_password
));
1045 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1047 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
1071 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
1075 const char *iso
= NULL
;
1076 const char *pwd
= NULL
;
1077 VTOY_JSON
*pNode
= NULL
;
1078 VTOY_JSON
*pCNode
= NULL
;
1080 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1082 grub_printf("Not object %d\n", json
->enDataType
);
1086 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1088 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1090 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1092 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
1096 grub_printf("Invalid bootpwd.\n");
1099 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1101 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1103 grub_printf("%s:<%s>\n", pNode
->pcName
, pNode
->unData
.pcStrVal
);
1107 grub_printf("Invalid pwd <%s>\n", pNode
->unData
.pcStrVal
);
1110 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1113 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1115 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1117 grub_printf("Not object %d\n", pCNode
->enDataType
);
1121 if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file")) != NULL
)
1123 pos
= grub_strchr(iso
, '*');
1124 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1126 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1128 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1130 grub_printf("file:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1131 grub_printf("pwd:<%s>\n\n", pwd
);
1135 grub_printf("Invalid password for <%s>\n", iso
);
1140 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1143 else if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent")) != NULL
)
1145 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
1147 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1148 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1150 grub_printf("dir:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1151 grub_printf("pwd:<%s>\n\n", pwd
);
1155 grub_printf("Invalid password for <%s>\n", iso
);
1160 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1165 grub_printf("No file item found in json.\n");
1174 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
1179 const char *iso
= NULL
;
1180 VTOY_JSON
*pNode
= NULL
;
1182 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1184 grub_printf("Not array type %d\n", json
->enDataType
);
1188 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1190 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
1192 grub_printf("NOT object type\n");
1195 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1198 pos
= grub_strchr(iso
, '*');
1199 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1201 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
1202 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
1204 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1206 if (autosel
>= 0 && autosel
<= pathnum
)
1208 grub_printf("autosel: %d [OK]\n", autosel
);
1212 grub_printf("autosel: %d [FAIL]\n", autosel
);
1218 grub_printf("image: %s [FAIL]\n", iso
);
1223 grub_printf("image not found\n");
1230 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1234 const char *iso
= NULL
;
1235 VTOY_JSON
*pNode
= NULL
;
1236 persistence_config
*node
= NULL
;
1237 persistence_config
*next
= NULL
;
1238 file_fullpath
*backendpath
= NULL
;
1242 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1244 debug("Not array %d\n", json
->enDataType
);
1248 if (g_persistence_head
)
1250 for (node
= g_persistence_head
; node
; node
= next
)
1253 grub_check_free(node
->backendpath
);
1257 g_persistence_head
= NULL
;
1260 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1262 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1263 if (iso
&& iso
[0] == '/')
1265 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1267 node
= grub_zalloc(sizeof(persistence_config
));
1270 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1271 node
->backendpath
= backendpath
;
1272 node
->backendnum
= pathnum
;
1275 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1277 if (autosel
>= 0 && autosel
<= pathnum
)
1279 node
->autosel
= autosel
;
1283 if (g_persistence_head
)
1285 node
->next
= g_persistence_head
;
1288 g_persistence_head
= node
;
1297 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1300 const char *path
= NULL
;
1301 const char *alias
= NULL
;
1302 VTOY_JSON
*pNode
= NULL
;
1306 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1308 grub_printf("Not array %d\n", json
->enDataType
);
1312 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1314 type
= vtoy_alias_image_file
;
1315 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1318 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1319 type
= vtoy_alias_directory
;
1322 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1323 if (path
&& path
[0] == '/' && alias
)
1325 if (vtoy_alias_image_file
== type
)
1327 if (grub_strchr(path
, '*'))
1329 grub_printf("image: <%s> [ * ]\n", path
);
1331 else if (ventoy_is_file_exist("%s%s", isodisk
, path
))
1333 grub_printf("image: <%s> [ OK ]\n", path
);
1337 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1342 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1344 grub_printf("dir: <%s> [ OK ]\n", path
);
1348 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1352 grub_printf("alias: <%s>\n\n", alias
);
1359 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1362 const char *path
= NULL
;
1363 const char *alias
= NULL
;
1364 VTOY_JSON
*pNode
= NULL
;
1365 menu_alias
*node
= NULL
;
1366 menu_alias
*next
= NULL
;
1370 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1372 debug("Not array %d\n", json
->enDataType
);
1376 if (g_menu_alias_head
)
1378 for (node
= g_menu_alias_head
; node
; node
= next
)
1384 g_menu_alias_head
= NULL
;
1387 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1389 type
= vtoy_alias_image_file
;
1390 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1393 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1394 type
= vtoy_alias_directory
;
1397 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1398 if (path
&& path
[0] == '/' && alias
)
1400 node
= grub_zalloc(sizeof(menu_alias
));
1404 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1405 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1407 if (g_menu_alias_head
)
1409 node
->next
= g_menu_alias_head
;
1412 g_menu_alias_head
= node
;
1421 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1424 const char *path
= NULL
;
1425 const char *archive
= NULL
;
1426 VTOY_JSON
*pNode
= NULL
;
1430 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1432 grub_printf("Not array %d\n", json
->enDataType
);
1436 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1438 type
= injection_type_file
;
1439 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1442 type
= injection_type_parent
;
1443 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1446 grub_printf("image/parent not found\n");
1451 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1454 grub_printf("archive not found\n");
1458 if (type
== injection_type_file
)
1460 if (grub_strchr(path
, '*'))
1462 grub_printf("image: <%s> [*]\n", path
);
1466 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1471 grub_printf("parent: <%s> [%s]\n", path
,
1472 ventoy_is_dir_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1475 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1481 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1484 const char *path
= NULL
;
1485 const char *archive
= NULL
;
1486 VTOY_JSON
*pNode
= NULL
;
1487 injection_config
*node
= NULL
;
1488 injection_config
*next
= NULL
;
1492 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1494 debug("Not array %d\n", json
->enDataType
);
1498 if (g_injection_head
)
1500 for (node
= g_injection_head
; node
; node
= next
)
1506 g_injection_head
= NULL
;
1509 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1511 type
= injection_type_file
;
1512 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1515 type
= injection_type_parent
;
1516 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1519 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1520 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1522 node
= grub_zalloc(sizeof(injection_config
));
1526 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1527 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1529 if (g_injection_head
)
1531 node
->next
= g_injection_head
;
1534 g_injection_head
= node
;
1542 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1546 const char *key
= NULL
;
1547 const char *class = NULL
;
1548 VTOY_JSON
*pNode
= NULL
;
1549 menu_class
*tail
= NULL
;
1550 menu_class
*node
= NULL
;
1551 menu_class
*next
= NULL
;
1555 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1557 debug("Not array %d\n", json
->enDataType
);
1561 if (g_menu_class_head
)
1563 for (node
= g_menu_class_head
; node
; node
= next
)
1569 g_menu_class_head
= NULL
;
1572 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1575 type
= vtoy_class_image_file
;
1576 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1579 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1586 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1587 type
= vtoy_class_directory
;
1591 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1594 node
= grub_zalloc(sizeof(menu_class
));
1598 node
->parent
= parent
;
1599 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1600 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1602 if (g_menu_class_head
)
1608 g_menu_class_head
= node
;
1618 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1620 const char *name
= NULL
;
1621 const char *key
= NULL
;
1622 const char *class = NULL
;
1623 VTOY_JSON
*pNode
= NULL
;
1627 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1629 grub_printf("Not array %d\n", json
->enDataType
);
1633 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1636 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1640 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1644 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1648 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1651 grub_printf("%s: <%s>\n", name
, key
);
1652 grub_printf("class: <%s>\n\n", class);
1659 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1663 const char *key
= NULL
;
1664 const char *cfg
= NULL
;
1665 VTOY_JSON
*pNode
= NULL
;
1666 custom_boot
*tail
= NULL
;
1667 custom_boot
*node
= NULL
;
1668 custom_boot
*next
= NULL
;
1672 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1674 debug("Not array %d\n", json
->enDataType
);
1678 if (g_custom_boot_head
)
1680 for (node
= g_custom_boot_head
; node
; node
= next
)
1686 g_custom_boot_head
= NULL
;
1689 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1691 type
= vtoy_custom_boot_image_file
;
1692 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1695 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1696 type
= vtoy_custom_boot_directory
;
1699 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1702 node
= grub_zalloc(sizeof(custom_boot
));
1706 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1707 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1709 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
1711 if (g_custom_boot_head
)
1717 g_custom_boot_head
= node
;
1732 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
1736 const char *key
= NULL
;
1737 const char *cfg
= NULL
;
1738 VTOY_JSON
*pNode
= NULL
;
1742 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1744 grub_printf("Not array %d\n", json
->enDataType
);
1748 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1750 type
= vtoy_custom_boot_image_file
;
1751 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1754 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1755 type
= vtoy_custom_boot_directory
;
1758 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1759 len
= (int)grub_strlen(cfg
);
1762 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
1764 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
1768 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
1769 grub_printf("vcfg: <%s>\n\n", cfg
);
1777 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
1779 const char *isof
= NULL
;
1780 const char *orgf
= NULL
;
1781 const char *newf
= NULL
;
1782 VTOY_JSON
*pNode
= NULL
;
1783 conf_replace
*tail
= NULL
;
1784 conf_replace
*node
= NULL
;
1785 conf_replace
*next
= NULL
;
1789 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1791 debug("Not array %d\n", json
->enDataType
);
1795 if (g_conf_replace_head
)
1797 for (node
= g_conf_replace_head
; node
; node
= next
)
1803 g_conf_replace_head
= NULL
;
1806 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1808 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1809 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1810 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1811 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1813 node
= grub_zalloc(sizeof(conf_replace
));
1816 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
1817 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
1818 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
1820 if (g_conf_replace_head
)
1826 g_conf_replace_head
= node
;
1836 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
1838 const char *isof
= NULL
;
1839 const char *orgf
= NULL
;
1840 const char *newf
= NULL
;
1841 VTOY_JSON
*pNode
= NULL
;
1842 grub_file_t file
= NULL
;
1847 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1849 grub_printf("Not array %d\n", json
->enDataType
);
1853 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1855 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1856 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1857 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1858 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1860 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
1862 grub_printf("iso:<%s> [OK]\n", isof
);
1864 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
1865 grub_script_execute_sourcecode(cmd
);
1867 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
1870 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
1872 grub_printf("org:<%s> [OK]\n", orgf
);
1876 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
1878 grub_file_close(file
);
1882 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
1885 grub_script_execute_sourcecode("loopback -d vtisocheck");
1887 else if (grub_strchr(isof
, '*'))
1889 grub_printf("iso:<%s> [*]\n", isof
);
1890 grub_printf("org:<%s>\n", orgf
);
1894 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
1895 grub_printf("org:<%s>\n", orgf
);
1898 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
1901 if (file
->size
> vtoy_max_replace_file_size
)
1903 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
1907 grub_printf("new:<%s> [OK]\n", newf
);
1909 grub_file_close(file
);
1913 grub_printf("new:<%s> [NOT Exist]\n", newf
);
1922 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
1924 VTOY_JSON
*pNode
= NULL
;
1925 auto_memdisk
*node
= NULL
;
1926 auto_memdisk
*next
= NULL
;
1930 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1932 debug("Not array %d\n", json
->enDataType
);
1936 if (g_auto_memdisk_head
)
1938 for (node
= g_auto_memdisk_head
; node
; node
= next
)
1944 g_auto_memdisk_head
= NULL
;
1947 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1949 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1951 node
= grub_zalloc(sizeof(auto_memdisk
));
1954 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1956 if (g_auto_memdisk_head
)
1958 node
->next
= g_auto_memdisk_head
;
1961 g_auto_memdisk_head
= node
;
1969 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
1971 VTOY_JSON
*pNode
= NULL
;
1973 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1975 grub_printf("Not array %d\n", json
->enDataType
);
1979 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1981 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1983 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1985 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
1987 grub_printf(" [*]\n");
1989 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1991 grub_printf(" [OK]\n");
1995 grub_printf(" [NOT EXIST]\n");
2003 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
2005 VTOY_JSON
*pNode
= NULL
;
2006 image_list
*node
= NULL
;
2007 image_list
*next
= NULL
;
2008 image_list
*tail
= NULL
;
2012 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2014 debug("Not array %d\n", json
->enDataType
);
2018 if (g_image_list_head
)
2020 for (node
= g_image_list_head
; node
; node
= next
)
2026 g_image_list_head
= NULL
;
2029 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
2031 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
2035 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
2038 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2040 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2042 node
= grub_zalloc(sizeof(image_list
));
2045 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2047 if (g_image_list_head
)
2053 g_image_list_head
= node
;
2063 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
2065 VTOY_JSON
*pNode
= NULL
;
2067 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2069 grub_printf("Not array %d\n", json
->enDataType
);
2073 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2075 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2077 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2079 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2081 grub_printf(" [*]\n");
2083 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2085 grub_printf(" [OK]\n");
2089 grub_printf(" [NOT EXIST]\n");
2097 static plugin_entry g_plugin_entries
[] =
2099 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
},
2100 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
},
2101 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
},
2102 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
},
2103 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
},
2104 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
},
2105 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
},
2106 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
},
2107 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
2108 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
2109 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
},
2110 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
},
2111 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
},
2112 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
},
2115 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
2119 VTOY_JSON
*cur
= json
;
2121 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
2125 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2127 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
2128 if (grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0 || grub_strcmp(key
, cur
->pcName
) == 0)
2130 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2131 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2142 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2147 VTOY_JSON
*json
= NULL
;
2152 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2155 return GRUB_ERR_NONE
;
2158 debug("json configuration file size %d\n", (int)file
->size
);
2160 buf
= grub_malloc(file
->size
+ 1);
2163 grub_file_close(file
);
2167 buf
[file
->size
] = 0;
2168 grub_file_read(file
, buf
, file
->size
);
2169 grub_file_close(file
);
2171 json
= vtoy_json_create();
2179 ret
= vtoy_json_parse(json
, buf
);
2182 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2183 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2185 debug("Failed to parse json string %d\n", ret
);
2190 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
2192 vtoy_json_destroy(json
);
2196 if (g_boot_pwd
.type
)
2198 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
2199 if (ventoy_check_password(&g_boot_pwd
, 3))
2201 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
2208 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2211 void ventoy_plugin_dump_injection(void)
2213 injection_config
*node
= NULL
;
2215 for (node
= g_injection_head
; node
; node
= node
->next
)
2217 grub_printf("\n%s:<%s>\n", (node
->type
== injection_type_file
) ? "IMAGE" : "PARENT", node
->isopath
);
2218 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
2225 void ventoy_plugin_dump_auto_install(void)
2228 install_template
*node
= NULL
;
2230 for (node
= g_install_template_head
; node
; node
= node
->next
)
2232 grub_printf("\n%s:<%s> <%d>\n",
2233 (node
->type
== auto_install_type_file
) ? "IMAGE" : "PARENT",
2234 node
->isopath
, node
->templatenum
);
2235 for (i
= 0; i
< node
->templatenum
; i
++)
2237 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
2244 void ventoy_plugin_dump_persistence(void)
2248 persistence_config
*node
= NULL
;
2249 ventoy_img_chunk_list chunk_list
;
2251 for (node
= g_persistence_head
; node
; node
= node
->next
)
2253 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
2255 for (i
= 0; i
< node
->backendnum
; i
++)
2257 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
2258 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
2261 grub_printf(" [ SUCCESS ]\n");
2262 grub_free(chunk_list
.chunk
);
2266 grub_printf(" [ FAILED ]\n");
2274 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
2277 install_template
*node
= NULL
;
2279 if (!g_install_template_head
)
2284 len
= (int)grub_strlen(isopath
);
2285 for (node
= g_install_template_head
; node
; node
= node
->next
)
2287 if (node
->type
== auto_install_type_file
)
2289 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2296 for (node
= g_install_template_head
; node
; node
= node
->next
)
2298 if (node
->type
== auto_install_type_parent
)
2300 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2310 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
2312 install_template
*node
= NULL
;
2314 node
= ventoy_plugin_find_install_template(isopath
);
2315 if ((!node
) || (!node
->templatepath
))
2320 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2325 return node
->templatepath
[node
->cursel
].path
;
2328 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2331 persistence_config
*node
= NULL
;
2333 if (!g_persistence_head
)
2338 len
= (int)grub_strlen(isopath
);
2339 for (node
= g_persistence_head
; node
; node
= node
->next
)
2341 if ((len
== node
->pathlen
) && (ventoy_strcmp(node
->isopath
, isopath
) == 0))
2350 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2353 grub_uint64_t start
= 0;
2354 grub_file_t file
= NULL
;
2355 persistence_config
*node
= NULL
;
2357 node
= ventoy_plugin_find_persistent(isopath
);
2358 if ((!node
) || (!node
->backendpath
))
2365 index
= node
->cursel
;
2368 if (index
< 0 || index
>= node
->backendnum
)
2373 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
2376 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
2380 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2381 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2382 if (NULL
== chunk_list
->chunk
)
2387 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2388 chunk_list
->cur_chunk
= 0;
2390 start
= file
->device
->disk
->partition
->start
;
2391 ventoy_get_block_list(file
, chunk_list
, start
);
2393 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2395 grub_free(chunk_list
->chunk
);
2396 chunk_list
->chunk
= NULL
;
2404 grub_file_close(file
);
2409 const char * ventoy_plugin_get_injection(const char *isopath
)
2412 injection_config
*node
= NULL
;
2414 if (!g_injection_head
)
2419 len
= (int)grub_strlen(isopath
);
2420 for (node
= g_injection_head
; node
; node
= node
->next
)
2422 if (node
->type
== injection_type_file
)
2424 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2426 return node
->archive
;
2431 for (node
= g_injection_head
; node
; node
= node
->next
)
2433 if (node
->type
== injection_type_parent
)
2435 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2437 return node
->archive
;
2445 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2448 menu_alias
*node
= NULL
;
2450 if (!g_menu_alias_head
)
2455 len
= (int)grub_strlen(isopath
);
2456 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2458 if (node
->type
== type
&& node
->pathlen
&&
2459 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2468 const char * ventoy_plugin_get_menu_class(int type
, const char *name
, const char *path
)
2472 menu_class
*node
= NULL
;
2474 if (!g_menu_class_head
)
2479 namelen
= (int)grub_strlen(name
);
2480 pathlen
= (int)grub_strlen(path
);
2482 if (vtoy_class_image_file
== type
)
2484 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2486 if (node
->type
!= type
)
2491 if (node
->parent
== 0)
2493 if ((node
->patlen
< namelen
) && grub_strstr(name
, node
->pattern
))
2500 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2502 if (node
->type
!= type
)
2509 if ((node
->patlen
< pathlen
) && ventoy_plugin_is_parent(node
->pattern
, node
->patlen
, path
))
2518 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2520 if (node
->type
== type
&& node
->patlen
== namelen
&& grub_strncmp(name
, node
->pattern
, namelen
) == 0)
2530 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2533 custom_boot
*node
= NULL
;
2535 node
= grub_zalloc(sizeof(custom_boot
));
2538 node
->type
= vtoy_custom_boot_image_file
;
2539 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2540 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2543 len
= node
->pathlen
- 5;
2544 node
->path
[len
] = 0;
2545 node
->pathlen
= len
;
2547 if (g_custom_boot_head
)
2549 node
->next
= g_custom_boot_head
;
2551 g_custom_boot_head
= node
;
2557 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2561 custom_boot
*node
= NULL
;
2563 if (!g_custom_boot_head
)
2568 len
= (int)grub_strlen(isopath
);
2570 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2572 if (node
->type
== vtoy_custom_boot_image_file
)
2574 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2581 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2582 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2584 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2586 if (isopath
[i
] == '/')
2603 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2605 custom_boot
*node
= NULL
;
2611 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2613 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
2614 node
->path
, node
->cfg
);
2620 int ventoy_plugin_check_memdisk(const char *isopath
)
2623 auto_memdisk
*node
= NULL
;
2625 if (!g_auto_memdisk_head
)
2630 len
= (int)grub_strlen(isopath
);
2631 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
2633 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2642 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
2646 image_list
*node
= NULL
;
2648 if (!g_image_list_head
)
2653 len
= (int)grub_strlen(name
);
2655 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
2657 if (vtoy_class_directory
== type
)
2659 if (len
< node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
2666 if (len
== node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
2676 conf_replace
* ventoy_plugin_find_conf_replace(const char *iso
)
2681 if (!g_conf_replace_head
)
2686 len
= (int)grub_strlen(iso
);
2688 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
2690 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
2699 dud
* ventoy_plugin_find_dud(const char *iso
)
2709 len
= (int)grub_strlen(iso
);
2710 for (node
= g_dud_head
; node
; node
= node
->next
)
2712 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
2721 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
2727 for (i
= 0; i
< node
->dudnum
; i
++)
2729 if (node
->files
[i
].size
> 0)
2731 debug("file %d has been loaded\n", i
);
2735 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
2738 buf
= grub_malloc(file
->size
);
2741 grub_file_read(file
, buf
, file
->size
);
2742 node
->files
[i
].size
= (int)file
->size
;
2743 node
->files
[i
].buf
= buf
;
2745 grub_file_close(file
);
2752 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
2756 const char *pos
= NULL
;
2757 menu_password
*node
= NULL
;
2766 len
= (int)grub_strlen(isopath
);
2767 for (node
= g_pwd_head
; node
; node
= node
->next
)
2769 if (node
->type
== vtoy_menu_pwd_file
)
2771 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2773 return &(node
->password
);
2778 for (node
= g_pwd_head
; node
; node
= node
->next
)
2780 if (node
->type
== vtoy_menu_pwd_parent
)
2782 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2784 return &(node
->password
);
2792 if (*isopath
== '.')
2801 for (i
= 0; i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
2803 if (g_file_type_pwd
[i
].type
&& 0 == grub_strcasecmp(pos
+ 1, g_menu_prefix
[i
]))
2805 return g_file_type_pwd
+ i
;
2813 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2816 const vtoy_password
*pwd
= NULL
;
2821 pwd
= ventoy_plugin_get_password(args
[0]);
2824 if (0 == ventoy_check_password(pwd
, 1))
2842 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2849 VTOY_JSON
*node
= NULL
;
2850 VTOY_JSON
*json
= NULL
;
2859 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2862 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
2863 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
2867 buf
= grub_malloc(file
->size
+ 1);
2870 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
2874 buf
[file
->size
] = 0;
2875 grub_file_read(file
, buf
, file
->size
);
2877 json
= vtoy_json_create();
2880 grub_printf("Failed to create json\n");
2884 ret
= vtoy_json_parse(json
, buf
);
2887 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
2891 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
2892 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
2894 if (grub_strcmp(node
->pcName
, args
[1]) == 0 || grub_strcmp(node
->pcName
, key
) == 0)
2902 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
2906 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2908 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
2910 if (g_plugin_entries
[i
].checkfunc
)
2912 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
2919 check_free(file
, grub_file_close
);
2920 check_free(json
, vtoy_json_destroy
);
2921 grub_check_free(buf
);
2926 grub_err_t
ventoy_cmd_set_theme(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2928 grub_uint32_t i
= 0;
2929 grub_uint32_t mod
= 0;
2930 theme_list
*node
= g_theme_head
;
2931 struct grub_datetime datetime
;
2937 if (g_theme_single_file
[0])
2939 debug("single theme %s\n", g_theme_single_file
);
2940 grub_env_set("theme", g_theme_single_file
);
2944 debug("g_theme_num = %d\n", g_theme_num
);
2946 if (g_theme_num
== 0)
2951 grub_memset(&datetime
, 0, sizeof(datetime
));
2952 grub_get_datetime(&datetime
);
2954 if (g_theme_random
== vtoy_theme_random_boot_second
)
2956 grub_divmod32((grub_uint32_t
)datetime
.second
, (grub_uint32_t
)g_theme_num
, &mod
);
2958 else if (g_theme_random
== vtoy_theme_random_boot_day
)
2960 grub_divmod32((grub_uint32_t
)datetime
.day
, (grub_uint32_t
)g_theme_num
, &mod
);
2962 else if (g_theme_random
== vtoy_theme_random_boot_month
)
2964 grub_divmod32((grub_uint32_t
)datetime
.month
, (grub_uint32_t
)g_theme_num
, &mod
);
2967 debug("%04d/%02d/%02d %02d:%02d:%02d radom:%d mod:%d\n",
2968 datetime
.year
, datetime
.month
, datetime
.day
,
2969 datetime
.hour
, datetime
.minute
, datetime
.second
,
2970 g_theme_random
, mod
);
2972 for (i
= 0; i
< mod
&& node
; i
++)
2977 debug("random theme %s\n", node
->theme
.path
);
2978 grub_env_set("theme", node
->theme
.path
);
2981 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);