From 7ae6715b557c1de5b9d5278d937121bf5c316fea Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 30 Nov 2011 02:14:59 +0000 Subject: [PATCH] [boot] write bootable mbr and fs_br (FAT32 only) --- license.h | 2 +- rufus.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++-------- rufus.rc | 12 ++++----- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/license.h b/license.h index 498e6e7f..e87eef01 100644 --- a/license.h +++ b/license.h @@ -26,7 +26,7 @@ const char* additional_copyrights = "http://pcunleashed.com\r\n" "Freeware\r\n" "\r\n" -"Boot record handling by ms-sys by Henrik Carlqvist:\r\n" +"Boot record handling from ms-sys by Henrik Carlqvist:\r\n" "http://ms-sys.sourceforge.net\r\n" "GNU General Public License (GPL) v2 or later\r\n" "\r\n" diff --git a/rufus.c b/rufus.c index b846de64..60abc5c4 100644 --- a/rufus.c +++ b/rufus.c @@ -706,13 +706,8 @@ static BOOL ProcessMBR(HANDLE hPhysicalDrive) BOOL r = FALSE; unsigned char* buf = NULL; size_t SecSize = SelectedDrive.Geometry.BytesPerSector; - size_t nSecs = 0x200/min(0x200, SelectedDrive.Geometry.BytesPerSector); - - if (SecSize * nSecs != 0x200) { - uprintf("Seriously? A drive where sector size is not a power of 2?!?\n"); - FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; - goto out; - } + size_t nSecs = (0x200 + SecSize -1) / SecSize; + FILE fake_fd; PrintStatus("Processing MBR...\n"); if (!AnalyzeMBR(hPhysicalDrive)) return FALSE; @@ -732,7 +727,7 @@ static BOOL ProcessMBR(HANDLE hPhysicalDrive) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; goto out; } - DumpBufferHex(buf, 0x200); +// DumpBufferHex(buf, 0x200); switch (ComboBox_GetCurSel(hFileSystem)) { // TODO: check for 0x06 & 0x0b? case FS_FAT16: @@ -742,14 +737,62 @@ static BOOL ProcessMBR(HANDLE hPhysicalDrive) buf[0x1c2] = 0x0c; break; } + if (IsChecked(IDC_DOSSTARTUP)) { + buf[0x1be] = 0x80; // Set first partition bootable + } - if (!write_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) { + if (!write_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize*nSecs)) { uprintf("Could not write MBR\n"); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; goto out; } - r = TRUE; + fake_fd._ptr = (char*)hPhysicalDrive; + fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; + r = write_95b_mbr(&fake_fd); + + if (!read_sectors(hPhysicalDrive, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize)) { + uprintf("Could not re-read MBR\n"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; + goto out; + } + DumpBufferHex(buf, 0x200); + +out: + safe_free(buf); + return r; +} + +static BOOL ProcessFS_BR(HANDLE hLogicalVolume) +{ + BOOL r = FALSE; + unsigned char* buf = NULL; + FILE fake_fd; + size_t SecSize = SelectedDrive.Geometry.BytesPerSector; + size_t nSecs = (0x400 + SecSize -1) / SecSize; + + fake_fd._ptr = (char*)hLogicalVolume; + fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; + write_fat_32_br(&fake_fd, 0); + + PrintStatus("Processing FS BR...\n"); + // FormatEx rewrites the MBR and removes the LBA attribute of FAT16 + // and FAT32 partitions - we need to correct this in the MBR + // TODO: something else for bootable GPT + buf = (unsigned char*)malloc(SecSize * nSecs); + if (buf == NULL) { + uprintf("Could not allocate memory for FS BR"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_ENOUGH_MEMORY; + goto out; + } + + if (!read_sectors(hLogicalVolume, SelectedDrive.Geometry.BytesPerSector, 0, nSecs, buf, SecSize*nSecs)) { + uprintf("Could not read FS BR\n"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_READ_FAULT; + goto out; + } + uprintf("FS_BR:\n"); + DumpBufferHex(buf, 0x400); out: safe_free(buf); @@ -854,8 +897,20 @@ static void __cdecl FormatThread(void* param) #endif if (IsChecked(IDC_DOSSTARTUP)) { + hLogicalVolume = GetDriveHandle(num, drive_name, TRUE, FALSE); + if (hLogicalVolume == INVALID_HANDLE_VALUE) { + uprintf("Could not re-mount volume\n"); + goto out; + } + ProcessFS_BR(hLogicalVolume); // TODO: check return value & set bootblock ExtractMSDOS(drive_name); + // TODO: + // http://www.multiboot.ru/msdos8.htm & http://en.wikipedia.org/wiki/Windows_Me#Real_mode_DOS + // COMMAND.COM and IO.SYS from diskcopy.dll are from the WinME crippled version of DOS + // that removed real mode DOS => they must be patched: + // IO.SYS 000003AA 75 -> EB + // COMMAND.COM 00006510 75 -> EB } out: diff --git a/rufus.rc b/rufus.rc index dd1f64d3..d20f9cfe 100644 --- a/rufus.rc +++ b/rufus.rc @@ -63,7 +63,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP CONTROL "https://github.com/pbatard/rufus",IDC_ABOUT_RUFUS_URL, "SysLink",WS_TABSTOP,46,47,114,9 - LTEXT "Version 1.0.0 (Build 49)",IDC_STATIC,46,19,78,8 + LTEXT "Version 1.0.0 (Build 50)",IDC_STATIC,46,19,78,8 PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 @@ -162,8 +162,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,49 - PRODUCTVERSION 1,0,0,49 + FILEVERSION 1,0,0,50 + PRODUCTVERSION 1,0,0,50 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -180,13 +180,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.0.0.49" + VALUE "FileVersion", "1.0.0.50" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.0.0.49" + VALUE "ProductVersion", "1.0.0.50" END END BLOCK "VarFileInfo" @@ -212,7 +212,7 @@ IDI_ICON ICON "rufus.ico" STRINGTABLE BEGIN - IDS_VERSION "Rufus v1.0.0.49" + IDS_VERSION "Rufus v1.0.0.50" END #endif // English resources