Commit e79dc57e authored by longpanda's avatar longpanda
Browse files

wimboot mode support Bob.Ombs.Modified.Win10PEx64 (#1842)

parent 7bf85a1e
......@@ -148,8 +148,6 @@ static char g_iso_vd_id_application[130];
static int g_pager_flag = 0;
static char g_old_pager[32];
static const char *g_vtoy_winpeshl_ini = "[LaunchApps]\r\nvtoyjump.exe";
const char *g_menu_class[img_type_max] =
{
"vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy"
......@@ -1148,6 +1146,10 @@ grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssiz
left -= VTOY_SIZE_2MB;
div = grub_divmod64((grub_uint64_t)((size - left) * 100), (grub_uint64_t)size, &ro);
if (div < 1)
{
div = 1;
}
grub_printf("\r%s %d%% ", g_vtoy_prompt_msg, (int)div);
grub_refresh();
}
......@@ -5987,12 +5989,6 @@ int ventoy_env_init(void)
grub_env_export("ventoy_env_param");
}
grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)g_vtoy_winpeshl_ini);
grub_env_set("vtoy_winpeshl_ini_addr", buf);
grub_snprintf(buf, sizeof(buf), "%d", (int)grub_strlen(g_vtoy_winpeshl_ini));
grub_env_set("vtoy_winpeshl_ini_size", buf);
grub_env_export("vtoy_winpeshl_ini_addr");
grub_env_export("vtoy_winpeshl_ini_size");
......
......@@ -1790,19 +1790,150 @@ end:
return rc;
}
static int ventoy_extract_init_exe(char *wimfile, grub_uint8_t **pexe_data, grub_uint32_t *pexe_len, char *exe_name)
{
int rc;
int ret = 1;
grub_uint16_t i;
grub_file_t file = NULL;
grub_uint32_t exe_len = 0;
wim_header *head = NULL;
grub_uint16_t *uname = NULL;
grub_uint8_t *exe_data = NULL;
grub_uint8_t *decompress_data = NULL;
wim_lookup_entry *lookup = NULL;
wim_security_header *security = NULL;
wim_directory_entry *rootdir = NULL;
wim_directory_entry *search = NULL;
wim_stream_entry *stream = NULL;
wim_lookup_entry *replace_look = NULL;
wim_header wimhdr;
wim_hash hashdata;
head = &wimhdr;
file = grub_file_open(wimfile, VENTOY_FILE_TYPE);
if (!file)
{
goto out;
}
grub_file_read(file, head, sizeof(wim_header));
rc = ventoy_read_resource(file, head, &head->metadata, (void **)&decompress_data);
if (rc)
{
grub_printf("failed to read meta data %d\n", rc);
goto out;
}
security = (wim_security_header *)decompress_data;
if (security->len > 0)
{
rootdir = (wim_directory_entry *)(decompress_data + ((security->len + 7) & 0xFFFFFFF8U));
}
else
{
rootdir = (wim_directory_entry *)(decompress_data + 8);
}
debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size);
lookup = grub_malloc(head->lookup.raw_size);
grub_file_seek(file, head->lookup.offset);
grub_file_read(file, lookup, head->lookup.raw_size);
/* search winpeshl.exe dirent entry */
search = search_replace_wim_dirent(file, head, lookup, decompress_data, rootdir);
if (!search)
{
debug("Failed to find replace file %p\n", search);
goto out;
}
uname = (grub_uint16_t *)(search + 1);
for (i = 0; i < search->name_len / 2 && i < 200; i++)
{
exe_name[i] = (char)uname[i];
}
exe_name[i] = 0;
debug("find replace file at %p <%s>\n", search, exe_name);
grub_memset(&hashdata, 0, sizeof(wim_hash));
if (grub_memcmp(&hashdata, search->hash.sha1, sizeof(wim_hash)) == 0)
{
debug("search hash all 0, now do deep search\n");
stream = (wim_stream_entry *)((char *)search + search->len);
for (i = 0; i < search->streams; i++)
{
if (stream->name_len == 0)
{
grub_memcpy(&hashdata, stream->hash.sha1, sizeof(wim_hash));
debug("new search hash: %02x %02x %02x %02x %02x %02x %02x %02x\n",
ventoy_varg_8(hashdata.sha1));
break;
}
stream = (wim_stream_entry *)((char *)stream + stream->len);
}
}
else
{
grub_memcpy(&hashdata, search->hash.sha1, sizeof(wim_hash));
}
/* find and extact winpeshl.exe */
replace_look = ventoy_find_look_entry(head, lookup, &hashdata);
if (replace_look)
{
exe_len = (grub_uint32_t)replace_look->resource.raw_size;
debug("find replace lookup entry_id:%ld raw_size:%u\n",
((long)replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len);
if (0 != ventoy_read_resource(file, head, &(replace_look->resource), (void **)&(exe_data)))
{
exe_len = 0;
exe_data = NULL;
debug("failed to read replace file meta data %u\n", exe_len);
}
}
else
{
debug("failed to find lookup entry for replace file %02x %02x %02x %02x\n",
ventoy_varg_4(hashdata.sha1));
}
if (exe_data)
{
ret = 0;
*pexe_data = exe_data;
*pexe_len = exe_len;
}
out:
grub_check_free(lookup);
grub_check_free(decompress_data);
check_free(file, grub_file_close);
return ret;
}
grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args)
{
int rc = 0;
int datalen = 0;
int dataflag = 0;
grub_uint32_t size = 0;
grub_uint32_t exe_len = 0;
grub_uint32_t jump_align = 0;
const char *addr = NULL;
ventoy_chain_head *chain = NULL;
ventoy_os_param *param = NULL;
char envbuf[64];
grub_uint8_t *param = NULL;
grub_uint8_t *exe_data = NULL;
ventoy_windows_data *rtdata = NULL;
char envbuf[64] = {0};
char exename[128] = {0};
wim_tail wim_data;
(void)ctxt;
(void)argc;
(void)args;
addr = grub_env_get("vtoy_chain_mem_addr");
if (!addr)
......@@ -1821,24 +1952,34 @@ grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc,
datalen = ventoy_get_windows_rtdata_len(chain->os_param.vtoy_img_path, &dataflag);
size = sizeof(ventoy_os_param) + datalen;
param = (ventoy_os_param *)grub_zalloc(size);
if (!param)
rc = ventoy_extract_init_exe(args[0], &exe_data, &exe_len, exename);
if (rc)
{
return 1;
}
grub_memcpy(param, &chain->os_param, sizeof(ventoy_os_param));
ventoy_fill_windows_rtdata(param + 1, param->vtoy_img_path, dataflag);
grub_memset(&wim_data, 0, sizeof(wim_data));
ventoy_cat_exe_file_data(&wim_data, exe_len, exe_data, datalen);
grub_check_free(exe_data);
jump_align = ventoy_align(wim_data.jump_exe_len, 16);
param = wim_data.jump_bin_data;
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)param);
grub_memcpy(param + jump_align, &chain->os_param, sizeof(ventoy_os_param));
rtdata = (ventoy_windows_data *)(param + jump_align + sizeof(ventoy_os_param));
ventoy_fill_windows_rtdata(rtdata, chain->os_param.vtoy_img_path, dataflag);
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)param);
grub_env_set("vtoy_wimboot_mem_addr", envbuf);
debug("vtoy_wimboot_mem_addr: %s\n", envbuf);
grub_snprintf(envbuf, sizeof(envbuf), "%u", size);
grub_snprintf(envbuf, sizeof(envbuf), "%u", wim_data.bin_align_len);
grub_env_set("vtoy_wimboot_mem_size", envbuf);
debug("vtoy_wimboot_mem_size: %s\n", envbuf);
grub_env_set(args[1], exename);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
......
......@@ -141,7 +141,7 @@ typedef struct ventoy_windows_data
grub_uint8_t windows11_bypass_check;
grub_uint32_t auto_install_len;
grub_uint8_t reserved[255 - 4];
/* auto_intall file buf */
......
......@@ -599,34 +599,35 @@ function ventoy_unix_comm_proc {
function uefi_windows_menu_func {
vt_windows_reset
if [ "$ventoy_compatible" = "NO" ]; then
if [ "$ventoy_fs_probe" = "iso9660" ]; then
loopback -d loop
vt_iso9660_nojoliet 1
loopback loop "$1$2"
fi
for file in "efi/microsoft/boot/bcd"; do
vt_windows_collect_wim_patch bcd (loop)/$file
done
if vt_check_mode 4 "$vt_chosen_name"; then
vt_windows_chain_data "${1}${chosen_path}"
ventoy_debug_pause
vtoy_wimboot_func
else
if [ "$ventoy_compatible" = "NO" ]; then
if [ "$ventoy_fs_probe" = "iso9660" ]; then
loopback -d loop
vt_iso9660_nojoliet 1
loopback loop "$1$2"
fi
for file in "efi/microsoft/boot/bcd"; do
vt_windows_collect_wim_patch bcd (loop)/$file
done
vt_windows_count_wim_patch vt_wim_cnt
if [ $vt_wim_cnt -eq 0 ]; then
distro_specify_wim_patch_phase2
vt_windows_count_wim_patch vt_wim_cnt
if [ $vt_wim_cnt -eq 0 ]; then
distro_specify_wim_patch_phase2
fi
ventoy_debug_pause
locate_wim "${chosen_path}"
fi
ventoy_debug_pause
locate_wim "${chosen_path}"
vt_windows_chain_data "${1}${chosen_path}"
ventoy_debug_pause
fi
vt_windows_chain_data "${1}${chosen_path}"
ventoy_debug_pause
if vt_check_mode 4 "$vt_chosen_name"; then
vtoy_windows_wimboot_func
fi
if [ -n "$vtoy_chain_mem_addr" ]; then
ventoy_acpi_param ${vtoy_chain_mem_addr} 2048
ventoy_cli_console
......@@ -942,8 +943,7 @@ function uefi_iso_memdisk {
ventoy_gui_console
}
function vtoy_windows_wimboot_func {
function vtoy_windows_wimboot {
if [ -f (loop)/x86/sources/boot.wim -a -f (loop)/x64/sources/boot.wim ]; then
vt_sel_wimboot vtoy_wimboot_bit
if [ "$vtoy_wimboot_bit" = "32" ]; then
......@@ -961,7 +961,7 @@ function vtoy_windows_wimboot_func {
fi
if [ -n "${vtdebug_flag}" ]; then
echo vtoy_wimboot_prefix=$vtoy_wimboot_prefix vtoy_wimboot_bit=$vtoy_wimboot_bit
echo vtoy_wimboot_prefix=$vtoy_wimboot_prefix vtoy_wimboot_bit=$vtoy_wimboot_bit vt_wimkernel=$vt_wimkernel
fi
for wmfile in sources/boot.wim boot/bcd boot/boot.sdi; do
......@@ -971,33 +971,24 @@ function vtoy_windows_wimboot_func {
done
if [ -f $vtoy_wimboot_prefix/sources/install.wim -o -f $vtoy_wimboot_prefix/sources/install.esd ]; then
vt_windows_wimboot_data
vt_windows_wimboot_data "$vtoy_wimboot_prefix/sources/boot.wim" vtoy_init_exe
else
return
fi
if [ "$grub_platform" = "pc" ]; then
set vt_wimkernel=wimboot.x86_64.xz
linux16 "$vtoy_path/$vt_wimkernel" quiet
ventoy_debug_pause
vt_set_wim_load_prompt 1 "Loading files......"
initrd16 newc:vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe \
newc:wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \
newc:winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size} \
initrd16 newc:winpeshl.exe:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \
newc:vtoy_wimboot:$vtoy_wimboot_prefix/boot/bcd \
newc:bcd:$vtoy_wimboot_prefix/boot/bcd \
newc:boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi \
newc:boot.wim:$vtoy_wimboot_prefix/sources/boot.wim
vt_set_wim_load_prompt 0
boot
else
if [ "$grub_cpu" = "i386" ]; then
set vt_wimkernel=wimboot.i386.efi.xz
else
set vt_wimkernel=wimboot.x86_64.xz
fi
vt_set_wim_load_prompt 1 "Loading files......"
vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/sources/boot.wim vtoy_wimfile_mem
vt_set_wim_load_prompt 0
......@@ -1010,9 +1001,8 @@ function vtoy_windows_wimboot_func {
ventoy_cli_console
chainloader "$vtoy_path/$vt_wimkernel" quiet \
"vf=wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size}" \
"vf=winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size}" \
"vf=vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe" \
"vf=winpeshl.exe:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size}" \
"vf=vtoy_wimboot:$vtoy_wimboot_prefix/boot/bcd" \
"vf=bcd:$vtoy_wimboot_prefix/boot/bcd" \
"vf=boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi" \
"vf=boot.wim:$vtoy_wimfile_path" \
......@@ -1023,37 +1013,118 @@ function vtoy_windows_wimboot_func {
fi
}
function legacy_windows_menu_func {
vt_windows_reset
function vtoy_winpe_wimboot {
unset vtoy_boot_mgr_exe
unset vtoy_boot_mgr_efi
set vtoy_wimboot_prefix=(loop)
set vtoy_bcd_path="$1"
set vtoy_sdi_path="$2"
set vtoy_wim_path="$3"
set vtoy_mgr_flag="$4"
if [ "$ventoy_compatible" = "NO" ]; then
if [ "$ventoy_fs_probe" = "iso9660" ]; then
loopback -d loop
vt_iso9660_nojoliet 1
loopback loop "$1$2"
if [ $vtoy_mgr_flag -eq 1 ]; then
set vtoy_boot_mgr_exe="newc:bootmgr.exe:$vtoy_wimboot_prefix/$5"
elif [ $vtoy_mgr_flag -eq 2 ]; then
set vtoy_boot_mgr_efi="vf=bootmgr.efi:$vtoy_wimboot_prefix/$5"
elif [ $vtoy_mgr_flag -eq 3 ]; then
set vtoy_boot_mgr_exe="newc:bootmgr.exe:$vtoy_wimboot_prefix/$5"
set vtoy_boot_mgr_efi="vf=bootmgr.efi:$vtoy_wimboot_prefix/$6"
fi
vt_windows_wimboot_data $vtoy_wimboot_prefix/$vtoy_wim_path vtoy_init_exe
if [ "$grub_platform" = "pc" ]; then
linux16 "$vtoy_path/$vt_wimkernel" quiet
ventoy_debug_pause
vt_set_wim_load_prompt 1 "Loading files......"
initrd16 newc:$vtoy_init_exe:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \
$vtoy_boot_mgr_exe \
newc:vtoy_wimboot:$vtoy_wimboot_prefix/$vtoy_bcd_path \
newc:bcd:$vtoy_wimboot_prefix/$vtoy_bcd_path \
newc:boot.sdi:$vtoy_wimboot_prefix/$vtoy_sdi_path \
newc:boot.wim:$vtoy_wimboot_prefix/$vtoy_wim_path
vt_set_wim_load_prompt 0
boot
else
vt_set_wim_load_prompt 1 "Loading files......"
vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/$vtoy_wim_path vtoy_wimfile_mem
vt_set_wim_load_prompt 0
if [ $? -eq 0 ]; then
set vtoy_wimfile_path=mem:${vtoy_wimfile_mem_addr}:size:${vtoy_wimfile_mem_size}
else
set vtoy_wimfile_path=$vtoy_wimboot_prefix/$vtoy_wim_path
fi
for file in "boot/bcd" "/efi/microsoft/boot/bcd" "SSTR/BCD" "boot/bce"; do
vt_windows_collect_wim_patch bcd (loop)/$file
done
distro_specify_wim_patch
vt_windows_count_wim_patch vt_wim_cnt
if [ $vt_wim_cnt -eq 0 ]; then
distro_specify_wim_patch_phase2
ventoy_cli_console
chainloader "$vtoy_path/$vt_wimkernel" quiet \
"vf=$vtoy_init_exe:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size}" \
"vf=vtoy_wimboot:$vtoy_wimboot_prefix/$vtoy_bcd_path" \
"$vtoy_boot_mgr_efi" \
"vf=bcd:$vtoy_wimboot_prefix/$vtoy_bcd_path" \
"vf=boot.sdi:$vtoy_wimboot_prefix/$vtoy_sdi_path" \
"vf=boot.wim:$vtoy_wimfile_path" \
pfsize=$vtoy_chain_file_size \
pfread=$vtoy_chain_file_read
boot
ventoy_gui_console
fi
}
function vtoy_wimboot_func {
echo -e "\n===================== VENTOY WIMBOOT ===================\n"
if [ "$grub_platform" = "pc" ]; then
set vt_wimkernel=wimboot.x86_64.xz
else
if [ "$grub_cpu" = "i386" ]; then
set vt_wimkernel=wimboot.i386.efi.xz
else
set vt_wimkernel=wimboot.x86_64.xz
fi
ventoy_debug_pause
locate_wim "${chosen_path}"
fi
vt_windows_chain_data "${1}${chosen_path}"
ventoy_debug_pause
if vt_str_begin "$vt_volume_id" "Modified-Win10PEx64"; then
vtoy_winpe_wimboot 'Boot/bcd' 'Boot/boot.sdi' 'sources/boot.wim' 1 'bootmgr.exe'
else
vtoy_windows_wimboot
fi
}
function legacy_windows_menu_func {
vt_windows_reset
if vt_check_mode 4 "$vt_chosen_name"; then
vtoy_windows_wimboot_func
vt_windows_chain_data "${1}${chosen_path}"
ventoy_debug_pause
vtoy_wimboot_func
else
if [ "$ventoy_compatible" = "NO" ]; then
if [ "$ventoy_fs_probe" = "iso9660" ]; then
loopback -d loop
vt_iso9660_nojoliet 1
loopback loop "$1$2"
fi
for file in "boot/bcd" "/efi/microsoft/boot/bcd" "SSTR/BCD" "boot/bce"; do
vt_windows_collect_wim_patch bcd (loop)/$file
done
distro_specify_wim_patch
vt_windows_count_wim_patch vt_wim_cnt
if [ $vt_wim_cnt -eq 0 ]; then
distro_specify_wim_patch_phase2
fi
ventoy_debug_pause
locate_wim "${chosen_path}"
fi
vt_windows_chain_data "${1}${chosen_path}"
ventoy_debug_pause
fi
if [ -n "$vtoy_chain_mem_addr" ]; then
......
......@@ -36,6 +36,8 @@ static ventoy_guid g_ventoy_guid = VENTOY_GUID;
static HANDLE g_vtoylog_mutex = NULL;
static HANDLE g_vtoyins_mutex = NULL;
static BOOL g_wimboot_mode = FALSE;
static DWORD g_vtoy_disk_drive;
static CHAR g_prog_full_path[MAX_PATH];
......@@ -46,33 +48,34 @@ static CHAR g_prog_name[MAX_PATH];
#define ORG_PECMD_PATH "X:\\Windows\\system32\\PECMD.EXE"
#define ORG_PECMD_BK_PATH "X:\\Windows\\system32\\PECMD.EXE_BACK.EXE"
#define WIMBOOT_FILE "X:\\Windows\\system32\\vtoy_wimboot"
#define WIMBOOT_DONE "X:\\Windows\\system32\\vtoy_wimboot_done"
#define AUTO_RUN_BAT "X:\\VentoyAutoRun.bat"
#define AUTO_RUN_LOG "X:\\VentoyAutoRun.log"
#define VTOY_AUTO_FILE "X:\\_vtoy_auto_install"
#define WINPESHL_INI "X:\\Windows\\system32\\winpeshl.ini"
#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;
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)
......@@ -92,27 +95,59 @@ static int split_path_name(char *fullpath, char *dir, char *name)
return 0;
}
static void TrimString(CHAR *String, BOOL TrimLeft)
{
CHAR *Pos1 = String;
CHAR *Pos2 = String;
size_t Len = strlen(String);
while (Len > 0)
{
if (String[Len - 1] != ' ' && String[Len - 1] != '\t')
{
break;
}
String[Len - 1] = 0;
Len--;
}
if (TrimLeft)
{
while (*Pos1 == ' ' || *Pos1 == '\t')
{
Pos1++;
}
while (*Pos1)
{
*Pos2++ = *Pos1++;
}
*Pos2++ = 0;
}
return;
}
void Log(const char *Fmt, ...)
{
va_list Arg;
int Len = 0;
FILE *File = NULL;
SYSTEMTIME Sys;
char szBuf[1024];
va_list Arg;
int Len = 0;
FILE *File = NULL;
SYSTEMTIME Sys;
char szBuf[1024];
DWORD LockStatus = 0;
DWORD PID = GetCurrentProcessId();
GetLocalTime(&Sys);
Len += sprintf_s(szBuf, sizeof(szBuf),
"[%4d/%02d/%02d %02d:%02d:%02d.%03d] [%u] ",
Sys.wYear, Sys.wMonth, Sys.wDay,
Sys.wHour, Sys.wMinute, Sys.wSecond,
GetLocalTime(&Sys);
Len += sprintf_s(szBuf, sizeof(szBuf),
"[%4d/%02d/%02d %02d:%02d:%02d.%03d] [%u] ",
Sys.wYear, Sys.wMonth, Sys.wDay,
Sys.wHour, Sys.wMinute, Sys.wSecond,
Sys.wMilliseconds, PID);
va_start(Arg, Fmt);
Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg);
va_end(Arg);
va_start(Arg, Fmt);
Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg);
va_end(Arg);
MUTEX_LOCK(g_vtoylog_mutex);
......@@ -130,140 +165,140 @@ void Log(const char *Fmt, ...)
static int LoadNtDriver(const char *DrvBinPath)
{
int i;
int rc = 0;
BOOL Ret;
DWORD Status;
SC_HANDLE hServiceMgr;
SC_HANDLE hService;
char name[256] = { 0 };
for (i = (int)strlen(DrvBinPath) - 1; i >= 0; i--)
{
if (DrvBinPath[i] == '\\' || DrvBinPath[i] == '/')
{
sprintf_s(name, sizeof(name), "%s", DrvBinPath + i + 1);
break;
}
}
Log("Load NT driver: %s %s", DrvBinPath, name);
hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hServiceMgr == NULL)
{
Log("OpenSCManager failed Error:%u", GetLastError());
return 1;
}
Log("OpenSCManager OK");
hService = CreateServiceA(hServiceMgr,
name,
name,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
DrvBinPath,
NULL, NULL, NULL, NULL, NULL);
if (hService == NULL)
{
Status = GetLastError();
if (Status != ERROR_IO_PENDING && Status != ERROR_SERVICE_EXISTS)
{
Log("CreateService failed v %u", Status);
CloseServiceHandle(hServiceMgr);
return 1;
}
hService = OpenServiceA(hServiceMgr, name, SERVICE_ALL_ACCESS);
if (hService == NULL)
{
Log("OpenService failed %u", Status);
CloseServiceHandle(hServiceMgr);
return 1;
}
}
Log("CreateService imdisk OK");
Ret = StartServiceA(hService, 0, NULL);
if (Ret)
{
Log("StartService OK");
}
else
{
Status = GetLastError();
if (Status == ERROR_SERVICE_ALREADY_RUNNING)
{
rc = 0;
}
else
{
Log("StartService error %u", Status);
rc = 1;
}
}
CloseServiceHandle(hService);
CloseServiceHandle(hServiceMgr);
Log("Load NT driver %s", rc ? "failed" : "success");
return rc;
int i;
int rc = 0;
BOOL Ret;
DWORD Status;
SC_HANDLE hServiceMgr;
SC_HANDLE hService;
char name[256] = { 0 };
for (i = (int)strlen(DrvBinPath) - 1; i >= 0; i--)
{
if (DrvBinPath[i] == '\\' || DrvBinPath[i] == '/')
{
sprintf_s(name, sizeof(name), "%s", DrvBinPath + i + 1);
break;
}
}
Log("Load NT driver: %s %s", DrvBinPath, name);
hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hServiceMgr == NULL)
{
Log("OpenSCManager failed Error:%u", GetLastError());
return 1;
}
Log("OpenSCManager OK");
hService = CreateServiceA(hServiceMgr,
name,
name,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
DrvBinPath,
NULL, NULL, NULL, NULL, NULL);
if (hService == NULL)
{
Status = GetLastError();
if (Status != ERROR_IO_PENDING && Status != ERROR_SERVICE_EXISTS)
{
Log("CreateService failed v %u", Status);
CloseServiceHandle(hServiceMgr);
return 1;
}
hService = OpenServiceA(hServiceMgr, name, SERVICE_ALL_ACCESS);
if (hService == NULL)
{
Log("OpenService failed %u", Status);
CloseServiceHandle(hServiceMgr);
return 1;
}
}
Log("CreateService imdisk OK");
Ret = StartServiceA(hService, 0, NULL);
if (Ret)
{
Log("StartService OK");
}
else
{
Status = GetLastError();
if (Status == ERROR_SERVICE_ALREADY_RUNNING)
{
rc = 0;
}
else
{
Log("StartService error %u", Status);
rc = 1;
}
}
CloseServiceHandle(hService);
CloseServiceHandle(hServiceMgr);
Log("Load NT driver %s", rc ? "failed" : "success");
return rc;
}
static int ReadWholeFile2Buf(const char *Fullpath, void **Data, DWORD *Size)
{
int rc = 1;
DWORD FileSize;
DWORD dwSize;
HANDLE Handle;
BYTE *Buffer = NULL;
int rc = 1;
DWORD FileSize;
DWORD dwSize;
HANDLE Handle;
BYTE *Buffer = NULL;
Log("ReadWholeFile2Buf <%s>", Fullpath);
Log("ReadWholeFile2Buf <%s>", Fullpath);
Handle = CreateFileA(Fullpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (Handle == INVALID_HANDLE_VALUE)
{
Log("Could not open the file<%s>, error:%u", Fullpath, GetLastError());
goto End;
}
Handle = CreateFileA(Fullpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (Handle == INVALID_HANDLE_VALUE)
{
Log("Could not open the file<%s>, error:%u", Fullpath, GetLastError());
goto End;
}
FileSize = SetFilePointer(Handle, 0, NULL, FILE_END);
FileSize = SetFilePointer(Handle, 0, NULL, FILE_END);
Buffer = malloc(FileSize);
if (!Buffer)
{
Log("Failed to alloc memory size:%u", FileSize);
goto End;
}
Buffer = malloc(FileSize);
if (!Buffer)
{
Log("Failed to alloc memory size:%u", FileSize);
goto End;
}
SetFilePointer(Handle, 0, NULL, FILE_BEGIN);
if (!ReadFile(Handle, Buffer, FileSize, &dwSize, NULL))
{
Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
goto End;
}
SetFilePointer(Handle, 0, NULL, FILE_BEGIN);
if (!ReadFile(Handle, Buffer, FileSize, &dwSize, NULL))
{
Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
goto End;
}
*Data = Buffer;
*Size = FileSize;
*Data = Buffer;
*Size = FileSize;
Log("Success read file size:%u", FileSize);
Log("Success read file size:%u", FileSize);
rc = 0;
rc = 0;
End:
SAFE_CLOSE_HANDLE(Handle);
SAFE_CLOSE_HANDLE(Handle);
return rc;
return rc;
}
static BOOL CheckPeHead(BYTE *Buffer, DWORD Size, DWORD Offset)
{
UINT32 PeOffset;
UINT32 PeOffset;
BYTE *Head = NULL;
DWORD End;
ventoy_windows_data *pdata = NULL;
......@@ -281,73 +316,73 @@ static BOOL CheckPeHead(BYTE *Buffer, DWORD Size, DWORD Offset)
}
}
if (Head[0] != 'M' || Head[1] != 'Z')
{
return FALSE;
}
if (Head[0] != 'M' || Head[1] != 'Z')
{
return FALSE;
}
PeOffset = *(UINT32 *)(Head + 60);
if (*(UINT32 *)(Head + PeOffset) != 0x00004550)
{
return FALSE;
}
PeOffset = *(UINT32 *)(Head + 60);
if (*(UINT32 *)(Head + PeOffset) != 0x00004550)
{
return FALSE;
}
return TRUE;
return TRUE;
}
static BOOL CheckOsParam(ventoy_os_param *param)
{
UINT32 i;
BYTE Sum = 0;
if (memcmp(&param->guid, &g_ventoy_guid, sizeof(ventoy_guid)))
{
return FALSE;
}
for (i = 0; i < sizeof(ventoy_os_param); i++)
{
Sum += *((BYTE *)param + i);
}
if (Sum)
{
return FALSE;
}
if (param->vtoy_img_location_addr % 4096)
{
return FALSE;
}
return TRUE;
UINT32 i;
BYTE Sum = 0;
if (memcmp(&param->guid, &g_ventoy_guid, sizeof(ventoy_guid)))
{
return FALSE;
}
for (i = 0; i < sizeof(ventoy_os_param); i++)
{
Sum += *((BYTE *)param + i);
}
if (Sum)
{
return FALSE;
}
if (param->vtoy_img_location_addr % 4096)
{
return FALSE;
}
return TRUE;
}
static int SaveBuffer2File(const char *Fullpath, void *Buffer, DWORD Length)
{
int rc = 1;
DWORD dwSize;
HANDLE Handle;
int rc = 1;
DWORD dwSize;
HANDLE Handle;
Log("SaveBuffer2File <%s> len:%u", Fullpath, Length);
Log("SaveBuffer2File <%s> len:%u", Fullpath, Length);
Handle = CreateFileA(Fullpath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, 0, 0);
if (Handle == INVALID_HANDLE_VALUE)
{
Log("Could not create new file, error:%u", GetLastError());
goto End;
}
Handle = CreateFileA(Fullpath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, 0, 0);
if (Handle == INVALID_HANDLE_VALUE)
{
Log("Could not create new file, error:%u", GetLastError());
goto End;
}
WriteFile(Handle, Buffer, Length, &dwSize, NULL);
WriteFile(Handle, Buffer, Length, &dwSize, NULL);
rc = 0;
rc = 0;
End:
SAFE_CLOSE_HANDLE(Handle);
SAFE_CLOSE_HANDLE(Handle);
return rc;
return rc;
}
static int IsUTF8Encode(const char *src)
......@@ -406,17 +441,17 @@ static BOOL IsDirExist(const char *Fmt, ...)
static BOOL IsFileExist(const char *Fmt, ...)
{
va_list Arg;
HANDLE hFile;
DWORD Attr;
va_list Arg;
HANDLE hFile;
DWORD Attr;
BOOL bRet = FALSE;
int UTF8 = 0;
CHAR FilePathA[MAX_PATH];
WCHAR FilePathW[MAX_PATH];
CHAR FilePathA[MAX_PATH];
WCHAR FilePathW[MAX_PATH];
va_start(Arg, Fmt);
vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg);
va_end(Arg);
va_start(Arg, Fmt);
vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg);
va_end(Arg);
UTF8 = IsUTF8Encode(FilePathA);
......@@ -429,12 +464,12 @@ static BOOL IsFileExist(const char *Fmt, ...)
{
hFile = CreateFileA(FilePathA, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
}
if (INVALID_HANDLE_VALUE == hFile)
{
if (INVALID_HANDLE_VALUE == hFile)
{
goto out;
}
}
CloseHandle(hFile);
CloseHandle(hFile);
if (UTF8)
{
......@@ -444,7 +479,7 @@ static BOOL IsFileExist(const char *Fmt, ...)
{
Attr = GetFileAttributesA(FilePathA);
}
if (Attr & FILE_ATTRIBUTE_DIRECTORY)
{
goto out;
......@@ -459,66 +494,66 @@ out:
static int GetPhyDiskUUID(const char LogicalDrive, UINT8 *UUID, UINT32 *DiskSig, DISK_EXTENT *DiskExtent)
{
BOOL Ret;
DWORD dwSize;
HANDLE Handle;
VOLUME_DISK_EXTENTS DiskExtents;
CHAR PhyPath[128];
UINT8 SectorBuf[512];
Log("GetPhyDiskUUID %C", LogicalDrive);
sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive);
Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (Handle == INVALID_HANDLE_VALUE)
{
Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
return 1;
}
Ret = DeviceIoControl(Handle,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL,
0,
&DiskExtents,
(DWORD)(sizeof(DiskExtents)),
(LPDWORD)&dwSize,
NULL);
if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
{
Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u", GetLastError());
CloseHandle(Handle);
return 1;
}
CloseHandle(Handle);
BOOL Ret;
DWORD dwSize;
HANDLE Handle;
VOLUME_DISK_EXTENTS DiskExtents;
CHAR PhyPath[128];
UINT8 SectorBuf[512];
Log("GetPhyDiskUUID %C", LogicalDrive);
sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive);
Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (Handle == INVALID_HANDLE_VALUE)
{
Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
return 1;
}
Ret = DeviceIoControl(Handle,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL,
0,
&DiskExtents,
(DWORD)(sizeof(DiskExtents)),
(LPDWORD)&dwSize,
NULL);
if (!Ret || DiskExtents.NumberOfDiskExtents == 0)
{
Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u", GetLastError());
CloseHandle(Handle);
return 1;
}
CloseHandle(Handle);
memcpy(DiskExtent, DiskExtents.Extents, sizeof(DISK_EXTENT));
Log("%C: is in PhysicalDrive%d Offset:%llu", LogicalDrive, DiskExtents.Extents[0].DiskNumber,
(ULONGLONG)(DiskExtents.Extents[0].StartingOffset.QuadPart));
sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber);
Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (Handle == INVALID_HANDLE_VALUE)
{
Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
return 1;
}
if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL))
{
Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
CloseHandle(Handle);
return 1;
}
memcpy(UUID, SectorBuf + 0x180, 16);
sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber);
Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (Handle == INVALID_HANDLE_VALUE)
{
Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
return 1;
}
if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL))
{
Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError());
CloseHandle(Handle);
return 1;
}
memcpy(UUID, SectorBuf + 0x180, 16);
if (DiskSig)
{
memcpy(DiskSig, SectorBuf + 0x1B8, 4);
}
CloseHandle(Handle);
return 0;
CloseHandle(Handle);
return 0;
}
static int VentoyMountAnywhere(HANDLE Handle)
......@@ -605,7 +640,7 @@ int VentoyMountY(HANDLE Handle)
static BOOL VentoyAPINeedMountY(const char *IsoPath)
{
(void)IsoPath;
(void)IsoPath;
/* TBD */
return FALSE;
......@@ -628,7 +663,7 @@ static int VentoyAttachVirtualDisk(HANDLE Handle, const char *IsoPath)
DriveYFree = 1;
}
if (DriveYFree && VentoyAPINeedMountY(IsoPath))
if (DriveYFree && VentoyAPINeedMountY(IsoPath))
{
return VentoyMountY(Handle);
}
......@@ -641,13 +676,13 @@ static int VentoyAttachVirtualDisk(HANDLE Handle, const char *IsoPath)
int VentoyMountISOByAPI(const char *IsoPath)
{
int i;
HANDLE Handle;
DWORD Status;
WCHAR wFilePath[512] = { 0 };
VIRTUAL_STORAGE_TYPE StorageType;
OPEN_VIRTUAL_DISK_PARAMETERS OpenParameters;
HANDLE Handle;
DWORD Status;
WCHAR wFilePath[512] = { 0 };
VIRTUAL_STORAGE_TYPE StorageType;
OPEN_VIRTUAL_DISK_PARAMETERS OpenParameters;
Log("VentoyMountISOByAPI <%s>", IsoPath);
Log("VentoyMountISOByAPI <%s>", IsoPath);
if (IsUTF8Encode(IsoPath))
{
......@@ -660,10 +695,10 @@ int VentoyMountISOByAPI(const char *IsoPath)
MultiByteToWideChar(CP_ACP, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR)));
}
memset(&StorageType, 0, sizeof(StorageType));
memset(&OpenParameters, 0, sizeof(OpenParameters));
OpenParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
memset(&StorageType, 0, sizeof(StorageType));
memset(&OpenParameters, 0, sizeof(OpenParameters));
OpenParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
for (i = 0; i < 10; i++)
{
......@@ -691,309 +726,400 @@ int VentoyMountISOByAPI(const char *IsoPath)
}
}
if (Status != ERROR_SUCCESS)
if (Status != ERROR_SUCCESS)
{
return 1;
}
Log("OpenVirtualDisk success");
Status = VentoyAttachVirtualDisk(Handle, IsoPath);
if (Status != ERROR_SUCCESS)
{
Log("Failed to attach virtual disk ErrorCode:%u", Status);
CloseHandle(Handle);
return 1;
}
Log("VentoyAttachVirtualDisk success");
CloseHandle(Handle);
return 0;
}
static HANDLE g_FatPhyDrive;
static UINT64 g_Part2StartSec;
static int CopyFileFromFatDisk(const CHAR* SrcFile, const CHAR *DstFile)
{
int rc = 1;
int size = 0;
char *buf = NULL;
void *flfile = NULL;
Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile, DstFile);
flfile = fl_fopen(SrcFile, "rb");
if (flfile)
{
fl_fseek(flfile, 0, SEEK_END);
size = (int)fl_ftell(flfile);
fl_fseek(flfile, 0, SEEK_SET);
buf = (char *)malloc(size);
if (buf)
{
fl_fread(buf, 1, size, flfile);
rc = 0;
SaveBuffer2File(DstFile, buf, size);
free(buf);
}
fl_fclose(flfile);
}
return rc;
}
static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
{
DWORD dwSize;
BOOL bRet;
DWORD ReadSize;
LARGE_INTEGER liCurrentPosition;
liCurrentPosition.QuadPart = Sector + g_Part2StartSec;
liCurrentPosition.QuadPart *= 512;
SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN);
ReadSize = (DWORD)(SectorCount * 512);
bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL);
if (bRet == FALSE || dwSize != ReadSize)
{
Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u", bRet, ReadSize, dwSize, GetLastError());
}
return 1;
}
static BOOL Is2K10PE(void)
{
BOOL bRet = FALSE;
FILE *fp = NULL;
CHAR szLine[1024];
fopen_s(&fp, "X:\\Windows\\System32\\PECMD.INI", "r");
if (!fp)
{
return FALSE;
}
memset(szLine, 0, sizeof(szLine));
while (fgets(szLine, sizeof(szLine) - 1, fp))
{
if (strstr(szLine, "2k10\\"))
{
bRet = TRUE;
break;
}
}
fclose(fp);
return bRet;
}
static CHAR GetIMDiskMountLogicalDrive(void)
{
CHAR Letter = 'Y';
DWORD Drives;
DWORD Mask = 0x1000000;
// fixed use M as mountpoint for 2K10 PE
if (Is2K10PE())
{
Log("Use M: for 2K10 PE");
return 'M';
}
Drives = GetLogicalDrives();
Log("Drives=0x%x", Drives);
while (Mask)
{
if ((Drives & Mask) == 0)
{
break;
}
Letter--;
Mask >>= 1;
}
return Letter;
}
UINT64 GetVentoyEfiPartStartSector(HANDLE hDrive)
{
BOOL bRet;
DWORD dwSize;
MBR_HEAD MBR;
VTOY_GPT_INFO *pGpt = NULL;
UINT64 StartSector = 0;
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);
if ((!bRet) || (dwSize != sizeof(MBR)))
{
0;
}
if (MBR.PartTbl[0].FsFlag == 0xEE)
{
Log("GPT partition style");
pGpt = malloc(sizeof(VTOY_GPT_INFO));
if (!pGpt)
{
return 0;
}
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL);
if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO)))
{
Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR);
return 0;
}
StartSector = pGpt->PartTbl[1].StartLBA;
free(pGpt);
}
else
{
Log("MBR partition style");
StartSector = MBR.PartTbl[1].StartSectorId;
}
Log("GetVentoyEfiPart StartSector: %llu", StartSector);
return StartSector;
}
static int VentoyRunImdisk(const char *IsoPath, const char *imdiskexe)
{
CHAR Letter;
CHAR Cmdline[512];
WCHAR CmdlineW[512];
PROCESS_INFORMATION Pi;
Log("VentoyRunImdisk <%s> <%s>", IsoPath, imdiskexe);
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);
if (IsUTF8Encode(IsoPath))
{
STARTUPINFOW Si;
GetStartupInfoW(&Si);
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
Utf8ToUtf16(Cmdline, CmdlineW);
CreateProcessW(NULL, CmdlineW, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
Log("This is UTF8 encoding");
}
else
{
STARTUPINFOA Si;
GetStartupInfoA(&Si);
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
CreateProcessA(NULL, Cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
Log("This is ANSI encoding");
}
Log("Wait for imdisk process ...");
WaitForSingleObject(Pi.hProcess, INFINITE);
Log("imdisk process finished");
return 0;
}
int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive)
{
int rc = 1;
BOOL bRet;
DWORD dwBytes;
HANDLE hDrive;
CHAR PhyPath[MAX_PATH];
GET_LENGTH_INFORMATION LengthInfo;
Log("VentoyMountISOByImdisk %s", IsoPath);
if (IsFileExist("X:\\Windows\\System32\\imdisk.exe"))
{
Log("imdisk.exe exist, use it directly...");
VentoyRunImdisk(IsoPath, "imdisk.exe");
return 0;
}
sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", PhyDrive);
hDrive = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (hDrive == INVALID_HANDLE_VALUE)
{
Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
goto End;
}
bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL);
if (!bRet)
{
return 1;
Log("Could not get phy disk %s size, error:%u", PhyPath, GetLastError());
goto End;
}
Log("OpenVirtualDisk success");
g_FatPhyDrive = hDrive;
g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive);
Status = VentoyAttachVirtualDisk(Handle, IsoPath);
if (Status != ERROR_SUCCESS)
{
Log("Failed to attach virtual disk ErrorCode:%u", Status);
CloseHandle(Handle);
return 1;
}
Log("Parse FAT fs...");
Log("VentoyAttachVirtualDisk success");
fl_init();
CloseHandle(Handle);
return 0;
}
if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
{
if (g_system_bit == 64)
{
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys");
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe");
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.cpl", "ventoy\\imdisk.cpl");
}
else
{
CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.sys", "ventoy\\imdisk.sys");
CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.exe", "ventoy\\imdisk.exe");
CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.cpl", "ventoy\\imdisk.cpl");
}
GetCurrentDirectoryA(sizeof(PhyPath), PhyPath);
strcat_s(PhyPath, sizeof(PhyPath), "\\ventoy\\imdisk.sys");
if (LoadNtDriver(PhyPath) == 0)
{
VentoyRunImdisk(IsoPath, "ventoy\\imdisk.exe");
rc = 0;
}
}
fl_shutdown();
End:
static HANDLE g_FatPhyDrive;
static UINT64 g_Part2StartSec;
SAFE_CLOSE_HANDLE(hDrive);
static int CopyFileFromFatDisk(const CHAR* SrcFile, const CHAR *DstFile)
{
int rc = 1;
int size = 0;
char *buf = NULL;
void *flfile = NULL;
Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile, DstFile);
flfile = fl_fopen(SrcFile, "rb");
if (flfile)
{
fl_fseek(flfile, 0, SEEK_END);
size = (int)fl_ftell(flfile);
fl_fseek(flfile, 0, SEEK_SET);
buf = (char *)malloc(size);
if (buf)
{
fl_fread(buf, 1, size, flfile);
rc = 0;
SaveBuffer2File(DstFile, buf, size);
free(buf);
}
fl_fclose(flfile);
}
return rc;
return rc;
}
static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)
static int GetIsoId(CONST CHAR *IsoPath, IsoId *ids)
{
DWORD dwSize;
BOOL bRet;
DWORD ReadSize;
LARGE_INTEGER liCurrentPosition;
int i;
int n = 0;
HANDLE hFile;
DWORD dwSize = 0;
BOOL bRet[8];
liCurrentPosition.QuadPart = Sector + g_Part2StartSec;
liCurrentPosition.QuadPart *= 512;
SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN);
hFile = CreateFileA(IsoPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return 1;
}
ReadSize = (DWORD)(SectorCount * 512);
SetFilePointer(hFile, 2048 * 16 + 8, NULL, FILE_BEGIN);
bRet[n++] = ReadFile(hFile, ids->SystemId, 32, &dwSize, NULL);
SetFilePointer(hFile, 2048 * 16 + 40, NULL, FILE_BEGIN);
bRet[n++] = ReadFile(hFile, ids->VolumeId, 32, &dwSize, NULL);
bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL);
if (bRet == FALSE || dwSize != ReadSize)
{
Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u", bRet, ReadSize, dwSize, GetLastError());
}
SetFilePointer(hFile, 2048 * 16 + 318, NULL, FILE_BEGIN);
bRet[n++] = ReadFile(hFile, ids->PulisherId, 128, &dwSize, NULL);
return 1;
}
SetFilePointer(hFile, 2048 * 16 + 446, NULL, FILE_BEGIN);
bRet[n++] = ReadFile(hFile, ids->PreparerId, 128, &dwSize, NULL);
static BOOL Is2K10PE(void)
{
BOOL bRet = FALSE;
FILE *fp = NULL;
CHAR szLine[1024];
fopen_s(&fp, "X:\\Windows\\System32\\PECMD.INI", "r");
if (!fp)
{
return FALSE;
}
memset(szLine, 0, sizeof(szLine));
while (fgets(szLine, sizeof(szLine) - 1, fp))
{
if (strstr(szLine, "2k10\\"))
{
bRet = TRUE;
break;
}
}
fclose(fp);
return bRet;
}
CloseHandle(hFile);
static CHAR GetIMDiskMountLogicalDrive(void)
{
CHAR Letter = 'Y';
DWORD Drives;
DWORD Mask = 0x1000000;
// fixed use M as mountpoint for 2K10 PE
if (Is2K10PE())
{
Log("Use M: for 2K10 PE");
return 'M';
}
Drives = GetLogicalDrives();
Log("Drives=0x%x", Drives);
while (Mask)
{
if ((Drives & Mask) == 0)
{
break;
}
Letter--;
Mask >>= 1;
}
return Letter;
}
UINT64 GetVentoyEfiPartStartSector(HANDLE hDrive)
{
BOOL bRet;
DWORD dwSize;
MBR_HEAD MBR;
VTOY_GPT_INFO *pGpt = NULL;
UINT64 StartSector = 0;
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);
Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);
if ((!bRet) || (dwSize != sizeof(MBR)))
{
0;
}
if (MBR.PartTbl[0].FsFlag == 0xEE)
{
Log("GPT partition style");
pGpt = malloc(sizeof(VTOY_GPT_INFO));
if (!pGpt)
{
return 0;
}
SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);
bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL);
if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO)))
{
Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR);
return 0;
}
StartSector = pGpt->PartTbl[1].StartLBA;
free(pGpt);
}
else
{
Log("MBR partition style");
StartSector = MBR.PartTbl[1].StartSectorId;
}
Log("GetVentoyEfiPart StartSector: %llu", StartSector);
return StartSector;
}
for (i = 0; i < n; i++)
{
if (bRet[i] == FALSE)
{
return 1;
}
}
static int VentoyRunImdisk(const char *IsoPath, const char *imdiskexe)
{
CHAR Letter;
CHAR Cmdline[512];
WCHAR CmdlineW[512];
PROCESS_INFORMATION Pi;
Log("VentoyRunImdisk <%s> <%s>", IsoPath, imdiskexe);
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);
if (IsUTF8Encode(IsoPath))
{
STARTUPINFOW Si;
GetStartupInfoW(&Si);
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
Utf8ToUtf16(Cmdline, CmdlineW);
CreateProcessW(NULL, CmdlineW, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
Log("This is UTF8 encoding");
}
else
{
STARTUPINFOA Si;
GetStartupInfoA(&Si);
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
CreateProcessA(NULL, Cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
Log("This is ANSI encoding");
}
Log("Wait for imdisk process ...");
WaitForSingleObject(Pi.hProcess, INFINITE);
Log("imdisk process finished");
return 0;
TrimString(ids->SystemId, FALSE);
TrimString(ids->VolumeId, FALSE);
TrimString(ids->PulisherId, FALSE);
TrimString(ids->PreparerId, FALSE);
Log("ISO ID: System<%s> Volume<%s> Pulisher<%s> Preparer<%s>",
ids->SystemId, ids->VolumeId, ids->PulisherId, ids->PreparerId);
return 0;
}
int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive)
static int CheckSkipMountIso(CONST CHAR *IsoPath)
{
int rc = 1;
BOOL bRet;
DWORD dwBytes;
HANDLE hDrive;
CHAR PhyPath[MAX_PATH];
GET_LENGTH_INFORMATION LengthInfo;
Log("VentoyMountISOByImdisk %s", IsoPath);
if (IsFileExist("X:\\Windows\\System32\\imdisk.exe"))
{
Log("imdisk.exe exist, use it directly...");
VentoyRunImdisk(IsoPath, "imdisk.exe");
return 0;
}
sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", PhyDrive);
hDrive = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (hDrive == INVALID_HANDLE_VALUE)
{
Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());
goto End;
}
bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL);
if (!bRet)
{
Log("Could not get phy disk %s size, error:%u", PhyPath, GetLastError());
goto End;
}
g_FatPhyDrive = hDrive;
g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive);
Log("Parse FAT fs...");
fl_init();
if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
{
if (g_system_bit == 64)
{
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys");
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe");
CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.cpl", "ventoy\\imdisk.cpl");
}
else
{
CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.sys", "ventoy\\imdisk.sys");
CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.exe", "ventoy\\imdisk.exe");
CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.cpl", "ventoy\\imdisk.cpl");
}
GetCurrentDirectoryA(sizeof(PhyPath), PhyPath);
strcat_s(PhyPath, sizeof(PhyPath), "\\ventoy\\imdisk.sys");
if (LoadNtDriver(PhyPath) == 0)
{
VentoyRunImdisk(IsoPath, "ventoy\\imdisk.exe");
rc = 0;
}
}
fl_shutdown();
BOOL InRoot = FALSE;
int slashcnt = 0;
CONST CHAR *p = NULL;
IsoId ID;
End:
// C:\\xxx
for (p = IsoPath; *p; p++)
{
if (*p == '\\' || *p == '/')
{
slashcnt++;
}
}
if (slashcnt == 2)
{
InRoot = TRUE;
}
SAFE_CLOSE_HANDLE(hDrive);
memset(&ID, 0, sizeof(ID));
if (GetIsoId(IsoPath, &ID))
{
return 0;
}
//Bob.Ombs.Modified.Win10PEx64.iso will auto find ISO file in root, so we can skip the mount
if (InRoot && strcmp(ID.VolumeId, "Modified-Win10PEx64") == 0)
{
return 1;
}
return rc;
return 0;
}
static int MountIsoFile(CONST CHAR *IsoPath, DWORD PhyDrive)
{
if (CheckSkipMountIso(IsoPath))
{
Log("Skip mount ISO file for <%s>", IsoPath);
return 0;
}
if (IsWindows8OrGreater())
{
Log("This is Windows 8 or latter...");
......@@ -1196,7 +1322,7 @@ static int DecompressInjectionArchive(const char *archive, DWORD PhyDrive)
}
g_FatPhyDrive = hDrive;
g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive);
g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive);
Log("Parse FAT fs...");
......@@ -1204,7 +1330,7 @@ static int DecompressInjectionArchive(const char *archive, DWORD PhyDrive)
if (0 == fl_attach_media(VentoyFatDiskRead, NULL))
{
if (g_system_bit == 64)
if (g_system_bit == 64)
{
CopyFileFromFatDisk("/ventoy/7z/64/7za.xz", "ventoy\\7za.xz");
}
......@@ -1301,10 +1427,10 @@ static int UnattendNeedVarExpand(const char *script)
char szLine[4096];
fopen_s(&fp, script, "r");
if (!fp)
{
return 0;
}
if (!fp)
{
return 0;
}
szLine[0] = szLine[4095] = 0;
......@@ -1417,36 +1543,6 @@ static int ExpandSingleVar(VarDiskInfo *pDiskInfo, int DiskNum, const char *var,
return 0;
}
static void TrimString(CHAR *String)
{
CHAR *Pos1 = String;
CHAR *Pos2 = String;
size_t Len = strlen(String);
while (Len > 0)
{
if (String[Len - 1] != ' ' && String[Len - 1] != '\t')
{
break;
}
String[Len - 1] = 0;
Len--;
}
while (*Pos1 == ' ' || *Pos1 == '\t')
{
Pos1++;
}
while (*Pos1)
{
*Pos2++ = *Pos1++;
}
*Pos2++ = 0;
return;
}
static int GetRegDwordValue(HKEY Key, LPCSTR SubKey, LPCSTR ValueName, DWORD *pValue)
{
HKEY hKey;
......@@ -1655,25 +1751,25 @@ static int EnumerateAllDisk(VarDiskInfo **ppDiskInfo, int *pDiskNum)
if (pDevDesc->VendorIdOffset)
{
safe_strcpy(pDiskInfo[i].VendorId, (char *)pDevDesc + pDevDesc->VendorIdOffset);
TrimString(pDiskInfo[i].VendorId);
TrimString(pDiskInfo[i].VendorId, TRUE);
}
if (pDevDesc->ProductIdOffset)
{
safe_strcpy(pDiskInfo[i].ProductId, (char *)pDevDesc + pDevDesc->ProductIdOffset);
TrimString(pDiskInfo[i].ProductId);
TrimString(pDiskInfo[i].ProductId, TRUE);
}
if (pDevDesc->ProductRevisionOffset)
{
safe_strcpy(pDiskInfo[i].ProductRev, (char *)pDevDesc + pDevDesc->ProductRevisionOffset);
TrimString(pDiskInfo[i].ProductRev);
TrimString(pDiskInfo[i].ProductRev, TRUE);
}
if (pDevDesc->SerialNumberOffset)
{
safe_strcpy(pDiskInfo[i].SerialNumber, (char *)pDevDesc + pDevDesc->SerialNumberOffset);
TrimString(pDiskInfo[i].SerialNumber);
TrimString(pDiskInfo[i].SerialNumber, TRUE);
}
free(pDevDesc);
......@@ -1716,19 +1812,19 @@ static int UnattendVarExpand(const char *script, const char *tmpfile)
}
fopen_s(&fp, script, "r");
if (!fp)
{
if (!fp)
{
free(pDiskInfo);
return 0;
}
return 0;
}
fopen_s(&fout, tmpfile, "w+");
if (!fout)
{
fclose(fp);
if (!fout)
{
fclose(fp);
free(pDiskInfo);
return 0;
}
return 0;
}
szLine[0] = szLine[4095] = 0;
......@@ -1979,12 +2075,12 @@ static int VentoyHook(ventoy_os_param *param)
DWORD VtoyDiskNum;
UINT32 DiskSig;
UINT32 VtoySig;
DISK_EXTENT DiskExtent;
DISK_EXTENT DiskExtent;
DISK_EXTENT VtoyDiskExtent;
UINT8 UUID[16];
CHAR IsoPath[MAX_PATH];
UINT8 UUID[16];
CHAR IsoPath[MAX_PATH];
Log("VentoyHook Path:<%s>", param->vtoy_img_path);
Log("VentoyHook Path:<%s>", param->vtoy_img_path);
if (IsUTF8Encode(param->vtoy_img_path))
{
......@@ -2039,12 +2135,12 @@ static int VentoyHook(ventoy_os_param *param)
}
if (find == FALSE)
{
Log("Failed to find ISO file");
return 1;
}
{
Log("Failed to find ISO file");
return 1;
}
Log("Find ISO file <%s>", IsoPath);
Log("Find ISO file <%s>", IsoPath);
//Find VtoyLetter in Vlnk Mode
if (g_os_param_reserved[6] == 1)
......@@ -2258,59 +2354,6 @@ static int ExtractWindowsDataFile(char *databuf)
return len;
}
int VentoyJumpWimboot(INT argc, CHAR **argv, CHAR *LunchFile)
{
int rc = 1;
char *buf = NULL;
DWORD size = 0;
DWORD Pos;
Log("VentoyJumpWimboot %dbit", g_system_bit);
sprintf_s(LunchFile, MAX_PATH, "X:\\setup.exe");
ReadWholeFile2Buf("wimboot.data", &buf, &size);
Log("wimboot.data size:%d", size);
memcpy(&g_os_param, buf, sizeof(ventoy_os_param));
memcpy(&g_windows_data, buf + sizeof(ventoy_os_param), sizeof(ventoy_windows_data));
ExtractWindowsDataFile(buf + sizeof(ventoy_os_param));
memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved));
if (g_os_param_reserved[0] == 1)
{
Log("break here for debug .....");
goto End;
}
// convert / to \\
for (Pos = 0; Pos < sizeof(g_os_param.vtoy_img_path) && g_os_param.vtoy_img_path[Pos]; Pos++)
{
if (g_os_param.vtoy_img_path[Pos] == '/')
{
g_os_param.vtoy_img_path[Pos] = '\\';
}
}
if (g_os_param_reserved[0] == 2)
{
Log("skip hook for debug .....");
rc = 0;
goto End;
}
rc = VentoyHook(&g_os_param);
End:
if (buf)
{
free(buf);
}
return rc;
}
static int ventoy_check_create_directory(void)
{
if (IsDirExist("ventoy"))
......@@ -2332,31 +2375,31 @@ static int ventoy_check_create_directory(void)
int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
{
int rc = 1;
int rc = 1;
int stat = 0;
int exlen = 0;
DWORD Pos;
DWORD PeStart;
DWORD Pos;
DWORD PeStart;
DWORD FileSize;
DWORD LockStatus = 0;
BYTE *Buffer = NULL;
CHAR ExeFileName[MAX_PATH];
BYTE *Buffer = NULL;
CHAR ExeFileName[MAX_PATH];
sprintf_s(ExeFileName, sizeof(ExeFileName), "%s", argv[0]);
if (!IsFileExist("%s", ExeFileName))
{
Log("File %s NOT exist, now try %s.exe", ExeFileName, ExeFileName);
sprintf_s(ExeFileName, sizeof(ExeFileName), "%s.exe", argv[0]);
sprintf_s(ExeFileName, sizeof(ExeFileName), "%s", argv[0]);
if (!IsFileExist("%s", ExeFileName))
{
Log("File %s NOT exist, now try %s.exe", ExeFileName, ExeFileName);
sprintf_s(ExeFileName, sizeof(ExeFileName), "%s.exe", argv[0]);
Log("File %s exist ? %s", ExeFileName, IsFileExist("%s", ExeFileName) ? "YES" : "NO");
}
Log("File %s exist ? %s", ExeFileName, IsFileExist("%s", ExeFileName) ? "YES" : "NO");
}
if (ReadWholeFile2Buf(ExeFileName, (void **)&Buffer, &FileSize))
{
goto End;
}
Log("VentoyJump %dbit", g_system_bit);
if (ReadWholeFile2Buf(ExeFileName, (void **)&Buffer, &FileSize))
{
goto End;
}
Log("VentoyJump %dbit", g_system_bit);
MUTEX_LOCK(g_vtoyins_mutex);
stat = ventoy_check_create_directory();
......@@ -2367,12 +2410,12 @@ int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
goto End;
}
for (PeStart = 0; PeStart < FileSize; PeStart += 16)
{
if (CheckOsParam((ventoy_os_param *)(Buffer + PeStart)) &&
for (PeStart = 0; PeStart < FileSize; PeStart += 16)
{
if (CheckOsParam((ventoy_os_param *)(Buffer + PeStart)) &&
CheckPeHead(Buffer, FileSize, PeStart + sizeof(ventoy_os_param)))
{
Log("Find os pararm at %u", PeStart);
{
Log("Find os pararm at %u", PeStart);
memcpy(&g_os_param, Buffer + PeStart, sizeof(ventoy_os_param));
memcpy(&g_windows_data, Buffer + PeStart + sizeof(ventoy_os_param), sizeof(ventoy_windows_data));
......@@ -2380,22 +2423,22 @@ int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved));
if (g_os_param_reserved[0] == 1)
{
Log("break here for debug .....");
goto End;
}
{
Log("break here for debug .....");
goto End;
}
// convert / to \\
// convert / to \\
for (Pos = 0; Pos < sizeof(g_os_param.vtoy_img_path) && g_os_param.vtoy_img_path[Pos]; Pos++)
{
{
if (g_os_param.vtoy_img_path[Pos] == '/')
{
{
g_os_param.vtoy_img_path[Pos] = '\\';
}
}
}
}
PeStart += sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exlen;
sprintf_s(LunchFile, MAX_PATH, "ventoy\\%s", GetFileNameInPath(ExeFileName));
PeStart += sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exlen;
sprintf_s(LunchFile, MAX_PATH, "ventoy\\%s", GetFileNameInPath(ExeFileName));
MUTEX_LOCK(g_vtoyins_mutex);
if (IsFileExist("%s", LunchFile))
......@@ -2406,18 +2449,18 @@ int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
goto End;
}
SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart);
SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart);
MUTEX_UNLOCK(g_vtoyins_mutex);
break;
}
}
break;
}
}
if (PeStart >= FileSize)
{
Log("OS param not found");
goto End;
}
if (PeStart >= FileSize)
{
Log("OS param not found");
goto End;
}
if (g_os_param_reserved[0] == 2)
{
......@@ -2430,128 +2473,112 @@ int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile)
End:
if (Buffer)
{
free(Buffer);
}
if (Buffer)
{
free(Buffer);
}
return rc;
return rc;
}
int real_main(int argc, char **argv)
{
int i = 0;
int rc = 0;
int wimboot = 0;
CHAR NewFile[MAX_PATH];
CHAR LunchFile[MAX_PATH];
CHAR CallParam[1024] = { 0 };
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
Log("#### real_main #### argc = %d", argc);
int i = 0;
int rc = 0;
CHAR NewFile[MAX_PATH];
CHAR LunchFile[MAX_PATH];
CHAR CallParam[1024] = { 0 };
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
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("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]);
}
}
GetStartupInfoA(&Si);
memset(LunchFile, 0, sizeof(LunchFile));
if (strstr(argv[0], "vtoyjump.exe"))
{
wimboot = 1;
DeleteFileA(WINPESHL_INI);
IsFileExist(WINPESHL_INI);
rc = VentoyJumpWimboot(argc, argv, LunchFile);
}
else
{
rc = VentoyJump(argc, argv, LunchFile);
}
Log("LunchFile=<%s> CallParam=<%s>", LunchFile, CallParam);
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);
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 if (wimboot && IsFileExist(WINPESHL_INI))
{
sprintf_s(LunchFile, MAX_PATH, "X:\\Windows\\system32\\winpeshl.exe");
Log("winpeshl.ini updated, now recall winpeshl.exe");
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]);
}
}
GetStartupInfoA(&Si);
memset(LunchFile, 0, sizeof(LunchFile));
rc = VentoyJump(argc, argv, LunchFile);
Log("LunchFile=<%s> CallParam=<%s>", LunchFile, CallParam);
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);
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
{
Log("We don't need to recover original <%s>", g_prog_name);
}
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;
}
Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed");
}
Log("Now launch <%s> ...", LunchFile);
if (g_os_param_reserved[0] == 4)
{
Log("Open cmd for debug ...");
sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");
}
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;
}
Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed");
}
Log("Now launch <%s> ...", LunchFile);
if (g_os_param_reserved[0] == 4)
{
Log("Open cmd for debug ...");
sprintf_s(LunchFile, sizeof(LunchFile), "%s", "cmd.exe");
}
Log("Backup log at this point");
CopyFileA(LOG_FILE, "X:\\Windows\\ventoy.backup", TRUE);
CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
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);
}
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("Wait process...");
WaitForSingleObject(Pi.hProcess, INFINITE);
Log("vtoyjump finished");
return 0;
Log("vtoyjump finished");
return 0;
}
static void VentoyToUpper(CHAR *str)
......@@ -2563,39 +2590,80 @@ static void VentoyToUpper(CHAR *str)
}
}
static int vtoy_remove_duplicate_file(char *File)
{
CHAR szCmd[MAX_PATH];
CHAR NewFile[MAX_PATH];
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
Log("<1> Copy New file", File);
sprintf_s(NewFile, sizeof(NewFile), "%s_NEW", File);
CopyFileA(File, NewFile, FALSE);
Log("<2> Remove file <%s>", File);
GetStartupInfoA(&Si);
Si.dwFlags |= STARTF_USESHOWWINDOW;
Si.wShowWindow = SW_HIDE;
sprintf_s(szCmd, sizeof(szCmd), "cmd.exe /c del /F /Q %s", File);
CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);
WaitForSingleObject(Pi.hProcess, INFINITE);
Log("<3> Copy back file <%s>", File);
MoveFileA(NewFile, File);
return 0;
}
int main(int argc, char **argv)
{
int i;
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
CHAR CurDir[MAX_PATH];
int i;
STARTUPINFOA Si;
PROCESS_INFORMATION Pi;
CHAR CurDir[MAX_PATH];
CHAR NewArgv0[MAX_PATH];
CHAR CallParam[1024] = { 0 };
CHAR CallParam[1024] = { 0 };
g_vtoylog_mutex = CreateMutexA(NULL, FALSE, "VTOYLOG_LOCK");
g_vtoyins_mutex = CreateMutexA(NULL, FALSE, "VTOYINS_LOCK");
g_vtoylog_mutex = CreateMutexA(NULL, FALSE, "VTOYLOG_LOCK");
g_vtoyins_mutex = CreateMutexA(NULL, FALSE, "VTOYINS_LOCK");
Log("######## VentoyJump %dbit ##########", g_system_bit);
Log("######## VentoyJump %dbit ##########", g_system_bit);
GetCurrentDirectoryA(sizeof(CurDir), CurDir);
Log("Current directory is <%s>", CurDir);
GetModuleFileNameA(NULL, g_prog_full_path, MAX_PATH);
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);
Log("EXE path: <%s> dir:<%s> name:<%s>", g_prog_full_path, g_prog_dir, g_prog_name);
if (IsFileExist(WIMBOOT_FILE))
{
Log("This is wimboot mode ...");
g_wimboot_mode = TRUE;
if (!IsFileExist(WIMBOOT_DONE))
{
vtoy_remove_duplicate_file(g_prog_full_path);
SaveBuffer2File(WIMBOOT_DONE, g_prog_full_path, 1);
}
}
else
{
Log("This is normal mode ...");
}
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]);
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)
{
return real_main(argc - 1, argv + 1);
}
else if (_stricmp(g_prog_name, "PECMD.exe") == 0)
{
strcpy_s(NewArgv0, sizeof(NewArgv0), g_prog_dir);
VentoyToUpper(NewArgv0);
......@@ -2613,32 +2681,31 @@ int main(int argc, char **argv)
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 ...");
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 ...");
ventoy_check_create_directory();
strcpy_s(NewArgv0, sizeof(NewArgv0), g_prog_full_path);
argv[0] = NewArgv0;
return real_main(argc, argv);
}
return real_main(argc, argv);
}
}
......@@ -164,6 +164,13 @@ typedef struct VarDiskInfo
CHAR SerialNumber[128];
}VarDiskInfo;
typedef struct IsoId
{
CHAR SystemId[64];
CHAR VolumeId[64];
CHAR PulisherId[256];
CHAR PreparerId[256];
}IsoId;
#define SAFE_CLOSE_HANDLE(handle) \
{\
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment