diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c index 00ebba52..b3cdcbcd 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c @@ -97,6 +97,24 @@ char *ventoy_str_last(char *str, char ch) return last; } +int ventoy_str_all_digit(const char *str) +{ + if (NULL == str || 0 == *str) + { + return 0; + } + + while (*str) + { + if (*str < '0' || *str > '9') + { + return 0; + } + } + + return 1; +} + int ventoy_strcmp(const char *pattern, const char *str) { while (*pattern && *str) 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 a5d692f2..eecc932d 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 @@ -483,7 +483,7 @@ static int ventoy_load_efiboot_template(char **buf, int *datalen, int *direntoff return 0; } -static int ventoy_set_check_result(int ret) +static int ventoy_set_check_result(int ret, const char *msg) { char buf[32]; @@ -497,7 +497,8 @@ static int ventoy_set_check_result(int ret) grub_printf(VTOY_WARNING"\n"); grub_printf(VTOY_WARNING"\n\n\n"); - grub_printf("This is NOT a standard Ventoy device and is NOT supported (%d).\n\n", ret); + grub_printf("This is NOT a standard Ventoy device and is NOT supported (%d).\n", ret); + grub_printf("Error message: <%s>\n\n", msg); grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n"); grub_printf("\n\nWill exit after 10 seconds ...... "); @@ -523,7 +524,7 @@ static int ventoy_check_official_device(grub_device_t dev) if (dev->disk == NULL || dev->disk->partition == NULL) { - return ventoy_set_check_result(1 | 0x1000); + return ventoy_set_check_result(1 | 0x1000, "Internal Error"); } if (0 == ventoy_check_file_exist("(%s,2)/ventoy/ventoy.cpio", dev->disk->name) || @@ -531,11 +532,17 @@ static int ventoy_check_official_device(grub_device_t dev) 0 == ventoy_check_file_exist("(%s,2)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) { #ifndef GRUB_MACHINE_EFI - if (0 == ventoy_check_file_exist("(ventoydisk)/ventoy/ventoy.cpio", dev->disk->name) || - 0 == ventoy_check_file_exist("(ventoydisk)/grub/localboot.cfg", dev->disk->name) || - 0 == ventoy_check_file_exist("(ventoydisk)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) + if (0 == ventoy_check_file_exist("(ventoydisk)/ventoy/ventoy.cpio", dev->disk->name)) { - return ventoy_set_check_result(2 | 0x1000); + return ventoy_set_check_result(2 | 0x1000, "File ventoy/ventoy.cpio missing in VTOYEFI partition"); + } + else if (0 == ventoy_check_file_exist("(ventoydisk)/grub/localboot.cfg", dev->disk->name)) + { + return ventoy_set_check_result(2 | 0x1000, "File grub/localboot.cfg missing in VTOYEFI partition"); + } + else if (0 == ventoy_check_file_exist("(ventoydisk)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) + { + return ventoy_set_check_result(2 | 0x1000, "File tool/mount.exfat-fuse_aarch64 missing in VTOYEFI partition"); } else { @@ -555,19 +562,19 @@ static int ventoy_check_official_device(grub_device_t dev) } if (!file) { - return ventoy_set_check_result(3 | 0x1000); + return ventoy_set_check_result(3 | 0x1000, "File ventoy/ventoy.cpio open failed in VTOYEFI partition"); } if (NULL == grub_strstr(file->fs->name, "fat")) { grub_file_close(file); - return ventoy_set_check_result(4 | 0x1000); + return ventoy_set_check_result(4 | 0x1000, "VTOYEFI partition is not FAT filesystem"); } partition = dev->disk->partition; if (partition->number != 0 || partition->start != 2048) { - return ventoy_set_check_result(5); + return ventoy_set_check_result(5, "Ventoy partition is not start at 1MB"); } if (workaround) @@ -579,7 +586,7 @@ static int ventoy_check_official_device(grub_device_t dev) (PartTbl[1].LastLBA + 1 - PartTbl[1].StartLBA) != 65536) { grub_file_close(file); - return ventoy_set_check_result(6); + return ventoy_set_check_result(6, "Disk partition layout check failed."); } } else @@ -589,7 +596,7 @@ static int ventoy_check_official_device(grub_device_t dev) PartTbl[1].SectorCount != 65536) { grub_file_close(file); - return ventoy_set_check_result(6); + return ventoy_set_check_result(6, "Disk partition layout check failed."); } } } @@ -600,7 +607,7 @@ static int ventoy_check_official_device(grub_device_t dev) if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start)) { grub_file_close(file); - return ventoy_set_check_result(7); + return ventoy_set_check_result(7, "Disk partition layout check failed."); } } @@ -612,21 +619,21 @@ static int ventoy_check_official_device(grub_device_t dev) dev2 = grub_device_open(devname); if (!dev2) { - return ventoy_set_check_result(8); + return ventoy_set_check_result(8, "Disk open failed"); } fs = grub_fs_probe(dev2); if (!fs) { grub_device_close(dev2); - return ventoy_set_check_result(9); + return ventoy_set_check_result(9, "FS probe failed"); } fs->fs_label(dev2, &label); if ((!label) || grub_strncmp("VTOYEFI", label, 7)) { grub_device_close(dev2); - return ventoy_set_check_result(10); + return ventoy_set_check_result(10, "Partition name is not VTOYEFI"); } grub_device_close(dev2); @@ -636,7 +643,7 @@ static int ventoy_check_official_device(grub_device_t dev) disk = grub_disk_open(dev->disk->name); if (!disk) { - return ventoy_set_check_result(11); + return ventoy_set_check_result(11, "Disk open failed"); } grub_memset(mbr, 0, 512); @@ -645,10 +652,10 @@ static int ventoy_check_official_device(grub_device_t dev) if (grub_memcmp(g_check_mbr_data, mbr, 0x30) || grub_memcmp(g_check_mbr_data + 0x30, mbr + 0x190, 16)) { - return ventoy_set_check_result(12); + return ventoy_set_check_result(12, "MBR check failed"); } - return ventoy_set_check_result(0); + return ventoy_set_check_result(0, NULL); } static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirhook_info *info, void *data) @@ -3367,58 +3374,19 @@ end: VENTOY_CMD_RETURN(GRUB_ERR_NONE); } -static int ventoy_is_builtin_var(const char *var) -{ - int i; - const char *c; - const char *builtin_vars_full[] = - { - "VT_DISK_1ST_NONVTOY", - "VT_DISK_1ST_NONUSB", - NULL - }; - - for (i = 0; builtin_vars_full[i]; i++) - { - if (grub_strcmp(builtin_vars_full[i], var) == 0) - { - return 1; - } - } - - if (grub_strncmp(var, "VT_DISK_CLOSEST_", 16) == 0) - { - c = var + 16; - while (*c) - { - if (*c < '0' || *c > '9') - { - break; - } - c++; - } - - if (*c == 0 && c != (var + 16)) - { - return 1; - } - } - - return 0; -} - -static int ventoy_var_expand(int *flag, const char *var, char *expand, int len) +static int ventoy_var_expand(int *record, int *flag, const char *var, char *expand, int len) { int i = 0; int n = 0; char c; const char *ch = var; + *record = 0; expand[0] = 0; while (*ch) { - if (*ch == '_' || (*ch >= '0' && *ch <= '9') || (*ch >= 'A' && *ch <= 'Z')) + if (*ch == '_' || (*ch >= '0' && *ch <= '9') || (*ch >= 'A' && *ch <= 'Z') || (*ch >= 'a' && *ch <= 'z')) { ch++; n++; @@ -3436,16 +3404,16 @@ static int ventoy_var_expand(int *flag, const char *var, char *expand, int len) goto end; } - if (ventoy_is_builtin_var(var)) + if (grub_strncmp(var, "VT_", 3) == 0) /* built-in variables */ { - + } else { if (*flag == 0) { *flag = 1; - grub_printf("\n=================== Parameter Expansion ===================\n\n"); + grub_printf("\n=================== Variables Expansion ===================\n\n"); } grub_printf("<%s>: ", var); @@ -3460,6 +3428,7 @@ static int ventoy_var_expand(int *flag, const char *var, char *expand, int len) { grub_printf("\n"); grub_refresh(); + *record = 1; break; } } @@ -3503,6 +3472,7 @@ static int ventoy_auto_install_var_expand(install_template *node) { int pos = 0; int flag = 0; + int record = 0; int newlen = 0; char *start = NULL; char *end = NULL; @@ -3511,6 +3481,8 @@ static int ventoy_auto_install_var_expand(install_template *node) char *nextline = NULL; grub_uint8_t *code = NULL; char value[512]; + var_node *CurNode = NULL; + var_node *pVarList = NULL; code = (grub_uint8_t *)node->filebuf; @@ -3563,8 +3535,33 @@ static int ventoy_auto_install_var_expand(install_template *node) *start = *end = 0; VTOY_APPEND_NEWBUF(curline); - value[sizeof(value) - 1] = 0; - ventoy_var_expand(&flag, start + 2, value, sizeof(value) - 1); + for (CurNode = pVarList; CurNode; CurNode = CurNode->next) + { + if (grub_strcmp(start + 2, CurNode->var) == 0) + { + grub_snprintf(value, sizeof(value) - 1, "%s", CurNode->val); + break; + } + } + + if (!CurNode) + { + value[sizeof(value) - 1] = 0; + ventoy_var_expand(&record, &flag, start + 2, value, sizeof(value) - 1); + + if (record) + { + CurNode = grub_zalloc(sizeof(var_node)); + if (CurNode) + { + grub_snprintf(CurNode->var, sizeof(CurNode->var), "%s", start + 2); + grub_snprintf(CurNode->val, sizeof(CurNode->val), "%s", value); + CurNode->next = pVarList; + pVarList = CurNode; + } + } + } + VTOY_APPEND_NEWBUF(value); VTOY_APPEND_NEWBUF(end + 2); @@ -3573,14 +3570,28 @@ static int ventoy_auto_install_var_expand(install_template *node) { VTOY_APPEND_NEWBUF(curline); } - - newbuf[pos++] = '\n'; + + if (pos > 0 && newbuf[pos - 1] == '\r') + { + newbuf[pos - 1] = '\n'; + } + else + { + newbuf[pos++] = '\n'; + } } grub_free(node->filebuf); node->filebuf = newbuf; node->filelen = pos; + while (pVarList) + { + CurNode = pVarList->next; + grub_free(pVarList); + pVarList = CurNode; + } + return 0; } 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 3ce2374f..3462c5e5 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 @@ -601,6 +601,7 @@ typedef struct chk_case_fs_dir grub_fs_t fs; }chk_case_fs_dir; +int ventoy_str_all_digit(const char *str); int ventoy_strcmp(const char *pattern, const char *str); int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n); void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param); @@ -1208,6 +1209,14 @@ typedef struct browser_node struct browser_node *next; }browser_node; +typedef struct var_node +{ + char var[128]; + char val[256]; + + struct var_node *next; +}var_node; + extern char *g_tree_script_buf; extern int g_tree_script_pos; extern int g_tree_script_pre; diff --git a/IMG/cpio/ventoy/hook/debian/disk_mount_hook.sh b/IMG/cpio/ventoy/hook/debian/disk_mount_hook.sh index 8fa19a41..4e00b8f1 100644 --- a/IMG/cpio/ventoy/hook/debian/disk_mount_hook.sh +++ b/IMG/cpio/ventoy/hook/debian/disk_mount_hook.sh @@ -34,3 +34,7 @@ fi vtlog "${vtdiskname#/dev/}2 found..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/udev_disk_hook.sh "${vtdiskname#/dev/}2" + +if [ -f /ventoy/autoinstall ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall +fi diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-cloud-init.sh b/IMG/cpio/ventoy/hook/debian/ventoy-cloud-init.sh index 875b496e..0663f988 100644 --- a/IMG/cpio/ventoy/hook/debian/ventoy-cloud-init.sh +++ b/IMG/cpio/ventoy/hook/debian/ventoy-cloud-init.sh @@ -44,10 +44,15 @@ if [ $vtSplit -eq 1 ]; then vtlog "Line number: $vtLine $vtLine1 $vtLine2" sed -n "1,${vtLine1}p" $VTOY_PATH/autoinstall >/tmpcidata/user-data sed -n "${vtLine2},\$p" $VTOY_PATH/autoinstall >/tmpcidata/meta-data + + sh /ventoy/hook/default/auto_install_varexp.sh /tmpcidata/user-data + sh /ventoy/hook/default/auto_install_varexp.sh /tmpcidata/meta-data else vtlog "only user-data avaliable" cp -a $VTOY_PATH/autoinstall /tmpcidata/user-data touch /tmpcidata/meta-data + + sh /ventoy/hook/default/auto_install_varexp.sh /tmpcidata/user-data fi diff --git a/IMG/cpio/ventoy/hook/default/auto_install_varexp.sh b/IMG/cpio/ventoy/hook/default/auto_install_varexp.sh new file mode 100644 index 00000000..af01d4e2 --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/auto_install_varexp.sh @@ -0,0 +1,53 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +PATH=$PATH:/ventoy/busybox:/ventoy/tool + +vlog() { + echo "$@" >> /ventoy/autoinstall.log +} + +if grep -q '\$\$VT_' /ventoy/autoinstall; then + vlog "======== auto install variables expansion =======" +else + vlog "======== auto install variables expansion no need =======" + exit 0 +fi + +if [ -f /ventoy/ventoy_os_param ]; then + VTOYDISK=$(vtoydump -f /ventoy/ventoy_os_param | awk -F'#' '{print $1}') + vlog VTOYDISK=$VTOYDISK + + if [ -b "$VTOYDISK" ]; then + vlog "$VTOYDISK exist OK" + else + vlog "$VTOYDISK does NOT exist" + exit 0 + fi + + if [ -n "$1" -a -f "$1" ]; then + vtoyexpand "$1" "$VTOYDISK" + else + vlog "File $1 not exist" + fi +else + vlog "os param file not exist" + exit 0 +fi + diff --git a/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh index cfbe43fb..c3c33b6a 100644 --- a/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh @@ -29,10 +29,12 @@ ventoy_add_kernel_udev_rule "loop6" "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k" if [ -f $VTOY_PATH/autoinstall ]; then $BUSYBOX_PATH/mv /sbin/loader /sbin/loader_bk - $BUSYBOX_PATH/mv $VTOY_PATH/tool/loader /sbin/loader + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/loader /sbin/loader RawCmdLine=$($BUSYBOX_PATH/cat /proc/cmdline) echo -n "/sbin/loader_bk" > "/ventoy/loader_exec_file" echo -n "--cmdline=$RawCmdLine ks=file:$VTOY_PATH/autoinstall" > "/ventoy/loader_exec_cmdline" #echo 111 > "/ventoy/loader_debug" + + echo "/bin/sh /ventoy/hook/rhel6/ventoy-varexp.sh" > "/ventoy/loader_hook_cmd" fi diff --git a/IMG/cpio/ventoy/hook/rhel6/ventoy-varexp.sh b/IMG/cpio/ventoy/hook/rhel6/ventoy-varexp.sh new file mode 100644 index 00000000..99c23a2d --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel6/ventoy-varexp.sh @@ -0,0 +1,37 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +PATH=$PATH:/ventoy/busybox:/ventoy/tool + +if grep -q '\$\$VT_' /ventoy/autoinstall; then + : +else + exit 0 +fi + +if [ -f /sbin/hald ]; then + mv /sbin/hald /sbin/hald_bk + cp -a /ventoy/tool/hald /sbin/hald + + rm -f "/ventoy/loader_exec_cmdline" + echo "/bin/sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall" > "/ventoy/loader_hook_cmd" + echo -n "/sbin/hald_bk" > "/ventoy/loader_exec_file" +fi + +exit 0 diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh new file mode 100644 index 00000000..661d4365 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh @@ -0,0 +1,24 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2022, longpanda +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +#************************************************************************************ + +if [ -f /run/install/ks.cfg ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /run/install/ks.cfg +fi + +exit 0 diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh index 271c38a8..bc5bc5eb 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh @@ -128,3 +128,6 @@ if [ -e /usr/sbin/anaconda-diskroot ]; then $SED 's/^mount $dev $repodir/mount -oro $dev $repodir/' -i /usr/sbin/anaconda-diskroot fi +if [ -f $VTOY_PATH/autoinstall ]; then + cp -a $VTOY_PATH/hook/rhel7/ventoy-autoexp.sh /lib/dracut/hooks/pre-mount/99-ventoy-autoexp.sh +fi diff --git a/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh b/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh index ff796664..d222f668 100644 --- a/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh +++ b/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh @@ -40,3 +40,11 @@ fi if $GREP -q 'mediacheck=1' /proc/cmdline; then ventoy_copy_device_mapper "${vtdiskname}" fi + +if [ -f /ventoy/autoinstall ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /ventoy/autoinstall +fi +if [ -f /autoinst.xml ]; then + sh /ventoy/hook/default/auto_install_varexp.sh /autoinst.xml +fi + diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 48e45507..b232262c 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -185,7 +185,7 @@ function locate_initrd { } function locate_wim { - vt_windows_locate_wim_patch (loop) + vt_windows_locate_wim_patch (loop) "$1" if [ -n "${vtdebug_flag}" ]; then echo '###############################################' @@ -615,7 +615,7 @@ function uefi_windows_menu_func { fi ventoy_debug_pause - locate_wim + locate_wim "${chosen_path}" fi vt_windows_chain_data "${1}${chosen_path}" @@ -1044,7 +1044,7 @@ function legacy_windows_menu_func { fi ventoy_debug_pause - locate_wim + locate_wim "${chosen_path}" fi vt_windows_chain_data "${1}${chosen_path}" @@ -2145,7 +2145,7 @@ function img_unsupport_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.76" +set VENTOY_VERSION="1.0.77" #ACPI not compatible with Window7/8, so disable by default set VTOY_PARAM_NO_ACPI=1 diff --git a/INSTALL/ventoy/vtoyjump32.exe b/INSTALL/ventoy/vtoyjump32.exe index 6a3f12d1..b21b2c0d 100644 Binary files a/INSTALL/ventoy/vtoyjump32.exe and b/INSTALL/ventoy/vtoyjump32.exe differ diff --git a/INSTALL/ventoy/vtoyjump64.exe b/INSTALL/ventoy/vtoyjump64.exe index 5ffe4955..6681a03f 100644 Binary files a/INSTALL/ventoy/vtoyjump64.exe and b/INSTALL/ventoy/vtoyjump64.exe differ diff --git a/VtoyTool/vtoyexpand.c b/VtoyTool/vtoyexpand.c new file mode 100644 index 00000000..c0a15d37 --- /dev/null +++ b/VtoyTool/vtoyexpand.c @@ -0,0 +1,554 @@ +/****************************************************************************** + * vtoyexpand.c ---- ventoy auto install script variable expansion + * + * Copyright (c) 2022, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vtoytool.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define TMP_FILE "/ventoy/tmp_var_expansion" + +#define SIZE_1MB (1024 * 1024) +#define ulong unsigned long +#define ulonglong unsigned long long + +typedef struct disk_info +{ + char name[128]; + ulonglong size; + int isUSB; + int isSDX; +}disk_info; + +static disk_info *g_disk_list = NULL; +static int g_disk_num = 0; +static const char *g_vtoy_disk_name = NULL; + +static void vlog(const char *fmt, ...) +{ + int n = 0; + va_list arg; + FILE *fp = NULL; + char log[1024]; + + fp = fopen("/ventoy/autoinstall.log", "a+"); + if (fp) + { + va_start(arg, fmt); + n += vsnprintf(log, sizeof(log) - 1, fmt, arg); + va_end(arg); + + fwrite(log, 1, n, fp); + fclose(fp); + } +} + +static int copy_file(const char *file1, const char *file2) +{ + int n; + int size; + int ret = 1; + FILE *fp1 = NULL; + FILE *fp2 = NULL; + char *buf = NULL; + + fp1 = fopen(file1, "rb"); + if (!fp1) + { + vlog("Failed to read file <%s>\n", file1); + goto end; + } + + fp2 = fopen(file2, "wb+"); + if (!fp2) + { + vlog("Failed to create file <%s>\n", file2); + goto end; + } + + fseek(fp1, 0, SEEK_END); + size = (int)ftell(fp1); + fseek(fp1, 0, SEEK_SET); + + buf = malloc(size); + if (!buf) + { + vlog("Failed to malloc buf\n"); + goto end; + } + + n = fread(buf, 1, size, fp1); + if (n != size) + { + vlog("Failed to read <%s> %d %d\n", file1, n, size); + goto end; + } + + n = fwrite(buf, 1, size, fp2); + if (n != size) + { + vlog("Failed to write <%s> %d %d\n", file2, n, size); + goto end; + } + + ret = 0; + +end: + + if (fp1) + fclose(fp1); + if (fp2) + fclose(fp2); + if (buf) + free(buf); + + return ret; +} + +static int vtoy_is_possible_blkdev(const char *name) +{ + if (name[0] == '.') + { + return 0; + } + + /* /dev/ramX */ + if (name[0] == 'r' && name[1] == 'a' && name[2] == 'm') + { + return 0; + } + + /* /dev/loopX */ + if (name[0] == 'l' && name[1] == 'o' && name[2] == 'o' && name[3] == 'p') + { + return 0; + } + + /* /dev/dm-X */ + if (name[0] == 'd' && name[1] == 'm' && name[2] == '-' && IS_DIGIT(name[3])) + { + return 0; + } + + /* /dev/srX */ + if (name[0] == 's' && name[1] == 'r' && (name[2] >= '0' && name[2] <= '9')) + { + return 0; + } + + return 1; +} + +static ulonglong vtoy_get_disk_size_in_byte(const char *disk) +{ + int fd; + int rc; + unsigned long long size = 0; + char diskpath[256] = {0}; + char sizebuf[64] = {0}; + + // Try 1: get size from sysfs + snprintf(diskpath, sizeof(diskpath) - 1, "/sys/block/%s/size", disk); + if (access(diskpath, F_OK) >= 0) + { + vlog("get disk size from sysfs for %s\n", disk); + + fd = open(diskpath, O_RDONLY | O_BINARY); + if (fd >= 0) + { + read(fd, sizebuf, sizeof(sizebuf)); + size = strtoull(sizebuf, NULL, 10); + close(fd); + return (size * 512); + } + } + else + { + vlog("%s not exist \n", diskpath); + } + + // Try 2: get size from ioctl + snprintf(diskpath, sizeof(diskpath) - 1, "/dev/%s", disk); + fd = open(diskpath, O_RDONLY); + if (fd >= 0) + { + vlog("get disk size from ioctl for %s\n", disk); + rc = ioctl(fd, BLKGETSIZE64, &size); + if (rc == -1) + { + size = 0; + vlog("failed to ioctl %d\n", rc); + } + close(fd); + } + else + { + vlog("failed to open %s %d\n", diskpath, errno); + } + + vlog("disk %s size %llu bytes\n", disk, (ulonglong)size); + return size; +} + +static int get_disk_num(void) +{ + int n = 0; + DIR* dir = NULL; + struct dirent* p = NULL; + + dir = opendir("/sys/block"); + if (!dir) + { + return 0; + } + + while ((p = readdir(dir)) != NULL) + { + n++; + } + closedir(dir); + + return n; +} + +static int is_usb_disk(const char *diskname) +{ + int rc; + char dstpath[1024] = { 0 }; + char syspath[1024] = { 0 }; + + snprintf(syspath, sizeof(syspath), "/sys/block/%s", diskname); + rc = readlink(syspath, dstpath, sizeof(dstpath) - 1); + if (rc > 0 && strstr(dstpath, "/usb")) + { + return 1; + } + + return 0; +} + +static int get_all_disk(void) +{ + int i = 0; + int j = 0; + int num = 0; + ulonglong cursize = 0; + DIR* dir = NULL; + struct dirent* p = NULL; + disk_info *node = NULL; + disk_info tmpnode; + + num = get_disk_num(); + if (num <= 0) + { + return 1; + } + + g_disk_list = malloc(num * sizeof(disk_info)); + if (!g_disk_list) + { + return 1; + } + memset(g_disk_list, 0, num * sizeof(disk_info)); + + dir = opendir("/sys/block"); + if (!dir) + { + return 0; + } + + while (((p = readdir(dir)) != NULL) && g_disk_num < num) + { + if (!vtoy_is_possible_blkdev(p->d_name)) + { + vlog("disk %s is filted by name\n", p->d_name); + continue; + } + + cursize = vtoy_get_disk_size_in_byte(p->d_name); + + node = g_disk_list + g_disk_num; + g_disk_num++; + + + snprintf(node->name, sizeof(node->name), p->d_name); + node->size = cursize; + node->isUSB = is_usb_disk(p->d_name); + if (strncmp(node->name, "sd", 2) == 0) + { + node->isSDX = 1; + } + } + closedir(dir); + + /* sort disks */ + for (i = 0; i < g_disk_num; i++) + { + for (j = i + 1; j < g_disk_num; j++) + { + if (g_disk_list[i].isSDX && g_disk_list[j].isSDX) + { + if (strcmp(g_disk_list[i].name, g_disk_list[j].name) > 0) + { + memcpy(&tmpnode, g_disk_list + i, sizeof(tmpnode)); + memcpy(g_disk_list + i, g_disk_list + j, sizeof(tmpnode)); + memcpy(g_disk_list + j, &tmpnode, sizeof(tmpnode)); + } + } + } + } + + vlog("============ DISK DUMP BEGIN ===========\n"); + for (i = 0; i < g_disk_num; i++) + { + node = g_disk_list + i; + vlog("[%d] %s %dGB(%llu) USB:%d\n", i, node->name, + node->size / 1024 / 1024 / 1024, node->size, node->isUSB); + } + vlog("============ DISK DUMP END ===========\n"); + + return 0; +} + +static int expand_var(const char *var, char *value, int len) +{ + int i; + int index = -1; + ulonglong uiDst = 0; + ulonglong delta = 0; + ulonglong maxsize = 0; + ulonglong maxdelta = 0xFFFFFFFFFFFFFFFFULL; + disk_info *node = NULL; + value[0] = 0; + + if (strcmp(var, "VT_LINUX_DISK_SDX_1ST_NONVTOY") == 0) + { + for (i = 0; i < g_disk_num; i++) + { + node = g_disk_list + i; + if (node->size > 0 && node->isSDX && strcmp(node->name, g_vtoy_disk_name) != 0) + { + vlog("%s=<%s>\n", var, node->name); + snprintf(value, len, "%s", node->name); + return 0; + } + } + + vlog("[Error] %s not found\n", var); + } + else if (strcmp(var, "VT_LINUX_DISK_SDX_1ST_NONUSB") == 0) + { + for (i = 0; i < g_disk_num; i++) + { + node = g_disk_list + i; + if (node->size > 0 && node->isSDX && node->isUSB == 0) + { + vlog("%s=<%s>\n", var, node->name); + snprintf(value, len, "%s", node->name); + return 0; + } + } + + vlog("[Error] %s not found\n", var); + } + else if (strcmp(var, "VT_LINUX_DISK_MAX_SIZE") == 0) + { + for (i = 0; i < g_disk_num; i++) + { + node = g_disk_list + i; + if (node->size > 0 && node->size > maxsize) + { + index = i; + maxsize = node->size; + } + } + + if (index >= 0) + { + vlog("%s=<%s>\n", var, g_disk_list[index].name); + snprintf(value, len, "%s", g_disk_list[index].name); + return 0; + } + else + { + vlog("[Error] %s not found\n", var); + } + } + else if (strncmp(var, "VT_LINUX_DISK_CLOSEST_", 22) == 0) + { + uiDst = strtoul(var + 22, NULL, 10); + uiDst = uiDst * (1024ULL * 1024ULL * 1024ULL); + + for (i = 0; i < g_disk_num; i++) + { + node = g_disk_list + i; + if (node->size == 0) + { + continue; + } + + if (node->size > uiDst) + { + delta = node->size - uiDst; + } + else + { + delta = uiDst - node->size; + } + + if (delta < maxdelta) + { + index = i; + maxdelta = delta; + } + } + + if (index >= 0) + { + vlog("%s=<%s>\n", var, g_disk_list[index].name); + snprintf(value, len, "%s", g_disk_list[index].name); + return 0; + } + else + { + vlog("[Error] %s not found\n", var); + } + } + else + { + vlog("Invalid var name <%s>\n", var); + snprintf(value, len, "$$%s$$", var); + } + + if (value[0] == 0) + { + snprintf(value, len, "$$%s$$", var); + } + + return 0; +} + +int vtoyexpand_main(int argc, char **argv) +{ + FILE *fp = NULL; + FILE *fout = NULL; + char *start = NULL; + char *end = NULL; + char line[4096]; + char value[256]; + + vlog("========= vtoyexpand_main %d ========\n", argc); + + if (argc != 3) + { + return 1; + } + + g_vtoy_disk_name = argv[2]; + if (strncmp(g_vtoy_disk_name, "/dev/", 5) == 0) + { + g_vtoy_disk_name += 5; + } + vlog("<%s> <%s> <%s>\n", argv[1], argv[2], g_vtoy_disk_name); + + get_all_disk(); + + fp = fopen(argv[1], "r"); + if (!fp) + { + vlog("Failed to open file <%s>\n", argv[1]); + return 1; + } + + fout = fopen(TMP_FILE, "w+"); + if (!fout) + { + vlog("Failed to create file <%s>\n", TMP_FILE); + fclose(fp); + return 1; + } + + memset(line, 0, sizeof(line)); + memset(value, 0, sizeof(value)); + + while (fgets(line, sizeof(line), fp)) + { + start = strstr(line, "$$VT_"); + if (start) + { + end = strstr(start + 5, "$$"); + } + + if (start && end) + { + *start = 0; + fprintf(fout, "%s", line); + + *end = 0; + expand_var(start + 2, value, sizeof(value)); + fprintf(fout, "%s", value); + + fprintf(fout, "%s", end + 2); + + memset(value, 0, sizeof(value)); + } + else + { + fprintf(fout, "%s", line); + } + + line[0] = line[4095] = 0; + } + + fclose(fp); + fclose(fout); + + vlog("delete file <%s>\n", argv[1]); + remove(argv[1]); + + vlog("Copy file <%s> --> <%s>\n", TMP_FILE, argv[1]); + copy_file(TMP_FILE, argv[1]); + + return 0; +} + +// wrapper main +#ifndef BUILD_VTOY_TOOL +int main(int argc, char **argv) +{ + return vtoyexpand_main(argc, argv); +} +#endif + diff --git a/VtoyTool/vtoyloader.c b/VtoyTool/vtoyloader.c index 0272d7f2..3db190bc 100644 --- a/VtoyTool/vtoyloader.c +++ b/VtoyTool/vtoyloader.c @@ -91,10 +91,6 @@ int vtoyloader_main(int argc, char **argv) { rc = vtoy_read_file_to_buf(HOOK_CMD_FILE, g_hook_cmd, sizeof(g_hook_cmd) - 1); debug("g_hook_cmd=<%s>\n", g_hook_cmd); - - // call hook script - rc = system(g_hook_cmd); - debug("system return code =<%d> errno=<%d>\n", rc, errno); } cmdline = (char *)malloc(CMDLINE_BUF_LEN); @@ -156,6 +152,13 @@ int vtoyloader_main(int argc, char **argv) debug("execv [%s]...\n", cmdlist[0]); + // call hook script + if (g_hook_cmd[0]) + { + rc = system(g_hook_cmd); + debug("system return code =<%d> errno=<%d>\n", rc, errno); + } + execv(cmdlist[0], cmdlist); return 0; diff --git a/VtoyTool/vtoytool.c b/VtoyTool/vtoytool.c index f6896860..48cd9ff3 100644 --- a/VtoyTool/vtoytool.c +++ b/VtoyTool/vtoytool.c @@ -38,6 +38,7 @@ int vtoyloader_main(int argc, char **argv); int vtoyvine_main(int argc, char **argv); int vtoyksym_main(int argc, char **argv); int vtoykmod_main(int argc, char **argv); +int vtoyexpand_main(int argc, char **argv); static char *g_vtoytool_name = NULL; static cmd_def g_cmd_list[] = @@ -46,8 +47,10 @@ static cmd_def g_cmd_list[] = { "vtoydump", vtoydump_main }, { "vtoydm", vtoydm_main }, { "loader", vtoyloader_main }, + { "hald", vtoyloader_main }, { "vtoyksym", vtoyksym_main }, { "vtoykmod", vtoykmod_main }, + { "vtoyexpand", vtoyexpand_main }, { "--install", vtoytool_install }, }; diff --git a/VtoyTool/vtoytool/00/vtoytool_32 b/VtoyTool/vtoytool/00/vtoytool_32 index 2f024861..90da6ce4 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_32 and b/VtoyTool/vtoytool/00/vtoytool_32 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_64 b/VtoyTool/vtoytool/00/vtoytool_64 index 51a0b16f..0c04940e 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_64 and b/VtoyTool/vtoytool/00/vtoytool_64 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_aa64 b/VtoyTool/vtoytool/00/vtoytool_aa64 index 7af30d5f..fc34a6c7 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_aa64 and b/VtoyTool/vtoytool/00/vtoytool_aa64 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_m64e b/VtoyTool/vtoytool/00/vtoytool_m64e index c7b3ccaf..d2047dd7 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_m64e and b/VtoyTool/vtoytool/00/vtoytool_m64e differ diff --git a/vtoyjump/vtoyjump/vtoyjump.c b/vtoyjump/vtoyjump/vtoyjump.c index 81f5b0db..82421608 100644 --- a/vtoyjump/vtoyjump/vtoyjump.c +++ b/vtoyjump/vtoyjump/vtoyjump.c @@ -36,6 +36,8 @@ static ventoy_guid g_ventoy_guid = VENTOY_GUID; static HANDLE g_vtoylog_mutex = NULL; static HANDLE g_vtoyins_mutex = NULL; +static DWORD g_vtoy_disk_drive; + static CHAR g_prog_full_path[MAX_PATH]; static CHAR g_prog_dir[MAX_PATH]; static CHAR g_prog_name[MAX_PATH]; @@ -760,7 +762,7 @@ static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL); if (bRet == FALSE || dwSize != ReadSize) { - Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, GetLastError()); + Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u", bRet, ReadSize, dwSize, GetLastError()); } return 1; @@ -1291,12 +1293,485 @@ End: return rc; } +static int UnattendNeedVarExpand(const char *script) +{ + FILE *fp = NULL; + char szLine[4096]; + + fopen_s(&fp, script, "r"); + if (!fp) + { + return 0; + } + + szLine[0] = szLine[4095] = 0; + + while (fgets(szLine, sizeof(szLine) - 1, fp)) + { + if (strstr(szLine, "$$VT_")) + { + fclose(fp); + return 1; + } + + szLine[0] = szLine[4095] = 0; + } + + fclose(fp); + return 0; +} + +static int ExpandSingleVar(VarDiskInfo *pDiskInfo, int DiskNum, const char *var, char *value, int len) +{ + int i; + int index = -1; + UINT64 uiDst = 0; + UINT64 uiDelta = 0; + UINT64 uiMaxSize = 0; + UINT64 uiMaxDelta = ULLONG_MAX; + + value[0] = 0; + + if (strcmp(var, "VT_WINDOWS_DISK_1ST_NONVTOY") == 0) + { + for (i = 0; i < DiskNum; i++) + { + if (pDiskInfo[i].Capacity > 0 && i != g_vtoy_disk_drive) + { + Log("%s=", var, i); + sprintf_s(value, len, "%d", i); + return 0; + } + } + } + else if (strcmp(var, "VT_WINDOWS_DISK_1ST_NONUSB") == 0) + { + for (i = 0; i < DiskNum; i++) + { + if (pDiskInfo[i].Capacity > 0 && pDiskInfo[i].BusType != BusTypeUsb) + { + Log("%s=", var, i); + sprintf_s(value, len, "%d", i); + return 0; + } + } + } + else if (strcmp(var, "VT_WINDOWS_DISK_MAX_SIZE") == 0) + { + for (i = 0; i < DiskNum; i++) + { + if (pDiskInfo[i].Capacity > 0 && pDiskInfo[i].Capacity > uiMaxSize) + { + index = i; + uiMaxSize = pDiskInfo[i].Capacity; + } + } + + Log("%s=", var, index); + sprintf_s(value, len, "%d", index); + } + else if (strncmp(var, "VT_WINDOWS_DISK_CLOSEST_", 24) == 0) + { + uiDst = strtoul(var + 24, NULL, 10); + uiDst = uiDst * (1024ULL * 1024ULL * 1024ULL); + + for (i = 0; i < DiskNum; i++) + { + if (pDiskInfo[i].Capacity == 0) + { + continue; + } + + if (pDiskInfo[i].Capacity > uiDst) + { + uiDelta = pDiskInfo[i].Capacity - uiDst; + } + else + { + uiDelta = uiDst - pDiskInfo[i].Capacity; + } + + if (uiDelta < uiMaxDelta) + { + uiMaxDelta = uiDelta; + index = i; + } + } + + Log("%s=", var, index); + sprintf_s(value, len, "%d", index); + } + else + { + Log("Invalid var name <%s>", var); + sprintf_s(value, len, "$$%s$$", var); + } + + if (value[0] == 0) + { + sprintf_s(value, len, "$$%s$$", var); + } + + return 0; +} + +static void TrimString(CHAR *String) +{ + CHAR *Pos1 = String; + CHAR *Pos2 = String; + size_t Len = strlen(String); + + while (Len > 0) + { + if (String[Len - 1] != ' ' && String[Len - 1] != '\t') + { + break; + } + String[Len - 1] = 0; + Len--; + } + + while (*Pos1 == ' ' || *Pos1 == '\t') + { + Pos1++; + } + + while (*Pos1) + { + *Pos2++ = *Pos1++; + } + *Pos2++ = 0; + + return; +} + +static int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue) +{ + HKEY hKey; + DWORD Type; + DWORD Size; + LSTATUS lRet; + DWORD Value; + + lRet = RegOpenKeyExA(Key, SubKey, 0, KEY_QUERY_VALUE, &hKey); + Log("RegOpenKeyExA <%s> Ret:%ld", SubKey, lRet); + + if (ERROR_SUCCESS == lRet) + { + Size = sizeof(Value); + lRet = RegQueryValueExA(hKey, ValueName, NULL, &Type, (LPBYTE)&Value, &Size); + Log("RegQueryValueExA <%s> ret:%u Size:%u Value:%u", ValueName, lRet, Size, Value); + + *pValue = Value; + RegCloseKey(hKey); + + return 0; + } + else + { + return 1; + } +} + +static const CHAR * GetBusTypeString(int Type) +{ + switch (Type) + { + case BusTypeUnknown: return "unknown"; + case BusTypeScsi: return "SCSI"; + case BusTypeAtapi: return "Atapi"; + case BusTypeAta: return "ATA"; + case BusType1394: return "1394"; + case BusTypeSsa: return "SSA"; + case BusTypeFibre: return "Fibre"; + case BusTypeUsb: return "USB"; + case BusTypeRAID: return "RAID"; + case BusTypeiScsi: return "iSCSI"; + case BusTypeSas: return "SAS"; + case BusTypeSata: return "SATA"; + case BusTypeSd: return "SD"; + case BusTypeMmc: return "MMC"; + case BusTypeVirtual: return "Virtual"; + case BusTypeFileBackedVirtual: return "FileBackedVirtual"; + case BusTypeSpaces: return "Spaces"; + case BusTypeNvme: return "Nvme"; + } + return "unknown"; +} + +static int GetHumanReadableGBSize(UINT64 SizeBytes) +{ + int i; + int Pow2 = 1; + double Delta; + double GB = SizeBytes * 1.0 / 1000 / 1000 / 1000; + + if ((SizeBytes % 1073741824) == 0) + { + return (int)(SizeBytes / 1073741824); + } + + for (i = 0; i < 12; i++) + { + if (Pow2 > GB) + { + Delta = (Pow2 - GB) / Pow2; + } + else + { + Delta = (GB - Pow2) / Pow2; + } + + if (Delta < 0.05) + { + return Pow2; + } + + Pow2 <<= 1; + } + + return (int)GB; +} + +static int EnumerateAllDisk(VarDiskInfo **ppDiskInfo, int *pDiskNum) +{ + int i; + DWORD Value; + int DiskNum = 0; + BOOL bRet; + DWORD dwBytes; + VarDiskInfo *pDiskInfo = NULL; + HANDLE Handle = INVALID_HANDLE_VALUE; + CHAR PhyDrive[128]; + GET_LENGTH_INFORMATION LengthInfo; + STORAGE_PROPERTY_QUERY Query; + STORAGE_DESCRIPTOR_HEADER DevDescHeader; + STORAGE_DEVICE_DESCRIPTOR *pDevDesc; + + if (GetRegDwordValue(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", "Count", &Value) == 0) + { + DiskNum = (int)Value; + } + else + { + Log("Failed to read disk count"); + return 1; + } + + Log("Current phy disk count:%d", DiskNum); + if (DiskNum <= 0) + { + return 1; + } + + pDiskInfo = malloc(DiskNum * sizeof(VarDiskInfo)); + if (!pDiskInfo) + { + Log("Failed to alloc"); + return 1; + } + memset(pDiskInfo, 0, DiskNum * sizeof(VarDiskInfo)); + + for (i = 0; i < DiskNum; i++) + { + SAFE_CLOSE_HANDLE(Handle); + + safe_sprintf(PhyDrive, "\\\\.\\PhysicalDrive%d", i); + Handle = CreateFileA(PhyDrive, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + Log("Create file Handle:%p %s status:%u", Handle, PhyDrive, LASTERR); + + if (Handle == INVALID_HANDLE_VALUE) + { + continue; + } + + bRet = DeviceIoControl(Handle, + IOCTL_DISK_GET_LENGTH_INFO, NULL, + 0, + &LengthInfo, + sizeof(LengthInfo), + &dwBytes, + NULL); + if (!bRet) + { + Log("DeviceIoControl IOCTL_DISK_GET_LENGTH_INFO failed error:%u", LASTERR); + continue; + } + + Log("PHYSICALDRIVE%d size %llu bytes", i, (ULONGLONG)LengthInfo.Length.QuadPart); + + Query.PropertyId = StorageDeviceProperty; + Query.QueryType = PropertyStandardQuery; + + bRet = DeviceIoControl(Handle, + IOCTL_STORAGE_QUERY_PROPERTY, + &Query, + sizeof(Query), + &DevDescHeader, + sizeof(STORAGE_DESCRIPTOR_HEADER), + &dwBytes, + NULL); + if (!bRet) + { + Log("DeviceIoControl1 error:%u dwBytes:%u", LASTERR, dwBytes); + continue; + } + + if (DevDescHeader.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR)) + { + Log("Invalid DevDescHeader.Size:%u", DevDescHeader.Size); + continue; + } + + pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(DevDescHeader.Size); + if (!pDevDesc) + { + Log("failed to malloc error:%u len:%u", LASTERR, DevDescHeader.Size); + continue; + } + + bRet = DeviceIoControl(Handle, + IOCTL_STORAGE_QUERY_PROPERTY, + &Query, + sizeof(Query), + pDevDesc, + DevDescHeader.Size, + &dwBytes, + NULL); + if (!bRet) + { + Log("DeviceIoControl2 error:%u dwBytes:%u", LASTERR, dwBytes); + free(pDevDesc); + continue; + } + + pDiskInfo[i].RemovableMedia = pDevDesc->RemovableMedia; + pDiskInfo[i].BusType = pDevDesc->BusType; + pDiskInfo[i].DeviceType = pDevDesc->DeviceType; + pDiskInfo[i].Capacity = LengthInfo.Length.QuadPart; + + if (pDevDesc->VendorIdOffset) + { + safe_strcpy(pDiskInfo[i].VendorId, (char *)pDevDesc + pDevDesc->VendorIdOffset); + TrimString(pDiskInfo[i].VendorId); + } + + if (pDevDesc->ProductIdOffset) + { + safe_strcpy(pDiskInfo[i].ProductId, (char *)pDevDesc + pDevDesc->ProductIdOffset); + TrimString(pDiskInfo[i].ProductId); + } + + if (pDevDesc->ProductRevisionOffset) + { + safe_strcpy(pDiskInfo[i].ProductRev, (char *)pDevDesc + pDevDesc->ProductRevisionOffset); + TrimString(pDiskInfo[i].ProductRev); + } + + if (pDevDesc->SerialNumberOffset) + { + safe_strcpy(pDiskInfo[i].SerialNumber, (char *)pDevDesc + pDevDesc->SerialNumberOffset); + TrimString(pDiskInfo[i].SerialNumber); + } + + free(pDevDesc); + SAFE_CLOSE_HANDLE(Handle); + } + + Log("########## DUMP DISK BEGIN ##########"); + for (i = 0; i < DiskNum; i++) + { + Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s", + i, GetBusTypeString(pDiskInfo[i].BusType), pDiskInfo[i].RemovableMedia, + GetHumanReadableGBSize(pDiskInfo[i].Capacity), pDiskInfo[i].Capacity, + pDiskInfo[i].VendorId, pDiskInfo[i].ProductId); + } + Log("Ventoy disk is PhyDvr%d", g_vtoy_disk_drive); + Log("########## DUMP DISK END ##########"); + + *ppDiskInfo = pDiskInfo; + *pDiskNum = DiskNum; + return 0; +} + +static int UnattendVarExpand(const char *script, const char *tmpfile) +{ + FILE *fp = NULL; + FILE *fout = NULL; + char *start = NULL; + char *end = NULL; + char szLine[4096]; + char szValue[256]; + int DiskNum = 0; + VarDiskInfo *pDiskInfo = NULL; + + Log("UnattendVarExpand ..."); + + if (EnumerateAllDisk(&pDiskInfo, &DiskNum)) + { + Log("Failed to EnumerateAllDisk"); + return 1; + } + + fopen_s(&fp, script, "r"); + if (!fp) + { + free(pDiskInfo); + return 0; + } + + fopen_s(&fout, tmpfile, "w+"); + if (!fout) + { + fclose(fp); + free(pDiskInfo); + return 0; + } + + szLine[0] = szLine[4095] = 0; + + while (fgets(szLine, sizeof(szLine) - 1, fp)) + { + start = strstr(szLine, "$$VT_"); + if (start) + { + end = strstr(start + 5, "$$"); + } + + if (start && end) + { + *start = 0; + fprintf(fout, "%s", szLine); + + *end = 0; + ExpandSingleVar(pDiskInfo, DiskNum, start + 2, szValue, sizeof(szValue) - 1); + fprintf(fout, "%s", szValue); + + fprintf(fout, "%s", end + 2); + } + else + { + fprintf(fout, "%s", szLine); + } + + szLine[0] = szLine[4095] = 0; + } + + fclose(fp); + fclose(fout); + free(pDiskInfo); + return 0; +} + +//#define VAR_DEBUG 1 + static int ProcessUnattendedInstallation(const char *script) { DWORD dw; HKEY hKey; LSTATUS Ret; CHAR Letter; + CHAR TmpFile[MAX_PATH]; CHAR CurDir[MAX_PATH]; Log("Copy unattended XML ..."); @@ -1311,16 +1786,34 @@ static int ProcessUnattendedInstallation(const char *script) { Letter = 'X'; } - + +#ifdef VAR_DEBUG + sprintf_s(CurDir, sizeof(CurDir), "%C:\\AutounattendXXX.xml", Letter); +#else sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter); - Log("Copy file <%s> --> <%s>", script, CurDir); - CopyFile(script, CurDir, FALSE); +#endif + if (UnattendNeedVarExpand(script)) + { + sprintf_s(TmpFile, sizeof(TmpFile), "%C:\\__Autounattend", Letter); + UnattendVarExpand(script, TmpFile); + + Log("Expand Copy file <%s> --> <%s>", script, CurDir); + CopyFile(TmpFile, CurDir, FALSE); + } + else + { + Log("No var expand copy file <%s> --> <%s>", script, CurDir); + CopyFile(script, CurDir, FALSE); + } + +#ifndef VAR_DEBUG Ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dw); if (ERROR_SUCCESS == Ret) { Ret = RegSetValueEx(hKey, "UnattendFile", 0, REG_SZ, CurDir, (DWORD)(strlen(CurDir) + 1)); } +#endif return 0; } @@ -1493,7 +1986,7 @@ static int VentoyHook(ventoy_os_param *param) if (IsUTF8Encode(param->vtoy_img_path)) { - Log("This file is UTF8 encoding\n"); + Log("This file is UTF8 encoding"); } for (i = 0; i < 5; i++) @@ -1622,6 +2115,8 @@ static int VentoyHook(ventoy_os_param *param) return 1; } + g_vtoy_disk_drive = VtoyDiskNum; + Drives = GetLogicalDrives(); Log("Drives before mount: 0x%x", Drives); diff --git a/vtoyjump/vtoyjump/vtoyjump.h b/vtoyjump/vtoyjump/vtoyjump.h index 1e37338e..d4599855 100644 --- a/vtoyjump/vtoyjump/vtoyjump.h +++ b/vtoyjump/vtoyjump/vtoyjump.h @@ -1,29 +1,29 @@ -/****************************************************************************** -* vtoyjump.h -* -* Copyright (c) 2020, longpanda -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 3 of the -* License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, but -* WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, see . -* -*/ -#ifndef __VTOYJUMP_H__ -#define __VTOYJUMP_H__ - -#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) - -#define SIZE_1MB (1024 * 1024) -#define VENTOY_EFI_PART_SIZE (32 * SIZE_1MB) +/****************************************************************************** +* vtoyjump.h +* +* Copyright (c) 2020, longpanda +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, see . +* +*/ +#ifndef __VTOYJUMP_H__ +#define __VTOYJUMP_H__ + +#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) + +#define SIZE_1MB (1024 * 1024) +#define VENTOY_EFI_PART_SIZE (32 * SIZE_1MB) #define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} @@ -67,106 +67,124 @@ typedef struct ventoy_os_param UINT8 reserved[27]; }ventoy_os_param; -typedef struct ventoy_windows_data -{ - char auto_install_script[384]; - char injection_archive[384]; - UINT8 windows11_bypass_check; - - UINT32 auto_install_len; - - UINT8 reserved[255 - 4]; - - /* auto install script file data ... + auto_install_len */ - /* ...... */ - - +typedef struct ventoy_windows_data +{ + char auto_install_script[384]; + char injection_archive[384]; + UINT8 windows11_bypass_check; + + UINT32 auto_install_len; + + UINT8 reserved[255 - 4]; + + /* auto install script file data ... + auto_install_len */ + /* ...... */ + + }ventoy_windows_data; - - -typedef struct PART_TABLE -{ - UINT8 Active; // 0x00 0x80 - - UINT8 StartHead; - UINT16 StartSector : 6; - UINT16 StartCylinder : 10; - - UINT8 FsFlag; - - UINT8 EndHead; - UINT16 EndSector : 6; - UINT16 EndCylinder : 10; - - UINT32 StartSectorId; - UINT32 SectorCount; -}PART_TABLE; - -typedef struct MBR_HEAD -{ - UINT8 BootCode[446]; - PART_TABLE PartTbl[4]; - UINT8 Byte55; - UINT8 ByteAA; -}MBR_HEAD; - -typedef struct VTOY_GPT_HDR -{ - CHAR Signature[8]; /* EFI PART */ - UINT8 Version[4]; - UINT32 Length; - UINT32 Crc; - UINT8 Reserved1[4]; - UINT64 EfiStartLBA; - UINT64 EfiBackupLBA; - UINT64 PartAreaStartLBA; - UINT64 PartAreaEndLBA; - GUID DiskGuid; - UINT64 PartTblStartLBA; - UINT32 PartTblTotNum; - UINT32 PartTblEntryLen; - UINT32 PartTblCrc; - UINT8 Reserved2[420]; -}VTOY_GPT_HDR; - -typedef struct VTOY_GPT_PART_TBL -{ - GUID PartType; - GUID PartGuid; - UINT64 StartLBA; - UINT64 LastLBA; - UINT64 Attr; - UINT16 Name[36]; -}VTOY_GPT_PART_TBL; - -typedef struct VTOY_GPT_INFO -{ - MBR_HEAD MBR; - VTOY_GPT_HDR Head; - VTOY_GPT_PART_TBL PartTbl[128]; -}VTOY_GPT_INFO; - - - + + +typedef struct PART_TABLE +{ + UINT8 Active; // 0x00 0x80 + + UINT8 StartHead; + UINT16 StartSector : 6; + UINT16 StartCylinder : 10; + + UINT8 FsFlag; + + UINT8 EndHead; + UINT16 EndSector : 6; + UINT16 EndCylinder : 10; + + UINT32 StartSectorId; + UINT32 SectorCount; +}PART_TABLE; + +typedef struct MBR_HEAD +{ + UINT8 BootCode[446]; + PART_TABLE PartTbl[4]; + UINT8 Byte55; + UINT8 ByteAA; +}MBR_HEAD; + +typedef struct VTOY_GPT_HDR +{ + CHAR Signature[8]; /* EFI PART */ + UINT8 Version[4]; + UINT32 Length; + UINT32 Crc; + UINT8 Reserved1[4]; + UINT64 EfiStartLBA; + UINT64 EfiBackupLBA; + UINT64 PartAreaStartLBA; + UINT64 PartAreaEndLBA; + GUID DiskGuid; + UINT64 PartTblStartLBA; + UINT32 PartTblTotNum; + UINT32 PartTblEntryLen; + UINT32 PartTblCrc; + UINT8 Reserved2[420]; +}VTOY_GPT_HDR; + +typedef struct VTOY_GPT_PART_TBL +{ + GUID PartType; + GUID PartGuid; + UINT64 StartLBA; + UINT64 LastLBA; + UINT64 Attr; + UINT16 Name[36]; +}VTOY_GPT_PART_TBL; + +typedef struct VTOY_GPT_INFO +{ + MBR_HEAD MBR; + VTOY_GPT_HDR Head; + VTOY_GPT_PART_TBL PartTbl[128]; +}VTOY_GPT_INFO; + + + #pragma pack() - - -#define SAFE_CLOSE_HANDLE(handle) \ -{\ - if (handle != INVALID_HANDLE_VALUE) \ - {\ - CloseHandle(handle); \ - (handle) = INVALID_HANDLE_VALUE; \ - }\ -} - -#define LASTERR GetLastError() - -int unxz(unsigned char *in, int in_size, - int(*fill)(void *dest, unsigned int size), - int(*flush)(void *src, unsigned int size), - unsigned char *out, int *in_used, - void(*error)(char *x)); - -#endif + + + +typedef struct VarDiskInfo +{ + UINT64 Capacity; + int BusType; + BOOL RemovableMedia; + BYTE DeviceType; + CHAR VendorId[128]; + CHAR ProductId[128]; + CHAR ProductRev[128]; + CHAR SerialNumber[128]; +}VarDiskInfo; + + +#define SAFE_CLOSE_HANDLE(handle) \ +{\ + if (handle != INVALID_HANDLE_VALUE) \ + {\ + CloseHandle(handle); \ + (handle) = INVALID_HANDLE_VALUE; \ + }\ +} + +#define safe_sprintf(dst, fmt, ...) sprintf_s(dst, sizeof(dst), fmt, __VA_ARGS__) +#define safe_strcpy(dst, src) strcpy_s(dst, sizeof(dst), src) + + +#define LASTERR GetLastError() + +int unxz(unsigned char *in, int in_size, + int(*fill)(void *dest, unsigned int size), + int(*flush)(void *src, unsigned int size), + unsigned char *out, int *in_used, + void(*error)(char *x)); + +#endif