1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include <grub/types.h>
21 #include <grub/misc.h>
25 #include <grub/disk.h>
26 #include <grub/device.h>
27 #include <grub/term.h>
28 #include <grub/partition.h>
29 #include <grub/file.h>
30 #include <grub/normal.h>
31 #include <grub/extcmd.h>
32 #include <grub/datetime.h>
33 #include <grub/i18n.h>
35 #include <grub/crypto.h>
36 #include <grub/time.h>
37 #include <grub/font.h>
38 #include <grub/ventoy.h>
39 #include "ventoy_def.h"
41 GRUB_MOD_LICENSE ("GPLv3+");
43 char g_arch_mode_suffix
[64];
44 static char g_iso_disk_name
[128];
45 static vtoy_password g_boot_pwd
;
46 static vtoy_password g_file_type_pwd
[img_type_max
];
47 static install_template
*g_install_template_head
= NULL
;
48 static dud
*g_dud_head
= NULL
;
49 static menu_password
*g_pwd_head
= NULL
;
50 static persistence_config
*g_persistence_head
= NULL
;
51 static menu_tip
*g_menu_tip_head
= NULL
;
52 static menu_alias
*g_menu_alias_head
= NULL
;
53 static menu_class
*g_menu_class_head
= NULL
;
54 static custom_boot
*g_custom_boot_head
= NULL
;
55 static injection_config
*g_injection_head
= NULL
;
56 static auto_memdisk
*g_auto_memdisk_head
= NULL
;
57 static image_list
*g_image_list_head
= NULL
;
58 static conf_replace
*g_conf_replace_head
= NULL
;
60 static int g_theme_num
= 0;
61 static theme_list
*g_theme_head
= NULL
;
62 static int g_theme_random
= vtoy_theme_random_boot_second
;
63 static char g_theme_single_file
[256];
65 static int ventoy_plugin_is_parent(const char *pat
, int patlen
, const char *isopath
)
69 if (isopath
[patlen
] == '/' && ventoy_strncmp(pat
, isopath
, patlen
) == 0 &&
70 grub_strchr(isopath
+ patlen
+ 1, '/') == NULL
)
77 if (pat
[0] == '/' && grub_strchr(isopath
+ 1, '/') == NULL
)
86 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
89 VTOY_JSON
*pNode
= NULL
;
90 VTOY_JSON
*pChild
= NULL
;
94 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
96 grub_printf("Not array type %d\n", json
->enDataType
);
100 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
102 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
104 pChild
= pNode
->pstChild
;
105 if (pChild
->enDataType
== JSON_TYPE_STRING
)
107 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
109 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
110 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
114 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
119 grub_printf("%s is NOT string type\n", pChild
->pcName
);
125 grub_printf("%s is not an object\n", pNode
->pcName
);
133 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
135 VTOY_JSON
*pNode
= NULL
;
136 VTOY_JSON
*pChild
= NULL
;
140 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
142 debug("Not array %d\n", json
->enDataType
);
146 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
148 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
150 pChild
= pNode
->pstChild
;
151 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
153 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
161 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
167 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
170 grub_printf("file: %s\n", value
);
173 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
177 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
182 grub_printf("Theme file %s does NOT exist\n", value
);
188 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
191 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
193 value
= node
->unData
.pcStrVal
;
194 grub_printf("file: %s\n", value
);
197 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
201 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
206 grub_printf("Theme file %s does NOT exist\n", value
);
211 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
214 grub_printf("random: %s\n", value
);
219 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
222 grub_printf("gfxmode: %s\n", value
);
225 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
228 grub_printf("display_mode: %s\n", value
);
231 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
234 grub_printf("serial_param %s\n", value
);
237 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
240 grub_printf("ventoy_left: %s\n", value
);
243 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
246 grub_printf("ventoy_top: %s\n", value
);
249 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
252 grub_printf("ventoy_color: %s\n", value
);
255 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
258 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
260 if (node
->enDataType
== JSON_TYPE_STRING
)
262 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
264 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
268 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
275 grub_printf("fonts NOT found\n");
281 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
285 VTOY_JSON
*node
= NULL
;
286 theme_list
*tail
= NULL
;
287 theme_list
*themenode
= NULL
;
289 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
294 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
298 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
301 if (ventoy_check_file_exist(filepath
) == 0)
303 debug("Theme file %s does not exist\n", filepath
);
307 debug("vtoy_theme %s\n", filepath
);
308 ventoy_env_export("vtoy_theme", filepath
);
309 grub_snprintf(g_theme_single_file
, sizeof(g_theme_single_file
), "%s", filepath
);
313 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "file");
316 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
318 value
= node
->unData
.pcStrVal
;
321 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
325 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
328 if (ventoy_check_file_exist(filepath
) == 0)
333 themenode
= grub_zalloc(sizeof(theme_list
));
336 grub_snprintf(themenode
->theme
.path
, sizeof(themenode
->theme
.path
), "%s", filepath
);
339 tail
->next
= themenode
;
343 g_theme_head
= themenode
;
350 ventoy_env_export("vtoy_theme", "random");
351 value
= vtoy_json_get_string_ex(json
->pstChild
, "random");
354 if (grub_strcmp(value
, "boot_second") == 0)
356 g_theme_random
= vtoy_theme_random_boot_second
;
358 else if (grub_strcmp(value
, "boot_day") == 0)
360 g_theme_random
= vtoy_theme_random_boot_day
;
362 else if (grub_strcmp(value
, "boot_month") == 0)
364 g_theme_random
= vtoy_theme_random_boot_month
;
370 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
373 debug("vtoy_gfxmode %s\n", value
);
374 ventoy_env_export("vtoy_gfxmode", value
);
377 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
380 debug("display_mode %s\n", value
);
381 ventoy_env_export("vtoy_display_mode", value
);
384 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
387 debug("serial_param %s\n", value
);
388 ventoy_env_export("vtoy_serial_param", value
);
391 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
394 ventoy_env_export("VTLE_LFT", value
);
397 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
400 ventoy_env_export("VTLE_TOP", value
);
403 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
406 ventoy_env_export("VTLE_CLR", value
);
409 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
412 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
414 if (node
->enDataType
== JSON_TYPE_STRING
&&
415 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
417 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
418 grub_font_load(filepath
);
426 static int ventoy_plugin_check_path(const char *path
, const char *file
)
430 grub_printf("%s is NOT begin with '/' \n", file
);
434 if (grub_strchr(file
, '\\'))
436 grub_printf("%s contains invalid '\\' \n", file
);
440 if (grub_strstr(file
, "//"))
442 grub_printf("%s contains invalid double slash\n", file
);
446 if (grub_strstr(file
, "../"))
448 grub_printf("%s contains invalid '../' \n", file
);
452 if (!ventoy_is_file_exist("%s%s", path
, file
))
454 grub_printf("%s%s does NOT exist\n", path
, file
);
461 static int ventoy_plugin_check_fullpath
472 VTOY_JSON
*node
= json
;
473 VTOY_JSON
*child
= NULL
;
477 if (0 == grub_strcmp(key
, node
->pcName
))
481 node
= node
->pstNext
;
489 if (JSON_TYPE_STRING
== node
->enDataType
)
492 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
493 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
495 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
497 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
499 if (JSON_TYPE_STRING
!= child
->enDataType
)
501 grub_printf("Non string json type\n");
505 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
506 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
517 static int ventoy_plugin_parse_fullpath
522 file_fullpath
**fullpath
,
528 VTOY_JSON
*node
= json
;
529 VTOY_JSON
*child
= NULL
;
530 file_fullpath
*path
= NULL
;
534 if (0 == grub_strcmp(key
, node
->pcName
))
538 node
= node
->pstNext
;
546 if (JSON_TYPE_STRING
== node
->enDataType
)
548 debug("%s is string type data\n", node
->pcName
);
550 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
552 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
556 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
559 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
565 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
567 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
569 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
571 debug("Invalid data type:%d\n", child
->enDataType
);
576 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
578 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
583 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
585 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
587 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
601 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
607 const char *iso
= NULL
;
608 VTOY_JSON
*pNode
= NULL
;
610 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
612 grub_printf("Not array type %d\n", json
->enDataType
);
616 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
618 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
620 grub_printf("NOT object type\n");
623 if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image")) != NULL
)
625 pos
= grub_strchr(iso
, '*');
626 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
628 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
629 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
631 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
633 if (autosel
>= 0 && autosel
<= pathnum
)
635 grub_printf("autosel: %d [OK]\n", autosel
);
639 grub_printf("autosel: %d [FAIL]\n", autosel
);
643 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
647 grub_printf("timeout: %d [OK]\n", timeout
);
651 grub_printf("timeout: %d [FAIL]\n", timeout
);
657 grub_printf("image: %s [FAIL]\n", iso
);
660 else if ((iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent")) != NULL
)
662 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
664 grub_printf("parent: %s [OK]\n", iso
);
665 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
667 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
669 if (autosel
>= 0 && autosel
<= pathnum
)
671 grub_printf("autosel: %d [OK]\n", autosel
);
675 grub_printf("autosel: %d [FAIL]\n", autosel
);
679 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
683 grub_printf("timeout: %d [OK]\n", timeout
);
687 grub_printf("timeout: %d [FAIL]\n", timeout
);
693 grub_printf("parent: %s [FAIL]\n", iso
);
698 grub_printf("image not found\n");
705 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
711 const char *iso
= NULL
;
712 VTOY_JSON
*pNode
= NULL
;
713 install_template
*node
= NULL
;
714 install_template
*next
= NULL
;
715 file_fullpath
*templatepath
= NULL
;
717 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
719 debug("Not array %d\n", json
->enDataType
);
723 if (g_install_template_head
)
725 for (node
= g_install_template_head
; node
; node
= next
)
728 grub_check_free(node
->templatepath
);
732 g_install_template_head
= NULL
;
735 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
737 type
= auto_install_type_file
;
738 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
741 type
= auto_install_type_parent
;
742 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
745 if (iso
&& iso
[0] == '/')
747 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
749 node
= grub_zalloc(sizeof(install_template
));
753 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
754 node
->templatepath
= templatepath
;
755 node
->templatenum
= pathnum
;
759 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
761 if (autosel
>= 0 && autosel
<= pathnum
)
763 node
->autosel
= autosel
;
767 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
771 node
->timeout
= timeout
;
775 if (g_install_template_head
)
777 node
->next
= g_install_template_head
;
780 g_install_template_head
= node
;
789 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
793 const char *iso
= NULL
;
794 VTOY_JSON
*pNode
= NULL
;
796 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
798 grub_printf("Not array type %d\n", json
->enDataType
);
802 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
804 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
806 grub_printf("NOT object type\n");
809 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
812 pos
= grub_strchr(iso
, '*');
813 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
815 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
816 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
820 grub_printf("image: %s [FAIL]\n", iso
);
825 grub_printf("image not found\n");
832 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
835 const char *iso
= NULL
;
836 VTOY_JSON
*pNode
= NULL
;
839 file_fullpath
*dudpath
= NULL
;
841 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
843 debug("Not array %d\n", json
->enDataType
);
849 for (node
= g_dud_head
; node
; node
= next
)
852 grub_check_free(node
->dudpath
);
859 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
861 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
862 if (iso
&& iso
[0] == '/')
864 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "dud", &dudpath
, &pathnum
))
866 node
= grub_zalloc(sizeof(dud
));
869 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
870 node
->dudpath
= dudpath
;
871 node
->dudnum
= pathnum
;
872 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
878 node
->next
= g_dud_head
;
895 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
902 vtoy_password tmpPwd
;
904 len
= (int)grub_strlen(pwdstr
);
907 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
911 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
913 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
915 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
916 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
918 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
922 for (i
= 0; i
< 16; i
++)
924 bytes
[0] = pwdstr
[4 + i
* 2];
925 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
928 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
930 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
934 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
938 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
940 else if ((len
- 4) > 32)
942 pos
= grub_strchr(pwdstr
+ 4, '#');
945 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
949 if (len
- 1 - (int)(long)(pos
- pwdstr
) != 32)
951 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
957 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
961 for (i
= 0; i
< 16; i
++)
963 bytes
[0] = pos
[i
* 2];
964 bytes
[1] = pos
[i
* 2 + 1];
967 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
969 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
973 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
978 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
982 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
988 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
994 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
1000 static int ventoy_plugin_get_pwd_type(const char *pwd
)
1005 for (i
= 0; pwd
&& i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
1007 grub_snprintf(pwdtype
, sizeof(pwdtype
), "%spwd", g_menu_prefix
[i
]);
1008 if (grub_strcmp(pwdtype
, pwd
) == 0)
1010 return img_type_start
+ i
;
1017 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
1020 const char *iso
= NULL
;
1021 const char *pwd
= NULL
;
1022 VTOY_JSON
*pNode
= NULL
;
1023 VTOY_JSON
*pCNode
= NULL
;
1024 menu_password
*node
= NULL
;
1025 menu_password
*tail
= NULL
;
1026 menu_password
*next
= NULL
;
1030 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1032 debug("Not object %d\n", json
->enDataType
);
1038 for (node
= g_pwd_head
; node
; node
= next
)
1047 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1049 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1051 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
1053 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1055 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, g_file_type_pwd
+ type
);
1057 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1059 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1061 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1066 type
= vtoy_menu_pwd_file
;
1067 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
1070 type
= vtoy_menu_pwd_parent
;
1071 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent");
1074 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1075 if (iso
&& pwd
&& iso
[0] == '/')
1077 node
= grub_zalloc(sizeof(menu_password
));
1081 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1083 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
1107 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
1111 const char *iso
= NULL
;
1112 const char *pwd
= NULL
;
1113 VTOY_JSON
*pNode
= NULL
;
1114 VTOY_JSON
*pCNode
= NULL
;
1116 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1118 grub_printf("Not object %d\n", json
->enDataType
);
1122 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1124 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
1126 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1128 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
1132 grub_printf("Invalid bootpwd.\n");
1135 else if ((type
= ventoy_plugin_get_pwd_type(pNode
->pcName
)) >= 0)
1137 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
1139 grub_printf("%s:<%s>\n", pNode
->pcName
, pNode
->unData
.pcStrVal
);
1143 grub_printf("Invalid pwd <%s>\n", pNode
->unData
.pcStrVal
);
1146 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
1149 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
1151 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
1153 grub_printf("Not object %d\n", pCNode
->enDataType
);
1157 if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file")) != NULL
)
1159 pos
= grub_strchr(iso
, '*');
1160 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1162 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1164 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1166 grub_printf("file:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1167 grub_printf("pwd:<%s>\n\n", pwd
);
1171 grub_printf("Invalid password for <%s>\n", iso
);
1176 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1179 else if ((iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "parent")) != NULL
)
1181 if (ventoy_is_dir_exist("%s%s", isodisk
, iso
))
1183 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
1184 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
1186 grub_printf("dir:<%s> [%s]\n", iso
, (pos
? "*" : "OK"));
1187 grub_printf("pwd:<%s>\n\n", pwd
);
1191 grub_printf("Invalid password for <%s>\n", iso
);
1196 grub_printf("<%s%s> not found\n", isodisk
, iso
);
1201 grub_printf("No file item found in json.\n");
1210 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
1216 const char *iso
= NULL
;
1217 VTOY_JSON
*pNode
= NULL
;
1219 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1221 grub_printf("Not array type %d\n", json
->enDataType
);
1225 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1227 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
1229 grub_printf("NOT object type\n");
1232 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1235 pos
= grub_strchr(iso
, '*');
1236 if (pos
|| 0 == ventoy_plugin_check_path(isodisk
, iso
))
1238 grub_printf("image: %s [%s]\n", iso
, (pos
? "*" : "OK"));
1239 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
1241 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1243 if (autosel
>= 0 && autosel
<= pathnum
)
1245 grub_printf("autosel: %d [OK]\n", autosel
);
1249 grub_printf("autosel: %d [FAIL]\n", autosel
);
1253 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
1257 grub_printf("timeout: %d [OK]\n", timeout
);
1261 grub_printf("timeout: %d [FAIL]\n", timeout
);
1267 grub_printf("image: %s [FAIL]\n", iso
);
1272 grub_printf("image not found\n");
1279 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1284 const char *iso
= NULL
;
1285 VTOY_JSON
*pNode
= NULL
;
1286 persistence_config
*node
= NULL
;
1287 persistence_config
*next
= NULL
;
1288 file_fullpath
*backendpath
= NULL
;
1292 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1294 debug("Not array %d\n", json
->enDataType
);
1298 if (g_persistence_head
)
1300 for (node
= g_persistence_head
; node
; node
= next
)
1303 grub_check_free(node
->backendpath
);
1307 g_persistence_head
= NULL
;
1310 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1312 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1313 if (iso
&& iso
[0] == '/')
1315 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1317 node
= grub_zalloc(sizeof(persistence_config
));
1320 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1321 node
->backendpath
= backendpath
;
1322 node
->backendnum
= pathnum
;
1326 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1328 if (autosel
>= 0 && autosel
<= pathnum
)
1330 node
->autosel
= autosel
;
1334 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "timeout", &timeout
))
1338 node
->timeout
= timeout
;
1342 if (g_persistence_head
)
1344 node
->next
= g_persistence_head
;
1347 g_persistence_head
= node
;
1356 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1359 const char *path
= NULL
;
1360 const char *alias
= NULL
;
1361 VTOY_JSON
*pNode
= NULL
;
1365 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1367 grub_printf("Not array %d\n", json
->enDataType
);
1371 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1373 type
= vtoy_alias_image_file
;
1374 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1377 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1378 type
= vtoy_alias_directory
;
1381 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1382 if (path
&& path
[0] == '/' && alias
)
1384 if (vtoy_alias_image_file
== type
)
1386 if (grub_strchr(path
, '*'))
1388 grub_printf("image: <%s> [ * ]\n", path
);
1390 else if (ventoy_is_file_exist("%s%s", isodisk
, path
))
1392 grub_printf("image: <%s> [ OK ]\n", path
);
1396 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1401 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1403 grub_printf("dir: <%s> [ OK ]\n", path
);
1407 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1411 grub_printf("alias: <%s>\n\n", alias
);
1418 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1421 const char *path
= NULL
;
1422 const char *alias
= NULL
;
1423 VTOY_JSON
*pNode
= NULL
;
1424 menu_alias
*node
= NULL
;
1425 menu_alias
*next
= NULL
;
1429 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1431 debug("Not array %d\n", json
->enDataType
);
1435 if (g_menu_alias_head
)
1437 for (node
= g_menu_alias_head
; node
; node
= next
)
1443 g_menu_alias_head
= NULL
;
1446 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1448 type
= vtoy_alias_image_file
;
1449 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1452 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1453 type
= vtoy_alias_directory
;
1456 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1457 if (path
&& path
[0] == '/' && alias
)
1459 node
= grub_zalloc(sizeof(menu_alias
));
1463 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1464 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1466 if (g_menu_alias_head
)
1468 node
->next
= g_menu_alias_head
;
1471 g_menu_alias_head
= node
;
1479 static int ventoy_plugin_menutip_check(VTOY_JSON
*json
, const char *isodisk
)
1482 const char *path
= NULL
;
1483 const char *tip
= NULL
;
1484 VTOY_JSON
*pNode
= NULL
;
1488 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1490 grub_printf("Not object %d\n", json
->enDataType
);
1494 tip
= vtoy_json_get_string_ex(json
->pstChild
, "left");
1497 grub_printf("left: <%s>\n", tip
);
1500 tip
= vtoy_json_get_string_ex(json
->pstChild
, "top");
1503 grub_printf("top: <%s>\n", tip
);
1506 tip
= vtoy_json_get_string_ex(json
->pstChild
, "color");
1509 grub_printf("color: <%s>\n", tip
);
1512 pNode
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "tips");
1513 for (pNode
= pNode
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1515 type
= vtoy_tip_image_file
;
1516 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1519 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1520 type
= vtoy_tip_directory
;
1523 if (path
&& path
[0] == '/')
1525 if (vtoy_tip_image_file
== type
)
1527 if (grub_strchr(path
, '*'))
1529 grub_printf("image: <%s> [ * ]\n", path
);
1531 else if (ventoy_is_file_exist("%s%s", isodisk
, path
))
1533 grub_printf("image: <%s> [ OK ]\n", path
);
1537 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1542 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1544 grub_printf("dir: <%s> [ OK ]\n", path
);
1548 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1552 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip");
1555 grub_printf("tip: <%s>\n", tip
);
1559 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip1");
1561 grub_printf("tip1: <%s>\n", tip
);
1563 grub_printf("tip1: <NULL>\n");
1565 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip2");
1567 grub_printf("tip2: <%s>\n", tip
);
1569 grub_printf("tip2: <NULL>\n");
1574 grub_printf("image: <%s> [ INVALID ]\n", path
);
1581 static int ventoy_plugin_menutip_entry(VTOY_JSON
*json
, const char *isodisk
)
1584 const char *path
= NULL
;
1585 const char *tip
= NULL
;
1586 VTOY_JSON
*pNode
= NULL
;
1587 menu_tip
*node
= NULL
;
1588 menu_tip
*next
= NULL
;
1592 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
1594 debug("Not object %d\n", json
->enDataType
);
1598 pNode
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "tips");
1601 debug("Not tips found\n");
1605 if (g_menu_tip_head
)
1607 for (node
= g_menu_tip_head
; node
; node
= next
)
1613 g_menu_tip_head
= NULL
;
1616 tip
= vtoy_json_get_string_ex(json
->pstChild
, "left");
1619 grub_env_set("VTOY_TIP_LEFT", tip
);
1622 tip
= vtoy_json_get_string_ex(json
->pstChild
, "top");
1625 grub_env_set("VTOY_TIP_TOP", tip
);
1628 tip
= vtoy_json_get_string_ex(json
->pstChild
, "color");
1631 grub_env_set("VTOY_TIP_COLOR", tip
);
1634 for (pNode
= pNode
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1636 type
= vtoy_tip_image_file
;
1637 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1640 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1641 type
= vtoy_tip_directory
;
1644 if (path
&& path
[0] == '/')
1646 node
= grub_zalloc(sizeof(menu_tip
));
1650 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1652 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip");
1655 grub_snprintf(node
->tip1
, 1000, "%s", tip
);
1659 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip1");
1661 grub_snprintf(node
->tip1
, 1000, "%s", tip
);
1663 tip
= vtoy_json_get_string_ex(pNode
->pstChild
, "tip2");
1665 grub_snprintf(node
->tip2
, 1000, "%s", tip
);
1668 if (g_menu_tip_head
)
1670 node
->next
= g_menu_tip_head
;
1673 g_menu_tip_head
= node
;
1681 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1684 const char *path
= NULL
;
1685 const char *archive
= NULL
;
1686 VTOY_JSON
*pNode
= NULL
;
1690 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1692 grub_printf("Not array %d\n", json
->enDataType
);
1696 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1698 type
= injection_type_file
;
1699 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1702 type
= injection_type_parent
;
1703 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1706 grub_printf("image/parent not found\n");
1711 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1714 grub_printf("archive not found\n");
1718 if (type
== injection_type_file
)
1720 if (grub_strchr(path
, '*'))
1722 grub_printf("image: <%s> [*]\n", path
);
1726 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1731 grub_printf("parent: <%s> [%s]\n", path
,
1732 ventoy_is_dir_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1735 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1741 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1744 const char *path
= NULL
;
1745 const char *archive
= NULL
;
1746 VTOY_JSON
*pNode
= NULL
;
1747 injection_config
*node
= NULL
;
1748 injection_config
*next
= NULL
;
1752 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1754 debug("Not array %d\n", json
->enDataType
);
1758 if (g_injection_head
)
1760 for (node
= g_injection_head
; node
; node
= next
)
1766 g_injection_head
= NULL
;
1769 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1771 type
= injection_type_file
;
1772 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1775 type
= injection_type_parent
;
1776 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1779 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1780 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1782 node
= grub_zalloc(sizeof(injection_config
));
1786 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1787 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1789 if (g_injection_head
)
1791 node
->next
= g_injection_head
;
1794 g_injection_head
= node
;
1802 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1806 const char *key
= NULL
;
1807 const char *class = NULL
;
1808 VTOY_JSON
*pNode
= NULL
;
1809 menu_class
*tail
= NULL
;
1810 menu_class
*node
= NULL
;
1811 menu_class
*next
= NULL
;
1815 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1817 debug("Not array %d\n", json
->enDataType
);
1821 if (g_menu_class_head
)
1823 for (node
= g_menu_class_head
; node
; node
= next
)
1829 g_menu_class_head
= NULL
;
1832 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1835 type
= vtoy_class_image_file
;
1836 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1839 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1846 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1847 type
= vtoy_class_directory
;
1851 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1854 node
= grub_zalloc(sizeof(menu_class
));
1858 node
->parent
= parent
;
1859 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1860 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1862 if (g_menu_class_head
)
1868 g_menu_class_head
= node
;
1878 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1880 const char *name
= NULL
;
1881 const char *key
= NULL
;
1882 const char *class = NULL
;
1883 VTOY_JSON
*pNode
= NULL
;
1887 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1889 grub_printf("Not array %d\n", json
->enDataType
);
1893 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1896 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1900 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "parent");
1904 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1908 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1911 grub_printf("%s: <%s>\n", name
, key
);
1912 grub_printf("class: <%s>\n\n", class);
1919 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1923 const char *key
= NULL
;
1924 const char *cfg
= NULL
;
1925 VTOY_JSON
*pNode
= NULL
;
1926 custom_boot
*tail
= NULL
;
1927 custom_boot
*node
= NULL
;
1928 custom_boot
*next
= NULL
;
1932 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1934 debug("Not array %d\n", json
->enDataType
);
1938 if (g_custom_boot_head
)
1940 for (node
= g_custom_boot_head
; node
; node
= next
)
1946 g_custom_boot_head
= NULL
;
1949 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1951 type
= vtoy_custom_boot_image_file
;
1952 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1955 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1956 type
= vtoy_custom_boot_directory
;
1959 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1962 node
= grub_zalloc(sizeof(custom_boot
));
1966 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1967 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1969 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
1971 if (g_custom_boot_head
)
1977 g_custom_boot_head
= node
;
1992 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
1996 const char *key
= NULL
;
1997 const char *cfg
= NULL
;
1998 VTOY_JSON
*pNode
= NULL
;
2002 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2004 grub_printf("Not array %d\n", json
->enDataType
);
2008 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2010 type
= vtoy_custom_boot_image_file
;
2011 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
2014 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
2015 type
= vtoy_custom_boot_directory
;
2018 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
2019 len
= (int)grub_strlen(cfg
);
2022 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
2024 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
2028 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
2029 grub_printf("vcfg: <%s>\n\n", cfg
);
2037 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
2040 const char *isof
= NULL
;
2041 const char *orgf
= NULL
;
2042 const char *newf
= NULL
;
2043 VTOY_JSON
*pNode
= NULL
;
2044 conf_replace
*tail
= NULL
;
2045 conf_replace
*node
= NULL
;
2046 conf_replace
*next
= NULL
;
2050 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2052 debug("Not array %d\n", json
->enDataType
);
2056 if (g_conf_replace_head
)
2058 for (node
= g_conf_replace_head
; node
; node
= next
)
2064 g_conf_replace_head
= NULL
;
2067 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2069 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
2070 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
2071 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
2072 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
2074 node
= grub_zalloc(sizeof(conf_replace
));
2077 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "img", &img
))
2082 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
2083 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
2084 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
2086 if (g_conf_replace_head
)
2092 g_conf_replace_head
= node
;
2102 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
2105 const char *isof
= NULL
;
2106 const char *orgf
= NULL
;
2107 const char *newf
= NULL
;
2108 VTOY_JSON
*pNode
= NULL
;
2109 grub_file_t file
= NULL
;
2114 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2116 grub_printf("Not array %d\n", json
->enDataType
);
2120 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2122 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
2123 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
2124 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
2125 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
2127 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
2129 grub_printf("iso:<%s> [OK]\n", isof
);
2131 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
2132 grub_script_execute_sourcecode(cmd
);
2134 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
2137 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
2139 grub_printf("org:<%s> [OK]\n", orgf
);
2143 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
2145 grub_file_close(file
);
2149 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
2152 grub_script_execute_sourcecode("loopback -d vtisocheck");
2154 else if (grub_strchr(isof
, '*'))
2156 grub_printf("iso:<%s> [*]\n", isof
);
2157 grub_printf("org:<%s>\n", orgf
);
2161 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
2162 grub_printf("org:<%s>\n", orgf
);
2165 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
2168 if (file
->size
> vtoy_max_replace_file_size
)
2170 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
2174 grub_printf("new1:<%s> [OK]\n", newf
);
2176 grub_file_close(file
);
2180 grub_printf("new:<%s> [NOT Exist]\n", newf
);
2183 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "img", &img
))
2185 grub_printf("img:<%d>\n", img
);
2195 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
2197 VTOY_JSON
*pNode
= NULL
;
2198 auto_memdisk
*node
= NULL
;
2199 auto_memdisk
*next
= NULL
;
2203 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2205 debug("Not array %d\n", json
->enDataType
);
2209 if (g_auto_memdisk_head
)
2211 for (node
= g_auto_memdisk_head
; node
; node
= next
)
2217 g_auto_memdisk_head
= NULL
;
2220 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2222 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2224 node
= grub_zalloc(sizeof(auto_memdisk
));
2227 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2229 if (g_auto_memdisk_head
)
2231 node
->next
= g_auto_memdisk_head
;
2234 g_auto_memdisk_head
= node
;
2242 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
2244 VTOY_JSON
*pNode
= NULL
;
2246 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2248 grub_printf("Not array %d\n", json
->enDataType
);
2252 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2254 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2256 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2258 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2260 grub_printf(" [*]\n");
2262 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2264 grub_printf(" [OK]\n");
2268 grub_printf(" [NOT EXIST]\n");
2276 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
2278 VTOY_JSON
*pNode
= NULL
;
2279 image_list
*node
= NULL
;
2280 image_list
*next
= NULL
;
2281 image_list
*tail
= NULL
;
2285 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2287 debug("Not array %d\n", json
->enDataType
);
2291 if (g_image_list_head
)
2293 for (node
= g_image_list_head
; node
; node
= next
)
2299 g_image_list_head
= NULL
;
2302 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
2304 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
2308 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
2311 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2313 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2315 node
= grub_zalloc(sizeof(image_list
));
2318 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
2320 if (g_image_list_head
)
2326 g_image_list_head
= node
;
2336 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
2338 VTOY_JSON
*pNode
= NULL
;
2340 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
2342 grub_printf("Not array %d\n", json
->enDataType
);
2346 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
2348 if (pNode
->enDataType
== JSON_TYPE_STRING
)
2350 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
2352 if (grub_strchr(pNode
->unData
.pcStrVal
, '*'))
2354 grub_printf(" [*]\n");
2356 else if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
2358 grub_printf(" [OK]\n");
2362 grub_printf(" [NOT EXIST]\n");
2370 static plugin_entry g_plugin_entries
[] =
2372 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
, 0 },
2373 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
, 0 },
2374 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
, 0 },
2375 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
, 0 },
2376 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
, 0 },
2377 { "menu_tip", ventoy_plugin_menutip_entry
, ventoy_plugin_menutip_check
, 0 },
2378 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
, 0 },
2379 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
, 0 },
2380 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
, 0 },
2381 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
, 0 },
2382 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
, 0 },
2383 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
, 0 },
2384 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
, 0 },
2385 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
, 0 },
2386 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
, 0 },
2389 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
2393 VTOY_JSON
*cur
= NULL
;
2395 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
2397 for (cur
= json
; cur
; cur
= cur
->pstNext
)
2399 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2401 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
2402 if (g_plugin_entries
[i
].flag
== 0 && grub_strcmp(key
, cur
->pcName
) == 0)
2404 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2405 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2406 g_plugin_entries
[i
].flag
= 1;
2413 for (cur
= json
; cur
; cur
= cur
->pstNext
)
2415 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2417 if (g_plugin_entries
[i
].flag
== 0 && grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0)
2419 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
2420 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
2421 g_plugin_entries
[i
].flag
= 1;
2430 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2435 grub_uint8_t
*code
= NULL
;
2437 VTOY_JSON
*json
= NULL
;
2442 grub_env_set("VTOY_TIP_LEFT", "10%");
2443 grub_env_set("VTOY_TIP_TOP", "80%+5");
2444 grub_env_set("VTOY_TIP_COLOR", "blue");
2445 grub_env_set("VTOY_TIP_ALIGN", "left");
2447 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2450 return GRUB_ERR_NONE
;
2453 debug("json configuration file size %d\n", (int)file
->size
);
2455 buf
= grub_malloc(file
->size
+ 1);
2458 grub_file_close(file
);
2462 buf
[file
->size
] = 0;
2463 grub_file_read(file
, buf
, file
->size
);
2464 grub_file_close(file
);
2466 json
= vtoy_json_create();
2472 code
= (grub_uint8_t
*)buf
;
2473 if (code
[0] == 0xef && code
[1] == 0xbb && code
[2] == 0xbf)
2475 offset
= 3; /* Skip UTF-8 BOM */
2477 else if ((code
[0] == 0xff && code
[1] == 0xfe) || (code
[0] == 0xfe && code
[1] == 0xff))
2479 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2480 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2482 grub_env_set("VTOY_PLUGIN_ENCODE_ERROR", "1");
2483 grub_env_export("VTOY_PLUGIN_ENCODE_ERROR");
2485 debug("Failed to parse json string %d\n", ret
);
2490 ret
= vtoy_json_parse(json
, buf
+ offset
);
2493 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
2494 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
2496 debug("Failed to parse json string %d\n", ret
);
2501 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
2503 vtoy_json_destroy(json
);
2507 if (g_boot_pwd
.type
)
2509 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
2510 if (ventoy_check_password(&g_boot_pwd
, 3))
2512 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
2519 if (g_menu_tip_head
)
2521 grub_env_set("VTOY_MENU_TIP_ENABLE", "1");
2525 grub_env_unset("VTOY_MENU_TIP_ENABLE");
2528 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2531 void ventoy_plugin_dump_injection(void)
2533 injection_config
*node
= NULL
;
2535 for (node
= g_injection_head
; node
; node
= node
->next
)
2537 grub_printf("\n%s:<%s>\n", (node
->type
== injection_type_file
) ? "IMAGE" : "PARENT", node
->isopath
);
2538 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
2545 void ventoy_plugin_dump_auto_install(void)
2548 install_template
*node
= NULL
;
2550 for (node
= g_install_template_head
; node
; node
= node
->next
)
2552 grub_printf("\n%s:<%s> <%d>\n",
2553 (node
->type
== auto_install_type_file
) ? "IMAGE" : "PARENT",
2554 node
->isopath
, node
->templatenum
);
2555 for (i
= 0; i
< node
->templatenum
; i
++)
2557 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
2564 void ventoy_plugin_dump_persistence(void)
2568 persistence_config
*node
= NULL
;
2569 ventoy_img_chunk_list chunk_list
;
2571 for (node
= g_persistence_head
; node
; node
= node
->next
)
2573 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
2575 for (i
= 0; i
< node
->backendnum
; i
++)
2577 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
2578 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
2581 grub_printf(" [ SUCCESS ]\n");
2582 grub_free(chunk_list
.chunk
);
2586 grub_printf(" [ FAILED ]\n");
2594 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
2597 install_template
*node
= NULL
;
2599 if (!g_install_template_head
)
2604 len
= (int)grub_strlen(isopath
);
2605 for (node
= g_install_template_head
; node
; node
= node
->next
)
2607 if (node
->type
== auto_install_type_file
)
2609 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2616 for (node
= g_install_template_head
; node
; node
= node
->next
)
2618 if (node
->type
== auto_install_type_parent
)
2620 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2630 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
2632 install_template
*node
= NULL
;
2634 node
= ventoy_plugin_find_install_template(isopath
);
2635 if ((!node
) || (!node
->templatepath
))
2640 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2645 return node
->templatepath
[node
->cursel
].path
;
2648 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2651 persistence_config
*node
= NULL
;
2653 if (!g_persistence_head
)
2658 len
= (int)grub_strlen(isopath
);
2659 for (node
= g_persistence_head
; node
; node
= node
->next
)
2661 if ((len
== node
->pathlen
) && (ventoy_strcmp(node
->isopath
, isopath
) == 0))
2670 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2673 grub_uint64_t start
= 0;
2674 grub_file_t file
= NULL
;
2675 persistence_config
*node
= NULL
;
2677 node
= ventoy_plugin_find_persistent(isopath
);
2678 if ((!node
) || (!node
->backendpath
))
2685 index
= node
->cursel
;
2688 if (index
< 0 || index
>= node
->backendnum
)
2693 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
2696 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
2700 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2701 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2702 if (NULL
== chunk_list
->chunk
)
2707 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2708 chunk_list
->cur_chunk
= 0;
2710 start
= file
->device
->disk
->partition
->start
;
2711 ventoy_get_block_list(file
, chunk_list
, start
);
2713 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2715 grub_free(chunk_list
->chunk
);
2716 chunk_list
->chunk
= NULL
;
2724 grub_file_close(file
);
2729 const char * ventoy_plugin_get_injection(const char *isopath
)
2732 injection_config
*node
= NULL
;
2734 if (!g_injection_head
)
2739 len
= (int)grub_strlen(isopath
);
2740 for (node
= g_injection_head
; node
; node
= node
->next
)
2742 if (node
->type
== injection_type_file
)
2744 if (node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2746 return node
->archive
;
2751 for (node
= g_injection_head
; node
; node
= node
->next
)
2753 if (node
->type
== injection_type_parent
)
2755 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
2757 return node
->archive
;
2765 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2768 menu_alias
*node
= NULL
;
2770 if (!g_menu_alias_head
)
2775 len
= (int)grub_strlen(isopath
);
2776 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2778 if (node
->type
== type
&& node
->pathlen
&&
2779 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2788 const menu_tip
* ventoy_plugin_get_menu_tip(int type
, const char *isopath
)
2791 menu_tip
*node
= NULL
;
2793 if (!g_menu_tip_head
)
2798 len
= (int)grub_strlen(isopath
);
2799 for (node
= g_menu_tip_head
; node
; node
= node
->next
)
2801 if (node
->type
== type
&& node
->pathlen
&&
2802 node
->pathlen
== len
&& ventoy_strcmp(node
->isopath
, isopath
) == 0)
2811 const char * ventoy_plugin_get_menu_class(int type
, const char *name
, const char *path
)
2815 menu_class
*node
= NULL
;
2817 if (!g_menu_class_head
)
2822 namelen
= (int)grub_strlen(name
);
2823 pathlen
= (int)grub_strlen(path
);
2825 if (vtoy_class_image_file
== type
)
2827 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2829 if (node
->type
!= type
)
2834 if (node
->parent
== 0)
2836 if ((node
->patlen
< namelen
) && grub_strstr(name
, node
->pattern
))
2843 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2845 if (node
->type
!= type
)
2852 if ((node
->patlen
< pathlen
) && ventoy_plugin_is_parent(node
->pattern
, node
->patlen
, path
))
2861 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2863 if (node
->type
== type
&& node
->patlen
== namelen
&& grub_strncmp(name
, node
->pattern
, namelen
) == 0)
2873 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2876 custom_boot
*node
= NULL
;
2878 node
= grub_zalloc(sizeof(custom_boot
));
2881 node
->type
= vtoy_custom_boot_image_file
;
2882 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2883 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2886 len
= node
->pathlen
- 5;
2887 node
->path
[len
] = 0;
2888 node
->pathlen
= len
;
2890 if (g_custom_boot_head
)
2892 node
->next
= g_custom_boot_head
;
2894 g_custom_boot_head
= node
;
2900 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2904 custom_boot
*node
= NULL
;
2906 if (!g_custom_boot_head
)
2911 len
= (int)grub_strlen(isopath
);
2913 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2915 if (node
->type
== vtoy_custom_boot_image_file
)
2917 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2924 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2925 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2927 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2929 if (isopath
[i
] == '/')
2946 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2948 custom_boot
*node
= NULL
;
2954 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2956 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
2957 node
->path
, node
->cfg
);
2963 int ventoy_plugin_check_memdisk(const char *isopath
)
2966 auto_memdisk
*node
= NULL
;
2968 if (!g_auto_memdisk_head
)
2973 len
= (int)grub_strlen(isopath
);
2974 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
2976 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
2985 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
2989 image_list
*node
= NULL
;
2991 if (!g_image_list_head
)
2996 len
= (int)grub_strlen(name
);
2998 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
3000 if (vtoy_class_directory
== type
)
3002 if (len
< node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
3009 if (len
== node
->pathlen
&& ventoy_strncmp(node
->isopath
, name
, len
) == 0)
3019 conf_replace
* ventoy_plugin_find_conf_replace(const char *iso
)
3024 if (!g_conf_replace_head
)
3029 len
= (int)grub_strlen(iso
);
3031 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
3033 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
3042 dud
* ventoy_plugin_find_dud(const char *iso
)
3052 len
= (int)grub_strlen(iso
);
3053 for (node
= g_dud_head
; node
; node
= node
->next
)
3055 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, iso
, len
) == 0)
3064 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
3070 for (i
= 0; i
< node
->dudnum
; i
++)
3072 if (node
->files
[i
].size
> 0)
3074 debug("file %d has been loaded\n", i
);
3078 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
3081 buf
= grub_malloc(file
->size
);
3084 grub_file_read(file
, buf
, file
->size
);
3085 node
->files
[i
].size
= (int)file
->size
;
3086 node
->files
[i
].buf
= buf
;
3088 grub_file_close(file
);
3095 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
3099 const char *pos
= NULL
;
3100 menu_password
*node
= NULL
;
3109 len
= (int)grub_strlen(isopath
);
3110 for (node
= g_pwd_head
; node
; node
= node
->next
)
3112 if (node
->type
== vtoy_menu_pwd_file
)
3114 if (node
->pathlen
== len
&& ventoy_strncmp(node
->isopath
, isopath
, len
) == 0)
3116 return &(node
->password
);
3121 for (node
= g_pwd_head
; node
; node
= node
->next
)
3123 if (node
->type
== vtoy_menu_pwd_parent
)
3125 if (node
->pathlen
< len
&& ventoy_plugin_is_parent(node
->isopath
, node
->pathlen
, isopath
))
3127 return &(node
->password
);
3135 if (*isopath
== '.')
3144 for (i
= 0; i
< (int)ARRAY_SIZE(g_menu_prefix
); i
++)
3146 if (g_file_type_pwd
[i
].type
&& 0 == grub_strcasecmp(pos
+ 1, g_menu_prefix
[i
]))
3148 return g_file_type_pwd
+ i
;
3156 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3159 const vtoy_password
*pwd
= NULL
;
3164 pwd
= ventoy_plugin_get_password(args
[0]);
3167 if (0 == ventoy_check_password(pwd
, 1))
3185 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3192 VTOY_JSON
*node
= NULL
;
3193 VTOY_JSON
*json
= NULL
;
3202 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
3205 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
3206 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
3210 buf
= grub_malloc(file
->size
+ 1);
3213 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
3217 buf
[file
->size
] = 0;
3218 grub_file_read(file
, buf
, file
->size
);
3220 json
= vtoy_json_create();
3223 grub_printf("Failed to create json\n");
3227 ret
= vtoy_json_parse(json
, buf
);
3230 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
3234 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
3235 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
3237 if (grub_strcmp(node
->pcName
, key
) == 0)
3245 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
3247 if (grub_strcmp(node
->pcName
, args
[1]) == 0)
3255 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
3260 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
3262 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
3264 if (g_plugin_entries
[i
].checkfunc
)
3266 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
3273 check_free(file
, grub_file_close
);
3274 check_free(json
, vtoy_json_destroy
);
3275 grub_check_free(buf
);
3280 grub_err_t
ventoy_cmd_set_theme(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3282 grub_uint32_t i
= 0;
3283 grub_uint32_t mod
= 0;
3284 theme_list
*node
= g_theme_head
;
3285 struct grub_datetime datetime
;
3291 if (g_theme_single_file
[0])
3293 debug("single theme %s\n", g_theme_single_file
);
3294 grub_env_set("theme", g_theme_single_file
);
3298 debug("g_theme_num = %d\n", g_theme_num
);
3300 if (g_theme_num
== 0)
3305 grub_memset(&datetime
, 0, sizeof(datetime
));
3306 grub_get_datetime(&datetime
);
3308 if (g_theme_random
== vtoy_theme_random_boot_second
)
3310 grub_divmod32((grub_uint32_t
)datetime
.second
, (grub_uint32_t
)g_theme_num
, &mod
);
3312 else if (g_theme_random
== vtoy_theme_random_boot_day
)
3314 grub_divmod32((grub_uint32_t
)datetime
.day
, (grub_uint32_t
)g_theme_num
, &mod
);
3316 else if (g_theme_random
== vtoy_theme_random_boot_month
)
3318 grub_divmod32((grub_uint32_t
)datetime
.month
, (grub_uint32_t
)g_theme_num
, &mod
);
3321 debug("%04d/%02d/%02d %02d:%02d:%02d radom:%d mod:%d\n",
3322 datetime
.year
, datetime
.month
, datetime
.day
,
3323 datetime
.hour
, datetime
.minute
, datetime
.second
,
3324 g_theme_random
, mod
);
3326 for (i
= 0; i
< mod
&& node
; i
++)
3331 debug("random theme %s\n", node
->theme
.path
);
3332 grub_env_set("theme", node
->theme
.path
);
3335 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);