mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[iso] add EFI boot support from 'efi.img' FAT images
* Required to support Debian Live 9.1 in ISO mode * Note that this only works if the efi.img boot files do not require additional content besides the one extracted from the ISO.
This commit is contained in:
		
							parent
							
								
									3d33493c6f
								
							
						
					
					
						commit
						5d371088cb
					
				
					 6 changed files with 263 additions and 60 deletions
				
			
		|  | @ -2042,7 +2042,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 					efi_dst[0] = drive_name[0]; | 					efi_dst[0] = drive_name[0]; | ||||||
| 					efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0; | 					efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0; | ||||||
| 					if (!CreateDirectoryA(efi_dst, 0)) { | 					if (!CreateDirectoryA(efi_dst, 0)) { | ||||||
| 						uprintf("Could not create directory '%s': %s\n", WindowsErrorString()); | 						uprintf("Could not create directory '%s': %s\n", efi_dst, WindowsErrorString()); | ||||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | ||||||
| 					} else { | 					} else { | ||||||
| 						efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\'; | 						efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\'; | ||||||
|  |  | ||||||
							
								
								
									
										224
									
								
								src/iso.c
									
										
									
									
									
								
							
							
						
						
									
										224
									
								
								src/iso.c
									
										
									
									
									
								
							|  | @ -39,6 +39,7 @@ | ||||||
| #include <cdio/udf.h> | #include <cdio/udf.h> | ||||||
| 
 | 
 | ||||||
| #include "rufus.h" | #include "rufus.h" | ||||||
|  | #include "libfat.h" | ||||||
| #include "missing.h" | #include "missing.h" | ||||||
| #include "resource.h" | #include "resource.h" | ||||||
| #include "msapi_utf8.h" | #include "msapi_utf8.h" | ||||||
|  | @ -73,6 +74,7 @@ static const char* grldr_name = "grldr"; | ||||||
| static const char* ldlinux_name = "ldlinux.sys"; | static const char* ldlinux_name = "ldlinux.sys"; | ||||||
| static const char* ldlinux_c32 = "ldlinux.c32"; | static const char* ldlinux_c32 = "ldlinux.c32"; | ||||||
| static const char* efi_dirname = "/efi/boot"; | static const char* efi_dirname = "/efi/boot"; | ||||||
|  | static const char* efi_img_name = "efi.img";	// Used by Debian Live ISOHybrids
 | ||||||
| static const char* efi_bootname[] = { "bootia32.efi", "bootia64.efi", "bootx64.efi", "bootarm.efi", "bootaa64.efi", "bootebc.efi" }; | static const char* efi_bootname[] = { "bootia32.efi", "bootia64.efi", "bootx64.efi", "bootarm.efi", "bootaa64.efi", "bootebc.efi" }; | ||||||
| static const char* install_wim_path = "/sources"; | static const char* install_wim_path = "/sources"; | ||||||
| static const char* install_wim_name[] = { "install.wim", "install.swm" }; | static const char* install_wim_name[] = { "install.wim", "install.swm" }; | ||||||
|  | @ -202,6 +204,10 @@ static BOOL check_iso_props(const char* psz_dirname, int64_t i_file_length, cons | ||||||
| 		if ((img_report.reactos_path[0] == 0) && (safe_stricmp(psz_basename, reactos_name) == 0)) | 		if ((img_report.reactos_path[0] == 0) && (safe_stricmp(psz_basename, reactos_name) == 0)) | ||||||
| 			safe_strcpy(img_report.reactos_path, sizeof(img_report.reactos_path), psz_fullpath); | 			safe_strcpy(img_report.reactos_path, sizeof(img_report.reactos_path), psz_fullpath); | ||||||
| 
 | 
 | ||||||
|  | 		// Check for the first 'efi.img' we can find (that hopefully contains EFI boot files)
 | ||||||
|  | 		if (!HAS_EFI_IMG(img_report) && (safe_stricmp(psz_basename, efi_img_name) == 0)) | ||||||
|  | 			safe_strcpy(img_report.efi_img_path, sizeof(img_report.efi_img_path), psz_fullpath); | ||||||
|  | 
 | ||||||
| 		// Check for the EFI boot entries
 | 		// Check for the EFI boot entries
 | ||||||
| 		if (safe_stricmp(psz_dirname, efi_dirname) == 0) { | 		if (safe_stricmp(psz_dirname, efi_dirname) == 0) { | ||||||
| 			for (i=0; i<ARRAYSIZE(efi_bootname); i++) | 			for (i=0; i<ARRAYSIZE(efi_bootname); i++) | ||||||
|  | @ -841,6 +847,9 @@ out: | ||||||
| 				uprintf("  Warning: Could not detect Isolinux version - Forcing to %s (embedded)", | 				uprintf("  Warning: Could not detect Isolinux version - Forcing to %s (embedded)", | ||||||
| 					img_report.sl_version_str); | 					img_report.sl_version_str); | ||||||
| 			} | 			} | ||||||
|  | 			if (!IS_EFI_BOOTABLE(img_report) && HAS_EFI_IMG(img_report) && ExtractEfiImgFiles(NULL)) { | ||||||
|  | 				img_report.has_efi = 0x80; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		if (HAS_WINPE(img_report)) { | 		if (HAS_WINPE(img_report)) { | ||||||
| 			// In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif
 | 			// In case we have a WinPE 1.x based iso, we extract and parse txtsetup.sif
 | ||||||
|  | @ -889,7 +898,11 @@ out: | ||||||
| 		StrArrayDestroy(&config_path); | 		StrArrayDestroy(&config_path); | ||||||
| 		StrArrayDestroy(&isolinux_path); | 		StrArrayDestroy(&isolinux_path); | ||||||
| 		SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0); | 		SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0); | ||||||
| 	} else if (HAS_SYSLINUX(img_report)) { | 	} else { | ||||||
|  | 		// For Debian live ISOs, that only provide EFI boot files in a FAT efi.img
 | ||||||
|  | 		if (img_report.has_efi == 0x80) | ||||||
|  | 			ExtractEfiImgFiles(dest_dir); | ||||||
|  | 		if (HAS_SYSLINUX(img_report)) { | ||||||
| 			safe_sprintf(path, sizeof(path), "%s\\syslinux.cfg", dest_dir); | 			safe_sprintf(path, sizeof(path), "%s\\syslinux.cfg", dest_dir); | ||||||
| 			// Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg
 | 			// Create a /syslinux.cfg (if none exists) that points to the existing isolinux cfg
 | ||||||
| 			fd = fopen(path, "r"); | 			fd = fopen(path, "r"); | ||||||
|  | @ -919,6 +932,7 @@ out: | ||||||
| 			if (fd != NULL) | 			if (fd != NULL) | ||||||
| 				fclose(fd); | 				fclose(fd); | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 	if (p_iso != NULL) | 	if (p_iso != NULL) | ||||||
| 		iso9660_close(p_iso); | 		iso9660_close(p_iso); | ||||||
| 	if (p_udf != NULL) | 	if (p_udf != NULL) | ||||||
|  | @ -945,7 +959,7 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f | ||||||
| 	file_handle = CreateFileU(dest_file, GENERIC_READ | GENERIC_WRITE, | 	file_handle = CreateFileU(dest_file, GENERIC_READ | GENERIC_WRITE, | ||||||
| 		FILE_SHARE_READ, NULL, CREATE_ALWAYS, attributes, NULL); | 		FILE_SHARE_READ, NULL, CREATE_ALWAYS, attributes, NULL); | ||||||
| 	if (file_handle == INVALID_HANDLE_VALUE) { | 	if (file_handle == INVALID_HANDLE_VALUE) { | ||||||
| 		uprintf("  Unable to create file %s: %s\n", dest_file, WindowsErrorString()); | 		uprintf("  Could not create file %s: %s", dest_file, WindowsErrorString()); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -956,12 +970,12 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f | ||||||
| 
 | 
 | ||||||
| 	p_udf_root = udf_get_root(p_udf, true, 0); | 	p_udf_root = udf_get_root(p_udf, true, 0); | ||||||
| 	if (p_udf_root == NULL) { | 	if (p_udf_root == NULL) { | ||||||
| 		uprintf("Could not locate UDF root directory\n"); | 		uprintf("Could not locate UDF root directory"); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	p_udf_file = udf_fopen(p_udf_root, iso_file); | 	p_udf_file = udf_fopen(p_udf_root, iso_file); | ||||||
| 	if (!p_udf_file) { | 	if (!p_udf_file) { | ||||||
| 		uprintf("Could not locate file %s in ISO image\n", iso_file); | 		uprintf("Could not locate file %s in ISO image", iso_file); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	file_length = udf_get_file_length(p_udf_file); | 	file_length = udf_get_file_length(p_udf_file); | ||||||
|  | @ -969,12 +983,12 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f | ||||||
| 		memset(buf, 0, UDF_BLOCKSIZE); | 		memset(buf, 0, UDF_BLOCKSIZE); | ||||||
| 		read_size = udf_read_block(p_udf_file, buf, 1); | 		read_size = udf_read_block(p_udf_file, buf, 1); | ||||||
| 		if (read_size < 0) { | 		if (read_size < 0) { | ||||||
| 			uprintf("Error reading UDF file %s\n", iso_file); | 			uprintf("Error reading UDF file %s", iso_file); | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 		buf_size = (DWORD)MIN(file_length, read_size); | 		buf_size = (DWORD)MIN(file_length, read_size); | ||||||
| 		if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) { | 		if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) { | ||||||
| 			uprintf("  Error writing file %s: %s\n", dest_file, WindowsErrorString()); | 			uprintf("  Error writing file %s: %s", dest_file, WindowsErrorString()); | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 		file_length -= read_size; | 		file_length -= read_size; | ||||||
|  | @ -985,13 +999,13 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f | ||||||
| try_iso: | try_iso: | ||||||
| 	p_iso = iso9660_open(iso); | 	p_iso = iso9660_open(iso); | ||||||
| 	if (p_iso == NULL) { | 	if (p_iso == NULL) { | ||||||
| 		uprintf("Unable to open image '%s'.\n", iso); | 		uprintf("Unable to open image '%s'", iso); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	p_statbuf = iso9660_ifs_stat_translate(p_iso, iso_file); | 	p_statbuf = iso9660_ifs_stat_translate(p_iso, iso_file); | ||||||
| 	if (p_statbuf == NULL) { | 	if (p_statbuf == NULL) { | ||||||
| 		uprintf("Could not get ISO-9660 file information for file %s\n", iso_file); | 		uprintf("Could not get ISO-9660 file information for file %s", iso_file); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -1000,12 +1014,12 @@ try_iso: | ||||||
| 		memset(buf, 0, ISO_BLOCKSIZE); | 		memset(buf, 0, ISO_BLOCKSIZE); | ||||||
| 		lsn = p_statbuf->lsn + (lsn_t)i; | 		lsn = p_statbuf->lsn + (lsn_t)i; | ||||||
| 		if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { | 		if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { | ||||||
| 			uprintf("  Error reading ISO9660 file %s at LSN %lu\n", iso_file, (long unsigned int)lsn); | 			uprintf("  Error reading ISO9660 file %s at LSN %lu", iso_file, (long unsigned int)lsn); | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 		buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE); | 		buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE); | ||||||
| 		if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) { | 		if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) { | ||||||
| 			uprintf("  Error writing file %s: %s\n", dest_file, WindowsErrorString()); | 			uprintf("  Error writing file %s: %s", dest_file, WindowsErrorString()); | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 		file_length -= ISO_BLOCKSIZE; | 		file_length -= ISO_BLOCKSIZE; | ||||||
|  | @ -1052,16 +1066,16 @@ uint32_t GetInstallWimVersion(const char* iso) | ||||||
| 
 | 
 | ||||||
| 	p_udf_root = udf_get_root(p_udf, true, 0); | 	p_udf_root = udf_get_root(p_udf, true, 0); | ||||||
| 	if (p_udf_root == NULL) { | 	if (p_udf_root == NULL) { | ||||||
| 		uprintf("Could not locate UDF root directory\n"); | 		uprintf("Could not locate UDF root directory"); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	p_udf_file = udf_fopen(p_udf_root, wim_path); | 	p_udf_file = udf_fopen(p_udf_root, wim_path); | ||||||
| 	if (!p_udf_file) { | 	if (!p_udf_file) { | ||||||
| 		uprintf("Could not locate file %s in ISO image\n", wim_path); | 		uprintf("Could not locate file %s in ISO image", wim_path); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	if (udf_read_block(p_udf_file, buf, 1) != UDF_BLOCKSIZE) { | 	if (udf_read_block(p_udf_file, buf, 1) != UDF_BLOCKSIZE) { | ||||||
| 		uprintf("Error reading UDF file %s\n", wim_path); | 		uprintf("Error reading UDF file %s", wim_path); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	r = wim_header[3]; | 	r = wim_header[3]; | ||||||
|  | @ -1070,16 +1084,16 @@ uint32_t GetInstallWimVersion(const char* iso) | ||||||
| try_iso: | try_iso: | ||||||
| 	p_iso = iso9660_open(iso); | 	p_iso = iso9660_open(iso); | ||||||
| 	if (p_iso == NULL) { | 	if (p_iso == NULL) { | ||||||
| 		uprintf("Unable to open image '%s'.\n", iso); | 		uprintf("Could not open image '%s'", iso); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	p_statbuf = iso9660_ifs_stat_translate(p_iso, wim_path); | 	p_statbuf = iso9660_ifs_stat_translate(p_iso, wim_path); | ||||||
| 	if (p_statbuf == NULL) { | 	if (p_statbuf == NULL) { | ||||||
| 		uprintf("Could not get ISO-9660 file information for file %s\n", wim_path); | 		uprintf("Could not get ISO-9660 file information for file %s", wim_path); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn, 1) != ISO_BLOCKSIZE) { | 	if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn, 1) != ISO_BLOCKSIZE) { | ||||||
| 		uprintf("Error reading ISO9660 file %s at LSN %lu\n", wim_path, (long unsigned int)p_statbuf->lsn); | 		uprintf("Error reading ISO-9660 file %s at LSN %lu", wim_path, (long unsigned int)p_statbuf->lsn); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	r = wim_header[3]; | 	r = wim_header[3]; | ||||||
|  | @ -1100,6 +1114,184 @@ out: | ||||||
| 	return bswap_uint32(r); | 	return bswap_uint32(r); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #define ISO_NB_BLOCKS 16 | ||||||
|  | typedef struct { | ||||||
|  | 	iso9660_t*      p_iso; | ||||||
|  | 	lsn_t           lsn; | ||||||
|  | 	libfat_sector_t sec_start; | ||||||
|  | 	// Use a multi block buffer, to improve sector reads
 | ||||||
|  | 	uint8_t         buf[ISO_BLOCKSIZE * ISO_NB_BLOCKS]; | ||||||
|  | } iso9660_readfat_private; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Read sectors from a FAT img file residing on an ISO-9660 filesystem. | ||||||
|  |  * NB: This assumes that the img file sectors are contiguous on the ISO. | ||||||
|  |   */ | ||||||
|  | int iso9660_readfat(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sec) | ||||||
|  | { | ||||||
|  | 	iso9660_readfat_private* p_private = (iso9660_readfat_private*)pp; | ||||||
|  | 
 | ||||||
|  | 	if (sizeof(p_private->buf) % secsize != 0) { | ||||||
|  | 		uprintf("iso9660_readfat: Sector size %d is not a divisor of %d", secsize, sizeof(p_private->buf)); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if ((sec < p_private->sec_start) || (sec >= p_private->sec_start + sizeof(p_private->buf) / secsize)) { | ||||||
|  | 		// Sector being queried is not in our multi block buffer -> Update it
 | ||||||
|  | 		p_private->sec_start = (((sec * secsize) / ISO_BLOCKSIZE) * ISO_BLOCKSIZE) / secsize; | ||||||
|  | 		if (iso9660_iso_seek_read(p_private->p_iso, p_private->buf, | ||||||
|  | 			p_private->lsn + (lsn_t)((p_private->sec_start * secsize) / ISO_BLOCKSIZE), ISO_NB_BLOCKS) | ||||||
|  | 			!= ISO_NB_BLOCKS * ISO_BLOCKSIZE) { | ||||||
|  | 			uprintf("Error reading ISO-9660 file %s at LSN %lu\n", img_report.efi_img_path, | ||||||
|  | 				(long unsigned int)(p_private->lsn + (p_private->sec_start * secsize) / ISO_BLOCKSIZE)); | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	memcpy(buf, &p_private->buf[(sec - p_private->sec_start)*secsize], secsize); | ||||||
|  | 	return (int)secsize; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Extract EFI bootloaders files from an ISO-9660 FAT img file into directory <dir>. | ||||||
|  |  * If <dir> is NULL, returns TRUE if an EFI bootloader exists in the img. | ||||||
|  |  * If <dir> is not NULL, returns TRUE if any if the bootloaders was properly written. | ||||||
|  |  */ | ||||||
|  | BOOL ExtractEfiImgFiles(const char* dir) | ||||||
|  | { | ||||||
|  | 	BOOL ret = FALSE; | ||||||
|  | 	HANDLE handle; | ||||||
|  | 	DWORD size, file_size, written; | ||||||
|  | 	iso9660_t* p_iso = NULL; | ||||||
|  | 	iso9660_stat_t* p_statbuf = NULL; | ||||||
|  | 	iso9660_readfat_private* p_private = NULL; | ||||||
|  | 	libfat_sector_t s; | ||||||
|  | 	int32_t dc, c; | ||||||
|  | 	struct libfat_filesystem *fs; | ||||||
|  | 	struct libfat_direntry direntry; | ||||||
|  | 	char name[12] = { 0 }; | ||||||
|  | 	char path[64]; | ||||||
|  | 	int i, j, k; | ||||||
|  | 	void* buf; | ||||||
|  | 
 | ||||||
|  | 	if ((image_path == NULL) || !HAS_EFI_IMG(img_report)) | ||||||
|  | 		return FALSE; | ||||||
|  | 
 | ||||||
|  | 	p_iso = iso9660_open(image_path); | ||||||
|  | 	if (p_iso == NULL) { | ||||||
|  | 		uprintf("Could not open image '%s' as an ISO-9660 file system", image_path); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 	p_statbuf = iso9660_ifs_stat_translate(p_iso, img_report.efi_img_path); | ||||||
|  | 	if (p_statbuf == NULL) { | ||||||
|  | 		uprintf("Could not get ISO-9660 file information for file %s\n", img_report.efi_img_path); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 	p_private = malloc(sizeof(iso9660_readfat_private)); | ||||||
|  | 	if (p_private == NULL) | ||||||
|  | 		goto out; | ||||||
|  | 	p_private->p_iso = p_iso; | ||||||
|  | 	p_private->lsn = p_statbuf->lsn; | ||||||
|  | 	p_private->sec_start = 0; | ||||||
|  | 	// Populate our intial buffer
 | ||||||
|  | 	if (iso9660_iso_seek_read(p_private->p_iso, p_private->buf, p_private->lsn, ISO_NB_BLOCKS) != ISO_NB_BLOCKS * ISO_BLOCKSIZE) { | ||||||
|  | 		uprintf("Error reading ISO-9660 file %s at LSN %lu\n", img_report.efi_img_path, (long unsigned int)p_private->lsn); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 	fs = libfat_open(iso9660_readfat, (intptr_t)p_private); | ||||||
|  | 	if (fs == NULL) { | ||||||
|  | 		uprintf("FAT access error"); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Navigate to /EFI/BOOT
 | ||||||
|  | 	if (libfat_searchdir(fs, 0, "EFI        ", &direntry) < 0) | ||||||
|  | 		goto out; | ||||||
|  | 	dc = direntry.entry[26] + (direntry.entry[27] << 8); | ||||||
|  | 	if (libfat_searchdir(fs, dc, "BOOT       ", &direntry) < 0) | ||||||
|  | 		goto out; | ||||||
|  | 	dc = direntry.entry[26] + (direntry.entry[27] << 8); | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < ARRAYSIZE(efi_bootname); i++) { | ||||||
|  | 		// Sanity check in case the EFI forum comes up with a 'bootmips64.efi' or something...
 | ||||||
|  | 		if (strlen(efi_bootname[i]) > 12) { | ||||||
|  | 			uprintf("Internal error: FAT 8.3"); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 		for (j = 0, k = 0; efi_bootname[i][j] != 0; j++) { | ||||||
|  | 			if (efi_bootname[i][j] == '.') { | ||||||
|  | 				while (k < 8) | ||||||
|  | 					name[k++] = ' '; | ||||||
|  | 			} else | ||||||
|  | 				name[k++] = toupper(efi_bootname[i][j]); | ||||||
|  | 		} | ||||||
|  | 		c = libfat_searchdir(fs, dc, name, &direntry); | ||||||
|  | 		if (c > 0) { | ||||||
|  | 			if (dir == NULL) { | ||||||
|  | 				if (!ret) | ||||||
|  | 					uprintf("  Detected EFI bootloader(s) (from '%s'):", img_report.efi_img_path); | ||||||
|  | 				uprintf("  ● '%s'", efi_bootname[i]); | ||||||
|  | 				ret = TRUE; | ||||||
|  | 			} else { | ||||||
|  | 				file_size = direntry.entry[28] + (direntry.entry[29] << 8) + (direntry.entry[30] << 16) + | ||||||
|  | 					(direntry.entry[31] << 24); | ||||||
|  | 				// Sanity check
 | ||||||
|  | 				if (file_size > 64 * MB) { | ||||||
|  | 					uprintf("Warning: File size is larger than 64 MB => not extracted"); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				static_sprintf(path, "%s\\efi", dir); | ||||||
|  | 				if (!CreateDirectoryA(path, 0) && (GetLastError() != ERROR_ALREADY_EXISTS)) { | ||||||
|  | 					uprintf("Could not create directory '%s': %s\n", path, WindowsErrorString()); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				safe_strcat(path, sizeof(path), "\\boot"); | ||||||
|  | 				if (!CreateDirectoryA(path, 0) && (GetLastError() != ERROR_ALREADY_EXISTS)) { | ||||||
|  | 					uprintf("Could not create directory '%s': %s\n", path, WindowsErrorString()); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				safe_strcat(path, sizeof(path), "\\"); | ||||||
|  | 				safe_strcat(path, sizeof(path), efi_bootname[i]); | ||||||
|  | 				uprintf("Extracting: %s (from '%s', %s)", path, img_report.efi_img_path, | ||||||
|  | 					SizeToHumanReadable(file_size, FALSE, FALSE)); | ||||||
|  | 				handle = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, | ||||||
|  | 					NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | ||||||
|  | 				if (handle == INVALID_HANDLE_VALUE) { | ||||||
|  | 					uprintf("Unable to create '%s': %s", path, WindowsErrorString()); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				written = 0; | ||||||
|  | 				s = libfat_clustertosector(fs, c); | ||||||
|  | 				while ((s != 0) && (s < 0xFFFFFFFFULL) && (written < file_size)) { | ||||||
|  | 					buf = libfat_get_sector(fs, s); | ||||||
|  | 					size = MIN(LIBFAT_SECTOR_SIZE, file_size - written); | ||||||
|  | 					if (!WriteFileWithRetry(handle, buf, size, &size, WRITE_RETRIES) || | ||||||
|  | 						(size != MIN(LIBFAT_SECTOR_SIZE, file_size - written))) { | ||||||
|  | 						uprintf("Error writing '%s': %s", path, WindowsErrorString()); | ||||||
|  | 						CloseHandle(handle); | ||||||
|  | 						continue; | ||||||
|  | 					} | ||||||
|  | 					written += size; | ||||||
|  | 					s = libfat_nextsector(fs, s); | ||||||
|  | 				} | ||||||
|  | 				CloseHandle(handle); | ||||||
|  | 				ret = TRUE; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	if (fs != NULL) | ||||||
|  | 		libfat_close(fs); | ||||||
|  | 	if (p_statbuf != NULL) | ||||||
|  | 		safe_free(p_statbuf->rr.psz_symlink); | ||||||
|  | 	safe_free(p_statbuf); | ||||||
|  | 	safe_free(p_private); | ||||||
|  | 	if (p_iso != NULL) | ||||||
|  | 		iso9660_close(p_iso); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // VirtDisk API Prototypes - Only available for Windows 8 or later
 | // VirtDisk API Prototypes - Only available for Windows 8 or later
 | ||||||
| PF_TYPE_DECL(WINAPI, DWORD, OpenVirtualDisk, (PVIRTUAL_STORAGE_TYPE, PCWSTR, | PF_TYPE_DECL(WINAPI, DWORD, OpenVirtualDisk, (PVIRTUAL_STORAGE_TYPE, PCWSTR, | ||||||
| 	VIRTUAL_DISK_ACCESS_MASK, OPEN_VIRTUAL_DISK_FLAG, POPEN_VIRTUAL_DISK_PARAMETERS, PHANDLE)); | 	VIRTUAL_DISK_ACCESS_MASK, OPEN_VIRTUAL_DISK_FLAG, POPEN_VIRTUAL_DISK_PARAMETERS, PHANDLE)); | ||||||
|  |  | ||||||
|  | @ -293,6 +293,18 @@ static __inline int LoadStringU(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, i | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static __inline HMODULE LoadLibraryU(LPCSTR lpFileName) | ||||||
|  | { | ||||||
|  | 	HMODULE ret; | ||||||
|  | 	DWORD err = ERROR_INVALID_DATA; | ||||||
|  | 	wconvert(lpFileName); | ||||||
|  | 	ret = LoadLibraryW(wlpFileName); | ||||||
|  | 	err = GetLastError(); | ||||||
|  | 	wfree(lpFileName); | ||||||
|  | 	SetLastError(err); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static __inline int DrawTextU(HDC hDC, LPCSTR lpText, int nCount, LPRECT lpRect, UINT uFormat) | static __inline int DrawTextU(HDC hDC, LPCSTR lpText, int nCount, LPRECT lpRect, UINT uFormat) | ||||||
| { | { | ||||||
| 	int ret; | 	int ret; | ||||||
|  | @ -1027,15 +1039,6 @@ static __inline BOOL GetVolumeInformationU(LPCSTR lpRootPathName, LPSTR lpVolume | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static __inline HMODULE LoadLibraryU(LPCSTR lpFileName) |  | ||||||
| { |  | ||||||
| 	HMODULE h; |  | ||||||
| 	wconvert(lpFileName); |  | ||||||
| 	h = LoadLibraryW(wlpFileName); |  | ||||||
| 	wfree(lpFileName); |  | ||||||
| 	return h; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -992,6 +992,9 @@ static void DisplayISOProps(void) | ||||||
| 	PRINT_ISO_PROP(HAS_REACTOS(img_report), "  Uses: ReactOS"); | 	PRINT_ISO_PROP(HAS_REACTOS(img_report), "  Uses: ReactOS"); | ||||||
| 	PRINT_ISO_PROP(img_report.has_grub4dos, "  Uses: Grub4DOS"); | 	PRINT_ISO_PROP(img_report.has_grub4dos, "  Uses: Grub4DOS"); | ||||||
| 	PRINT_ISO_PROP(img_report.has_grub2, "  Uses: GRUB2"); | 	PRINT_ISO_PROP(img_report.has_grub2, "  Uses: GRUB2"); | ||||||
|  | 	if (img_report.has_efi == 0x80) | ||||||
|  | 		uprintf("  Uses: EFI (through '%s')", img_report.efi_img_path); | ||||||
|  | 	else | ||||||
| 		PRINT_ISO_PROP(img_report.has_efi, "  Uses: EFI %s", HAS_WIN7_EFI(img_report) ? "(win7_x64)" : ""); | 		PRINT_ISO_PROP(img_report.has_efi, "  Uses: EFI %s", HAS_WIN7_EFI(img_report) ? "(win7_x64)" : ""); | ||||||
| 	PRINT_ISO_PROP(HAS_BOOTMGR(img_report), "  Uses: Bootmgr"); | 	PRINT_ISO_PROP(HAS_BOOTMGR(img_report), "  Uses: Bootmgr"); | ||||||
| 	PRINT_ISO_PROP(HAS_WINPE(img_report), "  Uses: WinPE %s", (img_report.uses_minint) ? "(with /minint)" : ""); | 	PRINT_ISO_PROP(HAS_WINPE(img_report), "  Uses: WinPE %s", (img_report.uses_minint) ? "(with /minint)" : ""); | ||||||
|  | @ -2259,7 +2262,9 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 	case WM_COMMAND: | 	case WM_COMMAND: | ||||||
| #ifdef RUFUS_TEST | #ifdef RUFUS_TEST | ||||||
| 		if (LOWORD(wParam) == IDC_TEST) { | 		if (LOWORD(wParam) == IDC_TEST) { | ||||||
| 			uprintf("Proceed = %s", CheckDriveAccess(2000)?"True":"False"); | 			ExtractEfiImgFiles("C:\\rufus"); | ||||||
|  | //			ExtractEFI("C:\\rufus\\efi.img", "C:\\rufus\\efi");
 | ||||||
|  | //			uprintf("Proceed = %s", CheckDriveAccess(2000)?"True":"False");
 | ||||||
| //			char* choices[] = { "Choice 1", "Choice 2", "Choice 3" };
 | //			char* choices[] = { "Choice 1", "Choice 2", "Choice 3" };
 | ||||||
| //			SelectionDyn("Test Choice", "Unused", choices, ARRAYSIZE(choices));
 | //			SelectionDyn("Test Choice", "Unused", choices, ARRAYSIZE(choices));
 | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
|  | @ -261,8 +261,9 @@ enum checksum_type { | ||||||
| #define HAS_WINPE(r)        (((r.winpe & WINPE_MININT) == WINPE_MININT)||((r.winpe & WINPE_I386) == WINPE_I386)) | #define HAS_WINPE(r)        (((r.winpe & WINPE_MININT) == WINPE_MININT)||((r.winpe & WINPE_I386) == WINPE_I386)) | ||||||
| #define HAS_WINDOWS(r)      (HAS_BOOTMGR(r) || (r.uses_minint) || HAS_WINPE(r)) | #define HAS_WINDOWS(r)      (HAS_BOOTMGR(r) || (r.uses_minint) || HAS_WINPE(r)) | ||||||
| #define HAS_WIN7_EFI(r)     ((r.has_efi == 1) && HAS_INSTALL_WIM(r)) | #define HAS_WIN7_EFI(r)     ((r.has_efi == 1) && HAS_INSTALL_WIM(r)) | ||||||
|  | #define HAS_EFI_IMG(r)      (r.efi_img_path[0] != 0) | ||||||
| #define IS_DD_BOOTABLE(r)   (r.is_bootable_img) | #define IS_DD_BOOTABLE(r)   (r.is_bootable_img) | ||||||
| #define IS_EFI_BOOTABLE(r)  (r.has_efi) | #define IS_EFI_BOOTABLE(r)  (r.has_efi != 0) | ||||||
| #define IS_BIOS_BOOTABLE(r) (HAS_BOOTMGR(r) || HAS_SYSLINUX(r) || HAS_WINPE(r) || HAS_GRUB(r) || HAS_REACTOS(r) || HAS_KOLIBRIOS(r)) | #define IS_BIOS_BOOTABLE(r) (HAS_BOOTMGR(r) || HAS_SYSLINUX(r) || HAS_WINPE(r) || HAS_GRUB(r) || HAS_REACTOS(r) || HAS_KOLIBRIOS(r)) | ||||||
| #define HAS_WINTOGO(r)      (HAS_BOOTMGR(r) && IS_EFI_BOOTABLE(r) && HAS_INSTALL_WIM(r) && (r.install_wim_version < MAX_WIM_VERSION)) | #define HAS_WINTOGO(r)      (HAS_BOOTMGR(r) && IS_EFI_BOOTABLE(r) && HAS_INSTALL_WIM(r) && (r.install_wim_version < MAX_WIM_VERSION)) | ||||||
| #define IS_FAT(fs)          ((fs == FS_FAT16) || (fs == FS_FAT32)) | #define IS_FAT(fs)          ((fs == FS_FAT16) || (fs == FS_FAT32)) | ||||||
|  | @ -273,6 +274,7 @@ typedef struct { | ||||||
| 	char cfg_path[128];			/* path to the ISO's isolinux.cfg */ | 	char cfg_path[128];			/* path to the ISO's isolinux.cfg */ | ||||||
| 	char reactos_path[128];		/* path to the ISO's freeldr.sys or setupldr.sys */ | 	char reactos_path[128];		/* path to the ISO's freeldr.sys or setupldr.sys */ | ||||||
| 	char install_wim_path[64];	/* path to install.wim or install.swm */ | 	char install_wim_path[64];	/* path to install.wim or install.swm */ | ||||||
|  | 	char efi_img_path[128];		/* path to an efi.img file */ | ||||||
| 	uint64_t image_size; | 	uint64_t image_size; | ||||||
| 	uint64_t projected_size; | 	uint64_t projected_size; | ||||||
| 	int64_t mismatch_size; | 	int64_t mismatch_size; | ||||||
|  | @ -440,6 +442,7 @@ extern SIZE GetTextSize(HWND hCtrl); | ||||||
| extern BOOL ExtractDOS(const char* path); | extern BOOL ExtractDOS(const char* path); | ||||||
| extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan); | extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan); | ||||||
| extern int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes); | extern int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes); | ||||||
|  | extern BOOL ExtractEfiImgFiles(const char* dir); | ||||||
| extern char* MountISO(const char* path); | extern char* MountISO(const char* path); | ||||||
| extern void UnMountISO(void); | extern void UnMountISO(void); | ||||||
| extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs); | extern BOOL InstallSyslinux(DWORD drive_index, char drive_letter, int fs); | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | ||||||
| IDD_DIALOG DIALOGEX 12, 12, 242, 376 | IDD_DIALOG DIALOGEX 12, 12, 242, 376 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||||
| EXSTYLE WS_EX_ACCEPTFILES | EXSTYLE WS_EX_ACCEPTFILES | ||||||
| CAPTION "Rufus 2.16.1173" | CAPTION "Rufus 2.16.1174" | ||||||
| FONT 8, "Segoe UI Symbol", 400, 0, 0x0 | FONT 8, "Segoe UI Symbol", 400, 0, 0x0 | ||||||
| BEGIN | BEGIN | ||||||
|     LTEXT           "Device",IDS_DEVICE_TXT,9,6,200,8 |     LTEXT           "Device",IDS_DEVICE_TXT,9,6,200,8 | ||||||
|  | @ -366,8 +366,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 2,16,1173,0 |  FILEVERSION 2,16,1174,0 | ||||||
|  PRODUCTVERSION 2,16,1173,0 |  PRODUCTVERSION 2,16,1174,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -384,13 +384,13 @@ BEGIN | ||||||
|         BEGIN |         BEGIN | ||||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" |             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "2.16.1173" |             VALUE "FileVersion", "2.16.1174" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus.exe" |             VALUE "OriginalFilename", "rufus.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "2.16.1173" |             VALUE "ProductVersion", "2.16.1174" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue