From 3f0d9d108f299e178102db57fe0a78fa83747a47 Mon Sep 17 00:00:00 2001 From: Scott Date: Fri, 28 Mar 2014 23:32:30 +1100 Subject: [PATCH] [core] add VHD target support * Adds Microsoft VHD/VHDX mounted image support * Also fix an issue where some devices would not be detected due to CM_Get_Device_ID_List_Size() returning a list size larger than actually required * Closes #305 * Closes #139 --- src/rufus.c | 50 ++++++++++++++++++++++++++++++-------------------- src/rufus.rc | 12 ++++++------ 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/rufus.c b/src/rufus.c index 608b4fb1..a156810a 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -631,17 +631,18 @@ static BOOL GetUSBDevices(DWORD devnum) { // 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* storage_name[] = { "USBSTOR", "UASPSTOR", "VUSBSTOR", "ETRONSTOR" }; const char* scsi_name = "SCSI"; + const char* vhd_name = "Microsoft Virtual Disk"; char letter_name[] = " (?:)"; - BOOL found = FALSE, is_SCSI, is_UASP; + BOOL found = FALSE, is_SCSI, is_UASP, is_VHD; HDEVINFO dev_info = NULL; SP_DEVINFO_DATA dev_info_data; SP_DEVICE_INTERFACE_DATA devint_data; PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data; DEVINST parent_inst, device_inst; DWORD size, i, j, k, datatype, drive_index; - ULONG list_size[ARRAYSIZE(usbstor_name)], full_list_size; + ULONG list_size[ARRAYSIZE(storage_name)], full_list_size; HANDLE hDrive; LONG maxwidth = 0; RECT rect; @@ -664,10 +665,10 @@ static BOOL GetUSBDevices(DWORD devnum) } full_list_size = 0; - for (s=0; 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; + CM_Get_Device_ID_ListA(storage_name[s], &devid_list[i], list_size[s], CM_GETIDLIST_FILTER_SERVICE); + // list_size is sometimes larger than required thus we need to find the real end + for (i += list_size[s]; i > 2; i--) { + if ((devid_list[i-2] != '\0') && (devid_list[i-1] == '\0') && (devid_list[i] == '\0')) + break; + } } } @@ -698,16 +703,18 @@ static BOOL GetUSBDevices(DWORD devnum) } // UASP drives are listed under SCSI (along with regular SYSTEM drives => "DANGER, WILL ROBINSON!!!") is_SCSI = (safe_stricmp(buffer, scsi_name) == 0); - if ((safe_stricmp(buffer, usbstor_name[0]) != 0) && (!is_SCSI)) + if ((safe_stricmp(buffer, storage_name[0]) != 0) && (!is_SCSI)) continue; memset(buffer, 0, sizeof(buffer)); vid = 0; pid = 0; - is_UASP = FALSE; + is_UASP = FALSE, is_VHD = FALSE; if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); // We can afford a failure on this call - just replace the name with "USB Storage Device (Generic)" safe_strcpy(buffer, sizeof(buffer), lmprintf(MSG_045)); + } else if (safe_stricmp(buffer, vhd_name) == 0) { + is_VHD = TRUE; } else { // 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... @@ -733,18 +740,21 @@ static BOOL GetUSBDevices(DWORD devnum) } } } - 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 + if (is_VHD) { + uprintf("Found VHD device '%s'\n", buffer); } else { - safe_sprintf(str, sizeof(str), "%04X:%04X", vid, pid); + 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 + } else { + safe_sprintf(str, sizeof(str), "%04X:%04X", vid, pid); + } + uprintf("Found %s device '%s' (%s)\n", is_UASP?"UAS":"USB", buffer, str); } - uprintf("Found %s device '%s' (%s)\n", is_UASP?"UAS":"USB", buffer, str); - devint_data.cbSize = sizeof(devint_data); hDrive = INVALID_HANDLE_VALUE; devint_detail_data = NULL; diff --git a/src/rufus.rc b/src/rufus.rc index 7d7f12d5..aef702e9 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -32,7 +32,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 -CAPTION "Rufus 1.4.7.445" +CAPTION "Rufus 1.4.7.446" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,291,50,14 @@ -165,7 +165,7 @@ END RTL_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_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 1.4.7.445" +CAPTION "Rufus 1.4.7.446" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,291,50,14 @@ -427,8 +427,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,7,445 - PRODUCTVERSION 1,4,7,445 + FILEVERSION 1,4,7,446 + PRODUCTVERSION 1,4,7,446 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -445,13 +445,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.4.7.445" + VALUE "FileVersion", "1.4.7.446" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.4.7.445" + VALUE "ProductVersion", "1.4.7.446" END END BLOCK "VarFileInfo"