[core] add UASP support

* Closes #229
This commit is contained in:
Pete Batard 2014-01-07 21:21:45 +00:00
parent bac13ad945
commit ec5ab918cf
3 changed files with 60 additions and 25 deletions

View File

@ -1,15 +1,18 @@
o Version 1.4.2 (2014.01.??) o Version 1.4.2 (2014.01.??)
Add USB Attached SCSI (UAS) support
Add ReactOS support Add ReactOS support
Add EFI/NTFS boot support, for targets that support it Add NTFS UEFI support, for targets that can support it
Add card hotplug detection for USB memory card readers Add insertion detection for USB memory card readers
Add retry when writing ISO files... again Add retry when writing ISO files... again
Add Indonesian translation, courtesy of Abe Akatsuki
Add Malay translation, courtesy of Muhammad Aman Add Malay translation, courtesy of Muhammad Aman
Add Portuguese (Portugal) translation, courtesy of Fernando Baptista
Speed up boot record cleanup, for slow drives Speed up boot record cleanup, for slow drives
Improve initial locale detection Improve initial locale detection
Save user selected locale between sessions Save user selected locale between sessions
Always use English locale in the log, where possible Always use English locale in the log, where possible
Fix detection of SanDisk, Kingston and Toshiba drives Fix detection for some SanDisk, Kingston and Toshiba drives
Fix an issue with drive letter assignation Fix a potential issue with drive letter assignation
Many other minor fixes and improvements Many other minor fixes and improvements
o Version 1.4.1 (2013.12.05) [BUGFIX RELEASE] o Version 1.4.1 (2013.12.05) [BUGFIX RELEASE]

View File

@ -634,7 +634,11 @@ static BOOL PopulateProperties(int ComboIndex)
*/ */
static BOOL GetUSBDevices(DWORD devnum) static BOOL GetUSBDevices(DWORD devnum)
{ {
BOOL r, found = FALSE; // 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!
const char* usbstor_name[] = { "USBSTOR", "UASPSTOR", "VUSBSTOR", "EtronSTOR" };
const char* scsi_name = "SCSI";
BOOL r, found = FALSE, is_SCSI, is_UASP;
HDEVINFO dev_info = NULL; HDEVINFO dev_info = NULL;
SP_DEVINFO_DATA dev_info_data; SP_DEVINFO_DATA dev_info_data;
SP_DEVICE_INTERFACE_DATA devint_data; SP_DEVICE_INTERFACE_DATA devint_data;
@ -642,14 +646,13 @@ static BOOL GetUSBDevices(DWORD devnum)
STORAGE_DEVICE_NUMBER_REDEF device_number; STORAGE_DEVICE_NUMBER_REDEF device_number;
DEVINST parent_inst, device_inst; DEVINST parent_inst, device_inst;
DWORD size, i, j, k, datatype, drive_index; DWORD size, i, j, k, datatype, drive_index;
ULONG list_size; ULONG list_size[ARRAYSIZE(usbstor_name)], full_list_size;
HANDLE hDrive; HANDLE hDrive;
LONG maxwidth = 0; LONG maxwidth = 0;
RECT rect; RECT rect;
int score; int s, 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";
uint16_t vid, pid; uint16_t vid, pid;
GUID _GUID_DEVINTERFACE_DISK = // only known to some... GUID _GUID_DEVINTERFACE_DISK = // only known to some...
{ 0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b} }; { 0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b} };
@ -665,17 +668,30 @@ static BOOL GetUSBDevices(DWORD devnum)
return FALSE; return FALSE;
} }
// Get a list of hardware IDs for all USB storage devices full_list_size = 0;
// This will be used to retrieve the VID:PID of our devices for (s=0; s<ARRAYSIZE(usbstor_name); s++) {
CM_Get_Device_ID_List_SizeA(&list_size, usbstor_name, CM_GETIDLIST_FILTER_SERVICE); // Get a list of hardware IDs for all USB storage devices
if (list_size == 0) // This will be used to retrieve the VID:PID of our devices
CM_Get_Device_ID_List_SizeA(&list_size[s], usbstor_name[s], CM_GETIDLIST_FILTER_SERVICE);
if (list_size[s] != 0)
full_list_size += list_size[s]-1; // remove extra NUL terminator
}
full_list_size += 1; // add extra NUL terminator
if (full_list_size < 2)
return FALSE; return FALSE;
devid_list = (char*)malloc(list_size); devid_list = (char*)malloc(full_list_size);
if (devid_list == NULL) { if (devid_list == NULL) {
uprintf("Could not allocate Dev ID list\n"); uprintf("Could not allocate Dev ID list\n");
return FALSE; return FALSE;
} }
CM_Get_Device_ID_ListA(usbstor_name, devid_list, list_size, CM_GETIDLIST_FILTER_SERVICE);
// Build a single list from all the storage enumerators we know of
for (s=0, i=0; s<ARRAYSIZE(usbstor_name); s++) {
if (list_size[s] > 1) {
CM_Get_Device_ID_ListA(usbstor_name[s], &devid_list[i], list_size[s], CM_GETIDLIST_FILTER_SERVICE);
i += list_size[s]-1;
}
}
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++) {
@ -685,11 +701,13 @@ static BOOL GetUSBDevices(DWORD devnum)
uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString());
continue; continue;
} }
// UASP drives are listed under SCSI (along with regular SYSTEM drives => "DANGER, WILL ROBINSON!!!")
if (safe_strcmp(buffer, usbstor_name) != 0) is_SCSI = (safe_stricmp(buffer, scsi_name) == 0);
if ((safe_stricmp(buffer, usbstor_name[0]) != 0) && (!is_SCSI))
continue; continue;
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
vid = 0; pid = 0; vid = 0; pid = 0;
is_UASP = FALSE;
if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME,
&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) {
uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString());
@ -702,7 +720,15 @@ static BOOL GetUSBDevices(DWORD devnum)
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) ) {
BOOL post_backslash = FALSE;
// If we're not dealing with the USBSTOR part of our list, then this is an UASP device
is_UASP = ((((uintptr_t)devid)+2) >= ((uintptr_t)devid_list)+list_size[0]);
for (j=0, k=0; (j<strlen(devid))&&(k<2); j++) { for (j=0, k=0; (j<strlen(devid))&&(k<2); j++) {
// The ID is in the form USB_VENDOR_BUSID\VID_xxxx&PID_xxxx\...
if (devid[j] == '\\')
post_backslash = TRUE;
if (!post_backslash)
continue;
if (devid[j] == '_') { if (devid[j] == '_') {
pid = (uint16_t)strtoul(&devid[j+1], NULL, 16); pid = (uint16_t)strtoul(&devid[j+1], NULL, 16);
// We could have used a vid_pid[] table, but keeping vid/pid separate is clearer // We could have used a vid_pid[] table, but keeping vid/pid separate is clearer
@ -712,11 +738,17 @@ static BOOL GetUSBDevices(DWORD devnum)
} }
} }
} }
if ((vid == 0) && (pid == 0)) if ((vid == 0) && (pid == 0)) {
if (is_SCSI) {
// If we have an SCSI drive and couldn't get a VID:PID, we are most likely
// dealing with a system drive => eliminate it!
continue;
}
safe_strcpy(str, sizeof(str), "????:????"); // Couldn't figure VID:PID safe_strcpy(str, sizeof(str), "????:????"); // Couldn't figure VID:PID
else } else {
safe_sprintf(str, sizeof(str), "%04X:%04X", vid, pid); safe_sprintf(str, sizeof(str), "%04X:%04X", vid, pid);
uprintf("Found device '%s' (%s)\n", buffer, str); }
uprintf("Found %s device '%s' (%s)\n", is_UASP?"UAS":"USB", buffer, str);
devint_data.cbSize = sizeof(devint_data); devint_data.cbSize = sizeof(devint_data);
hDrive = INVALID_HANDLE_VALUE; hDrive = INVALID_HANDLE_VALUE;
@ -787,7 +819,7 @@ static BOOL GetUSBDevices(DWORD devnum)
if ((!enable_HDDs) && ((score = IsHDD(drive_index, 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("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("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' (click the white triangle first)"); uprintf("NOTE: You can enable the listing of USB Hard Drives in 'Advanced Options' (after clicking the white triangle)");
safe_closehandle(hDrive); safe_closehandle(hDrive);
safe_free(devint_detail_data); safe_free(devint_detail_data);
break; break;

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.2.374" CAPTION "Rufus v1.4.2.375"
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
@ -288,8 +288,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,2,374 FILEVERSION 1,4,2,375
PRODUCTVERSION 1,4,2,374 PRODUCTVERSION 1,4,2,375
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -306,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.2.374" VALUE "FileVersion", "1.4.2.375"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2014 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.2.374" VALUE "ProductVersion", "1.4.2.375"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"