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
;
48 static auto_memdisk
*g_auto_memdisk_head
= NULL
;
50 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
53 VTOY_JSON
*pNode
= NULL
;
54 VTOY_JSON
*pChild
= NULL
;
58 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
60 grub_printf("Not array type %d\n", json
->enDataType
);
64 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
66 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
68 pChild
= pNode
->pstChild
;
69 if (pChild
->enDataType
== JSON_TYPE_STRING
)
71 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
75 grub_printf("%s is NOT string type\n", pChild
->pcName
);
81 grub_printf("%s is not an object\n", pNode
->pcName
);
89 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
91 VTOY_JSON
*pNode
= NULL
;
92 VTOY_JSON
*pChild
= NULL
;
96 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
98 debug("Not array %d\n", json
->enDataType
);
102 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
104 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
106 pChild
= pNode
->pstChild
;
107 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
109 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
117 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
123 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
126 grub_printf("file: %s\n", value
);
129 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
133 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
138 grub_printf("Theme file %s does NOT exist\n", value
);
143 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
146 grub_printf("gfxmode: %s\n", value
);
149 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
152 grub_printf("display_mode: %s\n", value
);
155 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
158 grub_printf("serial_param %s\n", value
);
161 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
164 grub_printf("ventoy_left: %s\n", value
);
167 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
170 grub_printf("ventoy_top: %s\n", value
);
173 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
176 grub_printf("ventoy_color: %s\n", value
);
179 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
182 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
184 if (node
->enDataType
== JSON_TYPE_STRING
)
186 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
188 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
192 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
199 grub_printf("fonts NOT found\n");
205 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
211 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
216 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
220 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
223 if (ventoy_is_file_exist(filepath
) == 0)
225 debug("Theme file %s does not exist\n", filepath
);
229 debug("vtoy_theme %s\n", filepath
);
230 grub_env_set("vtoy_theme", filepath
);
233 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
236 debug("vtoy_gfxmode %s\n", value
);
237 grub_env_set("vtoy_gfxmode", value
);
240 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
243 debug("display_mode %s\n", value
);
244 grub_env_set("vtoy_display_mode", value
);
247 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
250 debug("serial_param %s\n", value
);
251 grub_env_set("vtoy_serial_param", value
);
254 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
257 grub_env_set("VTLE_LFT", value
);
260 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
263 grub_env_set("VTLE_TOP", value
);
266 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
269 grub_env_set("VTLE_CLR", value
);
272 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
275 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
277 if (node
->enDataType
== JSON_TYPE_STRING
&&
278 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
280 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
281 grub_font_load(filepath
);
289 static int ventoy_plugin_check_path(const char *path
, const char *file
)
293 grub_printf("%s is NOT begin with '/' \n", file
);
297 if (grub_strchr(file
, '\\'))
299 grub_printf("%s contains invalid '\\' \n", file
);
303 if (grub_strstr(file
, "//"))
305 grub_printf("%s contains invalid double slash\n", file
);
309 if (grub_strstr(file
, "../"))
311 grub_printf("%s contains invalid '../' \n", file
);
315 if (!ventoy_is_file_exist("%s%s", path
, file
))
317 grub_printf("%s%s does NOT exist\n", path
, file
);
324 static int ventoy_plugin_check_fullpath
335 VTOY_JSON
*node
= json
;
336 VTOY_JSON
*child
= NULL
;
340 if (0 == grub_strcmp(key
, node
->pcName
))
344 node
= node
->pstNext
;
352 if (JSON_TYPE_STRING
== node
->enDataType
)
355 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
356 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
358 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
360 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
362 if (JSON_TYPE_STRING
!= child
->enDataType
)
364 grub_printf("Non string json type\n");
368 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
369 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
380 static int ventoy_plugin_parse_fullpath
385 file_fullpath
**fullpath
,
391 VTOY_JSON
*node
= json
;
392 VTOY_JSON
*child
= NULL
;
393 file_fullpath
*path
= NULL
;
397 if (0 == grub_strcmp(key
, node
->pcName
))
401 node
= node
->pstNext
;
409 if (JSON_TYPE_STRING
== node
->enDataType
)
411 debug("%s is string type data\n", node
->pcName
);
413 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
415 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
419 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
422 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
428 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
430 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
432 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
434 debug("Invalid data type:%d\n", child
->enDataType
);
439 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
441 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
446 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
448 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
450 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
464 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
468 const char *iso
= NULL
;
469 VTOY_JSON
*pNode
= NULL
;
471 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
473 grub_printf("Not array type %d\n", json
->enDataType
);
477 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
479 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
481 grub_printf("NOT object type\n");
484 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
487 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
489 grub_printf("image: %s [OK]\n", iso
);
490 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
492 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
494 if (autosel
>= 0 && autosel
<= pathnum
)
496 grub_printf("autosel: %d [OK]\n", autosel
);
500 grub_printf("autosel: %d [FAIL]\n", autosel
);
506 grub_printf("image: %s [FAIL]\n", iso
);
511 grub_printf("image not found\n");
518 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
522 const char *iso
= NULL
;
523 VTOY_JSON
*pNode
= NULL
;
524 install_template
*node
= NULL
;
525 install_template
*next
= NULL
;
526 file_fullpath
*templatepath
= NULL
;
528 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
530 debug("Not array %d\n", json
->enDataType
);
534 if (g_install_template_head
)
536 for (node
= g_install_template_head
; node
; node
= next
)
539 grub_check_free(node
->templatepath
);
543 g_install_template_head
= NULL
;
546 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
548 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
549 if (iso
&& iso
[0] == '/')
551 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
553 node
= grub_zalloc(sizeof(install_template
));
556 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
557 node
->templatepath
= templatepath
;
558 node
->templatenum
= pathnum
;
561 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
563 if (autosel
>= 0 && autosel
<= pathnum
)
565 node
->autosel
= autosel
;
569 if (g_install_template_head
)
571 node
->next
= g_install_template_head
;
574 g_install_template_head
= node
;
583 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
587 const char *iso
= NULL
;
588 VTOY_JSON
*pNode
= NULL
;
590 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
592 grub_printf("Not array type %d\n", json
->enDataType
);
596 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
598 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
600 grub_printf("NOT object type\n");
603 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
606 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
608 grub_printf("image: %s [OK]\n", iso
);
609 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
611 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
613 if (autosel
>= 0 && autosel
<= pathnum
)
615 grub_printf("autosel: %d [OK]\n", autosel
);
619 grub_printf("autosel: %d [FAIL]\n", autosel
);
625 grub_printf("image: %s [FAIL]\n", iso
);
630 grub_printf("image not found\n");
637 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
641 const char *iso
= NULL
;
642 VTOY_JSON
*pNode
= NULL
;
643 persistence_config
*node
= NULL
;
644 persistence_config
*next
= NULL
;
645 file_fullpath
*backendpath
= NULL
;
649 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
651 debug("Not array %d\n", json
->enDataType
);
655 if (g_persistence_head
)
657 for (node
= g_persistence_head
; node
; node
= next
)
660 grub_check_free(node
->backendpath
);
664 g_persistence_head
= NULL
;
667 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
669 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
670 if (iso
&& iso
[0] == '/')
672 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
674 node
= grub_zalloc(sizeof(persistence_config
));
677 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
678 node
->backendpath
= backendpath
;
679 node
->backendnum
= pathnum
;
682 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
684 if (autosel
>= 0 && autosel
<= pathnum
)
686 node
->autosel
= autosel
;
690 if (g_persistence_head
)
692 node
->next
= g_persistence_head
;
695 g_persistence_head
= node
;
704 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
707 const char *path
= NULL
;
708 const char *alias
= NULL
;
709 VTOY_JSON
*pNode
= NULL
;
713 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
715 grub_printf("Not array %d\n", json
->enDataType
);
719 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
721 type
= vtoy_alias_image_file
;
722 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
725 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
726 type
= vtoy_alias_directory
;
729 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
730 if (path
&& path
[0] == '/' && alias
)
732 if (vtoy_alias_image_file
== type
)
734 if (ventoy_is_file_exist("%s%s", isodisk
, path
))
736 grub_printf("image: <%s> [ OK ]\n", path
);
740 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
745 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
747 grub_printf("dir: <%s> [ OK ]\n", path
);
751 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
755 grub_printf("alias: <%s>\n\n", alias
);
762 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
765 const char *path
= NULL
;
766 const char *alias
= NULL
;
767 VTOY_JSON
*pNode
= NULL
;
768 menu_alias
*node
= NULL
;
769 menu_alias
*next
= NULL
;
773 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
775 debug("Not array %d\n", json
->enDataType
);
779 if (g_menu_alias_head
)
781 for (node
= g_menu_alias_head
; node
; node
= next
)
787 g_menu_alias_head
= NULL
;
790 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
792 type
= vtoy_alias_image_file
;
793 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
796 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
797 type
= vtoy_alias_directory
;
800 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
801 if (path
&& path
[0] == '/' && alias
)
803 node
= grub_zalloc(sizeof(menu_alias
));
807 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
808 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
810 if (g_menu_alias_head
)
812 node
->next
= g_menu_alias_head
;
815 g_menu_alias_head
= node
;
824 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
826 const char *path
= NULL
;
827 const char *archive
= NULL
;
828 VTOY_JSON
*pNode
= NULL
;
832 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
834 grub_printf("Not array %d\n", json
->enDataType
);
838 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
840 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
843 grub_printf("image not found\n");
847 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
850 grub_printf("archive not found\n");
854 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
855 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
861 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
863 const char *path
= NULL
;
864 const char *archive
= NULL
;
865 VTOY_JSON
*pNode
= NULL
;
866 injection_config
*node
= NULL
;
867 injection_config
*next
= NULL
;
871 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
873 debug("Not array %d\n", json
->enDataType
);
877 if (g_injection_head
)
879 for (node
= g_injection_head
; node
; node
= next
)
885 g_injection_head
= NULL
;
888 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
890 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
891 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
892 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
894 node
= grub_zalloc(sizeof(injection_config
));
897 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
898 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
900 if (g_injection_head
)
902 node
->next
= g_injection_head
;
905 g_injection_head
= node
;
913 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
916 const char *key
= NULL
;
917 const char *class = NULL
;
918 VTOY_JSON
*pNode
= NULL
;
919 menu_class
*tail
= NULL
;
920 menu_class
*node
= NULL
;
921 menu_class
*next
= NULL
;
925 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
927 debug("Not array %d\n", json
->enDataType
);
931 if (g_menu_class_head
)
933 for (node
= g_menu_class_head
; node
; node
= next
)
939 g_menu_class_head
= NULL
;
942 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
944 type
= vtoy_class_image_file
;
945 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
948 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
949 type
= vtoy_class_directory
;
952 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
955 node
= grub_zalloc(sizeof(menu_class
));
959 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
960 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
962 if (g_menu_class_head
)
968 g_menu_class_head
= node
;
978 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
981 const char *key
= NULL
;
982 const char *class = NULL
;
983 VTOY_JSON
*pNode
= NULL
;
987 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
989 grub_printf("Not array %d\n", json
->enDataType
);
993 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
995 type
= vtoy_class_image_file
;
996 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
999 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1000 type
= vtoy_class_directory
;
1003 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1006 grub_printf("%s: <%s>\n", (type
== vtoy_class_directory
) ? "dir" : "key", key
);
1007 grub_printf("class: <%s>\n\n", class);
1014 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
1016 VTOY_JSON
*pNode
= NULL
;
1017 auto_memdisk
*node
= NULL
;
1018 auto_memdisk
*next
= NULL
;
1022 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1024 debug("Not array %d\n", json
->enDataType
);
1028 if (g_auto_memdisk_head
)
1030 for (node
= g_auto_memdisk_head
; node
; node
= next
)
1036 g_auto_memdisk_head
= NULL
;
1039 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1041 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1043 node
= grub_zalloc(sizeof(auto_memdisk
));
1046 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1048 if (g_auto_memdisk_head
)
1050 node
->next
= g_auto_memdisk_head
;
1053 g_auto_memdisk_head
= node
;
1061 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
1063 VTOY_JSON
*pNode
= NULL
;
1065 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1067 grub_printf("Not array %d\n", json
->enDataType
);
1071 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1073 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1075 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1077 if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1079 grub_printf(" [OK]\n");
1083 grub_printf(" [NOT EXIST]\n");
1091 static plugin_entry g_plugin_entries
[] =
1093 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
},
1094 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
},
1095 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
},
1096 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
},
1097 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
},
1098 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
},
1099 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
},
1100 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
},
1103 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
1106 VTOY_JSON
*cur
= json
;
1108 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
1112 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
1114 if (grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0)
1116 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
1117 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
1128 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1133 VTOY_JSON
*json
= NULL
;
1138 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s/ventoy/ventoy.json", args
[0]);
1141 return GRUB_ERR_NONE
;
1144 debug("json configuration file size %d\n", (int)file
->size
);
1146 buf
= grub_malloc(file
->size
+ 1);
1149 grub_file_close(file
);
1153 buf
[file
->size
] = 0;
1154 grub_file_read(file
, buf
, file
->size
);
1155 grub_file_close(file
);
1157 json
= vtoy_json_create();
1165 ret
= vtoy_json_parse(json
, buf
);
1168 debug("Failed to parse json string %d\n", ret
);
1173 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
1175 vtoy_json_destroy(json
);
1179 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1182 void ventoy_plugin_dump_injection(void)
1184 injection_config
*node
= NULL
;
1186 for (node
= g_injection_head
; node
; node
= node
->next
)
1188 grub_printf("\nIMAGE:<%s>\n", node
->isopath
);
1189 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
1196 void ventoy_plugin_dump_auto_install(void)
1199 install_template
*node
= NULL
;
1201 for (node
= g_install_template_head
; node
; node
= node
->next
)
1203 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->templatenum
);
1204 for (i
= 0; i
< node
->templatenum
; i
++)
1206 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
1213 void ventoy_plugin_dump_persistence(void)
1217 persistence_config
*node
= NULL
;
1218 ventoy_img_chunk_list chunk_list
;
1220 for (node
= g_persistence_head
; node
; node
= node
->next
)
1222 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
1224 for (i
= 0; i
< node
->backendnum
; i
++)
1226 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
1227 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
1230 grub_printf(" [ SUCCESS ]\n");
1231 grub_free(chunk_list
.chunk
);
1235 grub_printf(" [ FAILED ]\n");
1243 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
1246 install_template
*node
= NULL
;
1248 if (!g_install_template_head
)
1253 len
= (int)grub_strlen(isopath
);
1254 for (node
= g_install_template_head
; node
; node
= node
->next
)
1256 if (node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1265 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
1267 install_template
*node
= NULL
;
1269 node
= ventoy_plugin_find_install_template(isopath
);
1270 if ((!node
) || (!node
->templatepath
))
1275 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
1280 return node
->templatepath
[node
->cursel
].path
;
1283 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
1286 persistence_config
*node
= NULL
;
1288 if (!g_persistence_head
)
1293 len
= (int)grub_strlen(isopath
);
1294 for (node
= g_persistence_head
; node
; node
= node
->next
)
1296 if ((len
== node
->pathlen
) && (grub_strcmp(node
->isopath
, isopath
) == 0))
1305 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
1308 grub_uint64_t start
= 0;
1309 grub_file_t file
= NULL
;
1310 persistence_config
*node
= NULL
;
1312 node
= ventoy_plugin_find_persistent(isopath
);
1313 if ((!node
) || (!node
->backendpath
))
1320 index
= node
->cursel
;
1323 if (index
< 0 || index
>= node
->backendnum
)
1328 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
1331 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
1335 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
1336 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
1337 if (NULL
== chunk_list
->chunk
)
1342 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
1343 chunk_list
->cur_chunk
= 0;
1345 start
= file
->device
->disk
->partition
->start
;
1346 ventoy_get_block_list(file
, chunk_list
, start
);
1348 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
1350 grub_free(chunk_list
->chunk
);
1351 chunk_list
->chunk
= NULL
;
1359 grub_file_close(file
);
1364 const char * ventoy_plugin_get_injection(const char *isopath
)
1367 injection_config
*node
= NULL
;
1369 if (!g_injection_head
)
1374 len
= (int)grub_strlen(isopath
);
1375 for (node
= g_injection_head
; node
; node
= node
->next
)
1377 if (node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1379 return node
->archive
;
1386 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
1389 menu_alias
*node
= NULL
;
1391 if (!g_menu_alias_head
)
1396 len
= (int)grub_strlen(isopath
);
1397 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
1399 if (node
->type
== type
&& node
->pathlen
&&
1400 node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1409 const char * ventoy_plugin_get_menu_class(int type
, const char *name
)
1412 menu_class
*node
= NULL
;
1414 if (!g_menu_class_head
)
1419 len
= (int)grub_strlen(name
);
1421 if (vtoy_class_image_file
== type
)
1423 for (node
= g_menu_class_head
; node
; node
= node
->next
)
1425 if (node
->type
== type
&& node
->patlen
<= len
&& grub_strstr(name
, node
->pattern
))
1433 for (node
= g_menu_class_head
; node
; node
= node
->next
)
1435 if (node
->type
== type
&& node
->patlen
== len
&& grub_strncmp(name
, node
->pattern
, len
) == 0)
1445 int ventoy_plugin_check_memdisk(const char *isopath
)
1448 auto_memdisk
*node
= NULL
;
1450 if (!g_auto_memdisk_head
)
1455 len
= (int)grub_strlen(isopath
);
1456 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
1458 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->isopath
, len
) == 0)
1467 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1473 VTOY_JSON
*node
= NULL
;
1474 VTOY_JSON
*json
= NULL
;
1483 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s/ventoy/ventoy.json", args
[0]);
1486 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
1490 buf
= grub_malloc(file
->size
+ 1);
1493 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
1497 buf
[file
->size
] = 0;
1498 grub_file_read(file
, buf
, file
->size
);
1500 json
= vtoy_json_create();
1503 grub_printf("Failed to create json\n");
1507 ret
= vtoy_json_parse(json
, buf
);
1510 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
1514 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
1516 if (grub_strcmp(node
->pcName
, args
[1]) == 0)
1524 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
1528 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
1530 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
1532 if (g_plugin_entries
[i
].checkfunc
)
1534 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
1541 check_free(file
, grub_file_close
);
1542 check_free(json
, vtoy_json_destroy
);
1543 grub_check_free(buf
);