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/time.h>
36 #include <grub/font.h>
37 #include <grub/ventoy.h>
38 #include "ventoy_def.h"
40 GRUB_MOD_LICENSE ("GPLv3+");
42 static char g_iso_disk_name
[128];
43 static install_template
*g_install_template_head
= NULL
;
44 static persistence_config
*g_persistence_head
= NULL
;
45 static menu_alias
*g_menu_alias_head
= NULL
;
46 static menu_class
*g_menu_class_head
= NULL
;
47 static injection_config
*g_injection_head
= NULL
;
49 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
52 VTOY_JSON
*pNode
= NULL
;
53 VTOY_JSON
*pChild
= NULL
;
57 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
59 grub_printf("Not array type %d\n", json
->enDataType
);
63 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
65 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
67 pChild
= pNode
->pstChild
;
68 if (pChild
->enDataType
== JSON_TYPE_STRING
)
70 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
74 grub_printf("%s is NOT string type\n", pChild
->pcName
);
80 grub_printf("%s is not an object\n", pNode
->pcName
);
88 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
90 VTOY_JSON
*pNode
= NULL
;
91 VTOY_JSON
*pChild
= NULL
;
95 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
97 debug("Not array %d\n", json
->enDataType
);
101 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
103 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
105 pChild
= pNode
->pstChild
;
106 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
108 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
116 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
122 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
125 grub_printf("file: %s\n", value
);
128 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
132 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
137 grub_printf("Theme file %s does NOT exist\n", value
);
142 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
145 grub_printf("gfxmode: %s\n", value
);
148 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
151 grub_printf("display_mode: %s\n", value
);
154 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
157 grub_printf("serial_param %s\n", value
);
160 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
163 grub_printf("ventoy_left: %s\n", value
);
166 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
169 grub_printf("ventoy_top: %s\n", value
);
172 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
175 grub_printf("ventoy_color: %s\n", value
);
178 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
181 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
183 if (node
->enDataType
== JSON_TYPE_STRING
)
185 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
187 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
191 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
198 grub_printf("fonts NOT found\n");
204 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
210 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
215 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
219 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
222 if (ventoy_is_file_exist(filepath
) == 0)
224 debug("Theme file %s does not exist\n", filepath
);
228 debug("vtoy_theme %s\n", filepath
);
229 grub_env_set("vtoy_theme", filepath
);
232 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
235 debug("vtoy_gfxmode %s\n", value
);
236 grub_env_set("vtoy_gfxmode", value
);
239 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
242 debug("display_mode %s\n", value
);
243 grub_env_set("vtoy_display_mode", value
);
246 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
249 debug("serial_param %s\n", value
);
250 grub_env_set("vtoy_serial_param", value
);
253 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
256 grub_env_set("VTLE_LFT", value
);
259 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
262 grub_env_set("VTLE_TOP", value
);
265 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
268 grub_env_set("VTLE_CLR", value
);
271 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
274 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
276 if (node
->enDataType
== JSON_TYPE_STRING
&&
277 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
279 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
280 grub_font_load(filepath
);
288 static int ventoy_plugin_check_path(const char *path
, const char *file
)
292 grub_printf("%s is NOT begin with '/' \n", file
);
296 if (grub_strchr(file
, '\\'))
298 grub_printf("%s contains invalid '\\' \n", file
);
302 if (grub_strstr(file
, "//"))
304 grub_printf("%s contains invalid double slash\n", file
);
308 if (grub_strstr(file
, "../"))
310 grub_printf("%s contains invalid '../' \n", file
);
314 if (!ventoy_is_file_exist("%s%s", path
, file
))
316 grub_printf("%s%s does NOT exist\n", path
, file
);
323 static int ventoy_plugin_check_fullpath
334 VTOY_JSON
*node
= json
;
335 VTOY_JSON
*child
= NULL
;
339 if (0 == grub_strcmp(key
, node
->pcName
))
343 node
= node
->pstNext
;
351 if (JSON_TYPE_STRING
== node
->enDataType
)
354 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
355 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
357 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
359 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
361 if (JSON_TYPE_STRING
!= child
->enDataType
)
363 grub_printf("Non string json type\n");
367 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
368 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
379 static int ventoy_plugin_parse_fullpath
384 file_fullpath
**fullpath
,
390 VTOY_JSON
*node
= json
;
391 VTOY_JSON
*child
= NULL
;
392 file_fullpath
*path
= NULL
;
396 if (0 == grub_strcmp(key
, node
->pcName
))
400 node
= node
->pstNext
;
408 if (JSON_TYPE_STRING
== node
->enDataType
)
410 debug("%s is string type data\n", node
->pcName
);
412 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
414 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
418 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
421 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
427 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
429 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
431 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
433 debug("Invalid data type:%d\n", child
->enDataType
);
438 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
440 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
445 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
447 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
449 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
463 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
467 const char *iso
= NULL
;
468 VTOY_JSON
*pNode
= NULL
;
470 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
472 grub_printf("Not array type %d\n", json
->enDataType
);
476 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
478 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
480 grub_printf("NOT object type\n");
483 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
486 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
488 grub_printf("image: %s [OK]\n", iso
);
489 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
491 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
493 if (autosel
>= 0 && autosel
<= pathnum
)
495 grub_printf("autosel: %d [OK]\n", autosel
);
499 grub_printf("autosel: %d [FAIL]\n", autosel
);
505 grub_printf("image: %s [FAIL]\n", iso
);
510 grub_printf("image not found\n");
517 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
521 const char *iso
= NULL
;
522 VTOY_JSON
*pNode
= NULL
;
523 install_template
*node
= NULL
;
524 install_template
*next
= NULL
;
525 file_fullpath
*templatepath
= NULL
;
527 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
529 debug("Not array %d\n", json
->enDataType
);
533 if (g_install_template_head
)
535 for (node
= g_install_template_head
; node
; node
= next
)
538 grub_check_free(node
->templatepath
);
542 g_install_template_head
= NULL
;
545 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
547 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
548 if (iso
&& iso
[0] == '/')
550 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
552 node
= grub_zalloc(sizeof(install_template
));
555 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
556 node
->templatepath
= templatepath
;
557 node
->templatenum
= pathnum
;
560 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
562 if (autosel
>= 0 && autosel
<= pathnum
)
564 node
->autosel
= autosel
;
568 if (g_install_template_head
)
570 node
->next
= g_install_template_head
;
573 g_install_template_head
= node
;
582 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
586 const char *iso
= NULL
;
587 VTOY_JSON
*pNode
= NULL
;
589 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
591 grub_printf("Not array type %d\n", json
->enDataType
);
595 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
597 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
599 grub_printf("NOT object type\n");
602 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
605 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
607 grub_printf("image: %s [OK]\n", iso
);
608 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
610 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
612 if (autosel
>= 0 && autosel
<= pathnum
)
614 grub_printf("autosel: %d [OK]\n", autosel
);
618 grub_printf("autosel: %d [FAIL]\n", autosel
);
624 grub_printf("image: %s [FAIL]\n", iso
);
629 grub_printf("image not found\n");
636 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
640 const char *iso
= NULL
;
641 VTOY_JSON
*pNode
= NULL
;
642 persistence_config
*node
= NULL
;
643 persistence_config
*next
= NULL
;
644 file_fullpath
*backendpath
= NULL
;
648 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
650 debug("Not array %d\n", json
->enDataType
);
654 if (g_persistence_head
)
656 for (node
= g_persistence_head
; node
; node
= next
)
659 grub_check_free(node
->backendpath
);
663 g_persistence_head
= NULL
;
666 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
668 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
669 if (iso
&& iso
[0] == '/')
671 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
673 node
= grub_zalloc(sizeof(persistence_config
));
676 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
677 node
->backendpath
= backendpath
;
678 node
->backendnum
= pathnum
;
681 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
683 if (autosel
>= 0 && autosel
<= pathnum
)
685 node
->autosel
= autosel
;
689 if (g_persistence_head
)
691 node
->next
= g_persistence_head
;
694 g_persistence_head
= node
;
703 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
706 const char *path
= NULL
;
707 const char *alias
= NULL
;
708 VTOY_JSON
*pNode
= NULL
;
712 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
714 grub_printf("Not array %d\n", json
->enDataType
);
718 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
720 type
= vtoy_alias_image_file
;
721 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
724 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
725 type
= vtoy_alias_directory
;
728 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
729 if (path
&& path
[0] == '/' && alias
)
731 if (vtoy_alias_image_file
== type
)
733 if (ventoy_is_file_exist("%s%s", isodisk
, path
))
735 grub_printf("image: <%s> [ OK ]\n", path
);
739 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
744 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
746 grub_printf("dir: <%s> [ OK ]\n", path
);
750 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
754 grub_printf("alias: <%s>\n\n", alias
);
761 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
764 const char *path
= NULL
;
765 const char *alias
= NULL
;
766 VTOY_JSON
*pNode
= NULL
;
767 menu_alias
*node
= NULL
;
768 menu_alias
*next
= NULL
;
772 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
774 debug("Not array %d\n", json
->enDataType
);
778 if (g_menu_alias_head
)
780 for (node
= g_menu_alias_head
; node
; node
= next
)
786 g_menu_alias_head
= NULL
;
789 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
791 type
= vtoy_alias_image_file
;
792 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
795 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
796 type
= vtoy_alias_directory
;
799 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
800 if (path
&& path
[0] == '/' && alias
)
802 node
= grub_zalloc(sizeof(menu_alias
));
806 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
807 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
809 if (g_menu_alias_head
)
811 node
->next
= g_menu_alias_head
;
814 g_menu_alias_head
= node
;
823 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
825 const char *path
= NULL
;
826 const char *archive
= NULL
;
827 VTOY_JSON
*pNode
= NULL
;
831 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
833 grub_printf("Not array %d\n", json
->enDataType
);
837 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
839 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
842 grub_printf("image not found\n");
846 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
849 grub_printf("archive not found\n");
853 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
854 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
860 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
862 const char *path
= NULL
;
863 const char *archive
= NULL
;
864 VTOY_JSON
*pNode
= NULL
;
865 injection_config
*node
= NULL
;
866 injection_config
*next
= NULL
;
870 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
872 debug("Not array %d\n", json
->enDataType
);
876 if (g_injection_head
)
878 for (node
= g_injection_head
; node
; node
= next
)
884 g_injection_head
= NULL
;
887 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
889 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
890 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
891 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
893 node
= grub_zalloc(sizeof(injection_config
));
896 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
897 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
899 if (g_injection_head
)
901 node
->next
= g_injection_head
;
904 g_injection_head
= node
;
912 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
915 const char *key
= NULL
;
916 const char *class = NULL
;
917 VTOY_JSON
*pNode
= NULL
;
918 menu_class
*tail
= NULL
;
919 menu_class
*node
= NULL
;
920 menu_class
*next
= NULL
;
924 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
926 debug("Not array %d\n", json
->enDataType
);
930 if (g_menu_class_head
)
932 for (node
= g_menu_class_head
; node
; node
= next
)
938 g_menu_class_head
= NULL
;
941 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
943 type
= vtoy_class_image_file
;
944 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
947 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
948 type
= vtoy_class_directory
;
951 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
954 node
= grub_zalloc(sizeof(menu_class
));
958 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
959 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
961 if (g_menu_class_head
)
967 g_menu_class_head
= node
;
977 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
980 const char *key
= NULL
;
981 const char *class = NULL
;
982 VTOY_JSON
*pNode
= NULL
;
986 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
988 grub_printf("Not array %d\n", json
->enDataType
);
992 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
994 type
= vtoy_class_image_file
;
995 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
998 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
999 type
= vtoy_class_directory
;
1002 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1005 grub_printf("%s: <%s>\n", (type
== vtoy_class_directory
) ? "dir" : "key", key
);
1006 grub_printf("class: <%s>\n\n", class);
1013 static plugin_entry g_plugin_entries
[] =
1015 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
},
1016 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
},
1017 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
},
1018 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
},
1019 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
},
1020 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
},
1021 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
},
1024 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
1027 VTOY_JSON
*cur
= json
;
1029 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
1033 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
1035 if (grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0)
1037 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
1038 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
1049 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1054 VTOY_JSON
*json
= NULL
;
1059 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s/ventoy/ventoy.json", args
[0]);
1062 return GRUB_ERR_NONE
;
1065 debug("json configuration file size %d\n", (int)file
->size
);
1067 buf
= grub_malloc(file
->size
+ 1);
1070 grub_file_close(file
);
1074 buf
[file
->size
] = 0;
1075 grub_file_read(file
, buf
, file
->size
);
1076 grub_file_close(file
);
1078 json
= vtoy_json_create();
1086 ret
= vtoy_json_parse(json
, buf
);
1089 debug("Failed to parse json string %d\n", ret
);
1094 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
1096 vtoy_json_destroy(json
);
1100 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1103 void ventoy_plugin_dump_injection(void)
1105 injection_config
*node
= NULL
;
1107 for (node
= g_injection_head
; node
; node
= node
->next
)
1109 grub_printf("\nIMAGE:<%s>\n", node
->isopath
);
1110 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
1117 void ventoy_plugin_dump_auto_install(void)
1120 install_template
*node
= NULL
;
1122 for (node
= g_install_template_head
; node
; node
= node
->next
)
1124 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->templatenum
);
1125 for (i
= 0; i
< node
->templatenum
; i
++)
1127 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
1134 void ventoy_plugin_dump_persistence(void)
1138 persistence_config
*node
= NULL
;
1139 ventoy_img_chunk_list chunk_list
;
1141 for (node
= g_persistence_head
; node
; node
= node
->next
)
1143 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
1145 for (i
= 0; i
< node
->backendnum
; i
++)
1147 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
1148 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
1151 grub_printf(" [ SUCCESS ]\n");
1152 grub_free(chunk_list
.chunk
);
1156 grub_printf(" [ FAILED ]\n");
1164 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
1166 install_template
*node
= NULL
;
1167 int len
= (int)grub_strlen(isopath
);
1169 for (node
= g_install_template_head
; node
; node
= node
->next
)
1171 if (node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1180 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
1182 install_template
*node
= NULL
;
1184 node
= ventoy_plugin_find_install_template(isopath
);
1185 if ((!node
) || (!node
->templatepath
))
1190 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
1195 return node
->templatepath
[node
->cursel
].path
;
1198 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
1200 persistence_config
*node
= NULL
;
1201 int len
= (int)grub_strlen(isopath
);
1203 for (node
= g_persistence_head
; node
; node
= node
->next
)
1205 if ((len
== node
->pathlen
) && (grub_strcmp(node
->isopath
, isopath
) == 0))
1214 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
1217 grub_uint64_t start
= 0;
1218 grub_file_t file
= NULL
;
1219 persistence_config
*node
= NULL
;
1221 node
= ventoy_plugin_find_persistent(isopath
);
1222 if ((!node
) || (!node
->backendpath
))
1229 index
= node
->cursel
;
1232 if (index
< 0 || index
>= node
->backendnum
)
1237 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
1240 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
1244 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
1245 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
1246 if (NULL
== chunk_list
->chunk
)
1251 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
1252 chunk_list
->cur_chunk
= 0;
1254 start
= file
->device
->disk
->partition
->start
;
1255 ventoy_get_block_list(file
, chunk_list
, start
);
1257 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
1259 grub_free(chunk_list
->chunk
);
1260 chunk_list
->chunk
= NULL
;
1268 grub_file_close(file
);
1273 const char * ventoy_plugin_get_injection(const char *isopath
)
1275 injection_config
*node
= NULL
;
1276 int len
= (int)grub_strlen(isopath
);
1278 for (node
= g_injection_head
; node
; node
= node
->next
)
1280 if (node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1282 return node
->archive
;
1289 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
1291 menu_alias
*node
= NULL
;
1292 int len
= (int)grub_strlen(isopath
);
1294 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
1296 if (node
->type
== type
&& node
->pathlen
&&
1297 node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1306 const char * ventoy_plugin_get_menu_class(int type
, const char *name
)
1308 menu_class
*node
= NULL
;
1309 int len
= (int)grub_strlen(name
);
1311 if (vtoy_class_image_file
== type
)
1313 for (node
= g_menu_class_head
; node
; node
= node
->next
)
1315 if (node
->type
== type
&& node
->patlen
<= len
&& grub_strstr(name
, node
->pattern
))
1323 for (node
= g_menu_class_head
; node
; node
= node
->next
)
1325 if (node
->type
== type
&& node
->patlen
== len
&& grub_strncmp(name
, node
->pattern
, len
) == 0)
1335 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1341 VTOY_JSON
*node
= NULL
;
1342 VTOY_JSON
*json
= NULL
;
1351 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s/ventoy/ventoy.json", args
[0]);
1354 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
1358 buf
= grub_malloc(file
->size
+ 1);
1361 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
1365 buf
[file
->size
] = 0;
1366 grub_file_read(file
, buf
, file
->size
);
1368 json
= vtoy_json_create();
1371 grub_printf("Failed to create json\n");
1375 ret
= vtoy_json_parse(json
, buf
);
1378 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
1382 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
1384 if (grub_strcmp(node
->pcName
, args
[1]) == 0)
1392 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
1396 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
1398 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
1400 if (g_plugin_entries
[i
].checkfunc
)
1402 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
1409 check_free(file
, grub_file_close
);
1410 check_free(json
, vtoy_json_destroy
);
1411 grub_check_free(buf
);