"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/format.c" between
rufus-3.12.tar.gz and rufus-3.13.tar.gz

About: Rufus is a utility that helps format and create bootable USB flash drives, such as USB keys/pendrives, memory sticks, etc (for Linux and Windows).

format.c  (rufus-3.12):format.c  (rufus-3.13)
skipping to change at line 708 skipping to change at line 708
r = TRUE; r = TRUE;
} }
out: out:
return r; return r;
} }
static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi ze, BOOL add1MB) static BOOL ClearMBRGPT(HANDLE hPhysicalDrive, LONGLONG DiskSize, DWORD SectorSi ze, BOOL add1MB)
{ {
BOOL r = FALSE; BOOL r = FALSE;
uint64_t i, j, last_sector = DiskSize/SectorSize, num_sectors_to_clear; uint64_t i, last_sector = DiskSize/SectorSize, num_sectors_to_clear;
unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1); unsigned char* pBuf = (unsigned char*) calloc(SectorSize, 1);
PrintInfoDebug(0, MSG_224); PrintInfoDebug(0, MSG_224);
if (pBuf == NULL) { if (pBuf == NULL) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_N OT_ENOUGH_MEMORY; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_N OT_ENOUGH_MEMORY;
goto out; goto out;
} }
// http://en.wikipedia.org/wiki/GUID_Partition_Table tells us we should c lear 34 sectors at the // http://en.wikipedia.org/wiki/GUID_Partition_Table tells us we should c lear 34 sectors at the
// beginning and 33 at the end. We bump these values to MAX_SECTORS_TO_CL EAR each end to help // beginning and 33 at the end. We bump these values to MAX_SECTORS_TO_CL EAR each end to help
// with reluctant access to large drive. // with reluctant access to large drive.
skipping to change at line 732 skipping to change at line 732
// Also, for various reasons (one of which being that Windows seems to ha ve issues // Also, for various reasons (one of which being that Windows seems to ha ve issues
// with GPT drives that contain a lot of small partitions) we try not not to clear // with GPT drives that contain a lot of small partitions) we try not not to clear
// sectors further than the lowest partition already residing on the disk . // sectors further than the lowest partition already residing on the disk .
num_sectors_to_clear = min(SelectedDrive.FirstDataSector, (DWORD)((add1MB ? 2048 : 0) + MAX_SECTORS_TO_CLEAR)); num_sectors_to_clear = min(SelectedDrive.FirstDataSector, (DWORD)((add1MB ? 2048 : 0) + MAX_SECTORS_TO_CLEAR));
// Special case for big floppy disks (FirstDataSector = 0) // Special case for big floppy disks (FirstDataSector = 0)
if (num_sectors_to_clear < 4) if (num_sectors_to_clear < 4)
num_sectors_to_clear = (DWORD)((add1MB ? 2048 : 0) + MAX_SECTORS_ TO_CLEAR); num_sectors_to_clear = (DWORD)((add1MB ? 2048 : 0) + MAX_SECTORS_ TO_CLEAR);
uprintf("Erasing %d sectors", num_sectors_to_clear); uprintf("Erasing %d sectors", num_sectors_to_clear);
for (i = 0; i < num_sectors_to_clear; i++) { for (i = 0; i < num_sectors_to_clear; i++) {
for (j = 1; j <= WRITE_RETRIES; j++) { CHECK_FOR_USER_CANCEL;
CHECK_FOR_USER_CANCEL; if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != Sect
if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) orSize)
== SectorSize) goto out;
break;
if (j >= WRITE_RETRIES)
goto out;
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000
);
// Don't sit idly but use the downtime to check for confl
icting processes...
Sleep(CheckDriveAccess(WRITE_TIMEOUT, FALSE));
}
} }
for (i = last_sector - MAX_SECTORS_TO_CLEAR; i < last_sector; i++) { for (i = last_sector - MAX_SECTORS_TO_CLEAR; i < last_sector; i++) {
for (j = 1; j <= WRITE_RETRIES; j++) { CHECK_FOR_USER_CANCEL;
CHECK_FOR_USER_CANCEL; // Windows seems to be an ass about keeping a lock on a backup GP
if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) T,
== SectorSize) // so we try to be lenient about not being able to clear it.
break; if (write_sectors(hPhysicalDrive, SectorSize, i, 1, pBuf) != Sect
if (j >= WRITE_RETRIES) { orSize)
// Windows seems to be an ass about keeping a loc break;
k on a backup GPT,
// so we try to be lenient about not being able t
o clear it.
uprintf("Warning: Failed to clear backup GPT...")
;
r = TRUE;
goto out;
}
uprintf("Retrying in %d seconds...", WRITE_TIMEOUT / 1000
);
Sleep(CheckDriveAccess(WRITE_TIMEOUT, FALSE));
}
} }
r = TRUE; r = TRUE;
out: out:
safe_free(pBuf); safe_free(pBuf);
return r; return r;
} }
/* /*
* Process the Master Boot Record * Process the Master Boot Record
skipping to change at line 1442 skipping to change at line 1426
if (use_esp) { if (use_esp) {
Sleep(200); Sleep(200);
AltUnmountVolume(ms_efi, FALSE); AltUnmountVolume(ms_efi, FALSE);
} }
return TRUE; return TRUE;
} }
static void update_progress(const uint64_t processed_bytes) static void update_progress(const uint64_t processed_bytes)
{ {
// NB: We don't really care about resetting this value to UINT64_MAX for
a new pass.
static uint64_t last_value = UINT64_MAX;
uint64_t cur_value;
UpdateProgressWithInfo(OP_FORMAT, MSG_261, processed_bytes, img_report.im age_size); UpdateProgressWithInfo(OP_FORMAT, MSG_261, processed_bytes, img_report.im age_size);
cur_value = (processed_bytes * min(80, img_report.image_size)) / img_repo
rt.image_size;
if (cur_value != last_value) {
last_value = cur_value;
uprintfs("+");
}
} }
// Some compressed images use streams that aren't multiple of the sector // Some compressed images use streams that aren't multiple of the sector
// size and cause write failures => Use a write override that alleviates // size and cause write failures => Use a write override that alleviates
// the problem. See GitHub issue #1422 for details. // the problem. See GitHub issue #1422 for details.
static int sector_write(int fd, const void* _buf, unsigned int count) static int sector_write(int fd, const void* _buf, unsigned int count)
{ {
const uint8_t* buf = (const uint8_t*)_buf; const uint8_t* buf = (const uint8_t*)_buf;
unsigned int sec_size = (unsigned int)SelectedDrive.SectorSize; unsigned int sec_size = (unsigned int)SelectedDrive.SectorSize;
int written, fill_size = 0; int written, fill_size = 0;
skipping to change at line 1497 skipping to change at line 1490
if (sec_buf_pos != 0) if (sec_buf_pos != 0)
memcpy(sec_buf, &buf[fill_size + written], sec_buf_pos); memcpy(sec_buf, &buf[fill_size + written], sec_buf_pos);
return (int)count; return (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, HANDLE hSourceImage)
{ {
BOOL s, ret = FALSE; BOOL s, ret = FALSE;
LARGE_INTEGER li; LARGE_INTEGER li;
DWORD rSize, wSize, xSize, BufSize; DWORD i, rSize, wSize, xSize, BufSize;
uint64_t wb, target_size = hSourceImage?img_report.image_size:SelectedDri ve.DiskSize; uint64_t wb, target_size = hSourceImage?img_report.image_size:SelectedDri ve.DiskSize;
uint64_t cur_value, last_value = UINT64_MAX;
int64_t bled_ret; int64_t bled_ret;
uint8_t *buffer = NULL; uint8_t* buffer = NULL;
uint8_t *cmp_buffer = NULL; uint32_t zero_data, *cmp_buffer = NULL;
int i, *ptr, zero_data, throttle_fast_zeroing = 0; int throttle_fast_zeroing = 0;
if (SelectedDrive.SectorSize < 512) {
uprintf("Unexpected sector size (%d) - Aborting", SelectedDrive.S
ectorSize);
return FALSE;
}
// We poked the MBR and other stuff, so we need to rewind // We poked the MBR and other stuff, so we need to rewind
li.QuadPart = 0; li.QuadPart = 0;
if (!SetFilePointerEx(hPhysicalDrive, li, NULL, FILE_BEGIN)) if (!SetFilePointerEx(hPhysicalDrive, li, NULL, FILE_BEGIN))
uprintf("Warning: Unable to rewind image position - wrong data mi ght be copied!"); uprintf("Warning: Unable to rewind image position - wrong data mi ght be copied!");
UpdateProgressWithInfoInit(NULL, FALSE); UpdateProgressWithInfoInit(NULL, FALSE);
if (img_report.compression_type != BLED_COMPRESSION_NONE) { if (img_report.compression_type != BLED_COMPRESSION_NONE) {
uprintf("Writing compressed image..."); uprintf("Writing compressed image:");
sec_buf = (uint8_t*)_mm_malloc(SelectedDrive.SectorSize, Selected Drive.SectorSize); sec_buf = (uint8_t*)_mm_malloc(SelectedDrive.SectorSize, Selected Drive.SectorSize);
if (sec_buf == NULL) { if (sec_buf == NULL) {
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAG E) | ERROR_NOT_ENOUGH_MEMORY; FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAG E) | ERROR_NOT_ENOUGH_MEMORY;
uprintf("Could not allocate disk write buffer"); uprintf("Could not allocate disk write buffer");
goto out; goto out;
} }
assert((uintptr_t)sec_buf % SelectedDrive.SectorSize == 0); assert((uintptr_t)sec_buf % SelectedDrive.SectorSize == 0);
sec_buf_pos = 0; sec_buf_pos = 0;
bled_init(_uprintf, NULL, sector_write, update_progress, NULL, &F ormatStatus); bled_init(_uprintf, NULL, sector_write, update_progress, NULL, &F ormatStatus);
bled_ret = bled_uncompress_with_handles(hSourceImage, hPhysicalDr ive, img_report.compression_type); bled_ret = bled_uncompress_with_handles(hSourceImage, hPhysicalDr ive, img_report.compression_type);
skipping to change at line 1539 skipping to change at line 1538
WriteFile(hPhysicalDrive, sec_buf, SelectedDrive.SectorSi ze, &wSize, NULL); WriteFile(hPhysicalDrive, sec_buf, SelectedDrive.SectorSi ze, &wSize, NULL);
} }
safe_mm_free(sec_buf); safe_mm_free(sec_buf);
if ((bled_ret < 0) && (SCODE_CODE(FormatStatus) != ERROR_CANCELLE D)) { if ((bled_ret < 0) && (SCODE_CODE(FormatStatus) != ERROR_CANCELLE D)) {
// Unfortunately, different compression backends return d ifferent negative error codes // Unfortunately, different compression backends return d ifferent negative error codes
uprintf("Could not write compressed image: %lld", bled_re t); uprintf("Could not write compressed image: %lld", bled_re t);
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAG E) | ERROR_WRITE_FAULT; FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAG E) | ERROR_WRITE_FAULT;
goto out; goto out;
} }
} else { } else {
uprintf(hSourceImage?"Writing Image...":fast_zeroing?"Fast-zeroin g drive...":"Zeroing drive..."); uprintf(hSourceImage?"Writing Image:":fast_zeroing?"Fast-zeroing drive:":"Zeroing drive:");
// Our buffer size must be a multiple of the sector size and *ALI GNED* to the sector size // Our buffer size must be a multiple of the sector size and *ALI GNED* to the sector size
BufSize = ((DD_BUFFER_SIZE + SelectedDrive.SectorSize - 1) / Sele ctedDrive.SectorSize) * SelectedDrive.SectorSize; BufSize = ((DD_BUFFER_SIZE + SelectedDrive.SectorSize - 1) / Sele ctedDrive.SectorSize) * SelectedDrive.SectorSize;
buffer = (uint8_t*)_mm_malloc(BufSize, SelectedDrive.SectorSize); buffer = (uint8_t*)_mm_malloc(BufSize, SelectedDrive.SectorSize);
if (buffer == NULL) { if (buffer == NULL) {
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAG E) | ERROR_NOT_ENOUGH_MEMORY; FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAG E) | ERROR_NOT_ENOUGH_MEMORY;
uprintf("Could not allocate disk write buffer"); uprintf("Could not allocate disk write 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, BufSize);
cmp_buffer = (uint8_t*)_mm_malloc(BufSize, SelectedDrive.SectorSi if (fast_zeroing) {
ze); cmp_buffer = (uint32_t*)_mm_malloc(BufSize, SelectedDrive
if (cmp_buffer == NULL) { .SectorSize);
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAG if (cmp_buffer == NULL) {
E) | ERROR_NOT_ENOUGH_MEMORY; FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILIT
uprintf("Could not allocate disk comparison buffer"); Y_STORAGE) | ERROR_NOT_ENOUGH_MEMORY;
goto out; uprintf("Could not allocate disk comparison buffe
r");
goto out;
}
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 bufferi ng overlapped and whatnot: // Don't bother trying for something clever, using double bufferi ng overlapped and whatnot:
// With Windows' default optimizations, sync read + sync write fo r sequential operations // With Windows' default optimizations, sync read + sync write fo r sequential operations
// will be as fast, if not faster, than whatever async scheme you can come up with. // will be as fast, if not faster, than whatever async scheme you can come up with.
rSize = BufSize; rSize = BufSize;
for (wb = 0, wSize = 0; wb < (uint64_t)SelectedDrive.DiskSize; wb += wSize) { 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); UpdateProgressWithInfo(OP_FORMAT, hSourceImage ? MSG_261 : fast_zeroing ? MSG_306 : MSG_286, wb, target_size);
cur_value = (wb * min(80, target_size)) / target_size;
if (cur_value != last_value) {
last_value = cur_value;
uprintfs("+");
}
if (hSourceImage != NULL) { if (hSourceImage != NULL) {
s = ReadFile(hSourceImage, buffer, BufSize, &rSiz e, NULL); s = ReadFile(hSourceImage, buffer, BufSize, &rSiz e, NULL);
if (!s) { if (!s) {
FormatStatus = ERROR_SEVERITY_ERROR | FAC (FACILITY_STORAGE) | ERROR_READ_FAULT; FormatStatus = ERROR_SEVERITY_ERROR | FAC (FACILITY_STORAGE) | ERROR_READ_FAULT;
uprintf("Read error: %s", WindowsErrorStr ing()); uprintf("Read error: %s", WindowsErrorStr ing());
goto out; goto out;
} }
if (rSize == 0) if (rSize == 0)
break; break;
} }
skipping to change at line 1599 skipping to change at line 1605
// Also, a back-off strategy is used to limit reading. // Also, a back-off strategy is used to limit reading.
if (throttle_fast_zeroing) { if (throttle_fast_zeroing) {
throttle_fast_zeroing--; throttle_fast_zeroing--;
} else if (fast_zeroing) { } else if (fast_zeroing) {
assert(hSourceImage == NULL); // Only enabled f or zeroing assert(hSourceImage == NULL); // Only enabled f or zeroing
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, rSize, & xSize, NULL);
if ((!s) || (xSize != rSize) ) { if ((!s) || (xSize != rSize) ) {
uprintf("Read error: Could not read data for comparison - %s", WindowsErrorString()); uprintf("Read error: Could not read data for fast zeroing comparison - %s", WindowsErrorString());
goto out; goto out;
} }
// Check for an empty block // Check for an empty block by comparing with the
ptr = (int*)(cmp_buffer); first element
// Get first element zero_data = cmp_buffer[0];
zero_data = ptr[0];
// Check all bits are the same // Check all bits are the same
if ((zero_data == 0) || (zero_data == -1)) { 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 < (int)(rSize / sizeof(int) for (i = 1; (i < rSize / sizeof(uint32_t)
); i++) { ) && (cmp_buffer[i] == zero_data); i++);
if (ptr[i] != zero_data) if (i >= rSize / sizeof(uint32_t)) {
break;
}
if (i >= (int)(rSize / sizeof(int))) {
// Block is empty, skip write // Block is empty, skip write
wSize = rSize; wSize = rSize;
continue; continue;
} }
} }
// Move the file pointer position back for writin g // Move the file pointer position back for writin g
li.QuadPart = wb; li.QuadPart = wb;
if (!SetFilePointerEx(hPhysicalDrive, li, NULL, F ILE_BEGIN)) { if (!SetFilePointerEx(hPhysicalDrive, li, NULL, F ILE_BEGIN)) {
uprintf("Error: Could not reset position - %s", WindowsErrorString()); uprintf("Error: Could not reset position - %s", WindowsErrorString());
skipping to change at line 1679 skipping to change at line 1680
* To change a volume file system * To change a volume file system
* Open a volume. * Open a volume.
* Lock the volume. * Lock the volume.
* Format the volume. * Format the volume.
* Dismount the volume. * Dismount the volume.
* Unlock the volume. * Unlock the volume.
* Close the volume handle. * Close the volume handle.
*/ */
DWORD WINAPI FormatThread(void* param) DWORD WINAPI FormatThread(void* param)
{ {
int i, r; int r;
BOOL ret, use_large_fat32, windows_to_go, actual_lock_drive = lock_drive; BOOL ret, use_large_fat32, windows_to_go, actual_lock_drive = lock_drive;
BOOL need_logical = FALSE;
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; 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;
char *bb_msg, *volume_name = NULL; char *bb_msg, *volume_name = NULL;
char drive_name[] = "?:\\"; char drive_name[] = "?:\\";
char drive_letters[27], fs_name[32], label[64]; char drive_letters[27], fs_name[32], label[64];
skipping to change at line 1716 skipping to change at line 1718
extra_partitions = XP_ESP | XP_MSR; extra_partitions = XP_ESP | XP_MSR;
else if ( ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) && else if ( ((fs_type == FS_NTFS) || (fs_type == FS_EXFAT)) &&
((boot_type == BT_UEFI_NTFS) || ((boot_type == BT_IMAGE ) && IS_EFI_BOOTABLE(img_report) && ((boot_type == BT_UEFI_NTFS) || ((boot_type == BT_IMAGE ) && IS_EFI_BOOTABLE(img_report) &&
((target_type == TT_UEFI) || (windows_to_go) || (allow _dual_uefi_bios)))) ) ((target_type == TT_UEFI) || (windows_to_go) || (allow _dual_uefi_bios)))) )
extra_partitions = XP_UEFI_NTFS; extra_partitions = XP_UEFI_NTFS;
else if ((boot_type == BT_IMAGE) && !write_as_image && HAS_PERSISTENCE(im g_report) && persistence_size) else if ((boot_type == BT_IMAGE) && !write_as_image && HAS_PERSISTENCE(im g_report) && persistence_size)
extra_partitions = XP_CASPER; extra_partitions = XP_CASPER;
else if (IsChecked(IDC_OLD_BIOS_FIXES)) else if (IsChecked(IDC_OLD_BIOS_FIXES))
extra_partitions = XP_COMPAT; extra_partitions = XP_COMPAT;
// On pre 1703 platforms (and even on later ones), anything with ext2/ext 3 doesn't sit // On pre 1703 platforms (and even on later ones), anything with ext2/ext 3 doesn't sit
// too well with Windows. Relaxing our locking rules seems to help... // too well with Windows. Same with ESPs. Relaxing our locking rules seem
if ((extra_partitions == XP_CASPER) || (fs_type >= FS_EXT2)) s to help...
if ((extra_partitions & (XP_ESP | XP_CASPER)) || (fs_type >= FS_EXT2))
actual_lock_drive = FALSE; actual_lock_drive = FALSE;
PrintInfoDebug(0, MSG_225); PrintInfoDebug(0, MSG_225);
hPhysicalDrive = GetPhysicalHandle(DriveIndex, actual_lock_drive, FALSE, !actual_lock_drive); hPhysicalDrive = GetPhysicalHandle(DriveIndex, actual_lock_drive, FALSE, !actual_lock_drive);
if (hPhysicalDrive == INVALID_HANDLE_VALUE) { if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_O PEN_FAILED; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_O PEN_FAILED;
goto out; goto out;
} }
// 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"); 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) {
uprintf("No drive letter was assigned..."); // Unassign all drives letters
drive_name[0] = GetUnusedDriveLetter(); drive_name[0] = RemoveDriveLetters(DriveIndex, TRUE, FALSE);
if (drive_name[0] == 0) { if (drive_name[0] == 0) {
uprintf("Could not find a suitable drive letter"); uprintf("Unable to find a drive letter to use");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE) FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APP
|APPERR(ERROR_CANT_ASSIGN_LETTER); ERR(ERROR_CANT_ASSIGN_LETTER);
goto out; goto out;
}
} else {
// Unmount all mounted volumes that belong to this drive
// Do it in reverse so that we always end on the first volume let
ter
for (i = (int)safe_strlen(drive_letters); i > 0; i--) {
drive_name[0] = drive_letters[i-1];
if (boot_type == BT_IMAGE) {
// 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') == dr
ive_letters[i-1]) {
uprintf("ABORTED: Cannot use an image tha
t is located on the target drive!");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(F
ACILITY_STORAGE)|ERROR_ACCESS_DENIED;
goto out;
}
}
if (!DeleteVolumeMountPointA(drive_name)) {
uprintf("Failed to delete mountpoint %s: %s", dri
ve_name, WindowsErrorString());
// Try to continue. We will bail out if this caus
es an issue.
}
}
} }
uprintf("Will use '%C:' as volume mountpoint", 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 dri ve // It kind of blows, but we have to relinquish access to the physical dri ve
// 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...
safe_unlockclose(hPhysicalDrive); safe_unlockclose(hPhysicalDrive);
PrintInfo(0, MSG_239, lmprintf(MSG_307)); PrintInfo(0, MSG_239, lmprintf(MSG_307));
if (!DeletePartitions(DriveIndex)) { if (!DeletePartition(DriveIndex, 0, FALSE)) {
SetLastError(FormatStatus); SetLastError(FormatStatus);
uprintf("Notice: Could not delete partitions: %s", WindowsErrorSt ring());
FormatStatus = 0; FormatStatus = 0;
// If we couldn't delete partitions, Windows give us trouble unle
ss we
// request access to the logical drive. Don't ask me why!
need_logical = TRUE;
} }
// An extra refresh of the (now empty) partition data here appears to be helpful // An extra refresh of the (now empty) partition data here appears to be helpful
GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_name, sizeof(fs_name ), TRUE); GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_name, sizeof(fs_name ), TRUE);
// Now get RW access to the physical drive... // Now get RW access to the physical drive
hPhysicalDrive = GetPhysicalHandle(DriveIndex, actual_lock_drive, TRUE, ! actual_lock_drive); hPhysicalDrive = GetPhysicalHandle(DriveIndex, actual_lock_drive, TRUE, ! actual_lock_drive);
if (hPhysicalDrive == INVALID_HANDLE_VALUE) { if (hPhysicalDrive == INVALID_HANDLE_VALUE) {
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERR OR_OPEN_FAILED; FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERR OR_OPEN_FAILED;
goto out; goto out;
} }
RefreshDriveLayout(hPhysicalDrive); RefreshDriveLayout(hPhysicalDrive);
// ...and get a lock to the logical drive so that we can actually write s // If we write an image that contains an ESP, Windows forcibly reassigns/
omething removes the target
hLogicalVolume = GetLogicalHandle(DriveIndex, 0, TRUE, FALSE, !actual_loc // drive, which causes a write error. To work around this, we must lock t
k_drive); he logical drive.
if (hLogicalVolume == INVALID_HANDLE_VALUE) { // Also need to lock logical drive if we couldn't delete partitions, to k
uprintf("Could not lock volume"); eep Windows happy...
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_O if (((boot_type == BT_IMAGE) && write_as_image) || (need_logical)) {
PEN_FAILED; uprintf("Requesting logical volume handle...");
goto out; hLogicalVolume = GetLogicalHandle(DriveIndex, 0, TRUE, FALSE, !ac
} else if (hLogicalVolume == NULL) { tual_lock_drive);
// NULL is returned for cases where the drive is not yet partitio if (hLogicalVolume == INVALID_HANDLE_VALUE) {
ned uprintf("Could not access logical volume");
uprintf("Drive does not appear to be partitioned"); FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAG
} else if (!UnmountVolume(hLogicalVolume)) { E) | ERROR_OPEN_FAILED;
uprintf("Trying to continue regardless..."); goto out;
// If the call succeeds (and we don't get a NULL logical handle a
s returned for
// unpartitioned drives), try to unmount the volume.
} else if ((hLogicalVolume == NULL) && (!UnmountVolume(hLogicalVo
lume))) {
uprintf("Trying to continue regardless...");
}
} }
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
if (!zero_drive && !write_as_image) { if (!zero_drive && !write_as_image) {
PrintInfoDebug(0, MSG_226); PrintInfoDebug(0, MSG_226);
AnalyzeMBR(hPhysicalDrive, "Drive", FALSE); AnalyzeMBR(hPhysicalDrive, "Drive", FALSE);
UpdateProgress(OP_ANALYZE_MBR, -1.0f); UpdateProgress(OP_ANALYZE_MBR, -1.0f);
} }
if (zero_drive) { if (zero_drive) {
skipping to change at line 1842 skipping to change at line 1831
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinut e, lt.wSecond); lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinut e, 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"); uprintf("Could not create log file for bad blocks check");
} else { } else {
fprintf(log_fd, APPLICATION_NAME " bad blocks che ck started on: %04d.%02d.%02d %02d:%02d:%02d", fprintf(log_fd, APPLICATION_NAME " bad blocks che ck started on: %04d.%02d.%02d %02d:%02d:%02d",
lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinut e, lt.wSecond); lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinut e, lt.wSecond);
fflush(log_fd); fflush(log_fd);
} }
if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, (s if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, (s
el >= 2) ? 4 : sel +1, el >= 2) ? 4 : sel +1, sel, &report, log_fd)) {
(sel < 2) ? 0 : sel - 2, &report, log_fd)) {
uprintf("Bad blocks: Check failed."); uprintf("Bad blocks: Check failed.");
if (!IS_ERROR(FormatStatus)) if (!IS_ERROR(FormatStatus))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(F ACILITY_STORAGE)|APPERR(ERROR_BADBLOCKS_FAILURE); FormatStatus = ERROR_SEVERITY_ERROR|FAC(F ACILITY_STORAGE)|APPERR(ERROR_BADBLOCKS_FAILURE);
ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSiz e, SelectedDrive.SectorSize, FALSE); ClearMBRGPT(hPhysicalDrive, SelectedDrive.DiskSiz e, SelectedDrive.SectorSize, FALSE);
fclose(log_fd); fclose(log_fd);
DeleteFileU(logfile); DeleteFileU(logfile);
goto out; goto out;
} }
uprintf("Bad Blocks: Check completed, %d bad block%s foun d. (%d/%d/%d errors)", uprintf("Bad Blocks: Check completed, %d bad block%s foun d. (%d/%d/%d errors)",
report.bb_count, (report.bb_count==1)?"":"s", report.bb_count, (report.bb_count==1)?"":"s",
skipping to change at line 1915 skipping to change at line 1903
volume_name = GetLogicalName(DriveIndex, 0, TRUE, TRUE); volume_name = GetLogicalName(DriveIndex, 0, TRUE, TRUE);
if ((volume_name != NULL) && (MountVolume(drive_name, vol ume_name))) if ((volume_name != NULL) && (MountVolume(drive_name, vol ume_name)))
uprintf("Remounted %s as %C:", volume_name, drive _name[0]); uprintf("Remounted %s as %C:", volume_name, drive _name[0]);
} }
goto out; goto out;
} }
UpdateProgress(OP_ZERO_MBR, -1.0f); UpdateProgress(OP_ZERO_MBR, -1.0f);
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
if (!CreatePartition(hPhysicalDrive, partition_type, fs_type, (partition_ if (!CreatePartition(hPhysicalDrive, partition_type, fs_type, (partition_
type==PARTITION_STYLE_MBR) && (target_type==TT_UEFI), extra_partitions)) { type == PARTITION_STYLE_MBR)
&& (target_type == TT_UEFI), extra_partitions)) {
FormatStatus = (LastWriteError != 0) ? LastWriteError : (ERROR_SE VERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE); FormatStatus = (LastWriteError != 0) ? LastWriteError : (ERROR_SE VERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE);
goto out; goto out;
} }
UpdateProgress(OP_PARTITION, -1.0f); UpdateProgress(OP_PARTITION, -1.0f);
// Close the (unmounted) volume before formatting // Close the (unmounted) volume before formatting
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", WindowsErrorString( )); uprintf("Could not close volume: %s", WindowsErrorString( ));
skipping to change at line 2031 skipping to change at line 2020
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE); volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN], TRUE, TRUE);
if (volume_name == NULL) { if (volume_name == NULL) {
uprintf("Could not get volume name"); uprintf("Could not get volume name");
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_N O_VOLUME_ID; FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_N O_VOLUME_ID;
goto out; goto out;
} }
uprintf("Found volume %s", volume_name); uprintf("Found volume %s", volume_name);
// Windows is really finicky with regards to reassigning drive letters ev
en after
// we forcibly removed them, so add yet another explicit call to RemoveDr
iveLetters()
RemoveDriveLetters(DriveIndex, FALSE, TRUE);
if (!MountVolume(drive_name, volume_name)) { if (!MountVolume(drive_name, volume_name)) {
uprintf("Could not remount %s as %C: %s\n", volume_name, drive_na me[0], WindowsErrorString()); uprintf("Could not remount %s as %C: %s\n", volume_name, drive_na me[0], WindowsErrorString());
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR( ERROR_CANT_MOUNT_VOLUME); FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR( ERROR_CANT_MOUNT_VOLUME);
goto out; goto out;
} }
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
// Disable file indexing, unless it was force-enabled by the user // Disable file indexing, unless it was force-enabled by the user
if ((!enable_file_indexing) && ((fs_type == FS_NTFS) || (fs_type == FS_UD F) || (fs_type == FS_REFS))) { if ((!enable_file_indexing) && ((fs_type == FS_NTFS) || (fs_type == FS_UD F) || (fs_type == FS_REFS))) {
uprintf("Disabling file indexing..."); uprintf("Disabling file indexing...");
skipping to change at line 2099 skipping to change at line 2091
} }
// We must close and unlock the volume to write files to it // We must close and unlock the volume to write files to it
safe_unlockclose(hLogicalVolume); safe_unlockclose(hLogicalVolume);
} }
} else { } else {
if (IsChecked(IDC_EXTENDED_LABEL)) if (IsChecked(IDC_EXTENDED_LABEL))
SetAutorun(drive_name); SetAutorun(drive_name);
} }
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
// We issue a complete remount of the filesystem at on account of: // We issue a complete remount of the filesystem on account of:
// - Ensuring the file explorer properly detects that the volume was upda ted // - Ensuring the file explorer properly detects that the volume was upda ted
// - Ensuring that an NTFS system will be reparsed so that it becomes boo table // - Ensuring that an NTFS system will be reparsed so that it becomes boo table
if (!RemountVolume(drive_name)) if (!RemountVolume(drive_name, FALSE))
goto out; goto out;
CHECK_FOR_USER_CANCEL; CHECK_FOR_USER_CANCEL;
if (boot_type != BT_NON_BOOTABLE) { if (boot_type != BT_NON_BOOTABLE) {
if ((boot_type == BT_MSDOS) || (boot_type == BT_FREEDOS)) { if ((boot_type == BT_MSDOS) || (boot_type == BT_FREEDOS)) {
UpdateProgress(OP_FILE_COPY, -1.0f); UpdateProgress(OP_FILE_COPY, -1.0f);
PrintInfoDebug(0, MSG_230); PrintInfoDebug(0, MSG_230);
if (!ExtractDOS(drive_name)) { if (!ExtractDOS(drive_name)) {
if (!IS_ERROR(FormatStatus)) if (!IS_ERROR(FormatStatus))
FormatStatus = ERROR_SEVERITY_ERROR|FAC(F ACILITY_STORAGE)|ERROR_CANNOT_COPY; FormatStatus = ERROR_SEVERITY_ERROR|FAC(F ACILITY_STORAGE)|ERROR_CANNOT_COPY;
skipping to change at line 2177 skipping to change at line 2169
if (!SetupWinPE(drive_name[0])) if (!SetupWinPE(drive_name[0]))
FormatStatus = ERROR_SEVERITY_ERR OR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH); FormatStatus = ERROR_SEVERITY_ERR OR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_PATCH);
} }
} }
} }
UpdateProgress(OP_FINALIZE, -1.0f); UpdateProgress(OP_FINALIZE, -1.0f);
PrintInfoDebug(0, MSG_233); PrintInfoDebug(0, MSG_233);
if (IsChecked(IDC_EXTENDED_LABEL)) if (IsChecked(IDC_EXTENDED_LABEL))
SetAutorun(drive_name); SetAutorun(drive_name);
// Issue another complete remount before we exit, to ensure we're clean // Issue another complete remount before we exit, to ensure we're clean
RemountVolume(drive_name); RemountVolume(drive_name, TRUE);
// NTFS fixup (WinPE/AIK images don't seem to boot without an ext ra checkdisk) // NTFS fixup (WinPE/AIK images don't seem to boot without an ext ra checkdisk)
if ((boot_type == BT_IMAGE) && (img_report.is_iso) && (fs_type == FS_NTFS)) { if ((boot_type == BT_IMAGE) && (img_report.is_iso) && (fs_type == FS_NTFS)) {
// Try to ensure that all messages from Checkdisk will be in English // Try to ensure that all messages from Checkdisk will be in English
if (PRIMARYLANGID(GetThreadUILanguage()) != LANG_ENGLISH) { if (PRIMARYLANGID(GetThreadUILanguage()) != LANG_ENGLISH) {
SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBL ANG_ENGLISH_US)); SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBL ANG_ENGLISH_US));
if (PRIMARYLANGID(GetThreadUILanguage()) != LANG_ ENGLISH) if (PRIMARYLANGID(GetThreadUILanguage()) != LANG_ ENGLISH)
uprintf("Note: CheckDisk messages may be localized"); uprintf("Note: CheckDisk messages may be localized");
} }
CheckDisk(drive_name[0]); CheckDisk(drive_name[0]);
UpdateProgress(OP_FINALIZE, -1.0f); UpdateProgress(OP_FINALIZE, -1.0f);
} }
} }
out: out:
safe_free(volume_name); safe_free(volume_name);
safe_free(buffer); safe_free(buffer);
safe_closehandle(hSourceImage); 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)) {
volume_name = GetLogicalName(DriveIndex, 0, TRUE, FALSE); volume_name = GetLogicalName(DriveIndex, partition_offset[PI_MAIN ], TRUE, TRUE);
if (volume_name != NULL) { if (volume_name != NULL) {
if (MountVolume(drive_name, volume_name)) if (MountVolume(drive_name, volume_name))
uprintf("Re-mounted volume as %C: after error", d rive_name[0]); uprintf("Re-mounted volume as %C: after error", d rive_name[0]);
free(volume_name); free(volume_name);
} }
} }
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)TRUE, 0); PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)TRUE, 0);
ExitThread(0); ExitThread(0);
} }
 End of changes. 34 change blocks. 
124 lines changed or deleted 117 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)