mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-19 09:25:12 -04:00
[core] drive handling improvements
* Use IOCTL_DISK_UPDATE_PROPERTIES after partitioning * Use IOCTL_DISK_DELETE_DRIVE_LAYOUT to invalidate partitions before formatting * Fix handling of unpartitioned drives * Increase delay after partitioning * All of the above should help with the infamous #122 * Also fix display of error messages in ms-sys' file.c as well as stdio.c * Also add commandline option -f to list fixed drives
This commit is contained in:
parent
fe3b1eb6f6
commit
cd5665881c
7 changed files with 163 additions and 72 deletions
45
src/drive.c
45
src/drive.c
|
@ -202,12 +202,18 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a handle to the first logical volume on the disk identified by DriveIndex
|
* Obtain a handle to the first logical volume on the disk identified by DriveIndex
|
||||||
|
* Returns INVALID_HANDLE_VALUE on error or NULL if no logical path exists (typical
|
||||||
|
* of unpartitioned drives)
|
||||||
*/
|
*/
|
||||||
HANDLE GetLogicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDrive)
|
HANDLE GetLogicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDrive)
|
||||||
{
|
{
|
||||||
HANDLE hLogical = INVALID_HANDLE_VALUE;
|
HANDLE hLogical = INVALID_HANDLE_VALUE;
|
||||||
char* LogicalPath = GetLogicalName(DriveIndex, FALSE);
|
char* LogicalPath = GetLogicalName(DriveIndex, FALSE);
|
||||||
|
if (LogicalPath == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
hLogical = GetHandle(LogicalPath, bWriteAccess, bLockDrive);
|
hLogical = GetHandle(LogicalPath, bWriteAccess, bLockDrive);
|
||||||
safe_free(LogicalPath);
|
safe_free(LogicalPath);
|
||||||
return hLogical;
|
return hLogical;
|
||||||
|
@ -490,8 +496,9 @@ typedef struct _DRIVE_LAYOUT_INFORMATION_EX4 {
|
||||||
* Create a partition table
|
* Create a partition table
|
||||||
* See http://technet.microsoft.com/en-us/library/cc739412.aspx for some background info
|
* See http://technet.microsoft.com/en-us/library/cc739412.aspx for some background info
|
||||||
* NB: if you modify the MBR outside of using the Windows API, Windows still uses the cached
|
* NB: if you modify the MBR outside of using the Windows API, Windows still uses the cached
|
||||||
* copy it got from the last IOCTL, and ignore your changes until you replug the drive...
|
* copy it got from the last IOCTL, and ignores your changes until you replug the drive
|
||||||
*/
|
* or issue an IOCTL_DISK_UPDATE_PROPERTIES.
|
||||||
|
*/
|
||||||
#if !defined(PARTITION_BASIC_DATA_GUID)
|
#if !defined(PARTITION_BASIC_DATA_GUID)
|
||||||
const GUID PARTITION_BASIC_DATA_GUID = { 0xebd0a0a2, 0xb9e5, 0x4433, {0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7} };
|
const GUID PARTITION_BASIC_DATA_GUID = { 0xebd0a0a2, 0xb9e5, 0x4433, {0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7} };
|
||||||
#endif
|
#endif
|
||||||
|
@ -627,6 +634,38 @@ BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL m
|
||||||
safe_closehandle(hDrive);
|
safe_closehandle(hDrive);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
// Diskpart does call the following IOCTL this after updating the partition table, so we do too
|
||||||
|
r = DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &size, NULL );
|
||||||
|
if (!r) {
|
||||||
|
uprintf("Could not refresh drive layout: %s\n", WindowsErrorString());
|
||||||
|
safe_closehandle(hDrive);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete the disk partition table */
|
||||||
|
BOOL DeletePartitions(HANDLE hDrive)
|
||||||
|
{
|
||||||
|
BOOL r;
|
||||||
|
DWORD size;
|
||||||
|
|
||||||
|
PrintStatus(0, TRUE, "Erasing Partitions...");
|
||||||
|
|
||||||
|
r = DeviceIoControl(hDrive, IOCTL_DISK_DELETE_DRIVE_LAYOUT, NULL, 0, NULL, 0, &size, NULL );
|
||||||
|
if (!r) {
|
||||||
|
uprintf("Could not delete drive layout: %s\n", WindowsErrorString());
|
||||||
|
safe_closehandle(hDrive);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = DeviceIoControl(hDrive, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, &size, NULL );
|
||||||
|
if (!r) {
|
||||||
|
uprintf("Could not refresh drive layout: %s\n", WindowsErrorString());
|
||||||
|
safe_closehandle(hDrive);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
92
src/format.c
92
src/format.c
|
@ -372,12 +372,14 @@ static BOOL FormatFAT32(DWORD DriveIndex)
|
||||||
// Open the drive (volume should already be locked)
|
// Open the drive (volume should already be locked)
|
||||||
hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE);
|
hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE);
|
||||||
if (IS_ERROR(FormatStatus)) goto out;
|
if (IS_ERROR(FormatStatus)) goto out;
|
||||||
if (hLogicalVolume == INVALID_HANDLE_VALUE)
|
if ((hLogicalVolume == INVALID_HANDLE_VALUE) || (hLogicalVolume == NULL))
|
||||||
die("Could not access logical volume\n", ERROR_OPEN_FAILED);
|
die("Invalid logical volume handle\n", ERROR_INVALID_HANDLE);
|
||||||
|
|
||||||
// Make sure we get exclusive access
|
// Make sure we get exclusive access
|
||||||
if (!UnmountVolume(hLogicalVolume))
|
if (!UnmountVolume(hLogicalVolume)) {
|
||||||
return r;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
// Work out drive params
|
// Work out drive params
|
||||||
if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dgDrive,
|
if (!DeviceIoControl (hLogicalVolume, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dgDrive,
|
||||||
|
@ -1088,19 +1090,45 @@ out:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mount the volume identified by drive_guid to mountpoint drive_name
|
||||||
|
*/
|
||||||
|
static BOOL MountVolume(char* drive_name, char *drive_guid)
|
||||||
|
{
|
||||||
|
char mounted_guid[50];
|
||||||
|
|
||||||
|
if (!SetVolumeMountPointA(drive_name, drive_guid)) {
|
||||||
|
// If the OS was faster than us at remounting the drive, this operation can fail
|
||||||
|
// with ERROR_DIR_NOT_EMPTY. If that's the case, just check that mountpoints match
|
||||||
|
if (GetLastError() == ERROR_DIR_NOT_EMPTY) {
|
||||||
|
if (!GetVolumeNameForVolumeMountPointA(drive_name, mounted_guid, sizeof(mounted_guid))) {
|
||||||
|
uprintf("%s already mounted, but volume GUID could not be checked\n", drive_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (safe_strcmp(drive_guid, mounted_guid) != 0) {
|
||||||
|
uprintf("%s already mounted, but volume GUID doesn't match:\r\n expected %s, got %s\n",
|
||||||
|
drive_name, drive_guid, mounted_guid);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
uprintf("%s was already mounted as %s\n", drive_guid, drive_name);
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Issue a complete remount of the volume
|
* Issue a complete remount of the volume
|
||||||
*/
|
*/
|
||||||
static BOOL RemountVolume(char drive_letter)
|
static BOOL RemountVolume(char* drive_name)
|
||||||
{
|
{
|
||||||
char drive_guid[50];
|
char drive_guid[50];
|
||||||
char drive_name[] = "?:\\";
|
|
||||||
|
|
||||||
drive_name[0] = drive_letter;
|
|
||||||
if (GetVolumeNameForVolumeMountPointA(drive_name, drive_guid, sizeof(drive_guid))) {
|
if (GetVolumeNameForVolumeMountPointA(drive_name, drive_guid, sizeof(drive_guid))) {
|
||||||
if (DeleteVolumeMountPointA(drive_name)) {
|
if (DeleteVolumeMountPointA(drive_name)) {
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
if (SetVolumeMountPointA(drive_name, drive_guid)) {
|
if (MountVolume(drive_name, drive_guid)) {
|
||||||
uprintf("Successfully remounted %s on %s\n", &drive_guid[4], drive_name);
|
uprintf("Successfully remounted %s on %s\n", &drive_guid[4], drive_name);
|
||||||
} else {
|
} else {
|
||||||
uprintf("Failed to remount %s on %s\n", &drive_guid[4], drive_name);
|
uprintf("Failed to remount %s on %s\n", &drive_guid[4], drive_name);
|
||||||
|
@ -1212,22 +1240,39 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
uprintf("Failed to delete mountpoint %s: %s\n", drive_name, WindowsErrorString());
|
uprintf("Failed to delete mountpoint %s: %s\n", 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\n", drive_name[0]);
|
||||||
|
|
||||||
|
// ...but we need a lock to the logical drive to be able to write anything to it
|
||||||
|
// TODO: Use a retry loop for the lock
|
||||||
hLogicalVolume = GetLogicalHandle(DriveIndex, FALSE, TRUE);
|
hLogicalVolume = GetLogicalHandle(DriveIndex, FALSE, TRUE);
|
||||||
if (hLogicalVolume == INVALID_HANDLE_VALUE) {
|
if (hLogicalVolume == INVALID_HANDLE_VALUE) {
|
||||||
uprintf("Could not lock volume\n");
|
uprintf("Could not lock volume\n");
|
||||||
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) {
|
||||||
|
// NULL is returned for cases where the drive is not yet partitioned
|
||||||
|
uprintf("Drive does not appear to be partitioned\n");
|
||||||
|
} else {
|
||||||
|
if (!UnmountVolume(hLogicalVolume))
|
||||||
|
uprintf("Trying to continue regardless...\n");
|
||||||
}
|
}
|
||||||
UnmountVolume(hLogicalVolume);
|
|
||||||
if (FormatStatus) goto out; // Check for user cancel
|
if (FormatStatus) goto out; // Check for user cancel
|
||||||
|
|
||||||
PrintStatus(0, TRUE, "Analyzing existing boot records...\n");
|
PrintStatus(0, TRUE, "Analyzing existing boot records...\n");
|
||||||
AnalyzeMBR(hPhysicalDrive);
|
AnalyzeMBR(hPhysicalDrive);
|
||||||
AnalyzePBR(hLogicalVolume);
|
if (hLogicalVolume != NULL) {
|
||||||
|
AnalyzePBR(hLogicalVolume);
|
||||||
|
}
|
||||||
UpdateProgress(OP_ANALYZE_MBR, -1.0f);
|
UpdateProgress(OP_ANALYZE_MBR, -1.0f);
|
||||||
|
|
||||||
|
// Zap any existing partitions. This should help to prevent access errors
|
||||||
|
// TODO: With this, we should be able to avoid having to deal with the logical volume above
|
||||||
|
if (!DeletePartitions(hPhysicalDrive)) {
|
||||||
|
uprintf("Could not reset partitions\n");
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_PARTITION_FAILURE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsChecked(IDC_BADBLOCKS)) {
|
if (IsChecked(IDC_BADBLOCKS)) {
|
||||||
do {
|
do {
|
||||||
// create a log file for bad blocks report. Since %USERPROFILE% may
|
// create a log file for bad blocks report. Since %USERPROFILE% may
|
||||||
|
@ -1290,11 +1335,13 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
}
|
}
|
||||||
// Close the (unmounted) volume before formatting, but keep the lock
|
// Close the (unmounted) volume before formatting, but keep the lock
|
||||||
// According to MS this relinquishes the lock, so...
|
// According to MS this relinquishes the lock, so...
|
||||||
PrintStatus(0, TRUE, "Closing existing volume...\n");
|
if (hLogicalVolume != NULL) {
|
||||||
if (!CloseHandle(hLogicalVolume)) {
|
PrintStatus(0, TRUE, "Closing existing volume...\n");
|
||||||
uprintf("Could not close volume: %s\n", WindowsErrorString());
|
if (!CloseHandle(hLogicalVolume)) {
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED;
|
uprintf("Could not close volume: %s\n", WindowsErrorString());
|
||||||
goto out;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ACCESS_DENIED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hLogicalVolume = INVALID_HANDLE_VALUE;
|
hLogicalVolume = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
@ -1318,8 +1365,9 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
}
|
}
|
||||||
UpdateProgress(OP_PARTITION, -1.0f);
|
UpdateProgress(OP_PARTITION, -1.0f);
|
||||||
|
|
||||||
// Add a small delay after partitioning to be safe
|
// Add a delay after partitioning to be safe
|
||||||
Sleep(200);
|
// TODO: Use a retry loop and test the lock
|
||||||
|
Sleep(2000);
|
||||||
|
|
||||||
// If FAT32 is requested and we have a large drive (>32 GB) use
|
// If FAT32 is requested and we have a large drive (>32 GB) use
|
||||||
// large FAT32 format, else use MS's FormatEx.
|
// large FAT32 format, else use MS's FormatEx.
|
||||||
|
@ -1350,7 +1398,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
}
|
}
|
||||||
if (FormatStatus) goto out; // Check for user cancel
|
if (FormatStatus) goto out; // Check for user cancel
|
||||||
|
|
||||||
if (!SetVolumeMountPointA(drive_name, guid_volume)) {
|
if (!MountVolume(drive_name, guid_volume)) {
|
||||||
uprintf("Could not remount %s on %s: %s\n", guid_volume, drive_name, WindowsErrorString());
|
uprintf("Could not remount %s on %s: %s\n", guid_volume, drive_name, 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;
|
||||||
|
@ -1368,7 +1416,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
// We still have a lock, which we need to modify the volume boot record
|
// We still have a lock, which we need to modify the volume boot record
|
||||||
// => no need to reacquire the lock...
|
// => no need to reacquire the lock...
|
||||||
hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE);
|
hLogicalVolume = GetLogicalHandle(DriveIndex, TRUE, FALSE);
|
||||||
if (hLogicalVolume == INVALID_HANDLE_VALUE) {
|
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\n");
|
||||||
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1397,7 +1445,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
// We issue a complete remount of the filesystem at on account of:
|
// We issue a complete remount of the filesystem at on account of:
|
||||||
// - Ensuring the file explorer properly detects that the volume was updated
|
// - Ensuring the file explorer properly detects that the volume was updated
|
||||||
// - Ensuring that an NTFS system will be reparsed so that it becomes bootable
|
// - Ensuring that an NTFS system will be reparsed so that it becomes bootable
|
||||||
if (!RemountVolume(drive_name[0]))
|
if (!RemountVolume(drive_name))
|
||||||
goto out;
|
goto out;
|
||||||
if (FormatStatus) goto out; // Check for user cancel
|
if (FormatStatus) goto out; // Check for user cancel
|
||||||
|
|
||||||
|
@ -1449,7 +1497,7 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
if (IsChecked(IDC_SET_ICON))
|
if (IsChecked(IDC_SET_ICON))
|
||||||
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[0]);
|
RemountVolume(drive_name);
|
||||||
// NTFS fixup (WinPE/AIK images don't seem to boot without an extra checkdisk)
|
// NTFS fixup (WinPE/AIK images don't seem to boot without an extra checkdisk)
|
||||||
if ((dt == DT_ISO) && (fs == FS_NTFS)) {
|
if ((dt == DT_ISO) && (fs == FS_NTFS)) {
|
||||||
CheckDisk(drive_name[0]);
|
CheckDisk(drive_name[0]);
|
||||||
|
|
|
@ -41,15 +41,15 @@ int64_t write_sectors(HANDLE hDrive, uint64_t SectorSize,
|
||||||
ptr.QuadPart = StartSector*SectorSize;
|
ptr.QuadPart = StartSector*SectorSize;
|
||||||
if(!SetFilePointerEx(hDrive, ptr, NULL, FILE_BEGIN))
|
if(!SetFilePointerEx(hDrive, ptr, NULL, FILE_BEGIN))
|
||||||
{
|
{
|
||||||
uprintf("write_sectors: Could not access sector %d - %s\n", StartSector, WindowsErrorString());
|
uprintf("write_sectors: Could not access sector 0x%08llx - %s\n", StartSector, WindowsErrorString());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((!WriteFile(hDrive, pBuf, Size, &Size, NULL)) || (Size != nSectors*SectorSize))
|
if((!WriteFile(hDrive, pBuf, Size, &Size, NULL)) || (Size != nSectors*SectorSize))
|
||||||
{
|
{
|
||||||
uprintf("write_sectors: Write error - %s\n", WindowsErrorString());
|
uprintf("write_sectors: Write error %s\n", (GetLastError()!=ERROR_SUCCESS)?WindowsErrorString():"");
|
||||||
uprintf(" Wrote: %d, Expected: %d\n", Size, nSectors*SectorSize);
|
uprintf(" Wrote: %d, Expected: %lld\n", Size, nSectors*SectorSize);
|
||||||
uprintf(" StartSector:%0X, nSectors:%0X, SectorSize:%0X\n", StartSector, nSectors, SectorSize);
|
uprintf(" StartSector: 0x%08llx, nSectors: 0x%llx, SectorSize: 0x%llx\n", StartSector, nSectors, SectorSize);
|
||||||
return Size;
|
return Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,15 +74,15 @@ int64_t read_sectors(HANDLE hDrive, uint64_t SectorSize,
|
||||||
ptr.QuadPart = StartSector*SectorSize;
|
ptr.QuadPart = StartSector*SectorSize;
|
||||||
if(!SetFilePointerEx(hDrive, ptr, NULL, FILE_BEGIN))
|
if(!SetFilePointerEx(hDrive, ptr, NULL, FILE_BEGIN))
|
||||||
{
|
{
|
||||||
uprintf("read_sectors: Could not access sector %d - %s\n", StartSector, WindowsErrorString());
|
uprintf("read_sectors: Could not access sector 0x%08llx - %s\n", StartSector, WindowsErrorString());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((!ReadFile(hDrive, pBuf, Size, &Size, NULL)) || (Size != nSectors*SectorSize))
|
if((!ReadFile(hDrive, pBuf, Size, &Size, NULL)) || (Size != nSectors*SectorSize))
|
||||||
{
|
{
|
||||||
uprintf("read_sectors: Read error - %s\n", WindowsErrorString());
|
uprintf("read_sectors: Read error %s\n", (GetLastError()!=ERROR_SUCCESS)?WindowsErrorString():"");
|
||||||
uprintf(" Read: %d, Expected: %d\n", Size, nSectors*SectorSize);
|
uprintf(" Read: %d, Expected: %lld\n", Size, nSectors*SectorSize);
|
||||||
uprintf(" StartSector:%0X, nSectors:%0X, SectorSize:%0X\n", StartSector, nSectors, SectorSize);
|
uprintf(" StartSector: 0x%08llx, nSectors: 0x%llx, SectorSize: 0x%llx\n", StartSector, nSectors, SectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int64_t)Size;
|
return (int64_t)Size;
|
||||||
|
|
12
src/rufus.c
12
src/rufus.c
|
@ -624,7 +624,7 @@ static BOOL GetUSBDevices(DWORD devnum)
|
||||||
if(GetLastError() != ERROR_NO_MORE_ITEMS) {
|
if(GetLastError() != ERROR_NO_MORE_ITEMS) {
|
||||||
uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString());
|
uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString());
|
||||||
} else {
|
} else {
|
||||||
uprintf("A device was eliminated because it didn't report itself as a disk\n");
|
uprintf("A device was eliminated because it didn't report itself as a removable disk\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1252,7 @@ static BOOL BootCheck(void)
|
||||||
"- Select 'Yes' to connect to the internet and download the file\n"
|
"- Select 'Yes' to connect to the internet and download the file\n"
|
||||||
"- Select 'No' if you will manually copy this file on the drive later\n\n"
|
"- Select 'No' if you will manually copy this file on the drive later\n\n"
|
||||||
"Note: The file will be downloaded in the current directory and once a "
|
"Note: The file will be downloaded in the current directory and once a "
|
||||||
"'%s' exists there, it will be reused automatically.\n", ldlinux_c32, ldlinux_c32, ldlinux_c32);
|
"'%s' exists there, it will be reused automatically.\n", ldlinux_c32, ldlinux_c32);
|
||||||
safe_sprintf(msgbox_title, sizeof(msgbox_title), "Download %s?", ldlinux_c32);
|
safe_sprintf(msgbox_title, sizeof(msgbox_title), "Download %s?", ldlinux_c32);
|
||||||
r = MessageBoxU(hMainDialog, msgbox, msgbox_title, MB_YESNOCANCEL|MB_ICONWARNING);
|
r = MessageBoxU(hMainDialog, msgbox, msgbox_title, MB_YESNOCANCEL|MB_ICONWARNING);
|
||||||
if (r == IDCANCEL)
|
if (r == IDCANCEL)
|
||||||
|
@ -1819,8 +1819,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_ERROR, 0);
|
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_ERROR, 0);
|
||||||
SetTaskbarProgressState(TASKBAR_ERROR);
|
SetTaskbarProgressState(TASKBAR_ERROR);
|
||||||
PrintStatus(0, FALSE, "FAILED");
|
PrintStatus(0, FALSE, "FAILED");
|
||||||
Notification(MSG_ERROR, NULL, "Error", "Error: %s.%s", StrError(FormatStatus),
|
Notification(MSG_ERROR, NULL, "Error", "Error: %s", StrError(FormatStatus));
|
||||||
(strchr(StrError(FormatStatus), '\n') != NULL)?"":"\nFor more information, please check the log.");
|
|
||||||
}
|
}
|
||||||
FormatStatus = 0;
|
FormatStatus = 0;
|
||||||
format_op_in_progress = FALSE;
|
format_op_in_progress = FALSE;
|
||||||
|
@ -1919,8 +1918,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
wait_for_mutex = 150; // Try to acquire the mutex for 15 seconds
|
wait_for_mutex = 150; // Try to acquire the mutex for 15 seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "?hi:w:", long_options, &option_index)) != EOF)
|
while ((opt = getopt_long(argc, argv, "?fhi:w:", long_options, &option_index)) != EOF)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'f':
|
||||||
|
enable_fixed_disks = TRUE;
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
if (_access(optarg, 0) != -1) {
|
if (_access(optarg, 0) != -1) {
|
||||||
iso_path = safe_strdup(optarg);
|
iso_path = safe_strdup(optarg);
|
||||||
|
|
|
@ -307,6 +307,7 @@ extern HANDLE GetLogicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDr
|
||||||
extern char GetDriveLetter(DWORD DriveIndex);
|
extern char GetDriveLetter(DWORD DriveIndex);
|
||||||
extern char GetUnusedDriveLetter(void);
|
extern char GetUnusedDriveLetter(void);
|
||||||
extern BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker);
|
extern BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker);
|
||||||
|
extern BOOL DeletePartitions(HANDLE hDrive);
|
||||||
extern const char* GetPartitionType(BYTE Type);
|
extern const char* GetPartitionType(BYTE Type);
|
||||||
extern BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize);
|
extern BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize);
|
||||||
extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label);
|
extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label);
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -30,7 +30,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 206, 329
|
IDD_DIALOG DIALOGEX 12, 12, 206, 329
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_APPWINDOW
|
EXSTYLE WS_EX_APPWINDOW
|
||||||
CAPTION "Rufus v1.3.4.257"
|
CAPTION "Rufus v1.3.4.258"
|
||||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Start",IDC_START,94,291,50,14
|
DEFPUSHBUTTON "Start",IDC_START,94,291,50,14
|
||||||
|
@ -278,8 +278,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,3,4,257
|
FILEVERSION 1,3,4,258
|
||||||
PRODUCTVERSION 1,3,4,257
|
PRODUCTVERSION 1,3,4,258
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -296,13 +296,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "1.3.4.257"
|
VALUE "FileVersion", "1.3.4.258"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2013 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2013 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus.exe"
|
VALUE "OriginalFilename", "rufus.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "1.3.4.257"
|
VALUE "ProductVersion", "1.3.4.258"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
59
src/stdio.c
59
src/stdio.c
|
@ -219,60 +219,61 @@ const char* StrError(DWORD error_code)
|
||||||
}
|
}
|
||||||
switch (SCODE_CODE(error_code)) {
|
switch (SCODE_CODE(error_code)) {
|
||||||
case ERROR_GEN_FAILURE:
|
case ERROR_GEN_FAILURE:
|
||||||
return "Undetermined error while formatting";
|
return "Undetermined error while formatting.";
|
||||||
case ERROR_INCOMPATIBLE_FS:
|
case ERROR_INCOMPATIBLE_FS:
|
||||||
return "Cannot use the selected file system for this media";
|
return "Cannot use the selected file system for this media.";
|
||||||
case ERROR_ACCESS_DENIED:
|
case ERROR_ACCESS_DENIED:
|
||||||
return "Access to the media is denied";
|
return "Access to the device is denied.";
|
||||||
case ERROR_WRITE_PROTECT:
|
case ERROR_WRITE_PROTECT:
|
||||||
return "Media is write protected";
|
return "Media is write protected.";
|
||||||
case ERROR_DEVICE_IN_USE:
|
case ERROR_DEVICE_IN_USE:
|
||||||
return "The device is in use by another process\n"
|
return "The device is in use by another process. "
|
||||||
"Please close any other process that may be accessing the device";
|
"Please close any other process that may be accessing the device.";
|
||||||
case ERROR_CANT_QUICK_FORMAT:
|
case ERROR_CANT_QUICK_FORMAT:
|
||||||
return "Quick format is not available for this device";
|
return "Quick format is not available for this device.";
|
||||||
case ERROR_LABEL_TOO_LONG:
|
case ERROR_LABEL_TOO_LONG:
|
||||||
return "The volume label is invalid";
|
return "The volume label is invalid.";
|
||||||
|
case ERROR_INVALID_HANDLE:
|
||||||
|
return "The device handle is invalid.";
|
||||||
case ERROR_INVALID_CLUSTER_SIZE:
|
case ERROR_INVALID_CLUSTER_SIZE:
|
||||||
return "The selected cluster size is not valid for this device";
|
return "The selected cluster size is not valid for this device.";
|
||||||
case ERROR_INVALID_VOLUME_SIZE:
|
case ERROR_INVALID_VOLUME_SIZE:
|
||||||
return "The volume size is invalid";
|
return "The volume size is invalid.";
|
||||||
case ERROR_NO_MEDIA_IN_DRIVE:
|
case ERROR_NO_MEDIA_IN_DRIVE:
|
||||||
return "Please insert a media in drive";
|
return "Please insert a media in drive.";
|
||||||
case ERROR_NOT_SUPPORTED:
|
case ERROR_NOT_SUPPORTED:
|
||||||
return "An unsupported command was received";
|
return "An unsupported command was received.";
|
||||||
case ERROR_NOT_ENOUGH_MEMORY:
|
case ERROR_NOT_ENOUGH_MEMORY:
|
||||||
return "Memory allocation error";
|
return "Memory allocation error.";
|
||||||
case ERROR_READ_FAULT:
|
case ERROR_READ_FAULT:
|
||||||
return "Read error";
|
return "Read error.";
|
||||||
case ERROR_WRITE_FAULT:
|
case ERROR_WRITE_FAULT:
|
||||||
return "Write error";
|
return "Write error.";
|
||||||
case ERROR_OPEN_FAILED:
|
case ERROR_OPEN_FAILED:
|
||||||
return "Could not open media. It may be in use by another process.\n"
|
return "Could not open media. It may be in use by another process. "
|
||||||
"Please re-plug the media and try again";
|
"Please re-plug the media and try again.";
|
||||||
case ERROR_PARTITION_FAILURE:
|
case ERROR_PARTITION_FAILURE:
|
||||||
return "Error while partitioning drive";
|
return "Error while partitioning drive.";
|
||||||
case ERROR_CANNOT_COPY:
|
case ERROR_CANNOT_COPY:
|
||||||
return "Could not copy files to target drive";
|
return "Could not copy files to target drive.";
|
||||||
case ERROR_CANCELLED:
|
case ERROR_CANCELLED:
|
||||||
return "Cancelled by user";
|
return "Cancelled by user.";
|
||||||
case ERROR_CANT_START_THREAD:
|
case ERROR_CANT_START_THREAD:
|
||||||
return "Unable to create formatting thread";
|
return "Unable to create formatting thread.";
|
||||||
case ERROR_BADBLOCKS_FAILURE:
|
case ERROR_BADBLOCKS_FAILURE:
|
||||||
return "Bad blocks check didn't complete";
|
return "Bad blocks check didn't complete.";
|
||||||
case ERROR_ISO_SCAN:
|
case ERROR_ISO_SCAN:
|
||||||
return "ISO image scan failure";
|
return "ISO image scan failure.";
|
||||||
case ERROR_ISO_EXTRACT:
|
case ERROR_ISO_EXTRACT:
|
||||||
return "ISO image extraction failure";
|
return "ISO image extraction failure.";
|
||||||
case ERROR_CANT_REMOUNT_VOLUME:
|
case ERROR_CANT_REMOUNT_VOLUME:
|
||||||
return "Unable to remount volume. You may have to use the\n"
|
return "Unable to remount volume.";
|
||||||
"mountvol.exe command to make your device accessible again";
|
|
||||||
case ERROR_CANT_PATCH:
|
case ERROR_CANT_PATCH:
|
||||||
return "Unable to patch/setup files for boot";
|
return "Unable to patch/setup files for boot.";
|
||||||
case ERROR_CANT_ASSIGN_LETTER:
|
case ERROR_CANT_ASSIGN_LETTER:
|
||||||
return "Unable to assign a drive letter";
|
return "Unable to assign a drive letter.";
|
||||||
case ERROR_CANT_MOUNT_VOLUME:
|
case ERROR_CANT_MOUNT_VOLUME:
|
||||||
return "Can't mount GUID volume";
|
return "Can't mount GUID volume.";
|
||||||
default:
|
default:
|
||||||
uprintf("Unknown error: %08X\n", error_code);
|
uprintf("Unknown error: %08X\n", error_code);
|
||||||
SetLastError(error_code);
|
SetLastError(error_code);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue