1
1
Fork 0
mirror of https://github.com/pbatard/rufus.git synced 2024-08-14 23:57:05 +00:00

[core] finalize UFD vs HDD detection

* Closes #219
This commit is contained in:
Pete Batard 2013-11-15 21:39:40 +00:00
parent aa0bf0ee2b
commit 5d51610c70
9 changed files with 336 additions and 81 deletions

View file

@ -6,6 +6,9 @@ the same changes.
Remember to also update the version number for your translation ('v x.y.z') Remember to also update the version number for your translation ('v x.y.z')
once you have matched all the changes that occurred for the en-US translation. once you have matched all the changes that occurred for the en-US translation.
o Version 1.0.3 (2013.11.15)
- IDC_ENABLE_FIXED_DISKS "List non removable or unpartitioned USB disks" -> "List USB Hard Drives"
- MSG_170 "Enable detection for disks not normally detected by Rufus" -> "Enable the listing of USB Hard Drive enclosures"
o Version 1.0.2 (2013.10.30) o Version 1.0.2 (2013.10.30)
- *NEW* MSG_110 "MS-DOS cannot boot from a drive using a 64 kilobyte Cluster size..." - *NEW* MSG_110 "MS-DOS cannot boot from a drive using a 64 kilobyte Cluster size..."
- *NEW* MSG_111 "Incompatible Cluster size" - *NEW* MSG_111 "Incompatible Cluster size"

View file

@ -53,7 +53,7 @@
# http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-LCID%5D.pdf # http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-LCID%5D.pdf
# for the LCID (0x####) codes you should use # for the LCID (0x####) codes you should use
l "en-US" "English (English)" 0x0409, 0x0809, 0x0c09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x3809, 0x3c09, 0x4009, 0x4409, 0x4809 l "en-US" "English (English)" 0x0409, 0x0809, 0x0c09, 0x1009, 0x1409, 0x1809, 0x1c09, 0x2009, 0x2409, 0x2809, 0x2c09, 0x3009, 0x3409, 0x3809, 0x3c09, 0x4009, 0x4409, 0x4809
v 1.0.2 v 1.0.3
# Main dialog # Main dialog
g IDD_DIALOG g IDD_DIALOG
@ -72,7 +72,7 @@ t IDC_LOG "Log"
t IDCANCEL "Close" t IDCANCEL "Close"
t IDC_START "Start" t IDC_START "Start"
t IDS_ADVANCED_OPTIONS_GRP "Advanced Options" t IDS_ADVANCED_OPTIONS_GRP "Advanced Options"
t IDC_ENABLE_FIXED_DISKS "List non removable or unpartitioned USB disks" t IDC_ENABLE_FIXED_DISKS "List USB Hard Drives"
t IDC_EXTRA_PARTITION "Add fixes for old BIOSes (extra partition, align, etc.)" t IDC_EXTRA_PARTITION "Add fixes for old BIOSes (extra partition, align, etc.)"
# 'MBR': See bhttp://en.wikipedia.org/wiki/Master_boot_record # 'MBR': See bhttp://en.wikipedia.org/wiki/Master_boot_record
# Rufus can install it's own custom MBR (the Rufus MBR), which also allows users # Rufus can install it's own custom MBR (the Rufus MBR), which also allows users
@ -318,7 +318,7 @@ t MSG_168 "Try to masquerade first bootable USB drive (usually 0x80) as a differ
"This should only be necessary if you install Windows XP and have more than one disk" "This should only be necessary if you install Windows XP and have more than one disk"
t MSG_169 "Create an extra hidden partition and try to align partitions boundaries.\n" t MSG_169 "Create an extra hidden partition and try to align partitions boundaries.\n"
"This can improve boot detection for older BIOSes" "This can improve boot detection for older BIOSes"
t MSG_170 "Enable detection for disks not normally detected by Rufus. USE AT YOUR OWN RISKS!!!" t MSG_170 "Enable the listing of USB Hard Drive enclosures. USE AT YOUR OWN RISKS!!!"
t MSG_171 "Start the formatting operation.\nThis will DESTROY any data on the target!" t MSG_171 "Start the formatting operation.\nThis will DESTROY any data on the target!"
t MSG_172 "Licensing information and credits" t MSG_172 "Licensing information and credits"
t MSG_173 "Click to select..." t MSG_173 "Click to select..."

View file

@ -199,6 +199,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="..\badblocks.h" /> <ClInclude Include="..\badblocks.h" />
<ClInclude Include="..\format.h" /> <ClInclude Include="..\format.h" />
<ClInclude Include="..\hdd_vs_ufd.h" />
<ClInclude Include="..\libcdio\cdio\cdio.h" /> <ClInclude Include="..\libcdio\cdio\cdio.h" />
<ClInclude Include="..\libcdio\cdio\iso9660.h" /> <ClInclude Include="..\libcdio\cdio\iso9660.h" />
<ClInclude Include="..\libcdio\cdio\logging.h" /> <ClInclude Include="..\libcdio\cdio\logging.h" />

View file

@ -116,6 +116,9 @@
<ClInclude Include="..\smart.h"> <ClInclude Include="..\smart.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\hdd_vs_ufd.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\res\rufus.ico"> <None Include="..\..\res\rufus.ico">

265
src/hdd_vs_ufd.h Normal file
View file

@ -0,0 +1,265 @@
/*
* Rufus: The Reliable USB Formatting Utility
* SMART HDD vs Flash detection - isHDD() tables
* Copyright © 2013 Pete Batard <pete@akeo.ie>
*
* Based in part on drivedb.h from Smartmontools:
* http://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h
* Copyright © 2003-11 Philip Williams, Bruce Allen
* Copyright © 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
*
* Also based on entries listed in the identification flash database
* (http://flashboot.ru/iflash/saved/) as well as the Linux USB IDs
* (http://www.linux-usb.org/usb.ids)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdint.h>
/*
* A positive score means HDD, a negative one an UFD
* The higher the absolute value, the greater the probability
*/
typedef struct {
const char* name;
const int score;
} str_score_t;
typedef struct {
const uint16_t vid;
const int score;
} vid_score_t;
typedef struct {
const uint16_t vid;
const uint16_t pid;
const int score;
} vidpid_score_t;
/*
* (UNUSED) The list below contains the most common flash VIDs
* according to (partial browsing of) http://flashboot.ru/iflash/saved/
*
* 0011 = Kingston
* 03f0 = HP
* 0420 = Chipsbank
* 046d = Logitech
* 048d = ITE
* 04f3 = Elan
* 058f = Alcor ALSO HDD
* 05dc = Lexar
* 05e3 = Genesys Logic
* 0718 = Imation Corp.
* 0781 = SanDisk
* 090c = Silicon Motion
* 0930 = Toshiba
* 093a = Pixart
* 0951 = Kingston
* 09da = A4 Tech
* 0bda = Realtek
* 0b27 = Ritek
* 0c76 = JMTek
* 0cf2 = ENE
* 1000 = Speed Tech
* 1002 = Hisun
* 1005 = Apacer Technology
* 1043 = iCreate
* 1221 = Kingston?
* 12d1 = Huawei
* 125f = Adata
* 1307 = USBest
* 13fe = Kingston
* 14cd = Super Top
* 1516 = CompUSA
* 1687 = Kingmax
* 18a5 = Verbatim ALSO HDD
* 18ec = Arkmicro
* 1908 = Ax216
* 1b1c = Corsair
* 1e3d = Chipsbank
* 1f75 = Innostor ALSO HDD
* 2001 = Micov
* 201e = Evdo
* 2188 = SMI
* 3538 = PQI
* 413c = Ameco
* 5136 = Skymedi
* 8564 = Transcend
* 8644 = NandTec
* eeee = ???
*/
/* String identifiers:
* Some info comes from http://knowledge.seagate.com/articles/en_US/FAQ/204763en,
* other http://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h
* '#' means any number in [0-9]
*/
static str_score_t str_score[] = {
{ "HP ", 10 },
{ "IC#", 10 },
{ "ST#", 10 },
{ "MX#", 10 },
{ "WDC", 10 },
{ "IBM", 10 },
{ "OCZ", 5 },
{ "STM#", 10 },
{ "HDS#", 10 }, // These Hitachi drives are a PITA
{ "HDP#", 10 },
{ "HDT#", 10 },
{ "HTE#", 10 },
{ "HTS#", 10 },
{ "HUA#", 10 },
{ "APPLE", 10 },
{ "INTEL", 10 },
{ "MAXTOR", 10 },
{ "HITACHI", 10 },
{ "SEAGATE", 10 },
{ "SAMSUNG", 10 },
{ "FUJITSU", 10 },
{ "TOSHIBA", 10 },
{ "QUANTUM", 10 },
{ "EXCELSTOR", 10 },
};
/* The lists belows set a score according to VID & VID:PID
* These were constructed as follows:
* 1. Pick all the VID:PIDs from http://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools/drivedb.h
* 2. Check that VID against http://flashboot.ru/iflash/saved/ as well as http://www.linux-usb.org/usb.ids
* 3. If a lot of flash or card reader devices are returned, add the VID:PID, with a positive score,
* in the vidpid table (so that the default will be UFD, and HDD the exception)
* 4. If only a few flash devices are returned, add the VID to our list with a positive score and
* add the flash entries in the VID:PID list with a negative score
* These lists MUST be kept in increasing VID/VID:PID order
*/
static vid_score_t vid_score[] = {
{ 0x0411, 5 }, // Buffalo
{ 0x0480, 5 }, // Toshiba
{ 0x04b4, 10 }, // Cypress
{ 0x04e8, 5 }, // Samsung
{ 0x04c5, 7 }, // Fujitsu
{ 0x04fc, 5 }, // Sunplus
{ 0x059b, 7 }, // Iomega
{ 0x059f, 5 }, // LaCie
{ 0x05ab, 10 }, // In-System Design
{ 0x067b, 7 }, // Prolific
{ 0x07ab, 8 }, // Freecom
{ 0x0928, 10 }, // PLX Technology
{ 0x0930, 5 }, // Toshiba
{ 0x0bc2, 10 }, // Seagate
{ 0x0d49, 10 }, // Maxtor
{ 0x0dc4, 10 }, // Macpower Peripherals
{ 0x1058, 10 }, // Western Digital
{ 0x13fd, 10 }, // Initio
{ 0x152d, 10 }, // JMicron
{ 0x174c, 8 }, // ASMedia
{ 0x1759, 8 }, // LucidPort
{ 0x1a4a, 10 }, // Silicon Image
{ 0x4971, 10 }, // Hitachi
};
static vidpid_score_t vidpid_score[] = {
{ 0x03f0, 0xbd07, 10 }, // HP Desktop HD BD07
{ 0x0402, 0x5621, 10 }, // ALi M5621
// NOT in VID list as 040d:6205 is a card reader
{ 0x040d, 0x6204, 10 }, // Connectland BE-USB2-35BP-LCM
// NOT in VID list as 043e:70e2 & 043e:70d3 are flash drives
{ 0x043e, 0x70f1, 10 }, // LG Mini HXD5
// NOT in VID list as 0471:0855 is a flash drive
{ 0x0471, 0x2021, 10 }, // Philips
// NOT in VID list as many UFDs and card readers exist
{ 0x05e3, 0x0718, 10 }, // Genesys Logic IDE/SATA Adapter
{ 0x05e3, 0x0719, 10 }, // Genesys Logic SATA adapter
{ 0x05e3, 0x0731, 10 }, // Genesys Logic GL3310 SATA 3Gb/s Bridge Controller
{ 0x05e3, 0x0731, 2 }, // Genesys Logic Mass Storage Device
// Only one HDD device => keep in this list
{ 0x0634, 0x0655, 5 }, // Micron USB SSD
// NOT in VID list as plenty of UFDs
{ 0x0718, 0x1000, 7 }, // Imation Odyssey external USB dock
// Only one HDD device
{ 0x0939, 0x0b16, 10 }, // Toshiba Stor.E
// Plenty of card readers
{ 0x0c0b, 0xb001, 10 }, // Dura Micro
{ 0x0c0b, 0xb159, 10 }, // Dura Micro 509
// Meh
{ 0x0e21, 0x0510, 5 }, // Cowon iAudio X5
{ 0x11b0, 0x6298, 10 }, // Enclosure from Kingston SSDNow notebook upgrade kit
// NOT in VID list as plenty of UFDs
{ 0x125f, 0xa93a, 10 }, // A-DATA SH93
{ 0x125f, 0xa94a, 10 }, // A-DATA DashDrive
// NOT in VID list as plenty of card readers
{ 0x14cd, 0x6116, 10 }, // Super Top generic enclosure
// Verbatim are way too widespread - good candidate for ATA passthrough
{ 0x18a5, 0x0214, 10 }, // Verbatim Portable Hard Drive
{ 0x18a5, 0x0215, 10 }, // Verbatim FW/USB160
{ 0x18a5, 0x0216, 10 }, // Verbatim External Hard Drive 47519
{ 0x18a5, 0x0227, 10 }, // Verbatim Pocket Hard Drive
{ 0x18a5, 0x022a, 10 }, // Verbatim External Hard Drive
{ 0x18a5, 0x022b, 10 }, // Verbatim Portable Hard Drive (Store'n'Go)
{ 0x18a5, 0x0237, 10 }, // Verbatim Portable Hard Drive (500 GB)
// SunPlus seem to have a bunch of UFDs
{ 0x1bcf, 0x0c31, 10 }, // SunplusIT
// Plenty of Innostor UFDs
{ 0x1f75, 0x0888, 10 }, // Innostor IS888
// NOT in VID list as plenty of UFDs
{ 0x3538, 0x0902, 10 }, // PQI H560
// Too many card readers to be in VID list
{ 0x55aa, 0x0015, 10 }, // OnSpec Hard Drive
{ 0x55aa, 0x0102, 8 }, // OnSpec SuperDisk
{ 0x55aa, 0x0103, 10 }, // OnSpec IDE Hard Drive
{ 0x55aa, 0x1234, 8 }, // OnSpec ATAPI Bridge
{ 0x55aa, 0x2b00, 8 }, // OnSpec USB->PATA
// Smartmontools are uncertain about that one, and so am I
{ 0x6795, 0x2756, 2 }, // Sharkoon 2-Bay RAID Box
// Buffalo exceptions
{ 0x0411, 0x01e8, -20 }, // Buffalo HD-PNTU2
// Samsung exceptions
{ 0x04e8, 0x0100, -20 }, // Kingston Flash Drive (128MB)
{ 0x04e8, 0x0100, -20 }, // Connect3D Flash Drive
{ 0x04e8, 0x0101, -20 }, // Connect3D Flash Drive
{ 0x04e8, 0x1a23, -20 }, // 2 GB UFD
{ 0x04e8, 0x5120, -20 }, // 4 GB UFD
{ 0x04e8, 0x6818, -20 }, // 8 GB UFD
{ 0x04e8, 0x6845, -20 }, // 16 GB UFD
{ 0x04e8, 0x685E, -20 }, // 16 GB UFD
// Sunplus exceptions
{ 0x04fc, 0x05d8, -20 }, // Verbatim flash drive
{ 0x04fc, 0x5720, -20 }, // Card reader
// LaCie exceptions
{ 0x059f, 0x1027, -20 }, // 16 GB UFD
{ 0x059f, 0x103B, -20 }, // 16 GB UFD
{ 0x059f, 0x1064, -20 }, // 16 GB UFD
// Prolific exceptions
{ 0x067b, 0x2517, -20 }, // 1 GB UFD
{ 0x067b, 0x2528, -20 }, // 8 GB UFD
{ 0x067b, 0x3400, -10 }, // Hi-Speed Flash Disk with TruePrint AES3400
{ 0x067b, 0x3500, -10 }, // Hi-Speed Flash Disk with TruePrint AES3500
// Freecom exceptions
{ 0x07ab, 0xfcab, -20 }, // 4 GB UFD
// Toshiba exceptions
{ 0x0930, 0x1400, -20 },
{ 0x0930, 0x6533, -20 },
{ 0x0930, 0x653e, -20 },
{ 0x0930, 0x6544, -20 },
{ 0x0930, 0x6545, -20 },
// Verbatim exceptions
{ 0x18a5, 0x0243, -20 },
{ 0x18a5, 0x0245, -20 },
{ 0x18a5, 0x0302, -20 },
{ 0x18a5, 0x0304, -20 },
{ 0x18a5, 0x3327, -20 },
};

View file

@ -737,9 +737,10 @@ static BOOL GetUSBDevices(DWORD devnum)
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)) { if ((!enable_HDDs) && ((score = IsHDD(drive_type, vid, pid, buffer)) > 0)) {
uprintf("USB HDD device removed (score %d > %d) " uprintf("Device eliminated because it was detected as an USB Hard Drive (score %d > 0)\n", score);
"[Note: You can enable USB HDDs in the Advanced Options]\n", score, IS_HDD_THRESHOLD); uprintf("If this device is not an USB Hard Drive, please e-mail the author of this application\n");
uprintf("NOTE: You can enable the listing of USB Hard Drives in 'Advanced Options' (white triangle)");
safe_closehandle(hDrive); safe_closehandle(hDrive);
safe_free(devint_detail_data); safe_free(devint_detail_data);
break; break;

View file

@ -56,7 +56,6 @@
#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"

View file

@ -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.316" CAPTION "Rufus v1.4.0.317"
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
@ -67,8 +67,7 @@ BEGIN
COMBOBOX IDC_DISK_ID,119,246,73,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_DISK_ID,119,246,73,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "Add fixes for old BIOSes (extra partition, align, etc.)",IDC_EXTRA_PARTITION, CONTROL "Add fixes for old BIOSes (extra partition, align, etc.)",IDC_EXTRA_PARTITION,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,235,181,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,235,181,10
CONTROL "List non removable or unpartitioned USB disks",IDC_ENABLE_FIXED_DISKS, CONTROL "List USB Hard Drives",IDC_ENABLE_FIXED_DISKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,222,181,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,222,181,10
PUSHBUTTON "",IDC_LANG,183,2,15,13,BS_TOP | BS_FLAT PUSHBUTTON "",IDC_LANG,183,2,15,13,BS_TOP | BS_FLAT
END END
@ -289,8 +288,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,0,316 FILEVERSION 1,4,0,317
PRODUCTVERSION 1,4,0,316 PRODUCTVERSION 1,4,0,317
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -307,13 +306,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.316" VALUE "FileVersion", "1.4.0.317"
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.316" VALUE "ProductVersion", "1.4.0.317"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -34,6 +34,7 @@
#include "msapi_utf8.h" #include "msapi_utf8.h"
#include "rufus.h" #include "rufus.h"
#include "smart.h" #include "smart.h"
#include "hdd_vs_ufd.h"
/* Helper functions */ /* Helper functions */
@ -400,59 +401,34 @@ BOOL SmartGetVersion(HANDLE hdevice)
* - removable flag (how do you actually find that one?) * - 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). * 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 * A positive score means that we think it's an USB HDD, zero or negative means that
* UFD we *try* to do what we can to avoid them formatting that drive by mistake. * we think it's an UFD.
* 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 * This is done so that, if someone already has an USB HDD plugged in (say as a
* DIFFERENTIATE AN USB HDD FROM A FLASH DRIVE. ALSO, REMEMBER THAT THE LICENSE OF THIS * backup drive) and plugs an UFD we *try* to do what we can to avoid them formatting
* APPLICATION MAKES ABSOLUETLY NO PROMISE ABOUT DATA PRESERVATION (PROVIDED "AS IS"). * that drive by mistake.
* THUS, IF DATA LOSS IS INCURRED DUE TO THE ALGORITHM BELOW, OR ANY OTHER PART OF THIS * However, because there is no foolproof (let alone easy) way to differentiate UFDs
* APPLICATION, THE RESPONSIBILITY IS ENTIRELY ON YOU! * from HDDs, thanks to every manufacturer, Microsoft, and their mothers, making it
* exceedingly troublesome to find what type of hardware we are actually accessing,
* you are expected to pay heed to the following:
*
* WARNING: NO PROMISE IS MADE ABOUT THIS ALGORITHM BEING ABLE TO CORRECTLY
* DIFFERENTIATE AN USB HDD FROM AN USB FLASH DRIVE. MOREOVER, YOU ARE REMINDED THAT
* THE LICENSE OF THIS APPLICATION MAKES NO PROMISE ABOUT AVOIDING DATA LOSS EITHER
* (PROVIDED "AS IS").
* THUS, IF DATA LOSS IS INCURRED DUE TO THIS, OR ANY OTHER PART OF THIS APPLICATION,
* NOT BEHAVING IN THE MANNER YOU EXPECTED, THE RESPONSIBILITY IS ENTIRELY ON YOU!
*
* What you have below, then, is our *current best guess* at differentiating UFDs
* from HDDs. But short of a crystal ball, this remains just a guess, which may be
* way off mark. Still, you are also reminded that 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!
* *
* But let me just elaborate further on why differentiating UFDs from HDDs is not as * But let me just elaborate further on why differentiating UFDs from HDDs is not as
* 'simple' as it seems: * 'simple' as it seems:
@ -465,17 +441,11 @@ static vid_score manufacturer_vid[] = {
* USB<->(S)ATA bridge seem to have their own method of implementing passthrough. * 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 * - SSDs have also changed the deal completely, as you can get something that looks
* like Flash but that is really an HDD. * like Flash but that is really an HDD.
* - Some manufacturers (eg. ALI) provide both USB Flash controllers and USB IDE/SATA * - Some manufacturers (eg. verbatim) provide both USB Flash Drives and USB HDDs, so
* controllers, so we can't exactly use the VID to say for sure what we're looking at. * 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 * - Finally, Microsoft is absolutely 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 * from the above) => there is no magic API we can query that will tell us what we're
* really looking at. * 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 IsHDD(UINT drive_type, uint16_t vid, uint16_t pid, const char* strid)
{ {
@ -483,31 +453,45 @@ int IsHDD(UINT drive_type, uint16_t vid, uint16_t pid, const char* strid)
size_t i, mlen, ilen; size_t i, mlen, ilen;
BOOL wc; BOOL wc;
// Boost the score if fixed, as these are *generally* HDDs
if (drive_type == DRIVE_FIXED) if (drive_type == DRIVE_FIXED)
score += 3; score += 3;
// Check the string against well known HDD identifiers
ilen = safe_strlen(strid); ilen = safe_strlen(strid);
for (i=0; i<ARRAYSIZE(manufacturer_str); i++) { for (i=0; i<ARRAYSIZE(str_score); i++) {
mlen = strlen(manufacturer_str[i].name); mlen = strlen(str_score[i].name);
if (mlen > ilen) if (mlen > ilen)
break; break;
wc = (manufacturer_str[i].name[mlen-1] == '#'); wc = (str_score[i].name[mlen-1] == '#');
if ( (_strnicmp(strid, manufacturer_str[i].name, mlen-((wc)?1:0)) == 0) if ( (_strnicmp(strid, str_score[i].name, mlen-((wc)?1:0)) == 0)
&& ((!wc) || ((strid[mlen] >= '0') && (strid[mlen] <= '9'))) ) { && ((!wc) || ((strid[mlen] >= '0') && (strid[mlen] <= '9'))) ) {
score += manufacturer_str[i].score; score += str_score[i].score;
break; break;
} }
} }
for (i=0; i<ARRAYSIZE(manufacturer_vid); i++) { // Check against known VIDs
if (vid == manufacturer_vid[i].vid) { for (i=0; i<ARRAYSIZE(vid_score); i++) {
score += manufacturer_vid[i].score; if (vid < vid_score[i].vid)
break;
if (vid == vid_score[i].vid) {
score += vid_score[i].score;
break; break;
} }
} }
// TODO: try to perform inquiry if uncertain // Check against known VID:PIDs
// TODO: lower the score for well known UFD manufacturers (ADATA, SanDisk, etc.) for (i=0; i<ARRAYSIZE(vidpid_score); i++) {
if (vid < vidpid_score[i].vid)
break;
if ((vid == vidpid_score[i].vid) && (pid == vidpid_score[i].pid)) {
score += vidpid_score[i].score;
break;
}
}
// TODO: try to perform inquiry if below a specific threshold (Verbatim, etc)?
// TODO: lower the score for well known UFD manufacturers (ADATA, SanDisk, etc.)?
return score; return score;
} }