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 install_template
*g_install_template_head
= NULL
;
47 static dud
*g_dud_head
= NULL
;
48 static menu_password
*g_pwd_head
= NULL
;
49 static persistence_config
*g_persistence_head
= NULL
;
50 static menu_alias
*g_menu_alias_head
= NULL
;
51 static menu_class
*g_menu_class_head
= NULL
;
52 static custom_boot
*g_custom_boot_head
= NULL
;
53 static injection_config
*g_injection_head
= NULL
;
54 static auto_memdisk
*g_auto_memdisk_head
= NULL
;
55 static image_list
*g_image_list_head
= NULL
;
56 static conf_replace
*g_conf_replace_head
= NULL
;
58 static int ventoy_plugin_control_check(VTOY_JSON
*json
, const char *isodisk
)
61 VTOY_JSON
*pNode
= NULL
;
62 VTOY_JSON
*pChild
= NULL
;
66 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
68 grub_printf("Not array type %d\n", json
->enDataType
);
72 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
74 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
76 pChild
= pNode
->pstChild
;
77 if (pChild
->enDataType
== JSON_TYPE_STRING
)
79 if (grub_strcmp(pChild
->pcName
, "VTOY_DEFAULT_IMAGE") == 0)
81 grub_printf("%s: %s [%s]\n", pChild
->pcName
, pChild
->unData
.pcStrVal
,
82 ventoy_check_file_exist("%s%s", isodisk
, pChild
->unData
.pcStrVal
) ? "OK" : "NOT EXIST");
86 grub_printf("%s: %s\n", pChild
->pcName
, pChild
->unData
.pcStrVal
);
91 grub_printf("%s is NOT string type\n", pChild
->pcName
);
97 grub_printf("%s is not an object\n", pNode
->pcName
);
105 static int ventoy_plugin_control_entry(VTOY_JSON
*json
, const char *isodisk
)
107 VTOY_JSON
*pNode
= NULL
;
108 VTOY_JSON
*pChild
= NULL
;
112 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
114 debug("Not array %d\n", json
->enDataType
);
118 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
120 if (pNode
->enDataType
== JSON_TYPE_OBJECT
)
122 pChild
= pNode
->pstChild
;
123 if (pChild
->enDataType
== JSON_TYPE_STRING
&& pChild
->pcName
&& pChild
->unData
.pcStrVal
)
125 ventoy_set_env(pChild
->pcName
, pChild
->unData
.pcStrVal
);
133 static int ventoy_plugin_theme_check(VTOY_JSON
*json
, const char *isodisk
)
139 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
142 grub_printf("file: %s\n", value
);
145 exist
= ventoy_is_file_exist("%s%s", isodisk
, value
);
149 exist
= ventoy_is_file_exist("%s/ventoy/%s", isodisk
, value
);
154 grub_printf("Theme file %s does NOT exist\n", value
);
159 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
162 grub_printf("gfxmode: %s\n", value
);
165 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
168 grub_printf("display_mode: %s\n", value
);
171 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
174 grub_printf("serial_param %s\n", value
);
177 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
180 grub_printf("ventoy_left: %s\n", value
);
183 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
186 grub_printf("ventoy_top: %s\n", value
);
189 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
192 grub_printf("ventoy_color: %s\n", value
);
195 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
198 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
200 if (node
->enDataType
== JSON_TYPE_STRING
)
202 if (ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
204 grub_printf("%s [OK]\n", node
->unData
.pcStrVal
);
208 grub_printf("%s [NOT EXIST]\n", node
->unData
.pcStrVal
);
215 grub_printf("fonts NOT found\n");
221 static int ventoy_plugin_theme_entry(VTOY_JSON
*json
, const char *isodisk
)
227 value
= vtoy_json_get_string_ex(json
->pstChild
, "file");
232 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, value
);
236 grub_snprintf(filepath
, sizeof(filepath
), "%s/ventoy/%s", isodisk
, value
);
239 if (ventoy_is_file_exist(filepath
) == 0)
241 debug("Theme file %s does not exist\n", filepath
);
245 debug("vtoy_theme %s\n", filepath
);
246 grub_env_set("vtoy_theme", filepath
);
249 value
= vtoy_json_get_string_ex(json
->pstChild
, "gfxmode");
252 debug("vtoy_gfxmode %s\n", value
);
253 grub_env_set("vtoy_gfxmode", value
);
256 value
= vtoy_json_get_string_ex(json
->pstChild
, "display_mode");
259 debug("display_mode %s\n", value
);
260 grub_env_set("vtoy_display_mode", value
);
263 value
= vtoy_json_get_string_ex(json
->pstChild
, "serial_param");
266 debug("serial_param %s\n", value
);
267 grub_env_set("vtoy_serial_param", value
);
270 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_left");
273 grub_env_set("VTLE_LFT", value
);
276 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_top");
279 grub_env_set("VTLE_TOP", value
);
282 value
= vtoy_json_get_string_ex(json
->pstChild
, "ventoy_color");
285 grub_env_set("VTLE_CLR", value
);
288 node
= vtoy_json_find_item(json
->pstChild
, JSON_TYPE_ARRAY
, "fonts");
291 for (node
= node
->pstChild
; node
; node
= node
->pstNext
)
293 if (node
->enDataType
== JSON_TYPE_STRING
&&
294 ventoy_check_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
))
296 grub_snprintf(filepath
, sizeof(filepath
), "%s%s", isodisk
, node
->unData
.pcStrVal
);
297 grub_font_load(filepath
);
305 static int ventoy_plugin_check_path(const char *path
, const char *file
)
309 grub_printf("%s is NOT begin with '/' \n", file
);
313 if (grub_strchr(file
, '\\'))
315 grub_printf("%s contains invalid '\\' \n", file
);
319 if (grub_strstr(file
, "//"))
321 grub_printf("%s contains invalid double slash\n", file
);
325 if (grub_strstr(file
, "../"))
327 grub_printf("%s contains invalid '../' \n", file
);
331 if (!ventoy_is_file_exist("%s%s", path
, file
))
333 grub_printf("%s%s does NOT exist\n", path
, file
);
340 static int ventoy_plugin_check_fullpath
351 VTOY_JSON
*node
= json
;
352 VTOY_JSON
*child
= NULL
;
356 if (0 == grub_strcmp(key
, node
->pcName
))
360 node
= node
->pstNext
;
368 if (JSON_TYPE_STRING
== node
->enDataType
)
371 ret
= ventoy_plugin_check_path(isodisk
, node
->unData
.pcStrVal
);
372 grub_printf("%s: %s [%s]\n", key
, node
->unData
.pcStrVal
, ret
? "FAIL" : "OK");
374 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
376 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
378 if (JSON_TYPE_STRING
!= child
->enDataType
)
380 grub_printf("Non string json type\n");
384 rc
= ventoy_plugin_check_path(isodisk
, child
->unData
.pcStrVal
);
385 grub_printf("%s: %s [%s]\n", key
, child
->unData
.pcStrVal
, rc
? "FAIL" : "OK");
396 static int ventoy_plugin_parse_fullpath
401 file_fullpath
**fullpath
,
407 VTOY_JSON
*node
= json
;
408 VTOY_JSON
*child
= NULL
;
409 file_fullpath
*path
= NULL
;
413 if (0 == grub_strcmp(key
, node
->pcName
))
417 node
= node
->pstNext
;
425 if (JSON_TYPE_STRING
== node
->enDataType
)
427 debug("%s is string type data\n", node
->pcName
);
429 if ((node
->unData
.pcStrVal
[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk
, node
->unData
.pcStrVal
)))
431 debug("%s%s file not found\n", isodisk
, node
->unData
.pcStrVal
);
435 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
));
438 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", node
->unData
.pcStrVal
);
444 else if (JSON_TYPE_ARRAY
== node
->enDataType
)
446 for (child
= node
->pstChild
; child
; child
= child
->pstNext
)
448 if ((JSON_TYPE_STRING
!= child
->enDataType
) || (child
->unData
.pcStrVal
[0] != '/'))
450 debug("Invalid data type:%d\n", child
->enDataType
);
455 debug("%s is array type data, count=%d\n", node
->pcName
, count
);
457 path
= (file_fullpath
*)grub_zalloc(sizeof(file_fullpath
) * count
);
462 for (count
= 0, child
= node
->pstChild
; child
; child
= child
->pstNext
)
464 if (ventoy_is_file_exist("%s%s", isodisk
, child
->unData
.pcStrVal
))
466 grub_snprintf(path
->path
, sizeof(path
->path
), "%s", child
->unData
.pcStrVal
);
480 static int ventoy_plugin_auto_install_check(VTOY_JSON
*json
, const char *isodisk
)
484 const char *iso
= NULL
;
485 VTOY_JSON
*pNode
= NULL
;
487 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
489 grub_printf("Not array type %d\n", json
->enDataType
);
493 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
495 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
497 grub_printf("NOT object type\n");
500 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
503 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
505 grub_printf("image: %s [OK]\n", iso
);
506 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "template", &pathnum
);
508 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
510 if (autosel
>= 0 && autosel
<= pathnum
)
512 grub_printf("autosel: %d [OK]\n", autosel
);
516 grub_printf("autosel: %d [FAIL]\n", autosel
);
522 grub_printf("image: %s [FAIL]\n", iso
);
527 grub_printf("image not found\n");
534 static int ventoy_plugin_auto_install_entry(VTOY_JSON
*json
, const char *isodisk
)
538 const char *iso
= NULL
;
539 VTOY_JSON
*pNode
= NULL
;
540 install_template
*node
= NULL
;
541 install_template
*next
= NULL
;
542 file_fullpath
*templatepath
= NULL
;
544 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
546 debug("Not array %d\n", json
->enDataType
);
550 if (g_install_template_head
)
552 for (node
= g_install_template_head
; node
; node
= next
)
555 grub_check_free(node
->templatepath
);
559 g_install_template_head
= NULL
;
562 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
564 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
565 if (iso
&& iso
[0] == '/')
567 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "template", &templatepath
, &pathnum
))
569 node
= grub_zalloc(sizeof(install_template
));
572 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
573 node
->templatepath
= templatepath
;
574 node
->templatenum
= pathnum
;
577 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
579 if (autosel
>= 0 && autosel
<= pathnum
)
581 node
->autosel
= autosel
;
585 if (g_install_template_head
)
587 node
->next
= g_install_template_head
;
590 g_install_template_head
= node
;
599 static int ventoy_plugin_dud_check(VTOY_JSON
*json
, const char *isodisk
)
602 const char *iso
= NULL
;
603 VTOY_JSON
*pNode
= NULL
;
605 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
607 grub_printf("Not array type %d\n", json
->enDataType
);
611 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
613 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
615 grub_printf("NOT object type\n");
618 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
621 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
623 grub_printf("image: %s [OK]\n", iso
);
624 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "dud", &pathnum
);
628 grub_printf("image: %s [FAIL]\n", iso
);
633 grub_printf("image not found\n");
640 static int ventoy_plugin_dud_entry(VTOY_JSON
*json
, const char *isodisk
)
643 const char *iso
= NULL
;
644 VTOY_JSON
*pNode
= NULL
;
647 file_fullpath
*dudpath
= NULL
;
649 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
651 debug("Not array %d\n", json
->enDataType
);
657 for (node
= g_dud_head
; node
; node
= next
)
660 grub_check_free(node
->dudpath
);
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
, "dud", &dudpath
, &pathnum
))
674 node
= grub_zalloc(sizeof(dud
));
677 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
678 node
->dudpath
= dudpath
;
679 node
->dudnum
= pathnum
;
680 node
->files
= grub_zalloc(sizeof(dudfile
) * pathnum
);
686 node
->next
= g_dud_head
;
703 static int ventoy_plugin_parse_pwdstr(char *pwdstr
, vtoy_password
*pwd
)
710 vtoy_password tmpPwd
;
712 len
= (int)grub_strlen(pwdstr
);
715 if (NULL
== pwd
) grub_printf("Password too long %d\n", len
);
719 grub_memset(&tmpPwd
, 0, sizeof(tmpPwd
));
721 if (grub_strncmp(pwdstr
, "txt#", 4) == 0)
723 tmpPwd
.type
= VTOY_PASSWORD_TXT
;
724 grub_snprintf(tmpPwd
.text
, sizeof(tmpPwd
.text
), "%s", pwdstr
+ 4);
726 else if (grub_strncmp(pwdstr
, "md5#", 4) == 0)
730 for (i
= 0; i
< 16; i
++)
732 bytes
[0] = pwdstr
[4 + i
* 2];
733 bytes
[1] = pwdstr
[4 + i
* 2 + 1];
736 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
738 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
742 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
746 tmpPwd
.type
= VTOY_PASSWORD_MD5
;
748 else if ((len
- 4) > 32)
750 pos
= grub_strchr(pwdstr
+ 4, '#');
753 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
757 if (len
- 1 - (int)(long)(pos
- pwdstr
) != 32)
759 if (NULL
== pwd
) grub_printf("Invalid md5 salt password format %s\n", pwdstr
);
765 grub_snprintf(tmpPwd
.salt
, sizeof(tmpPwd
.salt
), "%s", pwdstr
+ 4);
769 for (i
= 0; i
< 16; i
++)
771 bytes
[0] = pos
[i
* 2];
772 bytes
[1] = pos
[i
* 2 + 1];
775 if (grub_isxdigit(bytes
[0]) && grub_isxdigit(bytes
[1]))
777 tmpPwd
.md5
[i
] = (grub_uint8_t
)grub_strtoul(bytes
, NULL
, 16);
781 if (NULL
== pwd
) grub_printf("Invalid md5 hex format %s %d\n", pwdstr
, i
);
786 tmpPwd
.type
= VTOY_PASSWORD_SALT_MD5
;
790 if (NULL
== pwd
) grub_printf("Invalid md5 password format %s\n", pwdstr
);
796 if (NULL
== pwd
) grub_printf("Invalid password format %s\n", pwdstr
);
802 grub_memcpy(pwd
, &tmpPwd
, sizeof(tmpPwd
));
808 static int ventoy_plugin_pwd_entry(VTOY_JSON
*json
, const char *isodisk
)
810 const char *iso
= NULL
;
811 const char *pwd
= NULL
;
812 VTOY_JSON
*pNode
= NULL
;
813 VTOY_JSON
*pCNode
= NULL
;
814 menu_password
*node
= NULL
;
815 menu_password
*tail
= NULL
;
816 menu_password
*next
= NULL
;
820 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
822 debug("Not object %d\n", json
->enDataType
);
828 for (node
= g_pwd_head
; node
; node
= next
)
837 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
839 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
841 ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, &g_boot_pwd
);
843 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
845 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
847 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
852 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
853 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
854 if (iso
&& pwd
&& iso
[0] == '/')
856 node
= grub_zalloc(sizeof(menu_password
));
859 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
861 if (ventoy_plugin_parse_pwdstr((char *)pwd
, &(node
->password
)))
885 static int ventoy_plugin_pwd_check(VTOY_JSON
*json
, const char *isodisk
)
887 const char *iso
= NULL
;
888 const char *pwd
= NULL
;
889 VTOY_JSON
*pNode
= NULL
;
890 VTOY_JSON
*pCNode
= NULL
;
892 if (json
->enDataType
!= JSON_TYPE_OBJECT
)
894 grub_printf("Not object %d\n", json
->enDataType
);
898 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
900 if (pNode
->pcName
&& grub_strcmp("bootpwd", pNode
->pcName
) == 0)
902 if (0 == ventoy_plugin_parse_pwdstr(pNode
->unData
.pcStrVal
, NULL
))
904 grub_printf("bootpwd:<%s>\n", pNode
->unData
.pcStrVal
);
908 grub_printf("Invalid bootpwd.\n");
911 else if (pNode
->pcName
&& grub_strcmp("menupwd", pNode
->pcName
) == 0)
914 for (pCNode
= pNode
->pstChild
; pCNode
; pCNode
= pCNode
->pstNext
)
916 if (pCNode
->enDataType
!= JSON_TYPE_OBJECT
)
918 grub_printf("Not object %d\n", pCNode
->enDataType
);
922 iso
= vtoy_json_get_string_ex(pCNode
->pstChild
, "file");
925 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
927 pwd
= vtoy_json_get_string_ex(pCNode
->pstChild
, "pwd");
929 if (0 == ventoy_plugin_parse_pwdstr((char *)pwd
, NULL
))
931 grub_printf("file:<%s> [OK]\n", iso
);
932 grub_printf("pwd:<%s>\n\n", pwd
);
936 grub_printf("Invalid password for <%s>\n", iso
);
941 grub_printf("<%s%s> not found\n", isodisk
, iso
);
946 grub_printf("No file item found in json.\n");
955 static int ventoy_plugin_persistence_check(VTOY_JSON
*json
, const char *isodisk
)
959 const char *iso
= NULL
;
960 VTOY_JSON
*pNode
= NULL
;
962 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
964 grub_printf("Not array type %d\n", json
->enDataType
);
968 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
970 if (pNode
->enDataType
!= JSON_TYPE_OBJECT
)
972 grub_printf("NOT object type\n");
975 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
978 if (0 == ventoy_plugin_check_path(isodisk
, iso
))
980 grub_printf("image: %s [OK]\n", iso
);
981 ventoy_plugin_check_fullpath(pNode
->pstChild
, isodisk
, "backend", &pathnum
);
983 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
985 if (autosel
>= 0 && autosel
<= pathnum
)
987 grub_printf("autosel: %d [OK]\n", autosel
);
991 grub_printf("autosel: %d [FAIL]\n", autosel
);
997 grub_printf("image: %s [FAIL]\n", iso
);
1002 grub_printf("image not found\n");
1009 static int ventoy_plugin_persistence_entry(VTOY_JSON
*json
, const char *isodisk
)
1013 const char *iso
= NULL
;
1014 VTOY_JSON
*pNode
= NULL
;
1015 persistence_config
*node
= NULL
;
1016 persistence_config
*next
= NULL
;
1017 file_fullpath
*backendpath
= NULL
;
1021 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1023 debug("Not array %d\n", json
->enDataType
);
1027 if (g_persistence_head
)
1029 for (node
= g_persistence_head
; node
; node
= next
)
1032 grub_check_free(node
->backendpath
);
1036 g_persistence_head
= NULL
;
1039 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1041 iso
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1042 if (iso
&& iso
[0] == '/')
1044 if (0 == ventoy_plugin_parse_fullpath(pNode
->pstChild
, isodisk
, "backend", &backendpath
, &pathnum
))
1046 node
= grub_zalloc(sizeof(persistence_config
));
1049 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", iso
);
1050 node
->backendpath
= backendpath
;
1051 node
->backendnum
= pathnum
;
1054 if (JSON_SUCCESS
== vtoy_json_get_int(pNode
->pstChild
, "autosel", &autosel
))
1056 if (autosel
>= 0 && autosel
<= pathnum
)
1058 node
->autosel
= autosel
;
1062 if (g_persistence_head
)
1064 node
->next
= g_persistence_head
;
1067 g_persistence_head
= node
;
1076 static int ventoy_plugin_menualias_check(VTOY_JSON
*json
, const char *isodisk
)
1079 const char *path
= NULL
;
1080 const char *alias
= NULL
;
1081 VTOY_JSON
*pNode
= NULL
;
1085 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1087 grub_printf("Not array %d\n", json
->enDataType
);
1091 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1093 type
= vtoy_alias_image_file
;
1094 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1097 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1098 type
= vtoy_alias_directory
;
1101 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1102 if (path
&& path
[0] == '/' && alias
)
1104 if (vtoy_alias_image_file
== type
)
1106 if (ventoy_is_file_exist("%s%s", isodisk
, path
))
1108 grub_printf("image: <%s> [ OK ]\n", path
);
1112 grub_printf("image: <%s> [ NOT EXIST ]\n", path
);
1117 if (ventoy_is_dir_exist("%s%s", isodisk
, path
))
1119 grub_printf("dir: <%s> [ OK ]\n", path
);
1123 grub_printf("dir: <%s> [ NOT EXIST ]\n", path
);
1127 grub_printf("alias: <%s>\n\n", alias
);
1134 static int ventoy_plugin_menualias_entry(VTOY_JSON
*json
, const char *isodisk
)
1137 const char *path
= NULL
;
1138 const char *alias
= NULL
;
1139 VTOY_JSON
*pNode
= NULL
;
1140 menu_alias
*node
= NULL
;
1141 menu_alias
*next
= NULL
;
1145 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1147 debug("Not array %d\n", json
->enDataType
);
1151 if (g_menu_alias_head
)
1153 for (node
= g_menu_alias_head
; node
; node
= next
)
1159 g_menu_alias_head
= NULL
;
1162 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1164 type
= vtoy_alias_image_file
;
1165 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1168 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1169 type
= vtoy_alias_directory
;
1172 alias
= vtoy_json_get_string_ex(pNode
->pstChild
, "alias");
1173 if (path
&& path
[0] == '/' && alias
)
1175 node
= grub_zalloc(sizeof(menu_alias
));
1179 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1180 grub_snprintf(node
->alias
, sizeof(node
->alias
), "%s", alias
);
1182 if (g_menu_alias_head
)
1184 node
->next
= g_menu_alias_head
;
1187 g_menu_alias_head
= node
;
1196 static int ventoy_plugin_injection_check(VTOY_JSON
*json
, const char *isodisk
)
1198 const char *path
= NULL
;
1199 const char *archive
= NULL
;
1200 VTOY_JSON
*pNode
= NULL
;
1204 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1206 grub_printf("Not array %d\n", json
->enDataType
);
1210 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1212 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1215 grub_printf("image not found\n");
1219 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1222 grub_printf("archive not found\n");
1226 grub_printf("image: <%s> [%s]\n", path
, ventoy_check_file_exist("%s%s", isodisk
, path
) ? "OK" : "NOT EXIST");
1227 grub_printf("archive: <%s> [%s]\n\n", archive
, ventoy_check_file_exist("%s%s", isodisk
, archive
) ? "OK" : "NOT EXIST");
1233 static int ventoy_plugin_injection_entry(VTOY_JSON
*json
, const char *isodisk
)
1235 const char *path
= NULL
;
1236 const char *archive
= NULL
;
1237 VTOY_JSON
*pNode
= NULL
;
1238 injection_config
*node
= NULL
;
1239 injection_config
*next
= NULL
;
1243 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1245 debug("Not array %d\n", json
->enDataType
);
1249 if (g_injection_head
)
1251 for (node
= g_injection_head
; node
; node
= next
)
1257 g_injection_head
= NULL
;
1260 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1262 path
= vtoy_json_get_string_ex(pNode
->pstChild
, "image");
1263 archive
= vtoy_json_get_string_ex(pNode
->pstChild
, "archive");
1264 if (path
&& path
[0] == '/' && archive
&& archive
[0] == '/')
1266 node
= grub_zalloc(sizeof(injection_config
));
1269 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", path
);
1270 grub_snprintf(node
->archive
, sizeof(node
->archive
), "%s", archive
);
1272 if (g_injection_head
)
1274 node
->next
= g_injection_head
;
1277 g_injection_head
= node
;
1285 static int ventoy_plugin_menuclass_entry(VTOY_JSON
*json
, const char *isodisk
)
1288 const char *key
= NULL
;
1289 const char *class = NULL
;
1290 VTOY_JSON
*pNode
= NULL
;
1291 menu_class
*tail
= NULL
;
1292 menu_class
*node
= NULL
;
1293 menu_class
*next
= NULL
;
1297 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1299 debug("Not array %d\n", json
->enDataType
);
1303 if (g_menu_class_head
)
1305 for (node
= g_menu_class_head
; node
; node
= next
)
1311 g_menu_class_head
= NULL
;
1314 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1316 type
= vtoy_class_image_file
;
1317 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1320 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1321 type
= vtoy_class_directory
;
1324 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1327 node
= grub_zalloc(sizeof(menu_class
));
1331 node
->patlen
= grub_snprintf(node
->pattern
, sizeof(node
->pattern
), "%s", key
);
1332 grub_snprintf(node
->class, sizeof(node
->class), "%s", class);
1334 if (g_menu_class_head
)
1340 g_menu_class_head
= node
;
1350 static int ventoy_plugin_menuclass_check(VTOY_JSON
*json
, const char *isodisk
)
1353 const char *key
= NULL
;
1354 const char *class = NULL
;
1355 VTOY_JSON
*pNode
= NULL
;
1359 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1361 grub_printf("Not array %d\n", json
->enDataType
);
1365 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1367 type
= vtoy_class_image_file
;
1368 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "key");
1371 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1372 type
= vtoy_class_directory
;
1375 class = vtoy_json_get_string_ex(pNode
->pstChild
, "class");
1378 grub_printf("%s: <%s>\n", (type
== vtoy_class_directory
) ? "dir" : "key", key
);
1379 grub_printf("class: <%s>\n\n", class);
1386 static int ventoy_plugin_custom_boot_entry(VTOY_JSON
*json
, const char *isodisk
)
1390 const char *key
= NULL
;
1391 const char *cfg
= NULL
;
1392 VTOY_JSON
*pNode
= NULL
;
1393 custom_boot
*tail
= NULL
;
1394 custom_boot
*node
= NULL
;
1395 custom_boot
*next
= NULL
;
1399 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1401 debug("Not array %d\n", json
->enDataType
);
1405 if (g_custom_boot_head
)
1407 for (node
= g_custom_boot_head
; node
; node
= next
)
1413 g_custom_boot_head
= NULL
;
1416 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1418 type
= vtoy_custom_boot_image_file
;
1419 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1422 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1423 type
= vtoy_custom_boot_directory
;
1426 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1429 node
= grub_zalloc(sizeof(custom_boot
));
1433 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", key
);
1434 len
= (int)grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", cfg
);
1436 if (len
>= 5 && grub_strncmp(node
->cfg
+ len
- 5, ".vcfg", 5) == 0)
1438 if (g_custom_boot_head
)
1444 g_custom_boot_head
= node
;
1459 static int ventoy_plugin_custom_boot_check(VTOY_JSON
*json
, const char *isodisk
)
1463 const char *key
= NULL
;
1464 const char *cfg
= NULL
;
1465 VTOY_JSON
*pNode
= NULL
;
1469 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1471 grub_printf("Not array %d\n", json
->enDataType
);
1475 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1477 type
= vtoy_custom_boot_image_file
;
1478 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "file");
1481 key
= vtoy_json_get_string_ex(pNode
->pstChild
, "dir");
1482 type
= vtoy_custom_boot_directory
;
1485 cfg
= vtoy_json_get_string_ex(pNode
->pstChild
, "vcfg");
1486 len
= (int)grub_strlen(cfg
);
1489 if (len
< 5 || grub_strncmp(cfg
+ len
- 5, ".vcfg", 5))
1491 grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg
);
1495 grub_printf("%s: <%s>\n", (type
== vtoy_custom_boot_directory
) ? "dir" : "file", key
);
1496 grub_printf("vcfg: <%s>\n\n", cfg
);
1504 static int ventoy_plugin_conf_replace_entry(VTOY_JSON
*json
, const char *isodisk
)
1506 const char *isof
= NULL
;
1507 const char *orgf
= NULL
;
1508 const char *newf
= NULL
;
1509 VTOY_JSON
*pNode
= NULL
;
1510 conf_replace
*tail
= NULL
;
1511 conf_replace
*node
= NULL
;
1512 conf_replace
*next
= NULL
;
1516 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1518 debug("Not array %d\n", json
->enDataType
);
1522 if (g_conf_replace_head
)
1524 for (node
= g_conf_replace_head
; node
; node
= next
)
1530 g_conf_replace_head
= NULL
;
1533 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1535 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1536 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1537 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1538 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1540 node
= grub_zalloc(sizeof(conf_replace
));
1543 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", isof
);
1544 grub_snprintf(node
->orgconf
, sizeof(node
->orgconf
), "%s", orgf
);
1545 grub_snprintf(node
->newconf
, sizeof(node
->newconf
), "%s", newf
);
1547 if (g_conf_replace_head
)
1553 g_conf_replace_head
= node
;
1563 static int ventoy_plugin_conf_replace_check(VTOY_JSON
*json
, const char *isodisk
)
1565 const char *isof
= NULL
;
1566 const char *orgf
= NULL
;
1567 const char *newf
= NULL
;
1568 VTOY_JSON
*pNode
= NULL
;
1569 grub_file_t file
= NULL
;
1574 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1576 grub_printf("Not array %d\n", json
->enDataType
);
1580 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1582 isof
= vtoy_json_get_string_ex(pNode
->pstChild
, "iso");
1583 orgf
= vtoy_json_get_string_ex(pNode
->pstChild
, "org");
1584 newf
= vtoy_json_get_string_ex(pNode
->pstChild
, "new");
1585 if (isof
&& orgf
&& newf
&& isof
[0] == '/' && orgf
[0] == '/' && newf
[0] == '/')
1587 if (ventoy_check_file_exist("%s%s", isodisk
, isof
))
1589 grub_printf("iso:<%s> [OK]\n", isof
);
1591 grub_snprintf(cmd
, sizeof(cmd
), "loopback vtisocheck \"%s%s\"", isodisk
, isof
);
1592 grub_script_execute_sourcecode(cmd
);
1594 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(vtisocheck)/%s", orgf
);
1597 if (grub_strcmp(file
->fs
->name
, "iso9660") == 0)
1599 grub_printf("org:<%s> [OK]\n", orgf
);
1603 grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf
);
1605 grub_file_close(file
);
1609 grub_printf("org:<%s> [NOT Exist]\n", orgf
);
1612 grub_script_execute_sourcecode("loopback -d vtisocheck");
1616 grub_printf("iso:<%s> [NOT Exist]\n", isof
);
1617 grub_printf("org:<%s>\n", orgf
);
1620 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isodisk
, newf
);
1623 if (file
->size
> vtoy_max_replace_file_size
)
1625 grub_printf("new:<%s> [Too Big %lu] \n", newf
, (ulong
)file
->size
);
1629 grub_printf("new:<%s> [OK]\n", newf
);
1631 grub_file_close(file
);
1635 grub_printf("new:<%s> [NOT Exist]\n", newf
);
1644 static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON
*json
, const char *isodisk
)
1646 VTOY_JSON
*pNode
= NULL
;
1647 auto_memdisk
*node
= NULL
;
1648 auto_memdisk
*next
= NULL
;
1652 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1654 debug("Not array %d\n", json
->enDataType
);
1658 if (g_auto_memdisk_head
)
1660 for (node
= g_auto_memdisk_head
; node
; node
= next
)
1666 g_auto_memdisk_head
= NULL
;
1669 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1671 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1673 node
= grub_zalloc(sizeof(auto_memdisk
));
1676 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1678 if (g_auto_memdisk_head
)
1680 node
->next
= g_auto_memdisk_head
;
1683 g_auto_memdisk_head
= node
;
1691 static int ventoy_plugin_auto_memdisk_check(VTOY_JSON
*json
, const char *isodisk
)
1693 VTOY_JSON
*pNode
= NULL
;
1695 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1697 grub_printf("Not array %d\n", json
->enDataType
);
1701 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1703 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1705 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1707 if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1709 grub_printf(" [OK]\n");
1713 grub_printf(" [NOT EXIST]\n");
1721 static int ventoy_plugin_image_list_entry(VTOY_JSON
*json
, const char *isodisk
)
1723 VTOY_JSON
*pNode
= NULL
;
1724 image_list
*node
= NULL
;
1725 image_list
*next
= NULL
;
1726 image_list
*tail
= NULL
;
1730 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1732 debug("Not array %d\n", json
->enDataType
);
1736 if (g_image_list_head
)
1738 for (node
= g_image_list_head
; node
; node
= next
)
1744 g_image_list_head
= NULL
;
1747 if (grub_strncmp(json
->pcName
, "image_blacklist", 15) == 0)
1749 g_plugin_image_list
= VENTOY_IMG_BLACK_LIST
;
1753 g_plugin_image_list
= VENTOY_IMG_WHITE_LIST
;
1756 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1758 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1760 node
= grub_zalloc(sizeof(image_list
));
1763 node
->pathlen
= grub_snprintf(node
->isopath
, sizeof(node
->isopath
), "%s", pNode
->unData
.pcStrVal
);
1765 if (g_image_list_head
)
1771 g_image_list_head
= node
;
1781 static int ventoy_plugin_image_list_check(VTOY_JSON
*json
, const char *isodisk
)
1783 VTOY_JSON
*pNode
= NULL
;
1785 if (json
->enDataType
!= JSON_TYPE_ARRAY
)
1787 grub_printf("Not array %d\n", json
->enDataType
);
1791 for (pNode
= json
->pstChild
; pNode
; pNode
= pNode
->pstNext
)
1793 if (pNode
->enDataType
== JSON_TYPE_STRING
)
1795 grub_printf("<%s> ", pNode
->unData
.pcStrVal
);
1797 if (ventoy_check_file_exist("%s%s", isodisk
, pNode
->unData
.pcStrVal
))
1799 grub_printf(" [OK]\n");
1803 grub_printf(" [NOT EXIST]\n");
1811 static plugin_entry g_plugin_entries
[] =
1813 { "control", ventoy_plugin_control_entry
, ventoy_plugin_control_check
},
1814 { "theme", ventoy_plugin_theme_entry
, ventoy_plugin_theme_check
},
1815 { "auto_install", ventoy_plugin_auto_install_entry
, ventoy_plugin_auto_install_check
},
1816 { "persistence", ventoy_plugin_persistence_entry
, ventoy_plugin_persistence_check
},
1817 { "menu_alias", ventoy_plugin_menualias_entry
, ventoy_plugin_menualias_check
},
1818 { "menu_class", ventoy_plugin_menuclass_entry
, ventoy_plugin_menuclass_check
},
1819 { "injection", ventoy_plugin_injection_entry
, ventoy_plugin_injection_check
},
1820 { "auto_memdisk", ventoy_plugin_auto_memdisk_entry
, ventoy_plugin_auto_memdisk_check
},
1821 { "image_list", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
1822 { "image_blacklist", ventoy_plugin_image_list_entry
, ventoy_plugin_image_list_check
},
1823 { "conf_replace", ventoy_plugin_conf_replace_entry
, ventoy_plugin_conf_replace_check
},
1824 { "dud", ventoy_plugin_dud_entry
, ventoy_plugin_dud_check
},
1825 { "password", ventoy_plugin_pwd_entry
, ventoy_plugin_pwd_check
},
1826 { "custom_boot", ventoy_plugin_custom_boot_entry
, ventoy_plugin_custom_boot_check
},
1829 static int ventoy_parse_plugin_config(VTOY_JSON
*json
, const char *isodisk
)
1833 VTOY_JSON
*cur
= json
;
1835 grub_snprintf(g_iso_disk_name
, sizeof(g_iso_disk_name
), "%s", isodisk
);
1839 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
1841 grub_snprintf(key
, sizeof(key
), "%s_%s", g_plugin_entries
[i
].key
, g_arch_mode_suffix
);
1842 if (grub_strcmp(g_plugin_entries
[i
].key
, cur
->pcName
) == 0 || grub_strcmp(key
, cur
->pcName
) == 0)
1844 debug("Plugin entry for %s\n", g_plugin_entries
[i
].key
);
1845 g_plugin_entries
[i
].entryfunc(cur
, isodisk
);
1856 grub_err_t
ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1861 VTOY_JSON
*json
= NULL
;
1866 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
1869 return GRUB_ERR_NONE
;
1872 debug("json configuration file size %d\n", (int)file
->size
);
1874 buf
= grub_malloc(file
->size
+ 1);
1877 grub_file_close(file
);
1881 buf
[file
->size
] = 0;
1882 grub_file_read(file
, buf
, file
->size
);
1883 grub_file_close(file
);
1885 json
= vtoy_json_create();
1893 ret
= vtoy_json_parse(json
, buf
);
1896 grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1");
1897 grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR");
1899 debug("Failed to parse json string %d\n", ret
);
1904 ventoy_parse_plugin_config(json
->pstChild
, args
[0]);
1906 vtoy_json_destroy(json
);
1910 if (g_boot_pwd
.type
)
1912 grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER"));
1913 if (ventoy_check_password(&g_boot_pwd
, 3))
1915 grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n");
1922 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1925 void ventoy_plugin_dump_injection(void)
1927 injection_config
*node
= NULL
;
1929 for (node
= g_injection_head
; node
; node
= node
->next
)
1931 grub_printf("\nIMAGE:<%s>\n", node
->isopath
);
1932 grub_printf("ARCHIVE:<%s>\n", node
->archive
);
1939 void ventoy_plugin_dump_auto_install(void)
1942 install_template
*node
= NULL
;
1944 for (node
= g_install_template_head
; node
; node
= node
->next
)
1946 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->templatenum
);
1947 for (i
= 0; i
< node
->templatenum
; i
++)
1949 grub_printf("SCRIPT %d:<%s>\n", i
, node
->templatepath
[i
].path
);
1956 void ventoy_plugin_dump_persistence(void)
1960 persistence_config
*node
= NULL
;
1961 ventoy_img_chunk_list chunk_list
;
1963 for (node
= g_persistence_head
; node
; node
= node
->next
)
1965 grub_printf("\nIMAGE:<%s> <%d>\n", node
->isopath
, node
->backendnum
);
1967 for (i
= 0; i
< node
->backendnum
; i
++)
1969 grub_printf("PERSIST %d:<%s>", i
, node
->backendpath
[i
].path
);
1970 rc
= ventoy_plugin_get_persistent_chunklist(node
->isopath
, i
, &chunk_list
);
1973 grub_printf(" [ SUCCESS ]\n");
1974 grub_free(chunk_list
.chunk
);
1978 grub_printf(" [ FAILED ]\n");
1986 install_template
* ventoy_plugin_find_install_template(const char *isopath
)
1989 install_template
*node
= NULL
;
1991 if (!g_install_template_head
)
1996 len
= (int)grub_strlen(isopath
);
1997 for (node
= g_install_template_head
; node
; node
= node
->next
)
1999 if (node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
2008 char * ventoy_plugin_get_cur_install_template(const char *isopath
)
2010 install_template
*node
= NULL
;
2012 node
= ventoy_plugin_find_install_template(isopath
);
2013 if ((!node
) || (!node
->templatepath
))
2018 if (node
->cursel
< 0 || node
->cursel
>= node
->templatenum
)
2023 return node
->templatepath
[node
->cursel
].path
;
2026 persistence_config
* ventoy_plugin_find_persistent(const char *isopath
)
2029 persistence_config
*node
= NULL
;
2031 if (!g_persistence_head
)
2036 len
= (int)grub_strlen(isopath
);
2037 for (node
= g_persistence_head
; node
; node
= node
->next
)
2039 if ((len
== node
->pathlen
) && (grub_strcmp(node
->isopath
, isopath
) == 0))
2048 int ventoy_plugin_get_persistent_chunklist(const char *isopath
, int index
, ventoy_img_chunk_list
*chunk_list
)
2051 grub_uint64_t start
= 0;
2052 grub_file_t file
= NULL
;
2053 persistence_config
*node
= NULL
;
2055 node
= ventoy_plugin_find_persistent(isopath
);
2056 if ((!node
) || (!node
->backendpath
))
2063 index
= node
->cursel
;
2066 if (index
< 0 || index
>= node
->backendnum
)
2071 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", g_iso_disk_name
, node
->backendpath
[index
].path
);
2074 debug("Failed to open file %s%s\n", g_iso_disk_name
, node
->backendpath
[index
].path
);
2078 grub_memset(chunk_list
, 0, sizeof(ventoy_img_chunk_list
));
2079 chunk_list
->chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2080 if (NULL
== chunk_list
->chunk
)
2085 chunk_list
->max_chunk
= DEFAULT_CHUNK_NUM
;
2086 chunk_list
->cur_chunk
= 0;
2088 start
= file
->device
->disk
->partition
->start
;
2089 ventoy_get_block_list(file
, chunk_list
, start
);
2091 if (0 != ventoy_check_block_list(file
, chunk_list
, start
))
2093 grub_free(chunk_list
->chunk
);
2094 chunk_list
->chunk
= NULL
;
2102 grub_file_close(file
);
2107 const char * ventoy_plugin_get_injection(const char *isopath
)
2110 injection_config
*node
= NULL
;
2112 if (!g_injection_head
)
2117 len
= (int)grub_strlen(isopath
);
2118 for (node
= g_injection_head
; node
; node
= node
->next
)
2120 if (node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
2122 return node
->archive
;
2129 const char * ventoy_plugin_get_menu_alias(int type
, const char *isopath
)
2132 menu_alias
*node
= NULL
;
2134 if (!g_menu_alias_head
)
2139 len
= (int)grub_strlen(isopath
);
2140 for (node
= g_menu_alias_head
; node
; node
= node
->next
)
2142 if (node
->type
== type
&& node
->pathlen
&&
2143 node
->pathlen
== len
&& grub_strcmp(node
->isopath
, isopath
) == 0)
2152 const char * ventoy_plugin_get_menu_class(int type
, const char *name
)
2155 menu_class
*node
= NULL
;
2157 if (!g_menu_class_head
)
2162 len
= (int)grub_strlen(name
);
2164 if (vtoy_class_image_file
== type
)
2166 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2168 if (node
->type
== type
&& node
->patlen
<= len
&& grub_strstr(name
, node
->pattern
))
2176 for (node
= g_menu_class_head
; node
; node
= node
->next
)
2178 if (node
->type
== type
&& node
->patlen
== len
&& grub_strncmp(name
, node
->pattern
, len
) == 0)
2188 int ventoy_plugin_add_custom_boot(const char *vcfgpath
)
2191 custom_boot
*node
= NULL
;
2193 node
= grub_zalloc(sizeof(custom_boot
));
2196 node
->type
= vtoy_custom_boot_image_file
;
2197 node
->pathlen
= grub_snprintf(node
->path
, sizeof(node
->path
), "%s", vcfgpath
);
2198 grub_snprintf(node
->cfg
, sizeof(node
->cfg
), "%s", vcfgpath
);
2201 len
= node
->pathlen
- 5;
2202 node
->path
[len
] = 0;
2203 node
->pathlen
= len
;
2205 if (g_custom_boot_head
)
2207 node
->next
= g_custom_boot_head
;
2209 g_custom_boot_head
= node
;
2215 const char * ventoy_plugin_get_custom_boot(const char *isopath
)
2219 custom_boot
*node
= NULL
;
2221 if (!g_custom_boot_head
)
2226 len
= (int)grub_strlen(isopath
);
2228 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2230 if (node
->type
== vtoy_custom_boot_image_file
)
2232 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->path
, len
) == 0)
2239 if (node
->pathlen
< len
&& isopath
[node
->pathlen
] == '/' &&
2240 grub_strncmp(isopath
, node
->path
, node
->pathlen
) == 0)
2242 for (i
= node
->pathlen
+ 1; i
< len
; i
++)
2244 if (isopath
[i
] == '/')
2261 grub_err_t
ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2263 custom_boot
*node
= NULL
;
2269 for (node
= g_custom_boot_head
; node
; node
= node
->next
)
2271 grub_printf("[%s] <%s>:<%s>\n", (node
->type
== vtoy_custom_boot_directory
) ? "dir" : "file",
2272 node
->path
, node
->cfg
);
2278 int ventoy_plugin_check_memdisk(const char *isopath
)
2281 auto_memdisk
*node
= NULL
;
2283 if (!g_auto_memdisk_head
)
2288 len
= (int)grub_strlen(isopath
);
2289 for (node
= g_auto_memdisk_head
; node
; node
= node
->next
)
2291 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->isopath
, len
) == 0)
2300 int ventoy_plugin_get_image_list_index(int type
, const char *name
)
2304 image_list
*node
= NULL
;
2306 if (!g_image_list_head
)
2311 len
= (int)grub_strlen(name
);
2313 for (node
= g_image_list_head
; node
; node
= node
->next
, index
++)
2315 if (vtoy_class_directory
== type
)
2317 if (len
< node
->pathlen
&& grub_strncmp(name
, node
->isopath
, len
) == 0)
2324 if (len
== node
->pathlen
&& grub_strncmp(name
, node
->isopath
, len
) == 0)
2334 conf_replace
* ventoy_plugin_find_conf_replace(const char *iso
)
2339 if (!g_conf_replace_head
)
2344 len
= (int)grub_strlen(iso
);
2346 for (node
= g_conf_replace_head
; node
; node
= node
->next
)
2348 if (node
->pathlen
== len
&& grub_strncmp(iso
, node
->isopath
, len
) == 0)
2357 dud
* ventoy_plugin_find_dud(const char *iso
)
2367 len
= (int)grub_strlen(iso
);
2368 for (node
= g_dud_head
; node
; node
= node
->next
)
2370 if (node
->pathlen
== len
&& grub_strncmp(iso
, node
->isopath
, len
) == 0)
2379 int ventoy_plugin_load_dud(dud
*node
, const char *isopart
)
2385 for (i
= 0; i
< node
->dudnum
; i
++)
2387 if (node
->files
[i
].size
> 0)
2389 debug("file %d has been loaded\n", i
);
2393 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", isopart
, node
->dudpath
[i
].path
);
2396 buf
= grub_malloc(file
->size
);
2399 grub_file_read(file
, buf
, file
->size
);
2400 node
->files
[i
].size
= (int)file
->size
;
2401 node
->files
[i
].buf
= buf
;
2403 grub_file_close(file
);
2410 static const vtoy_password
* ventoy_plugin_get_password(const char *isopath
)
2413 menu_password
*node
= NULL
;
2415 if ((!g_pwd_head
) || (!isopath
))
2420 len
= (int)grub_strlen(isopath
);
2421 for (node
= g_pwd_head
; node
; node
= node
->next
)
2423 if (node
->pathlen
== len
&& grub_strncmp(isopath
, node
->isopath
, len
) == 0)
2425 return &(node
->password
);
2432 grub_err_t
ventoy_cmd_check_password(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2435 const vtoy_password
*pwd
= NULL
;
2440 pwd
= ventoy_plugin_get_password(args
[0]);
2443 if (0 == ventoy_check_password(pwd
, 1))
2461 grub_err_t
ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2468 VTOY_JSON
*node
= NULL
;
2469 VTOY_JSON
*json
= NULL
;
2478 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy.json", args
[0]);
2481 grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
2482 grub_printf("Attention: directory name and filename are both case-sensitive.\n");
2486 buf
= grub_malloc(file
->size
+ 1);
2489 grub_printf("Failed to malloc memory %lu.\n", (ulong
)(file
->size
+ 1));
2493 buf
[file
->size
] = 0;
2494 grub_file_read(file
, buf
, file
->size
);
2496 json
= vtoy_json_create();
2499 grub_printf("Failed to create json\n");
2503 ret
= vtoy_json_parse(json
, buf
);
2506 grub_printf("Syntax error detected in ventoy.json, please check it.\n");
2510 grub_snprintf(key
, sizeof(key
), "%s_%s", args
[1], g_arch_mode_suffix
);
2511 for (node
= json
->pstChild
; node
; node
= node
->pstNext
)
2513 if (grub_strcmp(node
->pcName
, args
[1]) == 0 || grub_strcmp(node
->pcName
, key
) == 0)
2521 grub_printf("%s is NOT found in ventoy.json\n", args
[1]);
2525 for (i
= 0; i
< (int)ARRAY_SIZE(g_plugin_entries
); i
++)
2527 if (grub_strcmp(g_plugin_entries
[i
].key
, args
[1]) == 0)
2529 if (g_plugin_entries
[i
].checkfunc
)
2531 ret
= g_plugin_entries
[i
].checkfunc(node
, args
[2]);
2538 check_free(file
, grub_file_close
);
2539 check_free(json
, vtoy_json_destroy
);
2540 grub_check_free(buf
);