]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
1.0.77 release v1.0.77
authorlongpanda <admin@ventoy.net>
Sun, 19 Jun 2022 05:56:49 +0000 (13:56 +0800)
committerlongpanda <admin@ventoy.net>
Sun, 19 Jun 2022 05:56:49 +0000 (13:56 +0800)
23 files changed:
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
IMG/cpio/ventoy/hook/debian/disk_mount_hook.sh
IMG/cpio/ventoy/hook/debian/ventoy-cloud-init.sh
IMG/cpio/ventoy/hook/default/auto_install_varexp.sh [new file with mode: 0644]
IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh
IMG/cpio/ventoy/hook/rhel6/ventoy-varexp.sh [new file with mode: 0644]
IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh [new file with mode: 0644]
IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh
IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh
INSTALL/grub/grub.cfg
INSTALL/ventoy/vtoyjump32.exe
INSTALL/ventoy/vtoyjump64.exe
VtoyTool/vtoyexpand.c [new file with mode: 0644]
VtoyTool/vtoyloader.c
VtoyTool/vtoytool.c
VtoyTool/vtoytool/00/vtoytool_32
VtoyTool/vtoytool/00/vtoytool_64
VtoyTool/vtoytool/00/vtoytool_aa64
VtoyTool/vtoytool/00/vtoytool_m64e
vtoyjump/vtoyjump/vtoyjump.c
vtoyjump/vtoyjump/vtoyjump.h

index 00ebba5253a2ae442e32f3d61a6b9e1a8c73e002..b3cdcbcd79462cd3cfb52654f12a15afc78893bf 100644 (file)
@@ -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)
index a5d692f24e3587f2a87eedcb905e8d10092e42df..eecc932d7f2ab01956df034975b97caad7372a3a 100644 (file)
@@ -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;
 }
 
index 3ce2374f5b40f849d75cf76cc64da1ffa503b4c9..3462c5e5c601f628211d7845c58aa68ee496f98a 100644 (file)
@@ -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;
index 8fa19a410e0e1b6a0bb8e5df82ad16d12b54f7fd..4e00b8f18030037e61f6045dca743229580f0901 100644 (file)
@@ -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
index 875b496e305f2550fe361d2756e47f241783b581..0663f988e7c23d41d2e4eaa7080e5d8b28783e07 100644 (file)
@@ -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 (file)
index 0000000..af01d4e
--- /dev/null
@@ -0,0 +1,53 @@
+#!/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
+
index cfbe43fb0b68762baa592a1262347fe6ba314ce2..c3c33b6ad6e006fea4779aaa924196e8c637ebd5 100644 (file)
@@ -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 (file)
index 0000000..99c23a2
--- /dev/null
@@ -0,0 +1,37 @@
+#!/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
diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-autoexp.sh
new file mode 100644 (file)
index 0000000..661d436
--- /dev/null
@@ -0,0 +1,24 @@
+#!/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
index 271c38a8d11e7e502b5e2d47070a32f781a73307..bc5bc5ebc24e39a5d7d1da8663c8c494e32ec074 100644 (file)
@@ -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
index ff7966641a770bc01fd6ddf6f09d546a4eec4d84..d222f6689f8e0b221e13ffd8e53389a66d753ff9 100644 (file)
@@ -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
+
index 48e45507b3d5ecb6af640492a9c31d836472f08f..b232262cd5bf5fcc4be98f92b8c5676375a05541 100644 (file)
@@ -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
index 6a3f12d1f688c774bcc28b969cc69e9416bfa616..b21b2c0d7b0b8892f3343c94445eb98eb386a0b2 100644 (file)
Binary files a/INSTALL/ventoy/vtoyjump32.exe and b/INSTALL/ventoy/vtoyjump32.exe differ
index 5ffe4955c6c44f0f7317fcffd93f329b03b87958..6681a03fb3d8c1fc4b161bfc570884fbdce7c462 100644 (file)
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 (file)
index 0000000..c0a15d3
--- /dev/null
@@ -0,0 +1,554 @@
+/******************************************************************************
+ * 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
+
index 0272d7f2b8cc481577f43cbd98f8b32d54621963..3db190bc47dcf3ca1df7824abc1dffd1f9973e91 100644 (file)
@@ -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;
index f6896860cf766d2d2ab537e5a830b6c2e012ffb7..48cd9ff30ca8d32f95c37bbedc26e71998468169 100644 (file)
@@ -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 },
 };
 
index 2f0248616002d509a0c3aa429f8870fb645f44c5..90da6ce4b90c5febeeb5b2b8ff3683253dc08bc3 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_32 and b/VtoyTool/vtoytool/00/vtoytool_32 differ
index 51a0b16fbcf018ab346d55dcb39441a56c4e755e..0c04940e1b6861c092ff3f582011f4db2a49d726 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_64 and b/VtoyTool/vtoytool/00/vtoytool_64 differ
index 7af30d5f841e2bc3e0cb7466ed646f139c7bdfd4..fc34a6c750d7da2582ab25c93e816c364b63d28b 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_aa64 and b/VtoyTool/vtoytool/00/vtoytool_aa64 differ
index c7b3ccafdceb4ccd28c4590d4a06724793de5f96..d2047dd7bf6273cfd74086e78dbbf6c1e9e3ca2e 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_m64e and b/VtoyTool/vtoytool/00/vtoytool_m64e differ
index 81f5b0db787ef61896f45ee86b760af18a0abc45..82421608fde58623a111df63cbfed31d4f476cfb 100644 (file)
@@ -36,6 +36,8 @@ static ventoy_guid g_ventoy_guid = VENTOY_GUID;
 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
@@ -760,7 +762,7 @@ static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
        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
@@ -1291,12 +1293,485 @@ End:
     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
@@ -1311,16 +1786,34 @@ static int ProcessUnattendedInstallation(const char *script)
     {\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
@@ -1493,7 +1986,7 @@ static int VentoyHook(ventoy_os_param *param)
 \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
@@ -1622,6 +2115,8 @@ static int VentoyHook(ventoy_os_param *param)
         return 1;\r
     }\r
 \r
+    g_vtoy_disk_drive = VtoyDiskNum;\r
+\r
     Drives = GetLogicalDrives();\r
     Log("Drives before mount: 0x%x", Drives);\r
 \r
index 1e37338e9e2c621d62a388f3f21d62d45e034708..d45998552096abfa49d7bc7053b6753f074df825 100644 (file)
@@ -1,29 +1,29 @@
-/******************************************************************************
-* 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 }}
 
@@ -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\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