diff --git a/src/drive.c b/src/drive.c index 2ad0a634..f673a408 100644 --- a/src/drive.c +++ b/src/drive.c @@ -579,6 +579,10 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m } break; case PARTITION_STYLE_GPT: + // TODO: (?) As per MSDN: "When specifying a GUID partition table (GPT) as the PARTITION_STYLE of the CREATE_DISK + // structure, an application should wait for the MSR partition arrival before sending the IOCTL_DISK_SET_DRIVE_LAYOUT_EX + // control code. For more information about device notification, see RegisterDeviceNotification." + CreateDisk.PartitionStyle = PARTITION_STYLE_GPT; IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId)); CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS; @@ -681,17 +685,17 @@ BOOL DeletePartitions(HANDLE hDrive) { BOOL r; DWORD size; + CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}}; - PrintStatus(0, TRUE, "Erasing Partitions..."); + PrintStatus(0, TRUE, "Deleting partitions..."); - r = DeviceIoControl(hDrive, IOCTL_DISK_DELETE_DRIVE_LAYOUT, NULL, 0, NULL, 0, &size, NULL ); + size = sizeof(CreateDisk); + r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK, + (BYTE*)&CreateDisk, size, NULL, 0, &size, NULL ); if (!r) { - // Ignore GEN_FAILURE as this is what XP returns for unpartitioned - if (GetLastError() != ERROR_GEN_FAILURE) { - uprintf("Could not delete drive layout: %s\n", WindowsErrorString()); - safe_closehandle(hDrive); - return FALSE; - } + uprintf("Could not delete drive layout: %s\n", WindowsErrorString()); + safe_closehandle(hDrive); + return FALSE; } r = DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &size, NULL ); @@ -699,9 +703,9 @@ BOOL DeletePartitions(HANDLE hDrive) uprintf("Could not refresh drive layout: %s\n", WindowsErrorString()); safe_closehandle(hDrive); return FALSE; - } +} - return TRUE; +return TRUE; } /* diff --git a/src/format.c b/src/format.c index 683e8b78..aee94141 100644 --- a/src/format.c +++ b/src/format.c @@ -576,9 +576,9 @@ static BOOL FormatFAT32(DWORD DriveIndex) // Set the FAT32 volume label GetWindowTextW(hLabel, wLabel, ARRAYSIZE(wLabel)); ToValidLabel(wLabel, TRUE); + PrintStatus(0, TRUE, "Setting Label (This may take while)..."); // Handle must be closed for SetVolumeLabel to work safe_closehandle(hLogicalVolume); - PrintStatus(0, TRUE, "Setting Label (This may take while)..."); VolumeName = GetLogicalName(DriveIndex, TRUE, TRUE); wVolumeName = utf8_to_wchar(VolumeName); if ((wVolumeName == NULL) || (!SetVolumeLabelW(wVolumeName, wLabel))) { @@ -708,22 +708,22 @@ static BOOL AnalyzeMBR(HANDLE hPhysicalDrive) return FALSE; } if (is_dos_mbr(&fake_fd)) { - uprintf("Drive has a Microsoft DOS/NT/95A master boot record\n"); + uprintf("Drive has a DOS/NT/95A master boot record\n"); } else if (is_dos_f2_mbr(&fake_fd)) { - uprintf("Drive has a Microsoft DOS/NT/95A master boot record " + uprintf("Drive has a DOS/NT/95A master boot record " "with the undocumented F2 instruction\n"); } else if (is_95b_mbr(&fake_fd)) { - uprintf("Drive has a Microsoft 95B/98/98SE/ME master boot record\n"); + uprintf("Drive has a Windows 95B/98/98SE/ME master boot record\n"); } else if (is_2000_mbr(&fake_fd)) { - uprintf("Drive has a Microsoft 2000/XP/2003 master boot record\n"); + uprintf("Drive has a Windows 2000/XP/2003 master boot record\n"); } else if (is_vista_mbr(&fake_fd)) { - uprintf("Drive has a Microsoft Vista master boot record\n"); + uprintf("Drive has a Windows Vista master boot record\n"); } else if (is_win7_mbr(&fake_fd)) { - uprintf("Drive has a Microsoft 7 master boot record\n"); + uprintf("Drive has a Windows 7 master boot record\n"); } else if (is_zero_mbr(&fake_fd)) { uprintf("Drive has a zeroed non-bootable master boot record\n"); } else { - uprintf("Unknown boot record\n"); + uprintf("Drive has an unknown master boot record\n"); } return TRUE; } @@ -753,6 +753,8 @@ static BOOL AnalyzePBR(HANDLE hLogicalVolume) } else { uprintf("Drive has an unknown FAT16 or FAT32 partition boot record\n"); } + } else { + uprintf("Drive has an unknown partition boot record\n"); } return TRUE; } @@ -1260,14 +1262,14 @@ DWORD WINAPI FormatThread(LPVOID param) PrintStatus(0, TRUE, "Analyzing existing boot records...\n"); AnalyzeMBR(hPhysicalDrive); - if (hLogicalVolume != NULL) { + if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) { AnalyzePBR(hLogicalVolume); } UpdateProgress(OP_ANALYZE_MBR, -1.0f); - // Zap any existing partitions. This should help to prevent access errors - // TODO: With this, we should be able to avoid having to deal with the logical volume above - if (!DeletePartitions(hPhysicalDrive)) { + // Zap any existing partitions. This helps prevent access errors. + // As this creates issues with FAT16 formatted MS drives, only do this for other filesystems + if ( (fs != FS_FAT16) && (!DeletePartitions(hPhysicalDrive)) ) { uprintf("Could not reset partitions\n"); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE; goto out; @@ -1333,7 +1335,7 @@ DWORD WINAPI FormatThread(LPVOID param) } } // Close the (unmounted) volume before formatting - if (hLogicalVolume != NULL) { + if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) { PrintStatus(0, TRUE, "Closing existing volume...\n"); if (!CloseHandle(hLogicalVolume)) { uprintf("Could not close volume: %s\n", WindowsErrorString()); @@ -1346,7 +1348,7 @@ DWORD WINAPI FormatThread(LPVOID param) // TODO: (v1.4) Our start button should become cancel instead of close // Especially after destructive badblocks test, you must zero the MBR/GPT completely - // before repartitioning. Else, all kind of bad things can happen. + // before repartitioning. Else, all kind of bad things happen. if (!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.Geometry.BytesPerSector)) { uprintf("unable to zero MBR/GPT\n"); if (!IS_ERROR(FormatStatus)) diff --git a/src/icon.c b/src/icon.c index 81293c93..793101b1 100644 --- a/src/icon.c +++ b/src/icon.c @@ -160,7 +160,7 @@ BOOL SetAutorun(const char* path) char filename[64]; wchar_t wlabel[128], wRufusVersion[32]; - safe_sprintf(filename, sizeof(filename), "%s\\autorun.inf", path); + safe_sprintf(filename, sizeof(filename), "%sautorun.inf", path); fd = fopen(filename, "r"); // If there's an existing autorun, don't overwrite if (fd != NULL) { uprintf("%s already exists - keeping it\n", filename); diff --git a/src/msapi_utf8.h b/src/msapi_utf8.h index b187d75d..80dce69b 100644 --- a/src/msapi_utf8.h +++ b/src/msapi_utf8.h @@ -45,6 +45,7 @@ extern "C" { MultiByteToWideChar(CP_UTF8, 0, src, -1, wdest, wdest_size) #define Edit_ReplaceSelU(hCtrl, str) ((void)SendMessageLU(hCtrl, EM_REPLACESEL, (WPARAM)FALSE, str)) #define ComboBox_AddStringU(hCtrl, str) ((int)(DWORD)SendMessageLU(hCtrl, CB_ADDSTRING, (WPARAM)FALSE, str)) +#define ComboBox_InsertStringU(hCtrl, index, str) ((int)(DWORD)SendMessageLU(hCtrl, CB_INSERTSTRING, (WPARAM)index, str)) #define ComboBox_GetTextU(hCtrl, str, max_str) GetWindowTextU(hCtrl, str, max_str) #define GetSaveFileNameU(p) GetOpenSaveFileNameU(p, TRUE) #define GetOpenFileNameU(p) GetOpenSaveFileNameU(p, FALSE) diff --git a/src/rufus.c b/src/rufus.c index 16260c42..8398ff54 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -94,7 +94,7 @@ static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes" static const char* BiosTypeLabel[BT_MAX] = { "BIOS", "UEFI" }; static const char* PartitionTypeLabel[2] = { "MBR", "GPT" }; static BOOL existing_key = FALSE; // For LGP set/restore -static BOOL iso_size_check = TRUE; +static BOOL size_check = TRUE; static BOOL log_displayed = FALSE; static BOOL iso_provided = FALSE; extern BOOL force_large_fat32; @@ -160,7 +160,7 @@ static BOOL DefineClusterSizes(void) default_fs = FS_UNKNOWN; memset(&SelectedDrive.ClusterSize, 0, sizeof(SelectedDrive.ClusterSize)); if (SelectedDrive.DiskSize < 8*MB) { - uprintf("This application does not support volumes smaller than 8 MB\n"); + uprintf("Device was eliminated because it is smaller than 8 MB\n"); goto out; } @@ -211,8 +211,11 @@ static BOOL DefineClusterSizes(void) // > 32GB FAT32 is not supported by MS and FormatEx but is achieved using fat32format // See: http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm // < 32 MB FAT32 is not allowed by FormatEx, so we don't bother + // We also found issues with > 1TB drives, so we use our own max threshold (can be disabled with Alt-S) + if ((size_check) && (1.0f*SelectedDrive.DiskSize >= 1.0f*MAX_FAT32_SIZE*TB)) + uprintf("FAT32 support is disabled for this device, as it is larger than %.1f TB\n", 1.0f*MAX_FAT32_SIZE); - if ((SelectedDrive.DiskSize >= 32*MB) && (SelectedDrive.DiskSize < 2*TB)) { + if ((SelectedDrive.DiskSize >= 32*MB) && ((!size_check) || (1.0f*SelectedDrive.DiskSize < 1.0f*MAX_FAT32_SIZE*TB))) { SelectedDrive.ClusterSize[FS_FAT32].Allowed = 0x000001F8; for (i=32; i<=(32*1024); i<<=1) { // 32 MB -> 32 GB if (SelectedDrive.DiskSize < i*MB) { @@ -625,7 +628,7 @@ static BOOL GetUSBDevices(DWORD devnum) if(GetLastError() != ERROR_NO_MORE_ITEMS) { uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString()); } else { - uprintf("A device was eliminated because it didn't report itself as a removable disk\n"); + uprintf("A device was eliminated because it didn't report itself as a non fixed USB disk\n"); } break; } @@ -1183,7 +1186,7 @@ static BOOL BootCheck(void) "No ISO image selected", MB_OK|MB_ICONERROR); return FALSE; } - if ((iso_size_check) && (iso_report.projected_size > (uint64_t)SelectedDrive.DiskSize)) { + if ((size_check) && (iso_report.projected_size > (uint64_t)SelectedDrive.DiskSize)) { MessageBoxU(hMainDialog, "This ISO image is too big " "for the selected target.", "ISO image too big", MB_OK|MB_ICONERROR); return FALSE; @@ -1828,7 +1831,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA uprintf("\r\n"); GetUSBDevices(DeviceNum); if (!IS_ERROR(FormatStatus)) { - // This is the only way to achieve instantanenous progress transition to 100% + // This is the only way to achieve instantaneous progress transition to 100% SendMessage(hProgress, PBM_SETRANGE, 0, ((MAX_PROGRESS+1)<<16) & 0xFFFF0000); SendMessage(hProgress, PBM_SETPOS, (MAX_PROGRESS+1), 0); SendMessage(hProgress, PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000); @@ -2024,8 +2027,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine // By default, Rufus will not copy ISOs that are larger than in size than // the target USB drive. If this is enabled, the size check is disabled. if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'S')) { - iso_size_check = !iso_size_check; - PrintStatus2000("ISO size check", iso_size_check); + size_check = !size_check; + PrintStatus2000("Size checks", size_check); + GetUSBDevices(0); continue; } // Alt-F => Toggle detection of fixed disks diff --git a/src/rufus.h b/src/rufus.h index 53aa6568..106adf25 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -36,8 +36,8 @@ #define STR_NO_LABEL "NO_LABEL" #define RUFUS_CANCELBOX_TITLE APPLICATION_NAME " - Cancellation" #define RUFUS_BLOCKING_IO_TITLE APPLICATION_NAME " - Flushing buffers" -#define DRIVE_ACCESS_TIMEOUT 10000 // How long we should retry drive access (in ms) -#define DRIVE_ACCESS_RETRIES 20 // How many times we should retry +#define DRIVE_ACCESS_TIMEOUT 15000 // How long we should retry drive access (in ms) +#define DRIVE_ACCESS_RETRIES 60 // How many times we should retry #define DRIVE_INDEX_MIN 0x00000080 #define DRIVE_INDEX_MAX 0x000000C0 #define MAX_DRIVES (DRIVE_INDEX_MAX - DRIVE_INDEX_MIN) @@ -51,6 +51,7 @@ #define PROPOSEDLABEL_TOLERANCE 0.10 #define FS_DEFAULT FS_FAT32 #define LARGE_FAT32_SIZE (32*1073741824LL) // Size at which we need to use fat32format +#define MAX_FAT32_SIZE 1.0f // Threshold above which we disable FAT32 formatting (in TB) #define WHITE RGB(255,255,255) #define SEPARATOR_GREY RGB(223,223,223) #define RUFUS_URL "http://rufus.akeo.ie" diff --git a/src/rufus.rc b/src/rufus.rc index 748fb8f1..35ce00ee 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -30,7 +30,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 206, 329 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_APPWINDOW -CAPTION "Rufus v1.3.4.263" +CAPTION "Rufus v1.3.4.267" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,291,50,14 @@ -277,8 +277,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,4,263 - PRODUCTVERSION 1,3,4,263 + FILEVERSION 1,3,4,267 + PRODUCTVERSION 1,3,4,267 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -295,13 +295,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.3.4.263" + VALUE "FileVersion", "1.3.4.267" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2013 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.3.4.263" + VALUE "ProductVersion", "1.3.4.267" END END BLOCK "VarFileInfo" diff --git a/src/stdio.c b/src/stdio.c index e8e81a33..bfc7bbef 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -249,6 +249,8 @@ const char* StrError(DWORD error_code) return "Read error."; case ERROR_WRITE_FAULT: return "Write error."; + case ERROR_INSTALL_FAILURE: + return "Installation failure"; case ERROR_OPEN_FAILED: return "Could not open media. It may be in use by another process. " "Please re-plug the media and try again."; diff --git a/src/syslinux.c b/src/syslinux.c index 0b621b75..f01f7984 100644 --- a/src/syslinux.c +++ b/src/syslinux.c @@ -146,7 +146,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter) /* Reopen the volume (we already have a lock) */ d_handle = GetLogicalHandle(drive_index, TRUE, FALSE); if (d_handle == INVALID_HANDLE_VALUE) { - uprintf("Could open volume for syslinux operation\n"); + uprintf("Could open volume for Syslinux installation\n"); goto out; } @@ -156,6 +156,10 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter) if (sectors == NULL) goto out; fs = libfat_open(libfat_readfile, (intptr_t) d_handle); + if (fs == NULL) { + uprintf("Syslinux FAT access error\n"); + goto out; + } ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", NULL); secp = sectors; nsectors = 0; @@ -199,7 +203,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter) !WriteFile(d_handle, sectbuf, SECTOR_SIZE, &bytes_written, NULL) || bytes_written != SECTOR_SIZE) { - uprintf("Could not write boot record: %s\n", WindowsErrorString()); + uprintf("Could not write Syslinux boot record: %s\n", WindowsErrorString()); goto out; } @@ -208,7 +212,7 @@ BOOL InstallSyslinux(DWORD drive_index, char drive_letter) if (dt == DT_SYSLINUX_V5) { fd = fopen(ldlinux_c32, "rb"); if (fd == NULL) { - uprintf("Caution: No '%s' was provided. The target will be missing a mandatory Syslinux file!\n", ldlinux_c32); + uprintf("Caution: No '%s' was provided. The target will be missing a required Syslinux file!\n", ldlinux_c32); } else { fclose(fd); ldlinux_path[11] = 'c'; ldlinux_path[12] = '3'; ldlinux_path[13] = '2'; diff --git a/src/syslinux/libfat/open.c b/src/syslinux/libfat/open.c index 43c4b085..ebc94f17 100644 --- a/src/syslinux/libfat/open.c +++ b/src/syslinux/libfat/open.c @@ -92,10 +92,13 @@ libfat_open(int (*readfunc) (intptr_t, void *, size_t, libfat_sector_t), } else goto barf; /* Impossibly many clusters */ + /* This check doesn't hold for Large FAT32 => remove it */ +#if 0 minfatsize = (minfatsize + LIBFAT_SECTOR_SIZE - 1) >> LIBFAT_SECTOR_SHIFT; if (minfatsize > fatsize) goto barf; /* The FATs don't fit */ +#endif if (fs->fat_type == FAT28) fs->rootcluster = read32(&bs->u.fat32.bpb_rootclus);