mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] add full extraction support for efi.img
* Also, Solus distro maintainers, I hate you!
This commit is contained in:
		
							parent
							
								
									dd9f9ce1e9
								
							
						
					
					
						commit
						f02fbe3acc
					
				
					 13 changed files with 327 additions and 77 deletions
				
			
		|  | @ -42,6 +42,7 @@ | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="..\src\syslinux\libfat\cache.c" /> |     <ClCompile Include="..\src\syslinux\libfat\cache.c" /> | ||||||
|  |     <ClCompile Include="..\src\syslinux\libfat\dumpdir.c" /> | ||||||
|     <ClCompile Include="..\src\syslinux\libfat\fatchain.c" /> |     <ClCompile Include="..\src\syslinux\libfat\fatchain.c" /> | ||||||
|     <ClCompile Include="..\src\syslinux\libfat\open.c" /> |     <ClCompile Include="..\src\syslinux\libfat\open.c" /> | ||||||
|     <ClCompile Include="..\src\syslinux\libfat\searchdir.c" /> |     <ClCompile Include="..\src\syslinux\libfat\searchdir.c" /> | ||||||
|  |  | ||||||
|  | @ -37,5 +37,8 @@ | ||||||
|     <ClCompile Include="..\src\syslinux\libfat\searchdir.c"> |     <ClCompile Include="..\src\syslinux\libfat\searchdir.c"> | ||||||
|       <Filter>Source Files</Filter> |       <Filter>Source Files</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="..\src\syslinux\libfat\dumpdir.c"> | ||||||
|  |       <Filter>Source Files</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| </Project> | </Project> | ||||||
							
								
								
									
										206
									
								
								src/iso.c
									
										
									
									
									
								
							
							
						
						
									
										206
									
								
								src/iso.c
									
										
									
									
									
								
							|  | @ -59,6 +59,7 @@ uint32_t GetInstallWimVersion(const char* iso); | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| 	BOOLEAN is_cfg; | 	BOOLEAN is_cfg; | ||||||
|  | 	BOOLEAN is_conf; | ||||||
| 	BOOLEAN is_syslinux_cfg; | 	BOOLEAN is_syslinux_cfg; | ||||||
| 	BOOLEAN is_grub_cfg; | 	BOOLEAN is_grub_cfg; | ||||||
| 	BOOLEAN is_old_c32[NB_OLD_C32]; | 	BOOLEAN is_old_c32[NB_OLD_C32]; | ||||||
|  | @ -291,11 +292,11 @@ static void fix_config(const char* psz_fullpath, const char* psz_path, const cha | ||||||
| 
 | 
 | ||||||
| 	// Workaround for config files requiring an ISO label for kernel append that may be
 | 	// Workaround for config files requiring an ISO label for kernel append that may be
 | ||||||
| 	// different from our USB label. Oh, and these labels must have spaces converted to \x20.
 | 	// different from our USB label. Oh, and these labels must have spaces converted to \x20.
 | ||||||
| 	if (props->is_cfg) { | 	if ((props->is_cfg) || (props->is_conf)) { | ||||||
| 		iso_label = replace_char(img_report.label, ' ', "\\x20"); | 		iso_label = replace_char(img_report.label, ' ', "\\x20"); | ||||||
| 		usb_label = replace_char(img_report.usb_label, ' ', "\\x20"); | 		usb_label = replace_char(img_report.usb_label, ' ', "\\x20"); | ||||||
| 		if ((iso_label != NULL) && (usb_label != NULL)) { | 		if ((iso_label != NULL) && (usb_label != NULL)) { | ||||||
| 			if (replace_in_token_data(src, (props->is_grub_cfg) ? "linuxefi" : "append", | 			if (replace_in_token_data(src, (props->is_grub_cfg) ? "linuxefi" : ((props->is_conf) ? "options" : "append"), | ||||||
| 				iso_label, usb_label, TRUE) != NULL) | 				iso_label, usb_label, TRUE) != NULL) | ||||||
| 				uprintf("  Patched %s: '%s' ➔ '%s'\n", src, iso_label, usb_label); | 				uprintf("  Patched %s: '%s' ➔ '%s'\n", src, iso_label, usb_label); | ||||||
| 		} | 		} | ||||||
|  | @ -881,7 +882,7 @@ out: | ||||||
| 					img_report.sl_version_str); | 					img_report.sl_version_str); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if (!IS_EFI_BOOTABLE(img_report) && HAS_EFI_IMG(img_report) && ExtractEfiImgFiles(NULL)) { | 		if (!IS_EFI_BOOTABLE(img_report) && HAS_EFI_IMG(img_report) && HasEfiImgBootLoaders()) { | ||||||
| 			img_report.has_efi = 0x80; | 			img_report.has_efi = 0x80; | ||||||
| 		} | 		} | ||||||
| 		if (HAS_WINPE(img_report)) { | 		if (HAS_WINPE(img_report)) { | ||||||
|  | @ -932,9 +933,9 @@ out: | ||||||
| 		StrArrayDestroy(&isolinux_path); | 		StrArrayDestroy(&isolinux_path); | ||||||
| 		SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0); | 		SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0); | ||||||
| 	} else { | 	} else { | ||||||
| 		// For Debian live ISOs, that only provide EFI boot files in a FAT efi.img
 | 		// Solus and other ISOs only provide EFI boot files in a FAT efi.img
 | ||||||
| 		if (img_report.has_efi == 0x80) | 		if (img_report.has_efi == 0x80) | ||||||
| 			ExtractEfiImgFiles(dest_dir); | 			DumpFatDir(dest_dir, 0); | ||||||
| 		if (HAS_SYSLINUX(img_report)) { | 		if (HAS_SYSLINUX(img_report)) { | ||||||
| 			static_sprintf(path, "%s\\syslinux.cfg", dest_dir); | 			static_sprintf(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
 | ||||||
|  | @ -1187,26 +1188,19 @@ int iso9660_readfat(intptr_t pp, void *buf, size_t secsize, libfat_sector_t sec) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Extract EFI bootloaders files from an ISO-9660 FAT img file into directory <dir>. |  * Returns TRUE if an EFI bootloader exists in the img. | ||||||
|  * 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 HasEfiImgBootLoaders(void) | ||||||
| { | { | ||||||
| 	BOOL ret = FALSE; | 	BOOL ret = FALSE; | ||||||
| 	HANDLE handle; |  | ||||||
| 	DWORD size, file_size, written; |  | ||||||
| 	iso9660_t* p_iso = NULL; | 	iso9660_t* p_iso = NULL; | ||||||
| 	iso9660_stat_t* p_statbuf = NULL; | 	iso9660_stat_t* p_statbuf = NULL; | ||||||
| 	iso9660_readfat_private* p_private = NULL; | 	iso9660_readfat_private* p_private = NULL; | ||||||
| 	libfat_sector_t s; |  | ||||||
| 	int32_t dc, c; | 	int32_t dc, c; | ||||||
| 	struct libfat_filesystem *lf_fs = NULL; | 	struct libfat_filesystem *lf_fs = NULL; | ||||||
| 	struct libfat_direntry direntry; | 	struct libfat_direntry direntry; | ||||||
| 	char name[12] = { 0 }; | 	char name[12] = { 0 }; | ||||||
| 	char path[64]; |  | ||||||
| 	int i, j, k; | 	int i, j, k; | ||||||
| 	void* buf; |  | ||||||
| 
 | 
 | ||||||
| 	if ((image_path == NULL) || !HAS_EFI_IMG(img_report)) | 	if ((image_path == NULL) || !HAS_EFI_IMG(img_report)) | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
|  | @ -1261,57 +1255,10 @@ BOOL ExtractEfiImgFiles(const char* dir) | ||||||
| 		} | 		} | ||||||
| 		c = libfat_searchdir(lf_fs, dc, name, &direntry); | 		c = libfat_searchdir(lf_fs, dc, name, &direntry); | ||||||
| 		if (c > 0) { | 		if (c > 0) { | ||||||
| 			if (dir == NULL) { | 			if (!ret) | ||||||
| 				if (!ret) | 				uprintf("  Detected EFI bootloader(s) (from '%s'):", img_report.efi_img_path); | ||||||
| 					uprintf("  Detected EFI bootloader(s) (from '%s'):", img_report.efi_img_path); | 			uprintf("  ● '%s'", efi_bootname[i]); | ||||||
| 				uprintf("  ● '%s'", efi_bootname[i]); | 			ret = TRUE; | ||||||
| 				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; |  | ||||||
| 				} |  | ||||||
| 				static_strcat(path, "\\boot"); |  | ||||||
| 				if (!CreateDirectoryA(path, 0) && (GetLastError() != ERROR_ALREADY_EXISTS)) { |  | ||||||
| 					uprintf("Could not create directory '%s': %s\n", path, WindowsErrorString()); |  | ||||||
| 					continue; |  | ||||||
| 				} |  | ||||||
| 				static_strcat(path, "\\"); |  | ||||||
| 				static_strcat(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(lf_fs, c); |  | ||||||
| 				while ((s != 0) && (s < 0xFFFFFFFFULL) && (written < file_size)) { |  | ||||||
| 					buf = libfat_get_sector(lf_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(lf_fs, s); |  | ||||||
| 				} |  | ||||||
| 				CloseHandle(handle); |  | ||||||
| 				ret = TRUE; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -1327,6 +1274,135 @@ out: | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | BOOL DumpFatDir(const char* path, int32_t cluster) | ||||||
|  | { | ||||||
|  | 	// We don't have concurrent calls to this function, so a static lf_fs is fine
 | ||||||
|  | 	static struct libfat_filesystem *lf_fs = NULL; | ||||||
|  | 	void* buf; | ||||||
|  | 	char *target = NULL, *name = NULL; | ||||||
|  | 	BOOL ret = FALSE; | ||||||
|  | 	HANDLE handle; | ||||||
|  | 	DWORD size, written; | ||||||
|  | 	libfat_diritem_t diritem = { 0 }; | ||||||
|  | 	libfat_dirpos_t dirpos = { cluster, -1, 0 }; | ||||||
|  | 	libfat_sector_t s; | ||||||
|  | 	iso9660_t* p_iso = NULL; | ||||||
|  | 	iso9660_stat_t* p_statbuf = NULL; | ||||||
|  | 	iso9660_readfat_private* p_private = NULL; | ||||||
|  | 
 | ||||||
|  | 	if (path == NULL) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	if (cluster == 0) { | ||||||
|  | 		// Root dir => Perform init stuff
 | ||||||
|  | 		if (image_path == NULL) | ||||||
|  | 			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[0];	// Image should be small enough not to use multiextents
 | ||||||
|  | 		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; | ||||||
|  | 		} | ||||||
|  | 		lf_fs = libfat_open(iso9660_readfat, (intptr_t)p_private); | ||||||
|  | 		if (lf_fs == NULL) { | ||||||
|  | 			uprintf("FAT access error"); | ||||||
|  | 			goto out; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	do { | ||||||
|  | 		dirpos.cluster = libfat_dumpdir(lf_fs, &dirpos, &diritem); | ||||||
|  | 		if (dirpos.cluster >= 0) { | ||||||
|  | 			name = wchar_to_utf8(diritem.name); | ||||||
|  | 			target = malloc(strlen(path) + safe_strlen(name) + 2); | ||||||
|  | 			if ((name == NULL) || (target == NULL)) { | ||||||
|  | 				uprintf("Could not allocate buffer"); | ||||||
|  | 				safe_free(name); | ||||||
|  | 				goto out; | ||||||
|  | 			} | ||||||
|  | 			strcpy(target, path); | ||||||
|  | 			strcat(target, "\\"); | ||||||
|  | 			strcat(target, name); | ||||||
|  | 			if (diritem.attributes & 0x10) { | ||||||
|  | 				// Directory => Create directory
 | ||||||
|  | 				if (!CreateDirectoryU(target, 0) && (GetLastError() != ERROR_ALREADY_EXISTS)) { | ||||||
|  | 					uprintf("Could not create directory '%s': %s\n", target, WindowsErrorString()); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				if (!DumpFatDir(target, dirpos.cluster)) | ||||||
|  | 					goto out; | ||||||
|  | 			} else { | ||||||
|  | 				// Need to figure out if it's a .conf file (Damn you Solus!!)
 | ||||||
|  | 				EXTRACT_PROPS props = { 0 }; | ||||||
|  | 				size_t len = strlen(name); | ||||||
|  | 				props.is_conf = ((len > 4) && (stricmp(&name[len - 5], ".conf") == 0)); | ||||||
|  | 				uprintf("Extracting: %s (from '%s', %s)", target, img_report.efi_img_path, | ||||||
|  | 					SizeToHumanReadable(diritem.size, FALSE, FALSE)); | ||||||
|  | 				handle = CreateFileU(target, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, | ||||||
|  | 					NULL, CREATE_ALWAYS, diritem.attributes, NULL); | ||||||
|  | 				if (handle == INVALID_HANDLE_VALUE) { | ||||||
|  | 					uprintf("Unable to create '%s': %s", target, WindowsErrorString()); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				written = 0; | ||||||
|  | 				s = libfat_clustertosector(lf_fs, dirpos.cluster); | ||||||
|  | 				while ((s != 0) && (s < 0xFFFFFFFFULL) && (written < diritem.size)) { | ||||||
|  | 					if (FormatStatus) goto out; | ||||||
|  | 					buf = libfat_get_sector(lf_fs, s); | ||||||
|  | 					size = MIN(LIBFAT_SECTOR_SIZE, diritem.size - written); | ||||||
|  | 					if (!WriteFileWithRetry(handle, buf, size, &size, WRITE_RETRIES) || | ||||||
|  | 						(size != MIN(LIBFAT_SECTOR_SIZE, diritem.size - written))) { | ||||||
|  | 						uprintf("Error writing '%s': %s", target, WindowsErrorString()); | ||||||
|  | 						CloseHandle(handle); | ||||||
|  | 						continue; | ||||||
|  | 					} | ||||||
|  | 					written += size; | ||||||
|  | 					s = libfat_nextsector(lf_fs, s); | ||||||
|  | 					// Trust me, you *REALLY* want to invoke libfat_flush() here
 | ||||||
|  | 					libfat_flush(lf_fs); | ||||||
|  | 				} | ||||||
|  | 				CloseHandle(handle); | ||||||
|  | 				if (props.is_conf) | ||||||
|  | 					fix_config(target, NULL, NULL, &props); | ||||||
|  | 			} | ||||||
|  | 			safe_free(target); | ||||||
|  | 			safe_free(name); | ||||||
|  | 		} | ||||||
|  | 	} while (dirpos.cluster >= 0); | ||||||
|  | 	ret = TRUE; | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	if (cluster == 0) { | ||||||
|  | 		if (lf_fs != NULL) { | ||||||
|  | 			libfat_close(lf_fs); | ||||||
|  | 			lf_fs = NULL; | ||||||
|  | 		} | ||||||
|  | 		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)); | ||||||
|  |  | ||||||
|  | @ -452,7 +452,7 @@ static __inline DWORD CharUpperBuffU(char* lpString, DWORD len) | ||||||
| 
 | 
 | ||||||
| static __inline HANDLE CreateFileU(const char* lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, | static __inline HANDLE CreateFileU(const char* lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, | ||||||
| 								   LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, | 								   LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, | ||||||
| 								   DWORD dwFlagsAndAttributes,  HANDLE hTemplateFile) | 								   DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) | ||||||
| { | { | ||||||
| 	HANDLE ret = INVALID_HANDLE_VALUE; | 	HANDLE ret = INVALID_HANDLE_VALUE; | ||||||
| 	DWORD err = ERROR_INVALID_DATA; | 	DWORD err = ERROR_INVALID_DATA; | ||||||
|  | @ -465,6 +465,18 @@ static __inline HANDLE CreateFileU(const char* lpFileName, DWORD dwDesiredAccess | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static __inline BOOL CreateDirectoryU(const char* lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes) | ||||||
|  | { | ||||||
|  | 	BOOL ret = FALSE; | ||||||
|  | 	DWORD err = ERROR_INVALID_DATA; | ||||||
|  | 	wconvert(lpPathName); | ||||||
|  | 	ret = CreateDirectoryW(wlpPathName, lpSecurityAttributes); | ||||||
|  | 	err = GetLastError(); | ||||||
|  | 	wfree(lpPathName); | ||||||
|  | 	SetLastError(err); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static __inline BOOL CopyFileU(const char* lpExistingFileName, const char* lpNewFileName, BOOL bFailIfExists) | static __inline BOOL CopyFileU(const char* lpExistingFileName, const char* lpNewFileName, BOOL bFailIfExists) | ||||||
| { | { | ||||||
| 	BOOL ret = FALSE; | 	BOOL ret = FALSE; | ||||||
|  |  | ||||||
|  | @ -121,7 +121,7 @@ typedef struct _OBJECT_TYPES_INFORMATION | ||||||
| typedef struct _PROCESS_BASIC_INFORMATION_WOW64 | typedef struct _PROCESS_BASIC_INFORMATION_WOW64 | ||||||
| { | { | ||||||
| 	PVOID Reserved1[2]; | 	PVOID Reserved1[2]; | ||||||
| 	// MinGW32 screws us with a sizeof(PVOID64) of 4 instead of 8 => Use an ULONGLONG instead
 | 	// MinGW32 screws us with a sizeof(PVOID64) of 4 instead of 8 => Use ULONGLONG instead
 | ||||||
| 	ULONGLONG PebBaseAddress; | 	ULONGLONG PebBaseAddress; | ||||||
| 	PVOID Reserved2[4]; | 	PVOID Reserved2[4]; | ||||||
| 	ULONG_PTR UniqueProcessId[2]; | 	ULONG_PTR UniqueProcessId[2]; | ||||||
|  |  | ||||||
|  | @ -1886,6 +1886,10 @@ 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) { | ||||||
|  | 			image_path = "C:\\Downloads\\fat.iso"; | ||||||
|  | 			strcpy(img_report.efi_img_path, "efi.img"); | ||||||
|  | 			DumpFatDir("C:\\tmp", 0); | ||||||
|  | 			image_path = NULL; | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -503,7 +503,8 @@ extern BOOL ExtractAppIcon(const char* filename, BOOL bSilent); | ||||||
| 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 BOOL HasEfiImgBootLoaders(void); | ||||||
|  | extern BOOL DumpFatDir(const char* path, int32_t cluster); | ||||||
| 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, 232, 326 | IDD_DIALOG DIALOGEX 12, 12, 232, 326 | ||||||
| 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 3.6.1506" | CAPTION "Rufus 3.6.1507" | ||||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||||
| BEGIN | BEGIN | ||||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP |     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||||
|  | @ -394,8 +394,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 3,6,1506,0 |  FILEVERSION 3,6,1507,0 | ||||||
|  PRODUCTVERSION 3,6,1506,0 |  PRODUCTVERSION 3,6,1507,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -413,13 +413,13 @@ BEGIN | ||||||
|             VALUE "Comments", "https://akeo.ie" |             VALUE "Comments", "https://akeo.ie" | ||||||
|             VALUE "CompanyName", "Akeo Consulting" |             VALUE "CompanyName", "Akeo Consulting" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "3.6.1506" |             VALUE "FileVersion", "3.6.1507" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus-3.6.exe" |             VALUE "OriginalFilename", "rufus-3.6.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "3.6.1506" |             VALUE "ProductVersion", "3.6.1507" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| noinst_LIBRARIES = libfat.a | noinst_LIBRARIES = libfat.a | ||||||
| 
 | 
 | ||||||
| libfat_a_SOURCES = cache.c fatchain.c open.c searchdir.c | libfat_a_SOURCES = cache.c fatchain.c open.c searchdir.c dumpdir.c | ||||||
| libfat_a_CFLAGS = $(AM_CFLAGS) | libfat_a_CFLAGS = $(AM_CFLAGS) | ||||||
|  |  | ||||||
|  | @ -95,7 +95,7 @@ libfat_a_AR = $(AR) $(ARFLAGS) | ||||||
| libfat_a_LIBADD = | libfat_a_LIBADD = | ||||||
| am_libfat_a_OBJECTS = libfat_a-cache.$(OBJEXT) \
 | am_libfat_a_OBJECTS = libfat_a-cache.$(OBJEXT) \
 | ||||||
| 	libfat_a-fatchain.$(OBJEXT) libfat_a-open.$(OBJEXT) \
 | 	libfat_a-fatchain.$(OBJEXT) libfat_a-open.$(OBJEXT) \
 | ||||||
| 	libfat_a-searchdir.$(OBJEXT) | 	libfat_a-searchdir.$(OBJEXT) libfat_a-dumpdir.$(OBJEXT) | ||||||
| libfat_a_OBJECTS = $(am_libfat_a_OBJECTS) | libfat_a_OBJECTS = $(am_libfat_a_OBJECTS) | ||||||
| AM_V_P = $(am__v_P_@AM_V@) | AM_V_P = $(am__v_P_@AM_V@) | ||||||
| am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) | am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) | ||||||
|  | @ -243,7 +243,7 @@ top_build_prefix = @top_build_prefix@ | ||||||
| top_builddir = @top_builddir@ | top_builddir = @top_builddir@ | ||||||
| top_srcdir = @top_srcdir@ | top_srcdir = @top_srcdir@ | ||||||
| noinst_LIBRARIES = libfat.a | noinst_LIBRARIES = libfat.a | ||||||
| libfat_a_SOURCES = cache.c fatchain.c open.c searchdir.c | libfat_a_SOURCES = cache.c fatchain.c open.c searchdir.c dumpdir.c | ||||||
| libfat_a_CFLAGS = $(AM_CFLAGS) | libfat_a_CFLAGS = $(AM_CFLAGS) | ||||||
| all: all-am | all: all-am | ||||||
| 
 | 
 | ||||||
|  | @ -324,6 +324,12 @@ libfat_a-searchdir.o: searchdir.c | ||||||
| libfat_a-searchdir.obj: searchdir.c | libfat_a-searchdir.obj: searchdir.c | ||||||
| 	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfat_a_CFLAGS) $(CFLAGS) -c -o libfat_a-searchdir.obj `if test -f 'searchdir.c'; then $(CYGPATH_W) 'searchdir.c'; else $(CYGPATH_W) '$(srcdir)/searchdir.c'; fi` | 	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfat_a_CFLAGS) $(CFLAGS) -c -o libfat_a-searchdir.obj `if test -f 'searchdir.c'; then $(CYGPATH_W) 'searchdir.c'; else $(CYGPATH_W) '$(srcdir)/searchdir.c'; fi` | ||||||
| 
 | 
 | ||||||
|  | libfat_a-dumpdir.o: dumpdir.c | ||||||
|  | 	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfat_a_CFLAGS) $(CFLAGS) -c -o libfat_a-dumpdir.o `test -f 'dumpdir.c' || echo '$(srcdir)/'`dumpdir.c | ||||||
|  | 
 | ||||||
|  | libfat_a-dumpdir.obj: dumpdir.c | ||||||
|  | 	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfat_a_CFLAGS) $(CFLAGS) -c -o libfat_a-dumpdir.obj `if test -f 'dumpdir.c'; then $(CYGPATH_W) 'dumpdir.c'; else $(CYGPATH_W) '$(srcdir)/dumpdir.c'; fi` | ||||||
|  | 
 | ||||||
| ID: $(am__tagged_files) | ID: $(am__tagged_files) | ||||||
| 	$(am__define_uniq_tagged_files); mkid -fID $$unique | 	$(am__define_uniq_tagged_files); mkid -fID $$unique | ||||||
| tags: tags-am | tags: tags-am | ||||||
|  |  | ||||||
|  | @ -28,7 +28,6 @@ | ||||||
|  * Also, since struct libfat_sector's data[0] is our buffer, this means we must BOTH |  * Also, since struct libfat_sector's data[0] is our buffer, this means we must BOTH | ||||||
|  * align that member in the struct declaration, and use aligned malloc/free. |  * align that member in the struct declaration, and use aligned malloc/free. | ||||||
|  */ |  */ | ||||||
| extern void _uprintf(const char *format, ...); |  | ||||||
| void *libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n) | void *libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n) | ||||||
| { | { | ||||||
|     struct libfat_sector *ls; |     struct libfat_sector *ls; | ||||||
|  |  | ||||||
							
								
								
									
										126
									
								
								src/syslinux/libfat/dumpdir.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								src/syslinux/libfat/dumpdir.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,126 @@ | ||||||
|  | /* ----------------------------------------------------------------------- *
 | ||||||
|  |  * | ||||||
|  |  *   Copyright 2019 Pete Batard <pete@akeo.ie> | ||||||
|  |  * | ||||||
|  |  *   This program is free software; you can redistribute it and/or modify | ||||||
|  |  *   it under the terms of the GNU General Public License as published by | ||||||
|  |  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330, | ||||||
|  |  *   Boston MA 02111-1307, USA; either version 2 of the License, or | ||||||
|  |  *   (at your option) any later version; incorporated herein by reference. | ||||||
|  |  * | ||||||
|  |  * ----------------------------------------------------------------------- */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * dumpdir.c | ||||||
|  |  * | ||||||
|  |  * Returns all files and directory items from a FAT directory. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <string.h> | ||||||
|  | #include "libfatint.h" | ||||||
|  | 
 | ||||||
|  | static struct fat_dirent* get_next_dirent(struct libfat_filesystem *fs, | ||||||
|  | 					  libfat_sector_t *sector, int *offset) | ||||||
|  | { | ||||||
|  |     struct fat_dirent *dep; | ||||||
|  | 
 | ||||||
|  |     *offset += sizeof(struct fat_dirent); | ||||||
|  |     if (*offset >= LIBFAT_SECTOR_SIZE) { | ||||||
|  | 	*offset = 0; | ||||||
|  | 	*sector = libfat_nextsector(fs, *sector); | ||||||
|  | 	if ((*sector == 0) || (*sector == (libfat_sector_t)-1)) | ||||||
|  | 	    return NULL; | ||||||
|  |     } | ||||||
|  |     dep = libfat_get_sector(fs, *sector); | ||||||
|  |     if (!dep) | ||||||
|  | 	return NULL; | ||||||
|  |     dep = (struct fat_dirent*) &((char*)dep)[*offset]; | ||||||
|  |     return dep; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void fill_utf16(wchar_t *name, unsigned char *entry) | ||||||
|  | { | ||||||
|  |     int i; | ||||||
|  |     for (i=0; i<5; i++) | ||||||
|  | 	name[i] = read16((le16_t*)&entry[1 + 2*i]); | ||||||
|  |     for (i=5; i<11; i++) | ||||||
|  | 	name[i] = read16((le16_t*)&entry[4 + 2*i]); | ||||||
|  |     for (i=11; i<12; i++) | ||||||
|  | 	name[i] = read16((le16_t*)&entry[6 + 2*i]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int libfat_dumpdir(struct libfat_filesystem *fs, libfat_dirpos_t *dp, | ||||||
|  | 		   libfat_diritem_t *di) | ||||||
|  | { | ||||||
|  |     int i, j; | ||||||
|  |     struct fat_dirent *dep; | ||||||
|  | 
 | ||||||
|  |     memset(di->name, 0, sizeof(di->name)); | ||||||
|  |     di->size = 0; | ||||||
|  |     di->attributes = 0; | ||||||
|  |     if (dp->offset < 0) { | ||||||
|  | 	/* First entry */ | ||||||
|  | 	dp->offset = 0; | ||||||
|  | 	dp->sector = libfat_clustertosector(fs, dp->cluster); | ||||||
|  | 	if ((dp->sector == 0) || (dp->sector == (libfat_sector_t)-1)) | ||||||
|  | 	    return -1; | ||||||
|  | 	dep = libfat_get_sector(fs, dp->sector); | ||||||
|  |     } else { | ||||||
|  | 	dep = get_next_dirent(fs, &dp->sector, &dp->offset); | ||||||
|  |     } | ||||||
|  |     if (!dep) | ||||||
|  | 	return -1;	/* Read error */ | ||||||
|  | 
 | ||||||
|  |     /* Ignore volume labels, deleted entries as well as '.' and '..' entries */ | ||||||
|  |     while ((dep->attribute == 0x08) || (dep->name[0] == 0xe5) || | ||||||
|  | 	   ((dep->name[0] == '.') && (dep->name[2] == ' ') && | ||||||
|  | 	    ((dep->name[1] == ' ') || (dep->name[1] == '.')))) { | ||||||
|  | 	dep = get_next_dirent(fs, &dp->sector, &dp->offset); | ||||||
|  | 	if (!dep) | ||||||
|  | 	    return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (dep->name[0] == 0) | ||||||
|  | 	return -2;	/* Last entry */ | ||||||
|  | 
 | ||||||
|  |     /* Build UCS-2 name */ | ||||||
|  |     j = -1; | ||||||
|  |     while (dep->attribute == 0x0F) {	/* LNF (Long File Name) entry */ | ||||||
|  | 	i = dep->name[0]; | ||||||
|  | 	if ((j < 0) && ((i & 0xF0) != 0x40))  /* End of LFN marker was not found */ | ||||||
|  | 	    break; | ||||||
|  | 	/* Isolate and check the sequence number, which should be decrementing */ | ||||||
|  | 	i = (i & 0x0F) - 1; | ||||||
|  | 	if ((j >= 0) && (i != j - 1)) | ||||||
|  | 	    return -3; | ||||||
|  | 	j = i; | ||||||
|  | 	fill_utf16(&di->name[13 * i], dep->name); | ||||||
|  | 	dep = get_next_dirent(fs, &dp->sector, &dp->offset); | ||||||
|  | 	if (!dep) | ||||||
|  | 	    return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (di->name[0] == 0) { | ||||||
|  | 	for (i = 0, j = 0; i < 12; i++) { | ||||||
|  | 	    if ((i >= 8) && (dep->name[i] == ' ')) | ||||||
|  | 		break; | ||||||
|  | 	    if (i == 8) | ||||||
|  | 		di->name[j++] = '.'; | ||||||
|  | 	    if (dep->name[i] == ' ') | ||||||
|  | 		continue; | ||||||
|  | 	    di->name[j] = dep->name[i]; | ||||||
|  | 	    /* Caseflags: bit 3 = lowercase basename, bit 4 = lowercase extension */ | ||||||
|  | 	    if ((di->name[j] >= 'A') && (di->name[j] <= 'Z')) { | ||||||
|  | 		if ((dep->caseflags & 0x02) && (i < 8)) | ||||||
|  | 		    di->name[j] += 0x20; | ||||||
|  | 		if ((dep->caseflags & 0x04) && (i >= 8)) | ||||||
|  | 		    di->name[j] += 0x20; | ||||||
|  | 	    } | ||||||
|  | 	    j++; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     di->attributes = dep->attribute & 0x37; | ||||||
|  |     di->size = read32(&dep->size); | ||||||
|  |     return read16(&dep->clustlo) + (read16(&dep->clusthi) << 16); | ||||||
|  | } | ||||||
|  | @ -39,6 +39,18 @@ struct libfat_direntry { | ||||||
|     unsigned char entry[32]; |     unsigned char entry[32]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | typedef struct libfat_dirpos { | ||||||
|  |     int32_t cluster; | ||||||
|  |     int32_t offset; | ||||||
|  |     libfat_sector_t sector; | ||||||
|  | } libfat_dirpos_t; | ||||||
|  | 
 | ||||||
|  | typedef struct libfat_diritem { | ||||||
|  |     wchar_t  name[256]; | ||||||
|  |     uint32_t size; | ||||||
|  |     uint8_t  attributes;    /* [--ad-shr] */ | ||||||
|  | } libfat_diritem_t; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Open the filesystem.  The readfunc is the function to read |  * Open the filesystem.  The readfunc is the function to read | ||||||
|  * sectors, in the format: |  * sectors, in the format: | ||||||
|  | @ -86,4 +98,14 @@ void *libfat_get_sector(struct libfat_filesystem *fs, libfat_sector_t n); | ||||||
| int32_t libfat_searchdir(struct libfat_filesystem *fs, int32_t dirclust, | int32_t libfat_searchdir(struct libfat_filesystem *fs, int32_t dirclust, | ||||||
| 			 const void *name, struct libfat_direntry *direntry); | 			 const void *name, struct libfat_direntry *direntry); | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Return all the files and directory items from a FAT directory. | ||||||
|  |  * Initial call must set dp->offset to negative and dp->cluster to the cluster | ||||||
|  |  * that contains the directory data. After that each subsequent call must use | ||||||
|  |  * the same dp. | ||||||
|  |  * Return value is the cluster for the corresponding item or negative on error. | ||||||
|  |  */ | ||||||
|  | int libfat_dumpdir(struct libfat_filesystem *fs, libfat_dirpos_t *dp, | ||||||
|  | 		   libfat_diritem_t *di); | ||||||
|  | 
 | ||||||
| #endif /* LIBFAT_H */ | #endif /* LIBFAT_H */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue