From 8b18d8ce1dd493d30f2ba0259bf570a63400492e Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 23 May 2019 13:09:25 +0100 Subject: [PATCH] [core] add CycleDevice and VDS layout refresh * Also fix some minor issues --- res/loc/po/sr-SP.po | 4 +- res/loc/rufus.loc | 2 +- src/dev.c | 189 +++++++++++++++++++++++++++++++++++--------- src/dev.h | 3 +- src/drive.c | 109 +++++++++++++++++++++++++ src/drive.h | 10 +++ src/format.c | 52 +++++++++--- src/iso.c | 4 +- src/rufus.c | 22 +++--- src/rufus.h | 3 - src/rufus.rc | 10 +-- 11 files changed, 336 insertions(+), 72 deletions(-) diff --git a/res/loc/po/sr-SP.po b/res/loc/po/sr-SP.po index b805edc4..78d4ead6 100644 --- a/res/loc/po/sr-SP.po +++ b/res/loc/po/sr-SP.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: 3.5\n" "Report-Msgid-Bugs-To: pete@akeo.ie\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" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1095,7 +1095,7 @@ msgstr "Verzija %d.%d (Izvršna verzija %d)" #. • MSG_176 msgid "English translation: Pete Batard " -msgstr "Preveo:\\line• Ivan Strugar \\line• Aleksandar Predić \\line• Miloš ljubičić " +msgstr "Preveo:\\line• Ivan Strugar \\line• Aleksandar Predić \\line• Miloš Ljubičić " #. • MSG_177 msgid "Report bugs or request enhancements at:" diff --git a/res/loc/rufus.loc b/res/loc/rufus.loc index 3a80d263..4133d811 100644 --- a/res/loc/rufus.loc +++ b/res/loc/rufus.loc @@ -11277,7 +11277,7 @@ t MSG_172 "Neispravan potpis preuzimanja" t MSG_173 "Kliknite za odabir..." t MSG_174 "Rufus - Pouzdan Alat Za Formatiranje USB diska" t MSG_175 "Verzija %d.%d (Izvršna verzija %d)" -t MSG_176 "Preveo:\\line• Ivan Strugar \\line• Aleksandar Predić \\line• Miloš ljubičić " +t MSG_176 "Preveo:\\line• Ivan Strugar \\line• Aleksandar Predić \\line• Miloš Ljubičić " t MSG_177 "Prijavite greške ili zahtjeve za poboljšanja na:" t MSG_178 "Dodatna autorska prava:" t MSG_179 "Polisa ažuriranja:" diff --git a/src/dev.c b/src/dev.c index c6ae6942..e3bd7c17 100644 --- a/src/dev.c +++ b/src/dev.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "rufus.h" @@ -43,7 +44,7 @@ #include "drive.h" #include "dev.h" -extern StrArray DriveID, DriveLabel, DriveHub; +extern StrArray DriveId, DriveName, DriveLabel, DriveHub; extern uint32_t DrivePort[MAX_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; BOOL r = FALSE; @@ -159,7 +160,7 @@ BOOL ResetDevice(int index) memset(&cycle_port, 0, size); cycle_port.ConnectionIndex = DrivePort[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 if (!DeviceIoControl(handle, IOCTL_USB_HUB_CYCLE_PORT, &cycle_port, size, &cycle_port, size, &size, NULL)) { uprintf(" Failed to cycle port: %s", WindowsErrorString()); @@ -173,6 +174,109 @@ out: 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) { int i; @@ -225,7 +329,7 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save) dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_CDROM, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (dev_info == INVALID_HANDLE_VALUE) { - uprintf("SetupDiGetClassDevs (Interface) failed: %s\n", WindowsErrorString()); + uprintf("SetupDiGetClassDevs (Interface) failed: %s", WindowsErrorString()); return FALSE; } dev_info_data.cbSize = sizeof(dev_info_data); @@ -233,7 +337,7 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save) memset(str, 0, sizeof(str)); if (!SetupDiGetDeviceRegistryPropertyU(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, &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"); } 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 (GetLastError() != ERROR_NO_MORE_ITEMS) { - uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString()); + uprintf("SetupDiEnumDeviceInterfaces failed: %s", WindowsErrorString()); } break; } @@ -255,21 +359,21 @@ BOOL GetOpticalMedia(IMG_SAVE* img_save) if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size); 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; } devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); } else { - uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s\n", WindowsErrorString()); + uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s", WindowsErrorString()); continue; } } if (devint_detail_data == NULL) { - uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated\n"); + uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated"); continue; } 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; } @@ -338,8 +442,8 @@ BOOL GetDevices(DWORD devnum) "SCSI", // "STORAGE", // "STORAGE" is used by 'Storage Spaces" and stuff => DANGEROUS! // Non-USB card reader drivers - This list *MUST* start with "SD" (delimiter) // See http://itdoc.hitachi.co.jp/manuals/3021/30213B5200e/DMDS0094.HTM - // Also http://www.carrona.org/dvrref.php. NB: These should be reported - // as enumerators by Rufus when Enum Debug is enabled + // Also http://www.carrona.org/dvrref.php. NB: All members from this list should have + // been reported as enumerators by Rufus, when Enum Debug is enabled. "SD", "PCISTOR", "RTSOR", "JMCR", "JMCF", "RIMMPTSK", "RIMSPTSK", "RISD", "RIXDPTSK", "TI21SONY", "ESD7SK", "ESM7SK", "O2MD", "O2SD", "VIACR" }; @@ -362,18 +466,19 @@ BOOL GetDevices(DWORD devnum) SP_DEVICE_INTERFACE_DATA devint_data; PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data; 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); ULONG list_size[ARRAYSIZE(usbstor_name)] = { 0 }, list_start[ARRAYSIZE(usbstor_name)] = { 0 }, full_list_size, ulFlags; HANDLE hDrive; LONG maxwidth = 0; int s, score, drive_number, remove_drive; 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; IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList)); - StrArrayClear(&DriveID); + StrArrayClear(&DriveId); + StrArrayClear(&DriveName); StrArrayClear(&DriveLabel); StrArrayClear(&DriveHub); 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 // 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 (htab_create(DEVID_HTAB_SIZE, &htab_devid)) { dev_info_data.cbSize = sizeof(dev_info_data); @@ -464,7 +569,7 @@ BOOL GetDevices(DWORD devnum) full_list_size += 1; // add extra NUL terminator devid_list = (char*)malloc(full_list_size); if (devid_list == NULL) { - uprintf("Could not allocate Device ID list\n"); + uprintf("Could not allocate Device ID list"); goto out; } for (s=0, i=0; s"); + } + memset(buffer, 0, sizeof(buffer)); 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)); if (!SetupDiGetDeviceRegistryPropertyU(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, - &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { - uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); + &data_type, (LPBYTE)buffer, sizeof(buffer), &size)) { + uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s", WindowsErrorString()); // We can afford a failure on this call - just replace the name with "USB Storage Device (Generic)" static_strcpy(buffer, lmprintf(MSG_045)); } else if ((!props.is_VHD) && (devid_list != NULL)) { @@ -668,7 +780,7 @@ BOOL GetDevices(DWORD devnum) } if (props.speed >= USB_SPEED_MAX) 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); if (props.is_LowerSpeed) 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(GetLastError() != ERROR_NO_MORE_ITEMS) { - uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString()); + uprintf("SetupDiEnumDeviceInterfaces failed: %s", WindowsErrorString()); } 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; } @@ -693,28 +805,28 @@ BOOL GetDevices(DWORD devnum) if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size); 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; } devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); } else { - uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s\n", WindowsErrorString()); + uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s", WindowsErrorString()); continue; } } if (devint_detail_data == NULL) { - uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated\n"); + uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated"); continue; } 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; } hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 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; } @@ -724,13 +836,13 @@ BOOL GetDevices(DWORD devnum) drive_index = drive_number + DRIVE_INDEX_MIN; 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_free(devint_detail_data); break; } 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_free(devint_detail_data); break; @@ -815,7 +927,8 @@ BOOL GetDevices(DWORD devnum) } // 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); if ((hub_path != NULL) && (StrArrayAdd(&DriveHub, hub_path, TRUE) >= 0)) DrivePort[DriveHub.Index - 1] = props.port; @@ -834,7 +947,7 @@ BOOL GetDevices(DWORD devnum) SendMessage(hDeviceList, CB_SETDROPPEDWIDTH, (WPARAM)maxwidth, 0); if (devnum >= DRIVE_INDEX_MIN) { - for (i=0; ilpVtbl->LoadService(This, pwszMachineName, ppService) #define IVdsServiceLoader_Release(This) (This)->lpVtbl->Release(This) #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 IVdsProvider_Release(This) (This)->lpVtbl->Release(This) #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); BOOL WaitForLogical(DWORD DriveIndex, DWORD PartitionIndex); 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); BOOL GetDriveLetters(DWORD DriveIndex, char* drive_letters); UINT GetDriveTypeFromIndex(DWORD DriveIndex); @@ -387,3 +392,8 @@ BOOL InitializeDisk(HANDLE hDrive); BOOL RefreshDriveLayout(HANDLE hDrive); const char* GetPartitionType(BYTE Type); 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); diff --git a/src/format.c b/src/format.c index bef0ee59..e067d2b1 100644 --- a/src/format.c +++ b/src/format.c @@ -793,10 +793,12 @@ const char* error_message(errcode_t error_code) case EXT2_ET_EA_INODE_CORRUPTED: return "Inode is corrupted"; 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); - else - static_sprintf(error_string, "Unknown ext2fs error 0x%08lX", error_code); + } else { + SetLastError((FormatStatus == 0) ? (ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | (error_code & 0xFFFF)) : FormatStatus); + static_sprintf(error_string, WindowsErrorString()); + } return error_string; } } @@ -826,13 +828,14 @@ const char* GetExtFsLabel(DWORD DriveIndex, DWORD PartitionIndex) char* volume_name = GetPartitionName(DriveIndex, PartitionIndex); 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); - if (r != 0) - return NULL; - strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN); - label[EXT2_LABEL_LEN] = 0; - ext2fs_close(ext2fs); - return label; + return (r == 0) ? label : NULL; } 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) { - BOOL r = FALSE; + BOOL r = FALSE, bFoundVolume = FALSE; HRESULT hr; ULONG ulFetched; IVdsServiceLoader *pLoader; @@ -1121,6 +1124,14 @@ static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD Cluster 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) { @@ -1241,6 +1252,7 @@ static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD Cluster if (!match) continue; + bFoundVolume = TRUE; if (strcmp(Label, FileSystemLabel[FS_UDF]) == 0) usFsVersion = ReadSetting32(SETTING_USE_UDF_VERSION); if (ClusterSize < 0x200) { @@ -1297,6 +1309,8 @@ static BOOL FormatDriveVds(DWORD DriveIndex, DWORD PartitionIndex, DWORD Cluster } out: + if ((!bFoundVolume) && (FormatStatus == 0)) + FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_PATH_NOT_FOUND; safe_free(VolumeName); safe_free(wVolumeName); safe_free(wLabel); @@ -2616,8 +2630,24 @@ DWORD WINAPI FormatThread(void* param) // VDS wants us to unlock the phys // TODO: IVdsDiskOnline::Offline? -> NOPE, NO_GO for removable media // TODO: IVdsService::Refresh()? IVdsHwProvider::Reenumerate()?? - if (use_vds) + if (use_vds) { 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 uprintf("Waiting for logical drive to reappear..."); diff --git a/src/iso.c b/src/iso.c index 5d2c9863..86a72d61 100644 --- a/src/iso.c +++ b/src/iso.c @@ -504,6 +504,7 @@ out: if (p_udf_dirent != NULL) udf_dirent_free(p_udf_dirent); ISO_BLOCKING(safe_closehandle(file_handle)); + safe_free(psz_sanpath); safe_free(psz_fullpath); return 1; } @@ -516,7 +517,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) EXTRACT_PROPS props; BOOL is_symlink, is_identical; 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)]; unsigned char buf[ISO_BLOCKSIZE]; CdioListNode_t* p_entnode; @@ -651,6 +652,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) out: ISO_BLOCKING(safe_closehandle(file_handle)); iso9660_filelist_free(p_entlist); + safe_free(psz_sanpath); return r; } diff --git a/src/rufus.c b/src/rufus.c index 4fe68cc4..080b6a02 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -119,7 +119,7 @@ char embedded_sl_version_ext[2][32]; char ClusterSizeLabel[MAX_CLUSTER_SIZES][64]; char msgbox[1024], msgbox_title[32], *ini_file = NULL, *image_path = NULL, *short_image_path; 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 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" }; @@ -857,14 +857,14 @@ static BOOL PopulateProperties(void) SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, use_fake_units)); // 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 (right_to_left_mode) - safe_sprintf(device_tooltip, safe_strlen(DriveID.String[device_index]) + 32, "(%s) %s", - SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE), DriveID.String[device_index]); + safe_sprintf(device_tooltip, safe_strlen(DriveName.String[device_index]) + 32, "(%s) %s", + SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE), DriveName.String[device_index]); else - safe_sprintf(device_tooltip, safe_strlen(DriveID.String[device_index]) + 32, "%s (%s)", - DriveID.String[device_index], SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE)); + safe_sprintf(device_tooltip, safe_strlen(DriveName.String[device_index]) + 32, "%s (%s)", + DriveName.String[device_index], SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE)); CreateTooltip(hDeviceList, device_tooltip, -1); free(device_tooltip); } @@ -1644,7 +1644,8 @@ static void InitDialog(HWND hDlg) IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0)); // Create the string arrays - StrArrayCreate(&DriveID, MAX_DRIVES); + StrArrayCreate(&DriveId, MAX_DRIVES); + StrArrayCreate(&DriveName, MAX_DRIVES); StrArrayCreate(&DriveLabel, MAX_DRIVES); StrArrayCreate(&DriveHub, MAX_DRIVES); StrArrayCreate(&BlockingProcess, 16); @@ -1982,7 +1983,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA if (ulRegister != 0) SHChangeNotifyDeregister(ulRegister); PostQuitMessage(0); - StrArrayDestroy(&DriveID); + StrArrayDestroy(&DriveId); + StrArrayDestroy(&DriveName); StrArrayDestroy(&DriveLabel); StrArrayDestroy(&DriveHub); StrArrayDestroy(&BlockingProcess); @@ -2765,7 +2767,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA int index = ComboBox_GetCurSel(hDeviceList); if (index >= 0) { 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))); @@ -3278,7 +3280,7 @@ relaunch: if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'C')) { int index = ComboBox_GetCurSel(hDeviceList); if (index >= 0) - ResetDevice(index); + CyclePort(index); continue; } // Alt-D => Delete the 'rufus_files' subdirectory diff --git a/src/rufus.h b/src/rufus.h index f084b813..7113645d 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -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 RunCommand(const char* cmdline, const char* dir, BOOL log); 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 LONG GetEntryWidth(HWND hDropDown, const char* entry); extern uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress); diff --git a/src/rufus.rc b/src/rufus.rc index ac1017c6..14985cdc 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.6.1535" +CAPTION "Rufus 3.6.1536" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -394,8 +394,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,6,1535,0 - PRODUCTVERSION 3,6,1535,0 + FILEVERSION 3,6,1536,0 + PRODUCTVERSION 3,6,1536,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -413,13 +413,13 @@ BEGIN VALUE "Comments", "https://akeo.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.6.1535" + VALUE "FileVersion", "3.6.1536" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2019 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus-3.6.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.6.1535" + VALUE "ProductVersion", "3.6.1536" END END BLOCK "VarFileInfo"