mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] add a cheat mode (Alt-P) to toggle GPT ESP to Basic Data
* Windows 10 or later *ONLY* * Also don't report a GPT partition name if it's empty
This commit is contained in:
		
							parent
							
								
									22fb8febc5
								
							
						
					
					
						commit
						23057f6124
					
				
					 6 changed files with 205 additions and 16 deletions
				
			
		
							
								
								
									
										174
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										174
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -34,6 +34,7 @@ | ||||||
| #include "rufus.h" | #include "rufus.h" | ||||||
| #include "missing.h" | #include "missing.h" | ||||||
| #include "resource.h" | #include "resource.h" | ||||||
|  | #include "settings.h" | ||||||
| #include "msapi_utf8.h" | #include "msapi_utf8.h" | ||||||
| #include "localization.h" | #include "localization.h" | ||||||
| 
 | 
 | ||||||
|  | @ -917,7 +918,7 @@ UINT GetDriveTypeFromIndex(DWORD DriveIndex) | ||||||
| char GetUnusedDriveLetter(void) | char GetUnusedDriveLetter(void) | ||||||
| { | { | ||||||
| 	DWORD size; | 	DWORD size; | ||||||
| 	char drive_letter = 'Z'+1, *drive, drives[26*4 + 1];	/* "D:\", "E:\", etc., plus one NUL */ | 	char drive_letter, *drive, drives[26*4 + 1];	/* "D:\", "E:\", etc., plus one NUL */ | ||||||
| 
 | 
 | ||||||
| 	size = GetLogicalDriveStringsA(sizeof(drives), drives); | 	size = GetLogicalDriveStringsA(sizeof(drives), drives); | ||||||
| 	if (size == 0) { | 	if (size == 0) { | ||||||
|  | @ -944,6 +945,29 @@ out: | ||||||
| 	return (drive_letter > 'Z') ? 0 : drive_letter; | 	return (drive_letter > 'Z') ? 0 : drive_letter; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | BOOL IsDriveLetterInUse(const char drive_letter) | ||||||
|  | { | ||||||
|  | 	DWORD size; | ||||||
|  | 	char *drive, drives[26 * 4 + 1]; | ||||||
|  | 
 | ||||||
|  | 	size = GetLogicalDriveStringsA(sizeof(drives), drives); | ||||||
|  | 	if (size == 0) { | ||||||
|  | 		uprintf("GetLogicalDriveStrings failed: %s", WindowsErrorString()); | ||||||
|  | 		return TRUE; | ||||||
|  | 	} | ||||||
|  | 	if (size > sizeof(drives)) { | ||||||
|  | 		uprintf("GetLogicalDriveStrings: Buffer too small (required %d vs. %d)", size, sizeof(drives)); | ||||||
|  | 		return TRUE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (drive = drives; *drive; drive += safe_strlen(drive) + 1) { | ||||||
|  | 		if (drive_letter == (char)toupper((int)*drive)) | ||||||
|  | 			return TRUE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return FALSE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Return the drive letter and volume label |  * Return the drive letter and volume label | ||||||
|  * If the drive doesn't have a volume assigned, space is returned for the letter |  * If the drive doesn't have a volume assigned, space is returned for the letter | ||||||
|  | @ -1130,6 +1154,142 @@ BOOL AnalyzePBR(HANDLE hLogicalVolume) | ||||||
| 	return TRUE; | 	return TRUE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static BOOL StoreEspInfo(GUID* guid) | ||||||
|  | { | ||||||
|  | 	uint8_t j; | ||||||
|  | 	char key_name[2][16], *str; | ||||||
|  | 	// Look for an empty slot and use that if available
 | ||||||
|  | 	for (j = 1; j <= MAX_ESP_TOGGLE; j++) { | ||||||
|  | 		static_sprintf(key_name[0], "ToggleEsp%02u", j); | ||||||
|  | 		str = ReadSettingStr(key_name[0]); | ||||||
|  | 		if ((str == NULL) || (str[0] == 0)) | ||||||
|  | 			return WriteSettingStr(key_name[0], GuidToString(guid)); | ||||||
|  | 	} | ||||||
|  | 	// All slots are used => Move every key down and add to last slot
 | ||||||
|  | 	// NB: No, we don't care that the slot we remove may not be the oldest.
 | ||||||
|  | 	for (j = 1; j < MAX_ESP_TOGGLE; j++) { | ||||||
|  | 		static_sprintf(key_name[0], "ToggleEsp%02u", j); | ||||||
|  | 		static_sprintf(key_name[1], "ToggleEsp%02u", j + 1); | ||||||
|  | 		WriteSettingStr(key_name[0], ReadSettingStr(key_name[1])); | ||||||
|  | 	} | ||||||
|  | 	return WriteSettingStr(key_name[1], GuidToString(guid)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static GUID* GetEspGuid(uint8_t index) | ||||||
|  | { | ||||||
|  | 	char key_name[16]; | ||||||
|  | 
 | ||||||
|  | 	static_sprintf(key_name, "ToggleEsp%02u", index); | ||||||
|  | 	return StringToGuid(ReadSettingStr(key_name)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static BOOL ClearEspInfo(uint8_t index) | ||||||
|  | { | ||||||
|  | 	char key_name[16]; | ||||||
|  | 	static_sprintf(key_name, "ToggleEsp%02u", index); | ||||||
|  | 	return WriteSettingStr(key_name, ""); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This calls changes the type of a GPT ESP back and forth to Basic Data. | ||||||
|  |  * Needed because Windows 10 doesn't mount ESPs by default, and also | ||||||
|  |  * doesn't let usermode apps (such as File Explorer) access mounted ESPs. | ||||||
|  |  */ | ||||||
|  | BOOL ToggleEsp(DWORD DriveIndex) | ||||||
|  | { | ||||||
|  | 	char *volume_name, mount_point[] = DEFAULT_ESP_MOUNT_POINT; | ||||||
|  | 	BOOL r, ret = FALSE, found = FALSE; | ||||||
|  | 	HANDLE hPhysical; | ||||||
|  | 	DWORD size, i, j, esp_index = 0; | ||||||
|  | 	BYTE layout[4096] = { 0 }; | ||||||
|  | 	GUID* guid; | ||||||
|  | 	PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; | ||||||
|  | 
 | ||||||
|  | 	if (nWindowsVersion < WINDOWS_10) { | ||||||
|  | 		uprintf("ESP toggling is only available for Windows 10 or later"); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	hPhysical = GetPhysicalHandle(DriveIndex, FALSE, TRUE, TRUE); | ||||||
|  | 	if (hPhysical == INVALID_HANDLE_VALUE) | ||||||
|  | 		return FALSE; | ||||||
|  | 
 | ||||||
|  | 	r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, | ||||||
|  | 		NULL, 0, layout, sizeof(layout), &size, NULL); | ||||||
|  | 	if (!r || size <= 0) { | ||||||
|  | 		uprintf("Could not get layout for drive 0x%02x: %s", DriveIndex, WindowsErrorString()); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 	if (DriveLayout->PartitionStyle != PARTITION_STYLE_GPT) { | ||||||
|  | 		uprintf("ESP toggling is only available for GPT drives"); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// See if the current drive contains an ESP
 | ||||||
|  | 	for (i = 0, j = 0; i < DriveLayout->PartitionCount; i++) { | ||||||
|  | 		if (CompareGUID(&DriveLayout->PartitionEntry[i].Gpt.PartitionType, &PARTITION_GENERIC_ESP)) { | ||||||
|  | 			esp_index = i; | ||||||
|  | 			j++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (j > 1) { | ||||||
|  | 		uprintf("ESP toggling is not available for drives with more than one ESP"); | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 	if (j == 1) { | ||||||
|  | 		// ESP -> Basic Data
 | ||||||
|  | 		i = esp_index; | ||||||
|  | 		uprintf("ESP name: '%S'", DriveLayout->PartitionEntry[i].Gpt.Name); | ||||||
|  | 		if (!StoreEspInfo(&DriveLayout->PartitionEntry[i].Gpt.PartitionId)) { | ||||||
|  | 			uprintf("ESP toggling data could not be stored"); | ||||||
|  | 			goto out; | ||||||
|  | 		} | ||||||
|  | 		DriveLayout->PartitionEntry[i].Gpt.PartitionType = PARTITION_MICROSOFT_DATA; | ||||||
|  | 	} else { | ||||||
|  | 		// Basic Data -> ESP
 | ||||||
|  | 		for (j = 1; j <= MAX_ESP_TOGGLE; j++) { | ||||||
|  | 			guid = GetEspGuid((uint8_t)j); | ||||||
|  | 			if (guid != NULL) { | ||||||
|  | 				for (i = 0; i < DriveLayout->PartitionCount; i++) { | ||||||
|  | 					if (CompareGUID(guid, &DriveLayout->PartitionEntry[i].Gpt.PartitionId)) { | ||||||
|  | 						uprintf("BD name: '%S'", DriveLayout->PartitionEntry[i].Gpt.Name); | ||||||
|  | 						found = TRUE; | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if (found) | ||||||
|  | 					break; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if (j > MAX_ESP_TOGGLE) | ||||||
|  | 			goto out; | ||||||
|  | 		DriveLayout->PartitionEntry[i].Gpt.PartitionType = PARTITION_GENERIC_ESP; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	DriveLayout->PartitionEntry[i].RewritePartition = TRUE;	// Just in case
 | ||||||
|  | 	r = DeviceIoControl(hPhysical, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, (BYTE*)DriveLayout, size, NULL, 0, &size, NULL); | ||||||
|  | 	if (!r) { | ||||||
|  | 		uprintf("Could not set drive layout: %s", WindowsErrorString()); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 	RefreshDriveLayout(hPhysical); | ||||||
|  | 	if (CompareGUID(&DriveLayout->PartitionEntry[i].Gpt.PartitionType, &PARTITION_GENERIC_ESP)) { | ||||||
|  | 		// We successfully reverted ESP from Basic Data -> Delete stored ESP info
 | ||||||
|  | 		ClearEspInfo((uint8_t)j); | ||||||
|  | 	} else if (!IsDriveLetterInUse(*mount_point)) { | ||||||
|  | 		// We succesfully switched ESP to Basic Data -> Try to mount it
 | ||||||
|  | 		volume_name = GetLogicalName(DriveIndex, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart, TRUE, FALSE); | ||||||
|  | 		MountVolume(mount_point, volume_name); | ||||||
|  | 		free(volume_name); | ||||||
|  | 	} | ||||||
|  | 	ret = TRUE; | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	safe_closehandle(hPhysical); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Fill the drive properties (size, FS, etc) |  * Fill the drive properties (size, FS, etc) | ||||||
|  * Returns TRUE if the drive has a partition that can be mounted in Windows, FALSE otherwise |  * Returns TRUE if the drive has a partition that can be mounted in Windows, FALSE otherwise | ||||||
|  | @ -1162,14 +1322,14 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 
 | 
 | ||||||
| 	hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE, TRUE); | 	hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE, TRUE); | ||||||
| 	if (hPhysical == INVALID_HANDLE_VALUE) | 	if (hPhysical == INVALID_HANDLE_VALUE) | ||||||
| 		return 0; | 		return FALSE; | ||||||
| 
 | 
 | ||||||
| 	r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, | 	r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, | ||||||
| 			NULL, 0, geometry, sizeof(geometry), &size, NULL); | 			NULL, 0, geometry, sizeof(geometry), &size, NULL); | ||||||
| 	if (!r || size <= 0) { | 	if (!r || size <= 0) { | ||||||
| 		suprintf("Could not get geometry for drive 0x%02x: %s", DriveIndex, WindowsErrorString()); | 		suprintf("Could not get geometry for drive 0x%02x: %s", DriveIndex, WindowsErrorString()); | ||||||
| 		safe_closehandle(hPhysical); | 		safe_closehandle(hPhysical); | ||||||
| 		return 0; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
| 	SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart; | 	SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart; | ||||||
| 	SelectedDrive.SectorSize = DiskGeometry->Geometry.BytesPerSector; | 	SelectedDrive.SectorSize = DiskGeometry->Geometry.BytesPerSector; | ||||||
|  | @ -1192,7 +1352,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 	if (!r || size <= 0) { | 	if (!r || size <= 0) { | ||||||
| 		suprintf("Could not get layout for drive 0x%02x: %s", DriveIndex, WindowsErrorString()); | 		suprintf("Could not get layout for drive 0x%02x: %s", DriveIndex, WindowsErrorString()); | ||||||
| 		safe_closehandle(hPhysical); | 		safe_closehandle(hPhysical); | ||||||
| 		return 0; | 		return FALSE; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| #if defined(__GNUC__) | #if defined(__GNUC__) | ||||||
|  | @ -1282,8 +1442,10 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | ||||||
| 			} | 			} | ||||||
| 			SelectedDrive.nPartitions++; | 			SelectedDrive.nPartitions++; | ||||||
| 			isUefiNtfs = (wcscmp(DriveLayout->PartitionEntry[i].Gpt.Name, L"UEFI:NTFS") == 0); | 			isUefiNtfs = (wcscmp(DriveLayout->PartitionEntry[i].Gpt.Name, L"UEFI:NTFS") == 0); | ||||||
| 			suprintf("Partition %d%s:\r\n  Type: %s\r\n  Name: '%S'", i+1, isUefiNtfs ? " (UEFI:NTFS)" : "", | 			suprintf("Partition %d%s:\r\n  Type: %s", i+1, isUefiNtfs ? " (UEFI:NTFS)" : "", | ||||||
| 				GetGPTPartitionType(&DriveLayout->PartitionEntry[i].Gpt.PartitionType), DriveLayout->PartitionEntry[i].Gpt.Name); | 				GetGPTPartitionType(&DriveLayout->PartitionEntry[i].Gpt.PartitionType)); | ||||||
|  | 			if (DriveLayout->PartitionEntry[i].Gpt.Name[0] != 0) | ||||||
|  | 				suprintf("  Name: '%S'", DriveLayout->PartitionEntry[i].Gpt.Name); | ||||||
| 			suprintf("  ID: %s\r\n  Size: %s (%" PRIi64 " bytes)\r\n  Start Sector: %" PRIi64 ", Attributes: 0x%016" PRIX64, | 			suprintf("  ID: %s\r\n  Size: %s (%" PRIi64 " bytes)\r\n  Start Sector: %" PRIi64 ", Attributes: 0x%016" PRIX64, | ||||||
| 				GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), | 				GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), | ||||||
| 				SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE), | 				SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE), | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Rufus: The Reliable USB Formatting Utility |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  * Drive access function calls |  * Drive access function calls | ||||||
|  * Copyright © 2011-2019 Pete Batard <pete@akeo.ie> |  * Copyright © 2011-2020 Pete Batard <pete@akeo.ie> | ||||||
|  * |  * | ||||||
|  * This program is free software: you can redistribute it and/or modify |  * 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 |  * it under the terms of the GNU General Public License as published by | ||||||
|  | @ -377,6 +377,7 @@ int GetDriveNumber(HANDLE hDrive, char* path); | ||||||
| BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters); | BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters); | ||||||
| UINT GetDriveTypeFromIndex(DWORD DriveIndex); | UINT GetDriveTypeFromIndex(DWORD DriveIndex); | ||||||
| char GetUnusedDriveLetter(void); | char GetUnusedDriveLetter(void); | ||||||
|  | BOOL IsDriveLetterInUse(const char drive_letter); | ||||||
| BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); | BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); | ||||||
| uint64_t GetDriveSize(DWORD DriveIndex); | uint64_t GetDriveSize(DWORD DriveIndex); | ||||||
| BOOL IsMediaPresent(DWORD DriveIndex); | BOOL IsMediaPresent(DWORD DriveIndex); | ||||||
|  | @ -399,3 +400,4 @@ BOOL CyclePort(int index); | ||||||
| int CycleDevice(int index); | int CycleDevice(int index); | ||||||
| BOOL RefreshLayout(DWORD DriveIndex); | BOOL RefreshLayout(DWORD DriveIndex); | ||||||
| BOOL GetOpticalMedia(IMG_SAVE* img_save); | BOOL GetOpticalMedia(IMG_SAVE* img_save); | ||||||
|  | BOOL ToggleEsp(DWORD DriveIndex); | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -3286,7 +3286,7 @@ relaunch: | ||||||
| 	while(GetMessage(&msg, NULL, 0, 0)) { | 	while(GetMessage(&msg, NULL, 0, 0)) { | ||||||
| 		static BOOL ctrl_without_focus = FALSE; | 		static BOOL ctrl_without_focus = FALSE; | ||||||
| 		BOOL no_focus = (msg.message == WM_SYSKEYDOWN) && !(msg.lParam & 0x20000000); | 		BOOL no_focus = (msg.message == WM_SYSKEYDOWN) && !(msg.lParam & 0x20000000); | ||||||
| 		// ** ****** **** ** **********
 | 		// ** ****** **** *************
 | ||||||
| 		// .,ABCDEFGHIJKLMNOPQRSTUVWXYZ
 | 		// .,ABCDEFGHIJKLMNOPQRSTUVWXYZ
 | ||||||
| 
 | 
 | ||||||
| 		// Sigh... The things one need to do to detect standalone use of the 'Alt' key.
 | 		// Sigh... The things one need to do to detect standalone use of the 'Alt' key.
 | ||||||
|  | @ -3452,6 +3452,14 @@ relaunch: | ||||||
| 				SaveISO(); | 				SaveISO(); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			// Alt-P => Toggle GPT ESP to and from Basic Data type (Windows 10 or later)
 | ||||||
|  | 			if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'P')) { | ||||||
|  | 				int index = ComboBox_GetCurSel(hDeviceList); | ||||||
|  | 				DWORD DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, index); | ||||||
|  | 				if (ToggleEsp(DeviceNum)) | ||||||
|  | 					CyclePort(index); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
| 			// Alt-Q => Enable file indexing (for file systems that support it)
 | 			// Alt-Q => Enable file indexing (for file systems that support it)
 | ||||||
| 			// For multiple reasons, file indexing is disabled by default
 | 			// For multiple reasons, file indexing is disabled by default
 | ||||||
| 			if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'Q')) { | 			if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'Q')) { | ||||||
|  |  | ||||||
|  | @ -71,6 +71,7 @@ | ||||||
| #define MAX_REFRESH                 25			// How long we should wait to refresh UI elements (in ms)
 | #define MAX_REFRESH                 25			// How long we should wait to refresh UI elements (in ms)
 | ||||||
| #define MAX_GUID_STRING_LENGTH      40 | #define MAX_GUID_STRING_LENGTH      40 | ||||||
| #define MAX_PARTITIONS              16			// Maximum number of partitions we handle
 | #define MAX_PARTITIONS              16			// Maximum number of partitions we handle
 | ||||||
|  | #define MAX_ESP_TOGGLE              8			// Maximum number of entries we record to toggle GPT ESP back and forth
 | ||||||
| #define MAX_SECTORS_TO_CLEAR        128			// nb sectors to zap when clearing the MBR/GPT (must be >34)
 | #define MAX_SECTORS_TO_CLEAR        128			// nb sectors to zap when clearing the MBR/GPT (must be >34)
 | ||||||
| #define MAX_WININST                 4			// Max number of install[.wim|.esd] we can handle on an image
 | #define MAX_WININST                 4			// Max number of install[.wim|.esd] we can handle on an image
 | ||||||
| #define MBR_UEFI_MARKER             0x49464555	// 'U', 'E', 'F', 'I', as a 32 bit little endian longword
 | #define MBR_UEFI_MARKER             0x49464555	// 'U', 'E', 'F', 'I', as a 32 bit little endian longword
 | ||||||
|  | @ -111,6 +112,7 @@ | ||||||
| #define WPPRECORDER_MORE_INFO_URL   "https://github.com/pbatard/rufus/wiki/FAQ#BSODs_with_Windows_To_Go_drives_created_from_Windows_10_1809_ISOs"
 | #define WPPRECORDER_MORE_INFO_URL   "https://github.com/pbatard/rufus/wiki/FAQ#BSODs_with_Windows_To_Go_drives_created_from_Windows_10_1809_ISOs"
 | ||||||
| #define SEVENZIP_URL                "https://www.7-zip.org"
 | #define SEVENZIP_URL                "https://www.7-zip.org"
 | ||||||
| #define FILES_DIR                   "rufus_files" | #define FILES_DIR                   "rufus_files" | ||||||
|  | #define DEFAULT_ESP_MOUNT_POINT     "S:\\" | ||||||
| #define IS_POWER_OF_2(x)            ((x != 0) && (((x) & ((x) - 1)) == 0)) | #define IS_POWER_OF_2(x)            ((x != 0) && (((x) & ((x) - 1)) == 0)) | ||||||
| #define IGNORE_RETVAL(expr)         do { (void)(expr); } while(0) | #define IGNORE_RETVAL(expr)         do { (void)(expr); } while(0) | ||||||
| #ifndef ARRAYSIZE | #ifndef ARRAYSIZE | ||||||
|  | @ -485,6 +487,7 @@ extern void UpdateProgressWithInfo(int op, int msg, uint64_t processed, uint64_t | ||||||
| #define UpdateProgressWithInfoInit(hProgressDialog, bNoAltMode) UpdateProgressWithInfo(OP_INIT, (int)bNoAltMode, (uint64_t)(uintptr_t)hProgressDialog, 0); | #define UpdateProgressWithInfoInit(hProgressDialog, bNoAltMode) UpdateProgressWithInfo(OP_INIT, (int)bNoAltMode, (uint64_t)(uintptr_t)hProgressDialog, 0); | ||||||
| extern const char* StrError(DWORD error_code, BOOL use_default_locale); | extern const char* StrError(DWORD error_code, BOOL use_default_locale); | ||||||
| extern char* GuidToString(const GUID* guid); | extern char* GuidToString(const GUID* guid); | ||||||
|  | extern GUID* StringToGuid(const char* str); | ||||||
| extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units); | extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units); | ||||||
| extern char* TimestampToHumanReadable(uint64_t ts); | extern char* TimestampToHumanReadable(uint64_t ts); | ||||||
| extern HWND MyCreateDialog(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc); | extern HWND MyCreateDialog(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc); | ||||||
|  |  | ||||||
							
								
								
									
										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.11.1667" | CAPTION "Rufus 3.11.1668" | ||||||
| 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 | ||||||
|  | @ -395,8 +395,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 3,11,1667,0 |  FILEVERSION 3,11,1668,0 | ||||||
|  PRODUCTVERSION 3,11,1667,0 |  PRODUCTVERSION 3,11,1668,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -414,13 +414,13 @@ BEGIN | ||||||
|             VALUE "Comments", "https://rufus.ie" |             VALUE "Comments", "https://rufus.ie" | ||||||
|             VALUE "CompanyName", "Akeo Consulting" |             VALUE "CompanyName", "Akeo Consulting" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "3.11.1667" |             VALUE "FileVersion", "3.11.1668" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" |             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" | ||||||
|             VALUE "OriginalFilename", "rufus-3.11.exe" |             VALUE "OriginalFilename", "rufus-3.11.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "3.11.1667" |             VALUE "ProductVersion", "3.11.1668" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								src/stdio.c
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								src/stdio.c
									
										
									
									
									
								
							|  | @ -674,12 +674,26 @@ char* GuidToString(const GUID* guid) | ||||||
| 
 | 
 | ||||||
| 	if (guid == NULL) return NULL; | 	if (guid == NULL) return NULL; | ||||||
| 	sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", | 	sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", | ||||||
| 		(unsigned int)guid->Data1, guid->Data2, guid->Data3, | 		(uint32_t)guid->Data1, guid->Data2, guid->Data3, | ||||||
| 		guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], | 		guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], | ||||||
| 		guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); | 		guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); | ||||||
| 	return guid_string; | 	return guid_string; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | GUID* StringToGuid(const char* str) | ||||||
|  | { | ||||||
|  | 	static GUID guid; | ||||||
|  | 
 | ||||||
|  | 	if (str == NULL) return NULL; | ||||||
|  | 	if (sscanf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", | ||||||
|  | 		(uint32_t*)&guid.Data1, (uint32_t*)&guid.Data2, (uint32_t*)&guid.Data3, | ||||||
|  | 		(uint32_t*)&guid.Data4[0], (uint32_t*)&guid.Data4[1], (uint32_t*)&guid.Data4[2], | ||||||
|  | 		(uint32_t*)&guid.Data4[3], (uint32_t*)&guid.Data4[4], (uint32_t*)&guid.Data4[5], | ||||||
|  | 		(uint32_t*)&guid.Data4[6], (uint32_t*)&guid.Data4[7]) != 11) | ||||||
|  | 		return NULL; | ||||||
|  | 	return &guid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Find upper power of 2
 | // Find upper power of 2
 | ||||||
| static __inline uint16_t upo2(uint16_t v) | static __inline uint16_t upo2(uint16_t v) | ||||||
| { | { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue