Compare commits

...

23 Commits

Author SHA1 Message Date
longpanda
f5843f576b 1.0.56 release 2021-10-22 17:19:01 +08:00
longpanda
be5bc6f3b7 Optimization for Ventoy2Disk.exe 2021-10-22 11:59:51 +08:00
longpanda
f3b65452f4 Add extra check.
Still, Ventoy is used in some non standard way. (e.g. WuYouBBS)
I have explained in
8bbd5a14a3

So I add an extra check.
This is also a prepare for the future Ventoy secure boot policy.
2021-10-22 11:58:49 +08:00
longpanda
ec4b6c2a2c Fix a bug when booting Porteus 4.0 i586 20170701.iso 2021-10-21 20:23:32 +08:00
longpanda
be8b6e8976 Optimization for Ventoy2Disk.exe 2021-10-21 19:14:44 +08:00
longpanda
82b1faa132 Ventoy2Disk.exe update 2021-10-20 23:21:10 +08:00
longpanda
52ae65f54d Optimization for Ventoy2Disk.exe 2021-10-20 22:57:18 +08:00
longpanda
ee104bfa97 Optimization for Ventoy2Disk.exe 2021-10-20 17:27:06 +08:00
longpanda
9cfd05811b Add timeout option for auto_install/persistence plugin (#1161) 2021-10-20 17:00:20 +08:00
Tayfun Akkoyun
0c66908935 Create tr_TR.txt (#1157)
Mater @ventoy 
I translated English help file to Turkish language...Can you add this file?
2021-10-20 11:15:32 +08:00
Sopor
f53de3bdb0 Update Swedish language (#1163) 2021-10-20 11:14:17 +08:00
marcellogianola
8516786b31 Update languages.json (#1154) 2021-10-20 11:13:58 +08:00
longpanda
f7c78879c7 Support Eset SysRescue image file. (#1162) 2021-10-20 10:43:36 +08:00
longpanda
f3e267a09e support ALT rescue 2021-10-19 23:07:27 +08:00
longpanda
7c1370dcb0 Fix the long delay for Tails 2021-10-19 20:12:50 +08:00
longpanda
1b5aa9c61d Fix the long delay for Tails 2021-10-19 19:48:46 +08:00
longpanda
d6eba15d71 1. Add Ctrl+h hotkey for help
2. Add VTOY_HELP_TXT_LANGUAGE option in Global Control plugin
3. Add Ctrl+m hotkey for file cheksum
2021-10-19 17:42:32 +08:00
longpanda
734c7b8ac4 1.0.55 release 2021-10-17 21:56:30 +08:00
longpanda
0fa25c4526 1. Add support for some special WinPE
2. Add VentoyAutoRun.bat feature
2021-10-16 23:34:53 +08:00
longpanda
1473be0e4c Improve the success rate of Ventoy2Disk.exe installation and upgrade 2021-10-16 23:34:20 +08:00
longpanda
cd9aa16b20 Add support for Pyabr OS 2021-10-16 23:32:39 +08:00
longpanda
a9be2fd4d9 Improvement for some special WinPE 2021-10-14 11:27:22 +08:00
longpanda
f354d2b733 misc update 2021-10-12 20:10:37 +08:00
48 changed files with 3306 additions and 918 deletions

View File

@@ -21,7 +21,7 @@ body:
attributes:
label: Ventoy Version
description: What version of ventoy are you running?
placeholder: 1.0.51
placeholder: 1.0.56
validations:
required: true
- type: dropdown

View File

@@ -45,10 +45,24 @@ int g_ventoy_wimboot_mode = 0;
int g_ventoy_iso_uefi_drv = 0;
int g_ventoy_last_entry = -1;
int g_ventoy_suppress_esc = 0;
int g_ventoy_suppress_esc_default = 1;
int g_ventoy_menu_esc = 0;
int g_ventoy_fn_mutex = 0;
int g_ventoy_terminal_output = 0;
#define VTOY_COMM_HOTKEY(cmdkey) \
if (0 == g_ventoy_fn_mutex) { \
cmdstr = grub_env_get(cmdkey); \
if (cmdstr) \
{ \
menu_fini (); \
g_ventoy_fn_mutex = 1; \
grub_script_execute_sourcecode(cmdstr); \
g_ventoy_fn_mutex = 0; \
goto refresh; \
} \
}
/* Time to delay after displaying an error message about a default/fallback
entry failing to boot. */
#define DEFAULT_ENTRY_ERROR_DELAY_MS 2500
@@ -388,7 +402,7 @@ int g_menu_update_mode = 0;
int g_ventoy_tip_label_enable = 0;
const char * g_ventoy_tip_msg1 = NULL;
const char * g_ventoy_tip_msg2 = NULL;
static const char *g_ventoy_cur_img_path = NULL;
static void menu_set_chosen_tip(grub_menu_t menu, int entry)
{
img_info *img;
@@ -402,6 +416,7 @@ static void menu_set_chosen_tip(grub_menu_t menu, int entry)
{
g_ventoy_tip_msg1 = img->tip1;
g_ventoy_tip_msg2 = img->tip2;
g_ventoy_cur_img_path = img->path;
}
}
}
@@ -625,7 +640,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
default_entry = get_entry_number (menu, "default");
if (g_ventoy_suppress_esc)
default_entry = 1;
default_entry = g_ventoy_suppress_esc_default;
else if (g_ventoy_last_entry >= 0 && g_ventoy_last_entry < menu->size) {
default_entry = g_ventoy_last_entry;
}
@@ -835,71 +850,23 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
case GRUB_TERM_KEY_F2:
case '2':
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F2_CMD");
if (cmdstr)
{
menu_fini ();
g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh;
}
}
VTOY_COMM_HOTKEY("VTOY_F2_CMD");
break;
case GRUB_TERM_KEY_F3:
case '3':
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F3_CMD");
if (cmdstr)
{
menu_fini ();
grub_script_execute_sourcecode(cmdstr);
goto refresh;
}
}
VTOY_COMM_HOTKEY("VTOY_F3_CMD");
break;
case GRUB_TERM_KEY_F4:
case '4':
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F4_CMD");
if (cmdstr)
{
menu_fini ();
g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh;
}
}
VTOY_COMM_HOTKEY("VTOY_F4_CMD");
break;
case GRUB_TERM_KEY_F5:
case '5':
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F5_CMD");
if (cmdstr)
{
menu_fini ();
g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh;
}
}
VTOY_COMM_HOTKEY("VTOY_F5_CMD");
break;
case GRUB_TERM_KEY_F6:
case '6':
if (0 == g_ventoy_fn_mutex) {
cmdstr = grub_env_get("VTOY_F6_CMD");
if (cmdstr)
{
menu_fini ();
g_ventoy_fn_mutex = 1;
grub_script_execute_sourcecode(cmdstr);
g_ventoy_fn_mutex = 0;
goto refresh;
}
}
VTOY_COMM_HOTKEY("VTOY_F6_CMD");
break;
case GRUB_TERM_KEY_F7:
menu_fini ();
@@ -945,6 +912,38 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
g_ventoy_menu_refresh = 1;
goto refresh;
case (GRUB_TERM_CTRL | 'h'):
{
cmdstr = grub_env_get("VTOY_HELP_CMD");
if (cmdstr)
{
grub_script_execute_sourcecode(cmdstr);
while (grub_getkey() != GRUB_TERM_ESC)
;
menu_fini ();
goto refresh;
}
break;
}
case (GRUB_TERM_CTRL | 'm'):
{
if (g_ventoy_cur_img_path)
{
grub_env_set("VTOY_CHKSUM_FILE_PATH", g_ventoy_cur_img_path);
cmdstr = grub_env_get("VTOY_CHKSUM_CMD");
if (cmdstr)
{
menu_fini();
grub_script_execute_sourcecode(cmdstr);
goto refresh;
}
}
else
{
grub_env_set("VTOY_CHKSUM_FILE_PATH", "X");
}
break;
}
default:
{
int entry;
@@ -1038,6 +1037,11 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
break;
}
if (autobooted == 0 && g_ventoy_menu_esc && auto_boot) {
g_ventoy_last_entry = boot_entry;
break;
}
e = grub_menu_get_entry (menu, boot_entry);
if (! e)
continue; /* Menu is empty. */

View File

@@ -51,6 +51,37 @@
GRUB_MOD_LICENSE ("GPLv3+");
static grub_uint8_t g_check_mbr_data[440] = {
0xEB, 0x63, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFA, 0x90, 0x90, 0xF6, 0xC2, 0x80, 0x74, 0x05, 0xF6, 0xC2, 0x70,
0x74, 0x02, 0xB2, 0x80, 0xEA, 0x79, 0x7C, 0x00, 0x00, 0x31, 0xC0, 0x8E, 0xD8, 0x8E, 0xD0, 0xBC,
0x00, 0x20, 0xFB, 0xA0, 0x64, 0x7C, 0x3C, 0xFF, 0x74, 0x02, 0x88, 0xC2, 0x52, 0xBE, 0x90, 0x7D,
0xE8, 0x16, 0x01, 0xBE, 0x05, 0x7C, 0xB4, 0x41, 0xBB, 0xAA, 0x55, 0xCD, 0x13, 0x5A, 0x52, 0x72,
0x3D, 0x81, 0xFB, 0x55, 0xAA, 0x75, 0x37, 0x83, 0xE1, 0x01, 0x74, 0x32, 0x31, 0xC0, 0x89, 0x44,
0x04, 0x40, 0x88, 0x44, 0xFF, 0x89, 0x44, 0x02, 0xC7, 0x04, 0x10, 0x00, 0x66, 0x8B, 0x1E, 0x5C,
0x7C, 0x66, 0x89, 0x5C, 0x08, 0x66, 0x8B, 0x1E, 0x60, 0x7C, 0x66, 0x89, 0x5C, 0x0C, 0xC7, 0x44,
0x06, 0x00, 0x70, 0xB4, 0x42, 0xCD, 0x13, 0x72, 0x05, 0xBB, 0x00, 0x70, 0xEB, 0x76, 0xB4, 0x08,
0xCD, 0x13, 0x73, 0x0D, 0x5A, 0x84, 0xD2, 0x0F, 0x83, 0xD8, 0x00, 0xBE, 0x96, 0x7D, 0xE9, 0x82,
0x00, 0x66, 0x0F, 0xB6, 0xC6, 0x88, 0x64, 0xFF, 0x40, 0x66, 0x89, 0x44, 0x04, 0x0F, 0xB6, 0xD1,
0xC1, 0xE2, 0x02, 0x88, 0xE8, 0x88, 0xF4, 0x40, 0x89, 0x44, 0x08, 0x0F, 0xB6, 0xC2, 0xC0, 0xE8,
0x02, 0x66, 0x89, 0x04, 0x66, 0xA1, 0x60, 0x7C, 0x66, 0x09, 0xC0, 0x75, 0x4E, 0x66, 0xA1, 0x5C,
0x7C, 0x66, 0x31, 0xD2, 0x66, 0xF7, 0x34, 0x88, 0xD1, 0x31, 0xD2, 0x66, 0xF7, 0x74, 0x04, 0x3B,
0x44, 0x08, 0x7D, 0x37, 0xFE, 0xC1, 0x88, 0xC5, 0x30, 0xC0, 0xC1, 0xE8, 0x02, 0x08, 0xC1, 0x88,
0xD0, 0x5A, 0x88, 0xC6, 0xBB, 0x00, 0x70, 0x8E, 0xC3, 0x31, 0xDB, 0xB8, 0x01, 0x02, 0xCD, 0x13,
0x72, 0x1E, 0x8C, 0xC3, 0x60, 0x1E, 0xB9, 0x00, 0x01, 0x8E, 0xDB, 0x31, 0xF6, 0xBF, 0x00, 0x80,
0x8E, 0xC6, 0xFC, 0xF3, 0xA5, 0x1F, 0x61, 0xFF, 0x26, 0x5A, 0x7C, 0xBE, 0x93, 0x7D, 0xEB, 0x03,
0xBE, 0x99, 0x7D, 0xE8, 0x33, 0x00, 0xBE, 0x9C, 0x7D, 0xE8, 0x2D, 0x00, 0xCD, 0x18, 0xEB, 0xFE,
0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44, 0x00, 0x52, 0x64, 0x00, 0x20, 0x45, 0x72, 0x0D,
0x0A, 0x00, 0xBB, 0x01, 0x00, 0xB4, 0x0E, 0xCD, 0x10, 0xAC, 0x3C, 0x00, 0x75, 0xF4, 0xC3, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
initrd_info *g_initrd_img_list = NULL;
initrd_info *g_initrd_img_tail = NULL;
int g_initrd_img_count = 0;
@@ -479,7 +510,7 @@ 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 (0x%x).\n\n", ret);
grub_printf("This is NOT a standard Ventoy device and is NOT supported (%d).\n\n", ret);
grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n");
grub_printf("\n\nWill exit after 10 seconds ...... ");
@@ -497,6 +528,8 @@ static int ventoy_check_official_device(grub_device_t dev)
grub_uint64_t offset;
char devname[64];
grub_fs_t fs;
grub_uint8_t mbr[512];
grub_disk_t disk;
grub_device_t dev2;
char *label = NULL;
struct grub_partition *partition;
@@ -611,7 +644,27 @@ static int ventoy_check_official_device(grub_device_t dev)
grub_device_close(dev2);
}
/* MBR check */
disk = grub_disk_open(dev->disk->name);
if (!disk)
{
return ventoy_set_check_result(11);
}
grub_memset(mbr, 0, 512);
grub_disk_read(disk, 0, 0, 512, mbr);
grub_disk_close(disk);
g_check_mbr_data[92] = mbr[92];
g_check_mbr_data[102] = mbr[102];
g_check_mbr_data[103] = mbr[103];
grub_memcpy(g_check_mbr_data + 0x180, mbr + 0x180, 16);
if (grub_memcmp(g_check_mbr_data, mbr, 440))
{
return ventoy_set_check_result(12);
}
return ventoy_set_check_result(0);
}
@@ -2969,6 +3022,7 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar
{
int i = 0;
int pos = 0;
int defidx = 1;
char *buf = NULL;
char configfile[128];
install_template *node = NULL;
@@ -2993,9 +3047,13 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar
if (node->autosel >= 0 && node->autosel <= node->templatenum)
{
node->cursel = node->autosel - 1;
debug("Auto install template auto select %d\n", node->autosel);
return 0;
defidx = node->autosel;
if (node->timeout < 0)
{
node->cursel = node->autosel - 1;
debug("Auto install template auto select %d\n", node->autosel);
return 0;
}
}
buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF);
@@ -3004,24 +3062,31 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar
return 0;
}
if (node->timeout > 0)
{
vtoy_ssprintf(buf, pos, "set timeout=%d\n", node->timeout);
}
vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" {\n"
" echo %s\n}\n", "123");
" echo %s\n}\n", "");
for (i = 0; i < node->templatenum; i++)
{
vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n"
" echo 123\n}\n",
vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\"{\n"
" echo \"\"\n}\n",
node->templatepath[i].path);
}
g_ventoy_menu_esc = 1;
g_ventoy_suppress_esc = 1;
g_ventoy_suppress_esc_default = defidx;
grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos);
grub_script_execute_sourcecode(configfile);
g_ventoy_menu_esc = 0;
g_ventoy_suppress_esc = 0;
g_ventoy_suppress_esc_default = 1;
grub_free(buf);
@@ -3034,6 +3099,7 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg
{
int i = 0;
int pos = 0;
int defidx = 1;
char *buf = NULL;
char configfile[128];
persistence_config *node;
@@ -3058,9 +3124,13 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg
if (node->autosel >= 0 && node->autosel <= node->backendnum)
{
node->cursel = node->autosel - 1;
debug("Persistence image auto select %d\n", node->autosel);
return 0;
defidx = node->autosel;
if (node->timeout < 0)
{
node->cursel = node->autosel - 1;
debug("Persistence image auto select %d\n", node->autosel);
return 0;
}
}
buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF);
@@ -3069,25 +3139,32 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg
return 0;
}
if (node->timeout > 0)
{
vtoy_ssprintf(buf, pos, "set timeout=%d\n", node->timeout);
}
vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" {\n"
" echo %s\n}\n", "123");
" echo %s\n}\n", "");
for (i = 0; i < node->backendnum; i++)
{
vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n"
" echo 123\n}\n",
" echo \"\"\n}\n",
node->backendpath[i].path);
}
g_ventoy_menu_esc = 1;
g_ventoy_suppress_esc = 1;
g_ventoy_suppress_esc_default = defidx;
grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos);
grub_script_execute_sourcecode(configfile);
g_ventoy_menu_esc = 0;
g_ventoy_suppress_esc = 0;
g_ventoy_suppress_esc_default = 1;
grub_free(buf);

View File

@@ -21,6 +21,8 @@
#ifndef __VENTOY_DEF_H__
#define __VENTOY_DEF_H__
#define VTOY_MAX_DIR_DEPTH 32
#define VTOY_MAX_SCRIPT_BUF (4 * 1024 * 1024)
#define VTOY_PART_BUF_LEN (128 * 1024)
@@ -827,6 +829,7 @@ typedef struct install_template
int pathlen;
char isopath[256];
int timeout;
int autosel;
int cursel;
int templatenum;
@@ -858,6 +861,7 @@ typedef struct persistence_config
int pathlen;
char isopath[256];
int timeout;
int autosel;
int cursel;
int backendnum;
@@ -985,6 +989,7 @@ typedef struct menu_password
extern int g_ventoy_menu_esc;
extern int g_ventoy_suppress_esc;
extern int g_ventoy_suppress_esc_default;
extern int g_ventoy_last_entry;
extern int g_ventoy_memdisk_mode;
extern int g_ventoy_iso_raw;

View File

@@ -978,6 +978,12 @@ static grub_err_t ventoy_linux_locate_initrd(int filt, int *filtcnt)
}
}
/* skip hdt.img */
if (file->size <= VTOY_SIZE_1MB && grub_strcmp(node->name, "/boot/hdt.img") == 0)
{
continue;
}
if (grub_strcmp(file->fs->name, "iso9660") == 0)
{
node->iso_type = 0;

View File

@@ -602,6 +602,7 @@ static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk
{
int pathnum = 0;
int autosel = 0;
int timeout = 0;
char *pos = NULL;
const char *iso = NULL;
VTOY_JSON *pNode = NULL;
@@ -638,6 +639,18 @@ static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk
grub_printf("autosel: %d [FAIL]\n", autosel);
}
}
if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
{
if (timeout >= 0)
{
grub_printf("timeout: %d [OK]\n", timeout);
}
else
{
grub_printf("timeout: %d [FAIL]\n", timeout);
}
}
}
else
{
@@ -662,6 +675,18 @@ static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk
grub_printf("autosel: %d [FAIL]\n", autosel);
}
}
if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
{
if (timeout >= 0)
{
grub_printf("timeout: %d [OK]\n", timeout);
}
else
{
grub_printf("timeout: %d [FAIL]\n", timeout);
}
}
}
else
{
@@ -682,6 +707,7 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk
int type = 0;
int pathnum = 0;
int autosel = 0;
int timeout = 0;
const char *iso = NULL;
VTOY_JSON *pNode = NULL;
install_template *node = NULL;
@@ -729,6 +755,7 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk
node->templatenum = pathnum;
node->autosel = -1;
node->timeout = -1;
if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
{
if (autosel >= 0 && autosel <= pathnum)
@@ -736,6 +763,14 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk
node->autosel = autosel;
}
}
if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
{
if (timeout >= 0)
{
node->timeout = timeout;
}
}
if (g_install_template_head)
{
@@ -1175,6 +1210,7 @@ static int ventoy_plugin_pwd_check(VTOY_JSON *json, const char *isodisk)
static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk)
{
int autosel = 0;
int timeout = 0;
int pathnum = 0;
char *pos = NULL;
const char *iso = NULL;
@@ -1213,6 +1249,18 @@ static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk)
grub_printf("autosel: %d [FAIL]\n", autosel);
}
}
if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
{
if (timeout >= 0)
{
grub_printf("timeout: %d [OK]\n", timeout);
}
else
{
grub_printf("timeout: %d [FAIL]\n", timeout);
}
}
}
else
{
@@ -1231,6 +1279,7 @@ static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk)
static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
{
int autosel = 0;
int timeout = 0;
int pathnum = 0;
const char *iso = NULL;
VTOY_JSON *pNode = NULL;
@@ -1273,6 +1322,7 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
node->backendnum = pathnum;
node->autosel = -1;
node->timeout = -1;
if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel))
{
if (autosel >= 0 && autosel <= pathnum)
@@ -1280,6 +1330,14 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
node->autosel = autosel;
}
}
if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "timeout", &timeout))
{
if (timeout >= 0)
{
node->timeout = timeout;
}
}
if (g_persistence_head)
{

View File

@@ -375,6 +375,7 @@ grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **a
g_ventoy_menu_esc = 1;
g_ventoy_suppress_esc = 1;
g_ventoy_suppress_esc_default = 1;
grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, size);
grub_script_execute_sourcecode(configfile);
@@ -776,6 +777,67 @@ end:
return ret;
}
static int parse_custom_setup_path(char *cmdline, const char **path, char *exefile)
{
int i = 0;
int len = 0;
char *pos1 = NULL;
char *pos2 = NULL;
if ((cmdline[0] == 'x' || cmdline[0] == 'X') && cmdline[1] == ':')
{
pos1 = pos2 = cmdline + 3;
while (i < VTOY_MAX_DIR_DEPTH && *pos2)
{
while (*pos2 && *pos2 != '\\' && *pos2 != '/')
{
pos2++;
}
path[i++] = pos1;
if (*pos2 == 0)
{
break;
}
*pos2 = 0;
pos1 = pos2 + 1;
pos2 = pos1;
}
if (i == 0 || i >= VTOY_MAX_DIR_DEPTH)
{
return 1;
}
}
else
{
path[i++] = "Windows";
path[i++] = "System32";
path[i++] = cmdline;
}
pos1 = (char *)path[i - 1];
while (*pos1 != ' ' && *pos1 != '\t' && *pos1)
{
pos1++;
}
*pos1 = 0;
len = (int)grub_strlen(path[i - 1]);
if (len < 4 || grub_strcasecmp(path[i - 1] + len - 4, ".exe") != 0)
{
grub_snprintf(exefile, 256, "%s.exe", path[i - 1]);
path[i - 1] = exefile;
}
debug("custom setup: %d <%s>\n", i, path[i - 1]);
return 0;
}
static wim_directory_entry * search_replace_wim_dirent
(
grub_file_t file,
@@ -786,38 +848,44 @@ static wim_directory_entry * search_replace_wim_dirent
)
{
int ret;
char exefile[256] = {0};
char cmdline[256] = {0};
wim_directory_entry *wim_dirent = NULL;
wim_directory_entry *pecmd_dirent = NULL;
const char *peset_path[] = { "Windows", "System32", "peset.exe", NULL };
const char *pecmd_path[] = { "Windows", "System32", "pecmd.exe", NULL };
const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL };
const char *custom_path[VTOY_MAX_DIR_DEPTH + 1] = { NULL };
pecmd_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path);
debug("search pecmd.exe %p\n", pecmd_dirent);
if (pecmd_dirent)
{
ret = parse_registry_setup_cmdline(file, head, lookup, meta_data, dir, cmdline, sizeof(cmdline));
ret = parse_registry_setup_cmdline(file, head, lookup, meta_data, dir, cmdline, sizeof(cmdline) - 1);
if (0 == ret)
{
debug("registry setup cmdline:<%s>\n", cmdline);
ventoy_str_toupper(cmdline);
if (grub_strncmp(cmdline, "PECMD", 5) == 0)
if (grub_strncasecmp(cmdline, "PECMD", 5) == 0)
{
wim_dirent = pecmd_dirent;
}
else if (grub_strncmp(cmdline, "PESET", 5) == 0)
else if (grub_strncasecmp(cmdline, "PESET", 5) == 0)
{
wim_dirent = search_full_wim_dirent(meta_data, dir, peset_path);
debug("search peset.exe %p\n", wim_dirent);
}
else if (grub_strncmp(cmdline, "WINPESHL", 8) == 0)
else if (grub_strncasecmp(cmdline, "WINPESHL", 8) == 0)
{
wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path);
debug("search winpeshl.exe %p\n", wim_dirent);
}
else if (0 == parse_custom_setup_path(cmdline, custom_path, exefile))
{
wim_dirent = search_full_wim_dirent(meta_data, dir, custom_path);
debug("search custom path %p\n", wim_dirent);
}
if (wim_dirent)
{
@@ -982,6 +1050,7 @@ int ventoy_fill_windows_rtdata(void *buf, char *isopath)
{
char *pos = NULL;
char *script = NULL;
const char *env = NULL;
ventoy_windows_data *data = (ventoy_windows_data *)buf;
grub_memset(data, 0, sizeof(ventoy_windows_data));
@@ -1020,7 +1089,13 @@ int ventoy_fill_windows_rtdata(void *buf, char *isopath)
{
debug("injection archive not configed %s\n", pos);
}
env = grub_env_get("VTOY_WIN11_BYPASS_CHECK");
if (env && env[0] == '1' && env[1] == 0)
{
data->windows11_bypass_check = 1;
}
return 0;
}

View File

@@ -135,7 +135,8 @@ typedef struct ventoy_windows_data
{
char auto_install_script[384];
char injection_archive[384];
grub_uint8_t reserved[256];
grub_uint8_t windows11_bypass_check;
grub_uint8_t reserved[255];
}ventoy_windows_data;

View File

@@ -22,9 +22,16 @@ porteus_hook() {
$SED "/searching *for *\$CFG *file/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/porteus-disk.sh" -i $1
}
if $GREP -q exfat /proc/filesystems; then
vtPath=$($VTOY_PATH/tool/vtoydump -p $VTOY_PATH/ventoy_os_param)
vtPath=$($VTOY_PATH/tool/vtoydump -p $VTOY_PATH/ventoy_os_param)
echo $vtPath | $GREP -q " "
_vtRet1=$?
$GREP -q exfat /proc/filesystems
_vtRet2=$?
echo "_vtRet1=$_vtRet1 _vtRet2=$_vtRet2 ..." >> $VTLOG
if [ $_vtRet1 -ne 0 -a $_vtRet2 -eq 0 ]; then
vtFindFlag=0
$GREP '`value from`' /usr/* -r | $AWK -F: '{print $1}' | while read vtline; do
echo "hooking $vtline ..." >> $VTLOG
@@ -34,11 +41,19 @@ if $GREP -q exfat /proc/filesystems; then
if [ $vtFindFlag -eq 0 ]; then
if $GREP -q '`value from`' /linuxrc; then
echo "hooking linuxrc ..." >> $VTLOG
$SED "/searching *for *\$CFG *file/i$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/porteus-path.sh" -i /linuxrc
$SED "/searching *for *\$CFG *file/iFROM=\$(cat /porteus-from)" -i /linuxrc
$SED "/searching *for *\$CFG *file/iISO=\$(cat /porteus-from)" -i /linuxrc
vtFindFlag=1
if $GREP -q "searching *for *\$CFG *file" /linuxrc; then
echo "hooking linuxrc CFG..." >> $VTLOG
$SED "/searching *for *\$CFG *file/i$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/porteus-path.sh" -i /linuxrc
$SED "/searching *for *\$CFG *file/iFROM=\$(cat /porteus-from)" -i /linuxrc
$SED "/searching *for *\$CFG *file/iISO=\$(cat /porteus-from)" -i /linuxrc
vtFindFlag=1
else
echo "hooking linuxrc SGN..." >> $VTLOG
$SED "/searching *for *\$SGN *file/i$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/porteus-path.sh" -i /linuxrc
$SED "/searching *for *\$SGN *file/iFROM=\$(cat /porteus-from)" -i /linuxrc
$SED "/searching *for *\$SGN *file/iISO=\$(cat /porteus-from)" -i /linuxrc
vtFindFlag=1
fi
fi
fi
@@ -46,7 +61,7 @@ else
for vtfile in '/linuxrc' '/init'; do
if [ -e $vtfile ]; then
if ! $GREP -q ventoy $vtfile; then
echo "hooking $vtfile ..." >> $VTLOG
echo "hooking disk $vtfile ..." >> $VTLOG
porteus_hook $vtfile
fi
fi

View File

@@ -0,0 +1,70 @@
#!/ventoy/busybox/sh
#************************************************************************************
# 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/>.
#
#************************************************************************************
. /ventoy/hook/ventoy-hook-lib.sh
if is_ventoy_hook_finished; then
exit 0
fi
vtlog "####### $0 $* ########"
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
ventoy_os_install_dmsetup_by_fuse() {
vtlog "ventoy_os_install_dmsetup_by_fuse $*"
mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs
vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table
vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse
mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso
mount -t squashfs $VTOY_PATH/mnt/iso/pyabr/01-core.sb $VTOY_PATH/mnt/squashfs
KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*)
vtlog "insmod $KoName"
insmod $KoName
umount $VTOY_PATH/mnt/squashfs
umount $VTOY_PATH/mnt/iso
umount $VTOY_PATH/mnt/fuse
}
wait_for_usb_disk_ready
vtdiskname=$(get_ventoy_disk_name)
if [ "$vtdiskname" = "unknown" ]; then
vtlog "ventoy disk not found"
PATH=$VTPATH_OLD
exit 0
fi
modprobe fuse
modprobe cuse
vtKver=$(uname -r)
ventoy_os_install_dmsetup_by_fuse $vtdiskname $vtKver
ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace"
PATH=$VTPATH_OLD
set_ventoy_hook_finish

View File

@@ -0,0 +1,20 @@
#!/ventoy/busybox/sh
#************************************************************************************
# 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/>.
#
#************************************************************************************
$SED "/find_data/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/pyabr-disk.sh" -i /init

View File

@@ -23,6 +23,11 @@ $SED "s#.*livefs_root=.*find_livefs.*#$BUSYBOX_PATH/mount -t iso9660 /dev/mapper
if [ -e /init ] && $GREP -q '^mountroot$' /init; then
echo "Here before mountroot ..." >> $VTLOG
$SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i /init
if [ -f /scripts/init-premount/ORDER ]; then
$SED "/\/scripts\/init-premount\/partitioning/,+1d" -i /scripts/init-premount/ORDER
fi
else
echo "Use default hook ..." >> $VTLOG
ventoy_systemd_udevd_work_around

View File

@@ -94,6 +94,10 @@ ventoy_get_debian_distro() {
echo 'mocaccino'; return
fi
if $GREP -q '/pyabr/' /proc/cmdline; then
echo 'pyabr'; return
fi
echo 'default'
}

View File

@@ -0,0 +1,47 @@
#!/ventoy/busybox/sh
#************************************************************************************
# 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/>.
#
#************************************************************************************
. /ventoy/hook/ventoy-hook-lib.sh
if is_ventoy_hook_finished; then
exit 0
fi
vtlog "####### $0 $* ########"
VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH
wait_for_usb_disk_ready
vtdiskname=$(get_ventoy_disk_name)
if [ "$vtdiskname" = "unknown" ]; then
vtlog "ventoy disk not found"
PATH=$VTPATH_OLD
exit 0
fi
ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace"
ventoy_create_dev_ventoy_part
ln -s "../../ventoy1" /dev/disk/by-label/ESYSRESCUE
PATH=$VTPATH_OLD
set_ventoy_hook_finish

View File

@@ -0,0 +1,26 @@
#!/ventoy/busybox/sh
#************************************************************************************
# 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/>.
#
#************************************************************************************
. $VTOY_PATH/hook/ventoy-os-lib.sh
$SED "/maybe_break premount/i\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/esysrescue/ventoy-disk.sh" -i /init
if [ -f /scripts/casper-bottom/09format_esr_data_partition ]; then
$SED '/mkfs.vfat.*edev.3/icp -a /dev/dm-3 /dev/ventoy3' -i /scripts/casper-bottom/09format_esr_data_partition
fi

Binary file not shown.

31
INSTALL/grub/checksum.cfg Normal file
View File

@@ -0,0 +1,31 @@
menuentry "Calculate md5sum" --class=checksum_md5 {
md5sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
echo -e "\n\npress ENTER to exit ..."
read vtInputKey
}
menuentry "Calculate sha1sum" --class=checksum_sha1 {
sha1sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
echo -e "\n\npress ENTER to exit ..."
read vtInputKey
}
menuentry "Calculate sha256sum" --class=checksum_sha256 {
sha256sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
echo -e "\n\npress ENTER to exit ..."
read vtInputKey
}
menuentry "Calculate sha512sum" --class=checksum_sha512{
sha512sum "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}"
echo -e "\n\npress ENTER to exit ..."
read vtInputKey
}
menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {
echo 'Return ...'
}

View File

@@ -90,6 +90,28 @@ function ventoy_ext_menu {
fi
}
function ventoy_checksum {
if [ -f "${vtoy_iso_part}${VTOY_CHKSUM_FILE_PATH}" ]; then
configfile $prefix/checksum.cfg
fi
}
function ventoy_show_help {
if [ -f $prefix/help.tar.gz ]; then
if [ -z "$vtoy_help_txt_mem_addr" ]; then
vt_load_file_to_mem "auto" $prefix/help.tar.gz vtoy_help_txt_mem
fi
loopback vt_help_tarfs mem:${vtoy_help_txt_mem_addr}:size:${vtoy_help_txt_mem_size}
if [ -f "(vt_help_tarfs)/help/${VTOY_HELP_TXT_LANGUAGE}.txt" ]; then
cat "(vt_help_tarfs)/help/${VTOY_HELP_TXT_LANGUAGE}.txt"
else
cat "(vt_help_tarfs)/help/en_US.txt"
fi
loopback -d vt_help_tarfs
fi
}
function get_os_type {
set vtoy_os=Linux
@@ -133,6 +155,8 @@ function vt_check_compatible_pe {
#set compatible if ISO file is less than 80MB
if [ $vt_chosen_size -gt 33554432 -a $vt_chosen_size -le 83886080 ]; then
set ventoy_compatible=YES
elif [ -e $1/WEPE/WEPE.INI ]; then
set ventoy_compatible=YES
fi
return
@@ -223,7 +247,8 @@ function distro_specify_initrd_file {
vt_linux_specify_initrd_file /boot/initramfs-x86_64.img
elif [ -f (loop)/boot/isolinux/initramfs_data64.cpio.gz ]; then
vt_linux_specify_initrd_file /boot/isolinux/initramfs_data64.cpio.gz
elif [ -f (loop)/boot/initrd.img ]; then
vt_linux_specify_initrd_file /boot/initrd.img
fi
@@ -328,6 +353,8 @@ function distro_specify_initrd_file_phase2 {
vt_linux_specify_initrd_file /360Disk/initrd.gz
elif [ -f (loop)/porteus/initrd.xz ]; then
vt_linux_specify_initrd_file /porteus/initrd.xz
elif [ -f (loop)/pyabr/boot/initrfs.img ]; then
vt_linux_specify_initrd_file /pyabr/boot/initrfs.img
fi
}
@@ -1664,6 +1691,23 @@ function ventoy_img_recalbox {
vt_unset_boot_opt
}
function ventoy_img_esysrescue {
vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
ventoy_debug_pause
#boot image file
vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=esysrescue
vt_img_hook_root
set root=(vtimghd,1)
configfile (vtimghd,1)/boot/grub/grub.cfg
vt_img_unhook_root
vt_unset_boot_opt
}
function ventoy_img_batocera {
vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver"
vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit
@@ -1916,6 +1960,8 @@ function img_common_menuentry {
ventoy_img_tails
elif [ "$vtImgHd2Label" = "RECALBOX" ]; then
ventoy_img_recalbox
elif [ "$vtImgHd1Label" = "ESYSRESCUE" ]; then
ventoy_img_esysrescue
elif [ -e (vtimghd,1)/easy.sfs ]; then
ventoy_img_easyos
elif [ -e (vtimghd,1)/volumio.initrd ]; then
@@ -1963,7 +2009,7 @@ function img_unsupport_menuentry {
#############################################################
#############################################################
set VENTOY_VERSION="1.0.54"
set VENTOY_VERSION="1.0.56"
#ACPI not compatible with Window7/8, so disable by default
set VTOY_PARAM_NO_ACPI=1
@@ -1983,6 +2029,11 @@ set VTOY_F2_CMD="ventoy_power"
set VTOY_F4_CMD="ventoy_localboot"
set VTOY_F5_CMD="ventoy_diagnosis"
set VTOY_F6_CMD="ventoy_ext_menu"
set VTOY_HELP_CMD="ventoy_show_help"
set VTOY_CHKSUM_CMD="ventoy_checksum"
set VTOY_HELP_TXT_LANGUAGE="en_US"
set VTOY_CHKSUM_FILE_PATH="X"
if [ "$grub_platform" = "pc" ]; then
set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net"
@@ -2072,10 +2123,10 @@ fi
if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then
set VTOY_F3_CMD="vt_dynamic_menu 1 1"
set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Tools F6:ExMenu"
set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Tools F6:ExMenu Ctrl+h:Help"
else
set VTOY_F3_CMD="vt_dynamic_menu 1 0"
set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Tools F6:ExMenu"
set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Tools F6:ExMenu Ctrl+h:Help"
fi
@@ -2163,6 +2214,14 @@ export VTOY_ISO_RAW_STR
export VTOY_GRUB2_MODE_STR
export VTOY_WIMBOOT_MODE_STR
export VTOY_ISO_UEFI_DRV_STR
export VTOY_F2_CMD
export VTOY_F4_CMD
export VTOY_F5_CMD
export VTOY_F6_CMD
export VTOY_HELP_CMD
export VTOY_CHKSUM_CMD
export VTOY_HELP_TXT_LANGUAGE
export VTOY_CHKSUM_FILE_PATH
#special VTOY_DEFAULT_IMAGE process

View File

@@ -0,0 +1,16 @@
Ctrl+h - Display this help information
F1 - Memdisk Mode (Only for small WinPE/LiveCD ISO/IMG)
F2 - Reboot/Power off
F3 - Switch menu mode between Treeview <-> ListView
F4 - Boot Windows/Linux in local disk
F5 - Utilities
F6 - Load Custom Grub2 Menu
F7 - Switch between GUI Mode <-> TEXT Mode
Ctrl+m - Checksum image files (md5/sha1/sha256/sha512)
Ctrl+w - WIMBOOT Mode (Only for standard Windows ISO)
Ctrl+r - Grub2 Mode (Only for some Linux distros)
Ctrl+i - Compatible Mode (Just only for test)
Press ESC to return ......

View File

@@ -0,0 +1,16 @@
Ctrl+h - Yardım bilgilerini göster
F1 - Memdisk Modu başlatır(Yalnızca küçük WinPE/LiveCD ISO/IMG ler için bu modu kullanabilirsiniz)
F2 - Bilgisayarı Yeniden Başlat/Kapat
F3 - Ventoy Menü modu olarak,Klasör görünümü(Treeview) ile Liste görünümü(ListView) arasında geçiş yapmayı sağlar.
F4 - Bilgisayarınızda yüklü olan Windows yada Linux işletim sistemini, sabit diskten başlatır.
F5 - Ventoy Araçlar menüsü
F6 - Özelleştirilmiş Grub2 menüsünü yükler
F7 - Grafik Modu(GUI Mode) ile Metin Modu(Text Mode) arasında geçiş yapmayı sağlar
Ctrl+m - İndirilen imaj dosyalarının hatasız indirildiğini teyit etmek için "md5/sha1/sha256/sha512" değerlerini kontrol etmeyi sağlar
Ctrl+w - WIMBOOT Modu çalıştırmayı sağlar(Sadece normal Windows ISO ları için)
Ctrl+r - Grub2 Modu çalıştırmayı sağlar (Sadece bazı Linux dağıtımları için)
Ctrl+i - Uyumluluk Modu'nu (Compatible Mode) çalıştırmayı sağlar (Sadece bazı çalışmayan ISO ları test etmek için bu modu kullanabilirsiniz)
Geriye dönmek için ESC tuşuna basınız......

View File

@@ -0,0 +1,15 @@
Ctrl+h - 显示本帮助信息
F1 - 把文件加载到内存启动(只适用于文件很小的 WinPE/LiveCD等
F2 - 电源操作 (重启、关机)
F3 - 菜单显示模式切换。可在列表模式和目录模式之间自由切换。
F4 - 启动本地硬盘上的 Windows/Linux 等系统。
F5 - 各类工具
F6 - 加载自定义 GRUB2 菜单。
F7 - 界面在文本模式和图形模式之间切换。
Ctrl+m - 计算文件校验值md5/sha1/sha256/sha512
Ctrl+w - WIMBOOT 模式 (只适用于标准的 Windows ISO文件
Ctrl+r - Grub2 模式 (只适用于常见的一些 Linux 系统ISO文件
Ctrl+i - 兼容模式 (只用作调试目的,不能正式使用)
按 ESC 键返回 ......

View File

@@ -46,7 +46,7 @@ terminal-box: "terminal_box_*.png"
}
+ hbox{
left = 30%
left = 28%
top = 95%
width = 10%
height = 25

Binary file not shown.

Binary file not shown.

View File

@@ -980,29 +980,29 @@
"STR_INCORRECT_DIR":"Si prega di eseguire nella cartella corretta",
"STR_INCORRECT_TREE_DIR":"Non eseguire qui, scarica il pacchetto di installazione ed avvialo",
"STR_DEVICE":"Dispositivo",
"STR_LOCAL_VER":"Versione Locale di Ventoy",
"STR_LOCAL_VER":"Versione locale di Ventoy",
"STR_DISK_VER":"Ventoy nel dispositivo",
"STR_STATUS":"Stato - PRONTO",
"STR_INSTALL":"Installa",
"STR_UPDATE":"Aggiorna",
"STR_UPDATE_TIP":"L'aggiornamento è sicuro, i file presenti nel dispositivo rimarranno invariati.#@Continuare?",
"STR_INSTALL_TIP":"Il disco verrà formattato e tutti i dati saranno persi.#@Continuare?",
"STR_INSTALL_TIP2":"Il disco verrà formattato e tutti i dati saranno persi.#@Continuare?' (Seconda Verifica)",
"STR_INSTALL_TIP2":"Il disco verrà formattato e tutti i dati saranno persi.#@Continuare?' (seconda verifica)",
"STR_INSTALL_SUCCESS":"Congratulazioni!#@Ventoy è stato installato con successo nel dispositivo",
"STR_INSTALL_FAILED":"Si è verificato un errore durante l'installazione. Reinserisci il dispostivo e riprova. Controlla il file log.txt per i dettagli.",
"STR_INSTALL_FAILED":"Si è verificato un errore durante l'installazione. Riconnetti il dispostivo e riprova. Controlla il file log.txt per i dettagli.",
"STR_UPDATE_SUCCESS":"Congratulazioni!#@Ventoy è stato aggiornato con successo nel dispositivo",
"STR_UPDATE_FAILED":"Si è verificato un errore durante l'aggiornamento. Reinserisci il dispostivo e riprova. Controlla il file log.txt per i dettagli.",
"STR_UPDATE_FAILED":"Si è verificato un errore durante l'aggiornamento. Riconnetti il dispostivo e riprova. Controlla il file log.txt per i dettagli.",
"STR_WAIT_PROCESS":"Un processo è in esecuzione, attendere prego...",
"STR_MENU_OPTION":"Opzioni",
"STR_MENU_SECURE_BOOT":"Avvio protetto (secure boot)",
"STR_MENU_PART_CFG":"Configurazione della partizione",
"STR_BTN_OK":"OK",
"STR_BTN_CANCEL":"Annulla",
"STR_PRESERVE_SPACE":"Conserva spazio nella parte finale del disco",
"STR_PRESERVE_SPACE":"Riserva spazio nella parte finale del disco",
"STR_SPACE_VAL_INVALID":"Quantità di spazio da riservare non valida",
"STR_MENU_CLEAR":"Rimuovi Ventoy",
"STR_CLEAR_SUCCESS":"Ventoy è stato rimosso con successo dal dispositivo.",
"STR_CLEAR_FAILED":"Si è verificato un errore durante la rimozione di Ventoy dal dispositivo. Reinserisci il dispositivo e riprova. Controlla il file log.txt per maggiori dettagli",
"STR_CLEAR_FAILED":"Si è verificato un errore durante la rimozione di Ventoy dal dispositivo. Riconnetti il dispositivo e riprova. Controlla il file log.txt per maggiori dettagli",
"STR_MENU_PART_STYLE":"Stile Tabella delle partizioni",
"STR_DISK_2TB_MBR_ERROR":"Seleziona GPT per dischi con dimensioni maggiori di 2TB",
"STR_SHOW_ALL_DEV":"Mostra tutti i dispositivi",
@@ -1015,7 +1015,7 @@
"STR_WEB_SERVICE_BUSY":"Il servizio è occupato, riprova più tardi.",
"STR_MENU_VTSI_CREATE":"Genera file VTSI",
"STR_VTSI_CREATE_TIP":"Questa volta non scriverà sul dispositivo, ma genererà solo un file VTSI#@Continuare?",
"STR_VTSI_CREATE_SUCCESS":"File VTSI creato con successo!#@Puoiusare Rufus(3.15+)per scrivere sul dispositivo in modo da completare l'installazione di Ventoy.",
"STR_VTSI_CREATE_SUCCESS":"File VTSI creato con successo!#@Puoi usare Rufus (versione 3.15 o successiva) per scrivere sul dispositivo in modo da completare l'installazione di Ventoy.",
"STR_VTSI_CREATE_FAILED":"Creazione File VTSI non riuscito.",
"STRXXX":""
},
@@ -1828,11 +1828,11 @@
"STR_WEB_REQUEST_TIMEOUT":"Kommunikationsfel: Begäran tog för lång tid",
"STR_WEB_SERVICE_UNAVAILABLE":"Kommunikationsfel: Tjänsten är inte tillgänglig",
"STR_WEB_TOKEN_MISMATCH":"Daemon-status uppdaterad. Försök igen senare.",
"STR_WEB_SERVICE_BUSY":"Tjänster är upptagen. Försök igen senare.",
"STR_MENU_VTSI_CREATE":"Generate VTSI File",
"STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?",
"STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.",
"STR_VTSI_CREATE_FAILED":"VTSI file created failed.",
"STR_WEB_SERVICE_BUSY":"Tjänsten är upptagen. Försök igen senare.",
"STR_MENU_VTSI_CREATE":"Skapa VTSI-fil",
"STR_VTSI_CREATE_TIP":"Den här gången skrivs det inget till enheten, utan det skapas endast en VTSI-fil#@Fortsätta?",
"STR_VTSI_CREATE_SUCCESS":"VTSI-filen skapad!#@Använd Rufus (3.15+) till att skriva till enheten för att slutföra installationen av Ventoy.",
"STR_VTSI_CREATE_FAILED":"Misslyckades med att skapa VTSI-filen.",
"STRXXX":""
},
{
@@ -1987,5 +1987,56 @@
"STR_VTSI_CREATE_SUCCESS":"VTSI ֆայլը հաջողությամբ ստեղծվեց!#@Դուք կարող եք օգտագործել Rufus (3.15+) կրիչում ձայնագրելու համար, որպեսզի ավարտեք Ventoy-ի տեղադրումը:",
"STR_VTSI_CREATE_FAILED":"VTSI ֆայլի ստեղծումը ձախողվեց։",
"STRXXX":""
},
{
"name":"Finnish (suomi)",
"FontFamily":"Courier New",
"FontSize":16,
"Author":"heidi.wenger",
"STR_ERROR":"Virhe",
"STR_WARNING":"Varoitus",
"STR_INFO":"Tiedot",
"STR_INCORRECT_DIR":"Ole hyvä ja aja oikean kansion alla!",
"STR_INCORRECT_TREE_DIR":"Älä aja minua tässä, ole hyvä ja lataa julkaistu asennuspaketti, ja suorita ajo siellä.",
"STR_DEVICE":"Laite",
"STR_LOCAL_VER":"Ventoy paketissa",
"STR_DISK_VER":"Ventoy laitteessa",
"STR_STATUS":"Tila - VALMIS",
"STR_INSTALL":"Asenna",
"STR_UPDATE":"Päivitä",
"STR_UPDATE_TIP":"Päivytystoiminto on turvallinen, ISO -tiedostot pysyvät muuttumattomana.#@Jatketaanko?",
"STR_INSTALL_TIP":"Laite tullaan alustamaan ja tämän johdosta kaikki tieto sen sisällä menetetään.#@Jatketaanko?",
"STR_INSTALL_TIP2":"Laite tullaan alustamaan ja tämän johdosta kaikki tieto sen sisällä menetetään.#@Jatketaanko? (Kaksoistarkistus)",
"STR_INSTALL_SUCCESS":"Onnittelut!#@Ventoy on asennettu laitteeseen onnistuneesti.",
"STR_INSTALL_FAILED":"Asennuksen yhteydessä ilmeni virhe. Voit nypätä USB-laitteen irti ja koettaa uudelleen. Katso log.txt nähdäksesi yksityiskohdat. Mikäli toimi epäonnistuu aina, lue usein kysytyt kysymykset (FAQ) virallisella sivustolla.",
"STR_UPDATE_SUCCESS":"Onnittelut!#@Ventoy päivitettiin laitteeseen onnistuneesti.",
"STR_UPDATE_FAILED":"Päivityksen aikana ilmeni virhe. Voit nypätä USB-laitteen irti ja koettaa uudelleen. Katso log.txt nähdäksesi yksityiskohdat. Mikäli toimi epäonnistuu aina, lue usein kysytyt kysymykset (FAQ) virallisella sivustolla.",
"STR_WAIT_PROCESS":"Toimi on ajossa juuri nyt, ole hyvä ja odota...",
"STR_MENU_OPTION":"Vaihtoehto",
"STR_MENU_SECURE_BOOT":"Secure Boot (turvakäynnistys) -tuki",
"STR_MENU_PART_CFG":"Osioasetukset",
"STR_BTN_OK":"SELVÄ",
"STR_BTN_CANCEL":"Peruuta",
"STR_PRESERVE_SPACE":"Jätä hiukan vapaata tilaa levyn loppuun",
"STR_SPACE_VAL_INVALID":"Epäkelpo määrä tilavaraukselle",
"STR_MENU_CLEAR":"Poista Ventoy",
"STR_CLEAR_SUCCESS":"Ventoy on nyt poistettu laitteesta onnistuneesti.",
"STR_CLEAR_FAILED":"Ilmeni virhe poistettaessa Ventoyta levyltä. Voit nypätä laitteen irti ja koettaa uudelleen. Katso log.txt nähdäksesi yksityiskohdat.",
"STR_MENU_PART_STYLE":"Osiotyyli",
"STR_DISK_2TB_MBR_ERROR":"Ole hyvä ja valitse GPT laitteille joissa on tilavuutta yli 2 teratavua",
"STR_SHOW_ALL_DEV":"Näytä kaikki laitteet",
"STR_PART_ALIGN_4KB":"Järjestä osiot 4Kt mukaisesti",
"STR_WEB_COMMUNICATION_ERR":"Kommunikaatiovirhe:",
"STR_WEB_REMOTE_ABNORMAL":"Kommunikaatiovirhe: epätavanomainen etävaste",
"STR_WEB_REQUEST_TIMEOUT":"Kommunikaatiovirhe: pyynnön aikavaste ylittyi",
"STR_WEB_SERVICE_UNAVAILABLE":"Kommunikaatiovirhe: palvelu on tavoittamattomissa",
"STR_WEB_TOKEN_MISMATCH":"Taustaohjelman tila päivittyi, ole hyvä ja yritä myöhemmin uudelleen.",
"STR_WEB_SERVICE_BUSY":"Palvelu ruuhkautunut, ole hyvä ja yritä myöhemmin uudelleen.",
"STR_MENU_VTSI_CREATE":"Luo VTSI -tiedosto",
"STR_VTSI_CREATE_TIP":"Tällä kerralla laitteeseen ei kirjoiteta, vaan luodaan ainoastaan VTSI -tiedosto#@Jatketaanko?",
"STR_VTSI_CREATE_SUCCESS":"VTSI -tiedosto luotiin onnistuneesti!#@Voit käyttää Rufus-ohjelmaa(3.15+) kirjoittaaksesi sen laitteeseen viimeistelläksesi Ventoy-asennuksen.",
"STR_VTSI_CREATE_FAILED":"VTSI -tiedoston luominen epäonnistui.",
"STRXXX":""
}
]

View File

@@ -16,7 +16,7 @@ You can copy many image files at a time and ventoy will give you a boot menu to
x86 Legacy BIOS, IA32 UEFI, x86_64 UEFI, ARM64 UEFI and MIPS64EL UEFI are supported in the same way.<br/>
Both MBR and GPT partition style are supported in the same way.<br/>
Most type of OS supported(Windows/WinPE/Linux/Unix/ChromeOS/Vmware/Xen...) <br/>
730+ ISO files are tested (<a href="https://www.ventoy.net/en/isolist.html">List</a>). 90%+ distros in <a href="https://distrowatch.com/">distrowatch.com</a> supported (<a href="https://www.ventoy.net/en/distrowatch.html">Details</a>). <br/>
760+ ISO files are tested (<a href="https://www.ventoy.net/en/isolist.html">List</a>). 90%+ distros in <a href="https://distrowatch.com/">distrowatch.com</a> supported (<a href="https://www.ventoy.net/en/distrowatch.html">Details</a>). <br/>
<br/>Official Website: <a href=https://www.ventoy.net>https://www.ventoy.net</a>
</h4>
@@ -52,7 +52,7 @@ VMware ESXi, Citrix XenServer, Xen XCP-ng
* FAT32/exFAT/NTFS/UDF/XFS/Ext2(3)(4) supported for main partition
* ISO files larger than 4GB supported
* Native boot menu style for Legacy & UEFI
* Most type of OS supported, 730+ iso files tested
* Most type of OS supported, 760+ iso files tested
* Linux vDisk boot supported
* Not only boot but also complete installation process
* Menu dynamically switchable between List/TreeView mode

View File

@@ -0,0 +1,57 @@
/******************************************************************************
* DiskService.h
*
* Copyright (c) 2021, 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 __DISKSERVICE_H__
#define __DISKSERVICE_H__
typedef struct VDS_PARA
{
UINT64 Attr;
GUID Type;
GUID Id;
WCHAR Name[36];
ULONG NameLen;
ULONGLONG Offset;
}VDS_PARA;
//VDS com
int VDS_Init(void);
BOOL VDS_CleanDisk(int DriveIndex);
BOOL VDS_DeleteAllPartitions(int DriveIndex);
BOOL VDS_DeleteVtoyEFIPartition(int DriveIndex);
BOOL VDS_ChangeVtoyEFIAttr(int DriveIndex, UINT64 Attr);
BOOL VDS_CreateVtoyEFIPart(int DriveIndex, UINT64 Offset);
BOOL VDS_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset);
BOOL VDS_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset);
BOOL VDS_FormatVtoyEFIPart(int DriveIndex, UINT64 Offset);
//diskpart.exe
BOOL DSPT_CleanDisk(int DriveIndex);
//
// Internel define
//
#endif

View File

@@ -0,0 +1,84 @@
/******************************************************************************
* DiskService_diskpart.c
*
* Copyright (c) 2021, 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 <Windows.h>
#include <winternl.h>
#include <commctrl.h>
#include <initguid.h>
#include <vds.h>
#include "Ventoy2Disk.h"
#include "DiskService.h"
STATIC BOOL IsDiskpartExist(void)
{
BOOL ret;
ret = IsFileExist("C:\\Windows\\system32\\diskpart.exe");
if (!ret)
{
Log("diskpart.exe not exist");
}
return ret;
}
STATIC BOOL DSPT_CommProc(const char *Cmd)
{
CHAR CmdBuf[MAX_PATH];
CHAR CmdFile[MAX_PATH];
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
GetCurrentDirectoryA(sizeof(CmdBuf), CmdBuf);
sprintf_s(CmdFile, sizeof(CmdFile), "%s\\ventoy\\diskpart_%u.txt", CmdBuf, GetCurrentProcessId());
SaveBufToFile(CmdFile, Cmd, strlen(Cmd));
GetStartupInfoA(&Si);
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
sprintf_s(CmdBuf, sizeof(CmdBuf), "C:\\Windows\\system32\\diskpart.exe /s \"%s\"", CmdFile);
Log("CreateProcess <%s>", CmdBuf);
CreateProcessA(NULL, CmdBuf, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
Log("Wair process ...");
WaitForSingleObject(Pi.hProcess, INFINITE);
Log("Process finished...");
DeleteFileA(CmdFile);
return TRUE;
}
BOOL DSPT_CleanDisk(int DriveIndex)
{
CHAR CmdBuf[128];
Log("CleanDiskByDiskpart <%d>", DriveIndex);
if (!IsDiskpartExist())
{
return FALSE;
}
sprintf_s(CmdBuf, sizeof(CmdBuf), "select disk %d\r\nclean\r\n", DriveIndex);
return DSPT_CommProc(CmdBuf);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
/******************************************************************************
* DiskService_wsma.c
*
* Copyright (c) 2021, 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 <Windows.h>
#include <winternl.h>
#include <commctrl.h>
#include <initguid.h>
#include <vds.h>
#include "Ventoy2Disk.h"
#include "DiskService.h"

View File

@@ -20,279 +20,16 @@
*/
#include <Windows.h>
#include <time.h>
#include <winternl.h>
#include <commctrl.h>
#include <initguid.h>
#include <vds.h>
#include "resource.h"
#include "Language.h"
#include "Ventoy2Disk.h"
#include "fat_filelib.h"
#include "ff.h"
/*
* Some code and functions in the file are copied from rufus.
* https://github.com/pbatard/rufus
*/
#define VDS_SET_ERROR SetLastError
#define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService)
#define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This)
#define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum)
#define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This))
#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))
#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))
#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This))
#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)
#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)
#define IVdsSwProvider_Release(This) (This)->lpVtbl->Release(This)
#define IVdsPack_QueryDisks(This, ppEnum) (This)->lpVtbl->QueryDisks(This, ppEnum)
#define IVdsDisk_GetProperties(This, pDiskProperties) (This)->lpVtbl->GetProperties(This, pDiskProperties)
#define IVdsDisk_Release(This) (This)->lpVtbl->Release(This)
#define IVdsDisk_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
#define IVdsAdvancedDisk_QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions) (This)->lpVtbl->QueryPartitions(This, ppPartitionPropArray, plNumberOfPartitions)
#define IVdsAdvancedDisk_DeletePartition(This, ullOffset, bForce, bForceProtected) (This)->lpVtbl->DeletePartition(This, ullOffset, bForce, bForceProtected)
#define IVdsAdvancedDisk_Clean(This, bForce, bForceOEM, bFullClean, ppAsync) (This)->lpVtbl->Clean(This, bForce, bForceOEM, bFullClean, ppAsync)
#define IVdsAdvancedDisk_Release(This) (This)->lpVtbl->Release(This)
#define IEnumVdsObject_Next(This, celt, ppObjectArray, pcFetched) (This)->lpVtbl->Next(This, celt, ppObjectArray, pcFetched)
#define IVdsPack_QueryVolumes(This, ppEnum) (This)->lpVtbl->QueryVolumes(This, ppEnum)
#define IVdsVolume_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
#define IVdsVolume_Release(This) (This)->lpVtbl->Release(This)
#define IVdsVolumeMF3_QueryVolumeGuidPathnames(This, pwszPathArray, pulNumberOfPaths) (This)->lpVtbl->QueryVolumeGuidPathnames(This,pwszPathArray,pulNumberOfPaths)
#define IVdsVolumeMF3_FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync) (This)->lpVtbl->FormatEx2(This, pwszFileSystemTypeName, usFileSystemRevision, ulDesiredUnitAllocationSize, pwszLabel, Options, ppAsync)
#define IVdsVolumeMF3_Release(This) (This)->lpVtbl->Release(This)
#define IVdsVolume_GetProperties(This, pVolumeProperties) (This)->lpVtbl->GetProperties(This,pVolumeProperties)
#define IVdsAsync_Cancel(This) (This)->lpVtbl->Cancel(This)
#define IVdsAsync_QueryStatus(This,pHrResult,pulPercentCompleted) (This)->lpVtbl->QueryStatus(This,pHrResult,pulPercentCompleted)
#define IVdsAsync_Wait(This,pHrResult,pAsyncOut) (This)->lpVtbl->Wait(This,pHrResult,pAsyncOut)
#define IVdsAsync_Release(This) (This)->lpVtbl->Release(This)
#define IUnknown_QueryInterface(This, a, b) (This)->lpVtbl->QueryInterface(This,a,b)
#define IUnknown_Release(This) (This)->lpVtbl->Release(This)
/*
* Delete all the partitions from a disk, using VDS
* Mostly copied from https://social.msdn.microsoft.com/Forums/vstudio/en-US/b90482ae-4e44-4b08-8731-81915030b32a/createpartition-using-vds-interface-throw-error-enointerface-dcom?forum=vcgeneral
*/
BOOL DeletePartitions(DWORD DriveIndex, BOOL OnlyPart2)
{
BOOL r = FALSE;
HRESULT hr;
ULONG ulFetched;
wchar_t wPhysicalName[48];
IVdsServiceLoader *pLoader;
IVdsService *pService;
IEnumVdsObject *pEnum;
IUnknown *pUnk;
swprintf_s(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex);
// Initialize COM
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);
// Create a VDS Loader Instance
hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
&IID_IVdsServiceLoader, (void **)&pLoader);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not create VDS Loader Instance: %u", LASTERR);
goto out;
}
// Load the VDS Service
hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);
IVdsServiceLoader_Release(pLoader);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not load VDS Service: %u", LASTERR);
goto out;
}
// Wait for the Service to become ready if needed
hr = IVdsService_WaitForServiceReady(pService);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("VDS Service is not ready: %u", LASTERR);
goto out;
}
// Query the VDS Service Providers
hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not query VDS Service Providers: %u", LASTERR);
goto out;
}
while (IEnumVdsObject_Next(pEnum, 1, &pUnk, &ulFetched) == S_OK) {
IVdsProvider *pProvider;
IVdsSwProvider *pSwProvider;
IEnumVdsObject *pEnumPack;
IUnknown *pPackUnk;
// Get VDS Provider
hr = IUnknown_QueryInterface(pUnk, &IID_IVdsProvider, (void **)&pProvider);
IUnknown_Release(pUnk);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not get VDS Provider: %u", LASTERR);
goto out;
}
// Get VDS Software Provider
hr = IVdsSwProvider_QueryInterface(pProvider, &IID_IVdsSwProvider, (void **)&pSwProvider);
IVdsProvider_Release(pProvider);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not get VDS Software Provider: %u", LASTERR);
goto out;
}
// Get VDS Software Provider Packs
hr = IVdsSwProvider_QueryPacks(pSwProvider, &pEnumPack);
IVdsSwProvider_Release(pSwProvider);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not get VDS Software Provider Packs: %u", LASTERR);
goto out;
}
// Enumerate Provider Packs
while (IEnumVdsObject_Next(pEnumPack, 1, &pPackUnk, &ulFetched) == S_OK) {
IVdsPack *pPack;
IEnumVdsObject *pEnumDisk;
IUnknown *pDiskUnk;
hr = IUnknown_QueryInterface(pPackUnk, &IID_IVdsPack, (void **)&pPack);
IUnknown_Release(pPackUnk);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not query VDS Software Provider Pack: %u", LASTERR);
goto out;
}
// Use the pack interface to access the disks
hr = IVdsPack_QueryDisks(pPack, &pEnumDisk);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not query VDS disks: %u", LASTERR);
goto out;
}
// List disks
while (IEnumVdsObject_Next(pEnumDisk, 1, &pDiskUnk, &ulFetched) == S_OK) {
VDS_DISK_PROP diskprop;
VDS_PARTITION_PROP* prop_array;
LONG i, prop_array_size;
IVdsDisk *pDisk;
IVdsAdvancedDisk *pAdvancedDisk;
// Get the disk interface.
hr = IUnknown_QueryInterface(pDiskUnk, &IID_IVdsDisk, (void **)&pDisk);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not query VDS Disk Interface: %u", LASTERR);
goto out;
}
// Get the disk properties
hr = IVdsDisk_GetProperties(pDisk, &diskprop);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not query VDS Disk Properties: %u", LASTERR);
goto out;
}
// Isolate the disk we want
if (_wcsicmp(wPhysicalName, diskprop.pwszName) != 0) {
IVdsDisk_Release(pDisk);
continue;
}
// Instantiate the AdvanceDisk interface for our disk.
hr = IVdsDisk_QueryInterface(pDisk, &IID_IVdsAdvancedDisk, (void **)&pAdvancedDisk);
IVdsDisk_Release(pDisk);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not access VDS Advanced Disk interface: %u", LASTERR);
goto out;
}
// Query the partition data, so we can get the start offset, which we need for deletion
hr = IVdsAdvancedDisk_QueryPartitions(pAdvancedDisk, &prop_array, &prop_array_size);
if (hr == S_OK) {
Log("Deleting ALL partition(s) from disk '%S':", diskprop.pwszName);
// Now go through each partition
for (i = 0; i < prop_array_size; i++) {
Log("* Partition %d (offset: %lld, size: %llu)", prop_array[i].ulPartitionNumber,
prop_array[i].ullOffset, (ULONGLONG)prop_array[i].ullSize);
if (OnlyPart2)
{
if (prop_array[i].ullOffset == 2048 * 512 || prop_array[i].ullSize != 32 * 1024 * 1024)
{
Log("Skip this partition...");
continue;
}
}
hr = IVdsAdvancedDisk_DeletePartition(pAdvancedDisk, prop_array[i].ullOffset, TRUE, TRUE);
if (hr != S_OK) {
r = FALSE;
VDS_SET_ERROR(hr);
Log("Could not delete partitions: %u", LASTERR);
}
else {
Log("Delete this partitions success");
}
}
r = TRUE;
}
else {
Log("No partition to delete on disk '%S'", diskprop.pwszName);
r = TRUE;
}
CoTaskMemFree(prop_array);
#if 0
// Issue a Clean while we're at it
HRESULT hr2 = E_FAIL;
ULONG completed;
IVdsAsync* pAsync;
hr = IVdsAdvancedDisk_Clean(pAdvancedDisk, TRUE, FALSE, FALSE, &pAsync);
while (SUCCEEDED(hr)) {
if (IS_ERROR(FormatStatus)) {
IVdsAsync_Cancel(pAsync);
break;
}
hr = IVdsAsync_QueryStatus(pAsync, &hr2, &completed);
if (SUCCEEDED(hr)) {
hr = hr2;
if (hr == S_OK)
break;
if (hr == VDS_E_OPERATION_PENDING)
hr = S_OK;
}
Sleep(500);
}
if (hr != S_OK) {
VDS_SET_ERROR(hr);
Log("Could not clean disk: %s", LASTERR);
}
#endif
IVdsAdvancedDisk_Release(pAdvancedDisk);
goto out;
}
}
}
out:
return r;
}
#include "DiskService.h"
static DWORD GetVentoyVolumeName(int PhyDrive, UINT64 StartSectorId, CHAR *NameBuf, UINT32 BufLen, BOOL DelSlash)
{
@@ -1095,25 +832,33 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
int len = 0;
int writelen = 0;
int partwrite = 0;
int Pos = PT_WRITE_VENTOY_START;
DWORD dwSize = 0;
BOOL bRet;
unsigned char *data = NULL;
LARGE_INTEGER liCurrentPosition;
LARGE_INTEGER liNewPosition;
BYTE *CheckBuf = NULL;
Log("FormatPart2Fat %llu...", StartSectorId);
CheckBuf = malloc(SIZE_1MB);
if (!CheckBuf)
{
Log("Failed to malloc check buf");
return 1;
}
rc = ReadWholeFileToBuf(VENTOY_FILE_DISK_IMG, 0, (void **)&data, &len);
if (rc)
{
Log("Failed to read img file %p %u", data, len);
free(CheckBuf);
return 1;
}
liCurrentPosition.QuadPart = StartSectorId * 512;
SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);
Log("Set file pointer: %llu New pointer:%llu", liCurrentPosition.QuadPart, liNewPosition.QuadPart);
SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);
memset(g_part_img_buf, 0, sizeof(g_part_img_buf));
@@ -1141,7 +886,34 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
goto End;
}
PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i);
PROGRESS_BAR_SET_POS(Pos);
if (i % 2 == 0)
{
Pos++;
}
}
//Read and check the data
liCurrentPosition.QuadPart = StartSectorId * 512;
SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);
for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)
{
bRet = ReadFile(hDrive, CheckBuf, SIZE_1MB, &dwSize, NULL);
Log("Read part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR);
if (!bRet || memcmp(CheckBuf, g_part_img_buf[0] + i * SIZE_1MB, SIZE_1MB))
{
Log("### [Check Fail] The data write and read does not match");
rc = 1;
goto End;
}
PROGRESS_BAR_SET_POS(Pos);
if (i % 2 == 0)
{
Pos++;
}
}
}
else
@@ -1178,7 +950,7 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
VentoyProcSecureBoot(g_SecureBoot);
for (int i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)
for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)
{
dwSize = 0;
bRet = WriteFile(hDrive, g_part_img_buf[i], SIZE_1MB, &dwSize, NULL);
@@ -1189,8 +961,35 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
rc = 1;
goto End;
}
PROGRESS_BAR_SET_POS(Pos);
if (i % 2 == 0)
{
Pos++;
}
}
PROGRESS_BAR_SET_POS(PT_WRITE_VENTOY_START + i);
//Read and check the data
liCurrentPosition.QuadPart = StartSectorId * 512;
SetFilePointerEx(hDrive, liCurrentPosition, &liNewPosition, FILE_BEGIN);
for (i = 0; i < VENTOY_EFI_PART_SIZE / SIZE_1MB; i++)
{
bRet = ReadFile(hDrive, CheckBuf, SIZE_1MB, &dwSize, NULL);
Log("Read part data bRet:%u dwSize:%u code:%u", bRet, dwSize, LASTERR);
if (!bRet || memcmp(CheckBuf, g_part_img_buf[i], SIZE_1MB))
{
Log("### [Check Fail] The data write and read does not match");
rc = 1;
goto End;
}
PROGRESS_BAR_SET_POS(Pos);
if (i % 2 == 0)
{
Pos++;
}
}
}
else
@@ -1204,6 +1003,7 @@ static int FormatPart2Fat(HANDLE hDrive, UINT64 StartSectorId)
End:
if (data) free(data);
if (CheckBuf)free(CheckBuf);
if (partwrite)
{
@@ -1369,7 +1169,7 @@ int ClearVentoyFromPhyDrive(HWND hWnd, PHY_DRIVE_INFO *pPhyDrive, char *pDrvLett
PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);
if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE))
if (!VDS_DeleteAllPartitions(pPhyDrive->PhyDrive))
{
Log("Notice: Could not delete partitions: %u", GetLastError());
}
@@ -1772,7 +1572,7 @@ End:
}
int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)
int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle, int TryId)
{
int i;
int rc = 0;
@@ -1789,7 +1589,7 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)
UINT64 Part1SectorCount = 0;
UINT64 Part2StartSector = 0;
Log("InstallVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>",
Log("InstallVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId,
PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,
GetHumanReadableGBSize(pPhyDrive->SizeInBytes));
@@ -1856,9 +1656,11 @@ int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle)
PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);
if (!DeletePartitions(pPhyDrive->PhyDrive, FALSE))
if (!VDS_DeleteAllPartitions(pPhyDrive->PhyDrive))
{
Log("Notice: Could not delete partitions: %u", GetLastError());
Log("Notice: Could not delete partitions: 0x%x", GetLastError());
rc = 1;
goto End;
}
Log("Deleting all partitions ......................... OK");
@@ -2026,108 +1828,251 @@ End:
return rc;
}
int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
static BOOL BackupDataBeforeCleanDisk(int PhyDrive, UINT64 DiskSize, BYTE **pBackup)
{
int i;
int rc = 0;
BOOL ForceMBR = FALSE;
HANDLE hVolume;
HANDLE hDrive;
DWORD Status;
DWORD dwSize;
BOOL bRet;
CHAR DriveName[] = "?:\\";
CHAR DriveLetters[MAX_PATH] = { 0 };
UINT64 StartSector;
DWORD dwSize;
DWORD dwStatus;
BOOL Return = FALSE;
BOOL ret = FALSE;
BYTE *backup = NULL;
HANDLE hDrive = INVALID_HANDLE_VALUE;
LARGE_INTEGER liCurPosition;
LARGE_INTEGER liNewPosition;
Log("BackupDataBeforeCleanDisk %d", PhyDrive);
backup = malloc(SIZE_1MB * 3);
if (!backup)
{
goto out;
}
hDrive = GetPhysicalHandle(PhyDrive, FALSE, FALSE, FALSE);
if (hDrive == INVALID_HANDLE_VALUE)
{
goto out;
}
//read first 1MB
dwStatus = SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
if (dwStatus != 0)
{
goto out;
}
dwSize = 0;
ret = ReadFile(hDrive, backup, SIZE_1MB, &dwSize, NULL);
if ((!ret) || (dwSize != SIZE_1MB))
{
Log("Failed to read %d %u 0x%x", ret, dwSize, LASTERR);
goto out;
}
liCurPosition.QuadPart = DiskSize - (SIZE_1MB * 2);
liNewPosition.QuadPart = 0;
if (0 == SetFilePointerEx(hDrive, liCurPosition, &liNewPosition, FILE_BEGIN) ||
liNewPosition.QuadPart != liCurPosition.QuadPart)
{
goto out;
}
dwSize = 0;
ret = ReadFile(hDrive, backup + SIZE_1MB, 2 * SIZE_1MB, &dwSize, NULL);
if ((!ret) || (dwSize != 2 * SIZE_1MB))
{
Log("Failed to read %d %u 0x%x", ret, dwSize, LASTERR);
goto out;
}
*pBackup = backup;
backup = NULL; //For don't free later
Return = TRUE;
out:
CHECK_CLOSE_HANDLE(hDrive);
if (backup)
free(backup);
return Return;
}
static BOOL WriteBackupDataToDisk(HANDLE hDrive, UINT64 Offset, BYTE *Data, DWORD Length)
{
DWORD dwSize = 0;
BOOL ret = FALSE;
LARGE_INTEGER liCurPosition;
LARGE_INTEGER liNewPosition;
Log("WriteBackupDataToDisk %llu %p %u", Offset, Data, Length);
liCurPosition.QuadPart = Offset;
liNewPosition.QuadPart = 0;
if (0 == SetFilePointerEx(hDrive, liCurPosition, &liNewPosition, FILE_BEGIN) ||
liNewPosition.QuadPart != liCurPosition.QuadPart)
{
return FALSE;
}
ret = WriteFile(hDrive, Data, Length, &dwSize, NULL);
if ((!ret) || dwSize != Length)
{
Log("Failed to write %d %u %u", ret, dwSize, LASTERR);
return FALSE;
}
Log("WriteBackupDataToDisk %llu %p %u success", Offset, Data, Length);
return TRUE;
}
int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId)
{
int i;
int rc = 0;
int MaxRetry = 3;
BOOL ForceMBR = FALSE;
BOOL Esp2Basic = FALSE;
BOOL ChangeAttr = FALSE;
BOOL CleanDisk = FALSE;
HANDLE hVolume;
HANDLE hDrive;
DWORD Status;
DWORD dwSize;
BOOL bRet;
CHAR DriveName[] = "?:\\";
CHAR DriveLetters[MAX_PATH] = { 0 };
UINT64 StartSector;
UINT64 ReservedMB = 0;
MBR_HEAD BootImg;
MBR_HEAD MBR;
VTOY_GPT_INFO *pGptInfo = NULL;
UINT8 ReservedData[4096];
MBR_HEAD BootImg;
MBR_HEAD MBR;
BYTE *pBackup = NULL;
VTOY_GPT_INFO *pGptInfo = NULL;
UINT8 ReservedData[4096];
Log("UpdateVentoy2PhyDrive %s PhyDrive%d <<%s %s %dGB>>",
pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,
GetHumanReadableGBSize(pPhyDrive->SizeInBytes));
Log("UpdateVentoy2PhyDrive try%d %s PhyDrive%d <<%s %s %dGB>>", TryId,
pPhyDrive->PartStyle ? "GPT" : "MBR", pPhyDrive->PhyDrive, pPhyDrive->VendorId, pPhyDrive->ProductId,
GetHumanReadableGBSize(pPhyDrive->SizeInBytes));
PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);
PROGRESS_BAR_SET_POS(PT_LOCK_FOR_CLEAN);
Log("Lock disk for umount ............................ ");
Log("Lock disk for umount ............................ ");
hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE);
if (hDrive == INVALID_HANDLE_VALUE)
{
Log("Failed to open physical disk");
return 1;
}
hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, FALSE, FALSE);
if (hDrive == INVALID_HANDLE_VALUE)
{
Log("Failed to open physical disk");
return 1;
}
if (pPhyDrive->PartStyle)
{
pGptInfo = malloc(sizeof(VTOY_GPT_INFO));
if (!pGptInfo)
{
return 1;
}
if (pPhyDrive->PartStyle)
{
pGptInfo = malloc(sizeof(VTOY_GPT_INFO));
if (!pGptInfo)
{
return 1;
}
memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));
memset(pGptInfo, 0, sizeof(VTOY_GPT_INFO));
// Read GPT Info
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL);
// Read GPT Info
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
ReadFile(hDrive, pGptInfo, sizeof(VTOY_GPT_INFO), &dwSize, NULL);
//MBR will be used to compare with local boot image
memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD));
//MBR will be used to compare with local boot image
memcpy(&MBR, &pGptInfo->MBR, sizeof(MBR_HEAD));
StartSector = pGptInfo->PartTbl[1].StartLBA;
Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector);
StartSector = pGptInfo->PartTbl[1].StartLBA;
Log("GPT StartSector in PartTbl:%llu", (ULONGLONG)StartSector);
ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048;
Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);
}
else
{
// Read MBR
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512) - 33) / 2048;
Log("GPT Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);
}
else
{
// Read MBR
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
StartSector = MBR.PartTbl[1].StartSectorId;
Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector);
StartSector = MBR.PartTbl[1].StartSectorId;
Log("MBR StartSector in PartTbl:%llu", (ULONGLONG)StartSector);
ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048;
Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);
}
ReservedMB = (pPhyDrive->SizeInBytes / 512 - (StartSector + VENTOY_EFI_PART_SIZE / 512)) / 2048;
Log("MBR Reserved Disk Space:%llu MB", (ULONGLONG)ReservedMB);
}
//Read Reserved Data
SetFilePointer(hDrive, 512 * 2040, NULL, FILE_BEGIN);
ReadFile(hDrive, ReservedData, sizeof(ReservedData), &dwSize, NULL);
//Read Reserved Data
SetFilePointer(hDrive, 512 * 2040, NULL, FILE_BEGIN);
ReadFile(hDrive, ReservedData, sizeof(ReservedData), &dwSize, NULL);
GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));
GetLettersBelongPhyDrive(pPhyDrive->PhyDrive, DriveLetters, sizeof(DriveLetters));
if (DriveLetters[0] == 0)
{
Log("No drive letter was assigned...");
}
else
{
// Unmount all mounted volumes that belong to this drive
// Do it in reverse so that we always end on the first volume letter
for (i = (int)strlen(DriveLetters); i > 0; i--)
{
DriveName[0] = DriveLetters[i - 1];
if (IsVentoyLogicalDrive(DriveName[0]))
{
Log("%s is ventoy logical drive", DriveName);
bRet = DeleteVolumeMountPointA(DriveName);
Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, LASTERR);
break;
}
}
}
if (DriveLetters[0] == 0)
{
Log("No drive letter was assigned...");
}
else
{
// Unmount all mounted volumes that belong to this drive
// Do it in reverse so that we always end on the first volume letter
for (i = (int)strlen(DriveLetters); i > 0; i--)
{
DriveName[0] = DriveLetters[i - 1];
if (IsVentoyLogicalDrive(DriveName[0]))
{
Log("%s is ventoy logical drive", DriveName);
bRet = DeleteVolumeMountPointA(DriveName);
Log("Delete mountpoint %s ret:%u code:%u", DriveName, bRet, LASTERR);
break;
}
}
}
// It kind of blows, but we have to relinquish access to the physical drive
// for VDS to be able to delete the partitions that reside on it...
DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);
CHECK_CLOSE_HANDLE(hDrive);
// It kind of blows, but we have to relinquish access to the physical drive
// for VDS to be able to delete the partitions that reside on it...
DeviceIoControl(hDrive, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);
CHECK_CLOSE_HANDLE(hDrive);
if (pPhyDrive->PartStyle == 1)
{
Log("TryId=%d EFI GPT partition type is 0x%llx", TryId, pPhyDrive->Part2GPTAttr);
PROGRESS_BAR_SET_POS(PT_DEL_ALL_PART);
if (TryId == 1)
{
Log("Change GPT partition type to ESP");
if (VDS_ChangeVtoyEFI2ESP(pPhyDrive->PhyDrive, StartSector * 512))
{
Esp2Basic = TRUE;
Sleep(1000);
}
}
else if (TryId == 2)
{
Log("Change GPT partition attribute");
if (VDS_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, 0x8000000000000001))
{
ChangeAttr = TRUE;
Sleep(1000);
}
}
else if (TryId == 3)
{
Log("Clean disk GPT partition table");
if (BackupDataBeforeCleanDisk(pPhyDrive->PhyDrive, pPhyDrive->SizeInBytes, &pBackup))
{
Log("Success to backup data before clean");
CleanDisk = TRUE;
VDS_CleanDisk(pPhyDrive->PhyDrive);
Sleep(1000);
}
else
{
Log("Failed to backup data before clean");
}
}
}
PROGRESS_BAR_SET_POS(PT_LOCK_FOR_WRITE);
Log("Lock disk for update ............................ ");
@@ -2143,30 +2088,71 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
Log("Lock volume for update .......................... ");
hVolume = INVALID_HANDLE_VALUE;
Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, StartSector, DriveLetters, sizeof(DriveLetters), TRUE);
//If we change VTOYEFI to ESP, it can not have s volume name, so don't try to get it.
if (CleanDisk)
{
WriteBackupDataToDisk(hDrive, pPhyDrive->SizeInBytes - (2 * SIZE_1MB), pBackup + SIZE_1MB, 2 * SIZE_1MB);
Status = ERROR_NOT_FOUND;
}
else if (Esp2Basic)
{
Status = ERROR_NOT_FOUND;
}
else
{
for (i = 0; i < MaxRetry; i++)
{
Status = GetVentoyVolumeName(pPhyDrive->PhyDrive, StartSector, DriveLetters, sizeof(DriveLetters), TRUE);
if (ERROR_SUCCESS == Status)
{
break;
}
else
{
Log("==== Volume not found, wait and retry %d... ====", i);
Sleep(2);
}
}
}
if (ERROR_SUCCESS == Status)
{
Log("Now lock and dismount volume <%s>", DriveLetters);
hVolume = CreateFileA(DriveLetters,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL);
for (i = 0; i < MaxRetry; i++)
{
hVolume = CreateFileA(DriveLetters,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
NULL);
if (hVolume == INVALID_HANDLE_VALUE)
{
Log("Failed to create file volume, errcode:%u, wait and retry ...", LASTERR);
Sleep(2000);
}
else
{
break;
}
}
if (hVolume == INVALID_HANDLE_VALUE)
{
Log("Failed to create file volume, errcode:%u", LASTERR);
rc = 1;
goto End;
}
else
{
bRet = DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);
Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet, LASTERR);
bRet = DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);
Log("FSCTL_LOCK_VOLUME bRet:%u code:%u", bRet, LASTERR);
bRet = DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);
Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet, LASTERR);
bRet = DeviceIoControl(hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);
Log("FSCTL_DISMOUNT_VOLUME bRet:%u code:%u", bRet, LASTERR);
}
}
else if (ERROR_NOT_FOUND == Status)
{
@@ -2178,18 +2164,17 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
goto End;
}
if (!TryWritePart2(hDrive, StartSector))
{
if (pPhyDrive->PartStyle == 0)
{
ForceMBR = TRUE;
Log("Try write failed, now delete partition 2...");
Log("Try write failed, now delete partition 2 for MBR...");
CHECK_CLOSE_HANDLE(hDrive);
Log("Now delete partition 2...");
DeletePartitions(pPhyDrive->PhyDrive, TRUE);
VDS_DeleteVtoyEFIPartition(pPhyDrive->PhyDrive);
hDrive = GetPhysicalHandle(pPhyDrive->PhyDrive, TRUE, TRUE, FALSE);
if (hDrive == INVALID_HANDLE_VALUE)
@@ -2199,6 +2184,12 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
goto End;
}
}
else
{
Log("TryWritePart2 failed ....");
rc = 1;
goto End;
}
}
PROGRESS_BAR_SET_POS(PT_FORMAT_PART2);
@@ -2269,6 +2260,13 @@ int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive)
}
}
if (CleanDisk)
{
WriteBackupDataToDisk(hDrive, 4 * 512, pBackup + 4 * 512, SIZE_1MB - 4 * 512);
WriteBackupDataToDisk(hDrive, 0, pBackup, 4 * 512);
free(pBackup);
}
//Refresh Drive Layout
DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &dwSize, NULL);
@@ -2285,6 +2283,29 @@ End:
CHECK_CLOSE_HANDLE(hDrive);
if (Esp2Basic)
{
Log("Recover GPT partition type to basic");
VDS_ChangeVtoyEFI2Basic(pPhyDrive->PhyDrive, StartSector * 512);
}
if (pPhyDrive->PartStyle == 1)
{
if (ChangeAttr || ((pPhyDrive->Part2GPTAttr >> 56) != 0xC0))
{
Log("Change EFI partition attr %u <0x%llx> to <0x%llx>", ChangeAttr, pPhyDrive->Part2GPTAttr, 0xC000000000000001ULL);
if (VDS_ChangeVtoyEFIAttr(pPhyDrive->PhyDrive, 0xC000000000000001ULL))
{
Log("Change EFI partition attr success");
pPhyDrive->Part2GPTAttr = 0xC000000000000001ULL;
}
else
{
Log("Change EFI partition attr failed");
}
}
}
if (pGptInfo)
{
free(pGptInfo);

View File

@@ -1,7 +1,8 @@
/******************************************************************************
* Utility.c
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
* Copyright (c) 2021, longpanda <admin@ventoy.net>
* Copyright (c) 2011-2020, Pete Batard <pete@akeo.ie>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -20,6 +21,25 @@
#include <Windows.h>
#include "Ventoy2Disk.h"
void TraceOut(const char *Fmt, ...)
{
va_list Arg;
int Len = 0;
FILE *File = NULL;
char szBuf[1024];
va_start(Arg, Fmt);
Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg);
va_end(Arg);
fopen_s(&File, VENTOY_FILE_LOG, "a+");
if (File)
{
fwrite(szBuf, 1, Len, File);
fclose(File);
}
}
void Log(const char *Fmt, ...)
{
va_list Arg;
@@ -92,6 +112,22 @@ BOOL IsPathExist(BOOL Dir, const char *Fmt, ...)
return TRUE;
}
int SaveBufToFile(const CHAR *FileName, const void *Buffer, int BufLen)
{
FILE *File = NULL;
void *Data = NULL;
fopen_s(&File, FileName, "wb");
if (File == NULL)
{
Log("Failed to open file %s", FileName);
return 1;
}
fwrite(Buffer, 1, BufLen, File);
fclose(File);
return 0;
}
int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen)
{
@@ -205,73 +241,239 @@ BOOL IsWow64(void)
return bIsWow64;
}
void DumpWindowsVersion(void)
/*
* Some code and functions in the file are copied from rufus.
* https://github.com/pbatard/rufus
*/
/* Windows versions */
enum WindowsVersion {
WINDOWS_UNDEFINED = -1,
WINDOWS_UNSUPPORTED = 0,
WINDOWS_XP = 0x51,
WINDOWS_2003 = 0x52, // Also XP_64
WINDOWS_VISTA = 0x60, // Also Server 2008
WINDOWS_7 = 0x61, // Also Server 2008_R2
WINDOWS_8 = 0x62, // Also Server 2012
WINDOWS_8_1 = 0x63, // Also Server 2012_R2
WINDOWS_10_PREVIEW1 = 0x64,
WINDOWS_10 = 0xA0, // Also Server 2016, also Server 2019
WINDOWS_11 = 0xB0, // Also Server 2022
WINDOWS_MAX
};
static const char* GetEdition(DWORD ProductType)
{
int Bit;
BOOL WsVer;
DWORD Major, Minor;
ULONGLONG MajorEqual, MinorEqual;
OSVERSIONINFOEXA Ver1, Ver2;
const CHAR *Ver = NULL;
CHAR WinVer[256] = { 0 };
// From: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo
// These values can be found in the winnt.h header.
switch (ProductType) {
case 0x00000000: return ""; // Undefined
case 0x00000001: return "Ultimate";
case 0x00000002: return "Home Basic";
case 0x00000003: return "Home Premium";
case 0x00000004: return "Enterprise";
case 0x00000005: return "Home Basic N";
case 0x00000006: return "Business";
case 0x00000007: return "Standard Server";
case 0x00000008: return "Datacenter Server";
case 0x00000009: return "Smallbusiness Server";
case 0x0000000A: return "Enterprise Server";
case 0x0000000B: return "Starter";
case 0x00000010: return "Business N";
case 0x00000011: return "Web Server";
case 0x00000012: return "Cluster Server";
case 0x00000013: return "Home Server";
case 0x0000001A: return "Home Premium N";
case 0x0000001B: return "Enterprise N";
case 0x0000001C: return "Ultimate N";
case 0x00000022: return "Home Premium Server";
case 0x0000002F: return "Starter N";
case 0x00000030: return "Pro";
case 0x00000031: return "Pro N";
case 0x00000042: return "Starter E";
case 0x00000043: return "Home Basic E";
case 0x00000044: return "Premium E";
case 0x00000045: return "Pro E";
case 0x00000046: return "Enterprise E";
case 0x00000047: return "Ultimate E";
case 0x00000048: return "Enterprise Eval";
case 0x00000054: return "Enterprise N Eval";
case 0x00000057: return "Thin PC";
case 0x0000006F: return "Core Connected";
case 0x00000070: return "Pro Student";
case 0x00000071: return "Core Connected N";
case 0x00000072: return "Pro Student N";
case 0x00000073: return "Core Connected Single Language";
case 0x00000074: return "Core Connected China";
case 0x00000079: return "Edu";
case 0x0000007A: return "Edu N";
case 0x0000007D: return "Enterprise S";
case 0x0000007E: return "Enterprise S N";
case 0x0000007F: return "Pro S";
case 0x00000080: return "Pro S N";
case 0x00000081: return "Enterprise S Eval";
case 0x00000082: return "Enterprise S N Eval";
case 0x0000008A: return "Pro Single Language";
case 0x0000008B: return "Pro China";
case 0x0000008C: return "Enterprise Subscription";
case 0x0000008D: return "Enterprise Subscription N";
case 0x00000095: return "Utility VM";
case 0x000000A1: return "Pro Workstation";
case 0x000000A2: return "Pro Workstation N";
case 0x000000A4: return "Pro for Education";
case 0x000000A5: return "Pro for Education N";
case 0x000000AB: return "Enterprise G"; // I swear Microsoft are just making up editions...
case 0x000000AC: return "Enterprise G N";
case 0x000000B6: return "Core OS";
case 0x000000B7: return "Cloud E";
case 0x000000B8: return "Cloud E N";
case 0x000000BD: return "Lite";
case 0xABCDABCD: return "(Unlicensed)";
default: return "(Unknown Edition)";
}
}
memset(&Ver1, 0, sizeof(Ver1));
memset(&Ver2, 0, sizeof(Ver2));
#define is_x64 IsWow64
#define static_strcpy safe_strcpy
#define REGKEY_HKCU HKEY_CURRENT_USER
#define REGKEY_HKLM HKEY_LOCAL_MACHINE
static int nWindowsVersion = WINDOWS_UNDEFINED;
static int nWindowsBuildNumber = -1;
static char WindowsVersionStr[128] = "";
/* Helpers for 32 bit registry operations */
/*
* Read a generic registry key value. If a short key_name is used, assume that
* it belongs to the application and create the app subkey if required
*/
static __inline BOOL _GetRegistryKey(HKEY key_root, const char* key_name, DWORD reg_type,
LPBYTE dest, DWORD dest_size)
{
const char software_prefix[] = "SOFTWARE\\";
char long_key_name[MAX_PATH] = { 0 };
BOOL r = FALSE;
size_t i;
LONG s;
HKEY hSoftware = NULL, hApp = NULL;
DWORD dwType = -1, dwSize = dest_size;
memset(dest, 0, dest_size);
if (key_name == NULL)
return FALSE;
for (i = strlen(key_name); i>0; i--) {
if (key_name[i] == '\\')
break;
}
if (i > 0) {
// Prefix with "SOFTWARE" if needed
if (_strnicmp(key_name, software_prefix, sizeof(software_prefix)-1) != 0) {
if (i + sizeof(software_prefix) >= sizeof(long_key_name))
return FALSE;
strcpy_s(long_key_name, sizeof(long_key_name), software_prefix);
strcat_s(long_key_name, sizeof(long_key_name), key_name);
long_key_name[sizeof(software_prefix)+i - 1] = 0;
}
else {
if (i >= sizeof(long_key_name))
return FALSE;
static_strcpy(long_key_name, key_name);
long_key_name[i] = 0;
}
i++;
if (RegOpenKeyExA(key_root, long_key_name, 0, KEY_READ, &hApp) != ERROR_SUCCESS) {
hApp = NULL;
goto out;
}
}
else {
if (RegOpenKeyExA(key_root, "SOFTWARE", 0, KEY_READ | KEY_CREATE_SUB_KEY, &hSoftware) != ERROR_SUCCESS) {
hSoftware = NULL;
goto out;
}
}
s = RegQueryValueExA(hApp, &key_name[i], NULL, &dwType, (LPBYTE)dest, &dwSize);
// No key means default value of 0 or empty string
if ((s == ERROR_FILE_NOT_FOUND) || ((s == ERROR_SUCCESS) && (dwType == reg_type) && (dwSize > 0))) {
r = TRUE;
}
out:
if (hSoftware != NULL)
RegCloseKey(hSoftware);
if (hApp != NULL)
RegCloseKey(hApp);
return r;
}
#define GetRegistryKey32(root, key, pval) _GetRegistryKey(root, key, REG_DWORD, (LPBYTE)pval, sizeof(DWORD))
static __inline INT32 ReadRegistryKey32(HKEY root, const char* key) {
DWORD val;
GetRegistryKey32(root, key, &val);
return (INT32)val;
}
/*
* Modified from smartmontools' os_win32.cpp
*/
void GetWindowsVersion(void)
{
OSVERSIONINFOEXA vi, vi2;
DWORD dwProductType;
const char* w = 0;
const char* w64 = "32 bit";
char *vptr;
size_t vlen;
unsigned major, minor;
ULONGLONG major_equal, minor_equal;
BOOL ws;
nWindowsVersion = WINDOWS_UNDEFINED;
static_strcpy(WindowsVersionStr, "Windows Undefined");
Ver1.dwOSVersionInfoSize = sizeof(Ver1);
// suppress the C4996 warning for GetVersionExA
#pragma warning(push)
#pragma warning(disable:4996)
if (!GetVersionExA((OSVERSIONINFOA *)&Ver1))
{
memset(&Ver1, 0, sizeof(Ver1));
Ver1.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if (!GetVersionExA((OSVERSIONINFOA *)&Ver1))
{
memset(&vi, 0, sizeof(vi));
vi.dwOSVersionInfoSize = sizeof(vi);
if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
memset(&vi, 0, sizeof(vi));
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if (!GetVersionExA((OSVERSIONINFOA *)&vi))
return;
}
}
#pragma warning(pop)
if (Ver1.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if (Ver1.dwMajorVersion > 6 || (Ver1.dwMajorVersion == 6 && Ver1.dwMinorVersion >= 2))
{
// GetVersionEx() has problem on some Windows version
if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
MajorEqual = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
for (Major = Ver1.dwMajorVersion; Major <= 9; Major++)
{
memset(&Ver2, 0, sizeof(Ver2));
Ver2.dwOSVersionInfoSize = sizeof(Ver2);
Ver2.dwMajorVersion = Major;
if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) {
// Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the actual OS version
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
// And starting with Windows 10 Preview 2, Windows enforces the use of the application/supportedOS
// manifest in order for VerSetConditionMask() to report the ACTUAL OS major and minor...
if (!VerifyVersionInfoA(&Ver2, VER_MAJORVERSION, MajorEqual))
{
major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
for (major = vi.dwMajorVersion; major <= 9; major++) {
memset(&vi2, 0, sizeof(vi2));
vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMajorVersion = major;
if (!VerifyVersionInfoA(&vi2, VER_MAJORVERSION, major_equal))
continue;
}
if (Ver1.dwMajorVersion < Major)
{
Ver1.dwMajorVersion = Major;
Ver1.dwMinorVersion = 0;
if (vi.dwMajorVersion < major) {
vi.dwMajorVersion = major; vi.dwMinorVersion = 0;
}
MinorEqual = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
for (Minor = Ver1.dwMinorVersion; Minor <= 9; Minor++)
{
memset(&Ver2, 0, sizeof(Ver2));
Ver2.dwOSVersionInfoSize = sizeof(Ver2);
Ver2.dwMinorVersion = Minor;
if (!VerifyVersionInfoA(&Ver2, VER_MINORVERSION, MinorEqual))
{
minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
for (minor = vi.dwMinorVersion; minor <= 9; minor++) {
memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2);
vi2.dwMinorVersion = minor;
if (!VerifyVersionInfoA(&vi2, VER_MINORVERSION, minor_equal))
continue;
}
Ver1.dwMinorVersion = Minor;
vi.dwMinorVersion = minor;
break;
}
@@ -279,84 +481,81 @@ void DumpWindowsVersion(void)
}
}
if (Ver1.dwMajorVersion <= 0xF && Ver1.dwMinorVersion <= 0xF)
{
WsVer = (Ver1.wProductType <= VER_NT_WORKSTATION);
switch ((Ver1.dwMajorVersion << 4) | Ver2.dwMinorVersion)
{
case 0x51:
{
Ver = "XP";
break;
}
case 0x52:
{
Ver = GetSystemMetrics(89) ? "Server 2003 R2" : "Server 2003";
break;
}
case 0x60:
{
Ver = WsVer ? "Vista" : "Server 2008";
break;
}
case 0x61:
{
Ver = WsVer ? "7" : "Server 2008 R2";
break;
}
case 0x62:
{
Ver = WsVer ? "8" : "Server 2012";
break;
}
case 0x63:
{
Ver = WsVer ? "8.1" : "Server 2012 R2";
break;
}
case 0x64:
{
Ver = WsVer ? "10 (Preview 1)" : "Server 10 (Preview 1)";
break;
}
case 0xA0:
{
Ver = WsVer ? "10" : ((Ver1.dwBuildNumber > 15000) ? "Server 2019" : "Server 2016");
break;
}
default:
{
Ver = "10 or later";
if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
ws = (vi.wProductType <= VER_NT_WORKSTATION);
nWindowsVersion = vi.dwMajorVersion << 4 | vi.dwMinorVersion;
switch (nWindowsVersion) {
case WINDOWS_XP: w = "XP";
break;
case WINDOWS_2003: w = (ws ? "XP_64" : (!GetSystemMetrics(89) ? "Server 2003" : "Server 2003_R2"));
break;
case WINDOWS_VISTA: w = (ws ? "Vista" : "Server 2008");
break;
case WINDOWS_7: w = (ws ? "7" : "Server 2008_R2");
break;
case WINDOWS_8: w = (ws ? "8" : "Server 2012");
break;
case WINDOWS_8_1: w = (ws ? "8.1" : "Server 2012_R2");
break;
case WINDOWS_10_PREVIEW1: w = (ws ? "10 (Preview 1)" : "Server 10 (Preview 1)");
break;
// Starting with Windows 10 Preview 2, the major is the same as the public-facing version
case WINDOWS_10:
if (vi.dwBuildNumber < 20000) {
w = (ws ? "10" : ((vi.dwBuildNumber < 17763) ? "Server 2016" : "Server 2019"));
break;
}
nWindowsVersion = WINDOWS_11;
// Fall through
case WINDOWS_11: w = (ws ? "11" : "Server 2022");
break;
default:
if (nWindowsVersion < WINDOWS_XP)
nWindowsVersion = WINDOWS_UNSUPPORTED;
else
w = "12 or later";
break;
}
}
}
Bit = IsWow64() ? 64 : 32;
if (is_x64())
w64 = "64-bit";
if (Ver1.wServicePackMinor)
{
safe_sprintf(WinVer, "Windows %s SP%u.%u %d-bit", Ver, Ver1.wServicePackMajor, Ver1.wServicePackMinor, Bit);
}
else if (Ver1.wServicePackMajor)
{
safe_sprintf(WinVer, "Windows %s SP%u %d-bit", Ver, Ver1.wServicePackMajor, Bit);
}
GetProductInfo(vi.dwMajorVersion, vi.dwMinorVersion, vi.wServicePackMajor, vi.wServicePackMinor, &dwProductType);
vptr = WindowsVersionStr;
vlen = sizeof(WindowsVersionStr) - 1;
if (!w)
sprintf_s(vptr, vlen, "%s %u.%u %s", (vi.dwPlatformId == VER_PLATFORM_WIN32_NT ? "NT" : "??"),
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);
else if (vi.wServicePackMinor)
sprintf_s(vptr, vlen, "%s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, w64);
else if (vi.wServicePackMajor)
sprintf_s(vptr, vlen, "%s SP%u %s", w, vi.wServicePackMajor, w64);
else
{
safe_sprintf(WinVer, "Windows %s %d-bit", Ver, Bit);
}
sprintf_s(vptr, vlen, "%s%s%s, %s",
w, (dwProductType != PRODUCT_UNDEFINED) ? " " : "", GetEdition(dwProductType), w64);
if (((Ver1.dwMajorVersion << 4) | Ver2.dwMinorVersion) >= 0x62)
{
Log("Windows Version : %s (Build %u)", WinVer, Ver1.dwBuildNumber);
}
else
{
Log("Windows Version : %s", WinVer);
// Add the build number (including UBR if available) for Windows 8.0 and later
nWindowsBuildNumber = vi.dwBuildNumber;
if (nWindowsVersion >= 0x62) {
int nUbr = ReadRegistryKey32(REGKEY_HKLM, "Software\\Microsoft\\Windows NT\\CurrentVersion\\UBR");
vptr = WindowsVersionStr + strlen(WindowsVersionStr);
vlen = sizeof(WindowsVersionStr) - strlen(WindowsVersionStr) - 1;
if (nUbr > 0)
sprintf_s(vptr, vlen, " (Build %d.%d)", nWindowsBuildNumber, nUbr);
else
sprintf_s(vptr, vlen, " (Build %d)", nWindowsBuildNumber);
}
}
void DumpWindowsVersion(void)
{
GetWindowsVersion();
Log("Windows Version: <<Windows %s>>", WindowsVersionStr);
return;
}

View File

@@ -71,7 +71,7 @@ int ParseCmdLineOption(LPSTR lpCmdLine)
return 0;
}
static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector)
static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UINT64 *Part2StartSector, UINT64 *GptPart2Attr)
{
int i;
BOOL bRet;
@@ -149,7 +149,15 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
if (memcmp(pGpt->PartTbl[1].Name, L"VTOYEFI", 7 * 2))
{
Log("Invalid ventoy efi part name");
if (pGpt->PartTbl[1].Name[0])
{
Log("Invalid ventoy efi part name <%S>", pGpt->PartTbl[1].Name);
}
else
{
Log("Invalid ventoy efi part name <null>");
}
return FALSE;
}
@@ -170,6 +178,7 @@ static BOOL IsVentoyPhyDrive(int PhyDrive, UINT64 SizeBytes, MBR_HEAD *pMBR, UIN
return FALSE;
}
*GptPart2Attr = pGpt->PartTbl[1].Attr;
*Part2StartSector = pGpt->PartTbl[1].StartLBA;
memcpy(pMBR, &(pGpt->MBR), sizeof(MBR_HEAD));
@@ -225,6 +234,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
int Letter = 'A';
int Id = 0;
int LetterCount = 0;
UINT64 Part2GPTAttr = 0;
UINT64 Part2StartSector = 0;
PHY_DRIVE_INFO *CurDrive;
MBR_HEAD MBR;
@@ -247,6 +257,7 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
for (i = 0; i < DriveCount; i++)
{
Part2GPTAttr = 0;
CurDrive = pDriveList + i;
CurDrive->Id = -1;
@@ -278,10 +289,11 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
}
}
if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector))
if (IsVentoyPhyDrive(CurDrive->PhyDrive, CurDrive->SizeInBytes, &MBR, &Part2StartSector, &Part2GPTAttr))
{
memcpy(&(CurDrive->MBR), &MBR, sizeof(MBR));
CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0;
CurDrive->Part2GPTAttr = Part2GPTAttr;
GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion), &(CurDrive->SecureBootSupport));
Log("PhyDrive %d is Ventoy Disk ver:%s SecureBoot:%u", CurDrive->PhyDrive, CurDrive->VentoyVersion, CurDrive->SecureBootSupport);

View File

@@ -53,6 +53,7 @@
}
#define LASTERR GetLastError()
#define RET_LASTERR (ret ? 0 : LASTERR)
#pragma pack(1)
typedef struct PART_TABLE
@@ -153,12 +154,13 @@ typedef struct PHY_DRIVE_INFO
BOOL SecureBootSupport;
MBR_HEAD MBR;
UINT64 Part2GPTAttr;
}PHY_DRIVE_INFO;
typedef enum PROGRESS_POINT
{
PT_START = 0,
PT_LOCK_FOR_CLEAN,
PT_LOCK_FOR_CLEAN = 8,
PT_DEL_ALL_PART,
PT_LOCK_FOR_WRITE,
PT_FORMAT_PART1,
@@ -185,6 +187,7 @@ extern HFONT g_language_normal_font;
extern HFONT g_language_bold_font;
extern int g_FilterUSB;
void TraceOut(const char *Fmt, ...);
void Log(const char *Fmt, ...);
BOOL IsPathExist(BOOL Dir, const char *Fmt, ...);
void DumpWindowsVersion(void);
@@ -207,11 +210,12 @@ int Ventoy2DiskInit(void);
int Ventoy2DiskDestroy(void);
PHY_DRIVE_INFO * GetPhyDriveInfoById(int Id);
int ParseCmdLineOption(LPSTR lpCmdLine);
int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle);
int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive);
int InstallVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int PartStyle, int TryId);
int UpdateVentoy2PhyDrive(PHY_DRIVE_INFO *pPhyDrive, int TryId);
int VentoyFillBackupGptHead(VTOY_GPT_INFO *pInfo, VTOY_GPT_HDR *pHead);
int VentoyFillWholeGpt(UINT64 DiskSizeBytes, VTOY_GPT_INFO *pInfo);
void SetProgressBarPos(int Pos);
int SaveBufToFile(const CHAR *FileName, const void *Buffer, int BufLen);
int ReadWholeFileToBuf(const CHAR *FileName, int ExtLen, void **Bufer, int *BufLen);
int INIT unxz(unsigned char *in, int in_size,
int(*fill)(void *dest, unsigned int size),

View File

@@ -92,6 +92,9 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="crc32.c" />
<ClCompile Include="DiskService_diskpart.c" />
<ClCompile Include="DiskService_vds.c" />
<ClCompile Include="DiskService_wmsa.c" />
<ClCompile Include="fat_io_lib\fat_access.c" />
<ClCompile Include="fat_io_lib\fat_cache.c" />
<ClCompile Include="fat_io_lib\fat_filelib.c" />
@@ -115,6 +118,7 @@
<ClCompile Include="xz-embedded-20130513\linux\lib\decompress_unxz.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="DiskService.h" />
<ClInclude Include="fat_io_lib\fat_access.h" />
<ClInclude Include="fat_io_lib\fat_cache.h" />
<ClInclude Include="fat_io_lib\fat_defs.h" />

View File

@@ -81,6 +81,15 @@
<ClCompile Include="VentoyJson.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="DiskService_diskpart.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="DiskService_vds.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="DiskService_wmsa.c">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Ventoy2Disk.h">
@@ -143,6 +152,9 @@
<ClInclude Include="VentoyJson.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="DiskService.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Ventoy2Disk.rc">

Binary file not shown.

View File

@@ -25,6 +25,7 @@
#include <Windows.h>
#include <time.h>
#include <winternl.h>
#include <commctrl.h>
#include <initguid.h>
@@ -471,6 +472,7 @@ int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive)
char cmdline[MAX_PATH] = { 0 };
wchar_t wexe_path[MAX_PATH], *wcmdline;
int cur_pid;
time_t starttime, curtime;
Log("FindProcessOccupyDisk for PhyDrive %d", pPhyDrive->PhyDrive);
@@ -504,11 +506,30 @@ int FindProcessOccupyDisk(HANDLE hDrive, PHY_DRIVE_INFO *pPhyDrive)
if (buffer == NULL)
goto out;
for (i = 0;; i++) {
Log("handles->NumberOfHandles = %lu", (ULONG)handles->NumberOfHandles);
if (handles->NumberOfHandles > 10000)
{
goto out;
}
starttime = time(NULL);
for (i = 0; i < handles->NumberOfHandles; i++) {
ULONG attempts = 8;
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo =
(i < handles->NumberOfHandles) ? &handles->Handles[i] : NULL;
//limit the search time
if ((i % 100) == 0)
{
curtime = time(NULL);
if (curtime - starttime > 10)
{
break;
}
}
if ((dupHandle != NULL) && (processHandle != NtCurrentProcess())) {
pfNtClose(dupHandle);
dupHandle = NULL;
@@ -663,8 +684,12 @@ out:
else
Log("NOTE: Could not identify the process(es) or service(s) accessing %S", _wHandleName);
PhFree(buffer);
PhFree(handles);
if (buffer)
PhFree(buffer);
if (handles)
PhFree(handles);
PhDestroyHeap();
return 0;

Binary file not shown.

View File

@@ -435,6 +435,24 @@ static int vtoy_printf_iso_path(ventoy_os_param *param)
return 0;
}
static int vtoy_printf_fs(ventoy_os_param *param)
{
const char *fs[] =
{
"exfat", "ntfs", "ext", "xfs", "udf", "fat"
};
if (param->vtoy_disk_part_type < 6)
{
printf("%s\n", fs[param->vtoy_disk_part_type]);
}
else
{
printf("unknown\n");
}
return 0;
}
static int vtoy_check_device(ventoy_os_param *param, const char *device)
{
unsigned long long size;
@@ -551,12 +569,13 @@ int vtoydump_main(int argc, char **argv)
int rc;
int ch;
int print_path = 0;
int print_fs = 0;
char filename[256] = {0};
char diskname[256] = {0};
char device[64] = {0};
ventoy_os_param *param = NULL;
while ((ch = getopt(argc, argv, "c:f:p:v::")) != -1)
while ((ch = getopt(argc, argv, "c:f:p:s:v::")) != -1)
{
if (ch == 'f')
{
@@ -575,6 +594,11 @@ int vtoydump_main(int argc, char **argv)
print_path = 1;
strncpy(filename, optarg, sizeof(filename) - 1);
}
else if (ch == 's')
{
print_fs = 1;
strncpy(filename, optarg, sizeof(filename) - 1);
}
else
{
fprintf(stderr, "Usage: %s -f datafile [ -v ] \n", argv[0]);
@@ -627,6 +651,10 @@ int vtoydump_main(int argc, char **argv)
{
rc = vtoy_printf_iso_path(param);
}
else if (print_fs)
{
rc = vtoy_printf_fs(param);
}
else if (device[0])
{
rc = vtoy_check_device(param, device);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,7 @@
/******************************************************************************
* vtoyjump.c
*
* Copyright (c) 2020, longpanda <admin@ventoy.net>
* Copyright (c) 2021, 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
@@ -31,22 +31,58 @@
static ventoy_os_param g_os_param;
static ventoy_windows_data g_windows_data;
static UINT8 g_os_param_reserved[32];
static BOOL g_64bit_system = FALSE;
static INT g_system_bit = VTOY_BIT;
static ventoy_guid g_ventoy_guid = VENTOY_GUID;
static HANDLE g_vtoylog_mutex = NULL;
static HANDLE g_vtoyins_mutex = NULL;
//Unicode "CmdLine"
static BOOL g_PecmdHasCmdLine = FALSE;
static UCHAR g_aucCmdLineHex[] =
{
0x43, 0x00, 0x6D, 0x00, 0x64, 0x00, 0x4C, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x65, 0x00
};
static CHAR g_prog_full_path[MAX_PATH];
static CHAR g_prog_dir[MAX_PATH];
static CHAR g_prog_name[MAX_PATH];
#define VTOY_PID_FILE "X:\\Windows\\System32\\pidventoy"
#define AUTO_RUN_BAT "X:\\VentoyAutoRun.bat"
#define AUTO_RUN_LOG "X:\\VentoyAutoRun.log"
#define LOG_FILE "X:\\Windows\\system32\\ventoy.log"
#define MUTEX_LOCK(hmutex) if (hmutex != NULL) LockStatus = WaitForSingleObject(hmutex, INFINITE)
#define MUTEX_UNLOCK(hmutex) if (hmutex != NULL && WAIT_OBJECT_0 == LockStatus) ReleaseMutex(hmutex)
static const char * GetFileNameInPath(const char *fullpath)
{
int i;
if (strstr(fullpath, ":"))
{
for (i = (int)strlen(fullpath); i > 0; i--)
{
if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\')
{
return fullpath + i;
}
}
}
return fullpath;
}
static int split_path_name(char *fullpath, char *dir, char *name)
{
CHAR ch;
CHAR *Pos = NULL;
Pos = (CHAR *)GetFileNameInPath(fullpath);
strcpy_s(name, MAX_PATH, Pos);
ch = *(Pos - 1);
*(Pos - 1) = 0;
strcpy_s(dir, MAX_PATH, fullpath);
*(Pos - 1) = ch;
return 0;
}
void Log(const char *Fmt, ...)
{
va_list Arg;
@@ -70,7 +106,7 @@ void Log(const char *Fmt, ...)
MUTEX_LOCK(g_vtoylog_mutex);
fopen_s(&File, "ventoy.log", "a+");
fopen_s(&File, LOG_FILE, "a+");
if (File)
{
fwrite(szBuf, 1, Len, File);
@@ -233,24 +269,6 @@ static BOOL CheckPeHead(BYTE *Head)
return TRUE;
}
static BOOL IsPe64(BYTE *buffer)
{
DWORD pe_off;
if (!CheckPeHead(buffer))
{
return FALSE;
}
pe_off = *(UINT32 *)(buffer + 60);
if (*(UINT16 *)(buffer + pe_off + 24) == 0x020b)
{
return TRUE;
}
return FALSE;
}
static BOOL CheckOsParam(ventoy_os_param *param)
{
@@ -528,7 +546,7 @@ int VentoyMountY(HANDLE Handle)
for (i = 0; physicalDriveName[i]; i++)
{
physicalDriveNameA[i] = toupper((CHAR)(physicalDriveName[i]));
physicalDriveNameA[i] = (CHAR)toupper((CHAR)(physicalDriveName[i]));
}
Log("physicalDriveNameA=<%s>", physicalDriveNameA);
@@ -553,8 +571,10 @@ int VentoyMountY(HANDLE Handle)
return bRet ? 0 : 1;
}
static BOOL VentoyNeedMountY(const char *IsoPath)
static BOOL VentoyAPINeedMountY(const char *IsoPath)
{
(void)IsoPath;
/* TBD */
return FALSE;
}
@@ -576,7 +596,7 @@ static int VentoyAttachVirtualDisk(HANDLE Handle, const char *IsoPath)
DriveYFree = 1;
}
if (DriveYFree && VentoyNeedMountY(IsoPath))
if (DriveYFree && VentoyAPINeedMountY(IsoPath))
{
return VentoyMountY(Handle);
}
@@ -744,7 +764,7 @@ static BOOL Is2K10PE(void)
return bRet;
}
static CHAR GetMountLogicalDrive(void)
static CHAR GetIMDiskMountLogicalDrive(void)
{
CHAR Letter = 'Y';
DWORD Drives;
@@ -832,7 +852,7 @@ static int VentoyRunImdisk(const char *IsoPath, const char *imdiskexe)
Log("VentoyRunImdisk <%s> <%s>", IsoPath, imdiskexe);
Letter = GetMountLogicalDrive();
Letter = GetIMDiskMountLogicalDrive();
sprintf_s(Cmdline, sizeof(Cmdline), "%s -a -o ro -f \"%s\" -m %C:", imdiskexe, IsoPath, Letter);
Log("mount iso to %C: use imdisk cmd <%s>", Letter, Cmdline);
@@ -909,7 +929,7 @@ int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive)
if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
{
if (g_64bit_system)
if (g_system_bit == 64)
{
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys");
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe");
@@ -1132,7 +1152,7 @@ static int DecompressInjectionArchive(const char *archive, DWORD PhyDrive)
if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
{
if (g_64bit_system)
if (g_system_bit == 64)
{
CopyFileFromFatDisk("/ventoy/7z/64/7za.exe", "ventoy\\7za.exe");
}
@@ -1228,13 +1248,126 @@ static int ProcessUnattendedInstallation(const char *script)
return 0;
}
static int Windows11BypassCheck(const char *isofile, const char MntLetter)
{
int Ret = 1;
DWORD dwHandle;
DWORD dwSize;
DWORD dwValue = 1;
UINT VerLen = 0;
CHAR *Buffer = NULL;
VS_FIXEDFILEINFO* VerInfo = NULL;
CHAR CheckFile[MAX_PATH];
UINT16 Major, Minor, Build, Revision;
Log("Windows11BypassCheck for <%s> %C:", isofile, MntLetter);
if (FALSE == IsFileExist("%C:\\sources\\boot.wim", MntLetter) ||
FALSE == IsFileExist("%C:\\sources\\compatresources.dll", MntLetter))
{
Log("boot.wim/compatresources.dll not exist, this is not a windows install media.");
goto End;
}
if (FALSE == IsFileExist("%C:\\sources\\install.wim", MntLetter) &&
FALSE == IsFileExist("%C:\\sources\\install.esd", MntLetter))
{
Log("install.wim/install.esd not exist, this is not a windows install media.");
goto End;
}
sprintf_s(CheckFile, sizeof(CheckFile), "%C:\\sources\\compatresources.dll", MntLetter);
dwSize = GetFileVersionInfoSizeA(CheckFile, &dwHandle);
if (0 == dwSize)
{
Log("Failed to get file version info size: %u", LASTERR);
goto End;
}
Buffer = malloc(dwSize);
if (!Buffer)
{
goto End;
}
if (FALSE == GetFileVersionInfoA(CheckFile, dwHandle, dwSize, Buffer))
{
Log("Failed to get file version info : %u", LASTERR);
goto End;
}
if (VerQueryValueA(Buffer, "\\", (LPVOID)&VerInfo, &VerLen) && VerLen != 0)
{
if (VerInfo->dwSignature == VS_FFI_SIGNATURE)
{
Major = HIWORD(VerInfo->dwFileVersionMS);
Minor = LOWORD(VerInfo->dwFileVersionMS);
Build = HIWORD(VerInfo->dwFileVersionLS);
Revision = LOWORD(VerInfo->dwFileVersionLS);
Log("FileVersionze: <%u %u %u %u>", Major, Minor, Build, Revision);
if (Major == 10 && Build > 20000)
{
Major = 11;
}
if (Major != 11)
{
Log("This is not Windows 11, not need to bypass.", Major);
goto End;
}
}
}
//Now we really need to bypass windows 11 check. create registry
HKEY hKey = NULL;
HKEY hSubKey = NULL;
LSTATUS Status;
Status = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwSize);
if (ERROR_SUCCESS != Status)
{
Log("Failed to create reg key System\\Setup %u %u", LASTERR, Status);
goto End;
}
Status = RegCreateKeyExA(hKey, "LabConfig", 0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_CREATE_SUB_KEY, NULL, &hSubKey, &dwSize);
if (ERROR_SUCCESS != Status)
{
Log("Failed to create LabConfig reg %u %u", LASTERR, Status);
goto End;
}
//set reg value
Status += RegSetValueExA(hSubKey, "BypassRAMCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
Status += RegSetValueExA(hSubKey, "BypassTPMCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
Status += RegSetValueExA(hSubKey, "BypassSecureBootCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
Status += RegSetValueExA(hSubKey, "BypassStorageCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
Status += RegSetValueExA(hSubKey, "BypassCPUCheck", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
Log("Create bypass registry %s %u", (Status == ERROR_SUCCESS) ? "SUCCESS" : "FAILED", Status);
Ret = 0;
End:
if (Buffer)
{
free(Buffer);
}
return Ret;
}
static int VentoyHook(ventoy_os_param *param)
{
int i;
int rc;
BOOL find = FALSE;
CHAR Letter;
CHAR MntLetter;
DWORD Drives;
DWORD NewDrives;
DISK_EXTENT DiskExtent;
UINT8 UUID[16];
CHAR IsoPath[MAX_PATH];
@@ -1299,9 +1432,43 @@ static int VentoyHook(ventoy_os_param *param)
Log("Find ISO file <%s>", IsoPath);
Drives = GetLogicalDrives();
Log("Drives before mount: 0x%x", Drives);
rc = MountIsoFile(IsoPath, DiskExtent.DiskNumber);
NewDrives = GetLogicalDrives();
Log("Drives after mount: 0x%x (0x%x)", NewDrives, (NewDrives ^ Drives));
MntLetter = 'A';
NewDrives = (NewDrives ^ Drives);
while (NewDrives)
{
if (NewDrives & 0x01)
{
if ((NewDrives >> 1) == 0)
{
Log("The ISO file is mounted at %C:", MntLetter);
}
else
{
Log("Maybe the ISO file is mounted at %C:", MntLetter);
}
break;
}
NewDrives >>= 1;
MntLetter++;
}
Log("Mount ISO FILE: %s", rc == 0 ? "SUCCESS" : "FAILED");
//Windows 11 bypass check
if (g_windows_data.windows11_bypass_check == 1)
{
Windows11BypassCheck(IsoPath, MntLetter);
}
// for protect
rc = DeleteVentoyPart2MountPoint(DiskExtent.DiskNumber);
Log("Delete ventoy mountpoint: %s", rc == 0 ? "SUCCESS" : "NO NEED");
@@ -1331,6 +1498,46 @@ static int VentoyHook(ventoy_os_param *param)
{
Log("decompress injection archive %s...", IsoPath);
DecompressInjectionArchive(IsoPath, DiskExtent.DiskNumber);
if (IsFileExist("%s", AUTO_RUN_BAT))
{
HANDLE hOut;
DWORD flags = CREATE_NO_WINDOW;
CHAR StrBuf[1024];
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
SECURITY_ATTRIBUTES Sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
Log("%s exist, now run it...", AUTO_RUN_BAT);
GetStartupInfoA(&Si);
hOut = CreateFileA(AUTO_RUN_LOG,
FILE_APPEND_DATA,
FILE_SHARE_WRITE | FILE_SHARE_READ,
&Sa,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
Si.dwFlags |= STARTF_USESTDHANDLES;
if (hOut != INVALID_HANDLE_VALUE)
{
Si.hStdError = hOut;
Si.hStdOutput = hOut;
}
sprintf_s(IsoPath, sizeof(IsoPath), "%C:\\%s", Letter, param->vtoy_img_path);
sprintf_s(StrBuf, sizeof(StrBuf), "cmd.exe /c %s \"%s\" %C", AUTO_RUN_BAT, IsoPath, MntLetter);
CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &Pi);
WaitForSingleObject(Pi.hProcess, INFINITE);
SAFE_CLOSE_HANDLE(hOut);
}
else
{
Log("%s not exist...", AUTO_RUN_BAT);
}
}
else
{
@@ -1345,24 +1552,6 @@ static int VentoyHook(ventoy_os_param *param)
return 0;
}
const char * GetFileNameInPath(const char *fullpath)
{
int i;
const char *pos = NULL;
if (strstr(fullpath, ":"))
{
for (i = (int)strlen(fullpath); i > 0; i--)
{
if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\')
{
return fullpath + i;
}
}
}
return fullpath;
}
int VentoyJumpWimboot(INT argc, CHAR **argv, CHAR *LunchFile)
{
@@ -1371,13 +1560,7 @@ int VentoyJumpWimboot(INT argc, CHAR **argv, CHAR *LunchFile)
DWORD size = 0;
DWORD Pos;
#ifdef VTOY_32
g_64bit_system = FALSE;
#else
g_64bit_system = TRUE;
#endif
Log("VentoyJumpWimboot %dbit", g_64bit_system ? 64 : 32);
Log("VentoyJumpWimboot %dbit", g_system_bit);
sprintf_s(LunchFile, MAX_PATH, "X:\\setup.exe");
@@ -1441,24 +1624,6 @@ static int ventoy_check_create_directory(void)
return 0;
}
static BOOL VentoyFindCmdLineStr(BYTE *buf, DWORD size)
{
DWORD i = 0;
UINT32 uiDataChk;
UINT32 uiDataHex = *(UINT32 *)(g_aucCmdLineHex);
for (i = 0; i < size - sizeof(g_aucCmdLineHex); i += 16)
{
uiDataChk = *(UINT32 *)(buf + i);
if (uiDataChk == uiDataHex && memcmp(buf + i, g_aucCmdLineHex, sizeof(g_aucCmdLineHex)) == 0)
{
return TRUE;
}
}
return FALSE;
}
int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
{
int rc = 1;
@@ -1484,8 +1649,7 @@ int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
goto End;
}
g_64bit_system = IsPe64(Buffer);
Log("VentoyJump %dbit", g_64bit_system ? 64 : 32);
Log("VentoyJump %dbit", g_system_bit);
MUTEX_LOCK(g_vtoyins_mutex);
stat = ventoy_check_create_directory();
@@ -1537,13 +1701,6 @@ int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart);
MUTEX_UNLOCK(g_vtoyins_mutex);
#ifdef VTOY_REJUMP_SUPPORTED
if (_stricmp(LunchFile, "ventoy\\PECMD.EXE") == 0)
{
g_PecmdHasCmdLine = VentoyFindCmdLineStr(Buffer + PeStart, FileSize - PeStart);
}
#endif
break;
}
}
@@ -1574,244 +1731,176 @@ End:
}
static int ventoy_append_process_id(const char *pidfile)
int real_main(int argc, char **argv)
{
DWORD PID = 0;
FILE *fp = NULL;
int i = 0;
int rc = 0;
CHAR NewFile[MAX_PATH];
CHAR LunchFile[MAX_PATH];
CHAR CallParam[1024] = { 0 };
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
PID = GetCurrentProcessId();
fopen_s(&fp, pidfile, "a+");
if (!fp)
{
return 1;
}
fprintf_s(fp, "%u\n", PID);
fclose(fp);
return 0;
}
static int ventoy_get_instance_id(const char *pidfile)
{
int instance = 0;
FILE *fp = NULL;
char line[256];
fopen_s(&fp, pidfile, "r");
if (!fp)
{
return 1;
}
while (fgets(line, sizeof(line), fp))
{
instance++;
}
fclose(fp);
return instance + 1;
}
int main(int argc, char **argv)
{
int i = 0;
int rc = 0;
int id = 0;
BOOL ReJump = FALSE;
CHAR *Pos = NULL;
CHAR CurDir[MAX_PATH];
CHAR LunchFile[MAX_PATH];
CHAR CallParam[1024] = { 0 };
DWORD LockStatus = 0;
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
#ifdef VTOY_REJUMP_SUPPORTED
if (argv[0] && strcmp(argv[0], "ventoy\\WinLogon.exe") == 0)
{
GetStartupInfoA(&Si);
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
sprintf_s(LunchFile, sizeof(LunchFile), "PECMD.EXE");
for (i = 1; i < argc; i++)
{
strcat_s(LunchFile, sizeof(LunchFile), " ");
strcat_s(LunchFile, sizeof(LunchFile), argv[i]);
}
CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
WaitForSingleObject(Pi.hProcess, INFINITE);
return 0;
}
#endif
g_PecmdHasCmdLine = 0;
g_vtoylog_mutex = CreateMutexA(NULL, FALSE, "VTOYLOG_LOCK");
g_vtoyins_mutex = CreateMutexA(NULL, FALSE, "VTOYINS_LOCK");
MUTEX_LOCK(g_vtoyins_mutex);
if (IsFileExist(VTOY_PID_FILE))
{
id = ventoy_get_instance_id(VTOY_PID_FILE);
}
else
{
id = 1;
}
ventoy_append_process_id(VTOY_PID_FILE);
MUTEX_UNLOCK(g_vtoyins_mutex);
if (argv[0] && argv[0][0] && argv[0][1] == ':')
{
GetCurrentDirectoryA(sizeof(CurDir), CurDir);
strcpy_s(LunchFile, sizeof(LunchFile), argv[0]);
Pos = (char *)GetFileNameInPath(LunchFile);
strcat_s(CurDir, sizeof(CurDir), "\\");
strcat_s(CurDir, sizeof(CurDir), Pos);
if (_stricmp(argv[0], CurDir) != 0)
{
*Pos = 0;
SetCurrentDirectoryA(LunchFile);
}
}
#ifdef VTOY_32
Log("######## VentoyJump 32bit [%d] ##########", id);
#else
Log("######## VentoyJump 64bit [%d] ##########", id);
#endif
Log("#### real_main #### argc = %d", argc);
Log("program full path: <%s>", g_prog_full_path);
Log("program dir: <%s>", g_prog_dir);
Log("program name:: <%s>", g_prog_name);
Log("argc = %d", argc);
for (i = 0; i < argc; i++)
{
Log("argv[%d]=<%s>", i, argv[i]);
if (i > 0)
{
strcat_s(CallParam, sizeof(CallParam), " ");
strcat_s(CallParam, sizeof(CallParam), argv[i]);
}
}
if (Pos && *Pos == 0)
for (i = 0; i < argc; i++)
{
Log("Old current directory = <%s>", CurDir);
Log("New current directory = <%s>", LunchFile);
Log("argv[%d]=<%s>", i, argv[i]);
if (i > 0)
{
strcat_s(CallParam, sizeof(CallParam), " ");
strcat_s(CallParam, sizeof(CallParam), argv[i]);
}
}
GetStartupInfoA(&Si);
memset(LunchFile, 0, sizeof(LunchFile));
if (strstr(argv[0], "vtoyjump.exe"))
{
rc = VentoyJumpWimboot(argc, argv, LunchFile);
}
else
{
GetCurrentDirectoryA(sizeof(CurDir), CurDir);
Log("Current directory = <%s>", CurDir);
rc = VentoyJump(argc, argv, LunchFile);
}
GetStartupInfoA(&Si);
Log("LunchFile=<%s> CallParam=<%s>", LunchFile, CallParam);
memset(LunchFile, 0, sizeof(LunchFile));
if (_stricmp(g_prog_name, "winpeshl.exe") != 0 && IsFileExist("ventoy\\%s", g_prog_name))
{
sprintf_s(NewFile, sizeof(NewFile), "%s_BACK.EXE", g_prog_full_path);
MoveFileA(g_prog_full_path, NewFile);
Log("Move <%s> to <%s>", g_prog_full_path, NewFile);
if (strstr(argv[0], "vtoyjump.exe"))
{
rc = VentoyJumpWimboot(argc, argv, LunchFile);
}
sprintf_s(NewFile, sizeof(NewFile), "ventoy\\%s", g_prog_name);
CopyFileA(NewFile, g_prog_full_path, TRUE);
Log("Copy <%s> to <%s>", NewFile, g_prog_full_path);
sprintf_s(LunchFile, sizeof(LunchFile), "%s", g_prog_full_path);
Log("Final lunchFile is <%s>", LunchFile);
}
else
{
rc = VentoyJump(argc, argv, LunchFile);
Log("We don't need to recover original <%s>", g_prog_name);
}
Log("id=%d LunchFile=<%s> CallParam=<%s>", id, LunchFile, CallParam);
if (g_os_param_reserved[0] == 3)
{
Log("Open log for debug ...");
sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log");
}
else
{
if (CallParam[0])
{
strcat_s(LunchFile, sizeof(LunchFile), CallParam);
}
else if (NULL == strstr(LunchFile, "setup.exe"))
{
Log("Not setup.exe, hide windows.");
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
}
if (id == 1 && _stricmp(argv[0], "PECMD.EXE") == 0 && _stricmp(LunchFile, "ventoy\\PECMD.EXE") == 0)
{
MUTEX_LOCK(g_vtoyins_mutex);
id = ventoy_get_instance_id(VTOY_PID_FILE);
MUTEX_UNLOCK(g_vtoyins_mutex);
Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed");
}
Log("Current instance id is: %d", id);
Log("Now launch <%s> ...", LunchFile);
if (id == 2)
{
#ifdef VTOY_REJUMP_SUPPORTED
if (g_PecmdHasCmdLine)
{
ReJump = TRUE;
CopyFileA("PECMD.EXE", "ventoy\\WinLogon.exe", TRUE);
}
#endif
if (g_os_param_reserved[0] == 4)
{
Log("Open cmd for debug ...");
sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");
}
MoveFileA("PECMD.EXE", "PECMD_BACK.EXE");
CopyFileA("ventoy\\PECMD.EXE", "PECMD.EXE", TRUE);
sprintf_s(LunchFile, sizeof(LunchFile), "%s", "PECMD.EXE");
Log("Move original PECMD.EXE <%s>", LunchFile);
}
else
{
Log("%d instance started, don't move PECMD.EXE", id);
}
}
Log("Backup log at this point");
CopyFileA(LOG_FILE, "X:\\Windows\\ventoy.backup", TRUE);
if (g_os_param_reserved[0] == 3)
{
Log("Open log for debug ...");
sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log");
}
else
{
if (CallParam[0])
{
strcat_s(LunchFile, sizeof(LunchFile), CallParam);
}
else if (NULL == strstr(LunchFile, "setup.exe"))
{
Log("Not setup.exe, hide windows.");
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
}
CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed");
}
Log("Now launch <%s> ...", LunchFile);
for (i = 0; rc && i < 1800; i++)
{
Log("Ventoy hook failed, now wait and retry ...");
Sleep(1000);
rc = VentoyHook(&g_os_param);
}
if (g_os_param_reserved[0] == 4)
{
Log("Open cmd for debug ...");
sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");
}
Log("Wait process...");
WaitForSingleObject(Pi.hProcess, INFINITE);
#ifdef VTOY_REJUMP_SUPPORTED
if (ReJump)
{
sprintf_s(CallParam, sizeof(CallParam), "ventoy\\WinLogon.exe%s", LunchFile + strlen("PECMD.EXE"));
Log("Now rejump to pecmd.exe <%s> ...", CallParam);
CreateProcessA(NULL, CallParam, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
Log("Wait rejump process...");
WaitForSingleObject(Pi.hProcess, INFINITE);
Log("rejump finished");
return 0;
}
#else
(void)ReJump;
#endif
CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
for (i = 0; rc && i < 1800; i++)
{
Log("Ventoy hook failed, now wait and retry ...");
Sleep(1000);
rc = VentoyHook(&g_os_param);
}
Log("Wait process...");
WaitForSingleObject(Pi.hProcess, INFINITE);
Log("vtoyjump finished");
Log("vtoyjump finished");
return 0;
}
int main(int argc, char **argv)
{
int i;
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
CHAR CurDir[MAX_PATH];
CHAR NewArgv0[MAX_PATH];
CHAR CallParam[1024] = { 0 };
g_vtoylog_mutex = CreateMutexA(NULL, FALSE, "VTOYLOG_LOCK");
g_vtoyins_mutex = CreateMutexA(NULL, FALSE, "VTOYINS_LOCK");
Log("######## VentoyJump %dbit ##########", g_system_bit);
GetCurrentDirectoryA(sizeof(CurDir), CurDir);
Log("Current directory is <%s>", CurDir);
GetModuleFileNameA(NULL, g_prog_full_path, MAX_PATH);
split_path_name(g_prog_full_path, g_prog_dir, g_prog_name);
Log("EXE path: <%s> dir:<%s> name:<%s>", g_prog_full_path, g_prog_dir, g_prog_name);
if (_stricmp(g_prog_name, "WinLogon.exe") == 0)
{
Log("This time is rejump back ...");
strcpy_s(g_prog_full_path, sizeof(g_prog_full_path), argv[1]);
split_path_name(g_prog_full_path, g_prog_dir, g_prog_name);
return real_main(argc - 1, argv + 1);
}
else if (_stricmp(g_prog_name, "PECMD.exe") == 0)
{
Log("We need to rejump for pecmd ...");
ventoy_check_create_directory();
CopyFileA(g_prog_full_path, "ventoy\\WinLogon.exe", TRUE);
sprintf_s(CallParam, sizeof(CallParam), "ventoy\\WinLogon.exe %s", g_prog_full_path);
for (i = 1; i < argc; i++)
{
strcat_s(CallParam, sizeof(CallParam), " ");
strcat_s(CallParam, sizeof(CallParam), argv[i]);
}
Log("Now rejump to <%s> ...", CallParam);
GetStartupInfoA(&Si);
CreateProcessA(NULL, CallParam, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
Log("Wait rejump process...");
WaitForSingleObject(Pi.hProcess, INFINITE);
Log("rejump finished");
return 0;
}
else
{
Log("We don't need to rejump ...");
strcpy_s(NewArgv0, sizeof(NewArgv0), g_prog_full_path);
argv[0] = NewArgv0;
return real_main(argc, argv);
}
}

View File

@@ -69,7 +69,8 @@ typedef struct ventoy_windows_data
{
char auto_install_script[384];
char injection_archive[384];
UINT8 reserved[256];
UINT8 windows11_bypass_check;
UINT8 reserved[255];
}ventoy_windows_data;

View File

@@ -126,7 +126,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>VTOY_32;FATFS_INC_FORMAT_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>VTOY_BIT=32;FATFS_INC_FORMAT_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
@@ -135,7 +135,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>VirtDisk.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Version.lib;VirtDisk.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -146,7 +146,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>VTOY_64;FATFS_INC_FORMAT_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>VTOY_BIT=64;FATFS_INC_FORMAT_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
@@ -155,7 +155,8 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>VirtDisk.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Version.lib;VirtDisk.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>Version.dll;VirtDisk.dll</DelayLoadDLLs>
</Link>
</ItemDefinitionGroup>
<ItemGroup>