1 /******************************************************************************
4 * Copyright (c) 2021, 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/>.
21 #include <grub/types.h>
22 #include <grub/misc.h>
26 #include <grub/disk.h>
27 #include <grub/device.h>
28 #include <grub/term.h>
29 #include <grub/partition.h>
30 #include <grub/file.h>
31 #include <grub/normal.h>
32 #include <grub/extcmd.h>
33 #include <grub/datetime.h>
34 #include <grub/i18n.h>
36 #include <grub/misc.h>
37 #include <grub/kernel.h>
38 #ifdef GRUB_MACHINE_EFI
39 #include <grub/efi/api.h>
40 #include <grub/efi/efi.h>
42 #include <grub/time.h>
43 #include <grub/video.h>
44 #include <grub/acpi.h>
45 #include <grub/charset.h>
46 #include <grub/crypto.h>
47 #include <grub/lib/crc.h>
48 #include <grub/ventoy.h>
49 #include "ventoy_def.h"
52 GRUB_MOD_LICENSE ("GPLv3+");
54 initrd_info
*g_initrd_img_list
= NULL
;
55 initrd_info
*g_initrd_img_tail
= NULL
;
56 int g_initrd_img_count
= 0;
57 int g_valid_initrd_count
= 0;
58 int g_default_menu_mode
= 0;
59 int g_filt_dot_underscore_file
= 0;
60 int g_sort_case_sensitive
= 0;
61 int g_tree_view_menu_style
= 0;
62 static grub_file_t g_old_file
;
63 static int g_ventoy_last_entry_back
;
66 char g_img_swap_tmp_buf
[1024];
67 img_info g_img_swap_tmp
;
68 img_info
*g_ventoy_img_list
= NULL
;
70 int g_ventoy_img_count
= 0;
72 grub_device_t g_enum_dev
= NULL
;
73 grub_fs_t g_enum_fs
= NULL
;
74 int g_img_max_search_level
= -1;
75 img_iterator_node g_img_iterator_head
;
76 img_iterator_node
*g_img_iterator_tail
= NULL
;
78 grub_uint8_t g_ventoy_break_level
= 0;
79 grub_uint8_t g_ventoy_debug_level
= 0;
80 grub_uint8_t g_ventoy_chain_type
= 0;
82 grub_uint8_t
*g_ventoy_cpio_buf
= NULL
;
83 grub_uint32_t g_ventoy_cpio_size
= 0;
84 cpio_newc_header
*g_ventoy_initrd_head
= NULL
;
85 grub_uint8_t
*g_ventoy_runtime_buf
= NULL
;
87 int g_plugin_image_list
= 0;
89 ventoy_grub_param
*g_grub_param
= NULL
;
91 ventoy_guid g_ventoy_guid
= VENTOY_GUID
;
93 ventoy_img_chunk_list g_img_chunk_list
;
95 int g_wimboot_enable
= 0;
96 ventoy_img_chunk_list g_wimiso_chunk_list
;
97 char *g_wimiso_path
= NULL
;
99 int g_vhdboot_enable
= 0;
101 grub_uint64_t g_conf_replace_offset
= 0;
102 grub_uint64_t g_svd_replace_offset
= 0;
103 conf_replace
*g_conf_replace_node
= NULL
;
104 grub_uint8_t
*g_conf_replace_new_buf
= NULL
;
105 int g_conf_replace_new_len
= 0;
106 int g_conf_replace_new_len_align
= 0;
108 ventoy_gpt_info
*g_ventoy_part_info
= NULL
;
109 grub_uint64_t g_ventoy_disk_size
= 0;
110 grub_uint64_t g_ventoy_disk_part_size
[2];
112 static char *g_tree_script_buf
= NULL
;
113 static int g_tree_script_pos
= 0;
115 static char *g_list_script_buf
= NULL
;
116 static int g_list_script_pos
= 0;
118 static char *g_part_list_buf
= NULL
;
119 static int g_part_list_pos
= 0;
121 static int g_video_mode_max
= 0;
122 static int g_video_mode_num
= 0;
123 static ventoy_video_mode
*g_video_mode_list
= NULL
;
125 static int g_enumerate_time_checked
= 0;
126 static grub_uint64_t g_enumerate_start_time_ms
;
127 static grub_uint64_t g_enumerate_finish_time_ms
;
128 static int g_vtoy_file_flt
[VTOY_FILE_FLT_BUTT
] = {0};
130 static const char *g_vtoy_winpeshl_ini
= "[LaunchApps]\r\nvtoyjump.exe";
132 static const char *g_menu_class
[] =
134 "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy"
137 const char *g_menu_prefix
[img_type_max
] =
139 "iso", "wim", "efi", "img", "vhd", "vtoy"
142 static int ventoy_get_fs_type(const char *fs
)
146 return ventoy_fs_max
;
148 else if (grub_strncmp(fs
, "exfat", 5) == 0)
150 return ventoy_fs_exfat
;
152 else if (grub_strncmp(fs
, "ntfs", 4) == 0)
154 return ventoy_fs_ntfs
;
156 else if (grub_strncmp(fs
, "ext", 3) == 0)
158 return ventoy_fs_ext
;
160 else if (grub_strncmp(fs
, "xfs", 3) == 0)
162 return ventoy_fs_xfs
;
164 else if (grub_strncmp(fs
, "udf", 3) == 0)
166 return ventoy_fs_udf
;
168 else if (grub_strncmp(fs
, "fat", 3) == 0)
170 return ventoy_fs_fat
;
173 return ventoy_fs_max
;
176 static int ventoy_string_check(const char *str
, grub_char_check_func check
)
195 static grub_ssize_t
ventoy_fs_read(grub_file_t file
, char *buf
, grub_size_t len
)
197 grub_memcpy(buf
, (char *)file
->data
+ file
->offset
, len
);
201 static int ventoy_control_get_flag(const char *key
)
203 const char *val
= ventoy_get_env(key
);
205 if (val
&& val
[0] == '1' && val
[1] == 0)
212 static grub_err_t
ventoy_fs_close(grub_file_t file
)
214 grub_file_close(g_old_file
);
215 grub_free(file
->data
);
223 static int ventoy_video_hook(const struct grub_video_mode_info
*info
, void *hook_arg
)
229 if (info
->mode_type
& GRUB_VIDEO_MODE_TYPE_PURE_TEXT
)
234 for (i
= 0; i
< g_video_mode_num
; i
++)
236 if (g_video_mode_list
[i
].width
== info
->width
&&
237 g_video_mode_list
[i
].height
== info
->height
&&
238 g_video_mode_list
[i
].bpp
== info
->bpp
)
244 g_video_mode_list
[g_video_mode_num
].width
= info
->width
;
245 g_video_mode_list
[g_video_mode_num
].height
= info
->height
;
246 g_video_mode_list
[g_video_mode_num
].bpp
= info
->bpp
;
249 if (g_video_mode_num
== g_video_mode_max
)
251 g_video_mode_max
*= 2;
252 g_video_mode_list
= grub_realloc(g_video_mode_list
, g_video_mode_max
* sizeof(ventoy_video_mode
));
258 static int ventoy_video_mode_cmp(ventoy_video_mode
*v1
, ventoy_video_mode
*v2
)
260 if (v1
->bpp
== v2
->bpp
)
262 if (v1
->width
== v2
->width
)
264 if (v1
->height
== v2
->height
)
270 return (v1
->height
< v2
->height
) ? -1 : 1;
275 return (v1
->width
< v2
->width
) ? -1 : 1;
280 return (v1
->bpp
< v2
->bpp
) ? -1 : 1;
284 static int ventoy_enum_video_mode(void)
287 grub_video_adapter_t adapter
;
288 grub_video_driver_id_t id
;
289 ventoy_video_mode mode
;
291 g_video_mode_num
= 0;
292 g_video_mode_max
= 1024;
293 g_video_mode_list
= grub_malloc(sizeof(ventoy_video_mode
) * g_video_mode_max
);
294 if (!g_video_mode_list
)
299 #ifdef GRUB_MACHINE_PCBIOS
300 grub_dl_load ("vbe");
303 id
= grub_video_get_driver_id ();
305 FOR_VIDEO_ADAPTERS (adapter
)
307 if (!adapter
->iterate
||
308 (adapter
->id
!= id
&& (id
!= GRUB_VIDEO_DRIVER_NONE
||
309 adapter
->init() != GRUB_ERR_NONE
)))
314 adapter
->iterate(ventoy_video_hook
, NULL
);
316 if (adapter
->id
!= id
)
322 /* sort video mode */
323 for (i
= 0; i
< g_video_mode_num
; i
++)
324 for (j
= i
+ 1; j
< g_video_mode_num
; j
++)
326 if (ventoy_video_mode_cmp(g_video_mode_list
+ i
, g_video_mode_list
+ j
) < 0)
328 grub_memcpy(&mode
, g_video_mode_list
+ i
, sizeof(ventoy_video_mode
));
329 grub_memcpy(g_video_mode_list
+ i
, g_video_mode_list
+ j
, sizeof(ventoy_video_mode
));
330 grub_memcpy(g_video_mode_list
+ j
, &mode
, sizeof(ventoy_video_mode
));
334 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
337 static grub_file_t
ventoy_wrapper_open(grub_file_t rawFile
, enum grub_file_type type
)
341 static struct grub_fs vtoy_fs
=
346 .fs_read
= ventoy_fs_read
,
347 .fs_close
= ventoy_fs_close
,
357 file
= (grub_file_t
)grub_zalloc(sizeof (*file
));
363 file
->data
= grub_malloc(rawFile
->size
+ 4096);
369 grub_file_read(rawFile
, file
->data
, rawFile
->size
);
370 len
= ventoy_fill_data(4096, (char *)file
->data
+ rawFile
->size
);
372 g_old_file
= rawFile
;
374 file
->size
= rawFile
->size
+ len
;
375 file
->device
= rawFile
->device
;
377 file
->not_easily_seekable
= 1;
382 static int ventoy_check_decimal_var(const char *name
, long *value
)
384 const char *value_str
= NULL
;
386 value_str
= grub_env_get(name
);
387 if (NULL
== value_str
)
389 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Variable %s not found", name
);
392 if (!ventoy_is_decimal(value_str
))
394 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Variable %s value '%s' is not an integer", name
, value_str
);
397 *value
= grub_strtol(value_str
, NULL
, 10);
399 return GRUB_ERR_NONE
;
402 grub_uint64_t
ventoy_get_vtoy_partsize(int part
)
404 grub_uint64_t sectors
;
406 if (grub_strncmp(g_ventoy_part_info
->Head
.Signature
, "EFI PART", 8) == 0)
408 sectors
= g_ventoy_part_info
->PartTbl
[part
].LastLBA
+ 1 - g_ventoy_part_info
->PartTbl
[part
].StartLBA
;
412 sectors
= g_ventoy_part_info
->MBR
.PartTbl
[part
].SectorCount
;
415 return sectors
* 512;
418 static int ventoy_load_efiboot_template(char **buf
, int *datalen
, int *direntoff
)
424 grub_uint32_t offset
;
426 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s/ventoy/ventoy_efiboot.img.xz", ventoy_get_env("vtoy_efi_part"));
429 debug("failed to open file <%s>\n", "ventoy_efiboot.img.xz");
433 len
= (int)file
->size
;
435 data
= (char *)grub_malloc(file
->size
);
441 grub_file_read(file
, data
, file
->size
);
442 grub_file_close(file
);
444 grub_snprintf(exec
, sizeof(exec
), "loopback efiboot mem:0x%llx:size:%d", (ulonglong
)(ulong
)data
, len
);
445 grub_script_execute_sourcecode(exec
);
447 file
= grub_file_open("(efiboot)/EFI/BOOT/BOOTX64.EFI", GRUB_FILE_TYPE_LINUX_INITRD
);
448 offset
= (grub_uint32_t
)grub_iso9660_get_last_file_dirent_pos(file
);
449 grub_file_close(file
);
451 grub_script_execute_sourcecode("loopback -d efiboot");
455 *direntoff
= offset
+ 2;
460 static int ventoy_set_check_result(int ret
)
464 grub_snprintf(buf
, sizeof(buf
), "%d", (ret
& 0x7FFF));
465 grub_env_set("VTOY_CHKDEV_RESULT_STRING", buf
);
466 grub_env_export("VTOY_CHKDEV_RESULT_STRING");
470 grub_printf(VTOY_WARNING
"\n");
471 grub_printf(VTOY_WARNING
"\n");
472 grub_printf(VTOY_WARNING
"\n\n\n");
474 grub_printf("This is NOT a standard Ventoy device and is NOT supported (0x%x).\n\n", ret
);
475 grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n");
477 grub_printf("\n\nWill exit after 10 seconds ...... ");
485 static int ventoy_check_official_device(grub_device_t dev
)
489 grub_uint64_t offset
;
494 struct grub_partition
*partition
;
496 if (dev
->disk
== NULL
|| dev
->disk
->partition
== NULL
)
498 return ventoy_set_check_result(1 | 0x1000);
501 if (0 == ventoy_check_file_exist("(%s,2)/ventoy/ventoy.cpio", dev
->disk
->name
) ||
502 0 == ventoy_check_file_exist("(%s,2)/grub/localboot.cfg", dev
->disk
->name
) ||
503 0 == ventoy_check_file_exist("(%s,2)/tool/mount.exfat-fuse_aarch64", dev
->disk
->name
))
505 #ifndef GRUB_MACHINE_EFI
506 if (0 == ventoy_check_file_exist("(ventoydisk)/ventoy/ventoy.cpio", dev
->disk
->name
) ||
507 0 == ventoy_check_file_exist("(ventoydisk)/grub/localboot.cfg", dev
->disk
->name
) ||
508 0 == ventoy_check_file_exist("(ventoydisk)/tool/mount.exfat-fuse_aarch64", dev
->disk
->name
))
510 return ventoy_set_check_result(2 | 0x1000);
519 /* We must have partition 2 */
522 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", "(ventoydisk)/ventoy/ventoy.cpio");
526 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(%s,2)/ventoy/ventoy.cpio", dev
->disk
->name
);
530 return ventoy_set_check_result(3 | 0x1000);
533 if (NULL
== grub_strstr(file
->fs
->name
, "fat"))
535 grub_file_close(file
);
536 return ventoy_set_check_result(4 | 0x1000);
539 partition
= dev
->disk
->partition
;
540 if (partition
->number
!= 0 || partition
->start
!= 2048)
542 return ventoy_set_check_result(5);
547 if (grub_strncmp(g_ventoy_part_info
->Head
.Signature
, "EFI PART", 8) == 0)
549 ventoy_gpt_part_tbl
*PartTbl
= g_ventoy_part_info
->PartTbl
;
550 if (PartTbl
[1].StartLBA
!= PartTbl
[0].LastLBA
+ 1 ||
551 (PartTbl
[1].LastLBA
+ 1 - PartTbl
[1].StartLBA
) != 65536)
553 grub_file_close(file
);
554 return ventoy_set_check_result(6);
559 ventoy_part_table
*PartTbl
= g_ventoy_part_info
->MBR
.PartTbl
;
560 if (PartTbl
[1].StartSectorId
!= PartTbl
[0].StartSectorId
+ PartTbl
[0].SectorCount
||
561 PartTbl
[1].SectorCount
!= 65536)
563 grub_file_close(file
);
564 return ventoy_set_check_result(6);
570 offset
= partition
->start
+ partition
->len
;
571 partition
= file
->device
->disk
->partition
;
572 if ((partition
->number
!= 1) || (partition
->len
!= 65536) || (offset
!= partition
->start
))
574 grub_file_close(file
);
575 return ventoy_set_check_result(7);
579 grub_file_close(file
);
583 grub_snprintf(devname
, sizeof(devname
), "%s,2", dev
->disk
->name
);
584 dev2
= grub_device_open(devname
);
587 return ventoy_set_check_result(8);
590 fs
= grub_fs_probe(dev2
);
593 grub_device_close(dev2
);
594 return ventoy_set_check_result(9);
597 fs
->fs_label(dev2
, &label
);
598 if ((!label
) || grub_strncmp("VTOYEFI", label
, 7))
600 grub_device_close(dev2
);
601 return ventoy_set_check_result(10);
604 grub_device_close(dev2
);
607 return ventoy_set_check_result(0);
610 static int ventoy_check_ignore_flag(const char *filename
, const struct grub_dirhook_info
*info
, void *data
)
614 if (filename
&& filename
[0] == '.' && 0 == grub_strncmp(filename
, ".ventoyignore", 13))
624 grub_uint64_t
ventoy_grub_get_file_size(const char *fmt
, ...)
626 grub_uint64_t size
= 0;
629 char fullpath
[256] = {0};
632 grub_vsnprintf(fullpath
, 255, fmt
, ap
);
635 file
= grub_file_open(fullpath
, VENTOY_FILE_TYPE
);
638 debug("grub_file_open failed <%s>\n", fullpath
);
644 grub_file_close(file
);
648 grub_file_t
ventoy_grub_file_open(enum grub_file_type type
, const char *fmt
, ...)
652 char fullpath
[256] = {0};
655 grub_vsnprintf(fullpath
, 255, fmt
, ap
);
658 file
= grub_file_open(fullpath
, type
);
661 debug("grub_file_open failed <%s> %d\n", fullpath
, grub_errno
);
668 int ventoy_is_file_exist(const char *fmt
, ...)
675 grub_snprintf(buf
, sizeof(buf
), "%s", "[ -f \"");
679 len
= grub_vsnprintf(pos
, 255, fmt
, ap
);
682 grub_strncpy(pos
+ len
, "\" ]", 3);
684 debug("script exec %s\n", buf
);
686 if (0 == grub_script_execute_sourcecode(buf
))
694 int ventoy_is_dir_exist(const char *fmt
, ...)
701 grub_snprintf(buf
, sizeof(buf
), "%s", "[ -d \"");
705 len
= grub_vsnprintf(pos
, 255, fmt
, ap
);
708 grub_strncpy(pos
+ len
, "\" ]", 3);
710 debug("script exec %s\n", buf
);
712 if (0 == grub_script_execute_sourcecode(buf
))
720 int ventoy_gzip_compress(void *mem_in
, int mem_in_len
, void *mem_out
, int mem_out_len
)
723 grub_uint8_t
*outbuf
;
724 grub_uint8_t gzHdr
[10] =
726 0x1F, 0x8B, /* magic */
734 grub_memset(&s
, 0, sizeof(mz_stream
));
736 mz_deflateInit2(&s
, 1, MZ_DEFLATED
, -MZ_DEFAULT_WINDOW_BITS
, 6, MZ_DEFAULT_STRATEGY
);
738 outbuf
= (grub_uint8_t
*)mem_out
;
740 mem_out_len
-= sizeof(gzHdr
) + 8;
741 grub_memcpy(outbuf
, gzHdr
, sizeof(gzHdr
));
742 outbuf
+= sizeof(gzHdr
);
744 s
.avail_in
= mem_in_len
;
747 s
.avail_out
= mem_out_len
;
750 mz_deflate(&s
, MZ_FINISH
);
754 outbuf
+= s
.total_out
;
755 *(grub_uint32_t
*)outbuf
= grub_getcrc32c(0, outbuf
, s
.total_out
);
756 *(grub_uint32_t
*)(outbuf
+ 4) = (grub_uint32_t
)(s
.total_out
);
758 return s
.total_out
+ sizeof(gzHdr
) + 8;
766 static grub_err_t
ventoy_cmd_debug(grub_extcmd_context_t ctxt
, int argc
, char **args
)
770 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {on|off}", cmd_raw_name
);
773 if (0 == grub_strcmp(args
[0], "on"))
776 grub_env_set("vtdebug_flag", "debug");
781 grub_env_set("vtdebug_flag", "");
784 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
787 static grub_err_t
ventoy_cmd_break(grub_extcmd_context_t ctxt
, int argc
, char **args
)
791 if (argc
< 1 || (args
[0][0] != '0' && args
[0][0] != '1'))
793 grub_printf("Usage: %s {level} [debug]\r\n", cmd_raw_name
);
794 grub_printf(" level:\r\n");
795 grub_printf(" 01/11: busybox / (+cat log)\r\n");
796 grub_printf(" 02/12: initrd / (+cat log)\r\n");
797 grub_printf(" 03/13: hook / (+cat log)\r\n");
799 grub_printf(" debug:\r\n");
800 grub_printf(" 0: debug is off\r\n");
801 grub_printf(" 1: debug is on\r\n");
803 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
806 g_ventoy_break_level
= (grub_uint8_t
)grub_strtoul(args
[0], NULL
, 16);
808 if (argc
> 1 && grub_strtoul(args
[1], NULL
, 10) > 0)
810 g_ventoy_debug_level
= 1;
813 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
816 static grub_err_t
ventoy_cmd_strstr(grub_extcmd_context_t ctxt
, int argc
, char **args
)
825 return (grub_strstr(args
[0], args
[1])) ? 0 : 1;
828 static grub_err_t
ventoy_cmd_strbegin(grub_extcmd_context_t ctxt
, int argc
, char **args
)
860 static grub_err_t
ventoy_cmd_incr(grub_extcmd_context_t ctxt
, int argc
, char **args
)
865 if ((argc
!= 2) || (!ventoy_is_decimal(args
[1])))
867 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {Variable} {Int}", cmd_raw_name
);
870 if (GRUB_ERR_NONE
!= ventoy_check_decimal_var(args
[0], &value_long
))
875 value_long
+= grub_strtol(args
[1], NULL
, 10);
877 grub_snprintf(buf
, sizeof(buf
), "%ld", value_long
);
878 grub_env_set(args
[0], buf
);
880 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
883 static grub_err_t
ventoy_cmd_mod(grub_extcmd_context_t ctxt
, int argc
, char **args
)
885 ulonglong value1
= 0;
886 ulonglong value2
= 0;
891 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {Int} {Int} {Variable}", cmd_raw_name
);
894 value1
= grub_strtoull(args
[0], NULL
, 10);
895 value2
= grub_strtoull(args
[1], NULL
, 10);
897 grub_snprintf(buf
, sizeof(buf
), "%llu", (value1
& (value2
- 1)));
898 grub_env_set(args
[2], buf
);
900 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
903 static grub_err_t
ventoy_cmd_file_size(grub_extcmd_context_t ctxt
, int argc
, char **args
)
918 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
921 debug("failed to open file <%s> for udf check\n", args
[0]);
925 grub_snprintf(buf
, sizeof(buf
), "%llu", (unsigned long long)file
->size
);
927 grub_env_set(args
[1], buf
);
929 grub_file_close(file
);
935 static grub_err_t
ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
943 g_wimboot_enable
= 0;
944 grub_check_free(g_wimiso_path
);
945 grub_check_free(g_wimiso_chunk_list
.chunk
);
947 file
= grub_file_open(args
[0], VENTOY_FILE_TYPE
);
953 grub_memset(&g_wimiso_chunk_list
, 0, sizeof(g_wimiso_chunk_list
));
954 g_wimiso_chunk_list
.chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
955 if (NULL
== g_wimiso_chunk_list
.chunk
)
957 return grub_error(GRUB_ERR_OUT_OF_MEMORY
, "Can't allocate image chunk memoty\n");
960 g_wimiso_chunk_list
.max_chunk
= DEFAULT_CHUNK_NUM
;
961 g_wimiso_chunk_list
.cur_chunk
= 0;
963 ventoy_get_block_list(file
, &g_wimiso_chunk_list
, file
->device
->disk
->partition
->start
);
965 g_wimboot_enable
= 1;
966 g_wimiso_path
= grub_strdup(args
[0]);
968 grub_file_close(file
);
973 static grub_err_t
ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt
, int argc
, char **args
)
983 ventoy_iso9660_override
*dirent
;
992 totlen
= sizeof(ventoy_chain_head
);
994 if (ventoy_load_efiboot_template(&buf
, &len
, &offset
))
996 debug("failed to load efiboot template %d\n", len
);
1002 debug("efiboot template len:%d offset:%d\n", len
, offset
);
1004 file
= ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD
, "%s", args
[0]);
1007 debug("failed to open file <%s>\n", args
[0]);
1011 totlen
+= ventoy_align_2k(file
->size
);
1013 dirent
= (ventoy_iso9660_override
*)(buf
+ offset
);
1014 dirent
->first_sector
= len
/ 2048;
1015 dirent
->first_sector_be
= grub_swap_bytes32(dirent
->first_sector
);
1016 dirent
->size
= (grub_uint32_t
)file
->size
;
1017 dirent
->size_be
= grub_swap_bytes32(dirent
->size
);
1019 debug("rawiso len:%d efilen:%d total:%d\n", len
, (int)file
->size
, totlen
);
1021 #ifdef GRUB_MACHINE_EFI
1022 data
= (char *)grub_efi_allocate_iso_buf(totlen
);
1024 data
= (char *)grub_malloc(totlen
);
1027 ventoy_fill_os_param(file
, (ventoy_os_param
*)data
);
1029 grub_memcpy(data
+ sizeof(ventoy_chain_head
), buf
, len
);
1030 grub_check_free(buf
);
1032 grub_file_read(file
, data
+ sizeof(ventoy_chain_head
) + len
, file
->size
);
1033 grub_file_close(file
);
1035 grub_snprintf(name
, sizeof(name
), "%s_addr", args
[1]);
1036 grub_snprintf(value
, sizeof(value
), "0x%llx", (ulonglong
)(ulong
)data
);
1037 grub_env_set(name
, value
);
1039 grub_snprintf(name
, sizeof(name
), "%s_size", args
[1]);
1040 grub_snprintf(value
, sizeof(value
), "%d", (int)(totlen
));
1041 grub_env_set(name
, value
);
1046 static grub_err_t
ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1053 enum grub_file_type type
;
1064 if (grub_strcmp(args
[0], "nodecompress") == 0)
1066 type
= VENTOY_FILE_TYPE
;
1070 type
= GRUB_FILE_TYPE_LINUX_INITRD
;
1073 file
= ventoy_grub_file_open(type
, "%s", args
[1]);
1076 debug("failed to open file <%s>\n", args
[1]);
1080 #ifdef GRUB_MACHINE_EFI
1081 buf
= (char *)grub_efi_allocate_chain_buf(file
->size
);
1083 buf
= (char *)grub_malloc(file
->size
);
1088 grub_file_close(file
);
1092 grub_file_read(file
, buf
, file
->size
);
1094 grub_snprintf(name
, sizeof(name
), "%s_addr", args
[2]);
1095 grub_snprintf(value
, sizeof(value
), "0x%llx", (unsigned long long)(unsigned long)buf
);
1096 grub_env_set(name
, value
);
1098 grub_snprintf(name
, sizeof(name
), "%s_size", args
[2]);
1099 grub_snprintf(value
, sizeof(value
), "%llu", (unsigned long long)file
->size
);
1100 grub_env_set(name
, value
);
1102 grub_file_close(file
);
1108 static grub_err_t
ventoy_cmd_load_img_memdisk(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1126 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
1129 debug("failed to open file <%s> for udf check\n", args
[0]);
1133 headlen
= sizeof(ventoy_chain_head
);
1135 #ifdef GRUB_MACHINE_EFI
1136 buf
= (char *)grub_efi_allocate_iso_buf(headlen
+ file
->size
);
1138 buf
= (char *)grub_malloc(headlen
+ file
->size
);
1141 ventoy_fill_os_param(file
, (ventoy_os_param
*)buf
);
1143 grub_file_read(file
, buf
+ headlen
, file
->size
);
1145 grub_snprintf(name
, sizeof(name
), "%s_addr", args
[1]);
1146 grub_snprintf(value
, sizeof(value
), "0x%llx", (unsigned long long)(unsigned long)buf
);
1147 grub_env_set(name
, value
);
1149 grub_snprintf(name
, sizeof(name
), "%s_size", args
[1]);
1150 grub_snprintf(value
, sizeof(value
), "%llu", (unsigned long long)file
->size
);
1151 grub_env_set(name
, value
);
1153 grub_file_close(file
);
1159 static grub_err_t
ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1168 if (args
[0][0] == '1')
1170 grub_iso9660_set_nojoliet(1);
1174 grub_iso9660_set_nojoliet(0);
1180 static grub_err_t
ventoy_cmd_is_udf(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1185 grub_uint8_t buf
[32];
1196 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
1199 debug("failed to open file <%s> for udf check\n", args
[0]);
1203 for (i
= 16; i
< 32; i
++)
1205 grub_file_seek(file
, i
* 2048);
1206 grub_file_read(file
, buf
, sizeof(buf
));
1214 grub_file_seek(file
, i
* 2048);
1215 grub_file_read(file
, buf
, sizeof(buf
));
1217 if (grub_memcmp(buf
+ 1, "BEA01", 5) == 0)
1220 grub_file_seek(file
, i
* 2048);
1221 grub_file_read(file
, buf
, sizeof(buf
));
1223 if (grub_memcmp(buf
+ 1, "NSR02", 5) == 0 ||
1224 grub_memcmp(buf
+ 1, "NSR03", 5) == 0)
1230 grub_file_close(file
);
1232 debug("ISO UDF: %s\n", rc
? "NO" : "YES");
1237 static grub_err_t
ventoy_cmd_cmp(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1239 long value_long1
= 0;
1240 long value_long2
= 0;
1242 if ((argc
!= 3) || (!ventoy_is_decimal(args
[0])) || (!ventoy_is_decimal(args
[2])))
1244 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {Int1} { eq|ne|gt|lt|ge|le } {Int2}", cmd_raw_name
);
1247 value_long1
= grub_strtol(args
[0], NULL
, 10);
1248 value_long2
= grub_strtol(args
[2], NULL
, 10);
1250 if (0 == grub_strcmp(args
[1], "eq"))
1252 grub_errno
= (value_long1
== value_long2
) ? GRUB_ERR_NONE
: GRUB_ERR_TEST_FAILURE
;
1254 else if (0 == grub_strcmp(args
[1], "ne"))
1256 grub_errno
= (value_long1
!= value_long2
) ? GRUB_ERR_NONE
: GRUB_ERR_TEST_FAILURE
;
1258 else if (0 == grub_strcmp(args
[1], "gt"))
1260 grub_errno
= (value_long1
> value_long2
) ? GRUB_ERR_NONE
: GRUB_ERR_TEST_FAILURE
;
1262 else if (0 == grub_strcmp(args
[1], "lt"))
1264 grub_errno
= (value_long1
< value_long2
) ? GRUB_ERR_NONE
: GRUB_ERR_TEST_FAILURE
;
1266 else if (0 == grub_strcmp(args
[1], "ge"))
1268 grub_errno
= (value_long1
>= value_long2
) ? GRUB_ERR_NONE
: GRUB_ERR_TEST_FAILURE
;
1270 else if (0 == grub_strcmp(args
[1], "le"))
1272 grub_errno
= (value_long1
<= value_long2
) ? GRUB_ERR_NONE
: GRUB_ERR_TEST_FAILURE
;
1276 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {Int1} { eq ne gt lt ge le } {Int2}", cmd_raw_name
);
1282 static grub_err_t
ventoy_cmd_device(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1285 char buf
[128] = {0};
1289 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s path var", cmd_raw_name
);
1292 grub_strncpy(buf
, (args
[0][0] == '(') ? args
[0] + 1 : args
[0], sizeof(buf
) - 1);
1293 pos
= grub_strstr(buf
, ",");
1299 grub_env_set(args
[1], buf
);
1301 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1304 static grub_err_t
ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt
, int argc
, char **args
)
1310 const char *files
[] = { "ventoy.dat", "VENTOY.DAT" };
1316 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s (loop)", cmd_raw_name
);
1319 for (i
= 0; i
< (int)ARRAY_SIZE(files
); i
++)
1321 grub_snprintf(buf
, sizeof(buf
) - 1, "[ -e \"%s/%s\" ]", args
[0], files
[i
]);
1322 if (0 == grub_script_execute_sourcecode(buf
))
1324 debug("file %s exist, ventoy_compatible YES\n", buf
);
1325 grub_env_set("ventoy_compatible", "YES");
1326 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1330 debug("file %s NOT exist\n", buf
);
1334 grub_snprintf(buf
, sizeof(buf
) - 1, "%s", args
[0][0] == '(' ? (args
[0] + 1) : args
[0]);
1335 pos
= grub_strstr(buf
, ")");
1341 disk
= grub_disk_open(buf
);
1344 grub_disk_read(disk
, 16 << 2, 0, 1024, g_img_swap_tmp_buf
);
1345 grub_disk_close(disk
);
1347 g_img_swap_tmp_buf
[703] = 0;
1348 for (i
= 318; i
< 703; i
++)
1350 if (g_img_swap_tmp_buf
[i
] == 'V' &&
1351 0 == grub_strncmp(g_img_swap_tmp_buf
+ i
, VENTOY_COMPATIBLE_STR
, VENTOY_COMPATIBLE_STR_LEN
))
1353 debug("Ventoy compatible string exist at %d, ventoy_compatible YES\n", i
);
1354 grub_env_set("ventoy_compatible", "YES");
1355 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1361 debug("failed to open disk <%s>\n", buf
);
1364 grub_env_set("ventoy_compatible", "NO");
1365 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
1368 int ventoy_cmp_img(img_info
*img1
, img_info
*img2
)
1374 if (g_plugin_image_list
== VENTOY_IMG_WHITE_LIST
)
1376 return (img1
->plugin_list_index
- img2
->plugin_list_index
);
1379 for (s1
= img1
->name
, s2
= img2
->name
; *s1
&& *s2
; s1
++, s2
++)
1384 if (0 == g_sort_case_sensitive
)
1386 if (grub_islower(c1
))
1388 c1
= c1
- 'a' + 'A';
1391 if (grub_islower(c2
))
1393 c2
= c2
- 'a' + 'A';
1406 static int ventoy_cmp_subdir(img_iterator_node
*node1
, img_iterator_node
*node2
)
1412 if (g_plugin_image_list
== VENTOY_IMG_WHITE_LIST
)
1414 return (node1
->plugin_list_index
- node2
->plugin_list_index
);
1417 for (s1
= node1
->dir
, s2
= node2
->dir
; *s1
&& *s2
; s1
++, s2
++)
1422 if (0 == g_sort_case_sensitive
)
1424 if (grub_islower(c1
))
1426 c1
= c1
- 'a' + 'A';
1429 if (grub_islower(c2
))
1431 c2
= c2
- 'a' + 'A';
1444 void ventoy_swap_img(img_info
*img1
, img_info
*img2
)
1446 grub_memcpy(&g_img_swap_tmp
, img1
, sizeof(img_info
));
1448 grub_memcpy(img1
, img2
, sizeof(img_info
));
1449 img1
->next
= g_img_swap_tmp
.next
;
1450 img1
->prev
= g_img_swap_tmp
.prev
;
1452 g_img_swap_tmp
.next
= img2
->next
;
1453 g_img_swap_tmp
.prev
= img2
->prev
;
1454 grub_memcpy(img2
, &g_img_swap_tmp
, sizeof(img_info
));
1457 static int ventoy_img_name_valid(const char *filename
, grub_size_t namelen
)
1461 if (g_filt_dot_underscore_file
&& filename
[0] == '.' && filename
[1] == '_')
1469 static int ventoy_collect_img_files(const char *filename
, const struct grub_dirhook_info
*info
, void *data
)
1478 img_iterator_node
*tmp
;
1479 img_iterator_node
*new_node
;
1480 img_iterator_node
*node
= (img_iterator_node
*)data
;
1482 if (g_enumerate_time_checked
== 0)
1484 g_enumerate_finish_time_ms
= grub_get_time_ms();
1485 if ((g_enumerate_finish_time_ms
- g_enumerate_start_time_ms
) >= 3000)
1488 grub_printf("\n\n Ventoy scanning files, please wait...\n");
1490 g_enumerate_time_checked
= 1;
1494 len
= grub_strlen(filename
);
1498 if (node
->level
+ 1 > g_img_max_search_level
)
1503 if ((len
== 1 && filename
[0] == '.') ||
1504 (len
== 2 && filename
[0] == '.' && filename
[1] == '.'))
1509 if (!ventoy_img_name_valid(filename
, len
))
1514 if (filename
[0] == '$' && 0 == grub_strncmp(filename
, "$RECYCLE.BIN", 12))
1519 if (g_plugin_image_list
== VENTOY_IMG_WHITE_LIST
)
1521 grub_snprintf(g_img_swap_tmp_buf
, sizeof(g_img_swap_tmp_buf
), "%s%s/", node
->dir
, filename
);
1522 index
= ventoy_plugin_get_image_list_index(vtoy_class_directory
, g_img_swap_tmp_buf
);
1525 debug("Directory %s not found in image_list plugin config...\n", g_img_swap_tmp_buf
);
1530 new_node
= grub_zalloc(sizeof(img_iterator_node
));
1533 new_node
->level
= node
->level
+ 1;
1534 new_node
->plugin_list_index
= index
;
1535 new_node
->dirlen
= grub_snprintf(new_node
->dir
, sizeof(new_node
->dir
), "%s%s/", node
->dir
, filename
);
1537 g_enum_fs
->fs_dir(g_enum_dev
, new_node
->dir
, ventoy_check_ignore_flag
, &ignore
);
1540 debug("Directory %s ignored...\n", new_node
->dir
);
1541 grub_free(new_node
);
1545 new_node
->tail
= node
->tail
;
1547 new_node
->parent
= node
;
1548 if (!node
->firstchild
)
1550 node
->firstchild
= new_node
;
1553 if (g_img_iterator_tail
)
1555 g_img_iterator_tail
->next
= new_node
;
1556 g_img_iterator_tail
= new_node
;
1560 g_img_iterator_head
.next
= new_node
;
1561 g_img_iterator_tail
= new_node
;
1567 debug("Find a file %s\n", filename
);
1573 if (FILE_FLT(ISO
) && 0 == grub_strcasecmp(filename
+ len
- 4, ".iso"))
1575 type
= img_type_iso
;
1577 else if (FILE_FLT(WIM
) && g_wimboot_enable
&& (0 == grub_strcasecmp(filename
+ len
- 4, ".wim")))
1579 type
= img_type_wim
;
1581 else if (FILE_FLT(VHD
) && g_vhdboot_enable
&& (0 == grub_strcasecmp(filename
+ len
- 4, ".vhd") ||
1582 (len
>= 5 && 0 == grub_strcasecmp(filename
+ len
- 5, ".vhdx"))))
1584 type
= img_type_vhd
;
1586 #ifdef GRUB_MACHINE_EFI
1587 else if (FILE_FLT(EFI
) && 0 == grub_strcasecmp(filename
+ len
- 4, ".efi"))
1589 type
= img_type_efi
;
1592 else if (FILE_FLT(IMG
) && 0 == grub_strcasecmp(filename
+ len
- 4, ".img"))
1594 if (len
== 18 && grub_strncmp(filename
, "ventoy_", 7) == 0)
1596 if (grub_strncmp(filename
+ 7, "wimboot", 7) == 0 ||
1597 grub_strncmp(filename
+ 7, "vhdboot", 7) == 0)
1602 type
= img_type_img
;
1604 else if (FILE_FLT(VTOY
) && len
>= 5 && 0 == grub_strcasecmp(filename
+ len
- 5, ".vtoy"))
1606 type
= img_type_vtoy
;
1608 else if (len
>= 9 && 0 == grub_strcasecmp(filename
+ len
- 5, ".vcfg"))
1610 if (filename
[len
- 9] == '.' || (len
>= 10 && filename
[len
- 10] == '.'))
1612 grub_snprintf(g_img_swap_tmp_buf
, sizeof(g_img_swap_tmp_buf
), "%s%s", node
->dir
, filename
);
1613 ventoy_plugin_add_custom_boot(g_img_swap_tmp_buf
);
1622 if (g_filt_dot_underscore_file
&& filename
[0] == '.' && filename
[1] == '_')
1627 if (g_plugin_image_list
)
1629 grub_snprintf(g_img_swap_tmp_buf
, sizeof(g_img_swap_tmp_buf
), "%s%s", node
->dir
, filename
);
1630 index
= ventoy_plugin_get_image_list_index(vtoy_class_image_file
, g_img_swap_tmp_buf
);
1631 if (VENTOY_IMG_WHITE_LIST
== g_plugin_image_list
&& index
== 0)
1633 debug("File %s not found in image_list plugin config...\n", g_img_swap_tmp_buf
);
1636 else if (VENTOY_IMG_BLACK_LIST
== g_plugin_image_list
&& index
> 0)
1638 debug("File %s found in image_blacklist plugin config %d ...\n", g_img_swap_tmp_buf
, index
);
1643 img
= grub_zalloc(sizeof(img_info
));
1647 img
->plugin_list_index
= index
;
1648 grub_snprintf(img
->name
, sizeof(img
->name
), "%s", filename
);
1650 img
->pathlen
= grub_snprintf(img
->path
, sizeof(img
->path
), "%s%s", node
->dir
, img
->name
);
1652 img
->size
= info
->size
;
1655 img
->size
= ventoy_grub_get_file_size("%s/%s%s", g_iso_path
, node
->dir
, filename
);
1658 if (img
->size
< VTOY_FILT_MIN_FILE_SIZE
)
1660 debug("img <%s> size too small %llu\n", img
->name
, (ulonglong
)img
->size
);
1665 if (g_ventoy_img_list
)
1667 tail
= *(node
->tail
);
1673 g_ventoy_img_list
= img
;
1676 img
->id
= g_ventoy_img_count
;
1678 if (node
&& NULL
== node
->firstiso
)
1680 node
->firstiso
= img
;
1691 *((img_info
**)(node
->tail
)) = img
;
1692 g_ventoy_img_count
++;
1694 img
->alias
= ventoy_plugin_get_menu_alias(vtoy_alias_image_file
, img
->path
);
1695 img
->class = ventoy_plugin_get_menu_class(vtoy_class_image_file
, img
->name
, img
->path
);
1698 img
->class = g_menu_class
[type
];
1700 img
->menu_prefix
= g_menu_prefix
[type
];
1702 if (img_type_iso
== type
)
1704 if (ventoy_plugin_check_memdisk(img
->path
))
1706 img
->menu_prefix
= "miso";
1710 debug("Add %s%s to list %d\n", node
->dir
, filename
, g_ventoy_img_count
);
1717 int ventoy_fill_data(grub_uint32_t buflen
, char *buffer
)
1719 int len
= GRUB_UINT_MAX
;
1720 const char *value
= NULL
;
1721 char name
[32] = {0};
1722 char plat
[32] = {0};
1723 char guidstr
[32] = {0};
1724 ventoy_guid guid
= VENTOY_GUID
;
1725 const char *fmt1
= NULL
;
1726 const char *fmt2
= NULL
;
1727 const char *fmt3
= NULL
;
1728 grub_uint32_t
*puint
= (grub_uint32_t
*)name
;
1729 grub_uint32_t
*puint2
= (grub_uint32_t
*)plat
;
1730 const char fmtdata
[]={ 0x39, 0x35, 0x25, 0x00, 0x35, 0x00, 0x23, 0x30, 0x30, 0x30, 0x30, 0x66, 0x66, 0x00 };
1731 const char fmtcode
[]={
1732 0x22, 0x0A, 0x2B, 0x20, 0x68, 0x62, 0x6F, 0x78, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x74, 0x6F, 0x70,
1733 0x20, 0x3D, 0x20, 0x25, 0x73, 0x0A, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x3D, 0x20, 0x25,
1734 0x73, 0x0A, 0x20, 0x20, 0x2B, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x74, 0x65, 0x78,
1735 0x74, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x20, 0x25, 0x73, 0x25, 0x73, 0x22, 0x20, 0x63, 0x6F,
1736 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x22, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E,
1737 0x20, 0x3D, 0x20, 0x22, 0x6C, 0x65, 0x66, 0x74, 0x22, 0x7D, 0x0A, 0x7D, 0x0A, 0x22, 0x00
1740 grub_memset(name
, 0, sizeof(name
));
1741 puint
[0] = grub_swap_bytes32(0x56454e54);
1742 puint
[3] = grub_swap_bytes32(0x4f4e0000);
1743 puint
[2] = grub_swap_bytes32(0x45525349);
1744 puint
[1] = grub_swap_bytes32(0x4f595f56);
1745 value
= ventoy_get_env(name
);
1747 grub_memset(name
, 0, sizeof(name
));
1748 puint
[1] = grub_swap_bytes32(0x5f544f50);
1749 puint
[0] = grub_swap_bytes32(0x56544c45);
1750 fmt1
= ventoy_get_env(name
);
1756 grub_memset(name
, 0, sizeof(name
));
1757 puint
[1] = grub_swap_bytes32(0x5f4c4654);
1758 puint
[0] = grub_swap_bytes32(0x56544c45);
1759 fmt2
= ventoy_get_env(name
);
1761 grub_memset(name
, 0, sizeof(name
));
1762 puint
[1] = grub_swap_bytes32(0x5f434c52);
1763 puint
[0] = grub_swap_bytes32(0x56544c45);
1764 fmt3
= ventoy_get_env(name
);
1766 grub_memcpy(guidstr
, &guid
, sizeof(guid
));
1768 puint2
[0] = grub_swap_bytes32(g_ventoy_plat_data
);
1770 /* Easter egg :) It will be appreciated if you reserve it, but NOT mandatory. */
1771 #pragma GCC diagnostic push
1772 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1773 len
= grub_snprintf(buffer
, buflen
, fmtcode
,
1774 fmt1
? fmt1
: fmtdata
,
1775 fmt2
? fmt2
: fmtdata
+ 4,
1776 value
? value
: "", plat
, guidstr
,
1777 fmt3
? fmt3
: fmtdata
+ 6);
1778 #pragma GCC diagnostic pop
1780 grub_memset(name
, 0, sizeof(name
));
1781 puint
[0] = grub_swap_bytes32(0x76746f79);
1782 puint
[2] = grub_swap_bytes32(0x656e7365);
1783 puint
[1] = grub_swap_bytes32(0x5f6c6963);
1784 ventoy_set_env(name
, guidstr
);
1789 int ventoy_check_password(const vtoy_password
*pwd
, int retry
)
1793 grub_uint8_t md5
[16];
1797 grub_memset(input
, 0, sizeof(input
));
1799 grub_printf("Enter password: ");
1802 if (pwd
->type
== VTOY_PASSWORD_TXT
)
1804 grub_password_get(input
, 128);
1805 if (grub_strcmp(pwd
->text
, input
) == 0)
1810 else if (pwd
->type
== VTOY_PASSWORD_MD5
)
1812 grub_password_get(input
, 128);
1813 grub_crypto_hash(GRUB_MD_MD5
, md5
, input
, grub_strlen(input
));
1814 if (grub_memcmp(pwd
->md5
, md5
, 16) == 0)
1819 else if (pwd
->type
== VTOY_PASSWORD_SALT_MD5
)
1821 offset
= (int)grub_snprintf(input
, 128, "%s", pwd
->salt
);
1822 grub_password_get(input
+ offset
, 128);
1824 grub_crypto_hash(GRUB_MD_MD5
, md5
, input
, grub_strlen(input
));
1825 if (grub_memcmp(pwd
->md5
, md5
, 16) == 0)
1831 grub_printf("Invalid password!\n\n");
1838 static img_info
* ventoy_get_min_iso(img_iterator_node
*node
)
1840 img_info
*minimg
= NULL
;
1841 img_info
*img
= (img_info
*)(node
->firstiso
);
1843 while (img
&& (img_iterator_node
*)(img
->parent
) == node
)
1845 if (img
->select
== 0 && (NULL
== minimg
|| ventoy_cmp_img(img
, minimg
) < 0))
1860 static img_iterator_node
* ventoy_get_min_child(img_iterator_node
*node
)
1862 img_iterator_node
*Minchild
= NULL
;
1863 img_iterator_node
*child
= node
->firstchild
;
1865 while (child
&& child
->parent
== node
)
1867 if (child
->select
== 0 && (NULL
== Minchild
|| ventoy_cmp_subdir(child
, Minchild
) < 0))
1871 child
= child
->next
;
1876 Minchild
->select
= 1;
1882 static int ventoy_dynamic_tree_menu(img_iterator_node
*node
)
1885 img_info
*img
= NULL
;
1886 const char *dir_class
= NULL
;
1887 const char *dir_alias
= NULL
;
1888 img_iterator_node
*child
= NULL
;
1890 if (node
->isocnt
== 0 || node
->done
== 1)
1895 if (node
->parent
&& node
->parent
->dirlen
< node
->dirlen
)
1897 offset
= node
->parent
->dirlen
;
1900 if (node
== &g_img_iterator_head
)
1902 if (g_default_menu_mode
== 0)
1904 if (g_tree_view_menu_style
== 0)
1906 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1907 "menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
1908 " echo 'return ...' \n"
1913 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1914 "menuentry \"[Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
1922 node
->dir
[node
->dirlen
- 1] = 0;
1923 dir_class
= ventoy_plugin_get_menu_class(vtoy_class_directory
, node
->dir
, node
->dir
);
1926 dir_class
= "vtoydir";
1929 dir_alias
= ventoy_plugin_get_menu_alias(vtoy_alias_directory
, node
->dir
);
1932 if (g_tree_view_menu_style
== 0)
1934 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1935 "submenu \"%-10s %s\" --class=\"%s\" --id=\"DIR_%s\" {\n",
1936 "DIR", dir_alias
, dir_class
, node
->dir
+ offset
);
1940 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1941 "submenu \"%s\" --class=\"%s\" --id=\"DIR_%s\" {\n",
1942 dir_alias
, dir_class
, node
->dir
+ offset
);
1947 dir_alias
= node
->dir
+ offset
;
1949 if (g_tree_view_menu_style
== 0)
1951 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1952 "submenu \"%-10s [%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n",
1953 "DIR", dir_alias
, dir_class
, node
->dir
+ offset
);
1957 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1958 "submenu \"[%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n",
1959 dir_alias
, dir_class
, node
->dir
+ offset
);
1963 if (g_tree_view_menu_style
== 0)
1965 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1966 "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n "
1967 " echo 'return ...' \n"
1972 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1973 "menuentry \"[../]\" --class=\"vtoyret\" VTOY_RET {\n "
1979 while ((child
= ventoy_get_min_child(node
)) != NULL
)
1981 ventoy_dynamic_tree_menu(child
);
1984 while ((img
= ventoy_get_min_iso(node
)) != NULL
)
1986 if (g_tree_view_menu_style
== 0)
1988 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
1989 "menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
1992 grub_get_human_size(img
->size
, GRUB_HUMAN_SIZE_SHORT
),
1993 img
->unsupport
? "[***********] " : "",
1994 img
->alias
? img
->alias
: img
->name
, img
->class, img
->id
,
1996 img
->unsupport
? "unsupport_menuentry" : "common_menuentry");
2000 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
,
2001 "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
2004 img
->unsupport
? "[***********] " : "",
2005 img
->alias
? img
->alias
: img
->name
, img
->class, img
->id
,
2007 img
->unsupport
? "unsupport_menuentry" : "common_menuentry");
2011 if (node
!= &g_img_iterator_head
)
2013 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
, "%s", "}\n");
2020 static int ventoy_set_default_menu(void)
2026 const char *strdata
= NULL
;
2027 img_info
*cur
= NULL
;
2028 img_info
*default_node
= NULL
;
2029 const char *default_image
= NULL
;
2031 default_image
= ventoy_get_env("VTOY_DEFAULT_IMAGE");
2032 if (default_image
&& default_image
[0] == '/')
2034 img_len
= grub_strlen(default_image
);
2036 for (cur
= g_ventoy_img_list
; cur
; cur
= cur
->next
)
2038 if (img_len
== cur
->pathlen
&& grub_strcmp(default_image
, cur
->path
) == 0)
2050 if (0 == g_default_menu_mode
)
2052 vtoy_ssprintf(g_list_script_buf
, g_list_script_pos
, "set default='VID_%d'\n", default_node
->id
);
2056 def
= grub_strdup(default_image
);
2062 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
, "set default=%c", '\'');
2064 strdata
= ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT");
2065 if (strdata
&& strdata
[0] == '/')
2067 pos
= def
+ grub_strlen(strdata
);
2078 while ((end
= grub_strchr(pos
, '/')) != NULL
)
2081 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
, "DIR_%s>", pos
);
2085 vtoy_ssprintf(g_tree_script_buf
, g_tree_script_pos
, "VID_%d'\n", default_node
->id
);
2093 static grub_err_t
ventoy_cmd_clear_img(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2095 img_info
*next
= NULL
;
2096 img_info
*cur
= g_ventoy_img_list
;
2109 g_ventoy_img_list
= NULL
;
2110 g_ventoy_img_count
= 0;
2112 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2115 static grub_err_t
ventoy_cmd_img_name(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2118 img_info
*cur
= g_ventoy_img_list
;
2122 if (argc
!= 2 || (!ventoy_is_decimal(args
[0])))
2124 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {imageID} {var}", cmd_raw_name
);
2127 img_id
= grub_strtol(args
[0], NULL
, 10);
2128 if (img_id
>= g_ventoy_img_count
)
2130 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "No such many images %ld %ld", img_id
, g_ventoy_img_count
);
2133 debug("Find image %ld name \n", img_id
);
2135 while (cur
&& img_id
> 0)
2143 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "No such many images");
2146 debug("image name is %s\n", cur
->name
);
2148 grub_env_set(args
[1], cur
->name
);
2150 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2153 static grub_err_t
ventoy_cmd_ext_select_img_path(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2157 img_info
*cur
= g_ventoy_img_list
;
2163 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {var}", cmd_raw_name
);
2166 len
= (int)grub_strlen(args
[0]);
2170 if (len
== cur
->pathlen
&& 0 == grub_strcmp(args
[0], cur
->path
))
2179 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "No such image");
2182 grub_snprintf(id
, sizeof(id
), "VID_%d", cur
->id
);
2183 grub_env_set("chosen", id
);
2184 grub_env_export("chosen");
2186 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2189 static grub_err_t
ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2194 const char *id
= NULL
;
2195 img_info
*cur
= g_ventoy_img_list
;
2199 if (argc
< 1 || argc
> 2)
2201 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {var}", cmd_raw_name
);
2204 id
= grub_env_get("chosen");
2206 pos
= grub_strstr(id
, "VID_");
2209 img_id
= (int)grub_strtoul(pos
+ 4, NULL
, 10);
2213 img_id
= (int)grub_strtoul(id
, NULL
, 10);
2218 if (img_id
== cur
->id
)
2227 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "No such image");
2230 grub_env_set(args
[0], cur
->path
);
2234 grub_snprintf(value
, sizeof(value
), "%llu", (ulonglong
)(cur
->size
));
2235 grub_env_set(args
[1], value
);
2238 g_svd_replace_offset
= 0;
2240 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2244 static grub_err_t
ventoy_cmd_list_img(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2248 grub_device_t dev
= NULL
;
2249 img_info
*cur
= NULL
;
2250 img_info
*tail
= NULL
;
2251 const char *strdata
= NULL
;
2252 char *device_name
= NULL
;
2254 img_iterator_node
*node
= NULL
;
2255 img_iterator_node
*tmp
= NULL
;
2261 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s {device} {cntvar}", cmd_raw_name
);
2264 if (g_ventoy_img_list
|| g_ventoy_img_count
)
2266 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Must clear image before list");
2271 g_enumerate_time_checked
= 0;
2272 g_enumerate_start_time_ms
= grub_get_time_ms();
2274 strdata
= ventoy_get_env("VTOY_FILT_DOT_UNDERSCORE_FILE");
2275 if (strdata
&& strdata
[0] == '1' && strdata
[1] == 0)
2277 g_filt_dot_underscore_file
= 1;
2280 strdata
= ventoy_get_env("VTOY_SORT_CASE_SENSITIVE");
2281 if (strdata
&& strdata
[0] == '1' && strdata
[1] == 0)
2283 g_sort_case_sensitive
= 1;
2286 device_name
= grub_file_get_device_name(args
[0]);
2292 g_enum_dev
= dev
= grub_device_open(device_name
);
2298 g_enum_fs
= fs
= grub_fs_probe(dev
);
2304 if (ventoy_get_fs_type(fs
->name
) >= ventoy_fs_max
)
2306 debug("unsupported fs:<%s>\n", fs
->name
);
2307 ventoy_set_env("VTOY_NO_ISO_TIP", "unsupported file system");
2311 ventoy_set_env("vtoy_iso_fs", fs
->name
);
2313 strdata
= ventoy_get_env("VTOY_DEFAULT_MENU_MODE");
2314 if (strdata
&& strdata
[0] == '1')
2316 g_default_menu_mode
= 1;
2319 grub_memset(&g_img_iterator_head
, 0, sizeof(g_img_iterator_head
));
2321 grub_snprintf(g_iso_path
, sizeof(g_iso_path
), "%s", args
[0]);
2323 strdata
= ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT");
2324 if (strdata
&& strdata
[0] == '/')
2326 len
= grub_snprintf(g_img_iterator_head
.dir
, sizeof(g_img_iterator_head
.dir
) - 1, "%s", strdata
);
2327 if (g_img_iterator_head
.dir
[len
- 1] != '/')
2329 g_img_iterator_head
.dir
[len
++] = '/';
2331 g_img_iterator_head
.dirlen
= len
;
2335 g_img_iterator_head
.dirlen
= 1;
2336 grub_strcpy(g_img_iterator_head
.dir
, "/");
2339 g_img_iterator_head
.tail
= &tail
;
2341 if (g_img_max_search_level
< 0)
2343 g_img_max_search_level
= GRUB_INT_MAX
;
2344 strdata
= ventoy_get_env("VTOY_MAX_SEARCH_LEVEL");
2345 if (strdata
&& ventoy_is_decimal(strdata
))
2347 g_img_max_search_level
= (int)grub_strtoul(strdata
, NULL
, 10);
2351 g_vtoy_file_flt
[VTOY_FILE_FLT_ISO
] = ventoy_control_get_flag("VTOY_FILE_FLT_ISO");
2352 g_vtoy_file_flt
[VTOY_FILE_FLT_WIM
] = ventoy_control_get_flag("VTOY_FILE_FLT_WIM");
2353 g_vtoy_file_flt
[VTOY_FILE_FLT_EFI
] = ventoy_control_get_flag("VTOY_FILE_FLT_EFI");
2354 g_vtoy_file_flt
[VTOY_FILE_FLT_IMG
] = ventoy_control_get_flag("VTOY_FILE_FLT_IMG");
2355 g_vtoy_file_flt
[VTOY_FILE_FLT_VHD
] = ventoy_control_get_flag("VTOY_FILE_FLT_VHD");
2356 g_vtoy_file_flt
[VTOY_FILE_FLT_VTOY
] = ventoy_control_get_flag("VTOY_FILE_FLT_VTOY");
2358 for (node
= &g_img_iterator_head
; node
; node
= node
->next
)
2360 fs
->fs_dir(dev
, node
->dir
, ventoy_collect_img_files
, node
);
2363 strdata
= ventoy_get_env("VTOY_TREE_VIEW_MENU_STYLE");
2364 if (strdata
&& strdata
[0] == '1' && strdata
[1] == 0)
2366 g_tree_view_menu_style
= 1;
2369 ventoy_set_default_menu();
2371 for (node
= &g_img_iterator_head
; node
; node
= node
->next
)
2373 ventoy_dynamic_tree_menu(node
);
2377 node
= g_img_iterator_head
.next
;
2385 /* sort image list by image name */
2386 for (cur
= g_ventoy_img_list
; cur
; cur
= cur
->next
)
2388 for (tail
= cur
->next
; tail
; tail
= tail
->next
)
2390 if (ventoy_cmp_img(cur
, tail
) > 0)
2392 ventoy_swap_img(cur
, tail
);
2397 if (g_default_menu_mode
== 1)
2399 vtoy_ssprintf(g_list_script_buf
, g_list_script_pos
,
2400 "menuentry \"%s [Return to TreeView]\" --class=\"vtoyret\" VTOY_RET {\n "
2401 " echo 'return ...' \n"
2405 for (cur
= g_ventoy_img_list
; cur
; cur
= cur
->next
)
2407 vtoy_ssprintf(g_list_script_buf
, g_list_script_pos
,
2408 "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
2411 cur
->unsupport
? "[***********] " : "",
2412 cur
->alias
? cur
->alias
: cur
->name
, cur
->class, cur
->id
,
2414 cur
->unsupport
? "unsupport_menuentry" : "common_menuentry");
2417 g_tree_script_buf
[g_tree_script_pos
] = 0;
2418 g_list_script_buf
[g_list_script_pos
] = 0;
2420 grub_snprintf(buf
, sizeof(buf
), "%d", g_ventoy_img_count
);
2421 grub_env_set(args
[1], buf
);
2425 check_free(device_name
, grub_free
);
2426 check_free(dev
, grub_device_close
);
2428 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2431 int ventoy_get_disk_guid(const char *filename
, grub_uint8_t
*guid
, grub_uint8_t
*signature
)
2438 device_name
= grub_file_get_device_name(filename
);
2450 pos2
= grub_strstr(pos
, ",");
2453 pos2
= grub_strstr(pos
, ")");
2461 disk
= grub_disk_open(pos
);
2464 grub_disk_read(disk
, 0, 0x180, 16, guid
);
2465 grub_disk_read(disk
, 0, 0x1b8, 4, signature
);
2466 grub_disk_close(disk
);
2473 grub_free(device_name
);
2477 grub_uint32_t
ventoy_get_iso_boot_catlog(grub_file_t file
)
2479 eltorito_descriptor desc
;
2481 grub_memset(&desc
, 0, sizeof(desc
));
2482 grub_file_seek(file
, 17 * 2048);
2483 grub_file_read(file
, &desc
, sizeof(desc
));
2485 if (desc
.type
!= 0 || desc
.version
!= 1)
2490 if (grub_strncmp((char *)desc
.id
, "CD001", 5) != 0 ||
2491 grub_strncmp((char *)desc
.system_id
, "EL TORITO SPECIFICATION", 23) != 0)
2499 int ventoy_has_efi_eltorito(grub_file_t file
, grub_uint32_t sector
)
2503 grub_uint8_t buf
[512];
2504 grub_uint8_t parttype
[] = { 0x04, 0x06, 0x0B, 0x0C };
2506 grub_file_seek(file
, sector
* 2048);
2507 grub_file_read(file
, buf
, sizeof(buf
));
2509 if (buf
[0] == 0x01 && buf
[1] == 0xEF)
2511 debug("%s efi eltorito in Validation Entry\n", file
->name
);
2515 if (buf
[0] == 0x01 && buf
[1] == 0x00)
2520 for (i
= 64; i
< (int)sizeof(buf
); i
+= 32)
2522 if ((buf
[i
] == 0x90 || buf
[i
] == 0x91) && buf
[i
+ 1] == 0xEF)
2524 debug("%s efi eltorito offset %d 0x%02x\n", file
->name
, i
, buf
[i
]);
2528 if ((buf
[i
] == 0x90 || buf
[i
] == 0x91) && buf
[i
+ 1] == 0x00 && x86count
== 1)
2530 debug("0x9100 assume %s efi eltorito offset %d 0x%02x\n", file
->name
, i
, buf
[i
]);
2535 if (x86count
&& buf
[32] == 0x88 && buf
[33] == 0x04)
2537 for (i
= 0; i
< (int)(ARRAY_SIZE(parttype
)); i
++)
2539 if (buf
[36] == parttype
[i
])
2541 debug("hard disk image assume %s efi eltorito, part type 0x%x\n", file
->name
, buf
[36]);
2547 debug("%s does not contain efi eltorito\n", file
->name
);
2551 void ventoy_fill_os_param(grub_file_t file
, ventoy_os_param
*param
)
2554 const char *fs
= NULL
;
2555 const char *cdprompt
= NULL
;
2557 grub_uint8_t chksum
= 0;
2560 disk
= file
->device
->disk
;
2561 grub_memcpy(¶m
->guid
, &g_ventoy_guid
, sizeof(ventoy_guid
));
2563 param
->vtoy_disk_size
= disk
->total_sectors
* (1 << disk
->log_sector_size
);
2564 param
->vtoy_disk_part_id
= disk
->partition
->number
+ 1;
2565 param
->vtoy_disk_part_type
= ventoy_get_fs_type(file
->fs
->name
);
2567 pos
= grub_strstr(file
->name
, "/");
2573 grub_snprintf(param
->vtoy_img_path
, sizeof(param
->vtoy_img_path
), "%s", pos
);
2575 ventoy_get_disk_guid(file
->name
, param
->vtoy_disk_guid
, param
->vtoy_disk_signature
);
2577 param
->vtoy_img_size
= file
->size
;
2579 param
->vtoy_reserved
[0] = g_ventoy_break_level
;
2580 param
->vtoy_reserved
[1] = g_ventoy_debug_level
;
2582 param
->vtoy_reserved
[2] = g_ventoy_chain_type
;
2584 /* Windows CD/DVD prompt 0:suppress 1:reserved */
2585 param
->vtoy_reserved
[4] = 0;
2586 if (g_ventoy_chain_type
== 1) /* Windows */
2588 cdprompt
= ventoy_get_env("VTOY_WINDOWS_CD_PROMPT");
2589 if (cdprompt
&& cdprompt
[0] == '1' && cdprompt
[1] == 0)
2591 param
->vtoy_reserved
[4] = 1;
2595 fs
= ventoy_get_env("ventoy_fs_probe");
2596 if (fs
&& grub_strcmp(fs
, "udf") == 0)
2598 param
->vtoy_reserved
[3] = 1;
2601 /* calculate checksum */
2602 for (i
= 0; i
< sizeof(ventoy_os_param
); i
++)
2604 chksum
+= *((grub_uint8_t
*)param
+ i
);
2606 param
->chksum
= (grub_uint8_t
)(0x100 - chksum
);
2611 int ventoy_check_block_list(grub_file_t file
, ventoy_img_chunk_list
*chunklist
, grub_disk_addr_t start
)
2613 grub_uint32_t i
= 0;
2614 grub_uint64_t total
= 0;
2615 grub_uint64_t fileblk
= 0;
2616 ventoy_img_chunk
*chunk
= NULL
;
2618 for (i
= 0; i
< chunklist
->cur_chunk
; i
++)
2620 chunk
= chunklist
->chunk
+ i
;
2622 if (chunk
->disk_start_sector
<= start
)
2624 debug("%u disk start invalid %lu\n", i
, (ulong
)start
);
2628 total
+= chunk
->disk_end_sector
+ 1 - chunk
->disk_start_sector
;
2631 fileblk
= (file
->size
+ 511) / 512;
2633 if (total
!= fileblk
)
2635 debug("Invalid total: %llu %llu\n", (ulonglong
)total
, (ulonglong
)fileblk
);
2636 if ((file
->size
% 512) && (total
+ 1 == fileblk
))
2638 debug("maybe img file to be processed.\n");
2648 int ventoy_get_block_list(grub_file_t file
, ventoy_img_chunk_list
*chunklist
, grub_disk_addr_t start
)
2652 grub_uint32_t i
= 0;
2653 grub_uint32_t sector
= 0;
2654 grub_uint32_t count
= 0;
2655 grub_off_t size
= 0;
2656 grub_off_t read
= 0;
2658 fs_type
= ventoy_get_fs_type(file
->fs
->name
);
2659 if (fs_type
== ventoy_fs_exfat
)
2661 grub_fat_get_file_chunk(start
, file
, chunklist
);
2663 else if (fs_type
== ventoy_fs_ext
)
2665 grub_ext_get_file_chunk(start
, file
, chunklist
);
2669 file
->read_hook
= (grub_disk_read_hook_t
)grub_disk_blocklist_read
;
2670 file
->read_hook_data
= chunklist
;
2672 for (size
= file
->size
; size
> 0; size
-= read
)
2674 read
= (size
> VTOY_SIZE_1GB
) ? VTOY_SIZE_1GB
: size
;
2675 grub_file_read(file
, NULL
, read
);
2678 for (i
= 0; start
> 0 && i
< chunklist
->cur_chunk
; i
++)
2680 chunklist
->chunk
[i
].disk_start_sector
+= start
;
2681 chunklist
->chunk
[i
].disk_end_sector
+= start
;
2684 if (ventoy_fs_udf
== fs_type
)
2686 for (i
= 0; i
< chunklist
->cur_chunk
; i
++)
2688 count
= (chunklist
->chunk
[i
].disk_end_sector
+ 1 - chunklist
->chunk
[i
].disk_start_sector
) >> 2;
2689 chunklist
->chunk
[i
].img_start_sector
= sector
;
2690 chunklist
->chunk
[i
].img_end_sector
= sector
+ count
- 1;
2696 len
= (int)grub_strlen(file
->name
);
2697 if ((len
> 4 && grub_strncasecmp(file
->name
+ len
- 4, ".img", 4) == 0) ||
2698 (len
> 4 && grub_strncasecmp(file
->name
+ len
- 4, ".vhd", 4) == 0) ||
2699 (len
> 5 && grub_strncasecmp(file
->name
+ len
- 5, ".vhdx", 5) == 0) ||
2700 (len
> 5 && grub_strncasecmp(file
->name
+ len
- 5, ".vtoy", 5) == 0))
2702 for (i
= 0; i
< chunklist
->cur_chunk
; i
++)
2704 count
= chunklist
->chunk
[i
].disk_end_sector
+ 1 - chunklist
->chunk
[i
].disk_start_sector
;
2714 chunklist
->chunk
[i
].img_start_sector
= sector
;
2715 chunklist
->chunk
[i
].img_end_sector
= sector
+ count
- 1;
2723 static grub_err_t
ventoy_cmd_img_sector(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2727 grub_disk_addr_t start
;
2732 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
2735 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Can't open file %s\n", args
[0]);
2738 g_conf_replace_node
= NULL
;
2739 g_conf_replace_offset
= 0;
2741 if (g_img_chunk_list
.chunk
)
2743 grub_free(g_img_chunk_list
.chunk
);
2746 if (ventoy_get_fs_type(file
->fs
->name
) >= ventoy_fs_max
)
2748 grub_file_close(file
);
2749 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Unsupported filesystem %s\n", file
->fs
->name
);
2752 /* get image chunk data */
2753 grub_memset(&g_img_chunk_list
, 0, sizeof(g_img_chunk_list
));
2754 g_img_chunk_list
.chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
2755 if (NULL
== g_img_chunk_list
.chunk
)
2757 return grub_error(GRUB_ERR_OUT_OF_MEMORY
, "Can't allocate image chunk memoty\n");
2760 g_img_chunk_list
.max_chunk
= DEFAULT_CHUNK_NUM
;
2761 g_img_chunk_list
.cur_chunk
= 0;
2763 start
= file
->device
->disk
->partition
->start
;
2765 ventoy_get_block_list(file
, &g_img_chunk_list
, start
);
2767 rc
= ventoy_check_block_list(file
, &g_img_chunk_list
, start
);
2768 grub_file_close(file
);
2772 return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET
, "Unsupported chunk list.\n");
2775 grub_memset(&g_grub_param
->file_replace
, 0, sizeof(g_grub_param
->file_replace
));
2776 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2779 static grub_err_t
ventoy_select_conf_replace(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2781 grub_uint64_t offset
= 0;
2782 grub_uint32_t align
= 0;
2783 grub_file_t file
= NULL
;
2784 conf_replace
*node
= NULL
;
2790 debug("select conf replace argc:%d\n", argc
);
2797 node
= ventoy_plugin_find_conf_replace(args
[1]);
2800 debug("Conf replace not found for %s\n", args
[1]);
2804 debug("Find conf replace for %s\n", args
[1]);
2806 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "(loop)%s", node
->orgconf
);
2809 debug("<(loop)%s> NOT exist\n", node
->orgconf
);
2813 offset
= grub_iso9660_get_last_file_dirent_pos(file
);
2814 grub_file_close(file
);
2816 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s%s", args
[0], node
->newconf
);
2819 debug("New config file <%s%s> NOT exist\n", args
[0], node
->newconf
);
2823 align
= ((int)file
->size
+ 2047) / 2048 * 2048;
2825 if (align
> vtoy_max_replace_file_size
)
2827 debug("New config file <%s%s> too big\n", args
[0], node
->newconf
);
2831 grub_file_read(file
, g_conf_replace_new_buf
, file
->size
);
2832 g_conf_replace_new_len
= (int)file
->size
;
2833 g_conf_replace_new_len_align
= align
;
2835 g_conf_replace_node
= node
;
2836 g_conf_replace_offset
= offset
+ 2;
2838 debug("conf_replace OK: newlen: %d\n", g_conf_replace_new_len
);
2843 grub_file_close(file
);
2845 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2848 static grub_err_t
ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2853 char configfile
[128];
2854 install_template
*node
= NULL
;
2860 debug("select auto installation argc:%d\n", argc
);
2867 node
= ventoy_plugin_find_install_template(args
[0]);
2870 debug("Auto install template not found for %s\n", args
[0]);
2874 if (node
->autosel
>= 0 && node
->autosel
<= node
->templatenum
)
2876 node
->cursel
= node
->autosel
- 1;
2877 debug("Auto install template auto select %d\n", node
->autosel
);
2881 buf
= (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF
);
2887 vtoy_ssprintf(buf
, pos
, "menuentry \"Boot without auto installation template\" {\n"
2888 " echo %s\n}\n", "123");
2890 for (i
= 0; i
< node
->templatenum
; i
++)
2892 vtoy_ssprintf(buf
, pos
, "menuentry \"Boot with %s\" {\n"
2894 node
->templatepath
[i
].path
);
2897 g_ventoy_menu_esc
= 1;
2898 g_ventoy_suppress_esc
= 1;
2900 grub_snprintf(configfile
, sizeof(configfile
), "configfile mem:0x%llx:size:%d", (ulonglong
)(ulong
)buf
, pos
);
2901 grub_script_execute_sourcecode(configfile
);
2903 g_ventoy_menu_esc
= 0;
2904 g_ventoy_suppress_esc
= 0;
2908 node
->cursel
= g_ventoy_last_entry
- 1;
2910 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2913 static grub_err_t
ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2918 char configfile
[128];
2919 persistence_config
*node
;
2925 debug("select persistence argc:%d\n", argc
);
2932 node
= ventoy_plugin_find_persistent(args
[0]);
2935 debug("Persistence image not found for %s\n", args
[0]);
2939 if (node
->autosel
>= 0 && node
->autosel
<= node
->backendnum
)
2941 node
->cursel
= node
->autosel
- 1;
2942 debug("Persistence image auto select %d\n", node
->autosel
);
2946 buf
= (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF
);
2952 vtoy_ssprintf(buf
, pos
, "menuentry \"Boot without persistence\" {\n"
2953 " echo %s\n}\n", "123");
2955 for (i
= 0; i
< node
->backendnum
; i
++)
2957 vtoy_ssprintf(buf
, pos
, "menuentry \"Boot with %s\" {\n"
2959 node
->backendpath
[i
].path
);
2963 g_ventoy_menu_esc
= 1;
2964 g_ventoy_suppress_esc
= 1;
2966 grub_snprintf(configfile
, sizeof(configfile
), "configfile mem:0x%llx:size:%d", (ulonglong
)(ulong
)buf
, pos
);
2967 grub_script_execute_sourcecode(configfile
);
2969 g_ventoy_menu_esc
= 0;
2970 g_ventoy_suppress_esc
= 0;
2974 node
->cursel
= g_ventoy_last_entry
- 1;
2976 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
2979 static grub_err_t
ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt
, int argc
, char **args
)
2982 ventoy_img_chunk
*cur
;
2988 for (i
= 0; i
< g_img_chunk_list
.cur_chunk
; i
++)
2990 cur
= g_img_chunk_list
.chunk
+ i
;
2991 grub_printf("image:[%u - %u] <==> disk:[%llu - %llu]\n",
2992 cur
->img_start_sector
, cur
->img_end_sector
,
2993 (unsigned long long)cur
->disk_start_sector
, (unsigned long long)cur
->disk_end_sector
2997 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
3000 static grub_err_t
ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3004 ventoy_img_chunk_list chunklist
;
3009 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
3012 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Can't open file %s\n", args
[0]);
3015 /* get image chunk data */
3016 grub_memset(&chunklist
, 0, sizeof(chunklist
));
3017 chunklist
.chunk
= grub_malloc(sizeof(ventoy_img_chunk
) * DEFAULT_CHUNK_NUM
);
3018 if (NULL
== chunklist
.chunk
)
3020 return grub_error(GRUB_ERR_OUT_OF_MEMORY
, "Can't allocate image chunk memoty\n");
3023 chunklist
.max_chunk
= DEFAULT_CHUNK_NUM
;
3024 chunklist
.cur_chunk
= 0;
3026 ventoy_get_block_list(file
, &chunklist
, 0);
3028 if (0 != ventoy_check_block_list(file
, &chunklist
, 0))
3030 grub_printf("########## UNSUPPORTED ###############\n");
3033 grub_printf("filesystem: <%s> entry number:<%u>\n", file
->fs
->name
, chunklist
.cur_chunk
);
3035 for (i
= 0; i
< chunklist
.cur_chunk
; i
++)
3037 grub_printf("%llu+%llu,", (ulonglong
)chunklist
.chunk
[i
].disk_start_sector
,
3038 (ulonglong
)(chunklist
.chunk
[i
].disk_end_sector
+ 1 - chunklist
.chunk
[i
].disk_start_sector
));
3041 grub_printf("\n==================================\n");
3043 for (i
= 0; i
< chunklist
.cur_chunk
; i
++)
3045 grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i
,
3046 (ulonglong
)chunklist
.chunk
[i
].img_start_sector
,
3047 (ulonglong
)chunklist
.chunk
[i
].img_end_sector
,
3048 (ulonglong
)chunklist
.chunk
[i
].disk_start_sector
,
3049 (ulonglong
)chunklist
.chunk
[i
].disk_end_sector
3053 grub_free(chunklist
.chunk
);
3054 grub_file_close(file
);
3056 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
3059 static grub_err_t
ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3062 ventoy_grub_param_file_replace
*replace
= NULL
;
3070 replace
= &(g_grub_param
->file_replace
);
3071 replace
->magic
= GRUB_FILE_REPLACE_MAGIC
;
3073 replace
->old_name_cnt
= 0;
3074 for (i
= 0; i
< 4 && i
+ 1 < argc
; i
++)
3076 replace
->old_name_cnt
++;
3077 grub_snprintf(replace
->old_file_name
[i
], sizeof(replace
->old_file_name
[i
]), "%s", args
[i
+ 1]);
3080 replace
->new_file_virtual_id
= (grub_uint32_t
)grub_strtoul(args
[0], NULL
, 10);
3083 VENTOY_CMD_RETURN(GRUB_ERR_NONE
);
3086 static grub_err_t
ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3094 grub_printf("List Mode: CurLen:%d MaxLen:%u\n", g_list_script_pos
, VTOY_MAX_SCRIPT_BUF
);
3095 grub_printf("%s", g_list_script_buf
);
3099 grub_printf("Tree Mode: CurLen:%d MaxLen:%u\n", g_tree_script_pos
, VTOY_MAX_SCRIPT_BUF
);
3100 grub_printf("%s", g_tree_script_buf
);
3106 static grub_err_t
ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3108 img_info
*cur
= g_ventoy_img_list
;
3116 grub_printf("path:<%s> id=%d list_index=%d\n", cur
->path
, cur
->id
, cur
->plugin_list_index
);
3117 grub_printf("name:<%s>\n\n", cur
->name
);
3124 static grub_err_t
ventoy_cmd_dump_injection(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3130 ventoy_plugin_dump_injection();
3135 static grub_err_t
ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3141 ventoy_plugin_dump_auto_install();
3146 static grub_err_t
ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3152 ventoy_plugin_dump_persistence();
3157 static grub_err_t
ventoy_cmd_check_mode(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3168 if (args
[0][0] == '0')
3170 return g_ventoy_memdisk_mode
? 0 : 1;
3172 else if (args
[0][0] == '1')
3174 return g_ventoy_iso_raw
? 0 : 1;
3176 else if (args
[0][0] == '2')
3178 return g_ventoy_iso_uefi_drv
? 0 : 1;
3180 else if (args
[0][0] == '3')
3182 return g_ventoy_grub2_mode
? 0 : 1;
3184 else if (args
[0][0] == '4')
3186 return g_ventoy_wimboot_mode
? 0 : 1;
3192 static grub_err_t
ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3194 static int configfile_mode
= 0;
3195 char memfile
[128] = {0};
3202 * args[0]: 0:normal 1:configfile
3203 * args[1]: 0:list_buf 1:tree_buf
3208 debug("Invalid argc %d\n", argc
);
3214 if (args
[0][0] == '0')
3216 if (args
[1][0] == '0')
3218 grub_script_execute_sourcecode(g_list_script_buf
);
3222 grub_script_execute_sourcecode(g_tree_script_buf
);
3227 if (configfile_mode
)
3229 debug("Now already in F3 mode %d\n", configfile_mode
);
3233 if (args
[1][0] == '0')
3235 grub_snprintf(memfile
, sizeof(memfile
), "configfile mem:0x%llx:size:%d",
3236 (ulonglong
)(ulong
)g_list_script_buf
, g_list_script_pos
);
3240 g_ventoy_last_entry
= -1;
3241 grub_snprintf(memfile
, sizeof(memfile
), "configfile mem:0x%llx:size:%d",
3242 (ulonglong
)(ulong
)g_tree_script_buf
, g_tree_script_pos
);
3245 configfile_mode
= 1;
3246 grub_script_execute_sourcecode(memfile
);
3247 configfile_mode
= 0;
3253 static grub_err_t
ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3264 g_ventoy_case_insensitive
= 1;
3265 file
= grub_file_open(args
[0], VENTOY_FILE_TYPE
);
3266 g_ventoy_case_insensitive
= 0;
3272 grub_file_close(file
);
3278 static grub_err_t
ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3283 const char *isopath
= NULL
;
3285 ventoy_mbr_head mbr
;
3292 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s variable\n", cmd_raw_name
);
3295 isopath
= grub_env_get("vtoy_iso_part");
3298 debug("isopath is null %p\n", isopath
);
3302 debug("isopath is %s\n", isopath
);
3304 for (id
= 0; id
< 30 && (find
== 0); id
++)
3306 grub_snprintf(hdname
, sizeof(hdname
), "hd%d,", id
);
3307 if (grub_strstr(isopath
, hdname
))
3309 debug("skip %s ...\n", hdname
);
3313 grub_snprintf(hdname
, sizeof(hdname
), "hd%d", id
);
3315 disk
= grub_disk_open(hdname
);
3318 debug("%s not exist\n", hdname
);
3322 grub_memset(&mbr
, 0, sizeof(mbr
));
3323 if (0 == grub_disk_read(disk
, 0, 0, 512, &mbr
))
3325 if (mbr
.Byte55
== 0x55 && mbr
.ByteAA
== 0xAA)
3327 if (mbr
.PartTbl
[0].Active
== 0x80 || mbr
.PartTbl
[1].Active
== 0x80 ||
3328 mbr
.PartTbl
[2].Active
== 0x80 || mbr
.PartTbl
[3].Active
== 0x80)
3331 grub_env_set(args
[0], hdname
);
3335 debug("%s is %s\n", hdname
, find
? "bootable" : "NOT bootable");
3339 debug("read %s failed\n", hdname
);
3342 grub_disk_close(disk
);
3348 static grub_err_t
ventoy_cmd_read_1st_line(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3359 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s file var \n", cmd_raw_name
);
3362 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
3365 debug("failed to open file %s\n", args
[0]);
3369 buf
= grub_malloc(len
);
3376 grub_file_read(file
, buf
, len
- 1);
3378 ventoy_get_line(buf
);
3379 ventoy_set_env(args
[1], buf
);
3383 grub_check_free(buf
);
3384 grub_file_close(file
);
3389 static int ventoy_img_partition_callback (struct grub_disk
*disk
, const grub_partition_t partition
, void *data
)
3394 g_part_list_pos
+= grub_snprintf(g_part_list_buf
+ g_part_list_pos
, VTOY_MAX_SCRIPT_BUF
- g_part_list_pos
,
3395 "0 %llu linear /dev/ventoy %llu\n",
3396 (ulonglong
)partition
->len
, (ulonglong
)partition
->start
);
3401 static grub_err_t
ventoy_cmd_img_part_info(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3403 char *device_name
= NULL
;
3404 grub_device_t dev
= NULL
;
3409 g_part_list_pos
= 0;
3410 grub_env_unset("vtoy_img_part_file");
3417 device_name
= grub_file_get_device_name(args
[0]);
3420 debug("ventoy_cmd_img_part_info failed, %s\n", args
[0]);
3424 dev
= grub_device_open(device_name
);
3427 debug("grub_device_open failed, %s\n", device_name
);
3431 grub_partition_iterate(dev
->disk
, ventoy_img_partition_callback
, NULL
);
3433 grub_snprintf(buf
, sizeof(buf
), "newc:vtoy_dm_table:mem:0x%llx:size:%d", (ulonglong
)(ulong
)g_part_list_buf
, g_part_list_pos
);
3434 grub_env_set("vtoy_img_part_file", buf
);
3438 check_free(device_name
, grub_free
);
3439 check_free(dev
, grub_device_close
);
3445 static grub_err_t
ventoy_cmd_file_strstr(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3456 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s file str \n", cmd_raw_name
);
3459 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
3462 debug("failed to open file %s\n", args
[0]);
3466 buf
= grub_malloc(file
->size
+ 1);
3472 buf
[file
->size
] = 0;
3473 grub_file_read(file
, buf
, file
->size
);
3475 if (grub_strstr(buf
, args
[1]))
3482 grub_check_free(buf
);
3483 grub_file_close(file
);
3488 static grub_err_t
ventoy_cmd_parse_volume(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3494 ventoy_iso9660_vd pvd
;
3501 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s sysid volid space \n", cmd_raw_name
);
3504 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
3507 debug("failed to open file %s\n", args
[0]);
3511 grub_file_seek(file
, 16 * 2048);
3512 len
= (int)grub_file_read(file
, &pvd
, sizeof(pvd
));
3513 if (len
!= sizeof(pvd
))
3515 debug("failed to read pvd %d\n", len
);
3519 grub_memset(buf
, 0, sizeof(buf
));
3520 grub_memcpy(buf
, pvd
.sys
, sizeof(pvd
.sys
));
3521 ventoy_set_env(args
[1], buf
);
3523 grub_memset(buf
, 0, sizeof(buf
));
3524 grub_memcpy(buf
, pvd
.vol
, sizeof(pvd
.vol
));
3525 ventoy_set_env(args
[2], buf
);
3529 grub_snprintf(buf
, sizeof(buf
), "%llu", (ulonglong
)size
);
3530 ventoy_set_env(args
[3], buf
);
3533 grub_file_close(file
);
3538 static grub_err_t
ventoy_cmd_parse_create_date(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3549 return grub_error(GRUB_ERR_BAD_ARGUMENT
, "Usage: %s var \n", cmd_raw_name
);
3552 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
3555 debug("failed to open file %s\n", args
[0]);
3559 grub_memset(buf
, 0, sizeof(buf
));
3560 grub_file_seek(file
, 16 * 2048 + 813);
3561 len
= (int)grub_file_read(file
, buf
, 17);
3564 debug("failed to read create date %d\n", len
);
3568 ventoy_set_env(args
[1], buf
);
3571 grub_file_close(file
);
3576 static grub_err_t
ventoy_cmd_img_hook_root(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3582 ventoy_env_hook_root(1);
3587 static grub_err_t
ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3593 ventoy_env_hook_root(0);
3598 #ifdef GRUB_MACHINE_EFI
3599 static grub_err_t
ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3604 grub_efi_guid_t global
= GRUB_EFI_GLOBAL_VARIABLE_GUID
;
3610 var
= grub_efi_get_variable("SecureBoot", &global
, &size
);
3611 if (var
&& *var
== 1)
3619 static grub_err_t
ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3628 static grub_err_t
ventoy_cmd_img_check_range(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3633 grub_uint64_t FileSectors
= 0;
3634 ventoy_gpt_info
*gpt
= NULL
;
3635 ventoy_part_table
*pt
= NULL
;
3636 grub_uint8_t zeroguid
[16] = {0};
3641 file
= ventoy_grub_file_open(VENTOY_FILE_TYPE
, "%s", args
[0]);
3644 debug("failed to open file %s\n", args
[0]);
3648 if (file
->size
% 512)
3650 debug("unaligned file size: %llu\n", (ulonglong
)file
->size
);
3654 gpt
= grub_zalloc(sizeof(ventoy_gpt_info
));
3660 FileSectors
= file
->size
/ 512;
3662 grub_file_read(file
, gpt
, sizeof(ventoy_gpt_info
));
3663 if (grub_strncmp(gpt
->Head
.Signature
, "EFI PART", 8) == 0)
3665 debug("This is EFI partition table\n");
3667 for (i
= 0; i
< 128; i
++)
3669 if (grub_memcmp(gpt
->PartTbl
[i
].PartGuid
, zeroguid
, 16))
3671 if (FileSectors
< gpt
->PartTbl
[i
].LastLBA
)
3673 debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i
,
3674 (ulonglong
)gpt
->PartTbl
[i
].LastLBA
, (ulonglong
)FileSectors
);
3682 debug("This is MBR partition table\n");
3684 for (i
= 0; i
< 4; i
++)
3686 pt
= gpt
->MBR
.PartTbl
+ i
;
3687 if (FileSectors
< pt
->StartSectorId
+ pt
->SectorCount
)
3689 debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i
,
3690 (ulonglong
)(pt
->StartSectorId
+ pt
->SectorCount
),
3691 (ulonglong
)FileSectors
);
3700 grub_file_close(file
);
3701 grub_check_free(gpt
);
3702 grub_errno
= GRUB_ERR_NONE
;
3706 static grub_err_t
ventoy_cmd_clear_key(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3715 for (i
= 0; i
< 500; i
++)
3717 ret
= grub_getkey_noblock();
3718 if (ret
== GRUB_TERM_NO_KEY
)
3727 grub_printf("\n\n Still have key input after clear.\n");
3735 static grub_err_t
ventoy_cmd_acpi_param(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3742 int image_sector_size
;
3744 ventoy_chain_head
*chain
;
3745 ventoy_img_chunk
*chunk
;
3746 ventoy_os_param
*osparam
;
3747 ventoy_image_location
*location
;
3748 ventoy_image_disk_region
*region
;
3749 struct grub_acpi_table_header
*acpi
;
3758 debug("ventoy_cmd_acpi_param %s %s\n", args
[0], args
[1]);
3760 chain
= (ventoy_chain_head
*)(ulong
)grub_strtoul(args
[0], NULL
, 16);
3766 image_sector_size
= (int)grub_strtol(args
[1], NULL
, 10);
3768 if (grub_memcmp(&g_ventoy_guid
, &(chain
->os_param
.guid
), 16))
3770 debug("Invalid ventoy guid 0x%x\n", chain
->os_param
.guid
.data1
);
3774 img_chunk_num
= chain
->img_chunk_num
;
3776 loclen
= sizeof(ventoy_image_location
) + (img_chunk_num
- 1) * sizeof(ventoy_image_disk_region
);
3777 datalen
= sizeof(ventoy_os_param
) + loclen
;
3779 buflen
= sizeof(struct grub_acpi_table_header
) + datalen
;
3780 acpi
= grub_zalloc(buflen
);
3786 /* Step1: Fill acpi table header */
3787 grub_memcpy(acpi
->signature
, "VTOY", 4);
3788 acpi
->length
= buflen
;
3790 grub_memcpy(acpi
->oemid
, "VENTOY", 6);
3791 grub_memcpy(acpi
->oemtable
, "OSPARAMS", 8);
3793 acpi
->creator_id
[0] = 1;
3794 acpi
->creator_rev
= 1;
3796 /* Step2: Fill data */
3797 osparam
= (ventoy_os_param
*)(acpi
+ 1);
3798 grub_memcpy(osparam
, &chain
->os_param
, sizeof(ventoy_os_param
));
3799 osparam
->vtoy_img_location_addr
= 0;
3800 osparam
->vtoy_img_location_len
= loclen
;
3801 osparam
->chksum
= 0;
3802 osparam
->chksum
= 0x100 - grub_byte_checksum(osparam
, sizeof(ventoy_os_param
));
3804 location
= (ventoy_image_location
*)(osparam
+ 1);
3805 grub_memcpy(&location
->guid
, &osparam
->guid
, sizeof(ventoy_guid
));
3806 location
->image_sector_size
= image_sector_size
;
3807 location
->disk_sector_size
= chain
->disk_sector_size
;
3808 location
->region_count
= img_chunk_num
;
3810 region
= location
->regions
;
3811 chunk
= (ventoy_img_chunk
*)((char *)chain
+ chain
->img_chunk_offset
);
3812 if (512 == image_sector_size
)
3814 for (i
= 0; i
< img_chunk_num
; i
++)
3816 region
->image_sector_count
= chunk
->disk_end_sector
- chunk
->disk_start_sector
+ 1;
3817 region
->image_start_sector
= chunk
->img_start_sector
* 4;
3818 region
->disk_start_sector
= chunk
->disk_start_sector
;
3825 for (i
= 0; i
< img_chunk_num
; i
++)
3827 region
->image_sector_count
= chunk
->img_end_sector
- chunk
->img_start_sector
+ 1;
3828 region
->image_start_sector
= chunk
->img_start_sector
;
3829 region
->disk_start_sector
= chunk
->disk_start_sector
;
3835 /* Step3: Fill acpi checksum */
3837 acpi
->checksum
= 0x100 - grub_byte_checksum(acpi
, acpi
->length
);
3839 /* load acpi table */
3840 grub_snprintf(cmd
, sizeof(cmd
), "acpi mem:0x%lx:size:%d", (ulong
)acpi
, acpi
->length
);
3841 grub_script_execute_sourcecode(cmd
);
3845 VENTOY_CMD_RETURN(0);
3848 static grub_err_t
ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3854 g_ventoy_last_entry_back
= g_ventoy_last_entry
;
3855 g_ventoy_last_entry
= -1;
3860 static grub_err_t
ventoy_cmd_pop_last_entry(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3866 g_ventoy_last_entry
= g_ventoy_last_entry_back
;
3871 static int ventoy_lib_module_callback(const char *filename
, const struct grub_dirhook_info
*info
, void *data
)
3873 const char *pos
= filename
+ 1;
3881 if ((*(pos
- 1) >= '0' && *(pos
- 1) <= '9') && (*(pos
+ 1) >= '0' && *(pos
+ 1) <= '9'))
3883 grub_strncpy((char *)data
, filename
, 128);
3894 static grub_err_t
ventoy_cmd_lib_module_ver(grub_extcmd_context_t ctxt
, int argc
, char **args
)
3897 char *device_name
= NULL
;
3898 grub_device_t dev
= NULL
;
3899 grub_fs_t fs
= NULL
;
3900 char buf
[128] = {0};
3906 debug("ventoy_cmd_lib_module_ver, invalid param num %d\n", argc
);
3910 debug("ventoy_cmd_lib_module_ver %s %s %s\n", args
[0], args
[1], args
[2]);
3912 device_name
= grub_file_get_device_name(args
[0]);
3915 debug("grub_file_get_device_name failed, %s\n", args
[0]);
3919 dev
= grub_device_open(device_name
);
3922 debug("grub_device_open failed, %s\n", device_name
);
3926 fs
= grub_fs_probe(dev
);
3929 debug("grub_fs_probe failed, %s\n", device_name
);
3933 fs
->fs_dir(dev
, args
[1], ventoy_lib_module_callback
, buf
);
3937 ventoy_set_env(args
[2], buf
);
3944 check_free(device_name
, grub_free
);
3945 check_free(dev
, grub_device_close
);
3950 int ventoy_load_part_table(const char *diskname
)
3957 g_ventoy_part_info
= grub_zalloc(sizeof(ventoy_gpt_info
));
3958 if (!g_ventoy_part_info
)
3963 disk
= grub_disk_open(diskname
);
3966 debug("Failed to open disk %s\n", diskname
);
3970 g_ventoy_disk_size
= disk
->total_sectors
* (1U << disk
->log_sector_size
);
3972 grub_disk_read(disk
, 0, 0, sizeof(ventoy_gpt_info
), g_ventoy_part_info
);
3973 grub_disk_close(disk
);
3975 grub_snprintf(name
, sizeof(name
), "%s,1", diskname
);
3976 dev
= grub_device_open(name
);
3979 /* Check for official Ventoy device */
3980 ret
= ventoy_check_official_device(dev
);
3981 grub_device_close(dev
);
3989 g_ventoy_disk_part_size
[0] = ventoy_get_vtoy_partsize(0);
3990 g_ventoy_disk_part_size
[1] = ventoy_get_vtoy_partsize(1);
3995 static grub_err_t
ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4002 ret
= ventoy_load_part_table(args
[0]);
4008 g_ventoy_disk_part_size
[0] = ventoy_get_vtoy_partsize(0);
4009 g_ventoy_disk_part_size
[1] = ventoy_get_vtoy_partsize(1);
4014 static grub_err_t
ventoy_cmd_check_custom_boot(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4017 const char *vcfg
= NULL
;
4022 vcfg
= ventoy_plugin_get_custom_boot(args
[0]);
4025 debug("custom boot <%s>:<%s>\n", args
[0], vcfg
);
4026 grub_env_set(args
[1], vcfg
);
4031 debug("custom boot <%s>:<NOT FOUND>\n", args
[0]);
4039 static grub_err_t
ventoy_cmd_part_exist(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4042 grub_uint8_t zeroguid
[16] = {0};
4047 id
= (int)grub_strtoul(args
[0], NULL
, 10);
4050 if (grub_memcmp(g_ventoy_part_info
->Head
.Signature
, "EFI PART", 8) == 0)
4052 if (id
>= 1 && id
<= 128)
4054 if (grub_memcmp(g_ventoy_part_info
->PartTbl
[id
- 1].PartGuid
, zeroguid
, 16))
4062 if (id
>= 1 && id
<= 4)
4064 if (g_ventoy_part_info
->MBR
.PartTbl
[id
- 1].FsFlag
)
4074 static grub_err_t
ventoy_cmd_get_fs_label(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4077 char *device_name
= NULL
;
4078 grub_device_t dev
= NULL
;
4079 grub_fs_t fs
= NULL
;
4084 debug("get fs label for %s\n", args
[0]);
4088 debug("ventoy_cmd_get_fs_label, invalid param num %d\n", argc
);
4092 device_name
= grub_file_get_device_name(args
[0]);
4095 debug("grub_file_get_device_name failed, %s\n", args
[0]);
4099 dev
= grub_device_open(device_name
);
4102 debug("grub_device_open failed, %s\n", device_name
);
4106 fs
= grub_fs_probe(dev
);
4107 if (NULL
== fs
|| NULL
== fs
->fs_label
)
4109 debug("grub_fs_probe failed, %s %p %p\n", device_name
, fs
, fs
->fs_label
);
4113 fs
->fs_label(dev
, &label
);
4116 debug("label=<%s>\n", label
);
4117 ventoy_set_env(args
[1], label
);
4125 check_free(device_name
, grub_free
);
4126 check_free(dev
, grub_device_close
);
4131 static int ventoy_fs_enum_1st_file(const char *filename
, const struct grub_dirhook_info
*info
, void *data
)
4135 grub_snprintf((char *)data
, 256, "%s", filename
);
4143 static grub_err_t
ventoy_cmd_fs_enum_1st_file(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4146 char *device_name
= NULL
;
4147 grub_device_t dev
= NULL
;
4148 grub_fs_t fs
= NULL
;
4149 char name
[256] ={0};
4155 debug("ventoy_cmd_fs_enum_1st_file, invalid param num %d\n", argc
);
4159 device_name
= grub_file_get_device_name(args
[0]);
4162 debug("grub_file_get_device_name failed, %s\n", args
[0]);
4166 dev
= grub_device_open(device_name
);
4169 debug("grub_device_open failed, %s\n", device_name
);
4173 fs
= grub_fs_probe(dev
);
4176 debug("grub_fs_probe failed, %s\n", device_name
);
4180 fs
->fs_dir(dev
, args
[1], ventoy_fs_enum_1st_file
, name
);
4183 ventoy_set_env(args
[2], name
);
4190 check_free(device_name
, grub_free
);
4191 check_free(dev
, grub_device_close
);
4196 static grub_err_t
ventoy_cmd_basename(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4206 debug("ventoy_cmd_basename, invalid param num %d\n", argc
);
4210 for (pos
= args
[0]; *pos
; pos
++)
4224 grub_env_set(args
[1], args
[0]);
4234 static grub_err_t
ventoy_cmd_basefile(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4244 debug("ventoy_cmd_basefile, invalid param num %d\n", argc
);
4249 len
= (int)grub_strlen(buf
);
4250 for (i
= len
; i
> 0; i
--)
4252 if (buf
[i
- 1] == '/')
4254 grub_env_set(args
[1], buf
+ i
);
4259 grub_env_set(args
[1], buf
);
4264 static grub_err_t
ventoy_cmd_enum_video_mode(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4266 struct grub_video_mode_info info
;
4273 if (!g_video_mode_list
)
4275 ventoy_enum_video_mode();
4278 if (grub_video_get_info(&info
) == GRUB_ERR_NONE
)
4280 grub_snprintf(buf
, sizeof(buf
), "Resolution (%ux%u)", info
.width
, info
.height
);
4284 grub_snprintf(buf
, sizeof(buf
), "Resolution (0x0)");
4287 grub_env_set("VTOY_CUR_VIDEO_MODE", buf
);
4289 grub_snprintf(buf
, sizeof(buf
), "%d", g_video_mode_num
);
4290 grub_env_set("VTOY_VIDEO_MODE_NUM", buf
);
4292 VENTOY_CMD_RETURN(0);
4295 static grub_err_t
vt_cmd_update_cur_video_mode(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4297 struct grub_video_mode_info info
;
4304 if (grub_video_get_info(&info
) == GRUB_ERR_NONE
)
4306 grub_snprintf(buf
, sizeof(buf
), "%ux%ux%u", info
.width
, info
.height
, info
.bpp
);
4310 grub_snprintf(buf
, sizeof(buf
), "0x0x0");
4313 grub_env_set(args
[0], buf
);
4315 VENTOY_CMD_RETURN(0);
4318 static grub_err_t
ventoy_cmd_get_video_mode(grub_extcmd_context_t ctxt
, int argc
, char **args
)
4326 if (!g_video_mode_list
)
4331 id
= (int)grub_strtoul(args
[0], NULL
, 10);
4332 if (id
< g_video_mode_num
)
4334 grub_snprintf(buf
, sizeof(buf
), "%ux%ux%u",
4335 g_video_mode_list
[id
].width
, g_video_mode_list
[id
].height
, g_video_mode_list
[id
].bpp
);
4338 grub_env_set(args
[1], buf
);
4340 VENTOY_CMD_RETURN(0);
4343 int ventoy_env_init(void)
4347 grub_env_set("vtdebug_flag", "");
4349 g_part_list_buf
= grub_malloc(VTOY_PART_BUF_LEN
);
4350 g_tree_script_buf
= grub_malloc(VTOY_MAX_SCRIPT_BUF
);
4351 g_list_script_buf
= grub_malloc(VTOY_MAX_SCRIPT_BUF
);
4352 g_conf_replace_new_buf
= grub_malloc(vtoy_max_replace_file_size
);
4354 ventoy_filt_register(0, ventoy_wrapper_open
);
4356 g_grub_param
= (ventoy_grub_param
*)grub_zalloc(sizeof(ventoy_grub_param
));
4359 g_grub_param
->grub_env_get
= grub_env_get
;
4360 g_grub_param
->grub_env_set
= (grub_env_set_pf
)grub_env_set
;
4361 g_grub_param
->grub_env_printf
= (grub_env_printf_pf
)grub_printf
;
4362 grub_snprintf(buf
, sizeof(buf
), "%p", g_grub_param
);
4363 grub_env_set("env_param", buf
);
4364 grub_env_set("ventoy_env_param", buf
);
4366 grub_env_export("env_param");
4367 grub_env_export("ventoy_env_param");
4370 grub_snprintf(buf
, sizeof(buf
), "0x%lx", (ulong
)g_vtoy_winpeshl_ini
);
4371 grub_env_set("vtoy_winpeshl_ini_addr", buf
);
4373 grub_snprintf(buf
, sizeof(buf
), "%d", (int)grub_strlen(g_vtoy_winpeshl_ini
));
4374 grub_env_set("vtoy_winpeshl_ini_size", buf
);
4376 grub_env_export("vtoy_winpeshl_ini_addr");
4377 grub_env_export("vtoy_winpeshl_ini_size");
4379 grub_snprintf(buf
, sizeof(buf
), "0x%lx", (ulong
)ventoy_chain_file_size
);
4380 grub_env_set("vtoy_chain_file_size", buf
);
4381 grub_env_export("vtoy_chain_file_size");
4383 grub_snprintf(buf
, sizeof(buf
), "0x%lx", (ulong
)ventoy_chain_file_read
);
4384 grub_env_set("vtoy_chain_file_read", buf
);
4385 grub_env_export("vtoy_chain_file_read");
4390 static cmd_para ventoy_cmds
[] =
4392 { "vt_incr", ventoy_cmd_incr
, 0, NULL
, "{Var} {INT}", "Increase integer variable", NULL
},
4393 { "vt_mod", ventoy_cmd_mod
, 0, NULL
, "{Int} {Int} {Var}", "mod integer variable", NULL
},
4394 { "vt_strstr", ventoy_cmd_strstr
, 0, NULL
, "", "", NULL
},
4395 { "vt_str_begin", ventoy_cmd_strbegin
, 0, NULL
, "", "", NULL
},
4396 { "vt_debug", ventoy_cmd_debug
, 0, NULL
, "{on|off}", "turn debug on/off", NULL
},
4397 { "vtdebug", ventoy_cmd_debug
, 0, NULL
, "{on|off}", "turn debug on/off", NULL
},
4398 { "vtbreak", ventoy_cmd_break
, 0, NULL
, "{level}", "set debug break", NULL
},
4399 { "vt_cmp", ventoy_cmd_cmp
, 0, NULL
, "{Int1} { eq|ne|gt|lt|ge|le } {Int2}", "Comare two integers", NULL
},
4400 { "vt_device", ventoy_cmd_device
, 0, NULL
, "path var", "", NULL
},
4401 { "vt_check_compatible", ventoy_cmd_check_compatible
, 0, NULL
, "", "", NULL
},
4402 { "vt_list_img", ventoy_cmd_list_img
, 0, NULL
, "{device} {cntvar}", "find all iso file in device", NULL
},
4403 { "vt_clear_img", ventoy_cmd_clear_img
, 0, NULL
, "", "clear image list", NULL
},
4404 { "vt_img_name", ventoy_cmd_img_name
, 0, NULL
, "{imageID} {var}", "get image name", NULL
},
4405 { "vt_chosen_img_path", ventoy_cmd_chosen_img_path
, 0, NULL
, "{var}", "get chosen img path", NULL
},
4406 { "vt_ext_select_img_path", ventoy_cmd_ext_select_img_path
, 0, NULL
, "{var}", "select chosen img path", NULL
},
4407 { "vt_img_sector", ventoy_cmd_img_sector
, 0, NULL
, "{imageName}", "", NULL
},
4408 { "vt_dump_img_sector", ventoy_cmd_dump_img_sector
, 0, NULL
, "", "", NULL
},
4409 { "vt_load_wimboot", ventoy_cmd_load_wimboot
, 0, NULL
, "", "", NULL
},
4410 { "vt_load_vhdboot", ventoy_cmd_load_vhdboot
, 0, NULL
, "", "", NULL
},
4411 { "vt_patch_vhdboot", ventoy_cmd_patch_vhdboot
, 0, NULL
, "", "", NULL
},
4412 { "vt_raw_chain_data", ventoy_cmd_raw_chain_data
, 0, NULL
, "", "", NULL
},
4413 { "vt_get_vtoy_type", ventoy_cmd_get_vtoy_type
, 0, NULL
, "", "", NULL
},
4414 { "vt_check_custom_boot", ventoy_cmd_check_custom_boot
, 0, NULL
, "", "", NULL
},
4415 { "vt_dump_custom_boot", ventoy_cmd_dump_custom_boot
, 0, NULL
, "", "", NULL
},
4417 { "vt_skip_svd", ventoy_cmd_skip_svd
, 0, NULL
, "", "", NULL
},
4418 { "vt_cpio_busybox64", ventoy_cmd_cpio_busybox_64
, 0, NULL
, "", "", NULL
},
4419 { "vt_load_cpio", ventoy_cmd_load_cpio
, 0, NULL
, "", "", NULL
},
4420 { "vt_trailer_cpio", ventoy_cmd_trailer_cpio
, 0, NULL
, "", "", NULL
},
4421 { "vt_push_last_entry", ventoy_cmd_push_last_entry
, 0, NULL
, "", "", NULL
},
4422 { "vt_pop_last_entry", ventoy_cmd_pop_last_entry
, 0, NULL
, "", "", NULL
},
4423 { "vt_get_lib_module_ver", ventoy_cmd_lib_module_ver
, 0, NULL
, "", "", NULL
},
4425 { "vt_load_part_table", ventoy_cmd_load_part_table
, 0, NULL
, "", "", NULL
},
4426 { "vt_check_part_exist", ventoy_cmd_part_exist
, 0, NULL
, "", "", NULL
},
4427 { "vt_get_fs_label", ventoy_cmd_get_fs_label
, 0, NULL
, "", "", NULL
},
4428 { "vt_fs_enum_1st_file", ventoy_cmd_fs_enum_1st_file
, 0, NULL
, "", "", NULL
},
4429 { "vt_file_basename", ventoy_cmd_basename
, 0, NULL
, "", "", NULL
},
4430 { "vt_file_basefile", ventoy_cmd_basefile
, 0, NULL
, "", "", NULL
},
4431 { "vt_enum_video_mode", ventoy_cmd_enum_video_mode
, 0, NULL
, "", "", NULL
},
4432 { "vt_get_video_mode", ventoy_cmd_get_video_mode
, 0, NULL
, "", "", NULL
},
4433 { "vt_update_cur_video_mode", vt_cmd_update_cur_video_mode
, 0, NULL
, "", "", NULL
},
4436 { "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd
, 0, NULL
, "", "", NULL
},
4437 { "vt_dump_menu", ventoy_cmd_dump_menu
, 0, NULL
, "", "", NULL
},
4438 { "vt_dynamic_menu", ventoy_cmd_dynamic_menu
, 0, NULL
, "", "", NULL
},
4439 { "vt_check_mode", ventoy_cmd_check_mode
, 0, NULL
, "", "", NULL
},
4440 { "vt_dump_img_list", ventoy_cmd_dump_img_list
, 0, NULL
, "", "", NULL
},
4441 { "vt_dump_injection", ventoy_cmd_dump_injection
, 0, NULL
, "", "", NULL
},
4442 { "vt_dump_auto_install", ventoy_cmd_dump_auto_install
, 0, NULL
, "", "", NULL
},
4443 { "vt_dump_persistence", ventoy_cmd_dump_persistence
, 0, NULL
, "", "", NULL
},
4444 { "vt_select_auto_install", ventoy_cmd_sel_auto_install
, 0, NULL
, "", "", NULL
},
4445 { "vt_select_persistence", ventoy_cmd_sel_persistence
, 0, NULL
, "", "", NULL
},
4446 { "vt_select_conf_replace", ventoy_select_conf_replace
, 0, NULL
, "", "", NULL
},
4448 { "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet
, 0, NULL
, "", "", NULL
},
4449 { "vt_is_udf", ventoy_cmd_is_udf
, 0, NULL
, "", "", NULL
},
4450 { "vt_file_size", ventoy_cmd_file_size
, 0, NULL
, "", "", NULL
},
4451 { "vt_load_file_to_mem", ventoy_cmd_load_file_to_mem
, 0, NULL
, "", "", NULL
},
4452 { "vt_load_img_memdisk", ventoy_cmd_load_img_memdisk
, 0, NULL
, "", "", NULL
},
4453 { "vt_concat_efi_iso", ventoy_cmd_concat_efi_iso
, 0, NULL
, "", "", NULL
},
4455 { "vt_linux_parse_initrd_isolinux", ventoy_cmd_isolinux_initrd_collect
, 0, NULL
, "{cfgfile}", "", NULL
},
4456 { "vt_linux_parse_initrd_grub", ventoy_cmd_grub_initrd_collect
, 0, NULL
, "{cfgfile}", "", NULL
},
4457 { "vt_linux_specify_initrd_file", ventoy_cmd_specify_initrd_file
, 0, NULL
, "", "", NULL
},
4458 { "vt_linux_clear_initrd", ventoy_cmd_clear_initrd_list
, 0, NULL
, "", "", NULL
},
4459 { "vt_linux_dump_initrd", ventoy_cmd_dump_initrd_list
, 0, NULL
, "", "", NULL
},
4460 { "vt_linux_initrd_count", ventoy_cmd_initrd_count
, 0, NULL
, "", "", NULL
},
4461 { "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count
, 0, NULL
, "", "", NULL
},
4462 { "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd
, 0, NULL
, "", "", NULL
},
4463 { "vt_linux_chain_data", ventoy_cmd_linux_chain_data
, 0, NULL
, "", "", NULL
},
4464 { "vt_linux_get_main_initrd_index", ventoy_cmd_linux_get_main_initrd_index
, 0, NULL
, "", "", NULL
},
4466 { "vt_windows_reset", ventoy_cmd_wimdows_reset
, 0, NULL
, "", "", NULL
},
4467 { "vt_windows_chain_data", ventoy_cmd_windows_chain_data
, 0, NULL
, "", "", NULL
},
4468 { "vt_windows_wimboot_data", ventoy_cmd_windows_wimboot_data
, 0, NULL
, "", "", NULL
},
4469 { "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch
, 0, NULL
, "", "", NULL
},
4470 { "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch
, 0, NULL
, "", "", NULL
},
4471 { "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count
, 0, NULL
, "", "", NULL
},
4472 { "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch
, 0, NULL
, "", "", NULL
},
4473 { "vt_wim_check_bootable", ventoy_cmd_wim_check_bootable
, 0, NULL
, "", "", NULL
},
4474 { "vt_wim_chain_data", ventoy_cmd_wim_chain_data
, 0, NULL
, "", "", NULL
},
4476 { "vt_add_replace_file", ventoy_cmd_add_replace_file
, 0, NULL
, "", "", NULL
},
4477 { "vt_test_block_list", ventoy_cmd_test_block_list
, 0, NULL
, "", "", NULL
},
4478 { "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase
, 0, NULL
, "", "", NULL
},
4481 { "vt_load_plugin", ventoy_cmd_load_plugin
, 0, NULL
, "", "", NULL
},
4482 { "vt_check_plugin_json", ventoy_cmd_plugin_check_json
, 0, NULL
, "", "", NULL
},
4483 { "vt_check_password", ventoy_cmd_check_password
, 0, NULL
, "", "", NULL
},
4485 { "vt_1st_line", ventoy_cmd_read_1st_line
, 0, NULL
, "", "", NULL
},
4486 { "vt_file_strstr", ventoy_cmd_file_strstr
, 0, NULL
, "", "", NULL
},
4487 { "vt_img_part_info", ventoy_cmd_img_part_info
, 0, NULL
, "", "", NULL
},
4490 { "vt_parse_iso_volume", ventoy_cmd_parse_volume
, 0, NULL
, "", "", NULL
},
4491 { "vt_parse_iso_create_date", ventoy_cmd_parse_create_date
, 0, NULL
, "", "", NULL
},
4492 { "vt_parse_freenas_ver", ventoy_cmd_parse_freenas_ver
, 0, NULL
, "", "", NULL
},
4493 { "vt_unix_parse_freebsd_ver", ventoy_cmd_unix_freebsd_ver
, 0, NULL
, "", "", NULL
},
4494 { "vt_unix_parse_freebsd_ver_elf", ventoy_cmd_unix_freebsd_ver_elf
, 0, NULL
, "", "", NULL
},
4495 { "vt_unix_reset", ventoy_cmd_unix_reset
, 0, NULL
, "", "", NULL
},
4496 { "vt_unix_replace_conf", ventoy_cmd_unix_replace_conf
, 0, NULL
, "", "", NULL
},
4497 { "vt_unix_replace_ko", ventoy_cmd_unix_replace_ko
, 0, NULL
, "", "", NULL
},
4498 { "vt_unix_fill_image_desc", ventoy_cmd_unix_fill_image_desc
, 0, NULL
, "", "", NULL
},
4499 { "vt_unix_gzip_new_ko", ventoy_cmd_unix_gzip_newko
, 0, NULL
, "", "", NULL
},
4500 { "vt_unix_chain_data", ventoy_cmd_unix_chain_data
, 0, NULL
, "", "", NULL
},
4502 { "vt_img_hook_root", ventoy_cmd_img_hook_root
, 0, NULL
, "", "", NULL
},
4503 { "vt_img_unhook_root", ventoy_cmd_img_unhook_root
, 0, NULL
, "", "", NULL
},
4504 { "vt_acpi_param", ventoy_cmd_acpi_param
, 0, NULL
, "", "", NULL
},
4505 { "vt_check_secureboot_var", ventoy_cmd_check_secureboot_var
, 0, NULL
, "", "", NULL
},
4506 { "vt_clear_key", ventoy_cmd_clear_key
, 0, NULL
, "", "", NULL
},
4507 { "vt_img_check_range", ventoy_cmd_img_check_range
, 0, NULL
, "", "", NULL
},
4508 { "vt_is_pe64", ventoy_cmd_is_pe64
, 0, NULL
, "", "", NULL
},
4509 { "vt_sel_wimboot", ventoy_cmd_sel_wimboot
, 0, NULL
, "", "", NULL
},
4513 int ventoy_register_all_cmd(void)
4516 cmd_para
*cur
= NULL
;
4518 for (i
= 0; i
< ARRAY_SIZE(ventoy_cmds
); i
++)
4520 cur
= ventoy_cmds
+ i
;
4521 cur
->cmd
= grub_register_extcmd(cur
->name
, cur
->func
, cur
->flags
,
4522 cur
->summary
, cur
->description
, cur
->parser
);
4528 int ventoy_unregister_all_cmd(void)
4532 for (i
= 0; i
< ARRAY_SIZE(ventoy_cmds
); i
++)
4534 grub_unregister_extcmd(ventoy_cmds
[i
].cmd
);