diff --git a/.vs/ms-sys.vcxproj b/.vs/ms-sys.vcxproj index ead1e5ac..a24b8efb 100644 --- a/.vs/ms-sys.vcxproj +++ b/.vs/ms-sys.vcxproj @@ -70,6 +70,8 @@ + + diff --git a/.vs/ms-sys.vcxproj.filters b/.vs/ms-sys.vcxproj.filters index f469421c..c714b2af 100644 --- a/.vs/ms-sys.vcxproj.filters +++ b/.vs/ms-sys.vcxproj.filters @@ -152,6 +152,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/ChangeLog.txt b/ChangeLog.txt index cb604143..351d037d 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,12 +1,13 @@ o Version 3.5 (2019.03.??) - Add a feature to download official retail Windows 8.1 or Windows 10 ISOs from Rufus + Add a feature to download official retail Windows 8.1 or Windows 10 ISOs Add Windows To Go support for MCT generated Windows ISOs Add a notice about the 'WppRecorder.sys' Microsoft bug for Windows 10 1809 ISOs Add a notice about trying to format a drive larger than 2 TB in MBR mode + Add a notice about Legacy boot when trying to boot UEFI-only media in Legacy mode Report the full PID and command line of detected blocking processes in the log Fix a potential silent abort when the drive is in use Fix 'Quick Format' option always being active - Fix potentially changing default file system selection after selecting an ISO + Fix some unwanted file system changes occurring after an ISO had been selected o Version 3.4 (2018.12.05) Set the default image selection directory to Downloads\ instead of My Documents\ diff --git a/res/mbr/gpt.S b/res/mbr/gpt.S new file mode 100644 index 00000000..4419238e --- /dev/null +++ b/res/mbr/gpt.S @@ -0,0 +1,100 @@ +/********************************************************************************/ +/* GPT - A protective MBR that displays a notice if a user attempts to boot a */ +/* GPT drive in BIOS/Legacy mode. */ +/* */ +/* Copyright (c) 2019 Pete Batard */ +/* */ +/* 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, either version 3 of the License, or (at your option) */ +/* any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, but WITHOUT */ +/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ +/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ +/* more details. */ +/* */ +/* You should have received a copy of the GNU General Public License along with */ +/* this program; if not, see . */ +/* */ +/********************************************************************************/ + +/********************************************************************************/ +/* GNU Assembler Settings: */ +/********************************************************************************/ +.intel_syntax noprefix +.code16 +/********************************************************************************/ + +/********************************************************************************/ +/* Constants: */ +/********************************************************************************/ +MBR_ADDR = 0x7c00 +MBR_SIZE = 0x200 +MBR_RESERVED = 0x1b8 # Start of the reserved section (partition table, etc.) +PT_MAX = 0x04 # Number of partition entries in the partition table +PT_ENTRY_SIZE = 0x10 # Size of a partition entry in the partition table + +/********************************************************************************/ +/* MBR: This section resides at 0x00007c00 and is exactly 512 bytes */ +/********************************************************************************/ +.section main, "ax" +.globl mbr +mbr: + inc cx + dec bx + inc bp + dec di + cld + xor ax, ax + mov ds, ax + mov si, offset sep + call print_string + mov si, offset hdr + call print_string + mov si, offset sep + call print_string + mov si, offset txt + call print_string + hlt + +print_string: + lodsb + cmp al, 0x00 + jz 0f + mov ah, 0x0e + mov bx, 0x0007 + int 0x10 + jmp print_string +0: ret + +/********************************************************************************/ +/* Data section */ +/********************************************************************************/ +sep: + .string "****************************************\r\n" +hdr: + .string "*** ERROR: LEGACY BOOT OF UEFI MEDIA ***\r\n" +txt: + .ascii "\r\n" \ + "This drive can only boot in UEFI mode.\r\n" \ + "It can not boot in BIOS/Legacy mode.\r\n" \ + "\r\n" \ + "If you want to boot this drive in BIOS/Legacy mode, you\r\n" \ + "should recreate it in Rufus using the following settings:\r\n" \ + "* Partition scheme -> MBR\r\n" \ + "* Target system -> BIOS...\r\n" \ + "\0" + +/********************************************************************************/ +/* From offset 0x1b8, the MBR contains the partition table and signature data */ +/********************************************************************************/ + .org MBR_RESERVED +disk_signature: + .space 0x04 +filler: + .space 0x02 +partition_table: + .space PT_ENTRY_SIZE * PT_MAX +mbr_signature: + .word 0xAA55 diff --git a/res/mbr/gpt.bin b/res/mbr/gpt.bin new file mode 100644 index 00000000..e3aee1cc Binary files /dev/null and b/res/mbr/gpt.bin differ diff --git a/src/format.c b/src/format.c index 26ee8274..1206213a 100644 --- a/src/format.c +++ b/src/format.c @@ -889,6 +889,15 @@ static BOOL WriteMBR(HANDLE hPhysicalDrive) if (SelectedDrive.SectorSize < 512) goto out; + if (pt == PARTITION_STYLE_GPT) { + // Add a notice in the protective MBR + fake_fd._handle = (char*)hPhysicalDrive; + set_bytes_per_sector(SelectedDrive.SectorSize); + uprintf(using_msg, "Rufus protective"); + r = write_rufus_gpt_mbr(fp); + goto notify; + } + // FormatEx rewrites the MBR and removes the LBA attribute of FAT16 // and FAT32 partitions - we need to correct this in the MBR buffer = (unsigned char*)_mm_malloc(SelectedDrive.SectorSize, 16); @@ -1018,6 +1027,9 @@ static BOOL WriteSBR(HANDLE hPhysicalDrive) FAKE_FD fake_fd = { 0 }; FILE* fp = (FILE*)&fake_fd; + if (pt == PARTITION_STYLE_GPT) + return TRUE; + fake_fd._handle = (char*)hPhysicalDrive; set_bytes_per_sector(SelectedDrive.SectorSize); // Ensure that we have sufficient space for the SBR @@ -1997,7 +2009,7 @@ DWORD WINAPI FormatThread(void* param) } // Thanks to Microsoft, we must fix the MBR AFTER the drive has been formatted - if (pt == PARTITION_STYLE_MBR) { + if ((pt == PARTITION_STYLE_MBR) || ((bt != BT_NON_BOOTABLE) && (pt == PARTITION_STYLE_GPT))) { PrintInfoDebug(0, MSG_228); // "Writing master boot record..." if ((!WriteMBR(hPhysicalDrive)) || (!WriteSBR(hPhysicalDrive))) { if (!IS_ERROR(FormatStatus)) diff --git a/src/ms-sys/br.c b/src/ms-sys/br.c index a6b6318d..ef7ed8bb 100644 --- a/src/ms-sys/br.c +++ b/src/ms-sys/br.c @@ -148,6 +148,15 @@ int is_rufus_mbr(FILE *fp) is_br(fp); } /* is_rufus_mbr */ +int is_rufus_gpt_mbr(FILE *fp) +{ +#include "mbr_gpt_rufus.h" + + return + contains_data(fp, 0x0, mbr_gpt_rufus_0x0, sizeof(mbr_gpt_rufus_0x0)) && + is_br(fp); +} /* is_rufus_gpt_mbr */ + int is_reactos_mbr(FILE *fp) { #include "mbr_reactos.h" @@ -289,6 +298,15 @@ int write_rufus_mbr(FILE *fp) write_bootmark(fp); } /* write_rufus_mbr */ +int write_rufus_gpt_mbr(FILE *fp) +{ +#include "mbr_gpt_rufus.h" + + return + write_data(fp, 0x0, mbr_gpt_rufus_0x0, sizeof(mbr_gpt_rufus_0x0)) && + write_bootmark(fp); +} /* write_rufus_gpt_mbr */ + int write_reactos_mbr(FILE *fp) { #include "mbr_reactos.h" diff --git a/src/ms-sys/inc/br.h b/src/ms-sys/inc/br.h index 16cdedb1..a4e3e9d1 100644 --- a/src/ms-sys/inc/br.h +++ b/src/ms-sys/inc/br.h @@ -54,6 +54,10 @@ int is_win7_mbr(FILE *fp); FALSE.The file position will change when this function is called! */ int is_rufus_mbr(FILE *fp); +/* returns TRUE if the file has a Rufus GPT master boot record, otherwise + FALSE.The file position will change when this function is called! */ +int is_rufus_gpt_mbr(FILE *fp); + /* returns TRUE if the file has a ReactOS master boot record, otherwise FALSE.The file position will change when this function is called! */ int is_reactos_mbr(FILE *fp); @@ -107,6 +111,10 @@ int write_win7_mbr(FILE *fp); FALSE */ int write_rufus_mbr(FILE *fp); +/* Writes a Rufus GPT master boot record to a file, returns TRUE on success, otherwise + FALSE */ +int write_rufus_gpt_mbr(FILE *fp); + /* Writes a ReactOS master boot record to a file, returns TRUE on success, otherwise FALSE */ int write_reactos_mbr(FILE *fp); diff --git a/src/ms-sys/inc/mbr_gpt_rufus.h b/src/ms-sys/inc/mbr_gpt_rufus.h new file mode 100644 index 00000000..2893d263 --- /dev/null +++ b/src/ms-sys/inc/mbr_gpt_rufus.h @@ -0,0 +1,41 @@ +/* + * Rufus Protective MBR for GPT systems + * https://github.com/pbatard/rufus/tree/master/res/mbr + * Copyright © 2019 Pete Batard + */ + +unsigned char mbr_gpt_rufus_0x0[] = { + 0x41, 0x4B, 0x45, 0x4F, 0xFC, 0x31, 0xC0, 0x8E, 0xD8, 0xBE, 0x31, 0x7C, + 0xE8, 0x13, 0x00, 0xBE, 0x5C, 0x7C, 0xE8, 0x0D, 0x00, 0xBE, 0x31, 0x7C, + 0xE8, 0x07, 0x00, 0xBE, 0x87, 0x7C, 0xE8, 0x01, 0x00, 0xF4, 0xAC, 0x3C, + 0x00, 0x74, 0x09, 0xB4, 0x0E, 0xBB, 0x07, 0x00, 0xCD, 0x10, 0xEB, 0xF2, + 0xC3, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x0D, 0x0A, 0x00, 0x2A, 0x2A, 0x2A, 0x20, + 0x45, 0x52, 0x52, 0x4F, 0x52, 0x3A, 0x20, 0x4C, 0x45, 0x47, 0x41, 0x43, + 0x59, 0x20, 0x42, 0x4F, 0x4F, 0x54, 0x20, 0x4F, 0x46, 0x20, 0x55, 0x45, + 0x46, 0x49, 0x20, 0x4D, 0x45, 0x44, 0x49, 0x41, 0x20, 0x2A, 0x2A, 0x2A, + 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x54, 0x68, 0x69, 0x73, 0x20, 0x64, 0x72, + 0x69, 0x76, 0x65, 0x20, 0x63, 0x61, 0x6E, 0x20, 0x6F, 0x6E, 0x6C, 0x79, + 0x20, 0x62, 0x6F, 0x6F, 0x74, 0x20, 0x69, 0x6E, 0x20, 0x55, 0x45, 0x46, + 0x49, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0A, 0x49, 0x74, 0x20, + 0x63, 0x61, 0x6E, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x62, 0x6F, 0x6F, 0x74, + 0x20, 0x69, 0x6E, 0x20, 0x42, 0x49, 0x4F, 0x53, 0x2F, 0x4C, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x20, 0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0A, 0x0D, + 0x0A, 0x49, 0x66, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x77, 0x61, 0x6E, 0x74, + 0x20, 0x74, 0x6F, 0x20, 0x62, 0x6F, 0x6F, 0x74, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x20, 0x64, 0x72, 0x69, 0x76, 0x65, 0x20, 0x69, 0x6E, 0x20, 0x42, + 0x49, 0x4F, 0x53, 0x2F, 0x4C, 0x65, 0x67, 0x61, 0x63, 0x79, 0x20, 0x6D, + 0x6F, 0x64, 0x65, 0x2C, 0x20, 0x79, 0x6F, 0x75, 0x0D, 0x0A, 0x73, 0x68, + 0x6F, 0x75, 0x6C, 0x64, 0x20, 0x72, 0x65, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x69, 0x6E, 0x20, 0x52, 0x75, 0x66, 0x75, + 0x73, 0x20, 0x75, 0x73, 0x69, 0x6E, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x6F, 0x6C, 0x6C, 0x6F, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3A, 0x0D, 0x0A, 0x2A, 0x20, 0x50, + 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73, 0x63, 0x68, + 0x65, 0x6D, 0x65, 0x20, 0x2D, 0x3E, 0x20, 0x4D, 0x42, 0x52, 0x0D, 0x0A, + 0x2A, 0x20, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x20, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6D, 0x20, 0x2D, 0x3E, 0x20, 0x42, 0x49, 0x4F, 0x53, 0x2E, + 0x2E, 0x2E, 0x0D, 0x0A, 0x00 +}; diff --git a/src/rufus.rc b/src/rufus.rc index 88db8349..dd1946eb 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.5.1472" +CAPTION "Rufus 3.5.1473" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -394,8 +394,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,5,1472,0 - PRODUCTVERSION 3,5,1472,0 + FILEVERSION 3,5,1473,0 + PRODUCTVERSION 3,5,1473,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -413,13 +413,13 @@ BEGIN VALUE "Comments", "https://akeo.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.5.1472" + VALUE "FileVersion", "3.5.1473" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus-3.5.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.5.1472" + VALUE "ProductVersion", "3.5.1473" END END BLOCK "VarFileInfo" diff --git a/src/ui.c b/src/ui.c index f5b297f8..13bf7b87 100644 --- a/src/ui.c +++ b/src/ui.c @@ -155,8 +155,10 @@ void GetMainButtonsWidth(HWND hDlg) MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2); bw = rc.right - rc.left; - for (i = 0; i < ARRAYSIZE(main_button_ids); i++) - bw = max(bw, GetTextWidth(hDlg, main_button_ids[i]) + cbw); + for (i = 0; i < ARRAYSIZE(main_button_ids); i++) { + // Make sure we add extra space for the SELECT split button (i == 0) if Fido is enabled + bw = max(bw, GetTextWidth(hDlg, main_button_ids[i]) + ((enable_fido && i == 0) ? (3 * cbw) / 2 : cbw)); + } // The 'CLOSE' button is also be used to display 'CANCEL' and we sometimes // want to add "DOWNLOAD" into the Select split button => measure that too. bw = max(bw, GetTextSize(GetDlgItem(hDlg, IDCANCEL), lmprintf(MSG_007)).cx + cbw);