mirror of
				https://github.com/ventoy/Ventoy.git
				synced 2025-10-30 00:05:09 -04:00 
			
		
		
		
	wimboot mode support Bob.Ombs.Modified.Win10PEx64 (#1842)
This commit is contained in:
		
							parent
							
								
									7bf85a1ef8
								
							
						
					
					
						commit
						e79dc57ebe
					
				| @ -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); | ||||
| 
 | ||||
|     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); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -599,6 +599,11 @@ function ventoy_unix_comm_proc { | ||||
| function uefi_windows_menu_func { | ||||
|     vt_windows_reset | ||||
| 
 | ||||
|     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 | ||||
| @ -619,12 +624,8 @@ function uefi_windows_menu_func { | ||||
|             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 | ||||
|     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,9 +1013,93 @@ 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 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 | ||||
| @ -1051,9 +1125,6 @@ function legacy_windows_menu_func { | ||||
|          | ||||
|         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 | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -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,13 +48,14 @@ 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) | ||||
| @ -92,6 +95,38 @@ 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, ...) | ||||
| { | ||||
| @ -992,8 +1027,99 @@ End: | ||||
|     return rc; | ||||
| } | ||||
| 
 | ||||
| static int GetIsoId(CONST CHAR *IsoPath, IsoId *ids) | ||||
| { | ||||
|     int i; | ||||
|     int n = 0; | ||||
|     HANDLE hFile; | ||||
|     DWORD dwSize = 0; | ||||
|     BOOL bRet[8]; | ||||
| 
 | ||||
|     hFile = CreateFileA(IsoPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); | ||||
|     if (hFile == INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     SetFilePointer(hFile, 2048 * 16 + 318, NULL, FILE_BEGIN); | ||||
|     bRet[n++] = ReadFile(hFile, ids->PulisherId, 128, &dwSize, NULL); | ||||
| 
 | ||||
|     SetFilePointer(hFile, 2048 * 16 + 446, NULL, FILE_BEGIN); | ||||
|     bRet[n++] = ReadFile(hFile, ids->PreparerId, 128, &dwSize, NULL); | ||||
| 
 | ||||
|     CloseHandle(hFile); | ||||
| 
 | ||||
| 
 | ||||
|     for (i = 0; i < n; i++) | ||||
|     { | ||||
|         if (bRet[i] == FALSE) | ||||
|         { | ||||
|             return 1; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
| static int CheckSkipMountIso(CONST CHAR *IsoPath) | ||||
| { | ||||
|     BOOL InRoot = FALSE; | ||||
|     int slashcnt = 0; | ||||
|     CONST CHAR *p = NULL; | ||||
|     IsoId ID; | ||||
| 
 | ||||
|     // C:\\xxx
 | ||||
|     for (p = IsoPath; *p; p++) | ||||
|     { | ||||
|         if (*p == '\\' || *p == '/') | ||||
|         { | ||||
|             slashcnt++; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (slashcnt == 2) | ||||
|     { | ||||
|         InRoot = TRUE; | ||||
|     } | ||||
| 
 | ||||
|     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 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..."); | ||||
| @ -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); | ||||
| @ -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")) | ||||
| @ -2443,7 +2486,6 @@ 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 }; | ||||
| @ -2453,7 +2495,7 @@ int real_main(int argc, char **argv) | ||||
|     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++) | ||||
| @ -2469,17 +2511,7 @@ int real_main(int argc, char **argv) | ||||
|     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); | ||||
| 
 | ||||
| @ -2496,11 +2528,6 @@ int real_main(int argc, char **argv) | ||||
|         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"); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Log("We don't need to recover original <%s>", g_prog_name); | ||||
| @ -2563,6 +2590,31 @@ 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; | ||||
| @ -2585,6 +2637,22 @@ int main(int argc, char **argv) | ||||
| 
 | ||||
|     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 ..."); | ||||
| @ -2641,4 +2709,3 @@ int main(int argc, char **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) \ | ||||
| {\ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user