mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-19 09:25:12 -04:00
[core] add HDD vs UFD detection
* Initial scoring to try to differentiate UFDs from HDDs (#219) * Also improve GetDriveLetter() and add a global for fixed vs removable * Also fix a bug with reporting of VID:PID with multiple devices * Also fix a warning in localization
This commit is contained in:
parent
803a4bff1c
commit
aa0bf0ee2b
7 changed files with 165 additions and 38 deletions
38
src/drive.c
38
src/drive.c
|
@ -36,7 +36,7 @@
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
RUFUS_DRIVE_INFO SelectedDrive;
|
RUFUS_DRIVE_INFO SelectedDrive;
|
||||||
extern BOOL enable_fixed_disks;
|
extern UINT drive_type;
|
||||||
|
|
||||||
// TODO: add a DetectSectorSize()?
|
// TODO: add a DetectSectorSize()?
|
||||||
// http://msdn.microsoft.com/en-us/library/ff800831.aspx
|
// http://msdn.microsoft.com/en-us/library/ff800831.aspx
|
||||||
|
@ -136,11 +136,11 @@ char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
VOLUME_DISK_EXTENTS DiskExtents;
|
VOLUME_DISK_EXTENTS DiskExtents;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
UINT drive_type;
|
|
||||||
int i, j;
|
int i, j;
|
||||||
static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" };
|
static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" };
|
||||||
static const char* volume_start = "\\\\?\\";
|
static const char* volume_start = "\\\\?\\";
|
||||||
|
|
||||||
|
drive_type = DRIVE_UNKNOWN;
|
||||||
CheckDriveIndex(DriveIndex);
|
CheckDriveIndex(DriveIndex);
|
||||||
|
|
||||||
for (i=0; hDrive == INVALID_HANDLE_VALUE; i++) {
|
for (i=0; hDrive == INVALID_HANDLE_VALUE; i++) {
|
||||||
|
@ -167,9 +167,7 @@ char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent
|
||||||
}
|
}
|
||||||
|
|
||||||
drive_type = GetDriveTypeA(volume_name);
|
drive_type = GetDriveTypeA(volume_name);
|
||||||
// NB: the HP utility allows drive_type == DRIVE_FIXED, which we don't allow by default
|
if ((drive_type != DRIVE_REMOVABLE) && (drive_type != DRIVE_FIXED))
|
||||||
// Using Alt-F in Rufus does enable listing, but this mode is unsupported.
|
|
||||||
if ((drive_type != DRIVE_REMOVABLE) && ((!enable_fixed_disks) || (drive_type != DRIVE_FIXED)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
volume_name[len-1] = 0;
|
volume_name[len-1] = 0;
|
||||||
|
@ -257,16 +255,17 @@ HANDLE GetLogicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDrive)
|
||||||
/*
|
/*
|
||||||
* Returns the first drive letter for a volume located on the drive identified by DriveIndex
|
* Returns the first drive letter for a volume located on the drive identified by DriveIndex
|
||||||
*/
|
*/
|
||||||
char GetDriveLetter(DWORD DriveIndex)
|
BOOL GetDriveLetter(DWORD DriveIndex, char* drive_letter)
|
||||||
{
|
{
|
||||||
DWORD size;
|
DWORD size;
|
||||||
BOOL r;
|
BOOL r = FALSE;
|
||||||
STORAGE_DEVICE_NUMBER_REDEF device_number = {0};
|
STORAGE_DEVICE_NUMBER_REDEF device_number = {0};
|
||||||
UINT drive_type;
|
|
||||||
HANDLE hDrive = INVALID_HANDLE_VALUE;
|
HANDLE hDrive = INVALID_HANDLE_VALUE;
|
||||||
char *drive, drives[26*4]; /* "D:\", "E:\", etc. */
|
char *drive, drives[26*4]; /* "D:\", "E:\", etc. */
|
||||||
char logical_drive[] = "\\\\.\\#:";
|
char logical_drive[] = "\\\\.\\#:";
|
||||||
char drive_letter = ' ';
|
|
||||||
|
drive_type = DRIVE_UNKNOWN;
|
||||||
|
*drive_letter = ' ';
|
||||||
CheckDriveIndex(DriveIndex);
|
CheckDriveIndex(DriveIndex);
|
||||||
|
|
||||||
size = GetLogicalDriveStringsA(sizeof(drives), drives);
|
size = GetLogicalDriveStringsA(sizeof(drives), drives);
|
||||||
|
@ -279,6 +278,7 @@ char GetDriveLetter(DWORD DriveIndex)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = TRUE;
|
||||||
for (drive = drives ;*drive; drive += safe_strlen(drive)+1) {
|
for (drive = drives ;*drive; drive += safe_strlen(drive)+1) {
|
||||||
if (!isalpha(*drive))
|
if (!isalpha(*drive))
|
||||||
continue;
|
continue;
|
||||||
|
@ -292,9 +292,8 @@ char GetDriveLetter(DWORD DriveIndex)
|
||||||
value there => Use GetDriveType() to filter out unwanted devices.
|
value there => Use GetDriveType() to filter out unwanted devices.
|
||||||
See https://github.com/pbatard/rufus/issues/32 for details. */
|
See https://github.com/pbatard/rufus/issues/32 for details. */
|
||||||
drive_type = GetDriveTypeA(drive);
|
drive_type = GetDriveTypeA(drive);
|
||||||
// NB: the HP utility allows drive_type == DRIVE_FIXED, which we don't allow by default
|
|
||||||
// Using Alt-F in Rufus does enable listing, but this mode is unsupported.
|
if ((drive_type != DRIVE_REMOVABLE) && (drive_type != DRIVE_FIXED))
|
||||||
if ((drive_type != DRIVE_REMOVABLE) && ((!enable_fixed_disks) || (drive_type != DRIVE_FIXED)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]);
|
safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]);
|
||||||
|
@ -305,19 +304,19 @@ char GetDriveLetter(DWORD DriveIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL,
|
r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL,
|
||||||
0, &device_number, sizeof(device_number), &size, NULL);
|
0, &device_number, sizeof(device_number), &size, NULL) && (size > 0);
|
||||||
safe_closehandle(hDrive);
|
safe_closehandle(hDrive);
|
||||||
if ((!r) || (size <= 0)) {
|
if (!r) {
|
||||||
uprintf("Could not get device number for device %s: %s\n",
|
uprintf("Could not get device number for device %s: %s\n",
|
||||||
logical_drive, WindowsErrorString());
|
logical_drive, WindowsErrorString());
|
||||||
} else if (device_number.DeviceNumber == DriveIndex) {
|
} else if (device_number.DeviceNumber == DriveIndex) {
|
||||||
drive_letter = *drive;
|
*drive_letter = *drive;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return drive_letter;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -368,10 +367,11 @@ BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label)
|
||||||
|
|
||||||
*label = STR_NO_LABEL;
|
*label = STR_NO_LABEL;
|
||||||
|
|
||||||
*letter = GetDriveLetter(DriveIndex);
|
if (!GetDriveLetter(DriveIndex, letter))
|
||||||
|
return FALSE;
|
||||||
if (*letter == ' ') {
|
if (*letter == ' ') {
|
||||||
// Drive without volume assigned - Tie to the display of fixed disks
|
// Drive without volume assigned - always enabled
|
||||||
return enable_fixed_disks;
|
return TRUE;
|
||||||
}
|
}
|
||||||
AutorunPath[0] = *letter;
|
AutorunPath[0] = *letter;
|
||||||
wDrivePath[0] = *letter;
|
wDrivePath[0] = *letter;
|
||||||
|
|
|
@ -1195,7 +1195,11 @@ DWORD WINAPI FormatThread(LPVOID param)
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this stage with have both a handle and a lock to the physical drive...
|
// At this stage with have both a handle and a lock to the physical drive...
|
||||||
drive_name[0] = GetDriveLetter(DriveIndex);
|
if (!GetDriveLetter(DriveIndex, &drive_name[0])) {
|
||||||
|
uprintf("Failed to get a drive letter\n");
|
||||||
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_ASSIGN_LETTER);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (drive_name[0] == ' ') {
|
if (drive_name[0] == ' ') {
|
||||||
uprintf("No drive letter was assigned...\n");
|
uprintf("No drive letter was assigned...\n");
|
||||||
drive_name[0] = GetUnusedDriveLetter();
|
drive_name[0] = GetUnusedDriveLetter();
|
||||||
|
|
|
@ -199,7 +199,7 @@ static uint32_t htab_hash(char* str)
|
||||||
do {
|
do {
|
||||||
// Because size is prime this guarantees to step through all available indexes
|
// Because size is prime this guarantees to step through all available indexes
|
||||||
if (idx <= hval2) {
|
if (idx <= hval2) {
|
||||||
idx = htab_size + idx - hval2;
|
idx = ((uint32_t)htab_size) + idx - hval2;
|
||||||
} else {
|
} else {
|
||||||
idx -= hval2;
|
idx -= hval2;
|
||||||
}
|
}
|
||||||
|
|
29
src/rufus.c
29
src/rufus.c
|
@ -117,7 +117,8 @@ HWND hDeviceList, hPartitionScheme, hFileSystem, hClusterSize, hLabel, hBootType
|
||||||
HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID;
|
HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID;
|
||||||
BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
|
BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
|
||||||
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE;
|
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE;
|
||||||
BOOL enable_fixed_disks = FALSE, advanced_mode = TRUE, force_update = FALSE;
|
BOOL enable_HDDs = FALSE, advanced_mode = TRUE, force_update = FALSE;
|
||||||
|
UINT drive_type = DRIVE_UNKNOWN;
|
||||||
int dialog_showing = 0;
|
int dialog_showing = 0;
|
||||||
uint16_t rufus_version[4];
|
uint16_t rufus_version[4];
|
||||||
RUFUS_UPDATE update = { {0,0,0,0}, {0,0}, NULL, NULL};
|
RUFUS_UPDATE update = { {0,0,0,0}, {0,0}, NULL, NULL};
|
||||||
|
@ -602,6 +603,7 @@ static BOOL GetUSBDevices(DWORD devnum)
|
||||||
HANDLE hDrive;
|
HANDLE hDrive;
|
||||||
LONG maxwidth = 0;
|
LONG maxwidth = 0;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
int score;
|
||||||
char drive_letter, *devid, *devid_list = NULL;
|
char drive_letter, *devid, *devid_list = NULL;
|
||||||
char *label, *entry, buffer[MAX_PATH], str[sizeof("0000:0000")+1];
|
char *label, *entry, buffer[MAX_PATH], str[sizeof("0000:0000")+1];
|
||||||
const char* usbstor_name = "USBSTOR";
|
const char* usbstor_name = "USBSTOR";
|
||||||
|
@ -653,7 +655,7 @@ static BOOL GetUSBDevices(DWORD devnum)
|
||||||
} else {
|
} else {
|
||||||
// Get the VID:PID of the device. We could avoid doing this lookup every time by keeping
|
// Get the VID:PID of the device. We could avoid doing this lookup every time by keeping
|
||||||
// a lookup table, but there shouldn't be that many USB storage devices connected...
|
// a lookup table, but there shouldn't be that many USB storage devices connected...
|
||||||
for (devid = devid_list; *devid; devid += strlen(devid_list) + 1) {
|
for (devid = devid_list; *devid; devid += strlen(devid) + 1) {
|
||||||
if ( (CM_Locate_DevNodeA(&parent_inst, devid, 0) == 0)
|
if ( (CM_Locate_DevNodeA(&parent_inst, devid, 0) == 0)
|
||||||
&& (CM_Get_Child(&device_inst, parent_inst, 0) == 0)
|
&& (CM_Get_Child(&device_inst, parent_inst, 0) == 0)
|
||||||
&& (device_inst == dev_info_data.DevInst) ) {
|
&& (device_inst == dev_info_data.DevInst) ) {
|
||||||
|
@ -684,7 +686,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 non fixed USB disk\n");
|
uprintf("A device was eliminated because it didn't report itself as a disk\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -730,12 +732,19 @@ static BOOL GetUSBDevices(DWORD devnum)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identify(hDrive);
|
|
||||||
|
|
||||||
if (GetDriveLabel(device_number.DeviceNumber + DRIVE_INDEX_MIN, &drive_letter, &label)) {
|
if (GetDriveLabel(device_number.DeviceNumber + DRIVE_INDEX_MIN, &drive_letter, &label)) {
|
||||||
// Must ensure that the combo box is UNSORTED for indexes to be the same
|
// Must ensure that the combo box is UNSORTED for indexes to be the same
|
||||||
StrArrayAdd(&DriveID, buffer);
|
StrArrayAdd(&DriveID, buffer);
|
||||||
StrArrayAdd(&DriveLabel, label);
|
StrArrayAdd(&DriveLabel, label);
|
||||||
|
|
||||||
|
if ((!enable_HDDs) && ((score = IsHDD(drive_type, vid, pid, buffer)) > IS_HDD_THRESHOLD)) {
|
||||||
|
uprintf("USB HDD device removed (score %d > %d) "
|
||||||
|
"[Note: You can enable USB HDDs in the Advanced Options]\n", score, IS_HDD_THRESHOLD);
|
||||||
|
safe_closehandle(hDrive);
|
||||||
|
safe_free(devint_detail_data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Drive letter ' ' is returned for drives that don't have a volume assigned yet
|
// Drive letter ' ' is returned for drives that don't have a volume assigned yet
|
||||||
if (drive_letter == ' ') {
|
if (drive_letter == ' ') {
|
||||||
entry = lmprintf(MSG_046, label, device_number.DeviceNumber);
|
entry = lmprintf(MSG_046, label, device_number.DeviceNumber);
|
||||||
|
@ -1809,8 +1818,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
case IDC_ENABLE_FIXED_DISKS:
|
case IDC_ENABLE_FIXED_DISKS:
|
||||||
if ((HIWORD(wParam)) == BN_CLICKED) {
|
if ((HIWORD(wParam)) == BN_CLICKED) {
|
||||||
enable_fixed_disks = !enable_fixed_disks;
|
enable_HDDs = !enable_HDDs;
|
||||||
PrintStatus2000(lmprintf(MSG_253), enable_fixed_disks);
|
PrintStatus2000(lmprintf(MSG_253), enable_HDDs);
|
||||||
GetUSBDevices(0);
|
GetUSBDevices(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2030,7 +2039,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
while ((opt = getopt_long(argc, argv, "?fhi:w:l:", long_options, &option_index)) != EOF)
|
while ((opt = getopt_long(argc, argv, "?fhi:w:l:", long_options, &option_index)) != EOF)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'f':
|
case 'f':
|
||||||
enable_fixed_disks = TRUE;
|
enable_HDDs = TRUE;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
if (_access(optarg, 0) != -1) {
|
if (_access(optarg, 0) != -1) {
|
||||||
|
@ -2166,8 +2175,8 @@ relaunch:
|
||||||
// This is a safety feature, to avoid someone unintentionally formatting a backup
|
// This is a safety feature, to avoid someone unintentionally formatting a backup
|
||||||
// drive instead of an USB key. If this is enabled, Rufus will allow fixed disk formatting.
|
// drive instead of an USB key. If this is enabled, Rufus will allow fixed disk formatting.
|
||||||
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'F')) {
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'F')) {
|
||||||
enable_fixed_disks = !enable_fixed_disks;
|
enable_HDDs = !enable_HDDs;
|
||||||
PrintStatus2000(lmprintf(MSG_253), enable_fixed_disks);
|
PrintStatus2000(lmprintf(MSG_253), enable_HDDs);
|
||||||
GetUSBDevices(0);
|
GetUSBDevices(0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#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 IS_HDD_THRESHOLD 5
|
||||||
#define WHITE RGB(255,255,255)
|
#define WHITE RGB(255,255,255)
|
||||||
#define SEPARATOR_GREY RGB(223,223,223)
|
#define SEPARATOR_GREY RGB(223,223,223)
|
||||||
#define RUFUS_URL "http://rufus.akeo.ie"
|
#define RUFUS_URL "http://rufus.akeo.ie"
|
||||||
|
@ -319,7 +320,7 @@ extern HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockD
|
||||||
extern BOOL WaitForLogical(DWORD DriveIndex);
|
extern BOOL WaitForLogical(DWORD DriveIndex);
|
||||||
extern char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
extern char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent);
|
||||||
extern HANDLE GetLogicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDrive);
|
extern HANDLE GetLogicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDrive);
|
||||||
extern char GetDriveLetter(DWORD DriveIndex);
|
extern BOOL GetDriveLetter(DWORD DriveIndex, char* drive_letter);
|
||||||
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 BOOL DeletePartitions(HANDLE hDrive);
|
||||||
|
@ -350,7 +351,7 @@ extern char* replace_in_token_data(const char* filename, const char* token, cons
|
||||||
extern void parse_update(char* buf, size_t len);
|
extern void parse_update(char* buf, size_t len);
|
||||||
extern BOOL WimExtractCheck(void);
|
extern BOOL WimExtractCheck(void);
|
||||||
extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst);
|
extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst);
|
||||||
extern BOOL Identify(HANDLE hPhysical);
|
extern int IsHDD(UINT drive_type, uint16_t vid, uint16_t pid, const char* strid);
|
||||||
|
|
||||||
static __inline BOOL UnlockDrive(HANDLE hDrive)
|
static __inline BOOL UnlockDrive(HANDLE hDrive)
|
||||||
{
|
{
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,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.4.0.315"
|
CAPTION "Rufus v1.4.0.316"
|
||||||
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
|
||||||
|
@ -289,8 +289,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,4,0,315
|
FILEVERSION 1,4,0,316
|
||||||
PRODUCTVERSION 1,4,0,315
|
PRODUCTVERSION 1,4,0,316
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -307,13 +307,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.4.0.315"
|
VALUE "FileVersion", "1.4.0.316"
|
||||||
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.4.0.315"
|
VALUE "ProductVersion", "1.4.0.316"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
113
src/smart.c
113
src/smart.c
|
@ -397,4 +397,117 @@ BOOL SmartGetVersion(HANDLE hdevice)
|
||||||
* - if IDENTIFY reports SMART capabilities
|
* - if IDENTIFY reports SMART capabilities
|
||||||
* - if it has extra non hidden partitions that aren't Windows
|
* - if it has extra non hidden partitions that aren't Windows
|
||||||
* - if the VID:PID (or VID) is of known USB to IDE/SATA bridge or known UFD maker
|
* - if the VID:PID (or VID) is of known USB to IDE/SATA bridge or known UFD maker
|
||||||
|
* - removable flag (how do you actually find that one?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* name;
|
||||||
|
const int score;
|
||||||
|
} str_score;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const uint16_t vid;
|
||||||
|
const int score;
|
||||||
|
} vid_score;
|
||||||
|
|
||||||
|
// If a disk ID starts with these, we consider it likely to be an HDD
|
||||||
|
// The info from http://knowledge.seagate.com/articles/en_US/FAQ/204763en is a start, but not
|
||||||
|
// entirely accurate for our usage as some models will be prefixed with the manufacturer name
|
||||||
|
// '#' below means any number in [0-9]
|
||||||
|
static str_score manufacturer_str[] = {
|
||||||
|
{ "HP ", 10 },
|
||||||
|
{ "ST#", 10 },
|
||||||
|
{ "MX#", 10 },
|
||||||
|
{ "WDC", 10 },
|
||||||
|
{ "IBM", 10 },
|
||||||
|
{ "STM#", 10 },
|
||||||
|
{ "HTS#", 10 },
|
||||||
|
{ "MAXTOR", 10 },
|
||||||
|
{ "HITACHI", 10 },
|
||||||
|
{ "SEAGATE", 10 },
|
||||||
|
{ "SAMSUNG", 10 },
|
||||||
|
{ "FUJITSU", 10 },
|
||||||
|
{ "TOSHIBA", 10 },
|
||||||
|
{ "QUANTUM", 10 },
|
||||||
|
};
|
||||||
|
|
||||||
|
// http://www.linux-usb.org/usb.ids
|
||||||
|
static vid_score manufacturer_vid[] = {
|
||||||
|
{ 0x04b4, 10 }, // Cypress
|
||||||
|
{ 0x067b, 10 }, // Prolific
|
||||||
|
{ 0x0bc2, 10 }, // Seagate
|
||||||
|
{ 0x152d, 10 }, // JMicron
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This attempts to detect whether a drive is an USB HDD or an USB Flash Drive (UFD).
|
||||||
|
* If someone already has an USB HDD plugged in (say as a backup drive) and plugs an
|
||||||
|
* UFD we *try* to do what we can to avoid them formatting that drive by mistake.
|
||||||
|
* But because there is no foolproof (let alone easy), way to differentiate UFDs from
|
||||||
|
* HDDs, thanks to every manufacturer, Microsoft, and their mothers making it
|
||||||
|
* exceedingly troublesome to find out what type of hardware we are actually accessing
|
||||||
|
* please pay heed to the following warning:
|
||||||
|
*
|
||||||
|
* WARNING: NO PROMISE IS MADE ABOUT THIS ALGORITHM BEING ABLE TO CORRECTLY
|
||||||
|
* DIFFERENTIATE AN USB HDD FROM A FLASH DRIVE. ALSO, REMEMBER THAT THE LICENSE OF THIS
|
||||||
|
* APPLICATION MAKES ABSOLUETLY NO PROMISE ABOUT DATA PRESERVATION (PROVIDED "AS IS").
|
||||||
|
* THUS, IF DATA LOSS IS INCURRED DUE TO THE ALGORITHM BELOW, OR ANY OTHER PART OF THIS
|
||||||
|
* APPLICATION, THE RESPONSIBILITY IS ENTIRELY ON YOU!
|
||||||
|
*
|
||||||
|
* But let me just elaborate further on why differentiating UFDs from HDDs is not as
|
||||||
|
* 'simple' as it seems:
|
||||||
|
* - many USB flash drives manufacturer will present UFDs as non-removable, which used
|
||||||
|
* to be reserved for HDDs => we can't use that as differentiator.
|
||||||
|
* - some UFDs (SanDisk Extreme) have added S.M.A.R.T. support, which also used to be
|
||||||
|
* reserved for HDDs => can't use that either
|
||||||
|
* - even if S.M.A.R.T. was enough, not all USB->IDE or USB->SATA bridges support ATA
|
||||||
|
* passthrough, which is required S.M.A.R.T. data, and each manufacturer of an
|
||||||
|
* USB<->(S)ATA bridge seem to have their own method of implementing passthrough.
|
||||||
|
* - SSDs have also changed the deal completely, as you can get something that looks
|
||||||
|
* like Flash but that is really an HDD.
|
||||||
|
* - Some manufacturers (eg. ALI) provide both USB Flash controllers and USB IDE/SATA
|
||||||
|
* controllers, so we can't exactly use the VID to say for sure what we're looking at.
|
||||||
|
* - Finally, Microsoft is abdsolutely no help either (which is kind of understandable
|
||||||
|
* from the above) => there is no magic API we can query that will tell us what we're
|
||||||
|
* really looking at.
|
||||||
|
*
|
||||||
|
* What you have below, then, is our *current best guess* at differentiating an UFD from
|
||||||
|
* an HDD. Short of a crystal ball however, this remains just a guess, which may be way
|
||||||
|
* off mark. Still, Rufus does produce PROMINENT warnings before you format a drive, and
|
||||||
|
* also provides extensive info about the drive (from the toolips and the log) => PAY
|
||||||
|
* ATTENTION TO THESE OR PAY THE PRICE!
|
||||||
|
*/
|
||||||
|
int IsHDD(UINT drive_type, uint16_t vid, uint16_t pid, const char* strid)
|
||||||
|
{
|
||||||
|
int score = 0;
|
||||||
|
size_t i, mlen, ilen;
|
||||||
|
BOOL wc;
|
||||||
|
|
||||||
|
if (drive_type == DRIVE_FIXED)
|
||||||
|
score += 3;
|
||||||
|
|
||||||
|
ilen = safe_strlen(strid);
|
||||||
|
for (i=0; i<ARRAYSIZE(manufacturer_str); i++) {
|
||||||
|
mlen = strlen(manufacturer_str[i].name);
|
||||||
|
if (mlen > ilen)
|
||||||
|
break;
|
||||||
|
wc = (manufacturer_str[i].name[mlen-1] == '#');
|
||||||
|
if ( (_strnicmp(strid, manufacturer_str[i].name, mlen-((wc)?1:0)) == 0)
|
||||||
|
&& ((!wc) || ((strid[mlen] >= '0') && (strid[mlen] <= '9'))) ) {
|
||||||
|
score += manufacturer_str[i].score;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<ARRAYSIZE(manufacturer_vid); i++) {
|
||||||
|
if (vid == manufacturer_vid[i].vid) {
|
||||||
|
score += manufacturer_vid[i].score;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: try to perform inquiry if uncertain
|
||||||
|
// TODO: lower the score for well known UFD manufacturers (ADATA, SanDisk, etc.)
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue