mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-09-19 18:31:15 +00:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f5843f576b | ||
|
be5bc6f3b7 | ||
|
f3b65452f4 | ||
|
ec4b6c2a2c | ||
|
be8b6e8976 | ||
|
82b1faa132 | ||
|
52ae65f54d | ||
|
ee104bfa97 | ||
|
9cfd05811b | ||
|
0c66908935 | ||
|
f53de3bdb0 | ||
|
8516786b31 | ||
|
f7c78879c7 | ||
|
f3e267a09e | ||
|
7c1370dcb0 | ||
|
1b5aa9c61d | ||
|
d6eba15d71 | ||
|
734c7b8ac4 | ||
|
0fa25c4526 | ||
|
1473be0e4c | ||
|
cd9aa16b20 | ||
|
a9be2fd4d9 | ||
|
f354d2b733 |
2
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
2
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
@@ -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
|
||||
|
@@ -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. */
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
70
IMG/cpio/ventoy/hook/debian/pyabr-disk.sh
Normal file
70
IMG/cpio/ventoy/hook/debian/pyabr-disk.sh
Normal 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
|
20
IMG/cpio/ventoy/hook/debian/pyabr-hook.sh
Normal file
20
IMG/cpio/ventoy/hook/debian/pyabr-hook.sh
Normal 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
|
@@ -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
|
||||
|
@@ -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'
|
||||
}
|
||||
|
||||
|
47
IMG/cpio/ventoy/loop/esysrescue/ventoy-disk.sh
Normal file
47
IMG/cpio/ventoy/loop/esysrescue/ventoy-disk.sh
Normal 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
|
26
IMG/cpio/ventoy/loop/esysrescue/ventoy-hook.sh
Normal file
26
IMG/cpio/ventoy/loop/esysrescue/ventoy-hook.sh
Normal 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
31
INSTALL/grub/checksum.cfg
Normal 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 ...'
|
||||
}
|
@@ -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
|
||||
|
16
INSTALL/grub/help/en_US.txt
Normal file
16
INSTALL/grub/help/en_US.txt
Normal 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 ......
|
16
INSTALL/grub/help/tr_TR.txt
Normal file
16
INSTALL/grub/help/tr_TR.txt
Normal 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......
|
15
INSTALL/grub/help/zh_CN.txt
Normal file
15
INSTALL/grub/help/zh_CN.txt
Normal 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 键返回 ......
|
@@ -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.
@@ -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":""
|
||||
}
|
||||
]
|
||||
|
@@ -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
|
||||
|
57
Ventoy2Disk/Ventoy2Disk/DiskService.h
Normal file
57
Ventoy2Disk/Ventoy2Disk/DiskService.h
Normal 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
|
84
Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c
Normal file
84
Ventoy2Disk/Ventoy2Disk/DiskService_diskpart.c
Normal 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);
|
||||
}
|
1223
Ventoy2Disk/Ventoy2Disk/DiskService_vds.c
Normal file
1223
Ventoy2Disk/Ventoy2Disk/DiskService_vds.c
Normal file
File diff suppressed because it is too large
Load Diff
27
Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c
Normal file
27
Ventoy2Disk/Ventoy2Disk/DiskService_wmsa.c
Normal 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"
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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),
|
||||
|
Binary file not shown.
@@ -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" />
|
||||
|
@@ -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.
@@ -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.
@@ -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.
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user