mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-25 12:14:33 -04:00
[core] split zeroing and dd write operations
* This is in preparation for async reads * Also move open/close image operations to WriteDrive() * Also increase DD buffer size to 32 MB to improve performance
This commit is contained in:
parent
d77a825ffd
commit
80eca5739d
5 changed files with 148 additions and 88 deletions
|
@ -11,7 +11,7 @@
|
||||||
<Identity
|
<Identity
|
||||||
Name="19453.net.Rufus"
|
Name="19453.net.Rufus"
|
||||||
Publisher="CN=7AC86D13-3E5A-491A-ADD5-80095C212740"
|
Publisher="CN=7AC86D13-3E5A-491A-ADD5-80095C212740"
|
||||||
Version="3.14.1774.0" />
|
Version="3.14.1775.0" />
|
||||||
|
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>Rufus</DisplayName>
|
<DisplayName>Rufus</DisplayName>
|
||||||
|
|
|
@ -748,9 +748,9 @@ BOOL VdsRescan(DWORD dwRescanType, DWORD dwSleepTime, BOOL bSilent)
|
||||||
BOOL DeletePartition(DWORD DriveIndex, ULONGLONG PartitionOffset, BOOL bSilent)
|
BOOL DeletePartition(DWORD DriveIndex, ULONGLONG PartitionOffset, BOOL bSilent)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_FALSE;
|
HRESULT hr = S_FALSE;
|
||||||
VDS_PARTITION_PROP* prop_array;
|
VDS_PARTITION_PROP* prop_array = NULL;
|
||||||
LONG i, prop_array_size;
|
LONG i, prop_array_size;
|
||||||
IVdsAdvancedDisk *pAdvancedDisk;
|
IVdsAdvancedDisk *pAdvancedDisk = NULL;
|
||||||
|
|
||||||
if (!GetVdsDiskInterface(DriveIndex, &IID_IVdsAdvancedDisk, (void**)&pAdvancedDisk, bSilent))
|
if (!GetVdsDiskInterface(DriveIndex, &IID_IVdsAdvancedDisk, (void**)&pAdvancedDisk, bSilent))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
216
src/format.c
216
src/format.c
|
@ -1484,12 +1484,13 @@ static int sector_write(int fd, const void* _buf, unsigned int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write an image file or zero a drive */
|
/* Write an image file or zero a drive */
|
||||||
static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
|
static BOOL WriteDrive(HANDLE hPhysicalDrive, BOOL bZeroDrive)
|
||||||
{
|
{
|
||||||
BOOL s, ret = FALSE;
|
BOOL s, ret = FALSE;
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
DWORD i, rSize, wSize, xSize, BufSize;
|
HANDLE hSourceImage = INVALID_HANDLE_VALUE;
|
||||||
uint64_t wb, target_size = hSourceImage?img_report.image_size:SelectedDrive.DiskSize;
|
DWORD i, read_size, write_size, comp_size, buf_size;
|
||||||
|
uint64_t wb, target_size = bZeroDrive ? SelectedDrive.DiskSize : img_report.image_size;
|
||||||
uint64_t cur_value, last_value = UINT64_MAX;
|
uint64_t cur_value, last_value = UINT64_MAX;
|
||||||
int64_t bled_ret;
|
int64_t bled_ret;
|
||||||
uint8_t* buffer = NULL;
|
uint8_t* buffer = NULL;
|
||||||
|
@ -1507,51 +1508,23 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
|
||||||
uprintf("Warning: Unable to rewind image position - wrong data might be copied!");
|
uprintf("Warning: Unable to rewind image position - wrong data might be copied!");
|
||||||
UpdateProgressWithInfoInit(NULL, FALSE);
|
UpdateProgressWithInfoInit(NULL, FALSE);
|
||||||
|
|
||||||
if (img_report.compression_type != BLED_COMPRESSION_NONE) {
|
if (bZeroDrive) {
|
||||||
uprintf("Writing compressed image:");
|
uprintf(fast_zeroing ? "Fast-zeroing drive:" : "Zeroing drive:");
|
||||||
sec_buf = (uint8_t*)_mm_malloc(SelectedDrive.SectorSize, SelectedDrive.SectorSize);
|
|
||||||
if (sec_buf == NULL) {
|
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_ENOUGH_MEMORY;
|
|
||||||
uprintf("Could not allocate disk write buffer");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
assert((uintptr_t)sec_buf % SelectedDrive.SectorSize == 0);
|
|
||||||
sec_buf_pos = 0;
|
|
||||||
bled_init(_uprintf, NULL, sector_write, update_progress, NULL, &FormatStatus);
|
|
||||||
bled_ret = bled_uncompress_with_handles(hSourceImage, hPhysicalDrive, img_report.compression_type);
|
|
||||||
bled_exit();
|
|
||||||
if ((bled_ret >= 0) && (sec_buf_pos != 0)) {
|
|
||||||
// A disk image that doesn't end up on disk boundary should be a rare
|
|
||||||
// enough case, so we dont bother checking the write operation and
|
|
||||||
// just issue a notice about it in the log.
|
|
||||||
uprintf("Notice: Compressed image data didn't end on block boundary.");
|
|
||||||
// Gonna assert that WriteFile() and _write() share the same file offset
|
|
||||||
WriteFile(hPhysicalDrive, sec_buf, SelectedDrive.SectorSize, &wSize, NULL);
|
|
||||||
}
|
|
||||||
safe_mm_free(sec_buf);
|
|
||||||
if ((bled_ret < 0) && (SCODE_CODE(FormatStatus) != ERROR_CANCELLED)) {
|
|
||||||
// Unfortunately, different compression backends return different negative error codes
|
|
||||||
uprintf("Could not write compressed image: %lld", bled_ret);
|
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uprintf(hSourceImage?"Writing Image:":fast_zeroing?"Fast-zeroing drive:":"Zeroing drive:");
|
|
||||||
// Our buffer size must be a multiple of the sector size and *ALIGNED* to the sector size
|
// Our buffer size must be a multiple of the sector size and *ALIGNED* to the sector size
|
||||||
BufSize = ((DD_BUFFER_SIZE + SelectedDrive.SectorSize - 1) / SelectedDrive.SectorSize) * SelectedDrive.SectorSize;
|
buf_size = ((DD_BUFFER_SIZE + SelectedDrive.SectorSize - 1) / SelectedDrive.SectorSize) * SelectedDrive.SectorSize;
|
||||||
buffer = (uint8_t*)_mm_malloc(BufSize, SelectedDrive.SectorSize);
|
buffer = (uint8_t*)_mm_malloc(buf_size, SelectedDrive.SectorSize);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_ENOUGH_MEMORY;
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_ENOUGH_MEMORY;
|
||||||
uprintf("Could not allocate disk write buffer");
|
uprintf("Could not allocate disk zeroing buffer");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
assert((uintptr_t)buffer % SelectedDrive.SectorSize == 0);
|
assert((uintptr_t)buffer % SelectedDrive.SectorSize == 0);
|
||||||
|
|
||||||
// Clear buffer
|
// Clear buffer
|
||||||
memset(buffer, fast_zeroing ? 0xff : 0x00, BufSize);
|
memset(buffer, fast_zeroing ? 0xff : 0x00, buf_size);
|
||||||
|
|
||||||
if (fast_zeroing) {
|
if (fast_zeroing) {
|
||||||
cmp_buffer = (uint32_t*)_mm_malloc(BufSize, SelectedDrive.SectorSize);
|
cmp_buffer = (uint32_t*)_mm_malloc(buf_size, SelectedDrive.SectorSize);
|
||||||
if (cmp_buffer == NULL) {
|
if (cmp_buffer == NULL) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_ENOUGH_MEMORY;
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_ENOUGH_MEMORY;
|
||||||
uprintf("Could not allocate disk comparison buffer");
|
uprintf("Could not allocate disk comparison buffer");
|
||||||
|
@ -1560,35 +1533,22 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
|
||||||
assert((uintptr_t)cmp_buffer % SelectedDrive.SectorSize == 0);
|
assert((uintptr_t)cmp_buffer % SelectedDrive.SectorSize == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't bother trying for something clever, using double buffering overlapped and whatnot:
|
read_size = buf_size;
|
||||||
// With Windows' default optimizations, sync read + sync write for sequential operations
|
for (wb = 0, write_size = 0; wb < target_size; wb += write_size) {
|
||||||
// will be as fast, if not faster, than whatever async scheme you can come up with.
|
UpdateProgressWithInfo(OP_FORMAT, fast_zeroing ? MSG_306 : MSG_286, wb, target_size);
|
||||||
rSize = BufSize;
|
|
||||||
for (wb = 0, wSize = 0; wb < target_size; wb += wSize) {
|
|
||||||
UpdateProgressWithInfo(OP_FORMAT, hSourceImage ? MSG_261 : fast_zeroing ? MSG_306 : MSG_286, wb, target_size);
|
|
||||||
cur_value = (wb * min(80, target_size)) / target_size;
|
cur_value = (wb * min(80, target_size)) / target_size;
|
||||||
if (cur_value != last_value) {
|
if (cur_value != last_value) {
|
||||||
last_value = cur_value;
|
last_value = cur_value;
|
||||||
uprintfs("+");
|
uprintfs("+");
|
||||||
}
|
}
|
||||||
if (hSourceImage != NULL) {
|
|
||||||
s = ReadFile(hSourceImage, buffer, BufSize, &rSize, NULL);
|
|
||||||
if (!s) {
|
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_READ_FAULT;
|
|
||||||
uprintf("Read error: %s", WindowsErrorString());
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (rSize == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Don't overflow our projected size (mostly for VHDs)
|
// Don't overflow our projected size (mostly for VHDs)
|
||||||
if (wb + rSize > target_size) {
|
if (wb + read_size > target_size) {
|
||||||
rSize = (DWORD)(target_size - wb);
|
read_size = (DWORD)(target_size - wb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteFile fails unless the size is a multiple of sector size
|
// WriteFile fails unless the size is a multiple of sector size
|
||||||
if (rSize % SelectedDrive.SectorSize != 0)
|
if (read_size % SelectedDrive.SectorSize != 0)
|
||||||
rSize = ((rSize + SelectedDrive.SectorSize - 1) / SelectedDrive.SectorSize) * SelectedDrive.SectorSize;
|
read_size = ((read_size + SelectedDrive.SectorSize - 1) / SelectedDrive.SectorSize) * SelectedDrive.SectorSize;
|
||||||
|
|
||||||
// Fast-zeroing: Depending on your hardware, reading from flash may be much faster than writing, so
|
// Fast-zeroing: Depending on your hardware, reading from flash may be much faster than writing, so
|
||||||
// we might speed things up by skipping empty blocks, or skipping the write if the data is the same.
|
// we might speed things up by skipping empty blocks, or skipping the write if the data is the same.
|
||||||
|
@ -1601,8 +1561,8 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
|
||||||
CHECK_FOR_USER_CANCEL;
|
CHECK_FOR_USER_CANCEL;
|
||||||
|
|
||||||
// Read block and compare against the block that needs to be written
|
// Read block and compare against the block that needs to be written
|
||||||
s = ReadFile(hPhysicalDrive, cmp_buffer, rSize, &xSize, NULL);
|
s = ReadFile(hPhysicalDrive, cmp_buffer, read_size, &comp_size, NULL);
|
||||||
if ((!s) || (xSize != rSize) ) {
|
if ((!s) || (comp_size != read_size)) {
|
||||||
uprintf("Read error: Could not read data for fast zeroing comparison - %s", WindowsErrorString());
|
uprintf("Read error: Could not read data for fast zeroing comparison - %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1612,10 +1572,10 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
|
||||||
// Check all bits are the same
|
// Check all bits are the same
|
||||||
if ((zero_data == 0) || (zero_data == 0xffffffff)) {
|
if ((zero_data == 0) || (zero_data == 0xffffffff)) {
|
||||||
// Compare the rest of the block against the first element
|
// Compare the rest of the block against the first element
|
||||||
for (i = 1; (i < rSize / sizeof(uint32_t)) && (cmp_buffer[i] == zero_data); i++);
|
for (i = 1; (i < read_size / sizeof(uint32_t)) && (cmp_buffer[i] == zero_data); i++);
|
||||||
if (i >= rSize / sizeof(uint32_t)) {
|
if (i >= read_size / sizeof(uint32_t)) {
|
||||||
// Block is empty, skip write
|
// Block is empty, skip write
|
||||||
wSize = rSize;
|
write_size = read_size;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1632,11 +1592,11 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
|
||||||
|
|
||||||
for (i = 1; i <= WRITE_RETRIES; i++) {
|
for (i = 1; i <= WRITE_RETRIES; i++) {
|
||||||
CHECK_FOR_USER_CANCEL;
|
CHECK_FOR_USER_CANCEL;
|
||||||
s = WriteFile(hPhysicalDrive, buffer, rSize, &wSize, NULL);
|
s = WriteFile(hPhysicalDrive, buffer, read_size, &write_size, NULL);
|
||||||
if ((s) && (wSize == rSize))
|
if ((s) && (write_size == read_size))
|
||||||
break;
|
break;
|
||||||
if (s)
|
if (s)
|
||||||
uprintf("Write error: Wrote %d bytes, expected %d bytes", wSize, rSize);
|
uprintf("Write error: Wrote %d bytes, expected %d bytes", write_size, read_size);
|
||||||
else
|
else
|
||||||
uprintf("Write error at sector %lld: %s", wb / SelectedDrive.SectorSize, WindowsErrorString());
|
uprintf("Write error at sector %lld: %s", wb / SelectedDrive.SectorSize, WindowsErrorString());
|
||||||
if (i < WRITE_RETRIES) {
|
if (i < WRITE_RETRIES) {
|
||||||
|
@ -1656,10 +1616,120 @@ static BOOL WriteDrive(HANDLE hPhysicalDrive, HANDLE hSourceImage)
|
||||||
if (i > WRITE_RETRIES)
|
if (i > WRITE_RETRIES)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
} else if (img_report.compression_type != BLED_COMPRESSION_NONE) {
|
||||||
|
uprintf("Writing compressed image:");
|
||||||
|
hSourceImage = CreateFileU(image_path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||||
|
if (hSourceImage == INVALID_HANDLE_VALUE) {
|
||||||
|
uprintf("Could not open image '%s': %s", image_path, WindowsErrorString());
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
sec_buf = (uint8_t*)_mm_malloc(SelectedDrive.SectorSize, SelectedDrive.SectorSize);
|
||||||
|
if (sec_buf == NULL) {
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
uprintf("Could not allocate disk write buffer");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
assert((uintptr_t)sec_buf % SelectedDrive.SectorSize == 0);
|
||||||
|
sec_buf_pos = 0;
|
||||||
|
bled_init(_uprintf, NULL, sector_write, update_progress, NULL, &FormatStatus);
|
||||||
|
bled_ret = bled_uncompress_with_handles(hSourceImage, hPhysicalDrive, img_report.compression_type);
|
||||||
|
bled_exit();
|
||||||
|
if ((bled_ret >= 0) && (sec_buf_pos != 0)) {
|
||||||
|
// A disk image that doesn't end up on disk boundary should be a rare
|
||||||
|
// enough case, so we dont bother checking the write operation and
|
||||||
|
// just issue a notice about it in the log.
|
||||||
|
uprintf("Notice: Compressed image data didn't end on block boundary.");
|
||||||
|
// Gonna assert that WriteFile() and _write() share the same file offset
|
||||||
|
WriteFile(hPhysicalDrive, sec_buf, SelectedDrive.SectorSize, &write_size, NULL);
|
||||||
|
}
|
||||||
|
safe_mm_free(sec_buf);
|
||||||
|
if ((bled_ret < 0) && (SCODE_CODE(FormatStatus) != ERROR_CANCELLED)) {
|
||||||
|
// Unfortunately, different compression backends return different negative error codes
|
||||||
|
uprintf("Could not write compressed image: %lld", bled_ret);
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hSourceImage = CreateFileU(image_path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
|
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||||
|
if (hSourceImage == INVALID_HANDLE_VALUE) {
|
||||||
|
uprintf("Could not open image '%s': %s", image_path, WindowsErrorString());
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_OPEN_FAILED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our buffer size must be a multiple of the sector size and *ALIGNED* to the sector size
|
||||||
|
buf_size = ((DD_BUFFER_SIZE + SelectedDrive.SectorSize - 1) / SelectedDrive.SectorSize) * SelectedDrive.SectorSize;
|
||||||
|
buffer = (uint8_t*)_mm_malloc(buf_size, SelectedDrive.SectorSize);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
uprintf("Could not allocate disk write buffer");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
assert((uintptr_t)buffer % SelectedDrive.SectorSize == 0);
|
||||||
|
|
||||||
|
// Don't bother trying for something clever, using double buffering overlapped and whatnot:
|
||||||
|
// With Windows' default optimizations, sync read + sync write for sequential operations
|
||||||
|
// will be as fast, if not faster, than whatever async scheme you can come up with.
|
||||||
|
read_size = buf_size;
|
||||||
|
for (wb = 0, write_size = 0; wb < target_size; wb += write_size) {
|
||||||
|
UpdateProgressWithInfo(OP_FORMAT, MSG_261, wb, target_size);
|
||||||
|
cur_value = (wb * min(80, target_size)) / target_size;
|
||||||
|
if (cur_value != last_value) {
|
||||||
|
last_value = cur_value;
|
||||||
|
uprintfs("+");
|
||||||
|
}
|
||||||
|
s = ReadFile(hSourceImage, buffer, buf_size, &read_size, NULL);
|
||||||
|
if (!s) {
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_READ_FAULT;
|
||||||
|
uprintf("Read error: %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (read_size == 0)
|
||||||
|
break;
|
||||||
|
// Don't overflow our projected size (mostly for VHDs)
|
||||||
|
if (wb + read_size > target_size) {
|
||||||
|
read_size = (DWORD)(target_size - wb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteFile fails unless the size is a multiple of sector size
|
||||||
|
if (read_size % SelectedDrive.SectorSize != 0)
|
||||||
|
read_size = ((read_size + SelectedDrive.SectorSize - 1) / SelectedDrive.SectorSize) * SelectedDrive.SectorSize;
|
||||||
|
|
||||||
|
for (i = 1; i <= WRITE_RETRIES; i++) {
|
||||||
|
CHECK_FOR_USER_CANCEL;
|
||||||
|
s = WriteFile(hPhysicalDrive, buffer, read_size, &write_size, NULL);
|
||||||
|
if ((s) && (write_size == read_size))
|
||||||
|
break;
|
||||||
|
if (s)
|
||||||
|
uprintf("Write error: Wrote %d bytes, expected %d bytes", write_size, read_size);
|
||||||
|
else
|
||||||
|
uprintf("Write error at sector %lld: %s", wb / SelectedDrive.SectorSize, WindowsErrorString());
|
||||||
|
if (i < WRITE_RETRIES) {
|
||||||
|
li.QuadPart = wb;
|
||||||
|
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000);
|
||||||
|
Sleep(WRITE_TIMEOUT);
|
||||||
|
if (!SetFilePointerEx(hPhysicalDrive, li, NULL, FILE_BEGIN)) {
|
||||||
|
uprintf("Write error: Could not reset position - %s", WindowsErrorString());
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_WRITE_FAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
Sleep(200);
|
||||||
|
}
|
||||||
|
if (i > WRITE_RETRIES)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
RefreshDriveLayout(hPhysicalDrive);
|
RefreshDriveLayout(hPhysicalDrive);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
|
safe_closehandle(hSourceImage);
|
||||||
safe_mm_free(buffer);
|
safe_mm_free(buffer);
|
||||||
safe_mm_free(cmp_buffer);
|
safe_mm_free(cmp_buffer);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1684,7 +1754,6 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
DWORD cr, DriveIndex = (DWORD)(uintptr_t)param, ClusterSize, Flags;
|
DWORD cr, DriveIndex = (DWORD)(uintptr_t)param, ClusterSize, Flags;
|
||||||
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
|
HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
|
||||||
HANDLE hLogicalVolume = INVALID_HANDLE_VALUE;
|
HANDLE hLogicalVolume = INVALID_HANDLE_VALUE;
|
||||||
HANDLE hSourceImage = INVALID_HANDLE_VALUE;
|
|
||||||
SYSTEMTIME lt;
|
SYSTEMTIME lt;
|
||||||
FILE* log_fd;
|
FILE* log_fd;
|
||||||
uint8_t *buffer = NULL, extra_partitions = 0;
|
uint8_t *buffer = NULL, extra_partitions = 0;
|
||||||
|
@ -1791,7 +1860,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zero_drive) {
|
if (zero_drive) {
|
||||||
WriteDrive(hPhysicalDrive, NULL);
|
WriteDrive(hPhysicalDrive, TRUE);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1875,15 +1944,7 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
|
|
||||||
// Write an image file
|
// Write an image file
|
||||||
if ((boot_type == BT_IMAGE) && write_as_image) {
|
if ((boot_type == BT_IMAGE) && write_as_image) {
|
||||||
hSourceImage = CreateFileU(image_path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
WriteDrive(hPhysicalDrive, FALSE);
|
||||||
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
||||||
if (hSourceImage == INVALID_HANDLE_VALUE) {
|
|
||||||
uprintf("Could not open image '%s': %s", image_path, WindowsErrorString());
|
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteDrive(hPhysicalDrive, hSourceImage);
|
|
||||||
|
|
||||||
// If the image contains a partition we might be able to access, try to re-mount it
|
// If the image contains a partition we might be able to access, try to re-mount it
|
||||||
safe_unlockclose(hPhysicalDrive);
|
safe_unlockclose(hPhysicalDrive);
|
||||||
|
@ -2188,7 +2249,6 @@ out:
|
||||||
}
|
}
|
||||||
safe_free(volume_name);
|
safe_free(volume_name);
|
||||||
safe_free(buffer);
|
safe_free(buffer);
|
||||||
safe_closehandle(hSourceImage);
|
|
||||||
safe_unlockclose(hLogicalVolume);
|
safe_unlockclose(hLogicalVolume);
|
||||||
safe_unlockclose(hPhysicalDrive); // This can take a while
|
safe_unlockclose(hPhysicalDrive); // This can take a while
|
||||||
if (IS_ERROR(FormatStatus)) {
|
if (IS_ERROR(FormatStatus)) {
|
||||||
|
|
|
@ -99,12 +99,12 @@
|
||||||
#define BADCLOCK_PATTERN_MLC {0x00, 0xff, 0x33, 0xcc}
|
#define BADCLOCK_PATTERN_MLC {0x00, 0xff, 0x33, 0xcc}
|
||||||
#define BADBLOCK_PATTERN_TLC {0x00, 0xff, 0x1c71c7, 0xe38e38}
|
#define BADBLOCK_PATTERN_TLC {0x00, 0xff, 0x1c71c7, 0xe38e38}
|
||||||
#define BADBLOCK_BLOCK_SIZE (128 * 1024)
|
#define BADBLOCK_BLOCK_SIZE (128 * 1024)
|
||||||
#define LARGE_FAT32_SIZE (32*1073741824LL) // Size at which we need to use fat32format
|
#define LARGE_FAT32_SIZE (32 * 1073741824LL) // Size at which we need to use fat32format
|
||||||
#define UDF_FORMAT_SPEED 3.1f // Speed estimate at which we expect UDF drives to be formatted (GB/s)
|
#define UDF_FORMAT_SPEED 3.1f // Speed estimate at which we expect UDF drives to be formatted (GB/s)
|
||||||
#define UDF_FORMAT_WARN 20 // Duration (in seconds) above which we warn about long UDF formatting times
|
#define UDF_FORMAT_WARN 20 // Duration (in seconds) above which we warn about long UDF formatting times
|
||||||
#define MAX_FAT32_SIZE 2.0f // Threshold above which we disable FAT32 formatting (in TB)
|
#define MAX_FAT32_SIZE 2.0f // Threshold above which we disable FAT32 formatting (in TB)
|
||||||
#define FAT32_CLUSTER_THRESHOLD 1.011f // For FAT32, cluster size changes don't occur at power of 2 boundaries but sligthly above
|
#define FAT32_CLUSTER_THRESHOLD 1.011f // For FAT32, cluster size changes don't occur at power of 2 boundaries but sligthly above
|
||||||
#define DD_BUFFER_SIZE 65536 // Minimum size of the buffer we use for DD operations
|
#define DD_BUFFER_SIZE (32 * 1024 * 1024) // Minimum size of buffer to use for DD operations
|
||||||
#define UBUFFER_SIZE 4096
|
#define UBUFFER_SIZE 4096
|
||||||
#define RSA_SIGNATURE_SIZE 256
|
#define RSA_SIGNATURE_SIZE 256
|
||||||
#define CBN_SELCHANGE_INTERNAL (CBN_SELCHANGE + 256)
|
#define CBN_SELCHANGE_INTERNAL (CBN_SELCHANGE + 256)
|
||||||
|
|
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.14.1774"
|
CAPTION "Rufus 3.14.1775"
|
||||||
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
|
||||||
|
@ -395,8 +395,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 3,14,1774,0
|
FILEVERSION 3,14,1775,0
|
||||||
PRODUCTVERSION 3,14,1774,0
|
PRODUCTVERSION 3,14,1775,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -414,13 +414,13 @@ BEGIN
|
||||||
VALUE "Comments", "https://rufus.ie"
|
VALUE "Comments", "https://rufus.ie"
|
||||||
VALUE "CompanyName", "Akeo Consulting"
|
VALUE "CompanyName", "Akeo Consulting"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "3.14.1774"
|
VALUE "FileVersion", "3.14.1775"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2021 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2021 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||||
VALUE "OriginalFilename", "rufus-3.14.exe"
|
VALUE "OriginalFilename", "rufus-3.14.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "3.14.1774"
|
VALUE "ProductVersion", "3.14.1775"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue