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)
return 0;
}
-static int ventoy_set_check_result(int ret)
+static int ventoy_set_check_result(int ret, const char *msg)
{
char buf[32];
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 ...... ");
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) ||
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
{
}
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)
(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
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.");
}
}
}
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.");
}
}
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);
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);
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)
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++;
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);
{
grub_printf("\n");
grub_refresh();
+ *record = 1;
break;
}
}
{
int pos = 0;
int flag = 0;
+ int record = 0;
int newlen = 0;
char *start = NULL;
char *end = NULL;
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;
*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);
{
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;
}
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);
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;
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
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
--- /dev/null
+#!/bin/sh
+#************************************************************************************
+# Copyright (c) 2022, longpanda <admin@ventoy.net>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+#************************************************************************************
+
+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
+
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
--- /dev/null
+#!/bin/sh
+#************************************************************************************
+# Copyright (c) 2022, longpanda <admin@ventoy.net>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+#************************************************************************************
+
+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
--- /dev/null
+#!/bin/sh
+#************************************************************************************
+# Copyright (c) 2022, longpanda <admin@ventoy.net>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+#************************************************************************************
+
+if [ -f /run/install/ks.cfg ]; then
+ sh /ventoy/hook/default/auto_install_varexp.sh /run/install/ks.cfg
+fi
+
+exit 0
$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
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
+
}
function locate_wim {
- vt_windows_locate_wim_patch (loop)
+ vt_windows_locate_wim_patch (loop) "$1"
if [ -n "${vtdebug_flag}" ]; then
echo '###############################################'
fi
ventoy_debug_pause
- locate_wim
+ locate_wim "${chosen_path}"
fi
vt_windows_chain_data "${1}${chosen_path}"
fi
ventoy_debug_pause
- locate_wim
+ locate_wim "${chosen_path}"
fi
vt_windows_chain_data "${1}${chosen_path}"
#############################################################
#############################################################
-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
--- /dev/null
+/******************************************************************************
+ * vtoyexpand.c ---- ventoy auto install script variable expansion
+ *
+ * Copyright (c) 2022, longpanda <admin@ventoy.net>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <linux/fs.h>
+#include <dirent.h>
+#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
+
{
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);
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;
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[] =
{ "vtoydump", vtoydump_main },
{ "vtoydm", vtoydm_main },
{ "loader", vtoyloader_main },
+ { "hald", vtoyloader_main },
{ "vtoyksym", vtoyksym_main },
{ "vtoykmod", vtoykmod_main },
+ { "vtoyexpand", vtoyexpand_main },
{ "--install", vtoytool_install },
};
static HANDLE g_vtoylog_mutex = NULL;\r
static HANDLE g_vtoyins_mutex = NULL;\r
\r
+static DWORD g_vtoy_disk_drive;\r
+\r
static CHAR g_prog_full_path[MAX_PATH];\r
static CHAR g_prog_dir[MAX_PATH];\r
static CHAR g_prog_name[MAX_PATH];\r
bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL);\r
if (bRet == FALSE || dwSize != ReadSize)\r
{\r
- Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, GetLastError());\r
+ Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u", bRet, ReadSize, dwSize, GetLastError());\r
}\r
\r
return 1;\r
return rc;\r
}\r
\r
+static int UnattendNeedVarExpand(const char *script)\r
+{\r
+ FILE *fp = NULL;\r
+ char szLine[4096];\r
+\r
+ fopen_s(&fp, script, "r");\r
+ if (!fp)\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ szLine[0] = szLine[4095] = 0;\r
+ \r
+ while (fgets(szLine, sizeof(szLine) - 1, fp))\r
+ {\r
+ if (strstr(szLine, "$$VT_"))\r
+ {\r
+ fclose(fp);\r
+ return 1;\r
+ }\r
+ \r
+ szLine[0] = szLine[4095] = 0;\r
+ }\r
+ \r
+ fclose(fp);\r
+ return 0;\r
+}\r
+\r
+static int ExpandSingleVar(VarDiskInfo *pDiskInfo, int DiskNum, const char *var, char *value, int len)\r
+{\r
+ int i;\r
+ int index = -1;\r
+ UINT64 uiDst = 0;\r
+ UINT64 uiDelta = 0;\r
+ UINT64 uiMaxSize = 0;\r
+ UINT64 uiMaxDelta = ULLONG_MAX;\r
+\r
+ value[0] = 0;\r
+ \r
+ if (strcmp(var, "VT_WINDOWS_DISK_1ST_NONVTOY") == 0)\r
+ {\r
+ for (i = 0; i < DiskNum; i++)\r
+ {\r
+ if (pDiskInfo[i].Capacity > 0 && i != g_vtoy_disk_drive)\r
+ {\r
+ Log("%s=<PhyDrive%d>", var, i);\r
+ sprintf_s(value, len, "%d", i);\r
+ return 0;\r
+ }\r
+ }\r
+ }\r
+ else if (strcmp(var, "VT_WINDOWS_DISK_1ST_NONUSB") == 0)\r
+ {\r
+ for (i = 0; i < DiskNum; i++)\r
+ {\r
+ if (pDiskInfo[i].Capacity > 0 && pDiskInfo[i].BusType != BusTypeUsb)\r
+ {\r
+ Log("%s=<PhyDrive%d>", var, i);\r
+ sprintf_s(value, len, "%d", i);\r
+ return 0;\r
+ }\r
+ }\r
+ }\r
+ else if (strcmp(var, "VT_WINDOWS_DISK_MAX_SIZE") == 0)\r
+ {\r
+ for (i = 0; i < DiskNum; i++)\r
+ {\r
+ if (pDiskInfo[i].Capacity > 0 && pDiskInfo[i].Capacity > uiMaxSize)\r
+ {\r
+ index = i;\r
+ uiMaxSize = pDiskInfo[i].Capacity;\r
+ }\r
+ }\r
+\r
+ Log("%s=<PhyDrive%d>", var, index);\r
+ sprintf_s(value, len, "%d", index);\r
+ }\r
+ else if (strncmp(var, "VT_WINDOWS_DISK_CLOSEST_", 24) == 0)\r
+ {\r
+ uiDst = strtoul(var + 24, NULL, 10);\r
+ uiDst = uiDst * (1024ULL * 1024ULL * 1024ULL);\r
+ \r
+ for (i = 0; i < DiskNum; i++)\r
+ {\r
+ if (pDiskInfo[i].Capacity == 0)\r
+ {\r
+ continue;\r
+ }\r
+ \r
+ if (pDiskInfo[i].Capacity > uiDst)\r
+ {\r
+ uiDelta = pDiskInfo[i].Capacity - uiDst;\r
+ }\r
+ else\r
+ {\r
+ uiDelta = uiDst - pDiskInfo[i].Capacity;\r
+ }\r
+ \r
+ if (uiDelta < uiMaxDelta)\r
+ {\r
+ uiMaxDelta = uiDelta;\r
+ index = i;\r
+ }\r
+ }\r
+\r
+ Log("%s=<PhyDrive%d>", var, index);\r
+ sprintf_s(value, len, "%d", index);\r
+ }\r
+ else\r
+ {\r
+ Log("Invalid var name <%s>", var);\r
+ sprintf_s(value, len, "$$%s$$", var);\r
+ }\r
+ \r
+ if (value[0] == 0)\r
+ {\r
+ sprintf_s(value, len, "$$%s$$", var);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+static void TrimString(CHAR *String)\r
+{\r
+ CHAR *Pos1 = String;\r
+ CHAR *Pos2 = String;\r
+ size_t Len = strlen(String);\r
+\r
+ while (Len > 0)\r
+ {\r
+ if (String[Len - 1] != ' ' && String[Len - 1] != '\t')\r
+ {\r
+ break;\r
+ }\r
+ String[Len - 1] = 0;\r
+ Len--;\r
+ }\r
+\r
+ while (*Pos1 == ' ' || *Pos1 == '\t')\r
+ {\r
+ Pos1++;\r
+ }\r
+\r
+ while (*Pos1)\r
+ {\r
+ *Pos2++ = *Pos1++;\r
+ }\r
+ *Pos2++ = 0;\r
+\r
+ return;\r
+}\r
+\r
+static int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue)\r
+{\r
+ HKEY hKey;\r
+ DWORD Type;\r
+ DWORD Size;\r
+ LSTATUS lRet;\r
+ DWORD Value;\r
+\r
+ lRet = RegOpenKeyExA(Key, SubKey, 0, KEY_QUERY_VALUE, &hKey);\r
+ Log("RegOpenKeyExA <%s> Ret:%ld", SubKey, lRet);\r
+\r
+ if (ERROR_SUCCESS == lRet)\r
+ {\r
+ Size = sizeof(Value);\r
+ lRet = RegQueryValueExA(hKey, ValueName, NULL, &Type, (LPBYTE)&Value, &Size);\r
+ Log("RegQueryValueExA <%s> ret:%u Size:%u Value:%u", ValueName, lRet, Size, Value);\r
+\r
+ *pValue = Value;\r
+ RegCloseKey(hKey);\r
+\r
+ return 0;\r
+ }\r
+ else\r
+ {\r
+ return 1;\r
+ }\r
+}\r
+\r
+static const CHAR * GetBusTypeString(int Type)\r
+{\r
+ switch (Type)\r
+ {\r
+ case BusTypeUnknown: return "unknown";\r
+ case BusTypeScsi: return "SCSI";\r
+ case BusTypeAtapi: return "Atapi";\r
+ case BusTypeAta: return "ATA";\r
+ case BusType1394: return "1394";\r
+ case BusTypeSsa: return "SSA";\r
+ case BusTypeFibre: return "Fibre";\r
+ case BusTypeUsb: return "USB";\r
+ case BusTypeRAID: return "RAID";\r
+ case BusTypeiScsi: return "iSCSI";\r
+ case BusTypeSas: return "SAS";\r
+ case BusTypeSata: return "SATA";\r
+ case BusTypeSd: return "SD";\r
+ case BusTypeMmc: return "MMC";\r
+ case BusTypeVirtual: return "Virtual";\r
+ case BusTypeFileBackedVirtual: return "FileBackedVirtual";\r
+ case BusTypeSpaces: return "Spaces";\r
+ case BusTypeNvme: return "Nvme";\r
+ }\r
+ return "unknown";\r
+}\r
+\r
+static int GetHumanReadableGBSize(UINT64 SizeBytes)\r
+{\r
+ int i;\r
+ int Pow2 = 1;\r
+ double Delta;\r
+ double GB = SizeBytes * 1.0 / 1000 / 1000 / 1000;\r
+\r
+ if ((SizeBytes % 1073741824) == 0)\r
+ {\r
+ return (int)(SizeBytes / 1073741824);\r
+ }\r
+\r
+ for (i = 0; i < 12; i++)\r
+ {\r
+ if (Pow2 > GB)\r
+ {\r
+ Delta = (Pow2 - GB) / Pow2;\r
+ }\r
+ else\r
+ {\r
+ Delta = (GB - Pow2) / Pow2;\r
+ }\r
+\r
+ if (Delta < 0.05)\r
+ {\r
+ return Pow2;\r
+ }\r
+\r
+ Pow2 <<= 1;\r
+ }\r
+\r
+ return (int)GB;\r
+}\r
+\r
+static int EnumerateAllDisk(VarDiskInfo **ppDiskInfo, int *pDiskNum)\r
+{\r
+ int i;\r
+ DWORD Value;\r
+ int DiskNum = 0;\r
+ BOOL bRet;\r
+ DWORD dwBytes;\r
+ VarDiskInfo *pDiskInfo = NULL;\r
+ HANDLE Handle = INVALID_HANDLE_VALUE;\r
+ CHAR PhyDrive[128]; \r
+ GET_LENGTH_INFORMATION LengthInfo;\r
+ STORAGE_PROPERTY_QUERY Query;\r
+ STORAGE_DESCRIPTOR_HEADER DevDescHeader;\r
+ STORAGE_DEVICE_DESCRIPTOR *pDevDesc;\r
+ \r
+ if (GetRegDwordValue(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", "Count", &Value) == 0)\r
+ {\r
+ DiskNum = (int)Value;\r
+ }\r
+ else\r
+ {\r
+ Log("Failed to read disk count");\r
+ return 1;\r
+ }\r
+\r
+ Log("Current phy disk count:%d", DiskNum);\r
+ if (DiskNum <= 0)\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ pDiskInfo = malloc(DiskNum * sizeof(VarDiskInfo));\r
+ if (!pDiskInfo)\r
+ {\r
+ Log("Failed to alloc");\r
+ return 1;\r
+ }\r
+ memset(pDiskInfo, 0, DiskNum * sizeof(VarDiskInfo));\r
+\r
+ for (i = 0; i < DiskNum; i++)\r
+ {\r
+ SAFE_CLOSE_HANDLE(Handle);\r
+\r
+ safe_sprintf(PhyDrive, "\\\\.\\PhysicalDrive%d", i);\r
+ Handle = CreateFileA(PhyDrive, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); \r
+ Log("Create file Handle:%p %s status:%u", Handle, PhyDrive, LASTERR);\r
+\r
+ if (Handle == INVALID_HANDLE_VALUE)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ bRet = DeviceIoControl(Handle,\r
+ IOCTL_DISK_GET_LENGTH_INFO, NULL,\r
+ 0,\r
+ &LengthInfo,\r
+ sizeof(LengthInfo),\r
+ &dwBytes,\r
+ NULL);\r
+ if (!bRet)\r
+ {\r
+ Log("DeviceIoControl IOCTL_DISK_GET_LENGTH_INFO failed error:%u", LASTERR);\r
+ continue;\r
+ }\r
+\r
+ Log("PHYSICALDRIVE%d size %llu bytes", i, (ULONGLONG)LengthInfo.Length.QuadPart);\r
+\r
+ Query.PropertyId = StorageDeviceProperty;\r
+ Query.QueryType = PropertyStandardQuery;\r
+\r
+ bRet = DeviceIoControl(Handle,\r
+ IOCTL_STORAGE_QUERY_PROPERTY,\r
+ &Query,\r
+ sizeof(Query),\r
+ &DevDescHeader,\r
+ sizeof(STORAGE_DESCRIPTOR_HEADER),\r
+ &dwBytes,\r
+ NULL);\r
+ if (!bRet)\r
+ {\r
+ Log("DeviceIoControl1 error:%u dwBytes:%u", LASTERR, dwBytes);\r
+ continue;\r
+ }\r
+\r
+ if (DevDescHeader.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR))\r
+ {\r
+ Log("Invalid DevDescHeader.Size:%u", DevDescHeader.Size);\r
+ continue;\r
+ }\r
+\r
+ pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(DevDescHeader.Size);\r
+ if (!pDevDesc)\r
+ {\r
+ Log("failed to malloc error:%u len:%u", LASTERR, DevDescHeader.Size);\r
+ continue;\r
+ }\r
+\r
+ bRet = DeviceIoControl(Handle,\r
+ IOCTL_STORAGE_QUERY_PROPERTY,\r
+ &Query,\r
+ sizeof(Query),\r
+ pDevDesc,\r
+ DevDescHeader.Size,\r
+ &dwBytes,\r
+ NULL);\r
+ if (!bRet)\r
+ {\r
+ Log("DeviceIoControl2 error:%u dwBytes:%u", LASTERR, dwBytes);\r
+ free(pDevDesc);\r
+ continue;\r
+ }\r
+\r
+ pDiskInfo[i].RemovableMedia = pDevDesc->RemovableMedia;\r
+ pDiskInfo[i].BusType = pDevDesc->BusType;\r
+ pDiskInfo[i].DeviceType = pDevDesc->DeviceType;\r
+ pDiskInfo[i].Capacity = LengthInfo.Length.QuadPart;\r
+\r
+ if (pDevDesc->VendorIdOffset)\r
+ {\r
+ safe_strcpy(pDiskInfo[i].VendorId, (char *)pDevDesc + pDevDesc->VendorIdOffset);\r
+ TrimString(pDiskInfo[i].VendorId);\r
+ }\r
+\r
+ if (pDevDesc->ProductIdOffset)\r
+ {\r
+ safe_strcpy(pDiskInfo[i].ProductId, (char *)pDevDesc + pDevDesc->ProductIdOffset);\r
+ TrimString(pDiskInfo[i].ProductId);\r
+ }\r
+\r
+ if (pDevDesc->ProductRevisionOffset)\r
+ {\r
+ safe_strcpy(pDiskInfo[i].ProductRev, (char *)pDevDesc + pDevDesc->ProductRevisionOffset);\r
+ TrimString(pDiskInfo[i].ProductRev);\r
+ }\r
+\r
+ if (pDevDesc->SerialNumberOffset)\r
+ {\r
+ safe_strcpy(pDiskInfo[i].SerialNumber, (char *)pDevDesc + pDevDesc->SerialNumberOffset);\r
+ TrimString(pDiskInfo[i].SerialNumber);\r
+ }\r
+\r
+ free(pDevDesc);\r
+ SAFE_CLOSE_HANDLE(Handle);\r
+ }\r
+\r
+ Log("########## DUMP DISK BEGIN ##########");\r
+ for (i = 0; i < DiskNum; i++)\r
+ {\r
+ Log("PhyDrv:%d BusType:%-4s Removable:%u Size:%dGB(%llu) Name:%s %s",\r
+ i, GetBusTypeString(pDiskInfo[i].BusType), pDiskInfo[i].RemovableMedia,\r
+ GetHumanReadableGBSize(pDiskInfo[i].Capacity), pDiskInfo[i].Capacity,\r
+ pDiskInfo[i].VendorId, pDiskInfo[i].ProductId);\r
+ }\r
+ Log("Ventoy disk is PhyDvr%d", g_vtoy_disk_drive);\r
+ Log("########## DUMP DISK END ##########");\r
+\r
+ *ppDiskInfo = pDiskInfo;\r
+ *pDiskNum = DiskNum;\r
+ return 0;\r
+}\r
+\r
+static int UnattendVarExpand(const char *script, const char *tmpfile)\r
+{\r
+ FILE *fp = NULL;\r
+ FILE *fout = NULL;\r
+ char *start = NULL;\r
+ char *end = NULL;\r
+ char szLine[4096];\r
+ char szValue[256];\r
+ int DiskNum = 0;\r
+ VarDiskInfo *pDiskInfo = NULL;\r
+\r
+ Log("UnattendVarExpand ...");\r
+\r
+ if (EnumerateAllDisk(&pDiskInfo, &DiskNum))\r
+ {\r
+ Log("Failed to EnumerateAllDisk");\r
+ return 1;\r
+ }\r
+ \r
+ fopen_s(&fp, script, "r");\r
+ if (!fp)\r
+ {\r
+ free(pDiskInfo);\r
+ return 0;\r
+ }\r
+\r
+ fopen_s(&fout, tmpfile, "w+");\r
+ if (!fout)\r
+ {\r
+ fclose(fp);\r
+ free(pDiskInfo);\r
+ return 0;\r
+ }\r
+\r
+ szLine[0] = szLine[4095] = 0;\r
+ \r
+ while (fgets(szLine, sizeof(szLine) - 1, fp))\r
+ {\r
+ start = strstr(szLine, "$$VT_");\r
+ if (start)\r
+ {\r
+ end = strstr(start + 5, "$$");\r
+ }\r
+\r
+ if (start && end)\r
+ {\r
+ *start = 0;\r
+ fprintf(fout, "%s", szLine);\r
+\r
+ *end = 0;\r
+ ExpandSingleVar(pDiskInfo, DiskNum, start + 2, szValue, sizeof(szValue) - 1);\r
+ fprintf(fout, "%s", szValue);\r
+ \r
+ fprintf(fout, "%s", end + 2);\r
+ }\r
+ else\r
+ {\r
+ fprintf(fout, "%s", szLine);\r
+ }\r
+ \r
+ szLine[0] = szLine[4095] = 0;\r
+ }\r
+\r
+ fclose(fp);\r
+ fclose(fout);\r
+ free(pDiskInfo);\r
+ return 0;\r
+}\r
+\r
+//#define VAR_DEBUG 1\r
+\r
static int ProcessUnattendedInstallation(const char *script)\r
{\r
DWORD dw;\r
HKEY hKey;\r
LSTATUS Ret;\r
CHAR Letter;\r
+ CHAR TmpFile[MAX_PATH];\r
CHAR CurDir[MAX_PATH];\r
\r
Log("Copy unattended XML ...");\r
{\r
Letter = 'X';\r
}\r
- \r
+\r
+#ifdef VAR_DEBUG\r
+ sprintf_s(CurDir, sizeof(CurDir), "%C:\\AutounattendXXX.xml", Letter);\r
+#else\r
sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter);\r
- Log("Copy file <%s> --> <%s>", script, CurDir);\r
- CopyFile(script, CurDir, FALSE);\r
+#endif\r
\r
+ if (UnattendNeedVarExpand(script))\r
+ {\r
+ sprintf_s(TmpFile, sizeof(TmpFile), "%C:\\__Autounattend", Letter);\r
+ UnattendVarExpand(script, TmpFile);\r
+ \r
+ Log("Expand Copy file <%s> --> <%s>", script, CurDir);\r
+ CopyFile(TmpFile, CurDir, FALSE);\r
+ }\r
+ else\r
+ {\r
+ Log("No var expand copy file <%s> --> <%s>", script, CurDir);\r
+ CopyFile(script, CurDir, FALSE);\r
+ }\r
+ \r
+#ifndef VAR_DEBUG\r
Ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dw);\r
if (ERROR_SUCCESS == Ret)\r
{\r
Ret = RegSetValueEx(hKey, "UnattendFile", 0, REG_SZ, CurDir, (DWORD)(strlen(CurDir) + 1));\r
}\r
+#endif\r
\r
return 0;\r
}\r
\r
if (IsUTF8Encode(param->vtoy_img_path))\r
{\r
- Log("This file is UTF8 encoding\n");\r
+ Log("This file is UTF8 encoding");\r
}\r
\r
for (i = 0; i < 5; i++)\r
return 1;\r
}\r
\r
+ g_vtoy_disk_drive = VtoyDiskNum;\r
+\r
Drives = GetLogicalDrives();\r
Log("Drives before mount: 0x%x", Drives);\r
\r
-/******************************************************************************
-* vtoyjump.h
-*
-* Copyright (c) 2020, longpanda <admin@ventoy.net>
-*
-* 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 <http://www.gnu.org/licenses/>.
-*
-*/
-#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)
+/******************************************************************************\r
+* vtoyjump.h\r
+*\r
+* Copyright (c) 2020, longpanda <admin@ventoy.net>\r
+*\r
+* This program is free software; you can redistribute it and/or\r
+* modify it under the terms of the GNU General Public License as\r
+* published by the Free Software Foundation; either version 3 of the\r
+* License, or (at your option) any later version.\r
+*\r
+* This program is distributed in the hope that it will be useful, but\r
+* WITHOUT ANY WARRANTY; without even the implied warranty of\r
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+* General Public License for more details.\r
+*\r
+* You should have received a copy of the GNU General Public License\r
+* along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*\r
+*/\r
+#ifndef __VTOYJUMP_H__\r
+#define __VTOYJUMP_H__\r
+\r
+#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) \r
+\r
+#define SIZE_1MB (1024 * 1024)\r
+#define VENTOY_EFI_PART_SIZE (32 * SIZE_1MB)\r
#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }}
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\r
+{\r
+ char auto_install_script[384];\r
+ char injection_archive[384];\r
+ UINT8 windows11_bypass_check;\r
+\r
+ UINT32 auto_install_len;\r
+ \r
+ UINT8 reserved[255 - 4];\r
+\r
+ /* auto install script file data ... + auto_install_len */\r
+ /* ...... */\r
+\r
+ \r
}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;
-
-
-
+\r
+\r
+typedef struct PART_TABLE\r
+{\r
+ UINT8 Active; // 0x00 0x80\r
+\r
+ UINT8 StartHead;\r
+ UINT16 StartSector : 6;\r
+ UINT16 StartCylinder : 10;\r
+\r
+ UINT8 FsFlag;\r
+\r
+ UINT8 EndHead;\r
+ UINT16 EndSector : 6;\r
+ UINT16 EndCylinder : 10;\r
+\r
+ UINT32 StartSectorId;\r
+ UINT32 SectorCount;\r
+}PART_TABLE;\r
+\r
+typedef struct MBR_HEAD\r
+{\r
+ UINT8 BootCode[446];\r
+ PART_TABLE PartTbl[4];\r
+ UINT8 Byte55;\r
+ UINT8 ByteAA;\r
+}MBR_HEAD;\r
+\r
+typedef struct VTOY_GPT_HDR\r
+{\r
+ CHAR Signature[8]; /* EFI PART */\r
+ UINT8 Version[4];\r
+ UINT32 Length;\r
+ UINT32 Crc;\r
+ UINT8 Reserved1[4];\r
+ UINT64 EfiStartLBA;\r
+ UINT64 EfiBackupLBA;\r
+ UINT64 PartAreaStartLBA;\r
+ UINT64 PartAreaEndLBA;\r
+ GUID DiskGuid;\r
+ UINT64 PartTblStartLBA;\r
+ UINT32 PartTblTotNum;\r
+ UINT32 PartTblEntryLen;\r
+ UINT32 PartTblCrc;\r
+ UINT8 Reserved2[420];\r
+}VTOY_GPT_HDR;\r
+\r
+typedef struct VTOY_GPT_PART_TBL\r
+{\r
+ GUID PartType;\r
+ GUID PartGuid;\r
+ UINT64 StartLBA;\r
+ UINT64 LastLBA;\r
+ UINT64 Attr;\r
+ UINT16 Name[36];\r
+}VTOY_GPT_PART_TBL;\r
+\r
+typedef struct VTOY_GPT_INFO\r
+{\r
+ MBR_HEAD MBR;\r
+ VTOY_GPT_HDR Head;\r
+ VTOY_GPT_PART_TBL PartTbl[128];\r
+}VTOY_GPT_INFO;\r
+\r
+\r
+\r
#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
+\r
+\r
+\r
+typedef struct VarDiskInfo\r
+{\r
+ UINT64 Capacity;\r
+ int BusType;\r
+ BOOL RemovableMedia;\r
+ BYTE DeviceType;\r
+ CHAR VendorId[128];\r
+ CHAR ProductId[128];\r
+ CHAR ProductRev[128];\r
+ CHAR SerialNumber[128];\r
+}VarDiskInfo;\r
+\r
+\r
+#define SAFE_CLOSE_HANDLE(handle) \\r
+{\\r
+ if (handle != INVALID_HANDLE_VALUE) \\r
+ {\\r
+ CloseHandle(handle); \\r
+ (handle) = INVALID_HANDLE_VALUE; \\r
+ }\\r
+}\r
+\r
+#define safe_sprintf(dst, fmt, ...) sprintf_s(dst, sizeof(dst), fmt, __VA_ARGS__)\r
+#define safe_strcpy(dst, src) strcpy_s(dst, sizeof(dst), src)\r
+\r
+\r
+#define LASTERR GetLastError()\r
+\r
+int unxz(unsigned char *in, int in_size,\r
+ int(*fill)(void *dest, unsigned int size),\r
+ int(*flush)(void *src, unsigned int size),\r
+ unsigned char *out, int *in_used,\r
+ void(*error)(char *x));\r
+\r
+#endif\r