diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c new file mode 100644 index 00000000..92492f9d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c @@ -0,0 +1,316 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct newc_head +{ + char magic[6]; + char ino[8]; + char mode[8]; + char uid[8]; + char gid[8]; + char nlink[8]; + char mtime[8]; + char filesize[8]; + char devmajor[8]; + char devminor[8]; + char rdevmajor[8]; + char rdevminor[8]; + char namesize[8]; + char check[8]; +} GRUB_PACKED; + +struct grub_linux_initrd_component +{ + grub_file_t file; + char *newc_name; + grub_off_t size; +}; + +struct dir +{ + char *name; + struct dir *next; + struct dir *child; +}; + +static char +hex (grub_uint8_t val) +{ + if (val < 10) + return '0' + val; + return 'a' + val - 10; +} + +static void +set_field (char *var, grub_uint32_t val) +{ + int i; + char *ptr = var; + for (i = 28; i >= 0; i -= 4) + *ptr++ = hex((val >> i) & 0xf); +} + +static grub_uint8_t * +make_header (grub_uint8_t *ptr, + const char *name, grub_size_t len, + grub_uint32_t mode, + grub_off_t fsize) +{ + struct newc_head *head = (struct newc_head *) ptr; + grub_uint8_t *optr; + grub_size_t oh = 0; + grub_memcpy (head->magic, "070701", 6); + set_field (head->ino, 0); + set_field (head->mode, mode); + set_field (head->uid, 0); + set_field (head->gid, 0); + set_field (head->nlink, 1); + set_field (head->mtime, 0); + set_field (head->filesize, fsize); + set_field (head->devmajor, 0); + set_field (head->devminor, 0); + set_field (head->rdevmajor, 0); + set_field (head->rdevminor, 0); + set_field (head->namesize, len); + set_field (head->check, 0); + optr = ptr; + ptr += sizeof (struct newc_head); + grub_memcpy (ptr, name, len); + ptr += len; + oh = ALIGN_UP_OVERHEAD (ptr - optr, 4); + grub_memset (ptr, 0, oh); + ptr += oh; + return ptr; +} + +static void +free_dir (struct dir *root) +{ + if (!root) + return; + free_dir (root->next); + free_dir (root->child); + grub_free (root->name); + grub_free (root); +} + +static grub_size_t +insert_dir (const char *name, struct dir **root, + grub_uint8_t *ptr) +{ + struct dir *cur, **head = root; + const char *cb, *ce = name; + grub_size_t size = 0; + while (1) + { + for (cb = ce; *cb == '/'; cb++); + for (ce = cb; *ce && *ce != '/'; ce++); + if (!*ce) + break; + + for (cur = *root; cur; cur = cur->next) + if (grub_memcmp (cur->name, cb, ce - cb) + && cur->name[ce - cb] == 0) + break; + if (!cur) + { + struct dir *n; + n = grub_zalloc (sizeof (*n)); + if (!n) + return 0; + n->next = *head; + n->name = grub_strndup (cb, ce - cb); + if (ptr) + { + grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce); + ptr = make_header (ptr, name, ce - name, + 040777, 0); + } + size += ALIGN_UP ((ce - (char *) name) + + sizeof (struct newc_head), 4); + *head = n; + cur = n; + } + root = &cur->next; + } + return size; +} + +grub_err_t +grub_initrd_init (int argc, char *argv[], + struct grub_linux_initrd_context *initrd_ctx) +{ + int i; + int newc = 0; + struct dir *root = 0; + + initrd_ctx->nfiles = 0; + initrd_ctx->components = 0; + + initrd_ctx->components = grub_zalloc (argc + * sizeof (initrd_ctx->components[0])); + if (!initrd_ctx->components) + return grub_errno; + + initrd_ctx->size = 0; + + for (i = 0; i < argc; i++) + { + const char *fname = argv[i]; + + initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); + + if (grub_memcmp (argv[i], "newc:", 5) == 0) + { + const char *ptr, *eptr; + ptr = argv[i] + 5; + while (*ptr == '/') + ptr++; + eptr = grub_strchr (ptr, ':'); + if (eptr) + { + initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); + if (!initrd_ctx->components[i].newc_name) + { + grub_initrd_close (initrd_ctx); + return grub_errno; + } + initrd_ctx->size + += ALIGN_UP (sizeof (struct newc_head) + + grub_strlen (initrd_ctx->components[i].newc_name), + 4); + initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, + &root, 0); + newc = 1; + fname = eptr + 1; + } + } + else if (newc) + { + initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) + + sizeof ("TRAILER!!!") - 1, 4); + free_dir (root); + root = 0; + newc = 0; + } + initrd_ctx->components[i].file = grub_file_open (fname, + GRUB_FILE_TYPE_LINUX_INITRD + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (!initrd_ctx->components[i].file) + { + grub_initrd_close (initrd_ctx); + return grub_errno; + } + initrd_ctx->nfiles++; + initrd_ctx->components[i].size + = grub_file_size (initrd_ctx->components[i].file); + initrd_ctx->size += initrd_ctx->components[i].size; + } + + if (newc) + { + initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); + initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) + + sizeof ("TRAILER!!!") - 1, 4); + free_dir (root); + root = 0; + } + + return GRUB_ERR_NONE; +} + +grub_size_t +grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx) +{ + return initrd_ctx->size; +} + +void +grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx) +{ + int i; + if (!initrd_ctx->components) + return; + for (i = 0; i < initrd_ctx->nfiles; i++) + { + grub_free (initrd_ctx->components[i].newc_name); + grub_file_close (initrd_ctx->components[i].file); + } + grub_free (initrd_ctx->components); + initrd_ctx->components = 0; +} + +extern int ventoy_need_prompt_load_file(void); +extern grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size); +grub_err_t +grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, + char *argv[], void *target) +{ + grub_uint8_t *ptr = target; + int i; + int newc = 0; + struct dir *root = 0; + grub_ssize_t cursize = 0; + grub_ssize_t readsize = 0; + + for (i = 0; i < initrd_ctx->nfiles; i++) + { + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); + ptr += ALIGN_UP_OVERHEAD (cursize, 4); + + if (initrd_ctx->components[i].newc_name) + { + ptr += insert_dir (initrd_ctx->components[i].newc_name, + &root, ptr); + ptr = make_header (ptr, initrd_ctx->components[i].newc_name, + grub_strlen (initrd_ctx->components[i].newc_name), + 0100777, + initrd_ctx->components[i].size); + newc = 1; + } + else if (newc) + { + ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, + 0, 0); + free_dir (root); + root = 0; + newc = 0; + } + + cursize = initrd_ctx->components[i].size; + if (ventoy_need_prompt_load_file() && initrd_ctx->components[i].newc_name && + grub_strcmp(initrd_ctx->components[i].newc_name, "boot.wim") == 0) + { + readsize = ventoy_load_file_with_prompt(initrd_ctx->components[i].file, ptr, cursize); + } + else + { + readsize = grub_file_read (initrd_ctx->components[i].file, ptr, cursize); + } + + if (readsize != cursize) + { + if (!grub_errno) + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), + argv[i]); + grub_initrd_close (initrd_ctx); + return grub_errno; + } + ptr += cursize; + } + if (newc) + { + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); + ptr += ALIGN_UP_OVERHEAD (cursize, 4); + ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0); + } + free_dir (root); + root = 0; + return GRUB_ERR_NONE; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c index f5256408..6383c944 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c @@ -139,6 +139,9 @@ const char *g_menu_prefix[img_type_max] = "iso", "wim", "efi", "img", "vhd", "vtoy" }; +static int g_vtoy_load_prompt = 0; +static char g_vtoy_prompt_msg[64]; + static int ventoy_get_fs_type(const char *fs) { if (NULL == fs) @@ -1043,6 +1046,61 @@ static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc return 0; } +grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_vtoy_load_prompt = 0; + grub_memset(g_vtoy_prompt_msg, 0, sizeof(g_vtoy_prompt_msg)); + + if (argc == 2 && args[0][0] == '1') + { + g_vtoy_load_prompt = 1; + grub_snprintf(g_vtoy_prompt_msg, sizeof(g_vtoy_prompt_msg), "%s", args[1]); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_need_prompt_load_file(void) +{ + return g_vtoy_load_prompt; +} + +grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size) +{ + grub_uint64_t ro = 0; + grub_uint64_t div = 0; + grub_ssize_t left = size; + char *cur = (char *)buf; + + grub_printf("\r%s 1%% ", g_vtoy_prompt_msg); + grub_refresh(); + + while (left >= VTOY_SIZE_2MB) + { + grub_file_read(file, cur, VTOY_SIZE_2MB); + cur += VTOY_SIZE_2MB; + left -= VTOY_SIZE_2MB; + + div = grub_divmod64((grub_uint64_t)((size - left) * 100), (grub_uint64_t)size, &ro); + grub_printf("\r%s %d%% ", g_vtoy_prompt_msg, (int)div); + grub_refresh(); + } + + if (left > 0) + { + grub_file_read(file, cur, left); + } + + grub_printf("\r%s 100%% \n", g_vtoy_prompt_msg); + grub_refresh(); + + return size; +} + static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int argc, char **args) { int rc = 1; @@ -1089,7 +1147,14 @@ static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int ar return 1; } - grub_file_read(file, buf, file->size); + if (g_vtoy_load_prompt) + { + ventoy_load_file_with_prompt(file, buf, file->size); + } + else + { + grub_file_read(file, buf, file->size); + } grub_snprintf(name, sizeof(name), "%s_addr", args[2]); grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf); @@ -4507,6 +4572,7 @@ static cmd_para ventoy_cmds[] = { "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL }, { "vt_is_pe64", ventoy_cmd_is_pe64, 0, NULL, "", "", NULL }, { "vt_sel_wimboot", ventoy_cmd_sel_wimboot, 0, NULL, "", "", NULL }, + { "vt_set_wim_load_prompt", ventoy_cmd_set_wim_prompt, 0, NULL, "", "", NULL }, }; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h index 8e2527bf..37e46c19 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -29,6 +29,8 @@ #define VTOY_SIZE_1GB 1073741824 #define VTOY_SIZE_1MB (1024 * 1024) +#define VTOY_SIZE_2MB (2 * 1024 * 1024) +#define VTOY_SIZE_4MB (4 * 1024 * 1024) #define VTOY_SIZE_512KB (512 * 1024) #define VTOY_SIZE_1KB 1024 @@ -564,6 +566,9 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args); +grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size); +int ventoy_need_prompt_load_file(void); VTOY_JSON *vtoy_json_find_item ( diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index d62b71df..21b7116f 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -848,13 +848,14 @@ function vtoy_windows_wimboot_func { linux16 "$vtoy_path/$vt_wimkernel" quiet ventoy_debug_pause - echo Loading files...... (This may take a few minutes, please wait) + vt_set_wim_load_prompt 1 "Loading files......" initrd16 newc:vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe \ newc:wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \ newc:winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size} \ newc:bcd:$vtoy_wimboot_prefix/boot/bcd \ newc:boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi \ newc:boot.wim:$vtoy_wimboot_prefix/sources/boot.wim + vt_set_wim_load_prompt 0 boot else if [ "$grub_cpu" = "i386" ]; then @@ -863,8 +864,10 @@ function vtoy_windows_wimboot_func { set vt_wimkernel=wimboot.x86_64.xz fi - echo Loading files...... (This may take a few minutes, please wait) + vt_set_wim_load_prompt 1 "Loading files......" vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/sources/boot.wim vtoy_wimfile_mem + vt_set_wim_load_prompt 0 + if [ $? -eq 0 ]; then set vtoy_wimfile_path=mem:${vtoy_wimfile_mem_addr}:size:${vtoy_wimfile_mem_size} else @@ -1793,7 +1796,7 @@ function img_unsupport_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.43" +set VENTOY_VERSION="1.0.44" #ACPI not compatible with Window7/8, so disable by default set VTOY_PARAM_NO_ACPI=1