diff --git a/res/localization/rufus.loc b/res/localization/rufus.loc index 6bd02e48..01a62559 100644 --- a/res/localization/rufus.loc +++ b/res/localization/rufus.loc @@ -506,7 +506,7 @@ t MSG_007 "撤消" ################################################################################ l "fr-FR" "French (Français)" 0x040c, 0x080c, 0x0c0c, 0x100c, 0x140c, 0x180c, 0x1c0c, 0x200c, 0x240c, 0x280c, 0x2c0c, 0x300c, 0x340c, 0x380c, 0xe40c -v 1.0.2 +v 1.0.3 b "en-US" g IDD_DIALOG @@ -530,7 +530,7 @@ t IDC_ABOUT "A propos..." t IDCANCEL "Fermer" t IDC_START "Démarrer" t IDS_ADVANCED_OPTIONS_GRP "Options avancées" -t IDC_ENABLE_FIXED_DISKS "Lister les disques fixes ou non partitionés" +t IDC_ENABLE_FIXED_DISKS "Lister les disques durs USB" t IDC_EXTRA_PARTITION "Options de compatibilité avec anciens BIOS" t IDC_RUFUS_MBR "Ajout du MBR Rufus, ID BIOS:" m IDC_DISK_ID +5,0 @@ -768,7 +768,7 @@ t MSG_168 "Camoufle le premier disque USB démarrable (généralement 0x80) sous "Changez cette option si vous installez Windows XP avec plus d’un disque dur" t MSG_169 "Créé une petite partition supplémentaire et essaye d’aligner les partitions.\n" "Peut améliorer la détection USB pour les vieux BIOS" -t MSG_170 "Active la détection de disque non normalement listés par Rufus. UTILISEZ A VOS PROPRES RISQUES !!! " +t MSG_170 "Liste les disques durs localisés dans des enceintes USB. UTILISEZ A VOS PROPRES RISQUES !!! " t MSG_171 "Lance le formatage. DETRUIT toutes les données existantes sur la cible !" t MSG_172 "Licence d’utilisation et remerciements" t MSG_173 "Cliquez pour sélectionner..." diff --git a/src/drive.c b/src/drive.c index 7f193e0e..2384b62b 100644 --- a/src/drive.c +++ b/src/drive.c @@ -36,7 +36,6 @@ * Globals */ RUFUS_DRIVE_INFO SelectedDrive; -extern UINT drive_type; // TODO: add a DetectSectorSize()? // http://msdn.microsoft.com/en-us/library/ff800831.aspx @@ -122,10 +121,12 @@ HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDrive) return hPhysical; } -// Return the first GUID volume name for the associated drive or NULL if not found -// See http://msdn.microsoft.com/en-us/library/cc542456.aspx -// The returned string is allocated and must be freed -// TODO: a drive may have multiple volumes - should we handle those? +/* + * Return the first GUID volume name for the associated drive or NULL if not found + * See http://msdn.microsoft.com/en-us/library/cc542456.aspx + * The returned string is allocated and must be freed + * TODO: a drive may have multiple volumes - should we handle those? + */ #define suprintf(...) if (!bSilent) uprintf(__VA_ARGS__) char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent) { @@ -136,11 +137,11 @@ char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent char path[MAX_PATH]; VOLUME_DISK_EXTENTS DiskExtents; DWORD size; + UINT drive_type; int i, j; static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" }; static const char* volume_start = "\\\\?\\"; - drive_type = DRIVE_UNKNOWN; CheckDriveIndex(DriveIndex); for (i=0; hDrive == INVALID_HANDLE_VALUE; i++) { @@ -253,19 +254,23 @@ 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, + * as well as the drive type. This is used as base for the 2 function calls that follow. */ -BOOL GetDriveLetter(DWORD DriveIndex, char* drive_letter) +static BOOL _GetDriveLetterAndType(DWORD DriveIndex, char* drive_letter, UINT* drive_type) { DWORD size; BOOL r = FALSE; STORAGE_DEVICE_NUMBER_REDEF device_number = {0}; HANDLE hDrive = INVALID_HANDLE_VALUE; + UINT _drive_type; char *drive, drives[26*4]; /* "D:\", "E:\", etc. */ char logical_drive[] = "\\\\.\\#:"; - drive_type = DRIVE_UNKNOWN; - *drive_letter = ' '; + if (drive_letter != NULL) + *drive_letter = ' '; + if (drive_type != NULL) + *drive_type = DRIVE_UNKNOWN; CheckDriveIndex(DriveIndex); size = GetLogicalDriveStringsA(sizeof(drives), drives); @@ -291,9 +296,9 @@ BOOL GetDriveLetter(DWORD DriveIndex, char* drive_letter) not unique! An HDD, a DVD and probably other drives can have the same value there => Use GetDriveType() to filter out unwanted devices. See https://github.com/pbatard/rufus/issues/32 for details. */ - drive_type = GetDriveTypeA(drive); + _drive_type = GetDriveTypeA(drive); - if ((drive_type != DRIVE_REMOVABLE) && (drive_type != DRIVE_FIXED)) + if ((_drive_type != DRIVE_REMOVABLE) && (_drive_type != DRIVE_FIXED)) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); @@ -310,7 +315,10 @@ BOOL GetDriveLetter(DWORD DriveIndex, char* drive_letter) uprintf("Could not get device number for device %s: %s\n", logical_drive, WindowsErrorString()); } else if (device_number.DeviceNumber == DriveIndex) { - *drive_letter = *drive; + if (drive_letter != NULL) + *drive_letter = *drive; + if (drive_type != NULL) + *drive_type = _drive_type; break; } } @@ -319,6 +327,20 @@ out: return r; } +// Could have used a #define, but this is clearer +BOOL GetDriveLetter(DWORD DriveIndex, char* drive_letter) +{ + return _GetDriveLetterAndType(DriveIndex, drive_letter, NULL); +} + +// There's already a GetDriveType in the Windows API +UINT GetDriveTypeFromIndex(DWORD DriveIndex) +{ + UINT drive_type; + _GetDriveLetterAndType(DriveIndex, NULL, &drive_type); + return drive_type; +} + /* * Return the next unused drive letter from the system */ @@ -400,6 +422,30 @@ BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label) return TRUE; } +/* + * Return the drive size + */ +uint64_t GetDriveSize(DWORD DriveIndex) +{ + BOOL r; + HANDLE hPhysical; + DWORD size; + BYTE geometry[128]; + void* disk_geometry = (void*)geometry; + PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; + + hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE); + if (hPhysical == INVALID_HANDLE_VALUE) + return FALSE; + + r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, + NULL, 0, geometry, sizeof(geometry), &size, NULL); + safe_closehandle(hPhysical); + if (!r || size <= 0) + return 0; + return DiskGeometry->DiskSize.QuadPart; +} + /* * Fill the drive properties (size, FS, etc) */ @@ -429,7 +475,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys if (hPhysical == INVALID_HANDLE_VALUE) return FALSE; - r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, + r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, geometry, sizeof(geometry), &size, NULL); if (!r || size <= 0) { uprintf("Could not get geometry for drive 0x%02x: %s\n", DriveIndex, WindowsErrorString()); diff --git a/src/rufus.c b/src/rufus.c index f3bc0514..c7c118b4 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -118,7 +118,6 @@ HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDis 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 enable_HDDs = FALSE, advanced_mode = TRUE, force_update = FALSE; -UINT drive_type = DRIVE_UNKNOWN; int dialog_showing = 0; uint16_t rufus_version[4]; RUFUS_UPDATE update = { {0,0,0,0}, {0,0}, NULL, NULL}; @@ -598,7 +597,7 @@ static BOOL GetUSBDevices(DWORD devnum) PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data; STORAGE_DEVICE_NUMBER_REDEF device_number; DEVINST parent_inst, device_inst; - DWORD size, i, j, k, datatype; + DWORD size, i, j, k, datatype, drive_index; ULONG list_size; HANDLE hDrive; LONG maxwidth = 0; @@ -732,12 +731,13 @@ static BOOL GetUSBDevices(DWORD devnum) continue; } - if (GetDriveLabel(device_number.DeviceNumber + DRIVE_INDEX_MIN, &drive_letter, &label)) { + drive_index = device_number.DeviceNumber + DRIVE_INDEX_MIN; + if (GetDriveLabel(drive_index, &drive_letter, &label)) { // Must ensure that the combo box is UNSORTED for indexes to be the same StrArrayAdd(&DriveID, buffer); StrArrayAdd(&DriveLabel, label); - if ((!enable_HDDs) && ((score = IsHDD(drive_type, vid, pid, buffer)) > 0)) { + if ((!enable_HDDs) && ((score = IsHDD(drive_index, vid, pid, buffer)) > 0)) { uprintf("Device eliminated because it was detected as an USB Hard Drive (score %d > 0)\n", score); 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)"); diff --git a/src/rufus.h b/src/rufus.h index 4c17068e..75ae4dff 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -320,6 +320,8 @@ extern BOOL WaitForLogical(DWORD DriveIndex); extern char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash, BOOL bSilent); extern HANDLE GetLogicalHandle(DWORD DriveIndex, BOOL bWriteAccess, BOOL bLockDrive); extern BOOL GetDriveLetter(DWORD DriveIndex, char* drive_letter); +extern UINT GetDriveTypeFromIndex(DWORD DriveIndex); +extern uint64_t GetDriveSize(DWORD DriveIndex); extern char GetUnusedDriveLetter(void); extern BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker); extern BOOL DeletePartitions(HANDLE hDrive); @@ -350,7 +352,7 @@ extern char* replace_in_token_data(const char* filename, const char* token, cons extern void parse_update(char* buf, size_t len); extern BOOL WimExtractCheck(void); extern BOOL WimExtractFile(const char* wim_image, int index, const char* src, const char* dst); -extern int IsHDD(UINT drive_type, uint16_t vid, uint16_t pid, const char* strid); +extern int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid); static __inline BOOL UnlockDrive(HANDLE hDrive) { diff --git a/src/rufus.rc b/src/rufus.rc index 7946bf1a..0a01eb58 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 206, 329 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_APPWINDOW -CAPTION "Rufus v1.4.0.317" +CAPTION "Rufus v1.4.0.318" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,291,50,14 @@ -288,8 +288,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,0,317 - PRODUCTVERSION 1,4,0,317 + FILEVERSION 1,4,0,318 + PRODUCTVERSION 1,4,0,318 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -306,13 +306,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.4.0.317" + VALUE "FileVersion", "1.4.0.318" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2013 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.4.0.317" + VALUE "ProductVersion", "1.4.0.318" END END BLOCK "VarFileInfo" diff --git a/src/smart.c b/src/smart.c index 6a5b3802..a03cbc38 100644 --- a/src/smart.c +++ b/src/smart.c @@ -391,19 +391,6 @@ BOOL SmartGetVersion(HANDLE hdevice) } #endif -/* - * TODO: SMART HDD vs UFD detection: - * - if the USB ID starts with - * "WDC", "IBM", "ST" + number, "STM", "HTS", "HITACHI", "SEAGATE", "MAXTOR", "SAMSUNG", "HP ", "FUJITSU", "TOSHIBA", "QUANTUM" - * - if IDENTIFY reports SMART capabilities - * - 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 - * - removable flag (how do you actually find that one?) - */ - - - - /* * This attempts to detect whether a drive is an USB HDD or an USB Flash Drive (UFD). * A positive score means that we think it's an USB HDD, zero or negative means that @@ -447,16 +434,26 @@ BOOL SmartGetVersion(HANDLE hdevice) * from the above) => there is no magic API we can query that will tell us what we're * really looking at. */ -int IsHDD(UINT drive_type, uint16_t vid, uint16_t pid, const char* strid) +#define GB 1073741824LL +int IsHDD(DWORD DriveIndex, uint16_t vid, uint16_t pid, const char* strid) { int score = 0; size_t i, mlen, ilen; BOOL wc; + uint64_t drive_size; // Boost the score if fixed, as these are *generally* HDDs - if (drive_type == DRIVE_FIXED) + // NB: Due to a Windows API limitation, drives with no mounted partition will never have DRIVE_FIXED + if (GetDriveTypeFromIndex(DriveIndex) == DRIVE_FIXED) score += 3; + // Adjust the score depending on the size + drive_size = GetDriveSize(DriveIndex); + if (drive_size > 512*GB) + score += 10; + else if (drive_size < 8*GB) + score -= 10; + // Check the string against well known HDD identifiers ilen = safe_strlen(strid); for (i=0; i