mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] report write errors more explicitly
* Also issue a port cycle on ERROR_NOT_READY * Also run a check for conflicting processes during write retries
This commit is contained in:
		
							parent
							
								
									b7ab196a97
								
							
						
					
					
						commit
						d4a663991b
					
				
					 7 changed files with 95 additions and 58 deletions
				
			
		
							
								
								
									
										69
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										69
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -54,7 +54,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Globals |  * Globals | ||||||
|  */ |  */ | ||||||
| DWORD FormatStatus = 0; | DWORD FormatStatus = 0, LastWriteError = 0; | ||||||
| badblocks_report report = { 0 }; | badblocks_report report = { 0 }; | ||||||
| static uint64_t LastRefresh = 0; | static uint64_t LastRefresh = 0; | ||||||
| static float format_percent = 0.0f; | static float format_percent = 0.0f; | ||||||
|  | @ -843,7 +843,8 @@ static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi | ||||||
| 			if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize) { | 			if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize) { | ||||||
| 				if (j < WRITE_RETRIES) { | 				if (j < WRITE_RETRIES) { | ||||||
| 					uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000); | 					uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000); | ||||||
| 					Sleep(WRITE_TIMEOUT); | 					// Don't sit idly but use the downtime to check for conflicting processes...
 | ||||||
|  | 					Sleep(CheckDriveAccess(WRITE_TIMEOUT, FALSE)); | ||||||
| 				} else | 				} else | ||||||
| 					goto out; | 					goto out; | ||||||
| 			} | 			} | ||||||
|  | @ -856,7 +857,7 @@ static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi | ||||||
| 			if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize) { | 			if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != SectorSize) { | ||||||
| 				if (j < WRITE_RETRIES) { | 				if (j < WRITE_RETRIES) { | ||||||
| 					uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000); | 					uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000); | ||||||
| 					Sleep(WRITE_TIMEOUT); | 					Sleep(CheckDriveAccess(WRITE_TIMEOUT, FALSE)); | ||||||
| 				} else { | 				} else { | ||||||
| 					// Windows seems to be an ass about keeping a lock on a backup GPT,
 | 					// Windows seems to be an ass about keeping a lock on a backup GPT,
 | ||||||
| 					// so we try to be lenient about not being able to clear it.
 | 					// so we try to be lenient about not being able to clear it.
 | ||||||
|  | @ -1799,15 +1800,15 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 
 | 
 | ||||||
| 	// At this stage we have both a handle and a lock to the physical drive
 | 	// At this stage we have both a handle and a lock to the physical drive
 | ||||||
| 	if (!GetDriveLetters(DriveIndex, drive_letters)) { | 	if (!GetDriveLetters(DriveIndex, drive_letters)) { | ||||||
| 		uprintf("Failed to get a drive letter\n"); | 		uprintf("Failed to get a drive letter"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER); | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	if (drive_letters[0] == 0) { | 	if (drive_letters[0] == 0) { | ||||||
| 		uprintf("No drive letter was assigned...\n"); | 		uprintf("No drive letter was assigned..."); | ||||||
| 		drive_name[0] =  GetUnusedDriveLetter(); | 		drive_name[0] =  GetUnusedDriveLetter(); | ||||||
| 		if (drive_name[0] == 0) { | 		if (drive_name[0] == 0) { | ||||||
| 			uprintf("Could not find a suitable drive letter\n"); | 			uprintf("Could not find a suitable drive letter"); | ||||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER); | 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER); | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
|  | @ -1819,18 +1820,18 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 			if (bt == BT_IMAGE) { | 			if (bt == BT_IMAGE) { | ||||||
| 				// If we are using an image, check that it isn't located on the drive we are trying to format
 | 				// If we are using an image, check that it isn't located on the drive we are trying to format
 | ||||||
| 				if ((PathGetDriveNumberU(image_path) + 'A') == drive_letters[i-1]) { | 				if ((PathGetDriveNumberU(image_path) + 'A') == drive_letters[i-1]) { | ||||||
| 					uprintf("ABORTED: Cannot use an image that is located on the target drive!\n"); | 					uprintf("ABORTED: Cannot use an image that is located on the target drive!"); | ||||||
| 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | ||||||
| 					goto out; | 					goto out; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if (!DeleteVolumeMountPointA(drive_name)) { | 			if (!DeleteVolumeMountPointA(drive_name)) { | ||||||
| 				uprintf("Failed to delete mountpoint %s: %s\n", drive_name, WindowsErrorString()); | 				uprintf("Failed to delete mountpoint %s: %", drive_name, WindowsErrorString()); | ||||||
| 				// Try to continue. We will bail out if this causes an issue.
 | 				// Try to continue. We will bail out if this causes an issue.
 | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	uprintf("Will use '%c:' as volume mountpoint\n", drive_name[0]); | 	uprintf("Will use '%c:' as volume mountpoint", drive_name[0]); | ||||||
| 
 | 
 | ||||||
| 	// It kind of blows, but we have to relinquish access to the physical drive
 | 	// It kind of blows, but we have to relinquish access to the physical drive
 | ||||||
| 	// for VDS to be able to delete the partitions that reside on it...
 | 	// for VDS to be able to delete the partitions that reside on it...
 | ||||||
|  | @ -1848,14 +1849,14 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	// ...and get a lock to the logical drive so that we can actually write something
 | 	// ...and get a lock to the logical drive so that we can actually write something
 | ||||||
| 	hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE, !lock_drive); | 	hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE, !lock_drive); | ||||||
| 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | 	if (hLogicalVolume == INVALID_HANDLE_VALUE) { | ||||||
| 		uprintf("Could not lock volume\n"); | 		uprintf("Could not lock volume"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} else if (hLogicalVolume == NULL) { | 	} else if (hLogicalVolume == NULL) { | ||||||
| 		// NULL is returned for cases where the drive is not yet partitioned
 | 		// NULL is returned for cases where the drive is not yet partitioned
 | ||||||
| 		uprintf("Drive does not appear to be partitioned\n"); | 		uprintf("Drive does not appear to be partitioned"); | ||||||
| 	} else if (!UnmountVolume(hLogicalVolume)) { | 	} else if (!UnmountVolume(hLogicalVolume)) { | ||||||
| 		uprintf("Trying to continue regardless...\n"); | 		uprintf("Trying to continue regardless..."); | ||||||
| 	} | 	} | ||||||
| 	CHECK_FOR_USER_CANCEL; | 	CHECK_FOR_USER_CANCEL; | ||||||
| 
 | 
 | ||||||
|  | @ -1877,8 +1878,8 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	if ((bt != BT_IMAGE) || (img_report.is_iso && !write_as_image)) { | 	if ((bt != BT_IMAGE) || (img_report.is_iso && !write_as_image)) { | ||||||
| 		if ((!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, use_large_fat32)) || | 		if ((!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, use_large_fat32)) || | ||||||
| 			(!InitializeDisk(hPhysicalDrive))) { | 			(!InitializeDisk(hPhysicalDrive))) { | ||||||
| 			uprintf("Could not reset partitions\n"); | 			uprintf("Could not reset partitions"); | ||||||
| 			FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_PARTITION_FAILURE; | 			FormatStatus = (LastWriteError != 0) ? LastWriteError : (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE); | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -1897,16 +1898,16 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 				lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); | 				lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); | ||||||
| 			log_fd = fopenU(logfile, "w+"); | 			log_fd = fopenU(logfile, "w+"); | ||||||
| 			if (log_fd == NULL) { | 			if (log_fd == NULL) { | ||||||
| 				uprintf("Could not create log file for bad blocks check\n"); | 				uprintf("Could not create log file for bad blocks check"); | ||||||
| 			} else { | 			} else { | ||||||
| 				fprintf(log_fd, APPLICATION_NAME " bad blocks check started on: %04d.%02d.%02d %02d:%02d:%02d\n", | 				fprintf(log_fd, APPLICATION_NAME " bad blocks check started on: %04d.%02d.%02d %02d:%02d:%02d", | ||||||
| 				lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); | 				lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); | ||||||
| 				fflush(log_fd); | 				fflush(log_fd); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, (sel >= 2) ? 4 : sel +1, | 			if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, (sel >= 2) ? 4 : sel +1, | ||||||
| 				(sel < 2) ? 0 : sel - 2, &report, log_fd)) { | 				(sel < 2) ? 0 : sel - 2, &report, log_fd)) { | ||||||
| 				uprintf("Bad blocks: Check failed.\n"); | 				uprintf("Bad blocks: Check failed."); | ||||||
| 				if (!IS_ERROR(FormatStatus)) | 				if (!IS_ERROR(FormatStatus)) | ||||||
| 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_BADBLOCKS_FAILURE); | 					FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_BADBLOCKS_FAILURE); | ||||||
| 				ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, FALSE); | 				ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, FALSE); | ||||||
|  | @ -1914,7 +1915,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 				DeleteFileU(logfile); | 				DeleteFileU(logfile); | ||||||
| 				goto out; | 				goto out; | ||||||
| 			} | 			} | ||||||
| 			uprintf("Bad Blocks: Check completed, %d bad block%s found. (%d/%d/%d errors)\n", | 			uprintf("Bad Blocks: Check completed, %d bad block%s found. (%d/%d/%d errors)", | ||||||
| 				report.bb_count, (report.bb_count==1)?"":"s", | 				report.bb_count, (report.bb_count==1)?"":"s", | ||||||
| 				report.num_read_errors, report.num_write_errors, report.num_corruption_errors); | 				report.num_read_errors, report.num_write_errors, report.num_corruption_errors); | ||||||
| 			r = IDOK; | 			r = IDOK; | ||||||
|  | @ -1923,7 +1924,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 					report.num_corruption_errors); | 					report.num_corruption_errors); | ||||||
| 				fprintf(log_fd, bb_msg); | 				fprintf(log_fd, bb_msg); | ||||||
| 				GetLocalTime(<); | 				GetLocalTime(<); | ||||||
| 				fprintf(log_fd, APPLICATION_NAME " bad blocks check ended on: %04d.%02d.%02d %02d:%02d:%02d\n", | 				fprintf(log_fd, APPLICATION_NAME " bad blocks check ended on: %04d.%02d.%02d %02d:%02d:%02d", | ||||||
| 				lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); | 				lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); | ||||||
| 				fclose(log_fd); | 				fclose(log_fd); | ||||||
| 				r = MessageBoxExU(hMainDialog, lmprintf(MSG_012, bb_msg, logfile), | 				r = MessageBoxExU(hMainDialog, lmprintf(MSG_012, bb_msg, logfile), | ||||||
|  | @ -1942,7 +1943,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		// Especially after destructive badblocks test, you must zero the MBR/GPT completely
 | 		// Especially after destructive badblocks test, you must zero the MBR/GPT completely
 | ||||||
| 		// before repartitioning. Else, all kind of bad things happen.
 | 		// before repartitioning. Else, all kind of bad things happen.
 | ||||||
| 		if (!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, use_large_fat32)) { | 		if (!ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSize, SelectedDrive.SectorSize, use_large_fat32)) { | ||||||
| 			uprintf("unable to zero MBR/GPT\n"); | 			uprintf("unable to zero MBR/GPT"); | ||||||
| 			if (!IS_ERROR(FormatStatus)) | 			if (!IS_ERROR(FormatStatus)) | ||||||
| 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | ||||||
| 			goto out; | 			goto out; | ||||||
|  | @ -1969,7 +1970,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		if (GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_type, sizeof(fs_type), TRUE)) { | 		if (GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_type, sizeof(fs_type), TRUE)) { | ||||||
| 			guid_volume = GetLogicalName(DriveIndex, TRUE, TRUE); | 			guid_volume = GetLogicalName(DriveIndex, TRUE, TRUE); | ||||||
| 			if ((guid_volume != NULL) && (MountVolume(drive_name, guid_volume))) | 			if ((guid_volume != NULL) && (MountVolume(drive_name, guid_volume))) | ||||||
| 				uprintf("Remounted %s as %C:\n", guid_volume, drive_name[0]); | 				uprintf("Remounted %s as %C:", guid_volume, drive_name[0]); | ||||||
| 		} | 		} | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
|  | @ -1978,7 +1979,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	CHECK_FOR_USER_CANCEL; | 	CHECK_FOR_USER_CANCEL; | ||||||
| 
 | 
 | ||||||
| 	if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (tt==TT_UEFI), extra_partitions)) { | 	if (!CreatePartition(hPhysicalDrive, pt, fs, (pt==PARTITION_STYLE_MBR) && (tt==TT_UEFI), extra_partitions)) { | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE; | 		FormatStatus = (LastWriteError != 0) ? LastWriteError : (ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	UpdateProgress(OP_PARTITION, -1.0f); | 	UpdateProgress(OP_PARTITION, -1.0f); | ||||||
|  | @ -1987,7 +1988,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) { | 	if ((hLogicalVolume != NULL) && (hLogicalVolume != INVALID_HANDLE_VALUE)) { | ||||||
| 		PrintInfoDebug(0, MSG_227); | 		PrintInfoDebug(0, MSG_227); | ||||||
| 		if (!CloseHandle(hLogicalVolume)) { | 		if (!CloseHandle(hLogicalVolume)) { | ||||||
| 			uprintf("Could not close volume: %s\n", WindowsErrorString()); | 			uprintf("Could not close volume: %s", WindowsErrorString()); | ||||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED; | ||||||
| 			goto out; | 			goto out; | ||||||
| 		} | 		} | ||||||
|  | @ -1995,7 +1996,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	hLogicalVolume = INVALID_HANDLE_VALUE; | 	hLogicalVolume = INVALID_HANDLE_VALUE; | ||||||
| 
 | 
 | ||||||
| 	// Wait for the logical drive we just created to appear
 | 	// Wait for the logical drive we just created to appear
 | ||||||
| 	uprintf("Waiting for logical drive to reappear...\n"); | 	uprintf("Waiting for logical drive to reappear..."); | ||||||
| 	Sleep(200); | 	Sleep(200); | ||||||
| 	if (!WaitForLogical(DriveIndex)) | 	if (!WaitForLogical(DriveIndex)) | ||||||
| 		uprintf("Logical drive was not found!");	// We try to continue even if this fails, just in case
 | 		uprintf("Logical drive was not found!");	// We try to continue even if this fails, just in case
 | ||||||
|  | @ -2006,7 +2007,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 	ret = use_large_fat32?FormatFAT32(DriveIndex):FormatDrive(DriveIndex); | 	ret = use_large_fat32?FormatFAT32(DriveIndex):FormatDrive(DriveIndex); | ||||||
| 	if (!ret) { | 	if (!ret) { | ||||||
| 		// Error will be set by FormatDrive() in FormatStatus
 | 		// Error will be set by FormatDrive() in FormatStatus
 | ||||||
| 		uprintf("Format error: %s\n", StrError(FormatStatus, TRUE)); | 		uprintf("Format error: %s", StrError(FormatStatus, TRUE)); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -2027,11 +2028,11 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 
 | 
 | ||||||
| 	guid_volume = GetLogicalName(DriveIndex, TRUE, TRUE); | 	guid_volume = GetLogicalName(DriveIndex, TRUE, TRUE); | ||||||
| 	if (guid_volume == NULL) { | 	if (guid_volume == NULL) { | ||||||
| 		uprintf("Could not get GUID volume name\n"); | 		uprintf("Could not get GUID volume name"); | ||||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_VOLUME_ID; | 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NO_VOLUME_ID; | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	uprintf("Found volume GUID %s\n", guid_volume); | 	uprintf("Found volume GUID %s, guid_volume"); | ||||||
| 
 | 
 | ||||||
| 	if (!MountVolume(drive_name, guid_volume)) { | 	if (!MountVolume(drive_name, guid_volume)) { | ||||||
| 		uprintf("Could not remount %s as %C: %s\n", guid_volume, drive_name[0], WindowsErrorString()); | 		uprintf("Could not remount %s as %C: %s\n", guid_volume, drive_name[0], WindowsErrorString()); | ||||||
|  | @ -2076,7 +2077,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 			// => no need to reacquire the lock...
 | 			// => no need to reacquire the lock...
 | ||||||
| 			hLogicalVolume = GetLogicalHandle(DriveIndex, FALSE, TRUE, FALSE); | 			hLogicalVolume = GetLogicalHandle(DriveIndex, FALSE, TRUE, FALSE); | ||||||
| 			if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) { | 			if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL)) { | ||||||
| 				uprintf("Could not re-mount volume for partition boot record access\n"); | 				uprintf("Could not re-mount volume for partition boot record access"); | ||||||
| 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; | ||||||
| 				goto out; | 				goto out; | ||||||
| 			} | 			} | ||||||
|  | @ -2116,7 +2117,7 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 		} else if (bt == BT_GRUB4DOS) { | 		} else if (bt == BT_GRUB4DOS) { | ||||||
| 			grub4dos_dst[0] = drive_name[0]; | 			grub4dos_dst[0] = drive_name[0]; | ||||||
| 			IGNORE_RETVAL(_chdirU(app_dir)); | 			IGNORE_RETVAL(_chdirU(app_dir)); | ||||||
| 			uprintf("Installing: %s (Grub4DOS loader) %s\n", grub4dos_dst, | 			uprintf("Installing: %s (Grub4DOS loader) %s", grub4dos_dst, | ||||||
| 				IsFileInDB(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr")?"✓":"✗"); | 				IsFileInDB(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr")?"✓":"✗"); | ||||||
| 			if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE)) | 			if (!CopyFileU(FILES_DIR "\\grub4dos-" GRUB4DOS_VERSION "\\grldr", grub4dos_dst, FALSE)) | ||||||
| 				uprintf("Failed to copy file: %s", WindowsErrorString()); | 				uprintf("Failed to copy file: %s", WindowsErrorString()); | ||||||
|  | @ -2139,10 +2140,10 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 				} | 				} | ||||||
| 				if (HAS_KOLIBRIOS(img_report)) { | 				if (HAS_KOLIBRIOS(img_report)) { | ||||||
| 					kolibri_dst[0] = drive_name[0]; | 					kolibri_dst[0] = drive_name[0]; | ||||||
| 					uprintf("Installing: %s (KolibriOS loader)\n", kolibri_dst); | 					uprintf("Installing: %s (KolibriOS loader)", kolibri_dst); | ||||||
| 					if (ExtractISOFile(image_path, "HD_Load/USB_Boot/MTLD_F32", kolibri_dst, | 					if (ExtractISOFile(image_path, "HD_Load/USB_Boot/MTLD_F32", kolibri_dst, | ||||||
| 						FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM) == 0) { | 						FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM) == 0) { | ||||||
| 						uprintf("Warning: loader installation failed - KolibriOS will not boot!\n"); | 						uprintf("Warning: loader installation failed - KolibriOS will not boot!"); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				// EFI mode selected, with no 'boot###.efi' but Windows 7 x64's 'bootmgr.efi' (bit #0)
 | 				// EFI mode selected, with no 'boot###.efi' but Windows 7 x64's 'bootmgr.efi' (bit #0)
 | ||||||
|  | @ -2152,12 +2153,12 @@ DWORD WINAPI FormatThread(void* param) | ||||||
| 					efi_dst[0] = drive_name[0]; | 					efi_dst[0] = drive_name[0]; | ||||||
| 					efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0; | 					efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = 0; | ||||||
| 					if (!CreateDirectoryA(efi_dst, 0)) { | 					if (!CreateDirectoryA(efi_dst, 0)) { | ||||||
| 						uprintf("Could not create directory '%s': %s\n", efi_dst, WindowsErrorString()); | 						uprintf("Could not create directory '%s': %s", efi_dst, WindowsErrorString()); | ||||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | ||||||
| 					} else { | 					} else { | ||||||
| 						efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\'; | 						efi_dst[sizeof(efi_dst) - sizeof("\\bootx64.efi")] = '\\'; | ||||||
| 						if (!WimExtractFile(img_report.wininst_path[0], 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) { | 						if (!WimExtractFile(img_report.wininst_path[0], 1, "Windows\\Boot\\EFI\\bootmgfw.efi", efi_dst)) { | ||||||
| 							uprintf("Failed to setup Win7 EFI boot\n"); | 							uprintf("Failed to setup Win7 EFI boot"); | ||||||
| 							FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | 							FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | @ -2199,7 +2200,7 @@ out: | ||||||
| 		guid_volume = GetLogicalName(DriveIndex, TRUE, FALSE); | 		guid_volume = GetLogicalName(DriveIndex, TRUE, FALSE); | ||||||
| 		if (guid_volume != NULL) { | 		if (guid_volume != NULL) { | ||||||
| 			if (MountVolume(drive_name, guid_volume)) | 			if (MountVolume(drive_name, guid_volume)) | ||||||
| 				uprintf("Re-mounted volume as %C: after error\n", drive_name[0]); | 				uprintf("Re-mounted volume as %C: after error", drive_name[0]); | ||||||
| 			free(guid_volume); | 			free(guid_volume); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| /******************************************************************
 | /******************************************************************
 | ||||||
|     Copyright (C) 2009  Henrik Carlqvist |     Copyright (C) 2009  Henrik Carlqvist | ||||||
|     Modified for Rufus/Windows (C) 2011-2016  Pete Batard |     Modified for Rufus/Windows (C) 2011-2019  Pete Batard | ||||||
| 
 | 
 | ||||||
|     This program is free software; you can redistribute it and/or modify |     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 |     it under the terms of the GNU General Public License as published by | ||||||
|  | @ -47,8 +47,10 @@ int64_t write_sectors(HANDLE hDrive, uint64_t SectorSize, | ||||||
|       return -1; |       return -1; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    LastWriteError = 0; | ||||||
|    if(!WriteFile(hDrive, pBuf, Size, &Size, NULL)) |    if(!WriteFile(hDrive, pBuf, Size, &Size, NULL)) | ||||||
|    { |    { | ||||||
|  |       LastWriteError = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|GetLastError(); | ||||||
|       uprintf("write_sectors: Write error %s\n", WindowsErrorString()); |       uprintf("write_sectors: Write error %s\n", WindowsErrorString()); | ||||||
|       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 -1; |       return -1; | ||||||
|  | @ -60,7 +62,8 @@ int64_t write_sectors(HANDLE hDrive, uint64_t SectorSize, | ||||||
|          uprintf("Warning: Possible short write\n"); |          uprintf("Warning: Possible short write\n"); | ||||||
|          return 0; |          return 0; | ||||||
|       } |       } | ||||||
|       uprintf("write_sectors:write error\n"); |       uprintf("write_sectors: Write error\n"); | ||||||
|  |       LastWriteError = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_WRITE_FAULT; | ||||||
|       uprintf("  Wrote: %d, Expected: %" PRIu64 "\n", Size, nSectors*SectorSize); |       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 -1; |       return -1; | ||||||
|  |  | ||||||
|  | @ -679,7 +679,7 @@ BYTE SearchProcess(char* HandleName, DWORD dwTimeOut, BOOL bPartialMatch, BOOL b | ||||||
| 	if (res == WAIT_TIMEOUT) { | 	if (res == WAIT_TIMEOUT) { | ||||||
| 		// Timeout - kill the thread
 | 		// Timeout - kill the thread
 | ||||||
| 		TerminateThread(handle, 0); | 		TerminateThread(handle, 0); | ||||||
| 		uprintf("Warning: Conflicting process search failed to complete due to timeout"); | 		uprintf("Warning: Search for conflicting processes was interrupted due to timeout"); | ||||||
| 	} else if (res != WAIT_OBJECT_0) { | 	} else if (res != WAIT_OBJECT_0) { | ||||||
| 		TerminateThread(handle, 0); | 		TerminateThread(handle, 0); | ||||||
| 		uprintf("Warning: Failed to wait for conflicting process search thread: %s", WindowsErrorString()); | 		uprintf("Warning: Failed to wait for conflicting process search thread: %s", WindowsErrorString()); | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										37
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -1783,18 +1783,21 @@ static void SaveISO(void) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Check for conflicting processes accessing the drive, and if any,
 | // Check for conflicting processes accessing the drive.
 | ||||||
| // ask the user whether they want to proceed.
 | // If bPrompt is true, ask the user whether they want to proceed.
 | ||||||
| // Parameter is the maximum amount of time we allow for this call to execute (in ms)
 | // dwTimeOut is the maximum amount of time we allow for this call to execute (in ms)
 | ||||||
| static BOOL CheckDriveAccess(DWORD dwTimeOut) | // If bPrompt is false, the return value is the amount of time remaining before
 | ||||||
|  | // dwTimeOut would expire (or zero if we spent more than dwTimeout in this procedure).
 | ||||||
|  | // If bPrompt is true, the return value is 0 on error, non-zero on success.
 | ||||||
|  | DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt) | ||||||
| { | { | ||||||
| 	uint32_t i, j; | 	uint32_t i, j; | ||||||
| 	BOOL ret = FALSE, proceed = TRUE; | 	DWORD ret = 0, proceed = TRUE; | ||||||
| 	BYTE access_mask; | 	BYTE access_mask; | ||||||
| 	char *PhysicalPath = NULL, DevPath[MAX_PATH]; | 	char *PhysicalPath = NULL, DevPath[MAX_PATH]; | ||||||
| 	char drive_letter[27], drive_name[] = "?:"; | 	char drive_letter[27], drive_name[] = "?:"; | ||||||
| 	char title[128]; | 	char title[128]; | ||||||
| 	uint64_t cur_time, end_time = GetTickCount64() + dwTimeOut; | 	uint64_t start_time = GetTickCount64(), cur_time, end_time = start_time + dwTimeOut; | ||||||
| 
 | 
 | ||||||
| 	// Get the current selected device
 | 	// Get the current selected device
 | ||||||
| 	DWORD DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList)); | 	DWORD DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, ComboBox_GetCurSel(hDeviceList)); | ||||||
|  | @ -1802,6 +1805,7 @@ static BOOL CheckDriveAccess(DWORD dwTimeOut) | ||||||
| 		return FALSE; | 		return FALSE; | ||||||
| 
 | 
 | ||||||
| 	// "Checking for conflicting processes..."
 | 	// "Checking for conflicting processes..."
 | ||||||
|  | 	if (bPrompt) | ||||||
| 		PrintInfo(0, MSG_278); | 		PrintInfo(0, MSG_278); | ||||||
| 
 | 
 | ||||||
| 	// Search for any blocking processes against the physical drive
 | 	// Search for any blocking processes against the physical drive
 | ||||||
|  | @ -1839,11 +1843,16 @@ static BOOL CheckDriveAccess(DWORD dwTimeOut) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Prompt the user if we detected blocking processes
 | 	// Prompt the user if we detected blocking processes
 | ||||||
| 	if (!proceed) { | 	if (bPrompt && !proceed) { | ||||||
| 		ComboBox_GetTextU(hDeviceList, title, sizeof(title)); | 		ComboBox_GetTextU(hDeviceList, title, sizeof(title)); | ||||||
| 		proceed = Notification(MSG_WARNING_QUESTION, NULL, NULL, title, lmprintf(MSG_132)); | 		proceed = Notification(MSG_WARNING_QUESTION, NULL, NULL, title, lmprintf(MSG_132)); | ||||||
| 	} | 	} | ||||||
| 	ret = proceed; | 	if (bPrompt) { | ||||||
|  | 		ret = (DWORD)proceed; | ||||||
|  | 	} else { | ||||||
|  | 		ret = (DWORD)(GetTickCount64() - start_time); | ||||||
|  | 		ret = (dwTimeOut > ret) ? (dwTimeOut - ret) : 0; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| out: | out: | ||||||
| 	PrintInfo(0, MSG_210); | 	PrintInfo(0, MSG_210); | ||||||
|  | @ -2207,6 +2216,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 			// Disable all controls except Cancel
 | 			// Disable all controls except Cancel
 | ||||||
| 			EnableControls(FALSE); | 			EnableControls(FALSE); | ||||||
| 			FormatStatus = 0; | 			FormatStatus = 0; | ||||||
|  | 			LastWriteError = 0; | ||||||
| 			StrArrayClear(&BlockingProcess); | 			StrArrayClear(&BlockingProcess); | ||||||
| 			format_op_in_progress = TRUE; | 			format_op_in_progress = TRUE; | ||||||
| 			no_confirmation_on_cancel = FALSE; | 			no_confirmation_on_cancel = FALSE; | ||||||
|  | @ -2604,7 +2614,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (!CheckDriveAccess(2000)) | 		if (!CheckDriveAccess(CHECK_DRIVE_TIMEOUT, TRUE)) | ||||||
| 			goto aborted_start; | 			goto aborted_start; | ||||||
| 
 | 
 | ||||||
| 		GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp)); | 		GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp)); | ||||||
|  | @ -2712,10 +2722,19 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 				if (SCODE_CODE(FormatStatus) == ERROR_NOT_READY) { | ||||||
|  | 					// A port cycle usually helps with a device not ready
 | ||||||
|  | 					int index = ComboBox_GetCurSel(hDeviceList); | ||||||
|  | 					if (index >= 0) { | ||||||
|  | 						uprintf("Device not ready → Trying to cycle port..."); | ||||||
|  | 						ResetDevice(index); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
| 				Notification(MSG_ERROR, NULL, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus, FALSE))); | 				Notification(MSG_ERROR, NULL, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus, FALSE))); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		FormatStatus = 0; | 		FormatStatus = 0; | ||||||
|  | 		LastWriteError = 0; | ||||||
| 		format_op_in_progress = FALSE; | 		format_op_in_progress = FALSE; | ||||||
| 		return (INT_PTR)TRUE; | 		return (INT_PTR)TRUE; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -79,6 +79,7 @@ | ||||||
| #define WRITE_TIMEOUT               5000		// How long we should wait between write retries (in ms)
 | #define WRITE_TIMEOUT               5000		// How long we should wait between write retries (in ms)
 | ||||||
| #define SEARCH_PROCESS_TIMEOUT      10000		// How long we should search for conflicting processes before giving up (in ms)
 | #define SEARCH_PROCESS_TIMEOUT      10000		// How long we should search for conflicting processes before giving up (in ms)
 | ||||||
| #define NET_SESSION_TIMEOUT         3500		// How long we should wait to connect, send or receive internet data
 | #define NET_SESSION_TIMEOUT         3500		// How long we should wait to connect, send or receive internet data
 | ||||||
|  | #define CHECK_DRIVE_TIMEOUT         2000 | ||||||
| #define MARQUEE_TIMER_REFRESH       10			// Time between progress bar marquee refreshes, in ms
 | #define MARQUEE_TIMER_REFRESH       10			// Time between progress bar marquee refreshes, in ms
 | ||||||
| #define FS_DEFAULT                  FS_FAT32 | #define FS_DEFAULT                  FS_FAT32 | ||||||
| #define SINGLE_CLUSTERSIZE_DEFAULT  0x00000100 | #define SINGLE_CLUSTERSIZE_DEFAULT  0x00000100 | ||||||
|  | @ -445,7 +446,7 @@ extern HWND hMainDialog, hLogDialog, hStatus, hDeviceList, hCapacity; | ||||||
| extern HWND hPartitionScheme, hTargetSystem, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog; | extern HWND hPartitionScheme, hTargetSystem, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog; | ||||||
| extern HWND hInfo, hProgress, hDiskID; | extern HWND hInfo, hProgress, hDiskID; | ||||||
| extern WORD selected_langid; | extern WORD selected_langid; | ||||||
| extern DWORD FormatStatus, DownloadStatus, MainThreadId; | extern DWORD FormatStatus, DownloadStatus, MainThreadId, LastWriteError; | ||||||
| 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, large_drive, usb_debug; | extern BOOL allow_dual_uefi_bios, large_drive, usb_debug; | ||||||
| extern int64_t iso_blocking_status; | extern int64_t iso_blocking_status; | ||||||
|  | @ -571,6 +572,7 @@ extern char* GetCurrentMUI(void); | ||||||
| extern void SetAlertPromptMessages(void); | extern void SetAlertPromptMessages(void); | ||||||
| extern BOOL SetAlertPromptHook(void); | extern BOOL SetAlertPromptHook(void); | ||||||
| extern void ClrAlertPromptHook(void); | extern void ClrAlertPromptHook(void); | ||||||
|  | extern DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt); | ||||||
| extern BYTE SearchProcess(char* HandleName, DWORD dwTimeout, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet); | extern BYTE SearchProcess(char* HandleName, DWORD dwTimeout, BOOL bPartialMatch, BOOL bIgnoreSelf, BOOL bQuiet); | ||||||
| extern BOOL EnablePrivileges(void); | extern BOOL EnablePrivileges(void); | ||||||
| extern void FlashTaskbar(HANDLE handle); | extern void FlashTaskbar(HANDLE handle); | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | ||||||
| IDD_DIALOG DIALOGEX 12, 12, 232, 326 | IDD_DIALOG DIALOGEX 12, 12, 232, 326 | ||||||
| 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 3.6.1514" | CAPTION "Rufus 3.6.1515" | ||||||
| FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | FONT 9, "Segoe UI Symbol", 400, 0, 0x0 | ||||||
| BEGIN | BEGIN | ||||||
|     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP |     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP | ||||||
|  | @ -394,8 +394,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 3,6,1514,0 |  FILEVERSION 3,6,1515,0 | ||||||
|  PRODUCTVERSION 3,6,1514,0 |  PRODUCTVERSION 3,6,1515,0 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -413,13 +413,13 @@ BEGIN | ||||||
|             VALUE "Comments", "https://akeo.ie" |             VALUE "Comments", "https://akeo.ie" | ||||||
|             VALUE "CompanyName", "Akeo Consulting" |             VALUE "CompanyName", "Akeo Consulting" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "3.6.1514" |             VALUE "FileVersion", "3.6.1515" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus-3.6.exe" |             VALUE "OriginalFilename", "rufus-3.6.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "3.6.1514" |             VALUE "ProductVersion", "3.6.1515" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								src/stdio.c
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								src/stdio.c
									
										
									
									
									
								
							|  | @ -1,7 +1,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Rufus: The Reliable USB Formatting Utility |  * Rufus: The Reliable USB Formatting Utility | ||||||
|  * Standard User I/O Routines (logging, status, etc.) |  * Standard User I/O Routines (logging, status, etc.) | ||||||
|  * Copyright © 2011-2017 Pete Batard <pete@akeo.ie> |  * Copyright © 2011-2019 Pete Batard <pete@akeo.ie> | ||||||
|  * |  * | ||||||
|  * This program is free software: you can redistribute it and/or modify |  * 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 |  * it under the terms of the GNU General Public License as published by | ||||||
|  | @ -26,6 +26,7 @@ | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <assert.h> | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <math.h> | #include <math.h> | ||||||
| 
 | 
 | ||||||
|  | @ -144,17 +145,18 @@ void DumpBufferHex(void *buf, size_t size) | ||||||
| // Convert a windows error to human readable string
 | // Convert a windows error to human readable string
 | ||||||
| const char *WindowsErrorString(void) | const char *WindowsErrorString(void) | ||||||
| { | { | ||||||
| static char err_string[256] = {0}; | 	static char err_string[256] = { 0 }; | ||||||
| 
 | 
 | ||||||
| 	DWORD size; | 	DWORD size, presize; | ||||||
| 	DWORD error_code, format_error; | 	DWORD error_code, format_error; | ||||||
| 
 | 
 | ||||||
| 	error_code = GetLastError(); | 	error_code = GetLastError(); | ||||||
| 
 | 
 | ||||||
| 	static_sprintf(err_string, "[0x%08lX] ", error_code); | 	static_sprintf(err_string, "[0x%08lX] ", error_code); | ||||||
|  | 	presize = (DWORD)strlen(err_string); | ||||||
| 
 | 
 | ||||||
| 	size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, HRESULT_CODE(error_code), | 	size = FormatMessageU(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, HRESULT_CODE(error_code), | ||||||
| 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[strlen(err_string)], | 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &err_string[presize], | ||||||
| 		sizeof(err_string)-(DWORD)strlen(err_string), NULL); | 		sizeof(err_string)-(DWORD)strlen(err_string), NULL); | ||||||
| 	if (size == 0) { | 	if (size == 0) { | ||||||
| 		format_error = GetLastError(); | 		format_error = GetLastError(); | ||||||
|  | @ -163,6 +165,13 @@ static char err_string[256] = {0}; | ||||||
| 				error_code, format_error); | 				error_code, format_error); | ||||||
| 		else | 		else | ||||||
| 			static_sprintf(err_string, "Unknown error 0x%08lX", error_code); | 			static_sprintf(err_string, "Unknown error 0x%08lX", error_code); | ||||||
|  | 	} else { | ||||||
|  | 		// Microsoft may suffix CRLF to error messages, which we need to remove...
 | ||||||
|  | 		assert(presize > 2); | ||||||
|  | 		size += presize - 2; | ||||||
|  | 		// Cannot underflow if the above assert passed since our first char is neither of the following
 | ||||||
|  | 		while ((err_string[size] == 0x0D) || (err_string[size] == 0x0A) || (err_string[size] == 0x20)) | ||||||
|  | 			err_string[size--] = 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	SetLastError(error_code);	// Make sure we don't change the errorcode on exit
 | 	SetLastError(error_code);	// Make sure we don't change the errorcode on exit
 | ||||||
|  | @ -356,6 +365,7 @@ BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		if (WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL)) { | 		if (WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL)) { | ||||||
|  | 			LastWriteError = 0; | ||||||
| 			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 */
 | 			// Some large drives return 0, even though all the data was written - See github #787 */
 | ||||||
|  | @ -366,13 +376,15 @@ BOOL WriteFileWithRetry(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr | ||||||
| 			uprintf("Wrote %d bytes but requested %d", *lpNumberOfBytesWritten, nNumberOfBytesToWrite); | 			uprintf("Wrote %d bytes but requested %d", *lpNumberOfBytesWritten, nNumberOfBytesToWrite); | ||||||
| 		} else { | 		} else { | ||||||
| 			uprintf("Write error [0x%08X]", GetLastError()); | 			uprintf("Write error [0x%08X]", GetLastError()); | ||||||
|  | 			LastWriteError = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|GetLastError(); | ||||||
| 		} | 		} | ||||||
| 		// If we can't reposition for the next run, just abort
 | 		// If we can't reposition for the next run, just abort
 | ||||||
| 		if (!readFilePointer) | 		if (!readFilePointer) | ||||||
| 			break; | 			break; | ||||||
| 		if (nTry < nNumRetries) { | 		if (nTry < nNumRetries) { | ||||||
| 			uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000); | 			uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000); | ||||||
| 			Sleep(WRITE_TIMEOUT); | 			// Don't sit idly but use the downtime to check for conflicting processes...
 | ||||||
|  | 			Sleep(CheckDriveAccess(WRITE_TIMEOUT, FALSE)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (SCODE_CODE(GetLastError()) == ERROR_SUCCESS) | 	if (SCODE_CODE(GetLastError()) == ERROR_SUCCESS) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue