mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[core] add a cheat mode to reset the current USB device (cycle port)
* Will not work on Vista, Windows 7 or Server 2008 * Also update Windows version info
This commit is contained in:
parent
13ba3e75b3
commit
8286a0f63a
6 changed files with 103 additions and 30 deletions
60
src/dev.c
60
src/dev.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Rufus: The Reliable USB Formatting Utility
|
||||
* Device detection and enumeration
|
||||
* Copyright © 2014-2017 Pete Batard <pete@akeo.ie>
|
||||
* Copyright © 2014-2017 Pete Batard <pete@akeo.ie>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -42,7 +42,8 @@
|
|||
#include "drive.h"
|
||||
#include "dev.h"
|
||||
|
||||
extern StrArray DriveID, DriveLabel;
|
||||
extern StrArray DriveID, DriveLabel, DriveHub;
|
||||
extern uint32_t DrivePort[MAX_DRIVES];
|
||||
extern BOOL enable_HDDs, use_fake_units, enable_vmdk, usb_debug, list_non_usb_removable_drives;
|
||||
|
||||
/*
|
||||
|
@ -123,6 +124,51 @@ out:
|
|||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cycle port (reset) the selected device
|
||||
*/
|
||||
BOOL ResetDevice(int index)
|
||||
{
|
||||
static uint64_t LastReset = 0;
|
||||
BOOL r = FALSE;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
DWORD size;
|
||||
USB_CYCLE_PORT_PARAMS cycle_port;
|
||||
|
||||
// Wait at least 10 secs between resets
|
||||
if (_GetTickCount64() < LastReset + 10000ULL) {
|
||||
uprintf("You must wait at least 10 seconds before trying to reset a device");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (DriveHub.String[index] == NULL)
|
||||
return FALSE;
|
||||
|
||||
LastReset = _GetTickCount64();
|
||||
|
||||
handle = CreateFileA(DriveHub.String[index], GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
uprintf("Could not open %s: %s", DriveHub.String[index], WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(&cycle_port, 0, sizeof(cycle_port));
|
||||
size = sizeof(cycle_port);
|
||||
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
|
||||
// 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());
|
||||
goto out;
|
||||
}
|
||||
r = TRUE;
|
||||
|
||||
out:
|
||||
safe_closehandle(handle);
|
||||
return r;
|
||||
}
|
||||
|
||||
static __inline BOOL IsVHD(const char* buffer)
|
||||
{
|
||||
int i;
|
||||
|
@ -319,12 +365,13 @@ BOOL GetDevices(DWORD devnum)
|
|||
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;
|
||||
char *p, *label, *entry, buffer[MAX_PATH], str[MAX_PATH], *method_str, *hub_path;
|
||||
usb_device_props props;
|
||||
|
||||
IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList));
|
||||
StrArrayClear(&DriveID);
|
||||
StrArrayClear(&DriveLabel);
|
||||
StrArrayClear(&DriveHub);
|
||||
StrArrayCreate(&dev_if_path, 128);
|
||||
// Add a dummy for string index zero, as this is what non matching hashes will point to
|
||||
StrArrayAdd(&dev_if_path, "", TRUE);
|
||||
|
@ -452,6 +499,7 @@ BOOL GetDevices(DWORD devnum)
|
|||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(&props, 0, sizeof(props));
|
||||
method_str = "";
|
||||
hub_path = NULL;
|
||||
if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME,
|
||||
&datatype, (LPBYTE)buffer, sizeof(buffer), &size)) {
|
||||
uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString());
|
||||
|
@ -584,8 +632,10 @@ BOOL GetDevices(DWORD devnum)
|
|||
if ((uintptr_t)htab_devid.table[j].data > 0) {
|
||||
uuprintf(" Matched with Hub[%d]: '%s'", (uintptr_t)htab_devid.table[j].data,
|
||||
dev_if_path.String[(uintptr_t)htab_devid.table[j].data]);
|
||||
if (GetUSBProperties(dev_if_path.String[(uintptr_t)htab_devid.table[j].data], device_id, &props))
|
||||
if (GetUSBProperties(dev_if_path.String[(uintptr_t)htab_devid.table[j].data], device_id, &props)) {
|
||||
method_str = "";
|
||||
hub_path = dev_if_path.String[(uintptr_t)htab_devid.table[j].data];
|
||||
}
|
||||
#ifdef FORCED_DEVICE
|
||||
props.vid = FORCED_VID;
|
||||
props.pid = FORCED_PID;
|
||||
|
@ -769,6 +819,8 @@ BOOL GetDevices(DWORD devnum)
|
|||
// Must ensure that the combo box is UNSORTED for indexes to be the same
|
||||
StrArrayAdd(&DriveID, buffer, TRUE);
|
||||
StrArrayAdd(&DriveLabel, label, TRUE);
|
||||
if ((hub_path != NULL) && (StrArrayAdd(&DriveHub, hub_path, TRUE) >= 0))
|
||||
DrivePort[DriveHub.Index - 1] = props.port;
|
||||
|
||||
IGNORE_RETVAL(ComboBox_SetItemData(hDeviceList, ComboBox_AddStringU(hDeviceList, entry), drive_index));
|
||||
maxwidth = max(maxwidth, GetEntryWidth(hDeviceList, entry));
|
||||
|
|
10
src/dev.h
10
src/dev.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Rufus: The Reliable USB Formatting Utility
|
||||
* Device listing
|
||||
* Copyright © 2014-2016 Pete Batard <pete@akeo.ie>
|
||||
* Copyright © 2014-2016 Pete Batard <pete@akeo.ie>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -106,9 +106,12 @@ DECLSPEC_IMPORT CONFIGRET WINAPI CM_Get_Sibling(PDEVINST pdnDevInst, DEVINST dnD
|
|||
// 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));
|
||||
|
||||
#define USB_HUB_CYCLE_PORT 273
|
||||
#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
|
||||
#define USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 279
|
||||
|
||||
#define IOCTL_USB_HUB_CYCLE_PORT \
|
||||
CTL_CODE(FILE_DEVICE_USB, USB_HUB_CYCLE_PORT, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
|
||||
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \
|
||||
|
@ -172,6 +175,11 @@ typedef struct _USB_NODE_CONNECTION_INFORMATION_EX_V2 {
|
|||
USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
|
||||
} USB_NODE_CONNECTION_INFORMATION_EX_V2, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2;
|
||||
|
||||
typedef struct {
|
||||
ULONG ConnectionIndex;
|
||||
ULONG StatusReturned;
|
||||
} USB_CYCLE_PORT_PARAMS;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
const GUID _GUID_DEVINTERFACE_DISK =
|
||||
|
|
30
src/rufus.c
30
src/rufus.c
|
@ -114,7 +114,8 @@ uint16_t rufus_version[3], embedded_sl_version[2];
|
|||
char embedded_sl_version_str[2][12] = { "?.??", "?.??" };
|
||||
char embedded_sl_version_ext[2][32];
|
||||
RUFUS_UPDATE update = { {0,0,0}, {0,0}, NULL, NULL};
|
||||
StrArray DriveID, DriveLabel, BlockingProcess;
|
||||
StrArray DriveID, DriveLabel, DriveHub, BlockingProcess;
|
||||
uint32_t DrivePort[MAX_DRIVES];
|
||||
extern char* szStatusMessage;
|
||||
|
||||
static HANDLE format_thid = NULL, dialog_handle = NULL;
|
||||
|
@ -1828,9 +1829,10 @@ static void InitDialog(HWND hDlg)
|
|||
}
|
||||
IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0));
|
||||
|
||||
// Create the string array
|
||||
// Create the string arrays
|
||||
StrArrayCreate(&DriveID, MAX_DRIVES);
|
||||
StrArrayCreate(&DriveLabel, MAX_DRIVES);
|
||||
StrArrayCreate(&DriveHub, MAX_DRIVES);
|
||||
StrArrayCreate(&BlockingProcess, 16);
|
||||
// Set various checkboxes
|
||||
CheckDlgButton(hDlg, IDC_QUICKFORMAT, BST_CHECKED);
|
||||
|
@ -2351,6 +2353,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
|||
PostQuitMessage(0);
|
||||
StrArrayDestroy(&DriveID);
|
||||
StrArrayDestroy(&DriveLabel);
|
||||
StrArrayDestroy(&DriveHub);
|
||||
StrArrayDestroy(&BlockingProcess);
|
||||
DestroyAllTooltips();
|
||||
DestroyWindow(hLogDlg);
|
||||
|
@ -3351,7 +3354,7 @@ relaunch:
|
|||
|
||||
// Do our own event processing and process "magic" commands
|
||||
while(GetMessage(&msg, NULL, 0, 0)) {
|
||||
// ** ***** **** ** ******** *
|
||||
// ** ***** **** ** **********
|
||||
// .,ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
|
||||
// Ctrl-A => Select the log data
|
||||
|
@ -3359,6 +3362,7 @@ relaunch:
|
|||
(msg.message == WM_KEYDOWN) && (msg.wParam == 'A') ) {
|
||||
// Might also need ES_NOHIDESEL property if you want to select when not active
|
||||
Edit_SetSel(hLog, 0, -1);
|
||||
continue;
|
||||
}
|
||||
// Alt-. => Enable USB enumeration debug
|
||||
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == VK_OEM_PERIOD)) {
|
||||
|
@ -3385,12 +3389,12 @@ relaunch:
|
|||
PrintStatusTimeout(lmprintf(MSG_256), detect_fakes);
|
||||
continue;
|
||||
}
|
||||
// Alt C => Force the update check to be successful
|
||||
// This will set the reported current version of Rufus to 0.0.0.0 when performing an update
|
||||
// check, so that it always succeeds. This is useful for translators.
|
||||
// Alt-C => Cycle USB port for currently selected device
|
||||
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'C')) {
|
||||
force_update = !force_update;
|
||||
PrintStatusTimeout(lmprintf(MSG_259), force_update);
|
||||
int index = ComboBox_GetCurSel(hDeviceList);
|
||||
if (index < 0)
|
||||
break;
|
||||
ResetDevice(index);
|
||||
continue;
|
||||
}
|
||||
// Alt-D => Delete the NoDriveTypeAutorun key on exit (useful if the app crashed)
|
||||
|
@ -3473,7 +3477,6 @@ relaunch:
|
|||
PrintStatusTimeout(lmprintf(MSG_290), !disable_file_indexing);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Alt-R => Remove all the registry keys that may have been created by Rufus
|
||||
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'R')) {
|
||||
PrintStatus(2000, DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME "\\" APPLICATION_NAME)?MSG_248:MSG_249);
|
||||
|
@ -3525,11 +3528,20 @@ relaunch:
|
|||
SHDeleteDirectoryExU(NULL, tmp_path, FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION);
|
||||
continue;
|
||||
}
|
||||
// Alt Y => Force the update check to be successful
|
||||
// This will set the reported current version of Rufus to 0.0.0.0 when performing an update
|
||||
// check, so that it always succeeds. This is useful for translators.
|
||||
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'Y')) {
|
||||
force_update = !force_update;
|
||||
PrintStatusTimeout(lmprintf(MSG_259), force_update);
|
||||
continue;
|
||||
}
|
||||
// Alt-Z => Zero the drive
|
||||
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'Z')) {
|
||||
zero_drive = TRUE;
|
||||
// Simulate a button click for Start
|
||||
PostMessage(hDlg, WM_COMMAND, (WPARAM)IDC_START, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hazardous cheat modes require Ctrl + Alt
|
||||
|
|
11
src/rufus.h
11
src/rufus.h
|
@ -369,11 +369,11 @@ enum WindowsVersion {
|
|||
WINDOWS_UNDEFINED = -1,
|
||||
WINDOWS_UNSUPPORTED = 0,
|
||||
WINDOWS_XP = 0x51,
|
||||
WINDOWS_2003 = 0x52, // Also XP x64
|
||||
WINDOWS_VISTA = 0x60,
|
||||
WINDOWS_7 = 0x61,
|
||||
WINDOWS_8 = 0x62,
|
||||
WINDOWS_8_1 = 0x63,
|
||||
WINDOWS_2003 = 0x52, // Also XP_64
|
||||
WINDOWS_VISTA = 0x60, // Also 2008
|
||||
WINDOWS_7 = 0x61, // Also 2008_R2
|
||||
WINDOWS_8 = 0x62, // Also 2012
|
||||
WINDOWS_8_1 = 0x63, // Also 2012_R2
|
||||
WINDOWS_10_PREVIEW1 = 0x64,
|
||||
WINDOWS_10 = 0xA0,
|
||||
WINDOWS_MAX
|
||||
|
@ -460,6 +460,7 @@ extern DWORD GetResourceSize(HMODULE module, char* name, char* type, const char*
|
|||
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);
|
||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
|||
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_ACCEPTFILES
|
||||
CAPTION "Rufus 2.18.1200"
|
||||
CAPTION "Rufus 2.18.1201"
|
||||
FONT 8, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
|
||||
|
@ -366,8 +366,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,18,1200,0
|
||||
PRODUCTVERSION 2,18,1200,0
|
||||
FILEVERSION 2,18,1201,0
|
||||
PRODUCTVERSION 2,18,1201,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -384,13 +384,13 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "2.18.1200"
|
||||
VALUE "FileVersion", "2.18.1201"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||
VALUE "OriginalFilename", "rufus.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "2.18.1200"
|
||||
VALUE "ProductVersion", "2.18.1201"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
12
src/stdfn.c
12
src/stdfn.c
|
@ -284,20 +284,20 @@ void GetWindowsVersion(void)
|
|||
switch (nWindowsVersion) {
|
||||
case 0x51: w = "XP";
|
||||
break;
|
||||
case 0x52: w = (!GetSystemMetrics(89)?"2003":"2003_R2");
|
||||
case 0x52: w = (!GetSystemMetrics(89)?"Server 2003":"Server 2003_R2");
|
||||
break;
|
||||
case 0x60: w = (ws?"Vista":"2008");
|
||||
case 0x60: w = (ws?"Vista":"Server 2008");
|
||||
break;
|
||||
case 0x61: w = (ws?"7":"2008_R2");
|
||||
case 0x61: w = (ws?"7":"Server 2008_R2");
|
||||
break;
|
||||
case 0x62: w = (ws?"8":"2012");
|
||||
case 0x62: w = (ws?"8":"Server 2012");
|
||||
break;
|
||||
case 0x63: w = (ws?"8.1":"2012_R2");
|
||||
case 0x63: w = (ws?"8.1":"Server 2012_R2");
|
||||
break;
|
||||
case 0x64: w = (ws?"10 (Preview 1)":"Server 10 (Preview 1)");
|
||||
break;
|
||||
// Starting with Windows 10 Preview 2, the major is the same as the public-facing version
|
||||
case 0xA0: w = (ws?"10":"Server 10");
|
||||
case 0xA0: w = (ws?"10":"Server 2016");
|
||||
break;
|
||||
default:
|
||||
if (nWindowsVersion < 0x51)
|
||||
|
|
Loading…
Reference in a new issue