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

This commit is contained in:
longpanda 2022-09-16 01:05:58 +08:00
parent 7bf85a1ef8
commit e79dc57ebe
8 changed files with 1118 additions and 836 deletions

View File

@ -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");

View File

@ -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);
grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)param);
jump_align = ventoy_align(wim_data.jump_exe_len, 16);
param = wim_data.jump_bin_data;
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);
}

View File

@ -599,32 +599,33 @@ 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
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
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 "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
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
@ -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 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 [ $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
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
fi
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 [ "$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
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

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -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) \
{\