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

[core] fix an enumeration issue and add support for ASUS UASP Turbo Mode

* Our detection for a match in the hash table, during USB enumeration, always
  pointed to the first hub when no match was found.
* Also, some USB mass storage devices (ASUS Turbo Mode devices, iPods) may
  have an additional driver inserted, which we now try to handle by looking
  up the grandparent.
* Thanks to NaoDarkness for helping investigate this
* Closes #513
This commit is contained in:
Pete Batard 2015-05-28 18:47:53 +01:00
parent 94e7e41082
commit ac213a16e9
5 changed files with 42 additions and 28 deletions

View file

@ -1,8 +1,9 @@
o Version 2.2 (2015.05.??) o Version 2.2 (2015.05.??)
Modernize the language selection button, courtesy of David Warner Modernize the language selection button, courtesy of David Warner
Add keyboard accessibility, courtesy of David Warner Add keyboard accessibility, courtesy of David Warner
Add a clear indication of UEFI-CSM usage Add a clear indication of when UEFI-CSM is to be used
Fix Rufus preventing Windows shutdown when idle Fix an USB detection issue and add support for ASUS UASP Turbo Mode
Fix prevention of Windows shutdown when Rufus is idle
Improve UI on high DPI monitors Improve UI on high DPI monitors
Other UI improvements and fixes Other UI improvements and fixes

View file

@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376 IDD_DIALOG DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.2.664" CAPTION "Rufus 2.2.665"
FONT 8, "Segoe UI", 400, 0, 0x1 FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@ -157,7 +157,7 @@ END
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376 IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rufus 2.2.664" CAPTION "Rufus 2.2.665"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@ -283,7 +283,7 @@ END
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376 IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 2.2.664" CAPTION "Rufus 2.2.665"
FONT 8, "Segoe UI", 400, 0, 0x1 FONT 8, "Segoe UI", 400, 0, 0x1
BEGIN BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@ -415,7 +415,7 @@ END
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376 IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL
CAPTION "Rufus 2.2.664" CAPTION "Rufus 2.2.665"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@ -671,8 +671,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,2,664,0 FILEVERSION 2,2,665,0
PRODUCTVERSION 2,2,664,0 PRODUCTVERSION 2,2,665,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -689,13 +689,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", "2.2.664" VALUE "FileVersion", "2.2.665"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2015 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", "2.2.664" VALUE "ProductVersion", "2.2.665"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -153,7 +153,7 @@ uint32_t htab_hash(char* str, htab_table* htab)
// existing hash // existing hash
return idx; return idx;
} }
// uprintf("hash collision ('%s' vs '%s')\n", str, htab_table[idx].str); // uprintf("hash collision ('%s' vs '%s')\n", str, htab->table[idx].str);
// Second hash function, as suggested in [Knuth] // Second hash function, as suggested in [Knuth]
hval2 = 1 + hval % (htab->size - 2); hval2 = 1 + hval % (htab->size - 2);

View file

@ -128,7 +128,7 @@ BOOL GetUSBDevices(DWORD devnum)
{ {
// The first two are standard Microsoft drivers (including the Windows 8 UASP one). // The first two are standard Microsoft drivers (including the Windows 8 UASP one).
// The rest are the vendor UASP drivers I know of so far - list may be incomplete! // The rest are the vendor UASP drivers I know of so far - list may be incomplete!
const char* storage_name[] = { "USBSTOR", "UASPSTOR", "VUSBSTOR", "ETRONSTOR" }; const char* storage_name[] = { "USBSTOR", "UASPSTOR", "VUSBSTOR", "ETRONSTOR", "ASUSSTPT" };
const char* scsi_name = "SCSI"; const char* scsi_name = "SCSI";
const char* usb_speed_name[USB_SPEED_MAX] = { "USB", "USB 1.0", "USB 1.1", "USB 2.0", "USB 3.0" }; const char* usb_speed_name[USB_SPEED_MAX] = { "USB", "USB 1.0", "USB 1.1", "USB 2.0", "USB 3.0" };
// Hash table and String Array used to match a Device ID with the parent hub's Device Interface Path // Hash table and String Array used to match a Device ID with the parent hub's Device Interface Path
@ -141,20 +141,22 @@ BOOL GetUSBDevices(DWORD devnum)
SP_DEVINFO_DATA dev_info_data; SP_DEVINFO_DATA dev_info_data;
SP_DEVICE_INTERFACE_DATA devint_data; SP_DEVICE_INTERFACE_DATA devint_data;
PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data; PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data;
DEVINST parent_inst, device_inst; DEVINST parent_inst, grandparent_inst, device_inst;
DWORD size, i, j, k, l, datatype, drive_index; DWORD size, i, j, k, l, datatype, drive_index;
ULONG list_size[ARRAYSIZE(storage_name)] = { 0 }, full_list_size, ulFlags; ULONG list_size[ARRAYSIZE(storage_name)] = { 0 }, list_start[ARRAYSIZE(storage_name)] = { 0 }, full_list_size, ulFlags;
HANDLE hDrive; HANDLE hDrive;
LONG maxwidth = 0; LONG maxwidth = 0;
int s, score, drive_number; int s, score, drive_number;
char drive_letters[27], *device_id, *devid_list = NULL, entry_msg[128]; char drive_letters[27], *device_id, *devid_list = NULL, entry_msg[128];
char *label, *entry, buffer[MAX_PATH], str[128]; char *label, *entry, buffer[MAX_PATH], str[MAX_PATH], *method_str;
usb_device_props props; usb_device_props props;
IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList)); IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList));
StrArrayClear(&DriveID); StrArrayClear(&DriveID);
StrArrayClear(&DriveLabel); StrArrayClear(&DriveLabel);
StrArrayCreate(&dev_if_path, 128); StrArrayCreate(&dev_if_path, 128);
// Add a dummy for string index zero, as this is what non matching hashes will point to
StrArrayAdd(&dev_if_path, "");
device_id = (char*)malloc(MAX_PATH); device_id = (char*)malloc(MAX_PATH);
if (device_id == NULL) if (device_id == NULL)
@ -196,7 +198,6 @@ BOOL GetUSBDevices(DWORD devnum)
} }
} }
} }
} }
free(devint_detail_data); free(devint_detail_data);
} }
@ -228,6 +229,7 @@ BOOL GetUSBDevices(DWORD devnum)
return FALSE; return FALSE;
} }
for (s=0, i=0; s<ARRAYSIZE(storage_name); s++) { for (s=0, i=0; s<ARRAYSIZE(storage_name); s++) {
list_start[s] = i;
if (list_size[s] > 1) { if (list_size[s] > 1) {
if (CM_Get_Device_ID_ListA(storage_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS) if (CM_Get_Device_ID_ListA(storage_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS)
continue; continue;
@ -249,6 +251,7 @@ BOOL GetUSBDevices(DWORD devnum)
dev_info_data.cbSize = sizeof(dev_info_data); dev_info_data.cbSize = sizeof(dev_info_data);
for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) { for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) {
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
method_str = "";
if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME, if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME,
&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) {
uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString());
@ -281,17 +284,27 @@ BOOL GetUSBDevices(DWORD devnum)
&& (CM_Get_Child(&device_inst, parent_inst, 0) == CR_SUCCESS) && (CM_Get_Child(&device_inst, parent_inst, 0) == CR_SUCCESS)
&& (device_inst == dev_info_data.DevInst) ) { && (device_inst == dev_info_data.DevInst) ) {
// If we're not dealing with the USBSTOR part of our list, then this is an UASP device // If we're not dealing with the USBSTOR part of our list, then this is an UASP device
props.is_UASP = ((((uintptr_t)device_id)+2) >= ((uintptr_t)devid_list)+list_size[0]); props.is_UASP = ((((uintptr_t)device_id)+2) >= ((uintptr_t)devid_list)+list_start[1]);
// Now get the properties of the device, and its Device ID, which we need to populate the properties // Now get the properties of the device, and its Device ID, which we need to populate the properties
j = htab_hash(device_id, &htab_devid); j = htab_hash(device_id, &htab_devid);
if (j > 0) { // If the hash didn't match a populated string in dev_if_path[] (htab_devid.table[j].data > 0),
GetUSBProperties(dev_if_path.String[(uint32_t)htab_devid.table[j].data], device_id, &props); // we might have an extra vendor driver in between (e.g. "ASUS USB 3.0 Boost Storage Driver"
// for UASP devices in ASUS "Turbo Mode" or "Apple Mobile Device USB Driver" for iPods)
// so try to see if we can match the grandparent.
if ( ((uint32_t)htab_devid.table[j].data == 0)
&& (CM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS)
&& (CM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) {
device_id = str;
method_str = "[GP]";
j = htab_hash(device_id, &htab_devid);
} }
if ((uint32_t)htab_devid.table[j].data > 0)
GetUSBProperties(dev_if_path.String[(uint32_t)htab_devid.table[j].data], device_id, &props);
// If the previous calls didn't succeed in getting the VID:PID, try from the device_id // If previous calls still didn't succeed, try reading the VID:PID from the device_id
// (This is for the case for USB media player devices, for instance)
if ((props.vid == 0) && (props.pid == 0)) { if ((props.vid == 0) && (props.pid == 0)) {
BOOL post_backslash = FALSE; BOOL post_backslash = FALSE;
method_str = "[ID]";
for (j=0, k=0; (j<strlen(device_id))&&(k<2); j++) { for (j=0, k=0; (j<strlen(device_id))&&(k<2); j++) {
// The ID is in the form USB_VENDOR_BUSID\VID_xxxx&PID_xxxx\... // The ID is in the form USB_VENDOR_BUSID\VID_xxxx&PID_xxxx\...
if (device_id[j] == '\\') if (device_id[j] == '\\')
@ -305,12 +318,11 @@ BOOL GetUSBDevices(DWORD devnum)
} }
} }
} }
} }
} }
} }
if (props.is_VHD) { if (props.is_VHD) {
uprintf("Found VHD device '%s'\n", buffer); uprintf("Found VHD device '%s'", buffer);
} else { } else {
if ((props.vid == 0) && (props.pid == 0)) { if ((props.vid == 0) && (props.pid == 0)) {
if (is_SCSI) { if (is_SCSI) {
@ -324,8 +336,8 @@ BOOL GetUSBDevices(DWORD devnum)
} }
if (props.speed >= USB_SPEED_MAX) if (props.speed >= USB_SPEED_MAX)
props.speed = 0; props.speed = 0;
uprintf("Found %s%s%s device '%s' (%s)\n", props.is_UASP?"UAS (":"", uprintf("Found %s%s%s device '%s' (%s) %s\n", props.is_UASP?"UAS (":"",
usb_speed_name[props.speed], props.is_UASP?")":"", buffer, str); usb_speed_name[props.speed], props.is_UASP?")":"", buffer, str, method_str);
if (props.is_LowerSpeed) if (props.is_LowerSpeed)
uprintf("NOTE: This device is an USB 3.0 device operating at lower speed..."); uprintf("NOTE: This device is an USB 3.0 device operating at lower speed...");
} }

View file

@ -32,9 +32,9 @@ typedef struct usb_device_props {
uint32_t pid; uint32_t pid;
uint32_t speed; uint32_t speed;
uint32_t port; uint32_t port;
BOOL is_UASP; BOOLEAN is_UASP;
BOOL is_VHD; BOOLEAN is_VHD;
BOOL is_LowerSpeed; BOOLEAN is_LowerSpeed;
} usb_device_props; } usb_device_props;
/* /*
@ -94,6 +94,7 @@ DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(PULONG pulLen, PCST
DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_ID_ListA(PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags); DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_ID_ListA(PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags);
DECLSPEC_IMPORT CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags); DECLSPEC_IMPORT CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags);
DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags); DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Child(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Parent(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Sibling(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags); DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Sibling(PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags);
// This last one is unknown from MinGW32 and needs to be fetched from the DLL // This last one is unknown from MinGW32 and needs to be fetched from the DLL
PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_DevNode_Registry_PropertyA, (DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG)); PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_DevNode_Registry_PropertyA, (DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG));