[core] add a workaround for >1TB HDDs that mistakenly report short writes

* It appears that 1.5TB and 2TB HDDs, accessed trough some Seagate ow WD USB ↔ SATA
  controllers, can report that 0 bytes were written on WriteFile(), even though all
  the data was effectively written. 1TB HDDs, accessed through the same controller,
  do not report this issue. So add a workaround for that.
* Also see #787
This commit is contained in:
Pete Batard 2016-09-06 17:56:36 +01:00
parent 8ca644de5a
commit aa4baab194
7 changed files with 32 additions and 13 deletions

View File

@ -3,6 +3,7 @@ o Version 2.11 (2016.09.??)
Improve support for Arch Linux derivatives Improve support for Arch Linux derivatives
Add a cheat mode to disable drive indexing (Alt-Q) on format Add a cheat mode to disable drive indexing (Alt-Q) on format
Fix handling of 'Super Floppy Disk' formatted drives Fix handling of 'Super Floppy Disk' formatted drives
Fix handling of misleading short write reports for drives larger than 1 TB
Fix an issue that enabled FAT32 file system selection on some Windows images Fix an issue that enabled FAT32 file system selection on some Windows images
Fix broken UI font for XP users Fix broken UI font for XP users
Fix sanitizing of exFAT labels Fix sanitizing of exFAT labels

View File

@ -1557,6 +1557,9 @@ DWORD WINAPI FormatThread(void* param)
tt = GETTARGETTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); tt = GETTARGETTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
use_large_fat32 = (fs == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32)); use_large_fat32 = (fs == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32));
windows_to_go = (togo_mode) && HAS_TOGO(img_report) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED); windows_to_go = (togo_mode) && HAS_TOGO(img_report) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED);
large_drive = (SelectedDrive.DiskSize > (1*TB));
if (large_drive)
uprintf("Notice: Large drive detected (may produce short writes)");
// Find out if we need to add any extra partitions // Find out if we need to add any extra partitions
if ((windows_to_go) && (tt == TT_UEFI) && (pt == PARTITION_STYLE_GPT)) if ((windows_to_go) && (tt == TT_UEFI) && (pt == PARTITION_STYLE_GPT))
// According to Microsoft, every GPT disk (we RUN Windows from) must have an MSR due to not having hidden sectors // According to Microsoft, every GPT disk (we RUN Windows from) must have an MSR due to not having hidden sectors

View File

@ -47,12 +47,23 @@ int64_t write_sectors(HANDLE hDrive, uint64_t SectorSize,
return -1; return -1;
} }
if((!WriteFile(hDrive, pBuf, Size, &Size, NULL)) || (Size != nSectors*SectorSize)) if(!WriteFile(hDrive, pBuf, Size, &Size, NULL))
{ {
uprintf("write_sectors: Write error %s\n", (GetLastError()!=ERROR_SUCCESS)?WindowsErrorString():""); uprintf("write_sectors: Write error %s\n", WindowsErrorString());
uprintf(" Wrote: %d, Expected: %" PRIu64 "\n", Size, nSectors*SectorSize);
uprintf(" StartSector: 0x%08" PRIx64 ", nSectors: 0x%" PRIx64 ", SectorSize: 0x%" PRIx64 "\n", StartSector, nSectors, SectorSize); uprintf(" StartSector: 0x%08" PRIx64 ", nSectors: 0x%" PRIx64 ", SectorSize: 0x%" PRIx64 "\n", StartSector, nSectors, SectorSize);
return Size; return -1;
}
if (Size != nSectors*SectorSize)
{
/* Some large drives return 0, even though all the data was written - See github #787 */
if (large_drive && Size == 0) {
uprintf("Warning: Possible short write\n");
return 0;
}
uprintf("write_sectors:write error\n");
uprintf(" Wrote: %d, Expected: %" PRIu64 "\n", Size, nSectors*SectorSize);
uprintf(" StartSector: 0x%08" PRIx64 ", nSectors: 0x%" PRIx64 ", SectorSize: 0x%" PRIx64 "\n", StartSector, nSectors, SectorSize);
return -1;
} }
return (int64_t)Size; return (int64_t)Size;

View File

@ -109,7 +109,7 @@ BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, mbr_selected_by_user = FALSE, tog
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE, right_to_left_mode = FALSE; BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE, right_to_left_mode = FALSE;
BOOL enable_HDDs = FALSE, force_update = FALSE, enable_ntfs_compression = FALSE, no_confirmation_on_cancel = FALSE, lock_drive = TRUE; BOOL enable_HDDs = FALSE, force_update = FALSE, enable_ntfs_compression = FALSE, no_confirmation_on_cancel = FALSE, lock_drive = TRUE;
BOOL advanced_mode, allow_dual_uefi_bios, detect_fakes, enable_vmdk, force_large_fat32, usb_debug, use_fake_units, preserve_timestamps; BOOL advanced_mode, allow_dual_uefi_bios, detect_fakes, enable_vmdk, force_large_fat32, usb_debug, use_fake_units, preserve_timestamps;
BOOL zero_drive = FALSE, list_non_usb_removable_drives = FALSE, disable_file_indexing; BOOL zero_drive = FALSE, list_non_usb_removable_drives = FALSE, disable_file_indexing, large_drive = FALSE;
int dialog_showing = 0, lang_button_id = 0; int dialog_showing = 0, lang_button_id = 0;
uint16_t rufus_version[3], embedded_sl_version[2]; uint16_t rufus_version[3], embedded_sl_version[2];
char embedded_sl_version_str[2][12] = { "?.??", "?.??" }; char embedded_sl_version_str[2][12] = { "?.??", "?.??" };

View File

@ -372,7 +372,7 @@ extern BOOL PromptOnError;
extern unsigned long syslinux_ldlinux_len[2]; extern unsigned long syslinux_ldlinux_len[2];
extern const int nb_steps[FS_MAX]; extern const int nb_steps[FS_MAX];
extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, iso_op_in_progress, format_op_in_progress, right_to_left_mode; extern BOOL use_own_c32[NB_OLD_C32], detect_fakes, iso_op_in_progress, format_op_in_progress, right_to_left_mode;
extern BOOL allow_dual_uefi_bios, togo_mode; extern BOOL allow_dual_uefi_bios, togo_mode, large_drive;
extern RUFUS_IMG_REPORT img_report; extern RUFUS_IMG_REPORT img_report;
extern int64_t iso_blocking_status; extern int64_t iso_blocking_status;
extern uint16_t rufus_version[3], embedded_sl_version[2]; extern uint16_t rufus_version[3], embedded_sl_version[2];

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376 IDD_DIALOG DIALOGEX 12, 12, 242, 376
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 2.11.993" CAPTION "Rufus 2.11.994"
FONT 8, "Segoe UI Symbol", 400, 0, 0x0 FONT 8, "Segoe UI Symbol", 400, 0, 0x0
BEGIN BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@ -320,8 +320,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,11,993,0 FILEVERSION 2,11,994,0
PRODUCTVERSION 2,11,993,0 PRODUCTVERSION 2,11,994,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -338,13 +338,13 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "2.11.993" VALUE "FileVersion", "2.11.994"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2016 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe" VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "2.11.993" VALUE "ProductVersion", "2.11.994"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -336,10 +336,14 @@ BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
if (WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL)) { if (WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL)) {
if (nNumberOfBytesToWrite == *lpNumberOfBytesWritten) if (nNumberOfBytesToWrite == *lpNumberOfBytesWritten)
return TRUE; return TRUE;
// Some large drives return 0, even though all the data was written - See github #787 */
if (large_drive && (*lpNumberOfBytesWritten == 0)) {
uprintf("Warning: Possible short write");
return TRUE;
}
uprintf(" Wrote %d bytes but requested %d%s", *lpNumberOfBytesWritten, uprintf(" Wrote %d bytes but requested %d%s", *lpNumberOfBytesWritten,
nNumberOfBytesToWrite, nTry < nNumRetries ? retry_msg : ""); nNumberOfBytesToWrite, nTry < nNumRetries ? retry_msg : "");
} } else {
else {
uprintf(" Write error [0x%08X]%s", GetLastError(), nTry < nNumRetries ? retry_msg : ""); uprintf(" Write error [0x%08X]%s", GetLastError(), nTry < nNumRetries ? retry_msg : "");
} }
// If we can't reposition for the next run, just abort // If we can't reposition for the next run, just abort