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 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
73 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
74 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
78 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
83 grub_printf("%s is NOT string type\n", pChild
->pcName
);
89 grub_printf("%s is not an object\n", pNode
->pcName
);
97 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
99 VTOY_JSON
*pNode
= NULL
;
100 VTOY_JSON
*pChild
= NULL
;
104 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
106 debug("Not array %d\n", json
->enDataType
);
110 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
112 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
114 pChild
= pNode
->pstChild
;
115 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
117 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
125 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
131 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
134 grub_printf("file: %s\n", value
);
137 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
141 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
146 grub_printf("Theme file %s does NOT exist\n", value
);
151 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
154 grub_printf("gfxmode: %s\n", value
);
157 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
160 grub_printf("display_mode: %s\n", value
);
163 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
166 grub_printf("serial_param %s\n", value
);
169 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
172 grub_printf("ventoy_left: %s\n", value
);
175 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
178 grub_printf("ventoy_top: %s\n", value
);
181 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
184 grub_printf("ventoy_color: %s\n", value
);
187 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
190 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
192 if (node
->enDataType
== JSON_TYPE_STRING
)
194 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
196 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
200 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
207 grub_printf("fonts NOT found\n");
213 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
219 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
224 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
228 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
231 if (ventoy_is_file_exist(filepath
) == 0)
233 debug("Theme file %s does not exist\n", filepath
);
237 debug("vtoy_theme %s\n", filepath
);
238 grub_env_set("vtoy_theme", filepath
);
241 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
244 debug("vtoy_gfxmode %s\n", value
);
245 grub_env_set("vtoy_gfxmode", value
);
248 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
251 debug("display_mode %s\n", value
);
252 grub_env_set("vtoy_display_mode", value
);
255 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
258 debug("serial_param %s\n", value
);
259 grub_env_set("vtoy_serial_param", value
);
262 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
265 grub_env_set("VTLE_LFT", value
);
268 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
271 grub_env_set("VTLE_TOP", value
);
274 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
277 grub_env_set("VTLE_CLR", value
);
280 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
283 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
285 if (node
->enDataType
== JSON_TYPE_STRING
&&
286 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
288 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
289 grub_font_load(filepath
);
297 static int ventoy_plugin_check_path(const char *path
, const char *file
)
301 grub_printf("%s is NOT begin with '/' \n", file
);
305 if (grub_strchr(file
, '\\'))
307 grub_printf("%s contains invalid '\\' \n", file
);
311 if (grub_strstr(file
, "//"))
313 grub_printf("%s contains invalid double slash\n", file
);
317 if (grub_strstr(file
, "../"))
319 grub_printf("%s contains invalid '../' \n", file
);
323 if (!ventoy_is_file_exist("%s%s", path
, file
))
325 grub_printf("%s%s does NOT exist\n", path
, file
);
332 static int ventoy_plugin_check_fullpath
343 VTOY_JSON
*node
= json
;
344 VTOY_JSON
*child
= NULL
;
348 if (0 == grub_strcmp(key
, node
->pcName
))
352 node
= node
->pstNext
;
360 if (JSON_TYPE_STRING
== node
->enDataType
)
363 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
364 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
366 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
368 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
370 if (JSON_TYPE_STRING
!= child
->enDataType
)
372 grub_printf("Non string json type\n");
376 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
377 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
388 static int ventoy_plugin_parse_fullpath
393 file_fullpath
**fullpath
,
399 VTOY_JSON
*node
= json
;
400 VTOY_JSON
*child
= NULL
;
401 file_fullpath
*path
= NULL
;
405 if (0 == grub_strcmp(key
, node
->pcName
))
409 node
= node
->pstNext
;
417 if (JSON_TYPE_STRING
== node
->enDataType
)
419 debug("%s is string type data\n", node
->pcName
);
421 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
423 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
427 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
430 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
436 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
438 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
440 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
442 debug("Invalid data type:%d\n", child
->enDataType
);
447 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
449 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
454 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
456 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
458 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
472 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
476 const char *iso
= NULL
;
477 VTOY_JSON
*pNode
= NULL
;
479 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
481 grub_printf("Not array type %d\n", json
->enDataType
);
485 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
487 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
489 grub_printf("NOT object type\n");
492 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
495 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
497 grub_printf("image: %s [OK]\n", iso
);
498 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
500 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
502 if (autosel
>= 0 && autosel
<= pathnum
)
504 grub_printf("autosel: %d [OK]\n", autosel
);
508 grub_printf("autosel: %d [FAIL]\n", autosel
);
514 grub_printf("image: %s [FAIL]\n", iso
);
519 grub_printf("image not found\n");
526 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
530 const char *iso
= NULL
;
531 VTOY_JSON
*pNode
= NULL
;
532 install_template
*node
= NULL
;
533 install_template
*next
= NULL
;
534 file_fullpath
*templatepath
= NULL
;
536 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
538 debug("Not array %d\n", json
->enDataType
);
542 if (g_install_template_head
)
544 for (node
= g_install_template_head
; node
; node
= next
)
547 grub_check_free(node
->templatepath
);
551 g_install_template_head
= NULL
;
554 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
556 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
557 if (iso
&& iso
[0] == '/')
559 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
561 node
= grub_zalloc(sizeof(install_template
));
564 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
565 node
->templatepath
= templatepath
;
566 node
->templatenum
= pathnum
;
569 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
571 if (autosel
>= 0 && autosel
<= pathnum
)
573 node
->autosel
= autosel
;
577 if (g_install_template_head
)
579 node
->next
= g_install_template_head
;
582 g_install_template_head
= node
;
591 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
595 const char *iso
= NULL
;
596 VTOY_JSON
*pNode
= NULL
;
598 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
600 grub_printf("Not array type %d\n", json
->enDataType
);
604 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
606 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
608 grub_printf("NOT object type\n");
611 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
614 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
616 grub_printf("image: %s [OK]\n", iso
);
617 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
619 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
621 if (autosel
>= 0 && autosel
<= pathnum
)
623 grub_printf("autosel: %d [OK]\n", autosel
);
627 grub_printf("autosel: %d [FAIL]\n", autosel
);
633 grub_printf("image: %s [FAIL]\n", iso
);
638 grub_printf("image not found\n");
645 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
649 const char *iso
= NULL
;
650 VTOY_JSON
*pNode
= NULL
;
651 persistence_config
*node
= NULL
;
652 persistence_config
*next
= NULL
;
653 file_fullpath
*backendpath
= NULL
;
657 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
659 debug("Not array %d\n", json
->enDataType
);
663 if (g_persistence_head
)
665 for (node
= g_persistence_head
; node
; node
= next
)
668 grub_check_free(node
->backendpath
);
672 g_persistence_head
= NULL
;
675 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
677 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
678 if (iso
&& iso
[0] == '/')
680 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
682 node
= grub_zalloc(sizeof(persistence_config
));
685 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
686 node
->backendpath
= backendpath
;
687 node
->backendnum
= pathnum
;
690 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
692 if (autosel
>= 0 && autosel
<= pathnum
)
694 node
->autosel
= autosel
;
698 if (g_persistence_head
)
700 node
->next
= g_persistence_head
;
703 g_persistence_head
= node
;
712 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
715 const char *path
= NULL
;
716 const char *alias
= NULL
;
717 VTOY_JSON
*pNode
= NULL
;
721 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
723 grub_printf("Not array %d\n", json
->enDataType
);
727 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
729 type
= vtoy_alias_image_file
;
730 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
733 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
734 type
= vtoy_alias_directory
;
737 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
738 if (path
&& path
[0] == '/' && alias
)
740 if (vtoy_alias_image_file
== type
)
742 if (ventoy_is_file_exist("%s%s", isodisk
, path
))
744 grub_printf("image: <%s> [ OK ]\n", path
);
748 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
753 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
755 grub_printf("dir: <%s> [ OK ]\n", path
);
759 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
763 grub_printf("alias: <%s>\n\n", alias
);
770 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
773 const char *path
= NULL
;
774 const char *alias
= NULL
;
775 VTOY_JSON
*pNode
= NULL
;
776 menu_alias
*node
= NULL
;
777 menu_alias
*next
= NULL
;
781 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
783 debug("Not array %d\n", json
->enDataType
);
787 if (g_menu_alias_head
)
789 for (node
= g_menu_alias_head
; node
; node
= next
)
795 g_menu_alias_head
= NULL
;
798 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
800 type
= vtoy_alias_image_file
;
801 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
804 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
805 type
= vtoy_alias_directory
;
808 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
809 if (path
&& path
[0] == '/' && alias
)
811 node
= grub_zalloc(sizeof(menu_alias
));
815 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
816 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
818 if (g_menu_alias_head
)
820 node
->next
= g_menu_alias_head
;
823 g_menu_alias_head
= node
;
832 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
834 const char *path
= NULL
;
835 const char *archive
= NULL
;
836 VTOY_JSON
*pNode
= NULL
;
840 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
842 grub_printf("Not array %d\n", json
->enDataType
);
846 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
848 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
851 grub_printf("image not found\n");
855 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
858 grub_printf("archive not found\n");
862 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
863 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
869 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
871 const char *path
= NULL
;
872 const char *archive
= NULL
;
873 VTOY_JSON
*pNode
= NULL
;
874 injection_config
*node
= NULL
;
875 injection_config
*next
= NULL
;
879 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
881 debug("Not array %d\n", json
->enDataType
);
885 if (g_injection_head
)
887 for (node
= g_injection_head
; node
; node
= next
)
893 g_injection_head
= NULL
;
896 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
898 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
899 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
900 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
902 node
= grub_zalloc(sizeof(injection_config
));
905 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
906 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
908 if (g_injection_head
)
910 node
->next
= g_injection_head
;
913 g_injection_head
= node
;
921 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
924 const char *key
= NULL
;
925 const char *class = NULL
;
926 VTOY_JSON
*pNode
= NULL
;
927 menu_class
*tail
= NULL
;
928 menu_class
*node
= NULL
;
929 menu_class
*next
= NULL
;
933 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
935 debug("Not array %d\n", json
->enDataType
);
939 if (g_menu_class_head
)
941 for (node
= g_menu_class_head
; node
; node
= next
)
947 g_menu_class_head
= NULL
;
950 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
952 type
= vtoy_class_image_file
;
953 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
956 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
957 type
= vtoy_class_directory
;
960 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
963 node
= grub_zalloc(sizeof(menu_class
));
967 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
968 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
970 if (g_menu_class_head
)
976 g_menu_class_head
= node
;
986 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
989 const char *key
= NULL
;
990 const char *class = NULL
;
991 VTOY_JSON
*pNode
= NULL
;
995 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
997 grub_printf("Not array %d\n", json
->enDataType
);
1001 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1003 type
= vtoy_class_image_file
;
1004 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1007 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1008 type
= vtoy_class_directory
;
1011 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1014 grub_printf("%s: <%s>\n", (type
== vtoy_class_directory
) ? "dir" : "key", key
);
1015 grub_printf("class: <%s>\n\n", class);
1022 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
1024 VTOY_JSON
*pNode
= NULL
;
1025 auto_memdisk
*node
= NULL
;
1026 auto_memdisk
*next
= NULL
;
1030 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1032 debug("Not array %d\n", json
->enDataType
);
1036 if (g_auto_memdisk_head
)
1038 for (node
= g_auto_memdisk_head
; node
; node
= next
)
1044 g_auto_memdisk_head
= NULL
;
1047 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1049 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1051 node
= grub_zalloc(sizeof(auto_memdisk
));
1054 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1056 if (g_auto_memdisk_head
)
1058 node
->next
= g_auto_memdisk_head
;
1061 g_auto_memdisk_head
= node
;
1069 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
1071 VTOY_JSON
*pNode
= NULL
;
1073 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1075 grub_printf("Not array %d\n", json
->enDataType
);
1079 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1081 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1083 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1085 if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1087 grub_printf(" [OK]\n");
1091 grub_printf(" [NOT EXIST]\n");
1099 static plugin_entry g_plugin_entries
[] =
1101 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
},
1102 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
},
1103 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
},
1104 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
},
1105 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
},
1106 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
},
1107 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
},
1108 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
},
1111 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
1114 VTOY_JSON
*cur
= json
;
1116 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
1120 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
1122 if (grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0)
1124 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
1125 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
1136 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1141 VTOY_JSON
*json
= NULL
;
1146 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s/ventoy/ventoy.json", args
[0]);
1149 return GRUB_ERR_NONE
;
1152 debug("json configuration file size %d\n", (int)file
->size
);
1154 buf
= grub_malloc(file
->size
+ 1);
1157 grub_file_close(file
);
1161 buf
[file
->size
] = 0;
1162 grub_file_read(file
, buf
, file
->size
);
1163 grub_file_close(file
);
1165 json
= vtoy_json_create();
1173 ret
= vtoy_json_parse(json
, buf
);
1176 debug("Failed to parse json string %d\n", ret
);
1181 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
1183 vtoy_json_destroy(json
);
1187 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1190 void ventoy_plugin_dump_injection(void)
1192 injection_config
*node
= NULL
;
1194 for (node
= g_injection_head
; node
; node
= node
->next
)
1196 grub_printf("\nIMAGE:<%s>\n", node
->isopath
);
1197 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
1204 void ventoy_plugin_dump_auto_install(void)
1207 install_template
*node
= NULL
;
1209 for (node
= g_install_template_head
; node
; node
= node
->next
)
1211 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->templatenum
);
1212 for (i
= 0; i
< node
->templatenum
; i
++)
1214 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
1221 void ventoy_plugin_dump_persistence(void)
1225 persistence_config
*node
= NULL
;
1226 ventoy_img_chunk_list chunk_list
;
1228 for (node
= g_persistence_head
; node
; node
= node
->next
)
1230 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
1232 for (i
= 0; i
< node
->backendnum
; i
++)
1234 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
1235 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
1238 grub_printf(" [ SUCCESS ]\n");
1239 grub_free(chunk_list
.chunk
);
1243 grub_printf(" [ FAILED ]\n");
1251 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
1254 install_template
*node
= NULL
;
1256 if (!g_install_template_head
)
1261 len
= (int)grub_strlen(isopath
);
1262 for (node
= g_install_template_head
; node
; node
= node
->next
)
1264 if (node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1273 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
1275 install_template
*node
= NULL
;
1277 node
= ventoy_plugin_find_install_template(isopath
);
1278 if ((!node
) || (!node
->templatepath
))
1283 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
1288 return node
->templatepath
[node
->cursel
].path
;
1291 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
1294 persistence_config
*node
= NULL
;
1296 if (!g_persistence_head
)
1301 len
= (int)grub_strlen(isopath
);
1302 for (node
= g_persistence_head
; node
; node
= node
->next
)
1304 if ((len
== node
->pathlen
) && (grub_strcmp(node
->isopath
, isopath
) == 0))
1313 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
1316 grub_uint64_t start
= 0;
1317 grub_file_t file
= NULL
;
1318 persistence_config
*node
= NULL
;
1320 node
= ventoy_plugin_find_persistent(isopath
);
1321 if ((!node
) || (!node
->backendpath
))
1328 index
= node
->cursel
;
1331 if (index
< 0 || index
>= node
->backendnum
)
1336 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
1339 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
1343 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
1344 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
1345 if (NULL
== chunk_list
->chunk
)
1350 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
1351 chunk_list
->cur_chunk
= 0;
1353 start
= file
->device
->disk
->partition
->start
;
1354 ventoy_get_block_list(file
, chunk_list
, start
);
1356 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
1358 grub_free(chunk_list
->chunk
);
1359 chunk_list
->chunk
= NULL
;
1367 grub_file_close(file
);
1372 const char * ventoy_plugin_get_injection(const char *isopath
)
1375 injection_config
*node
= NULL
;
1377 if (!g_injection_head
)
1382 len
= (int)grub_strlen(isopath
);
1383 for (node
= g_injection_head
; node
; node
= node
->next
)
1385 if (node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1387 return node
->archive
;
1394 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
1397 menu_alias
*node
= NULL
;
1399 if (!g_menu_alias_head
)
1404 len
= (int)grub_strlen(isopath
);
1405 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
1407 if (node
->type
== type
&& node
->pathlen
&&
1408 node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
1417 const char * ventoy_plugin_get_menu_class(int type
, const char *name
)
1420 menu_class
*node
= NULL
;
1422 if (!g_menu_class_head
)
1427 len
= (int)grub_strlen(name
);
1429 if (vtoy_class_image_file
== type
)
1431 for (node
= g_menu_class_head
; node
; node
= node
->next
)
1433 if (node
->type
== type
&& node
->patlen
<= len
&& grub_strstr(name
, node
->pattern
))
1441 for (node
= g_menu_class_head
; node
; node
= node
->next
)
1443 if (node
->type
== type
&& node
->patlen
== len
&& grub_strncmp(name
, node
->pattern
, len
) == 0)
1453 int ventoy_plugin_check_memdisk(const char *isopath
)
1456 auto_memdisk
*node
= NULL
;
1458 if (!g_auto_memdisk_head
)
1463 len
= (int)grub_strlen(isopath
);
1464 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
1466 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->isopath
, len
) == 0)
1475 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1481 VTOY_JSON
*node
= NULL
;
1482 VTOY_JSON
*json
= NULL
;
1491 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s/ventoy/ventoy.json", args
[0]);
1494 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
1498 buf
= grub_malloc(file
->size
+ 1);
1501 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
1505 buf
[file
->size
] = 0;
1506 grub_file_read(file
, buf
, file
->size
);
1508 json
= vtoy_json_create();
1511 grub_printf("Failed to create json\n");
1515 ret
= vtoy_json_parse(json
, buf
);
1518 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
1522 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
1524 if (grub_strcmp(node
->pcName
, args
[1]) == 0)
1532 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
1536 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
1538 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
1540 if (g_plugin_entries
[i
].checkfunc
)
1542 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
1549 check_free(file
, grub_file_close
);
1550 check_free(json
, vtoy_json_destroy
);
1551 grub_check_free(buf
);