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

[core] add CycleDevice and VDS layout refresh

* Also fix some minor issues
This commit is contained in:
Pete Batard 2019-05-23 13:09:25 +01:00
parent bf59239c39
commit 8b18d8ce1d
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
11 changed files with 336 additions and 72 deletions

View file

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: 3.5\n" "Project-Id-Version: 3.5\n"
"Report-Msgid-Bugs-To: pete@akeo.ie\n" "Report-Msgid-Bugs-To: pete@akeo.ie\n"
"POT-Creation-Date: 2019-05-21 21:48+0100\n" "POT-Creation-Date: 2019-05-21 21:48+0100\n"
"PO-Revision-Date: 2019-05-21 23:54+0100\n" "PO-Revision-Date: 2019-05-22 00:04+0100\n"
"Language: sr_SP\n" "Language: sr_SP\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -1095,7 +1095,7 @@ msgstr "Verzija %d.%d (Izvršna verzija %d)"
#. • MSG_176 #. • MSG_176
msgid "English translation: Pete Batard <mailto:pete@akeo.ie>" msgid "English translation: Pete Batard <mailto:pete@akeo.ie>"
msgstr "Preveo:\\line• Ivan Strugar <mailto:isdjuka@gmail.com>\\line• Aleksandar Predić <mailto:notesofdespairandlove@gmail.com>\\line• Miloš ljubičić <mailto:ljubimilos@gmail.com>" msgstr "Preveo:\\line• Ivan Strugar <mailto:isdjuka@gmail.com>\\line• Aleksandar Predić <mailto:notesofdespairandlove@gmail.com>\\line• Miloš Ljubičić <mailto:ljubimilos@gmail.com>"
#. • MSG_177 #. • MSG_177
msgid "Report bugs or request enhancements at:" msgid "Report bugs or request enhancements at:"

View file

@ -11277,7 +11277,7 @@ t MSG_172 "Neispravan potpis preuzimanja"
t MSG_173 "Kliknite za odabir..." t MSG_173 "Kliknite za odabir..."
t MSG_174 "Rufus - Pouzdan Alat Za Formatiranje USB diska" t MSG_174 "Rufus - Pouzdan Alat Za Formatiranje USB diska"
t MSG_175 "Verzija %d.%d (Izvršna verzija %d)" t MSG_175 "Verzija %d.%d (Izvršna verzija %d)"
t MSG_176 "Preveo:\\line• Ivan Strugar <mailto:isdjuka@gmail.com>\\line• Aleksandar Predić <mailto:notesofdespairandlove@gmail.com>\\line• Miloš ljubičić <mailto:ljubimilos@gmail.com>" t MSG_176 "Preveo:\\line• Ivan Strugar <mailto:isdjuka@gmail.com>\\line• Aleksandar Predić <mailto:notesofdespairandlove@gmail.com>\\line• Miloš Ljubičić <mailto:ljubimilos@gmail.com>"
t MSG_177 "Prijavite greške ili zahtjeve za poboljšanja na:" t MSG_177 "Prijavite greške ili zahtjeve za poboljšanja na:"
t MSG_178 "Dodatna autorska prava:" t MSG_178 "Dodatna autorska prava:"
t MSG_179 "Polisa ažuriranja:" t MSG_179 "Polisa ažuriranja:"

189
src/dev.c
View file

@ -32,6 +32,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <commctrl.h> #include <commctrl.h>
#include <setupapi.h> #include <setupapi.h>
#include <cfg.h>
#include <assert.h> #include <assert.h>
#include "rufus.h" #include "rufus.h"
@ -43,7 +44,7 @@
#include "drive.h" #include "drive.h"
#include "dev.h" #include "dev.h"
extern StrArray DriveID, DriveLabel, DriveHub; extern StrArray DriveId, DriveName, DriveLabel, DriveHub;
extern uint32_t DrivePort[MAX_DRIVES]; extern uint32_t DrivePort[MAX_DRIVES];
extern BOOL enable_HDDs, use_fake_units, enable_vmdk, usb_debug, list_non_usb_removable_drives; extern BOOL enable_HDDs, use_fake_units, enable_vmdk, usb_debug, list_non_usb_removable_drives;
@ -126,9 +127,9 @@ out:
} }
/* /*
* Cycle port (reset) the selected device * Cycle the USB port of the selected device
*/ */
BOOL ResetDevice(int index) BOOL CyclePort(int index)
{ {
static uint64_t LastReset = 0; static uint64_t LastReset = 0;
BOOL r = FALSE; BOOL r = FALSE;
@ -159,7 +160,7 @@ BOOL ResetDevice(int index)
memset(&cycle_port, 0, size); memset(&cycle_port, 0, size);
cycle_port.ConnectionIndex = DrivePort[index]; cycle_port.ConnectionIndex = DrivePort[index];
uprintf("Cycling port %d (reset) on %s", DrivePort[index], DriveHub.String[index]); uprintf("Cycling port %d (reset) on %s", DrivePort[index], DriveHub.String[index]);
// As per https://msdn.microsoft.com/en-us/library/windows/hardware/ff537340.aspx // As per https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/usbioctl/ni-usbioctl-ioctl_usb_hub_cycle_port
// IOCTL_USB_HUB_CYCLE_PORT is not supported on Windows 7, Windows Vista, and Windows Server 2008 // IOCTL_USB_HUB_CYCLE_PORT is not supported on Windows 7, Windows Vista, and Windows Server 2008
if (!DeviceIoControl(handle, IOCTL_USB_HUB_CYCLE_PORT, &cycle_port, size, &cycle_port, size, &size, NULL)) { if (!DeviceIoControl(handle, IOCTL_USB_HUB_CYCLE_PORT, &cycle_port, size, &cycle_port, size, &size, NULL)) {
uprintf(" Failed to cycle port: %s", WindowsErrorString()); uprintf(" Failed to cycle port: %s", WindowsErrorString());
@ -173,6 +174,109 @@ out:
return r; return r;
} }
/*
* Forces a refresh by disabling and then re-enabling the device using SetupAPI.
* Returns the Windows error code from the operation.
* Note: Currently, this may leave the device disabled after re-plug or reboot...
*/
int CycleDevice(int index)
{
BOOL found = FALSE, disabled = FALSE;
char device_instance_id[MAX_PATH];
DWORD i, size, ret = ERROR_DEV_NOT_EXIST;
LONG dev_status, problem_code;
HDEVINFO dev_info;
SP_DEVINFO_DATA dev_info_data;
SP_PROPCHANGE_PARAMS propchange_params;
if ((index < 0) || (safe_strlen(DriveId.String[index]) < 8))
return ERROR_INVALID_PARAMETER;
// Need DIGCF_ALLCLASSES else disabled devices won't be listed.
dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (dev_info == INVALID_HANDLE_VALUE) {
uprintf("Could not get classes for device cycling: %s", WindowsErrorString());
return ERROR_PATH_NOT_FOUND;
}
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
for (i = 0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) {
memset(device_instance_id, 0, sizeof(device_instance_id));
size = sizeof(device_instance_id);
if (!SetupDiGetDeviceInstanceIdA(dev_info, &dev_info_data, device_instance_id, size, &size)) {
continue;
}
if (safe_strcmp(DriveId.String[index], device_instance_id) != 0)
continue;
found = TRUE;
// Detect if the device is already disabled
if (CM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS)
disabled = (dev_status & DN_HAS_PROBLEM) && (problem_code == CM_PROB_DISABLED);
// Disable the device
if (!disabled) {
memset(&propchange_params, 0, sizeof(propchange_params));
propchange_params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
propchange_params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
propchange_params.Scope = DICS_FLAG_GLOBAL;
propchange_params.StateChange = DICS_DISABLE;
if (!SetupDiSetClassInstallParams(dev_info, &dev_info_data,
(SP_CLASSINSTALL_HEADER*)&propchange_params, sizeof(propchange_params))) {
uprintf("Could not cycle device (D1): %s", WindowsErrorString());
break;
}
if (!SetupDiChangeState(dev_info, &dev_info_data)) {
uprintf("Could not cycle device (D2): %s", WindowsErrorString());
// If we failed to actually change the status, we must revert the properties
ret = ERROR_OPERATION_ABORTED;
}
Sleep(250);
}
// Re-enable the device
memset(&propchange_params, 0, sizeof(propchange_params));
propchange_params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
propchange_params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
propchange_params.Scope = DICS_FLAG_GLOBAL;
propchange_params.StateChange = DICS_ENABLE;
if (!SetupDiSetClassInstallParams(dev_info, &dev_info_data,
(SP_CLASSINSTALL_HEADER*)&propchange_params, sizeof(propchange_params))) {
uprintf("Could not cycle device (E1): %s", WindowsErrorString());
ret = ERROR_OPERATION_ABORTED;
}
if (ret == ERROR_OPERATION_ABORTED)
break;
if (!SetupDiChangeState(dev_info, &dev_info_data)) {
uprintf("Could not cycle device (E2): %s", WindowsErrorString());
ret = ERROR_GEN_FAILURE;
} else {
ret = ERROR_SUCCESS;
}
// This is great: The MS APIs may let you believe that disabling and reenabling was
// successful, but leave the device in an actual disabled state... So we can end up
// with zombie devices, that are effectively disabled, but that Windows still sees
// as enabled... So we need to detect this.
if (CM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) {
disabled = (dev_status & DN_HAS_PROBLEM) && (problem_code == CM_PROB_DISABLED);
if (disabled)
ret = ERROR_DEVICE_REINITIALIZATION_NEEDED;
}
break;
}
SetupDiDestroyDeviceInfoList(dev_info);
if (!found)
uprintf("Could not find a device to cycle!");
return ret;
}
static __inline BOOL IsVHD(const char* buffer) static __inline BOOL IsVHD(const char* buffer)
{ {
int i; int i;
@ -225,7 +329,7 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save)
dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_CDROM, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_CDROM, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (dev_info == INVALID_HANDLE_VALUE) { if (dev_info == INVALID_HANDLE_VALUE) {
uprintf("SetupDiGetClassDevs (Interface) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetClassDevs (Interface) failed: %s", WindowsErrorString());
return FALSE; return FALSE;
} }
dev_info_data.cbSize = sizeof(dev_info_data); dev_info_data.cbSize = sizeof(dev_info_data);
@ -233,7 +337,7 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save)
memset(str, 0, sizeof(str)); memset(str, 0, sizeof(str));
if (!SetupDiGetDeviceRegistryPropertyU(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, if (!SetupDiGetDeviceRegistryPropertyU(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME,
&datatype, (LPBYTE)str, sizeof(str), &size)) { &datatype, (LPBYTE)str, sizeof(str), &size)) {
uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s", WindowsErrorString());
static_strcpy(str, "Generic Optical Drive"); static_strcpy(str, "Generic Optical Drive");
} }
uprintf("Found '%s' optical device", str); uprintf("Found '%s' optical device", str);
@ -246,7 +350,7 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save)
if (!SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_CDROM, j, &devint_data)) { if (!SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_CDROM, j, &devint_data)) {
if (GetLastError() != ERROR_NO_MORE_ITEMS) { if (GetLastError() != ERROR_NO_MORE_ITEMS) {
uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString()); uprintf("SetupDiEnumDeviceInterfaces failed: %s", WindowsErrorString());
} }
break; break;
} }
@ -255,21 +359,21 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save)
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size); devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size);
if (devint_detail_data == NULL) { if (devint_detail_data == NULL) {
uprintf("Unable to allocate data for SP_DEVICE_INTERFACE_DETAIL_DATA\n"); uprintf("Unable to allocate data for SP_DEVICE_INTERFACE_DETAIL_DATA");
continue; continue;
} }
devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
} else { } else {
uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s", WindowsErrorString());
continue; continue;
} }
} }
if (devint_detail_data == NULL) { if (devint_detail_data == NULL) {
uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated\n"); uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated");
continue; continue;
} }
if (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) { if (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) {
uprintf("SetupDiGetDeviceInterfaceDetail (actual) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceInterfaceDetail (actual) failed: %s", WindowsErrorString());
continue; continue;
} }
@ -338,8 +442,8 @@ BOOL GetDevices(DWORD devnum)
"SCSI", // "STORAGE", // "STORAGE" is used by 'Storage Spaces" and stuff => DANGEROUS! "SCSI", // "STORAGE", // "STORAGE" is used by 'Storage Spaces" and stuff => DANGEROUS!
// Non-USB card reader drivers - This list *MUST* start with "SD" (delimiter) // Non-USB card reader drivers - This list *MUST* start with "SD" (delimiter)
// See http://itdoc.hitachi.co.jp/manuals/3021/30213B5200e/DMDS0094.HTM // See http://itdoc.hitachi.co.jp/manuals/3021/30213B5200e/DMDS0094.HTM
// Also http://www.carrona.org/dvrref.php. NB: These should be reported // Also http://www.carrona.org/dvrref.php. NB: All members from this list should have
// as enumerators by Rufus when Enum Debug is enabled // been reported as enumerators by Rufus, when Enum Debug is enabled.
"SD", "PCISTOR", "RTSOR", "JMCR", "JMCF", "RIMMPTSK", "RIMSPTSK", "RISD", "RIXDPTSK", "SD", "PCISTOR", "RTSOR", "JMCR", "JMCF", "RIMMPTSK", "RIMSPTSK", "RISD", "RIXDPTSK",
"TI21SONY", "ESD7SK", "ESM7SK", "O2MD", "O2SD", "VIACR" "TI21SONY", "ESD7SK", "ESM7SK", "O2MD", "O2SD", "VIACR"
}; };
@ -362,18 +466,19 @@ BOOL GetDevices(DWORD devnum)
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, grandparent_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, data_type, drive_index;
DWORD uasp_start = ARRAYSIZE(usbstor_name), card_start = ARRAYSIZE(genstor_name); DWORD uasp_start = ARRAYSIZE(usbstor_name), card_start = ARRAYSIZE(genstor_name);
ULONG list_size[ARRAYSIZE(usbstor_name)] = { 0 }, list_start[ARRAYSIZE(usbstor_name)] = { 0 }, full_list_size, ulFlags; ULONG list_size[ARRAYSIZE(usbstor_name)] = { 0 }, list_start[ARRAYSIZE(usbstor_name)] = { 0 }, full_list_size, ulFlags;
HANDLE hDrive; HANDLE hDrive;
LONG maxwidth = 0; LONG maxwidth = 0;
int s, score, drive_number, remove_drive; int s, score, drive_number, remove_drive;
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 *p, *label, *entry, buffer[MAX_PATH], str[MAX_PATH], *method_str, *hub_path; char *p, *label, *entry, buffer[MAX_PATH], str[MAX_PATH], device_instance_id[MAX_PATH], *method_str, *hub_path;
usb_device_props props; usb_device_props props;
IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList)); IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList));
StrArrayClear(&DriveID); StrArrayClear(&DriveId);
StrArrayClear(&DriveName);
StrArrayClear(&DriveLabel); StrArrayClear(&DriveLabel);
StrArrayClear(&DriveHub); StrArrayClear(&DriveHub);
StrArrayCreate(&dev_if_path, 128); StrArrayCreate(&dev_if_path, 128);
@ -386,7 +491,7 @@ BOOL GetDevices(DWORD devnum)
// Build a hash table associating a CM Device ID of an USB device with the SetupDI Device Interface Path // Build a hash table associating a CM Device ID of an USB device with the SetupDI Device Interface Path
// of its parent hub - this is needed to retrieve the device speed // of its parent hub - this is needed to retrieve the device speed
dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_USB_HUB, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_USB_HUB, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (dev_info != INVALID_HANDLE_VALUE) { if (dev_info != INVALID_HANDLE_VALUE) {
if (htab_create(DEVID_HTAB_SIZE, &htab_devid)) { if (htab_create(DEVID_HTAB_SIZE, &htab_devid)) {
dev_info_data.cbSize = sizeof(dev_info_data); dev_info_data.cbSize = sizeof(dev_info_data);
@ -464,7 +569,7 @@ BOOL GetDevices(DWORD devnum)
full_list_size += 1; // add extra NUL terminator full_list_size += 1; // add extra NUL terminator
devid_list = (char*)malloc(full_list_size); devid_list = (char*)malloc(full_list_size);
if (devid_list == NULL) { if (devid_list == NULL) {
uprintf("Could not allocate Device ID list\n"); uprintf("Could not allocate Device ID list");
goto out; goto out;
} }
for (s=0, i=0; s<ARRAYSIZE(usbstor_name); s++) { for (s=0, i=0; s<ARRAYSIZE(usbstor_name); s++) {
@ -487,9 +592,9 @@ BOOL GetDevices(DWORD devnum)
} }
// Now use SetupDi to enumerate all our disk storage devices // Now use SetupDi to enumerate all our disk storage devices
dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (dev_info == INVALID_HANDLE_VALUE) { if (dev_info == INVALID_HANDLE_VALUE) {
uprintf("SetupDiGetClassDevs (Interface) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetClassDevs (Interface) failed: %s", WindowsErrorString());
goto out; goto out;
} }
dev_info_data.cbSize = sizeof(dev_info_data); dev_info_data.cbSize = sizeof(dev_info_data);
@ -499,8 +604,8 @@ BOOL GetDevices(DWORD devnum)
method_str = ""; method_str = "";
hub_path = NULL; hub_path = NULL;
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)) { &data_type, (LPBYTE)buffer, sizeof(buffer), &size)) {
uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s", WindowsErrorString());
continue; continue;
} }
@ -533,7 +638,7 @@ BOOL GetDevices(DWORD devnum)
// according to your locale, so we poke the Hardware ID // according to your locale, so we poke the Hardware ID
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
props.is_VHD = SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_HARDWAREID, props.is_VHD = SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_HARDWAREID,
&datatype, (LPBYTE)buffer, sizeof(buffer), &size) && IsVHD(buffer); &data_type, (LPBYTE)buffer, sizeof(buffer), &size) && IsVHD(buffer);
// Additional detection for SCSI card readers // Additional detection for SCSI card readers
if ((!props.is_CARD) && (safe_strnicmp(buffer, scsi_disk_prefix, sizeof(scsi_disk_prefix)-1) == 0)) { if ((!props.is_CARD) && (safe_strnicmp(buffer, scsi_disk_prefix, sizeof(scsi_disk_prefix)-1) == 0)) {
for (j = 0; j < ARRAYSIZE(scsi_card_name); j++) { for (j = 0; j < ARRAYSIZE(scsi_card_name); j++) {
@ -553,14 +658,21 @@ BOOL GetDevices(DWORD devnum)
} }
uuprintf(" Hardware ID: '%s'", buffer); uuprintf(" Hardware ID: '%s'", buffer);
// Keep track of the Device Instance ID, which we'll need to "reset" the device
if (!SetupDiGetDeviceInstanceIdA(dev_info, &dev_info_data, device_instance_id,
sizeof(device_instance_id), &size)) {
uprintf("SetupDiGetDeviceInstanceId failed: %s", WindowsErrorString());
static_strcpy(device_instance_id, "<N/A>");
}
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
props.is_Removable = SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_REMOVAL_POLICY, props.is_Removable = SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_REMOVAL_POLICY,
&datatype, (LPBYTE)buffer, sizeof(buffer), &size) && IsRemovable(buffer); &data_type, (LPBYTE)buffer, sizeof(buffer), &size) && IsRemovable(buffer);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
if (!SetupDiGetDeviceRegistryPropertyU(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, if (!SetupDiGetDeviceRegistryPropertyU(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME,
&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { &data_type, (LPBYTE)buffer, sizeof(buffer), &size)) {
uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s", WindowsErrorString());
// We can afford a failure on this call - just replace the name with "USB Storage Device (Generic)" // We can afford a failure on this call - just replace the name with "USB Storage Device (Generic)"
static_strcpy(buffer, lmprintf(MSG_045)); static_strcpy(buffer, lmprintf(MSG_045));
} else if ((!props.is_VHD) && (devid_list != NULL)) { } else if ((!props.is_VHD) && (devid_list != NULL)) {
@ -668,7 +780,7 @@ BOOL GetDevices(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) %s\n", props.is_UASP?"UAS (":"", uprintf("Found %s%s%s device '%s' (%s) %s", props.is_UASP?"UAS (":"",
usb_speed_name[props.speed], props.is_UASP?")":"", buffer, str, method_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...");
@ -682,9 +794,9 @@ BOOL GetDevices(DWORD devnum)
if (!SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_DISK, j, &devint_data)) { if (!SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_DISK, j, &devint_data)) {
if(GetLastError() != ERROR_NO_MORE_ITEMS) { if(GetLastError() != ERROR_NO_MORE_ITEMS) {
uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString()); uprintf("SetupDiEnumDeviceInterfaces failed: %s", WindowsErrorString());
} else { } else {
uprintf("A device was eliminated because it didn't report itself as a disk\n"); uprintf("A device was eliminated because it didn't report itself as a disk");
} }
break; break;
} }
@ -693,28 +805,28 @@ BOOL GetDevices(DWORD devnum)
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size); devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size);
if (devint_detail_data == NULL) { if (devint_detail_data == NULL) {
uprintf("Unable to allocate data for SP_DEVICE_INTERFACE_DETAIL_DATA\n"); uprintf("Unable to allocate data for SP_DEVICE_INTERFACE_DETAIL_DATA");
continue; continue;
} }
devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
} else { } else {
uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s", WindowsErrorString());
continue; continue;
} }
} }
if (devint_detail_data == NULL) { if (devint_detail_data == NULL) {
uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated\n"); uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated");
continue; continue;
} }
if(!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) { if(!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) {
uprintf("SetupDiGetDeviceInterfaceDetail (actual) failed: %s\n", WindowsErrorString()); uprintf("SetupDiGetDeviceInterfaceDetail (actual) failed: %s", WindowsErrorString());
continue; continue;
} }
hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE, hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hDrive == INVALID_HANDLE_VALUE) { if(hDrive == INVALID_HANDLE_VALUE) {
uprintf("Could not open '%s': %s\n", devint_detail_data->DevicePath, WindowsErrorString()); uprintf("Could not open '%s': %s", devint_detail_data->DevicePath, WindowsErrorString());
continue; continue;
} }
@ -724,13 +836,13 @@ BOOL GetDevices(DWORD devnum)
drive_index = drive_number + DRIVE_INDEX_MIN; drive_index = drive_number + DRIVE_INDEX_MIN;
if (!IsMediaPresent(drive_index)) { if (!IsMediaPresent(drive_index)) {
uprintf("Device eliminated because it appears to contain no media\n"); uprintf("Device eliminated because it appears to contain no media");
safe_closehandle(hDrive); safe_closehandle(hDrive);
safe_free(devint_detail_data); safe_free(devint_detail_data);
break; break;
} }
if (GetDriveSize(drive_index) < (MIN_DRIVE_SIZE*MB)) { if (GetDriveSize(drive_index) < (MIN_DRIVE_SIZE*MB)) {
uprintf("Device eliminated because it is smaller than %d MB\n", MIN_DRIVE_SIZE); uprintf("Device eliminated because it is smaller than %d MB", MIN_DRIVE_SIZE);
safe_closehandle(hDrive); safe_closehandle(hDrive);
safe_free(devint_detail_data); safe_free(devint_detail_data);
break; break;
@ -815,7 +927,8 @@ BOOL GetDevices(DWORD devnum)
} }
// Must ensure that the combo box is UNSORTED for indexes to be the same // Must ensure that the combo box is UNSORTED for indexes to be the same
StrArrayAdd(&DriveID, buffer, TRUE); StrArrayAdd(&DriveId, device_instance_id, TRUE);
StrArrayAdd(&DriveName, buffer, TRUE);
StrArrayAdd(&DriveLabel, label, TRUE); StrArrayAdd(&DriveLabel, label, TRUE);
if ((hub_path != NULL) && (StrArrayAdd(&DriveHub, hub_path, TRUE) >= 0)) if ((hub_path != NULL) && (StrArrayAdd(&DriveHub, hub_path, TRUE) >= 0))
DrivePort[DriveHub.Index - 1] = props.port; DrivePort[DriveHub.Index - 1] = props.port;
@ -834,7 +947,7 @@ BOOL GetDevices(DWORD devnum)
SendMessage(hDeviceList, CB_SETDROPPEDWIDTH, (WPARAM)maxwidth, 0); SendMessage(hDeviceList, CB_SETDROPPEDWIDTH, (WPARAM)maxwidth, 0);
if (devnum >= DRIVE_INDEX_MIN) { if (devnum >= DRIVE_INDEX_MIN) {
for (i=0; i<ComboBox_GetCount(hDeviceList); i++) { for (i = 0; i < ComboBox_GetCount(hDeviceList); i++) {
if ((DWORD)ComboBox_GetItemData(hDeviceList, i) == devnum) { if ((DWORD)ComboBox_GetItemData(hDeviceList, i) == devnum) {
found = TRUE; found = TRUE;
break; break;

View file

@ -98,11 +98,12 @@ typedef enum USB_HUB_NODE {
/* Cfgmgr32.dll interface */ /* Cfgmgr32.dll interface */
DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST dnDevInst, PCSTR Buffer, ULONG BufferLen, ULONG ulFlags); DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST dnDevInst, PCSTR Buffer, ULONG BufferLen, ULONG ulFlags);
DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(PULONG pulLen, PCSTR pszFilter, ULONG ulFlags); DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(PULONG pulLen, PCSTR pszFilter, ULONG ulFlags);
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_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);
DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_DevNode_Status(PULONG pulStatus, PULONG pulProblemNumber, 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));

View file

@ -419,6 +419,89 @@ out:
return ret; return ret;
} }
/*
* Call on VDS to refresh the drive layout
*/
BOOL RefreshLayout(DWORD DriveIndex)
{
BOOL r = FALSE;
HRESULT hr;
wchar_t wPhysicalName[24];
IVdsServiceLoader *pLoader;
IVdsService *pService;
IEnumVdsObject *pEnum;
CheckDriveIndex(DriveIndex);
wnsprintf(wPhysicalName, ARRAYSIZE(wPhysicalName), L"\\\\?\\PhysicalDrive%lu", DriveIndex);
// Initialize COM
IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
IGNORE_RETVAL(CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL));
// Create a VDS Loader Instance
hr = CoCreateInstance(&CLSID_VdsLoader, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
&IID_IVdsServiceLoader, (void **)&pLoader);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("Could not create VDS Loader Instance: %s", WindowsErrorString());
goto out;
}
// Load the VDS Service
hr = IVdsServiceLoader_LoadService(pLoader, L"", &pService);
IVdsServiceLoader_Release(pLoader);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("Could not load VDS Service: %s", WindowsErrorString());
goto out;
}
// Wait for the Service to become ready if needed
hr = IVdsService_WaitForServiceReady(pService);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("VDS Service is not ready: %s", WindowsErrorString());
goto out;
}
// Query the VDS Service Providers
hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("Could not query VDS Service Providers: %s", WindowsErrorString());
goto out;
}
// Remove mountpoints
hr = IVdsService_CleanupObsoleteMountPoints(pService);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("Could not clean up VDS mountpoints: %s", WindowsErrorString());
goto out;
}
// Invoke layout refresh
hr = IVdsService_Refresh(pService);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("Could not refresh VDS layout: %s", WindowsErrorString());
goto out;
}
// Force re-enum
hr = IVdsService_Reenumerate(pService);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("Could not refresh VDS layout: %s", WindowsErrorString());
goto out;
}
r = TRUE;
out:
return r;
}
/* /*
* Delete all the partitions from a disk, using VDS * Delete all the partitions from a disk, using VDS
* Mostly copied from https://social.msdn.microsoft.com/Forums/vstudio/en-US/b90482ae-4e44-4b08-8731-81915030b32a/createpartition-using-vds-interface-throw-error-enointerface-dcom?forum=vcgeneral * Mostly copied from https://social.msdn.microsoft.com/Forums/vstudio/en-US/b90482ae-4e44-4b08-8731-81915030b32a/createpartition-using-vds-interface-throw-error-enointerface-dcom?forum=vcgeneral
@ -460,6 +543,14 @@ BOOL DeletePartitions(DWORD DriveIndex)
goto out; goto out;
} }
// Wait for the Service to become ready if needed
hr = IVdsService_WaitForServiceReady(pService);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("VDS Service is not ready: %s", WindowsErrorString());
goto out;
}
// Query the VDS Service Providers // Query the VDS Service Providers
hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum); hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
if (hr != S_OK) { if (hr != S_OK) {
@ -666,6 +757,24 @@ HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive,
return hLogical; return hLogical;
} }
/*
* Similar to the above, but use the partition name instead
*/
HANDLE GetPartitionHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare)
{
HANDLE handle = INVALID_HANDLE_VALUE;
char* volume_name = GetPartitionName(DriveIndex, PartitionIndex);
if (volume_name == NULL) {
uprintf("Could not get partition volume name");
return NULL;
}
handle = GetHandle(volume_name, bLockDrive, bWriteAccess, bWriteShare);
free(volume_name);
return handle;
}
/* /*
* Who would have thought that Microsoft would make it so unbelievably hard to * Who would have thought that Microsoft would make it so unbelievably hard to
* get the frickin' device number for a drive? You have to use TWO different * get the frickin' device number for a drive? You have to use TWO different

View file

@ -292,6 +292,10 @@ interface IVdsAsync {
#define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService) #define IVdsServiceLoader_LoadService(This, pwszMachineName, ppService) (This)->lpVtbl->LoadService(This, pwszMachineName, ppService)
#define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This) #define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This)
#define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum) #define IVdsService_QueryProviders(This, masks, ppEnum) (This)->lpVtbl->QueryProviders(This, masks, ppEnum)
#define IVdsService_WaitForServiceReady(This) ((This)->lpVtbl->WaitForServiceReady(This))
#define IVdsService_CleanupObsoleteMountPoints(This) ((This)->lpVtbl->CleanupObsoleteMountPoints(This))
#define IVdsService_Refresh(This) ((This)->lpVtbl->Refresh(This))
#define IVdsService_Reenumerate(This) ((This)->lpVtbl->Reenumerate(This))
#define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject) #define IVdsSwProvider_QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
#define IVdsProvider_Release(This) (This)->lpVtbl->Release(This) #define IVdsProvider_Release(This) (This)->lpVtbl->Release(This)
#define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum) #define IVdsSwProvider_QueryPacks(This, ppEnum) (This)->lpVtbl->QueryPacks(This, ppEnum)
@ -367,6 +371,7 @@ HANDLE GetPhysicalHandle(DWORD DriveIndex, BOOL bLockDrive, BOOL bWriteAccess, B
char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingBackslash, BOOL bSilent); char* GetLogicalName(DWORD DriveIndex, DWORD PartitionIndex, BOOL bKeepTrailingBackslash, BOOL bSilent);
BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex); BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex);
HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare); HANDLE GetLogicalHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
HANDLE GetPartitionHandle(DWORD DriveIndex, DWORD PartitionIndex, BOOL bLockDrive, BOOL bWriteAccess, BOOL bWriteShare);
int GetDriveNumber(HANDLE hDrive, char* path); int GetDriveNumber(HANDLE hDrive, char* path);
BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters); BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters);
UINT GetDriveTypeFromIndex(DWORD DriveIndex); UINT GetDriveTypeFromIndex(DWORD DriveIndex);
@ -387,3 +392,8 @@ BOOL InitializeDisk(HANDLE hDrive);
BOOL RefreshDriveLayout(HANDLE hDrive); BOOL RefreshDriveLayout(HANDLE hDrive);
const char* GetPartitionType(BYTE Type); const char* GetPartitionType(BYTE Type);
const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex); const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex);
BOOL GetDevices(DWORD devnum);
BOOL CyclePort(int index);
int CycleDevice(int index);
BOOL RefreshLayout(DWORD DriveIndex);
BOOL GetOpticalMedia(IMG_SAVE* img_save);

View file

@ -793,10 +793,12 @@ const char* error_message(errcode_t error_code)
case EXT2_ET_EA_INODE_CORRUPTED: case EXT2_ET_EA_INODE_CORRUPTED:
return "Inode is corrupted"; return "Inode is corrupted";
default: default:
if ((error_code > EXT2_ET_BASE) && error_code < (EXT2_ET_BASE + 1000)) if ((error_code > EXT2_ET_BASE) && error_code < (EXT2_ET_BASE + 1000)) {
static_sprintf(error_string, "Unknown ext2fs error %ld (EXT2_ET_BASE + %ld)", error_code, error_code - EXT2_ET_BASE); static_sprintf(error_string, "Unknown ext2fs error %ld (EXT2_ET_BASE + %ld)", error_code, error_code - EXT2_ET_BASE);
else } else {
static_sprintf(error_string, "Unknown ext2fs error 0x%08lX", error_code); SetLastError((FormatStatus == 0) ? (ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | (error_code & 0xFFFF)) : FormatStatus);
static_sprintf(error_string, WindowsErrorString());
}
return error_string; return error_string;
} }
} }
@ -826,13 +828,14 @@ const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex)
char* volume_name = GetPartitionName(DriveIndex, PartitionIndex); char* volume_name = GetPartitionName(DriveIndex, PartitionIndex);
r = ext2fs_open(volume_name, EXT2_FLAG_SKIP_MMP, 0, 0, manager, &ext2fs); r = ext2fs_open(volume_name, EXT2_FLAG_SKIP_MMP, 0, 0, manager, &ext2fs);
if (r == 0) {
strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN);
label[EXT2_LABEL_LEN] = 0;
}
if (ext2fs != NULL)
ext2fs_close(ext2fs);
free(volume_name); free(volume_name);
if (r != 0) return (r == 0) ? label : NULL;
return NULL;
strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN);
label[EXT2_LABEL_LEN] = 0;
ext2fs_close(ext2fs);
return label;
} }
BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) BOOL FormatExtFs(DWORD DriveIndex, DWORD PartitionIndex, DWORD BlockSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
@ -1074,7 +1077,7 @@ out:
*/ */
static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags) static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD ClusterSize, LPCSTR FSName, LPCSTR Label, DWORD Flags)
{ {
BOOL r = FALSE; BOOL r = FALSE, bFoundVolume = FALSE;
HRESULT hr; HRESULT hr;
ULONG ulFetched; ULONG ulFetched;
IVdsServiceLoader *pLoader; IVdsServiceLoader *pLoader;
@ -1121,6 +1124,14 @@ static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD Cluster
goto out; goto out;
} }
// Wait for the Service to become ready if needed
hr = IVdsService_WaitForServiceReady(pService);
if (hr != S_OK) {
VDS_SET_ERROR(hr);
uprintf("VDS Service is not ready: %s", WindowsErrorString());
goto out;
}
// Query the VDS Service Providers // Query the VDS Service Providers
hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum); hr = IVdsService_QueryProviders(pService, VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
if (hr != S_OK) { if (hr != S_OK) {
@ -1241,6 +1252,7 @@ static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD Cluster
if (!match) if (!match)
continue; continue;
bFoundVolume = TRUE;
if (strcmp(Label, FileSystemLabel[FS_UDF]) == 0) if (strcmp(Label, FileSystemLabel[FS_UDF]) == 0)
usFsVersion = ReadSetting32(SETTING_USE_UDF_VERSION); usFsVersion = ReadSetting32(SETTING_USE_UDF_VERSION);
if (ClusterSize < 0x200) { if (ClusterSize < 0x200) {
@ -1297,6 +1309,8 @@ static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD Cluster
} }
out: out:
if ((!bFoundVolume) && (FormatStatus == 0))
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_PATH_NOT_FOUND;
safe_free(VolumeName); safe_free(VolumeName);
safe_free(wVolumeName); safe_free(wVolumeName);
safe_free(wLabel); safe_free(wLabel);
@ -2616,8 +2630,24 @@ DWORD WINAPI FormatThread(void* param)
// VDS wants us to unlock the phys // VDS wants us to unlock the phys
// TODO: IVdsDiskOnline::Offline? -> NOPE, NO_GO for removable media // TODO: IVdsDiskOnline::Offline? -> NOPE, NO_GO for removable media
// TODO: IVdsService::Refresh()? IVdsHwProvider::Reenumerate()?? // TODO: IVdsService::Refresh()? IVdsHwProvider::Reenumerate()??
if (use_vds) if (use_vds) {
safe_unlockclose(hPhysicalDrive); safe_unlockclose(hPhysicalDrive);
uprintf("Refreshing drive layout...");
#if 0
// **DON'T USE** This may leave the device disabled on re-plug or reboot
DWORD cr = CycleDevice(ComboBox_GetCurSel(hDeviceList));
if (cr == ERROR_DEVICE_REINITIALIZATION_NEEDED) {
uprintf("Zombie device detected, trying again...");
Sleep(1000);
cr = CycleDevice(ComboBox_GetCurSel(hDeviceList));
}
if (cr == 0)
uprintf("Successfully cycled device");
else
uprintf("Cycling device failed!");
#endif
RefreshLayout(DriveIndex);
}
// Wait for the logical drive we just created to appear // Wait for the logical drive we just created to appear
uprintf("Waiting for logical drive to reappear..."); uprintf("Waiting for logical drive to reappear...");

View file

@ -504,6 +504,7 @@ out:
if (p_udf_dirent != NULL) if (p_udf_dirent != NULL)
udf_dirent_free(p_udf_dirent); udf_dirent_free(p_udf_dirent);
ISO_BLOCKING(safe_closehandle(file_handle)); ISO_BLOCKING(safe_closehandle(file_handle));
safe_free(psz_sanpath);
safe_free(psz_fullpath); safe_free(psz_fullpath);
return 1; return 1;
} }
@ -516,7 +517,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
EXTRACT_PROPS props; EXTRACT_PROPS props;
BOOL is_symlink, is_identical; BOOL is_symlink, is_identical;
int length, r = 1; int length, r = 1;
char tmp[128], psz_fullpath[MAX_PATH], *psz_basename, *psz_sanpath; char tmp[128], psz_fullpath[MAX_PATH], *psz_basename = NULL, *psz_sanpath = NULL;
const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)]; const char *psz_iso_name = &psz_fullpath[strlen(psz_extract_dir)];
unsigned char buf[ISO_BLOCKSIZE]; unsigned char buf[ISO_BLOCKSIZE];
CdioListNode_t* p_entnode; CdioListNode_t* p_entnode;
@ -651,6 +652,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
out: out:
ISO_BLOCKING(safe_closehandle(file_handle)); ISO_BLOCKING(safe_closehandle(file_handle));
iso9660_filelist_free(p_entlist); iso9660_filelist_free(p_entlist);
safe_free(psz_sanpath);
return r; return r;
} }

View file

@ -119,7 +119,7 @@ char embedded_sl_version_ext[2][32];
char ClusterSizeLabel[MAX_CLUSTER_SIZES][64]; char ClusterSizeLabel[MAX_CLUSTER_SIZES][64];
char msgbox[1024], msgbox_title[32], *ini_file = NULL, *image_path = NULL, *short_image_path; char msgbox[1024], msgbox_title[32], *ini_file = NULL, *image_path = NULL, *short_image_path;
char image_option_txt[128], *fido_url = NULL; char image_option_txt[128], *fido_url = NULL;
StrArray DriveID, DriveLabel, DriveHub, BlockingProcess, ImageList; StrArray DriveId, DriveName, DriveLabel, DriveHub, BlockingProcess, ImageList;
// Number of steps for each FS for FCC_STRUCTURE_PROGRESS // Number of steps for each FS for FCC_STRUCTURE_PROGRESS
const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10, 1, 1, 1, 1 }; const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10, 1, 1, 1, 1 };
const char* flash_type[BADLOCKS_PATTERN_TYPES] = { "SLC", "MLC", "TLC" }; const char* flash_type[BADLOCKS_PATTERN_TYPES] = { "SLC", "MLC", "TLC" };
@ -857,14 +857,14 @@ static BOOL PopulateProperties(void)
SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, use_fake_units)); SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, use_fake_units));
// Add a tooltip (with the size of the device in parenthesis) // Add a tooltip (with the size of the device in parenthesis)
device_tooltip = (char*) malloc(safe_strlen(DriveID.String[device_index]) + 32); device_tooltip = (char*) malloc(safe_strlen(DriveName.String[device_index]) + 32);
if (device_tooltip != NULL) { if (device_tooltip != NULL) {
if (right_to_left_mode) if (right_to_left_mode)
safe_sprintf(device_tooltip, safe_strlen(DriveID.String[device_index]) + 32, "(%s) %s", safe_sprintf(device_tooltip, safe_strlen(DriveName.String[device_index]) + 32, "(%s) %s",
SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE), DriveID.String[device_index]); SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE), DriveName.String[device_index]);
else else
safe_sprintf(device_tooltip, safe_strlen(DriveID.String[device_index]) + 32, "%s (%s)", safe_sprintf(device_tooltip, safe_strlen(DriveName.String[device_index]) + 32, "%s (%s)",
DriveID.String[device_index], SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE)); DriveName.String[device_index], SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE));
CreateTooltip(hDeviceList, device_tooltip, -1); CreateTooltip(hDeviceList, device_tooltip, -1);
free(device_tooltip); free(device_tooltip);
} }
@ -1644,7 +1644,8 @@ static void InitDialog(HWND hDlg)
IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0)); IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0));
// Create the string arrays // Create the string arrays
StrArrayCreate(&DriveID, MAX_DRIVES); StrArrayCreate(&DriveId, MAX_DRIVES);
StrArrayCreate(&DriveName, MAX_DRIVES);
StrArrayCreate(&DriveLabel, MAX_DRIVES); StrArrayCreate(&DriveLabel, MAX_DRIVES);
StrArrayCreate(&DriveHub, MAX_DRIVES); StrArrayCreate(&DriveHub, MAX_DRIVES);
StrArrayCreate(&BlockingProcess, 16); StrArrayCreate(&BlockingProcess, 16);
@ -1982,7 +1983,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
if (ulRegister != 0) if (ulRegister != 0)
SHChangeNotifyDeregister(ulRegister); SHChangeNotifyDeregister(ulRegister);
PostQuitMessage(0); PostQuitMessage(0);
StrArrayDestroy(&DriveID); StrArrayDestroy(&DriveId);
StrArrayDestroy(&DriveName);
StrArrayDestroy(&DriveLabel); StrArrayDestroy(&DriveLabel);
StrArrayDestroy(&DriveHub); StrArrayDestroy(&DriveHub);
StrArrayDestroy(&BlockingProcess); StrArrayDestroy(&BlockingProcess);
@ -2765,7 +2767,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
int index = ComboBox_GetCurSel(hDeviceList); int index = ComboBox_GetCurSel(hDeviceList);
if (index >= 0) { if (index >= 0) {
uprintf("Device not ready → Trying to cycle port..."); uprintf("Device not ready → Trying to cycle port...");
ResetDevice(index); CyclePort(index);
} }
} }
Notification(MSG_ERROR, NULL, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus, FALSE))); Notification(MSG_ERROR, NULL, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus, FALSE)));
@ -3278,7 +3280,7 @@ relaunch:
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'C')) { if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'C')) {
int index = ComboBox_GetCurSel(hDeviceList); int index = ComboBox_GetCurSel(hDeviceList);
if (index >= 0) if (index >= 0)
ResetDevice(index); CyclePort(index);
continue; continue;
} }
// Alt-D => Delete the 'rufus_files' subdirectory // Alt-D => Delete the 'rufus_files' subdirectory

View file

@ -510,9 +510,6 @@ extern unsigned char* GetResource(HMODULE module, char* name, char* type, const
extern DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc); extern DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc);
extern DWORD RunCommand(const char* cmdline, const char* dir, BOOL log); extern DWORD RunCommand(const char* cmdline, const char* dir, BOOL log);
extern BOOL CompareGUID(const GUID *guid1, const GUID *guid2); extern BOOL CompareGUID(const GUID *guid1, const GUID *guid2);
extern BOOL GetDevices(DWORD devnum);
extern BOOL ResetDevice(int index);
extern BOOL GetOpticalMedia(IMG_SAVE* img_save);
extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue); extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
extern LONG GetEntryWidth(HWND hDropDown, const char* entry); extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
extern uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress); extern uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress);

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326 IDD_DIALOG DIALOGEX 12, 12, 232, 326
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_ACCEPTFILES EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 3.6.1535" CAPTION "Rufus 3.6.1536"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0 FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -394,8 +394,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,6,1535,0 FILEVERSION 3,6,1536,0
PRODUCTVERSION 3,6,1535,0 PRODUCTVERSION 3,6,1536,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -413,13 +413,13 @@ BEGIN
VALUE "Comments", "https://akeo.ie" VALUE "Comments", "https://akeo.ie"
VALUE "CompanyName", "Akeo Consulting" VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.6.1535" VALUE "FileVersion", "3.6.1536"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2019 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus-3.6.exe" VALUE "OriginalFilename", "rufus-3.6.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.6.1535" VALUE "ProductVersion", "3.6.1536"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"