From 3f0d5746574fd302f8530b3de3aea00e0844fb8a Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Sat, 15 Aug 2020 14:57:48 +0100 Subject: [PATCH] [misc] improve ToggleEsp() call to take an offset * Also fix a MinGW warning --- src/drive.c | 109 +++++++++++++++++++++++++++++---------------------- src/drive.h | 2 +- src/rufus.c | 2 +- src/rufus.rc | 10 ++--- 4 files changed, 69 insertions(+), 54 deletions(-) diff --git a/src/drive.c b/src/drive.c index 85a15e38..4f1c8ecc 100644 --- a/src/drive.c +++ b/src/drive.c @@ -73,6 +73,7 @@ PF_TYPE_DECL(NTAPI, NTSTATUS, NtQueryVolumeInformationFile, (HANDLE, PIO_STATUS_ */ RUFUS_DRIVE_INFO SelectedDrive; extern BOOL installed_uefi_ntfs, write_as_esp; +extern int nWindowsVersion; uint64_t partition_offset[3]; uint64_t persistence_size = 0; @@ -1198,7 +1199,7 @@ static BOOL ClearEspInfo(uint8_t index) * 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) +BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset) { char *volume_name, mount_point[] = DEFAULT_ESP_MOUNT_POINT; BOOL r, ret = FALSE, found = FALSE; @@ -1208,7 +1209,7 @@ BOOL ToggleEsp(DWORD DriveIndex) GUID* guid; PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; - if (nWindowsVersion < WINDOWS_10) { + if ((PartitionOffset == 0) && (nWindowsVersion < WINDOWS_10)) { uprintf("ESP toggling is only available for Windows 10 or later"); return FALSE; } @@ -1223,50 +1224,62 @@ BOOL ToggleEsp(DWORD DriveIndex) uprintf("Could not get layout for drive 0x%02x: %s", DriveIndex, WindowsErrorString()); goto out; } + // TODO: Handle MBR 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)) { - found = TRUE; - break; - } - } - if (found) - break; + if (PartitionOffset == 0) { + // 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 > MAX_ESP_TOGGLE) + + if (j > 1) { + uprintf("ESP toggling is not available for drives with more than one ESP"); goto out; - DriveLayout->PartitionEntry[i].Gpt.PartitionType = PARTITION_GENERIC_ESP; + } + 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)) { + found = TRUE; + break; + } + } + if (found) + break; + } + } + if (j > MAX_ESP_TOGGLE) + goto out; + DriveLayout->PartitionEntry[i].Gpt.PartitionType = PARTITION_GENERIC_ESP; + } + } else { + for (i = 0, j = 0; i < DriveLayout->PartitionCount; i++) { + if (DriveLayout->PartitionEntry[i].StartingOffset.QuadPart == PartitionOffset) + DriveLayout->PartitionEntry[i].Gpt.PartitionType = PARTITION_GENERIC_ESP; + } + } + if (i >= DriveLayout->PartitionCount) { + uprintf("No partition to toggle"); + goto out; } DriveLayout->PartitionEntry[i].RewritePartition = TRUE; // Just in case @@ -1276,14 +1289,16 @@ BOOL ToggleEsp(DWORD DriveIndex) goto out; } 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); - IGNORE_RETVAL(MountVolume(mount_point, volume_name)); - free(volume_name); + if (PartitionOffset == 0) { + 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); + IGNORE_RETVAL(MountVolume(mount_point, volume_name)); + free(volume_name); + } } ret = TRUE; @@ -1521,8 +1536,8 @@ BOOL UnmountVolume(HANDLE hDrive) BOOL MountVolume(char* drive_name, char *volume_name) { char mounted_guid[52]; - char mounted_letter[27] = { 0 }; #if defined(WINDOWS_IS_NOT_BUGGY) + char mounted_letter[27] = { 0 }; DWORD size; #endif diff --git a/src/drive.h b/src/drive.h index b4f5e0e2..99d9cde7 100644 --- a/src/drive.h +++ b/src/drive.h @@ -400,4 +400,4 @@ BOOL CyclePort(int index); int CycleDevice(int index); BOOL RefreshLayout(DWORD DriveIndex); BOOL GetOpticalMedia(IMG_SAVE* img_save); -BOOL ToggleEsp(DWORD DriveIndex); +BOOL ToggleEsp(DWORD DriveIndex, uint64_t PartitionOffset); diff --git a/src/rufus.c b/src/rufus.c index 45c8916d..c170759f 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -3640,7 +3640,7 @@ relaunch: if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'P')) { int index = ComboBox_GetCurSel(hDeviceList); DWORD DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, index); - if (ToggleEsp(DeviceNum)) + if (ToggleEsp(DeviceNum, 0)) CyclePort(index); continue; } diff --git a/src/rufus.rc b/src/rufus.rc index 5e5ea417..06c2a5dd 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.12.1694" +CAPTION "Rufus 3.12.1695" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -395,8 +395,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,12,1694,0 - PRODUCTVERSION 3,12,1694,0 + FILEVERSION 3,12,1695,0 + PRODUCTVERSION 3,12,1695,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -414,13 +414,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.12.1694" + VALUE "FileVersion", "3.12.1695" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.12.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.12.1694" + VALUE "ProductVersion", "3.12.1695" END END BLOCK "VarFileInfo"