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:
		
							parent
							
								
									bf59239c39
								
							
						
					
					
						commit
						8b18d8ce1d
					
				
					 11 changed files with 336 additions and 72 deletions
				
			
		|  | @ -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:" | ||||||
|  |  | ||||||
|  | @ -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
									
										
									
									
									
								
							
							
						
						
									
										189
									
								
								src/dev.c
									
										
									
									
									
								
							|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -103,6 +103,7 @@ DECLSPEC_IMPORT CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINST | ||||||
| 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)); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										109
									
								
								src/drive.c
									
										
									
									
									
								
							
							
						
						
									
										109
									
								
								src/drive.c
									
										
									
									
									
								
							|  | @ -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 | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/drive.h
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/drive.h
									
										
									
									
									
								
							|  | @ -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); | ||||||
|  |  | ||||||
							
								
								
									
										48
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										48
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -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); | ||||||
| 	free(volume_name); | 	if (r == 0) { | ||||||
| 	if (r != 0) |  | ||||||
| 		return NULL; |  | ||||||
| 		strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN); | 		strncpy(label, ext2fs->super->s_volume_name, EXT2_LABEL_LEN); | ||||||
| 		label[EXT2_LABEL_LEN] = 0; | 		label[EXT2_LABEL_LEN] = 0; | ||||||
|  | 	} | ||||||
|  | 	if (ext2fs != NULL) | ||||||
| 		ext2fs_close(ext2fs); | 		ext2fs_close(ext2fs); | ||||||
| 	return label; | 	free(volume_name); | ||||||
|  | 	return (r == 0) ? label : NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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..."); | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -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
 | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -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" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue