2011-11-13 20:53:23 +00:00
|
|
|
/*
|
2011-12-05 11:36:02 +00:00
|
|
|
* Rufus: The Reliable USB Formatting Utility
|
2022-06-20 12:47:43 +00:00
|
|
|
* Copyright © 2011-2022 Pete Batard <pete@akeo.ie>
|
2013-12-27 16:06:59 +00:00
|
|
|
*
|
2011-11-13 20:53:23 +00:00
|
|
|
* 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
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2011-11-21 20:12:23 +00:00
|
|
|
/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
|
|
|
|
#ifdef _CRTDBG_MAP_ALLOC
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <crtdbg.h>
|
|
|
|
#endif
|
|
|
|
|
2011-11-13 20:53:23 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <windowsx.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2011-11-24 02:24:50 +00:00
|
|
|
#include <math.h>
|
2011-11-20 02:34:15 +00:00
|
|
|
#include <winioctl.h>
|
2013-12-20 18:32:10 +00:00
|
|
|
#include <shlobj.h>
|
2011-11-27 23:40:28 +00:00
|
|
|
#include <process.h>
|
2018-05-09 14:55:30 +00:00
|
|
|
#include <dwmapi.h>
|
2011-11-26 00:25:04 +00:00
|
|
|
#include <dbt.h>
|
2013-02-04 01:14:28 +00:00
|
|
|
#include <io.h>
|
|
|
|
#include <getopt.h>
|
2018-06-30 21:45:15 +00:00
|
|
|
#include <assert.h>
|
2021-12-12 00:57:26 +00:00
|
|
|
#include <delayimp.h>
|
2011-11-20 22:49:55 +00:00
|
|
|
|
2011-11-19 19:08:23 +00:00
|
|
|
#include "rufus.h"
|
2022-07-25 12:18:14 +00:00
|
|
|
#include "format.h"
|
2016-02-20 22:52:32 +00:00
|
|
|
#include "missing.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#include "msapi_utf8.h"
|
|
|
|
#include "localization.h"
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
#include "ui.h"
|
[ui] add forced DD mode exceptions for Red Hat based distros
* Anaconda broke ISO compatibility, most likely with the following commit:
https://github.com/rhinstaller/anaconda/commit/84529204fe02300b9829da41099a8254dc2a1c54
* However, Ret Hat, and its followers, have drunk the "DD only" kool aid, and
appear to be blissfully unaware of the very real drawbacks that enforcing a
"DD only" mode for ISOHybrid can actually place on distro users.
* Rather than spend another wasted effort trying get people, who appear to be
impervious to even remotely consider the idea that DD imaging can have flaws,
to look into the possibility that Red Hat might indeed have introduced a
regression, and given the downright hostility I have been subjected to from
trying to state this *very verifiable* fact, we'll just force DD mode for the
affected Red Hat and derivatives, whilst trusting that users will be smart
enough to compare their more limited installation experience against the ones
from other distros (such as Arch, Debian or Ubuntu, which, unlike Red Hat and
co., appear to fully understand that the whole ISOHybrid vs DD mode situation
is not all black and white), and see for themselves which distros do actually
place *their* interests first, rather than just the interests of the distro
maintainers...
2021-04-23 16:04:55 +00:00
|
|
|
#include "re.h"
|
2022-08-02 19:14:29 +00:00
|
|
|
#include "vhd.h"
|
2022-07-25 12:18:14 +00:00
|
|
|
#include "wue.h"
|
2014-01-05 01:39:41 +00:00
|
|
|
#include "drive.h"
|
2015-01-25 00:56:38 +00:00
|
|
|
#include "settings.h"
|
2014-12-29 20:34:41 +00:00
|
|
|
#include "bled/bled.h"
|
2020-05-12 13:13:44 +00:00
|
|
|
#include "cdio/logging.h"
|
2014-12-30 19:46:13 +00:00
|
|
|
#include "../res/grub/grub_version.h"
|
|
|
|
#include "../res/grub2/grub2_version.h"
|
2011-11-13 20:53:23 +00:00
|
|
|
|
2020-02-03 12:35:49 +00:00
|
|
|
enum bootcheck_return {
|
|
|
|
BOOTCHECK_PROCEED = 0,
|
|
|
|
BOOTCHECK_CANCEL = -1,
|
|
|
|
BOOTCHECK_DOWNLOAD_ERROR = -2,
|
|
|
|
BOOTCHECK_GENERAL_ERROR = -3,
|
|
|
|
};
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
static const char* cmdline_hogger = "rufus.com";
|
|
|
|
static const char* ep_reg = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
|
|
|
|
static const char* vs_reg = "Software\\Microsoft\\VisualStudio";
|
2022-06-23 12:34:24 +00:00
|
|
|
static const char* arch_name[ARCH_MAX] = {
|
|
|
|
"unknown", "x86_32", "x86_64", "ARM", "ARM64", "Itanic", "RISC-V 32", "RISC-V 64", "RISC-V 128", "EBC" };
|
2012-02-07 16:17:14 +00:00
|
|
|
static BOOL existing_key = FALSE; // For LGP set/restore
|
2013-07-05 22:58:04 +00:00
|
|
|
static BOOL size_check = TRUE;
|
2012-05-30 23:32:25 +00:00
|
|
|
static BOOL log_displayed = FALSE;
|
2020-07-19 21:35:30 +00:00
|
|
|
static BOOL img_provided = FALSE;
|
2013-12-28 01:27:09 +00:00
|
|
|
static BOOL user_notified = FALSE;
|
2013-10-24 21:57:34 +00:00
|
|
|
static BOOL relaunch = FALSE;
|
2015-08-14 22:09:45 +00:00
|
|
|
static BOOL dont_display_image_name = FALSE;
|
2022-11-16 16:50:53 +00:00
|
|
|
static BOOL dont_process_dbt_devnodes = FALSE;
|
2016-01-09 05:06:45 +00:00
|
|
|
static BOOL user_changed_label = FALSE;
|
2021-09-19 20:01:45 +00:00
|
|
|
static BOOL user_deleted_rufus_dir = FALSE;
|
2016-01-09 05:06:45 +00:00
|
|
|
static BOOL app_changed_label = FALSE;
|
2018-03-22 23:14:20 +00:00
|
|
|
static BOOL allowed_filesystem[FS_MAX] = { 0 };
|
|
|
|
static int64_t last_iso_blocking_status;
|
2018-10-23 19:10:52 +00:00
|
|
|
static int selected_pt = -1, selected_fs = FS_UNKNOWN, preselected_fs = FS_UNKNOWN;
|
2022-07-25 12:18:14 +00:00
|
|
|
static int image_index = 0, select_index = 0;
|
2018-03-22 23:14:20 +00:00
|
|
|
static RECT relaunch_rc = { -65536, -65536, 0, 0};
|
2019-08-24 22:45:53 +00:00
|
|
|
static UINT uMBRChecked = BST_UNCHECKED;
|
2020-07-10 10:55:29 +00:00
|
|
|
static HANDLE format_thread = NULL;
|
2018-03-22 23:14:20 +00:00
|
|
|
static HWND hSelectImage = NULL, hStart = NULL;
|
|
|
|
static char szTimer[12] = "00:00:00";
|
|
|
|
static unsigned int timer;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
static char uppercase_select[2][64], uppercase_start[64], uppercase_close[64], uppercase_cancel[64];
|
2018-03-22 23:14:20 +00:00
|
|
|
|
2021-10-08 18:22:33 +00:00
|
|
|
extern HANDLE update_check_thread, wim_thread;
|
2020-06-25 10:58:56 +00:00
|
|
|
extern BOOL enable_iso, enable_joliet, enable_rockridge, enable_extra_hashes;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
extern BYTE* fido_script;
|
2019-03-07 16:29:43 +00:00
|
|
|
extern HWND hFidoDlg;
|
2014-12-30 19:46:13 +00:00
|
|
|
extern uint8_t* grub2_buf;
|
|
|
|
extern long grub2_len;
|
2018-03-22 23:14:20 +00:00
|
|
|
extern char* szStatusMessage;
|
2014-02-04 20:01:28 +00:00
|
|
|
extern const char* old_c32_name[NB_OLD_C32];
|
2017-04-12 19:40:43 +00:00
|
|
|
extern const char* cert_name[3];
|
2019-04-25 17:58:55 +00:00
|
|
|
extern const char* FileSystemLabel[FS_MAX];
|
2011-12-01 02:56:44 +00:00
|
|
|
|
2011-11-13 20:53:23 +00:00
|
|
|
/*
|
|
|
|
* Globals
|
|
|
|
*/
|
2014-05-12 21:44:10 +00:00
|
|
|
OPENED_LIBRARIES_VARS;
|
2018-07-05 23:40:52 +00:00
|
|
|
RUFUS_UPDATE update = { { 0,0,0 },{ 0,0 }, NULL, NULL };
|
2011-11-21 17:06:17 +00:00
|
|
|
HINSTANCE hMainInstance;
|
2018-05-01 17:07:07 +00:00
|
|
|
HWND hMainDialog, hMultiToolbar, hSaveToolbar, hHashToolbar, hAdvancedDeviceToolbar, hAdvancedFormatToolbar, hUpdatesDlg = NULL;
|
2018-07-06 04:46:36 +00:00
|
|
|
HFONT hInfoFont;
|
2018-07-18 11:22:37 +00:00
|
|
|
uint8_t image_options = IMOP_WINTOGO;
|
2018-07-05 23:40:52 +00:00
|
|
|
uint16_t rufus_version[3], embedded_sl_version[2];
|
2022-05-25 12:21:36 +00:00
|
|
|
uint32_t dur_mins, dur_secs;
|
2016-01-11 13:06:33 +00:00
|
|
|
loc_cmd* selected_locale = NULL;
|
2015-10-18 20:31:47 +00:00
|
|
|
WORD selected_langid = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
|
2016-05-30 16:32:49 +00:00
|
|
|
DWORD MainThreadId;
|
2018-03-22 23:14:20 +00:00
|
|
|
HWND hDeviceList, hPartitionScheme, hTargetSystem, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog = NULL;
|
2020-07-17 20:51:15 +00:00
|
|
|
HWND hImageOption, hLogDialog = NULL, hProgress = NULL, hDiskID;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
HANDLE dialog_handle = NULL;
|
2022-07-08 17:48:02 +00:00
|
|
|
BOOL is_x86_32, use_own_c32[NB_OLD_C32] = { FALSE, FALSE }, mbr_selected_by_user = FALSE, lock_drive = TRUE;
|
|
|
|
BOOL op_in_progress = TRUE, right_to_left_mode = FALSE, has_uefi_csm = FALSE, its_a_me_mario = FALSE;
|
|
|
|
BOOL enable_HDDs = FALSE, enable_VHDs = TRUE, enable_ntfs_compression = FALSE, no_confirmation_on_cancel = FALSE;
|
|
|
|
BOOL advanced_mode_device, advanced_mode_format, allow_dual_uefi_bios, detect_fakes, enable_vmdk, force_large_fat32;
|
|
|
|
BOOL usb_debug, use_fake_units, preserve_timestamps = FALSE, fast_zeroing = FALSE, app_changed_size = FALSE;
|
2018-11-20 12:28:20 +00:00
|
|
|
BOOL zero_drive = FALSE, list_non_usb_removable_drives = FALSE, enable_file_indexing, large_drive = FALSE;
|
2021-10-23 01:49:15 +00:00
|
|
|
BOOL write_as_image = FALSE, write_as_esp = FALSE, use_vds = FALSE, ignore_boot_marker = FALSE;
|
2022-07-08 17:48:02 +00:00
|
|
|
BOOL appstore_version = FALSE, is_vds_available = TRUE;
|
2018-07-05 23:40:52 +00:00
|
|
|
float fScale = 1.0f;
|
2021-10-08 18:22:33 +00:00
|
|
|
int dialog_showing = 0, selection_default = BT_IMAGE, persistence_unit_selection = -1, imop_win_sel = 0;
|
2022-07-25 12:18:14 +00:00
|
|
|
int default_fs, fs_type, boot_type, partition_type, target_type;
|
2020-07-10 10:55:29 +00:00
|
|
|
int force_update = 0, default_thread_priority = THREAD_PRIORITY_ABOVE_NORMAL;
|
2018-07-05 23:40:52 +00:00
|
|
|
char szFolderPath[MAX_PATH], app_dir[MAX_PATH], system_dir[MAX_PATH], temp_dir[MAX_PATH], sysnative_dir[MAX_PATH];
|
2021-07-28 15:37:45 +00:00
|
|
|
char app_data_dir[MAX_PATH], user_dir[MAX_PATH];
|
2014-01-24 19:59:23 +00:00
|
|
|
char embedded_sl_version_str[2][12] = { "?.??", "?.??" };
|
2014-08-05 23:57:32 +00:00
|
|
|
char embedded_sl_version_ext[2][32];
|
2018-03-22 23:14:20 +00:00
|
|
|
char ClusterSizeLabel[MAX_CLUSTER_SIZES][64];
|
2018-07-05 23:40:52 +00:00
|
|
|
char msgbox[1024], msgbox_title[32], *ini_file = NULL, *image_path = NULL, *short_image_path;
|
2022-07-25 12:18:14 +00:00
|
|
|
char *archive_path = NULL, image_option_txt[128], *fido_url = NULL;
|
2022-05-25 12:21:36 +00:00
|
|
|
StrArray BlockingProcess, ImageList;
|
2018-07-06 04:46:36 +00:00
|
|
|
// Number of steps for each FS for FCC_STRUCTURE_PROGRESS
|
2019-04-25 17:58:55 +00:00
|
|
|
const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10, 1, 1, 1, 1 };
|
2018-07-06 04:46:36 +00:00
|
|
|
const char* flash_type[BADLOCKS_PATTERN_TYPES] = { "SLC", "MLC", "TLC" };
|
2022-05-25 12:21:36 +00:00
|
|
|
RUFUS_DRIVE rufus_drive[MAX_DRIVES] = { 0 };
|
2011-12-09 01:39:13 +00:00
|
|
|
|
2015-01-12 00:53:09 +00:00
|
|
|
// TODO: Remember to update copyright year in stdlg's AboutCallback() WM_INITDIALOG,
|
|
|
|
// localization_data.sh and the .rc when the year changes!
|
2011-11-18 21:46:34 +00:00
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Fill in the cluster size names
|
2013-10-15 21:58:27 +00:00
|
|
|
static void SetClusterSizeLabels(void)
|
|
|
|
{
|
2018-03-22 23:14:20 +00:00
|
|
|
unsigned int i, j, msg_id;
|
2020-02-23 16:29:16 +00:00
|
|
|
safe_sprintf(ClusterSizeLabel[0], 64, "%s", lmprintf(MSG_029));
|
2018-03-22 23:14:20 +00:00
|
|
|
for (i=512, j=1, msg_id=MSG_026; j<MAX_CLUSTER_SIZES; i<<=1, j++) {
|
2013-10-15 21:58:27 +00:00
|
|
|
if (i > 8192) {
|
|
|
|
i /= 1024;
|
2018-03-22 23:14:20 +00:00
|
|
|
msg_id++;
|
|
|
|
}
|
|
|
|
safe_sprintf(ClusterSizeLabel[j], 64, "%d %s", i, lmprintf(msg_id));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SetAllowedFileSystems(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
memset(allowed_filesystem, 0, sizeof(allowed_filesystem));
|
|
|
|
// Nothing is allowed if we don't have a drive
|
|
|
|
if (ComboBox_GetCurSel(hDeviceList) < 0)
|
|
|
|
return;
|
|
|
|
switch (selection_default) {
|
|
|
|
case BT_NON_BOOTABLE:
|
|
|
|
for (i = 0; i < FS_MAX; i++)
|
|
|
|
allowed_filesystem[i] = TRUE;
|
|
|
|
break;
|
|
|
|
case BT_MSDOS:
|
|
|
|
case BT_FREEDOS:
|
|
|
|
allowed_filesystem[FS_FAT16] = TRUE;
|
|
|
|
allowed_filesystem[FS_FAT32] = TRUE;
|
|
|
|
break;
|
|
|
|
case BT_IMAGE:
|
2018-09-07 13:11:25 +00:00
|
|
|
allowed_filesystem[FS_NTFS] = TRUE;
|
|
|
|
// Don't allow anything besides NTFS if the image has a >4GB file
|
|
|
|
if ((image_path != NULL) && (img_report.has_4GB_file))
|
|
|
|
break;
|
2019-04-13 14:29:27 +00:00
|
|
|
if (!HAS_WINDOWS(img_report) || (target_type != TT_BIOS) || allow_dual_uefi_bios) {
|
2021-10-08 18:22:33 +00:00
|
|
|
if (!HAS_WINTOGO(img_report) || (ComboBox_GetCurItemData(hImageOption) != IMOP_WIN_TO_GO)) {
|
2018-03-22 23:14:20 +00:00
|
|
|
allowed_filesystem[FS_FAT16] = TRUE;
|
|
|
|
allowed_filesystem[FS_FAT32] = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2021-07-27 17:10:29 +00:00
|
|
|
case BT_GRUB2:
|
|
|
|
allowed_filesystem[FS_EXT2] = TRUE;
|
|
|
|
allowed_filesystem[FS_EXT3] = TRUE;
|
|
|
|
allowed_filesystem[FS_EXT4] = TRUE;
|
|
|
|
// Fall through
|
2018-03-22 23:14:20 +00:00
|
|
|
case BT_SYSLINUX_V6:
|
2019-04-18 11:53:12 +00:00
|
|
|
case BT_GRUB4DOS:
|
2018-03-22 23:14:20 +00:00
|
|
|
allowed_filesystem[FS_NTFS] = TRUE;
|
|
|
|
// Fall through
|
|
|
|
case BT_SYSLINUX_V4:
|
|
|
|
case BT_REACTOS:
|
|
|
|
allowed_filesystem[FS_FAT16] = TRUE;
|
|
|
|
allowed_filesystem[FS_FAT32] = TRUE;
|
|
|
|
break;
|
|
|
|
case BT_UEFI_NTFS:
|
|
|
|
allowed_filesystem[FS_NTFS] = TRUE;
|
2020-01-30 13:51:19 +00:00
|
|
|
allowed_filesystem[FS_EXFAT] = TRUE;
|
2018-03-22 23:14:20 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset disk ID to 0x80 if Rufus MBR is used
|
|
|
|
if (selection_default != BT_IMAGE) {
|
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Populate the Boot selection dropdown
|
|
|
|
static void SetBootOptions(void)
|
|
|
|
{
|
|
|
|
char tmp[32];
|
|
|
|
|
|
|
|
IGNORE_RETVAL(ComboBox_ResetContent(hBootType));
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, lmprintf(MSG_279)), BT_NON_BOOTABLE));
|
|
|
|
if (nWindowsVersion < WINDOWS_10) // The diskcopy.dll along with its MS-DOS floppy image was removed in Windows 10
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), BT_MSDOS));
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), BT_FREEDOS));
|
|
|
|
image_index = (nWindowsVersion < WINDOWS_10) ? 3 : 2;
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType,
|
|
|
|
(image_path == NULL) ? lmprintf(MSG_281, lmprintf(MSG_280)) : short_image_path), BT_IMAGE));
|
|
|
|
|
|
|
|
if (advanced_mode_device) {
|
|
|
|
static_sprintf(tmp, "Syslinux %s", embedded_sl_version_str[0]);
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, tmp), BT_SYSLINUX_V4));
|
|
|
|
static_sprintf(tmp, "Syslinux %s", embedded_sl_version_str[1]);
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, tmp), BT_SYSLINUX_V6));
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "ReactOS"), BT_REACTOS));
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType,
|
|
|
|
"Grub " GRUB2_PACKAGE_VERSION), BT_GRUB2));
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType,
|
|
|
|
"Grub4DOS " GRUB4DOS_VERSION), BT_GRUB4DOS));
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "UEFI:NTFS"), BT_UEFI_NTFS));
|
|
|
|
}
|
|
|
|
if ((!advanced_mode_device) && (selection_default >= BT_SYSLINUX_V4)) {
|
|
|
|
selection_default = BT_IMAGE;
|
|
|
|
CheckDlgButton(hMainDialog, IDC_DISK_ID, BST_UNCHECKED);
|
|
|
|
}
|
|
|
|
SetComboEntry(hBootType, selection_default);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SetPartitionSchemeAndTargetSystem(BOOL only_target)
|
|
|
|
{
|
|
|
|
// MBR, GPT, SFD
|
|
|
|
BOOL allowed_partition_scheme[3] = { TRUE, TRUE, FALSE };
|
|
|
|
// BIOS, UEFI, DUAL
|
|
|
|
BOOL allowed_target_system[3] = { TRUE, TRUE, FALSE };
|
|
|
|
BOOL is_windows_to_go_selected;
|
|
|
|
|
|
|
|
if (!only_target)
|
|
|
|
IGNORE_RETVAL(ComboBox_ResetContent(hPartitionScheme));
|
|
|
|
IGNORE_RETVAL(ComboBox_ResetContent(hTargetSystem));
|
|
|
|
|
2020-07-17 20:51:15 +00:00
|
|
|
boot_type = (int)ComboBox_GetCurItemData(hBootType);
|
2019-04-13 14:29:27 +00:00
|
|
|
is_windows_to_go_selected = (boot_type == BT_IMAGE) && (image_path != NULL) && HAS_WINTOGO(img_report) &&
|
2021-10-08 18:22:33 +00:00
|
|
|
(ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO);
|
2018-03-22 23:14:20 +00:00
|
|
|
// If no device is selected, don't populate anything
|
|
|
|
if (ComboBox_GetCurSel(hDeviceList) < 0)
|
|
|
|
return;
|
2019-04-13 14:29:27 +00:00
|
|
|
switch (boot_type) {
|
2018-03-22 23:14:20 +00:00
|
|
|
case BT_NON_BOOTABLE:
|
|
|
|
allowed_partition_scheme[PARTITION_STYLE_SFD] = TRUE;
|
|
|
|
allowed_target_system[0] = FALSE;
|
|
|
|
allowed_target_system[1] = FALSE;
|
|
|
|
allowed_target_system[2] = TRUE;
|
|
|
|
break;
|
|
|
|
case BT_IMAGE:
|
|
|
|
if (image_path == NULL)
|
|
|
|
break;
|
|
|
|
// Check if image is EFI bootable
|
|
|
|
if (!IS_EFI_BOOTABLE(img_report)) {
|
|
|
|
allowed_partition_scheme[PARTITION_STYLE_GPT] = FALSE;
|
|
|
|
allowed_target_system[1] = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Image is EFI bootable => set dual BIOS + UEFI and so on...
|
|
|
|
if (IS_BIOS_BOOTABLE(img_report)) {
|
|
|
|
if (!HAS_WINDOWS(img_report) || allow_dual_uefi_bios || is_windows_to_go_selected) {
|
|
|
|
allowed_target_system[0] = FALSE;
|
|
|
|
allowed_target_system[1] = TRUE;
|
|
|
|
allowed_target_system[2] = TRUE;
|
|
|
|
}
|
2020-09-15 20:02:08 +00:00
|
|
|
// Syslinux 4.x or earlier has no support for NTFS so if an image is using Syslinux 4.x only
|
|
|
|
// and has a 4 GB file (which forces us to use NTFS) then disable MBR altogether as we won't
|
|
|
|
// be able to make a working MBR install of Syslinux.
|
|
|
|
if (HAS_SYSLINUX(img_report) && (SL_MAJOR(img_report.sl_version) < 5) && img_report.has_4GB_file &&
|
|
|
|
!HAS_BOOTMGR(img_report) && !HAS_WINPE(img_report) && !HAS_GRUB(img_report))
|
|
|
|
allowed_partition_scheme[PARTITION_STYLE_MBR] = FALSE;
|
2018-03-22 23:14:20 +00:00
|
|
|
} else {
|
|
|
|
allowed_target_system[0] = FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case BT_MSDOS:
|
|
|
|
case BT_FREEDOS:
|
|
|
|
case BT_SYSLINUX_V4:
|
|
|
|
case BT_SYSLINUX_V6:
|
|
|
|
case BT_REACTOS:
|
|
|
|
case BT_GRUB4DOS:
|
|
|
|
case BT_GRUB2:
|
|
|
|
allowed_partition_scheme[PARTITION_STYLE_GPT] = FALSE;
|
|
|
|
allowed_target_system[1] = FALSE;
|
|
|
|
break;
|
|
|
|
case BT_UEFI_NTFS:
|
|
|
|
allowed_target_system[0] = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!only_target) {
|
2019-02-01 12:34:01 +00:00
|
|
|
// Override partition type selection to GPT for drives larger than 2TB
|
|
|
|
if (SelectedDrive.DiskSize > 2 * TB)
|
|
|
|
selected_pt = PARTITION_STYLE_GPT;
|
2018-03-26 17:58:22 +00:00
|
|
|
// Try to reselect the current drive's partition scheme
|
2018-04-27 15:31:03 +00:00
|
|
|
int preferred_pt = SelectedDrive.PartitionStyle;
|
2018-03-22 23:14:20 +00:00
|
|
|
if (allowed_partition_scheme[PARTITION_STYLE_MBR])
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme,
|
|
|
|
ComboBox_AddStringU(hPartitionScheme, "MBR"), PARTITION_STYLE_MBR));
|
|
|
|
if (allowed_partition_scheme[PARTITION_STYLE_GPT])
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme,
|
|
|
|
ComboBox_AddStringU(hPartitionScheme, "GPT"), PARTITION_STYLE_GPT));
|
|
|
|
if (allowed_partition_scheme[PARTITION_STYLE_SFD])
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hPartitionScheme,
|
|
|
|
ComboBox_AddStringU(hPartitionScheme, sfd_name), PARTITION_STYLE_SFD));
|
2018-03-26 17:58:22 +00:00
|
|
|
// Override the partition scheme according to the current
|
2019-04-13 14:29:27 +00:00
|
|
|
if (boot_type == BT_NON_BOOTABLE)
|
2018-04-27 15:31:03 +00:00
|
|
|
preferred_pt = (selected_pt >= 0) ? selected_pt : PARTITION_STYLE_MBR;
|
2019-04-13 14:29:27 +00:00
|
|
|
else if (boot_type == BT_UEFI_NTFS)
|
2018-04-27 15:31:03 +00:00
|
|
|
preferred_pt = (selected_pt >= 0) ? selected_pt : PARTITION_STYLE_GPT;
|
2020-07-19 21:35:30 +00:00
|
|
|
else if ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.is_iso || img_report.is_windows_img)) {
|
2018-03-26 17:58:22 +00:00
|
|
|
if (HAS_WINDOWS(img_report) && img_report.has_efi)
|
2018-05-16 11:56:31 +00:00
|
|
|
preferred_pt = allow_dual_uefi_bios? PARTITION_STYLE_MBR :
|
|
|
|
((selected_pt >= 0) ? selected_pt : PARTITION_STYLE_GPT);
|
2022-01-07 13:25:46 +00:00
|
|
|
if (IS_DD_BOOTABLE(img_report))
|
2018-04-27 15:31:03 +00:00
|
|
|
preferred_pt = (selected_pt >= 0) ? selected_pt : PARTITION_STYLE_MBR;
|
2018-03-26 17:58:22 +00:00
|
|
|
}
|
2018-04-27 15:31:03 +00:00
|
|
|
SetComboEntry(hPartitionScheme, preferred_pt);
|
2020-07-17 20:51:15 +00:00
|
|
|
partition_type = (int)ComboBox_GetCurItemData(hPartitionScheme);
|
2018-03-22 23:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
has_uefi_csm = FALSE;
|
2019-04-13 14:29:27 +00:00
|
|
|
if (allowed_target_system[0] && (partition_type != PARTITION_STYLE_GPT)) {
|
2018-03-22 23:14:20 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hTargetSystem,
|
|
|
|
ComboBox_AddStringU(hTargetSystem, lmprintf(MSG_031)), TT_BIOS));
|
|
|
|
has_uefi_csm = TRUE;
|
|
|
|
}
|
2019-04-13 14:29:27 +00:00
|
|
|
if (allowed_target_system[1] && !((partition_type == PARTITION_STYLE_MBR) && (boot_type == BT_IMAGE) && IS_BIOS_BOOTABLE(img_report) && IS_EFI_BOOTABLE(img_report)) )
|
2018-03-22 23:14:20 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hTargetSystem,
|
|
|
|
ComboBox_AddStringU(hTargetSystem, lmprintf(MSG_032)), TT_UEFI));
|
2019-04-13 14:29:27 +00:00
|
|
|
if (allowed_target_system[2] && ((partition_type != PARTITION_STYLE_GPT) || (boot_type == BT_NON_BOOTABLE)))
|
2018-03-22 23:14:20 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hTargetSystem,
|
|
|
|
ComboBox_AddStringU(hTargetSystem, lmprintf(MSG_033)), TT_BIOS));
|
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hTargetSystem, 0));
|
2020-07-17 20:51:15 +00:00
|
|
|
target_type = (int)ComboBox_GetCurItemData(hTargetSystem);
|
2018-03-22 23:14:20 +00:00
|
|
|
// Can't update a tooltip from a thread, so we send a message instead
|
|
|
|
SendMessage(hMainDialog, UM_UPDATE_CSM_TOOLTIP, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Populate the Allocation unit size field
|
|
|
|
static BOOL SetClusterSizes(int FSType)
|
|
|
|
{
|
|
|
|
char* szClustSize;
|
|
|
|
int i, k, default_index = 0;
|
|
|
|
ULONG j;
|
|
|
|
|
|
|
|
IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize));
|
|
|
|
|
|
|
|
if ((FSType < 0) || (FSType >= FS_MAX)) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((SelectedDrive.ClusterSize[FSType].Allowed == 0)
|
|
|
|
|| (SelectedDrive.ClusterSize[FSType].Default == 0)) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0, j = 0x100, k = 0; j<0x10000000; i++, j <<= 1) {
|
|
|
|
if (j & SelectedDrive.ClusterSize[FSType].Allowed) {
|
|
|
|
if (j == SelectedDrive.ClusterSize[FSType].Default) {
|
|
|
|
szClustSize = lmprintf(MSG_030, ClusterSizeLabel[i]);
|
|
|
|
default_index = k;
|
|
|
|
} else {
|
|
|
|
szClustSize = ClusterSizeLabel[i];
|
|
|
|
}
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hClusterSize, ComboBox_AddStringU(hClusterSize, szClustSize), j));
|
2013-10-15 21:58:27 +00:00
|
|
|
k++;
|
|
|
|
}
|
|
|
|
}
|
2018-03-22 23:14:20 +00:00
|
|
|
|
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hClusterSize, default_index));
|
|
|
|
return TRUE;
|
2013-10-15 21:58:27 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 01:02:17 +00:00
|
|
|
static BOOL IsRefsAvailable(MEDIA_TYPE MediaType)
|
|
|
|
{
|
|
|
|
// The creation of ReFS drives was added in Windows 8.1... but then removed by
|
|
|
|
// Microsoft in Windows 10 1709, except for the Enterprise and Pro Workstation
|
|
|
|
// versions. Oh and VdsService::QueryFileSystemTypes() is *USELESS* to detect
|
|
|
|
// if ReFS is available on the system. Oh, and it only applies to fixed media.
|
|
|
|
|
|
|
|
if (MediaType != FixedMedia)
|
|
|
|
return FALSE;
|
|
|
|
if (nWindowsVersion < WINDOWS_8_1 || nWindowsBuildNumber <= 0)
|
|
|
|
return FALSE;
|
2022-02-04 17:41:44 +00:00
|
|
|
// Per https://gist.github.com/0xbadfca11/da0598e47dd643d933dc
|
|
|
|
if (nWindowsBuildNumber < 16226)
|
2021-10-21 01:02:17 +00:00
|
|
|
return TRUE;
|
|
|
|
switch (nWindowsEdition) {
|
|
|
|
case 0x0000000A: // Enterprise Server
|
|
|
|
case 0x0000001B: // Enterprise N
|
|
|
|
case 0x00000046: // Enterprise E
|
|
|
|
case 0x00000048: // Enterprise Eval
|
|
|
|
case 0x00000054: // Enterprise N Eval
|
|
|
|
case 0x0000007D: // Enterprise S
|
|
|
|
case 0x0000007E: // Enterprise S N
|
|
|
|
case 0x00000081: // Enterprise S Eval
|
|
|
|
case 0x00000082: // Enterprise S N Eval
|
|
|
|
case 0x0000008C: // Enterprise Subscription
|
|
|
|
case 0x0000008D: // Enterprise Subscription N
|
|
|
|
case 0x000000A1: // Pro Workstation
|
|
|
|
case 0x000000A2: // Pro Workstation N
|
|
|
|
case 0x000000AB: // Enterprise G
|
|
|
|
case 0x000000AC: // Enterprise G N
|
|
|
|
return TRUE;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Populate the File System and Cluster Size dropdowns
|
2019-04-13 14:29:27 +00:00
|
|
|
static BOOL SetFileSystemAndClusterSize(char* fs_name)
|
2011-12-01 02:56:44 +00:00
|
|
|
{
|
2018-03-22 23:14:20 +00:00
|
|
|
int fs_index;
|
2011-12-01 02:56:44 +00:00
|
|
|
LONGLONG i;
|
2014-01-24 02:46:06 +00:00
|
|
|
char tmp[128] = "", *entry;
|
2011-12-01 15:01:10 +00:00
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_ResetContent(hFileSystem));
|
|
|
|
IGNORE_RETVAL(ComboBox_ResetContent(hClusterSize));
|
2011-12-01 15:01:10 +00:00
|
|
|
default_fs = FS_UNKNOWN;
|
2011-12-01 02:56:44 +00:00
|
|
|
memset(&SelectedDrive.ClusterSize, 0, sizeof(SelectedDrive.ClusterSize));
|
|
|
|
|
2011-12-13 02:10:27 +00:00
|
|
|
/*
|
2018-03-22 23:14:20 +00:00
|
|
|
* See https://support.microsoft.com/en-gb/help/140365/default-cluster-size-for-ntfs--fat--and-exfat
|
2012-11-03 17:40:33 +00:00
|
|
|
* The following are MS's allowed cluster sizes for FAT16 and FAT32:
|
2011-12-13 02:10:27 +00:00
|
|
|
*
|
|
|
|
* FAT16
|
|
|
|
* 31M : 512 - 4096
|
|
|
|
* 63M : 1024 - 8192
|
|
|
|
* 127M : 2048 - 16k
|
|
|
|
* 255M : 4096 - 32k
|
|
|
|
* 511M : 8192 - 64k
|
|
|
|
* 1023M: 16k - 64k
|
|
|
|
* 2047M: 32k - 64k
|
|
|
|
* 4095M: 64k
|
|
|
|
* 4GB+ : N/A
|
|
|
|
*
|
|
|
|
* FAT32
|
|
|
|
* 31M : N/A
|
2014-04-10 21:01:48 +00:00
|
|
|
* 63M : N/A (NB unlike MS, we're allowing 512-512 here)
|
2011-12-13 02:10:27 +00:00
|
|
|
* 127M : 512 - 1024
|
|
|
|
* 255M : 512 - 2048
|
|
|
|
* 511M : 512 - 4096
|
|
|
|
* 1023M: 512 - 8192
|
|
|
|
* 2047M: 512 - 16k
|
|
|
|
* 4095M: 1024 - 32k
|
|
|
|
* 7GB : 2048 - 64k
|
|
|
|
* 15GB : 4096 - 64k
|
2012-11-03 17:40:33 +00:00
|
|
|
* 31GB : 8192 - 64k This is as far as Microsoft's FormatEx goes...
|
|
|
|
* 63GB : 16k - 64k ...but we can go higher using fat32format from RidgeCrop.
|
|
|
|
* 2TB+ : N/A
|
2014-04-04 17:22:00 +00:00
|
|
|
*
|
2011-12-13 02:10:27 +00:00
|
|
|
*/
|
|
|
|
|
2011-12-01 02:56:44 +00:00
|
|
|
// FAT 16
|
|
|
|
if (SelectedDrive.DiskSize < 4*GB) {
|
2011-12-13 02:10:27 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_FAT16].Allowed = 0x00001E00;
|
2022-11-16 16:55:41 +00:00
|
|
|
for (i = 32; i <= 4096; i <<= 1) { // 8 MB -> 4 GB
|
2011-12-01 02:56:44 +00:00
|
|
|
if (SelectedDrive.DiskSize < i*MB) {
|
|
|
|
SelectedDrive.ClusterSize[FS_FAT16].Default = 16*(ULONG)i;
|
|
|
|
break;
|
|
|
|
}
|
2011-12-13 02:10:27 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_FAT16].Allowed <<= 1;
|
2011-12-01 02:56:44 +00:00
|
|
|
}
|
2011-12-13 02:10:27 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_FAT16].Allowed &= 0x0001FE00;
|
2011-12-01 02:56:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// FAT 32
|
2013-06-20 14:41:22 +00:00
|
|
|
// > 32GB FAT32 is not supported by MS and FormatEx but is achieved using fat32format
|
2011-12-13 02:10:27 +00:00
|
|
|
// See: http://www.ridgecrop.demon.co.uk/index.htm?fat32format.htm
|
2012-11-03 17:40:33 +00:00
|
|
|
// < 32 MB FAT32 is not allowed by FormatEx, so we don't bother
|
2013-09-22 02:28:56 +00:00
|
|
|
if ((SelectedDrive.DiskSize >= 32*MB) && (1.0f*SelectedDrive.DiskSize < 1.0f*MAX_FAT32_SIZE*TB)) {
|
2011-12-13 02:10:27 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_FAT32].Allowed = 0x000001F8;
|
|
|
|
for (i=32; i<=(32*1024); i<<=1) { // 32 MB -> 32 GB
|
2014-04-13 14:20:20 +00:00
|
|
|
if (SelectedDrive.DiskSize*1.0f < i*MB*FAT32_CLUSTER_THRESHOLD) { // MS
|
2011-12-01 02:56:44 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_FAT32].Default = 8*(ULONG)i;
|
|
|
|
break;
|
|
|
|
}
|
2011-12-13 02:10:27 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_FAT32].Allowed <<= 1;
|
2011-12-01 02:56:44 +00:00
|
|
|
}
|
2011-12-13 02:10:27 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_FAT32].Allowed &= 0x0001FE00;
|
|
|
|
|
|
|
|
// Default cluster sizes in the 256MB to 32 GB range do not follow the rule above
|
2012-11-03 17:40:33 +00:00
|
|
|
if ((SelectedDrive.DiskSize >= 256*MB) && (SelectedDrive.DiskSize < 32*GB)) {
|
2011-12-13 02:10:27 +00:00
|
|
|
for (i=8; i<=32; i<<=1) { // 256 MB -> 32 GB
|
2014-04-13 14:20:20 +00:00
|
|
|
if (SelectedDrive.DiskSize*1.0f < i*GB*FAT32_CLUSTER_THRESHOLD) {
|
2016-05-02 11:06:38 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_FAT32].Default = ((ULONG)i/2)*KB;
|
2011-12-13 02:10:27 +00:00
|
|
|
break;
|
|
|
|
}
|
2011-12-01 02:56:44 +00:00
|
|
|
}
|
|
|
|
}
|
2012-11-03 17:40:33 +00:00
|
|
|
// More adjustments for large drives
|
|
|
|
if (SelectedDrive.DiskSize >= 32*GB) {
|
|
|
|
SelectedDrive.ClusterSize[FS_FAT32].Allowed &= 0x0001C000;
|
|
|
|
SelectedDrive.ClusterSize[FS_FAT32].Default = 0x00008000;
|
|
|
|
}
|
2011-12-01 02:56:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (SelectedDrive.DiskSize < 256*TB) {
|
2013-07-08 23:14:29 +00:00
|
|
|
// NTFS
|
2011-12-01 02:56:44 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_NTFS].Allowed = 0x0001FE00;
|
|
|
|
for (i=16; i<=256; i<<=1) { // 7 MB -> 256 TB
|
|
|
|
if (SelectedDrive.DiskSize < i*TB) {
|
2016-05-02 11:06:38 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_NTFS].Default = ((ULONG)i/4)*KB;
|
2011-12-01 02:56:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-13 14:29:48 +00:00
|
|
|
// exFAT
|
|
|
|
SelectedDrive.ClusterSize[FS_EXFAT].Allowed = 0x03FFFE00;
|
|
|
|
if (SelectedDrive.DiskSize < 256*MB) // < 256 MB
|
|
|
|
SelectedDrive.ClusterSize[FS_EXFAT].Default = 4*KB;
|
|
|
|
else if (SelectedDrive.DiskSize < 32*GB) // < 32 GB
|
|
|
|
SelectedDrive.ClusterSize[FS_EXFAT].Default = 32*KB;
|
|
|
|
else
|
|
|
|
SelectedDrive.ClusterSize[FS_EXFAT].Default = 128*KB;
|
2013-07-08 23:14:29 +00:00
|
|
|
|
2017-11-13 14:29:48 +00:00
|
|
|
// UDF
|
|
|
|
SelectedDrive.ClusterSize[FS_UDF].Allowed = SINGLE_CLUSTERSIZE_DEFAULT;
|
|
|
|
SelectedDrive.ClusterSize[FS_UDF].Default = 1;
|
2014-03-29 00:22:54 +00:00
|
|
|
|
2019-05-03 22:51:05 +00:00
|
|
|
// ext2/ext3/ext4
|
2020-10-02 12:58:15 +00:00
|
|
|
if (advanced_mode_format && (SelectedDrive.DiskSize >= MIN_EXT_SIZE)) {
|
2019-05-03 22:51:05 +00:00
|
|
|
SelectedDrive.ClusterSize[FS_EXT2].Allowed = SINGLE_CLUSTERSIZE_DEFAULT;
|
|
|
|
SelectedDrive.ClusterSize[FS_EXT2].Default = 1;
|
|
|
|
SelectedDrive.ClusterSize[FS_EXT3].Allowed = SINGLE_CLUSTERSIZE_DEFAULT;
|
|
|
|
SelectedDrive.ClusterSize[FS_EXT3].Default = 1;
|
|
|
|
}
|
|
|
|
|
2021-10-21 01:02:17 +00:00
|
|
|
// ReFS (only applicable for a select number of Windows platforms and editions)
|
|
|
|
if ((SelectedDrive.DiskSize >= 512 * MB) && (IsRefsAvailable(SelectedDrive.MediaType))) {
|
|
|
|
if (SelectedDrive.DiskSize < 16 * TB) { // < 16 TB
|
|
|
|
SelectedDrive.ClusterSize[FS_REFS].Allowed = 64 * KB + 4 * KB;
|
|
|
|
SelectedDrive.ClusterSize[FS_REFS].Default = 4 * KB;
|
|
|
|
} else {
|
|
|
|
SelectedDrive.ClusterSize[FS_REFS].Allowed = 64 * KB;
|
|
|
|
SelectedDrive.ClusterSize[FS_REFS].Default = 64 * KB;
|
2014-04-02 21:47:35 +00:00
|
|
|
}
|
2014-03-29 00:22:54 +00:00
|
|
|
}
|
2011-12-01 02:56:44 +00:00
|
|
|
}
|
|
|
|
|
2011-12-01 15:01:10 +00:00
|
|
|
// Only add the filesystems we can service
|
2018-03-22 23:14:20 +00:00
|
|
|
SetAllowedFileSystems();
|
|
|
|
SetClusterSizeLabels();
|
|
|
|
|
|
|
|
for (fs_index = 0; fs_index < FS_MAX; fs_index++) {
|
2014-10-28 19:16:35 +00:00
|
|
|
// Remove all cluster sizes that are below the sector size
|
2018-03-22 23:14:20 +00:00
|
|
|
if (SelectedDrive.ClusterSize[fs_index].Allowed != SINGLE_CLUSTERSIZE_DEFAULT) {
|
|
|
|
SelectedDrive.ClusterSize[fs_index].Allowed &= ~(SelectedDrive.SectorSize - 1);
|
|
|
|
if ((SelectedDrive.ClusterSize[fs_index].Default & SelectedDrive.ClusterSize[fs_index].Allowed) == 0)
|
2014-10-28 19:16:35 +00:00
|
|
|
// We lost our default => Use rightmost bit to select the new one
|
2018-03-22 23:14:20 +00:00
|
|
|
SelectedDrive.ClusterSize[fs_index].Default =
|
|
|
|
SelectedDrive.ClusterSize[fs_index].Allowed & (-(LONG)SelectedDrive.ClusterSize[fs_index].Allowed);
|
2014-10-28 19:16:35 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
if (SelectedDrive.ClusterSize[fs_index].Allowed != 0) {
|
2013-01-09 23:24:31 +00:00
|
|
|
tmp[0] = 0;
|
|
|
|
// Tell the user if we're going to use Large FAT32 or regular
|
2018-03-22 23:14:20 +00:00
|
|
|
if ((fs_index == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32)))
|
2017-08-10 18:43:04 +00:00
|
|
|
static_strcat(tmp, "Large ");
|
2018-03-22 23:14:20 +00:00
|
|
|
static_strcat(tmp, FileSystemLabel[fs_index]);
|
2011-12-01 15:01:10 +00:00
|
|
|
if (default_fs == FS_UNKNOWN) {
|
2013-10-15 21:58:27 +00:00
|
|
|
entry = lmprintf(MSG_030, tmp);
|
2018-03-22 23:14:20 +00:00
|
|
|
default_fs = fs_index;
|
2013-10-15 21:58:27 +00:00
|
|
|
} else {
|
|
|
|
entry = tmp;
|
2011-12-01 15:01:10 +00:00
|
|
|
}
|
2018-03-22 23:14:20 +00:00
|
|
|
if (allowed_filesystem[fs_index]) {
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hFileSystem,
|
|
|
|
ComboBox_AddStringU(hFileSystem, entry), fs_index));
|
2011-12-04 20:13:51 +00:00
|
|
|
}
|
2011-12-01 02:56:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-01 15:01:10 +00:00
|
|
|
// re-select existing FS if it's one we know
|
2013-01-24 21:30:11 +00:00
|
|
|
SelectedDrive.FSType = FS_UNKNOWN;
|
2019-04-13 14:29:27 +00:00
|
|
|
if (safe_strlen(fs_name) != 0) {
|
2018-03-22 23:14:20 +00:00
|
|
|
for (SelectedDrive.FSType = FS_MAX - 1; SelectedDrive.FSType >= 0; SelectedDrive.FSType--) {
|
2019-04-13 14:29:27 +00:00
|
|
|
if (safe_strcmp(fs_name, FileSystemLabel[SelectedDrive.FSType]) == 0) {
|
2011-11-24 23:49:42 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-12-01 15:01:10 +00:00
|
|
|
} else {
|
2018-05-06 21:31:42 +00:00
|
|
|
// Re-select last user-selected FS
|
|
|
|
SelectedDrive.FSType = selected_fs;
|
2011-11-19 01:30:20 +00:00
|
|
|
}
|
|
|
|
|
2022-11-16 16:55:41 +00:00
|
|
|
for (i = 0; i < ComboBox_GetCount(hFileSystem); i++) {
|
2011-12-01 15:01:10 +00:00
|
|
|
if (ComboBox_GetItemData(hFileSystem, i) == SelectedDrive.FSType) {
|
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hFileSystem, i));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == ComboBox_GetCount(hFileSystem)) {
|
|
|
|
// failed to reselect => pick default
|
2018-03-22 23:14:20 +00:00
|
|
|
SetComboEntry(hFileSystem, default_fs);
|
2011-12-01 15:01:10 +00:00
|
|
|
}
|
|
|
|
|
2020-07-17 20:51:15 +00:00
|
|
|
return SetClusterSizes((int)ComboBox_GetCurItemData(hFileSystem));
|
2011-11-18 21:46:34 +00:00
|
|
|
}
|
|
|
|
|
2012-02-16 11:37:59 +00:00
|
|
|
static void SetFSFromISO(void)
|
|
|
|
{
|
2018-05-06 21:31:42 +00:00
|
|
|
int i, fs_tmp, preferred_fs = FS_UNKNOWN;
|
2022-11-16 16:55:41 +00:00
|
|
|
uint32_t fs_mask = FS_NTFS | (img_report.has_4GB_file ? 0 : FS_FAT32);
|
2020-07-17 20:51:15 +00:00
|
|
|
BOOL windows_to_go = (image_options & IMOP_WINTOGO) && (boot_type == BT_IMAGE) &&
|
2021-10-08 18:22:33 +00:00
|
|
|
HAS_WINTOGO(img_report) && (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO);
|
2012-02-16 11:37:59 +00:00
|
|
|
|
2014-05-22 00:52:25 +00:00
|
|
|
if (image_path == NULL)
|
2012-02-16 11:37:59 +00:00
|
|
|
return;
|
|
|
|
|
2012-03-03 23:12:48 +00:00
|
|
|
// Create a mask of all the FS's available
|
2022-11-16 16:55:41 +00:00
|
|
|
for (i = 0; i < ComboBox_GetCount(hFileSystem); i++) {
|
2018-03-22 23:14:20 +00:00
|
|
|
fs_tmp = (int)ComboBox_GetItemData(hFileSystem, i);
|
2022-11-16 16:55:41 +00:00
|
|
|
fs_mask |= 1 << fs_tmp;
|
2018-10-23 19:10:52 +00:00
|
|
|
}
|
|
|
|
|
2022-11-16 16:55:41 +00:00
|
|
|
// If the FS requested from the command line is valid use it
|
|
|
|
if ((preselected_fs != FS_UNKNOWN) && (fs_mask & (1 << preselected_fs))) {
|
|
|
|
preferred_fs = preselected_fs;
|
|
|
|
} else {
|
2018-10-23 19:10:52 +00:00
|
|
|
// Syslinux and EFI have precedence over bootmgr (unless the user selected BIOS as target type)
|
|
|
|
if ((HAS_SYSLINUX(img_report)) || (HAS_REACTOS(img_report)) || HAS_KOLIBRIOS(img_report) ||
|
2022-11-16 16:55:41 +00:00
|
|
|
(IS_EFI_BOOTABLE(img_report) && (target_type == TT_UEFI) && (!windows_to_go) && (!img_report.has_4GB_file))) {
|
|
|
|
if (fs_mask & (1 << FS_FAT32))
|
2018-10-23 19:10:52 +00:00
|
|
|
preferred_fs = FS_FAT32;
|
2022-11-16 16:55:41 +00:00
|
|
|
else if ((fs_mask & (1 << FS_FAT16)) && !HAS_KOLIBRIOS(img_report))
|
2018-10-23 19:10:52 +00:00
|
|
|
preferred_fs = FS_FAT16;
|
|
|
|
} else if ((windows_to_go) || HAS_BOOTMGR(img_report) || HAS_WINPE(img_report)) {
|
2022-11-16 16:55:41 +00:00
|
|
|
if ((fs_mask & (1 << FS_FAT32)) && (!img_report.has_4GB_file) && (allow_dual_uefi_bios))
|
|
|
|
preferred_fs = FS_FAT32;
|
|
|
|
else if (fs_mask & (1 << FS_NTFS))
|
2018-10-23 19:10:52 +00:00
|
|
|
preferred_fs = FS_NTFS;
|
2012-02-16 11:37:59 +00:00
|
|
|
}
|
|
|
|
}
|
2012-03-03 23:12:48 +00:00
|
|
|
|
|
|
|
// Try to select the FS
|
2019-03-14 18:53:08 +00:00
|
|
|
for (i = 0; i < ComboBox_GetCount(hFileSystem); i++) {
|
2018-03-22 23:14:20 +00:00
|
|
|
fs_tmp = (int)ComboBox_GetItemData(hFileSystem, i);
|
2019-03-14 18:53:08 +00:00
|
|
|
if (fs_tmp == preferred_fs) {
|
2012-03-03 23:12:48 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hFileSystem, i));
|
2019-03-14 18:53:08 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-03-03 23:12:48 +00:00
|
|
|
}
|
2019-03-14 18:53:08 +00:00
|
|
|
if (selected_fs == FS_UNKNOWN)
|
|
|
|
selected_fs = preferred_fs;
|
2012-03-03 23:12:48 +00:00
|
|
|
|
2022-11-16 16:55:41 +00:00
|
|
|
SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE_INTERNAL << 16) | IDC_FILE_SYSTEM,
|
2012-02-16 11:37:59 +00:00
|
|
|
ComboBox_GetCurSel(hFileSystem));
|
|
|
|
}
|
|
|
|
|
2013-02-04 23:15:11 +00:00
|
|
|
static void SetMBRProps(void)
|
2012-05-16 22:38:39 +00:00
|
|
|
{
|
2016-12-14 23:27:04 +00:00
|
|
|
BOOL needs_masquerading = HAS_WINPE(img_report) && (!img_report.uses_minint);
|
2021-04-08 16:29:13 +00:00
|
|
|
fs_type = (int)ComboBox_GetCurItemData(hFileSystem);
|
2012-05-16 22:38:39 +00:00
|
|
|
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((!mbr_selected_by_user) && ((image_path == NULL) || (boot_type != BT_IMAGE) || (fs_type != FS_NTFS) || HAS_GRUB(img_report) ||
|
2021-10-08 18:22:33 +00:00
|
|
|
((image_options & IMOP_WINTOGO) && (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO)) )) {
|
2012-05-16 22:38:39 +00:00
|
|
|
CheckDlgButton(hMainDialog, IDC_RUFUS_MBR, BST_UNCHECKED);
|
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-12-14 23:27:04 +00:00
|
|
|
uMBRChecked = (needs_masquerading || HAS_BOOTMGR(img_report) || mbr_selected_by_user)?BST_CHECKED:BST_UNCHECKED;
|
2014-03-14 23:13:04 +00:00
|
|
|
if (IsWindowEnabled(GetDlgItem(hMainDialog, IDC_RUFUS_MBR)))
|
|
|
|
CheckDlgButton(hMainDialog, IDC_RUFUS_MBR, uMBRChecked);
|
2012-05-16 22:38:39 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, needs_masquerading?1:0));
|
|
|
|
}
|
|
|
|
|
2018-07-06 04:46:36 +00:00
|
|
|
static void SetProposedLabel(int ComboIndex)
|
|
|
|
{
|
|
|
|
const char no_label[] = STR_NO_LABEL, empty[] = "";
|
|
|
|
|
|
|
|
app_changed_label = TRUE;
|
|
|
|
// If bootable ISO creation is selected, and we have an ISO selected with a valid name, use that
|
|
|
|
// Also some distros (eg. Arch) require the USB to have the same label as the ISO
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((boot_type == BT_IMAGE) && (image_path != NULL) && (img_report.label[0] != 0)) {
|
2018-07-06 04:46:36 +00:00
|
|
|
SetWindowTextU(hLabel, img_report.label);
|
|
|
|
// If we force the ISO label, we need to reset the user_changed_label flag
|
|
|
|
user_changed_label = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the user manually changed the label, try to preserve it
|
|
|
|
if (user_changed_label) {
|
|
|
|
app_changed_label = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Empty the label if no device is currently selected
|
|
|
|
if (ComboIndex < 0) {
|
|
|
|
SetWindowTextU(hLabel, "");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Else if no existing label is available, propose one according to the size (eg: "256MB", "8GB")
|
2022-05-25 12:21:36 +00:00
|
|
|
if ((_stricmp(no_label, rufus_drive[ComboIndex].label) == 0) || (_stricmp(no_label, empty) == 0)
|
|
|
|
|| (safe_stricmp(lmprintf(MSG_207), rufus_drive[ComboIndex].label) == 0)) {
|
2018-07-06 04:46:36 +00:00
|
|
|
SetWindowTextU(hLabel, SelectedDrive.proposed_label);
|
|
|
|
} else {
|
2022-05-25 12:21:36 +00:00
|
|
|
SetWindowTextU(hLabel, rufus_drive[ComboIndex].label);
|
2018-07-06 04:46:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// This handles the enabling/disabling of the "Add fixes for old BIOSes" and "Use Rufus MBR" controls
|
|
|
|
static void EnableMBRBootOptions(BOOL enable, BOOL remove_checkboxes)
|
2012-05-25 16:54:06 +00:00
|
|
|
{
|
2019-04-13 14:29:27 +00:00
|
|
|
BOOL actual_enable_mbr = (boot_type > BT_IMAGE) ? FALSE: enable;
|
2018-03-22 23:14:20 +00:00
|
|
|
BOOL actual_enable_fix = enable;
|
2014-03-14 23:13:04 +00:00
|
|
|
static UINT uXPartChecked = BST_UNCHECKED;
|
|
|
|
|
2019-05-03 22:51:05 +00:00
|
|
|
if ((partition_type != PARTITION_STYLE_MBR) || (target_type != TT_BIOS) || (boot_type == BT_NON_BOOTABLE) ||
|
2019-08-24 22:45:53 +00:00
|
|
|
((boot_type == BT_IMAGE) && (!IS_BIOS_BOOTABLE(img_report) || IS_DD_ONLY(img_report)))) {
|
2018-03-22 23:14:20 +00:00
|
|
|
// These options cannot apply if we aren't using MBR+BIOS, or are using an image that isn't BIOS bootable
|
2014-11-18 23:49:29 +00:00
|
|
|
actual_enable_mbr = FALSE;
|
2018-03-22 23:14:20 +00:00
|
|
|
actual_enable_fix = FALSE;
|
|
|
|
} else {
|
|
|
|
// If we are using an image, the Rufus MBR only applies if it's for Windows
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((boot_type == BT_IMAGE) && !HAS_WINPE(img_report) && !HAS_BOOTMGR(img_report)) {
|
2018-03-22 23:14:20 +00:00
|
|
|
actual_enable_mbr = FALSE;
|
|
|
|
mbr_selected_by_user = FALSE;
|
|
|
|
}
|
2014-11-18 23:49:29 +00:00
|
|
|
}
|
2018-03-22 23:14:20 +00:00
|
|
|
|
2014-03-15 14:14:10 +00:00
|
|
|
if (remove_checkboxes) {
|
|
|
|
// Store/Restore the checkbox states
|
2014-11-18 23:49:29 +00:00
|
|
|
if (IsWindowEnabled(GetDlgItem(hMainDialog, IDC_RUFUS_MBR)) && !actual_enable_mbr) {
|
2014-03-15 14:14:10 +00:00
|
|
|
uMBRChecked = IsChecked(IDC_RUFUS_MBR);
|
|
|
|
CheckDlgButton(hMainDialog, IDC_RUFUS_MBR, BST_UNCHECKED);
|
2014-11-18 23:49:29 +00:00
|
|
|
} else if (!IsWindowEnabled(GetDlgItem(hMainDialog, IDC_RUFUS_MBR)) && actual_enable_mbr) {
|
2014-03-15 14:14:10 +00:00
|
|
|
CheckDlgButton(hMainDialog, IDC_RUFUS_MBR, uMBRChecked);
|
2019-07-02 16:49:33 +00:00
|
|
|
}
|
|
|
|
if (IsWindowEnabled(GetDlgItem(hMainDialog, IDC_OLD_BIOS_FIXES)) && !actual_enable_fix) {
|
|
|
|
uXPartChecked = IsChecked(IDC_OLD_BIOS_FIXES);
|
|
|
|
CheckDlgButton(hMainDialog, IDC_OLD_BIOS_FIXES, BST_UNCHECKED);
|
|
|
|
} else if (!IsWindowEnabled(GetDlgItem(hMainDialog, IDC_OLD_BIOS_FIXES)) && actual_enable_fix) {
|
2018-03-22 23:14:20 +00:00
|
|
|
CheckDlgButton(hMainDialog, IDC_OLD_BIOS_FIXES, uXPartChecked);
|
2014-03-15 14:14:10 +00:00
|
|
|
}
|
2014-03-14 23:13:04 +00:00
|
|
|
}
|
2013-02-04 23:15:11 +00:00
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_OLD_BIOS_FIXES), actual_enable_fix);
|
2014-11-18 23:49:29 +00:00
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_RUFUS_MBR), actual_enable_mbr);
|
|
|
|
EnableWindow(hDiskID, actual_enable_mbr);
|
2013-02-04 23:15:11 +00:00
|
|
|
}
|
|
|
|
|
2019-07-30 10:41:04 +00:00
|
|
|
static void EnableExtendedLabel(BOOL enable, BOOL remove_checkboxes)
|
2019-05-03 22:51:05 +00:00
|
|
|
{
|
|
|
|
static UINT checked, state = 0;
|
2019-08-24 22:45:53 +00:00
|
|
|
HWND hCtrl = GetDlgItem(hMainDialog, IDC_EXTENDED_LABEL);
|
|
|
|
|
2022-06-08 18:37:24 +00:00
|
|
|
if (IS_EXT(fs_type) || ((boot_type == BT_IMAGE) && IS_DD_ONLY(img_report)))
|
2019-08-24 22:45:53 +00:00
|
|
|
enable = FALSE;
|
2019-05-03 22:51:05 +00:00
|
|
|
|
2019-07-30 10:41:04 +00:00
|
|
|
if (remove_checkboxes) {
|
2019-08-24 22:45:53 +00:00
|
|
|
if (!enable && (state != 1)) {
|
2019-07-30 10:41:04 +00:00
|
|
|
checked = IsChecked(IDC_EXTENDED_LABEL);
|
|
|
|
CheckDlgButton(hMainDialog, IDC_EXTENDED_LABEL, BST_UNCHECKED);
|
|
|
|
state = 1;
|
|
|
|
} else if (enable && !IsWindowEnabled(hCtrl) && (state != 2)) {
|
|
|
|
if (state != 0)
|
|
|
|
CheckDlgButton(hMainDialog, IDC_EXTENDED_LABEL, checked);
|
|
|
|
state = 2;
|
|
|
|
}
|
2019-05-03 22:51:05 +00:00
|
|
|
}
|
|
|
|
EnableWindow(hCtrl, enable);
|
|
|
|
}
|
|
|
|
|
2019-08-24 22:45:53 +00:00
|
|
|
static void EnableQuickFormat(BOOL enable, BOOL remove_checkboxes)
|
2018-04-17 07:14:31 +00:00
|
|
|
{
|
2019-08-24 22:45:53 +00:00
|
|
|
static UINT checked, state = 0;
|
2018-04-17 07:14:31 +00:00
|
|
|
HWND hCtrl = GetDlgItem(hMainDialog, IDC_QUICK_FORMAT);
|
|
|
|
|
2019-08-24 22:45:53 +00:00
|
|
|
if ((boot_type == BT_IMAGE) && IS_DD_ONLY(img_report))
|
|
|
|
enable = FALSE;
|
2019-02-11 15:10:27 +00:00
|
|
|
|
2018-04-17 07:14:31 +00:00
|
|
|
// Disable/restore the quick format control depending on large FAT32 or ReFS
|
2019-04-13 14:29:27 +00:00
|
|
|
if (((fs_type == FS_FAT32) && ((SelectedDrive.DiskSize > LARGE_FAT32_SIZE) || (force_large_fat32))) || (fs_type == FS_REFS)) {
|
2018-10-03 17:14:40 +00:00
|
|
|
enable = FALSE;
|
2019-08-24 22:45:53 +00:00
|
|
|
// Quick Format is the only option for the above
|
|
|
|
remove_checkboxes = FALSE;
|
2019-02-11 15:10:27 +00:00
|
|
|
CheckDlgButton(hMainDialog, IDC_QUICK_FORMAT, BST_CHECKED);
|
2018-04-17 07:14:31 +00:00
|
|
|
}
|
2018-10-03 17:14:40 +00:00
|
|
|
|
2019-08-24 22:45:53 +00:00
|
|
|
if (remove_checkboxes) {
|
|
|
|
if (!enable && (state != 1)) {
|
|
|
|
checked = IsChecked(IDC_QUICK_FORMAT);
|
|
|
|
CheckDlgButton(hMainDialog, IDC_QUICK_FORMAT, BST_UNCHECKED);
|
|
|
|
state = 1;
|
|
|
|
} else if (enable && !IsWindowEnabled(hCtrl) && (state != 2)) {
|
|
|
|
if (state != 0)
|
|
|
|
CheckDlgButton(hMainDialog, IDC_QUICK_FORMAT, checked);
|
|
|
|
state = 2;
|
|
|
|
}
|
2018-10-03 17:14:40 +00:00
|
|
|
}
|
|
|
|
EnableWindow(hCtrl, enable);
|
2018-04-17 07:14:31 +00:00
|
|
|
}
|
|
|
|
|
2014-03-15 14:14:10 +00:00
|
|
|
static void EnableBootOptions(BOOL enable, BOOL remove_checkboxes)
|
2013-02-04 23:15:11 +00:00
|
|
|
{
|
2018-03-22 23:14:20 +00:00
|
|
|
BOOL actual_enable_bb, actual_enable = enable;
|
2012-05-25 16:54:06 +00:00
|
|
|
|
2020-02-15 14:40:05 +00:00
|
|
|
// If no device is selected, don't enable anything and also don't remove the checkboxes
|
|
|
|
if (ComboBox_GetCurSel(hDeviceList) < 0) {
|
2018-03-22 23:14:20 +00:00
|
|
|
actual_enable = FALSE;
|
2020-02-15 14:40:05 +00:00
|
|
|
remove_checkboxes = FALSE;
|
|
|
|
}
|
2018-03-22 23:14:20 +00:00
|
|
|
// If boot selection is set to image, but no image is currently selected, don't enable anything
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((boot_type == BT_IMAGE) && (image_path == NULL))
|
2018-03-22 23:14:20 +00:00
|
|
|
actual_enable = FALSE;
|
|
|
|
actual_enable_bb = actual_enable;
|
|
|
|
// If we are dealing with a pure DD image, remove all options except Bad Blocks check
|
2022-01-07 13:25:46 +00:00
|
|
|
if ((boot_type == BT_IMAGE) && IS_DD_BOOTABLE(img_report) && (!img_report.is_iso))
|
2018-03-22 23:14:20 +00:00
|
|
|
actual_enable = FALSE;
|
|
|
|
|
2020-07-17 20:51:15 +00:00
|
|
|
EnableWindow(hImageOption, actual_enable);
|
2018-07-15 00:01:39 +00:00
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SLIDER), actual_enable);
|
2018-08-14 22:05:52 +00:00
|
|
|
// Make sure we set the range if we have persistence
|
|
|
|
if ((image_path != NULL) && HAS_PERSISTENCE(img_report))
|
|
|
|
SetPersistenceSize();
|
2018-07-18 11:22:37 +00:00
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SIZE), (persistence_size != 0) && actual_enable);
|
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_PERSISTENCE_UNITS), (persistence_size != 0) && actual_enable);
|
2018-03-22 23:14:20 +00:00
|
|
|
EnableMBRBootOptions(actual_enable, remove_checkboxes);
|
|
|
|
|
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_LABEL), actual_enable);
|
2019-08-24 22:45:53 +00:00
|
|
|
if (boot_type == BT_IMAGE) {
|
|
|
|
if (IS_DD_ONLY(img_report))
|
|
|
|
remove_checkboxes = TRUE;
|
|
|
|
else if (image_path == NULL)
|
|
|
|
remove_checkboxes = FALSE;
|
|
|
|
}
|
|
|
|
EnableQuickFormat(actual_enable, remove_checkboxes);
|
|
|
|
EnableExtendedLabel(actual_enable, remove_checkboxes);
|
2018-03-22 23:14:20 +00:00
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_BAD_BLOCKS), actual_enable_bb);
|
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_NB_PASSES), actual_enable_bb);
|
2013-12-22 20:48:57 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Toggle controls according to operation
|
2019-07-30 10:41:04 +00:00
|
|
|
static void EnableControls(BOOL enable, BOOL remove_checkboxes)
|
2018-03-22 23:14:20 +00:00
|
|
|
{
|
2019-08-22 13:04:41 +00:00
|
|
|
op_in_progress = !enable;
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// The following only get disabled on format/checksum and otherwise remain enabled,
|
|
|
|
// even if no device or image are selected
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableWindow(hDeviceList, enable);
|
|
|
|
EnableWindow(hBootType, enable);
|
|
|
|
EnableWindow(hSelectImage, enable);
|
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDC_LIST_USB_HDD), enable);
|
|
|
|
EnableWindow(hAdvancedDeviceToolbar, enable);
|
|
|
|
EnableWindow(hAdvancedFormatToolbar, enable);
|
|
|
|
SendMessage(hMultiToolbar, TB_ENABLEBUTTON, (WPARAM)IDC_LANG, (LPARAM)enable);
|
|
|
|
SendMessage(hMultiToolbar, TB_ENABLEBUTTON, (WPARAM)IDC_ABOUT, (LPARAM)enable);
|
|
|
|
SendMessage(hMultiToolbar, TB_ENABLEBUTTON, (WPARAM)IDC_SETTINGS, (LPARAM)enable);
|
2018-03-22 23:14:20 +00:00
|
|
|
|
|
|
|
// Checksum button is enabled if an image has been selected
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableWindow(hHashToolbar, enable && (boot_type == BT_IMAGE) && (image_path != NULL));
|
2018-03-22 23:14:20 +00:00
|
|
|
|
|
|
|
// Toggle CLOSE/CANCEL
|
2019-07-30 10:41:04 +00:00
|
|
|
SetDlgItemTextU(hMainDialog, IDCANCEL, enable ? uppercase_close : uppercase_cancel);
|
2018-03-22 23:14:20 +00:00
|
|
|
|
|
|
|
// Only enable the following controls if a device is active
|
2019-07-30 10:41:04 +00:00
|
|
|
enable = (ComboBox_GetCurSel(hDeviceList) < 0) ? FALSE : enable;
|
2020-07-17 20:51:15 +00:00
|
|
|
EnableWindow(hImageOption, enable);
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableWindow(hSaveToolbar, enable);
|
2018-03-22 23:14:20 +00:00
|
|
|
|
|
|
|
// Enable or disable the Start button and the other boot options
|
2019-07-30 10:41:04 +00:00
|
|
|
enable = ((boot_type == BT_IMAGE) && (image_path == NULL)) ? FALSE : enable;
|
|
|
|
EnableWindow(hStart, enable);
|
|
|
|
EnableBootOptions(enable, remove_checkboxes);
|
2018-03-22 23:14:20 +00:00
|
|
|
|
|
|
|
// Finally, only enable the half-size dropdowns if we aren't dealing with a pure DD image
|
2020-07-19 21:35:30 +00:00
|
|
|
enable = ((boot_type == BT_IMAGE) && (image_path != NULL) &&
|
|
|
|
(!(img_report.is_iso || img_report.is_windows_img))) ? FALSE : enable;
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableWindow(hPartitionScheme, enable);
|
|
|
|
EnableWindow(hTargetSystem, enable);
|
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDS_CSM_HELP_TXT), enable);
|
|
|
|
EnableWindow(hFileSystem, enable);
|
|
|
|
EnableWindow(hClusterSize, enable);
|
2018-03-22 23:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Populate the UI main dropdown properties.
|
|
|
|
// This should be called on device or boot type change.
|
2018-05-06 21:31:42 +00:00
|
|
|
static BOOL PopulateProperties(void)
|
2011-11-18 21:46:34 +00:00
|
|
|
{
|
2013-11-30 17:39:38 +00:00
|
|
|
char* device_tooltip;
|
2018-05-06 21:31:42 +00:00
|
|
|
int device_index = ComboBox_GetCurSel(hDeviceList);
|
2019-04-13 14:29:27 +00:00
|
|
|
char fs_name[32];
|
2011-11-18 21:46:34 +00:00
|
|
|
|
2011-11-24 02:24:50 +00:00
|
|
|
memset(&SelectedDrive, 0, sizeof(SelectedDrive));
|
2018-03-22 23:14:20 +00:00
|
|
|
EnableWindow(hStart, FALSE);
|
2011-11-24 02:24:50 +00:00
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
if (device_index < 0)
|
2016-02-17 11:38:12 +00:00
|
|
|
goto out;
|
2011-11-18 23:41:28 +00:00
|
|
|
|
2018-08-14 22:05:52 +00:00
|
|
|
persistence_unit_selection = -1;
|
2018-03-22 23:14:20 +00:00
|
|
|
// Get data from the currently selected drive
|
|
|
|
SelectedDrive.DeviceNumber = (DWORD)ComboBox_GetItemData(hDeviceList, device_index);
|
2018-05-06 21:31:42 +00:00
|
|
|
// This fills the SelectedDrive properties
|
2019-04-13 14:29:27 +00:00
|
|
|
GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_name, sizeof(fs_name), FALSE);
|
2018-03-22 23:14:20 +00:00
|
|
|
SetPartitionSchemeAndTargetSystem(FALSE);
|
2018-05-06 21:31:42 +00:00
|
|
|
// Attempt to reselect the last file system explicitly set by the user
|
2019-04-13 14:29:27 +00:00
|
|
|
if (!SetFileSystemAndClusterSize((selected_fs == FS_UNKNOWN) ? fs_name : NULL)) {
|
2016-02-17 11:38:12 +00:00
|
|
|
SetProposedLabel(-1);
|
2018-03-22 23:14:20 +00:00
|
|
|
uprintf("No file system is selectable for this drive\n");
|
2011-11-18 21:46:34 +00:00
|
|
|
return FALSE;
|
2016-02-17 11:38:12 +00:00
|
|
|
}
|
2018-03-22 23:14:20 +00:00
|
|
|
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
2011-11-24 20:02:14 +00:00
|
|
|
|
2012-02-21 19:46:28 +00:00
|
|
|
// Set a proposed label according to the size (eg: "256MB", "8GB")
|
2020-02-23 16:29:16 +00:00
|
|
|
static_sprintf(SelectedDrive.proposed_label, "%s",
|
2020-11-03 12:49:08 +00:00
|
|
|
SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, TRUE));
|
2012-02-21 19:46:28 +00:00
|
|
|
|
2013-11-30 17:39:38 +00:00
|
|
|
// Add a tooltip (with the size of the device in parenthesis)
|
2022-05-25 12:21:36 +00:00
|
|
|
device_tooltip = (char*) malloc(safe_strlen(rufus_drive[device_index].name) + 32);
|
2014-03-01 00:09:40 +00:00
|
|
|
if (device_tooltip != NULL) {
|
2018-05-10 11:07:21 +00:00
|
|
|
if (right_to_left_mode)
|
2022-05-25 12:21:36 +00:00
|
|
|
safe_sprintf(device_tooltip, safe_strlen(rufus_drive[device_index].name) + 32, "(%s) %s",
|
|
|
|
SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE), rufus_drive[device_index].name);
|
2018-05-10 11:07:21 +00:00
|
|
|
else
|
2022-05-25 12:21:36 +00:00
|
|
|
safe_sprintf(device_tooltip, safe_strlen(rufus_drive[device_index].name) + 32, "%s (%s)",
|
|
|
|
rufus_drive[device_index].name, SizeToHumanReadable(SelectedDrive.DiskSize, FALSE, FALSE));
|
2013-11-30 17:39:38 +00:00
|
|
|
CreateTooltip(hDeviceList, device_tooltip, -1);
|
2014-03-01 00:09:40 +00:00
|
|
|
free(device_tooltip);
|
|
|
|
}
|
2013-11-30 17:39:38 +00:00
|
|
|
|
2016-02-17 11:38:12 +00:00
|
|
|
out:
|
2018-03-22 23:14:20 +00:00
|
|
|
SetProposedLabel(device_index);
|
2011-11-18 21:46:34 +00:00
|
|
|
return TRUE;
|
2011-11-17 01:43:06 +00:00
|
|
|
}
|
2011-11-13 20:53:23 +00:00
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Callback for the log window
|
|
|
|
BOOL CALLBACK LogCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
2012-05-30 23:32:25 +00:00
|
|
|
{
|
2018-03-22 23:14:20 +00:00
|
|
|
HDC hDC;
|
2012-05-30 23:32:25 +00:00
|
|
|
HFONT hf;
|
2018-08-20 08:46:23 +00:00
|
|
|
LONG lfHeight;
|
|
|
|
LONG_PTR style;
|
2012-05-30 23:32:25 +00:00
|
|
|
DWORD log_size;
|
2012-11-30 00:18:28 +00:00
|
|
|
char *log_buffer = NULL, *filepath;
|
2014-05-22 21:46:36 +00:00
|
|
|
EXT_DECL(log_ext, "rufus.log", __VA_GROUP__("*.log"), __VA_GROUP__("Rufus log"));
|
2012-05-30 23:32:25 +00:00
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
2013-10-15 21:58:27 +00:00
|
|
|
apply_localization(IDD_LOG, hDlg);
|
2012-05-30 23:32:25 +00:00
|
|
|
hLog = GetDlgItem(hDlg, IDC_LOG_EDIT);
|
2016-02-15 23:02:02 +00:00
|
|
|
|
2012-05-30 23:32:25 +00:00
|
|
|
// Increase the size of our log textbox to MAX_LOG_SIZE (unsigned word)
|
|
|
|
PostMessage(hLog, EM_LIMITTEXT, MAX_LOG_SIZE , 0);
|
|
|
|
// Set the font to Unicode so that we can display anything
|
2018-03-22 23:14:20 +00:00
|
|
|
hDC = GetDC(NULL);
|
2020-06-25 10:58:56 +00:00
|
|
|
lfHeight = -MulDiv(9, GetDeviceCaps(hDC, LOGPIXELSY), 72);
|
2018-03-22 23:14:20 +00:00
|
|
|
safe_release_dc(NULL, hDC);
|
2012-05-30 23:32:25 +00:00
|
|
|
hf = CreateFontA(lfHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
2020-06-25 10:58:56 +00:00
|
|
|
DEFAULT_CHARSET, 0, 0, PROOF_QUALITY, 0, "Consolas");
|
2012-05-30 23:32:25 +00:00
|
|
|
SendDlgItemMessageA(hDlg, IDC_LOG_EDIT, WM_SETFONT, (WPARAM)hf, TRUE);
|
2015-04-19 03:15:44 +00:00
|
|
|
// Set 'Close Log' as the selected button
|
|
|
|
SendMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, IDCANCEL), TRUE);
|
2016-02-15 23:02:02 +00:00
|
|
|
|
|
|
|
// Suppress any inherited RTL flags from our edit control's style. Otherwise
|
|
|
|
// the displayed text becomes a mess due to Windows trying to interpret
|
|
|
|
// dots, parenthesis, columns and so on in an RTL context...
|
|
|
|
// We also take this opportunity to fix the scroll bar and text alignment.
|
2018-08-20 08:46:23 +00:00
|
|
|
style = GetWindowLongPtr(hLog, GWL_EXSTYLE);
|
2016-02-15 23:02:02 +00:00
|
|
|
style &= ~(WS_EX_RTLREADING | WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR);
|
2018-08-20 08:46:23 +00:00
|
|
|
SetWindowLongPtr(hLog, GWL_EXSTYLE, style);
|
|
|
|
style = GetWindowLongPtr(hLog, GWL_STYLE);
|
2016-02-15 23:02:02 +00:00
|
|
|
style &= ~(ES_RIGHT);
|
2018-08-20 08:46:23 +00:00
|
|
|
SetWindowLongPtr(hLog, GWL_STYLE, style);
|
2015-04-19 03:15:44 +00:00
|
|
|
break;
|
2013-12-27 16:06:59 +00:00
|
|
|
case WM_COMMAND:
|
2012-05-30 23:32:25 +00:00
|
|
|
switch (LOWORD(wParam)) {
|
|
|
|
case IDCANCEL:
|
|
|
|
ShowWindow(hDlg, SW_HIDE);
|
|
|
|
log_displayed = FALSE;
|
2018-05-16 11:56:31 +00:00
|
|
|
// Set focus to the Cancel button on the main dialog
|
2021-11-01 16:00:02 +00:00
|
|
|
// This avoids intempestive tooltip display from the log toolbar button
|
2018-05-16 11:56:31 +00:00
|
|
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDCANCEL), TRUE);
|
2012-05-30 23:32:25 +00:00
|
|
|
return TRUE;
|
|
|
|
case IDC_LOG_CLEAR:
|
|
|
|
SetWindowTextA(hLog, "");
|
|
|
|
return TRUE;
|
|
|
|
case IDC_LOG_SAVE:
|
|
|
|
log_size = GetWindowTextLengthU(hLog);
|
2013-06-30 01:31:52 +00:00
|
|
|
if (log_size <= 0)
|
|
|
|
break;
|
|
|
|
log_buffer = (char*)malloc(log_size);
|
2012-05-30 23:32:25 +00:00
|
|
|
if (log_buffer != NULL) {
|
|
|
|
log_size = GetDlgItemTextU(hDlg, IDC_LOG_EDIT, log_buffer, log_size);
|
2013-06-06 22:40:37 +00:00
|
|
|
if (log_size != 0) {
|
|
|
|
log_size--; // remove NUL terminator
|
2021-07-28 15:37:45 +00:00
|
|
|
filepath = FileDialog(TRUE, user_dir, &log_ext, 0);
|
|
|
|
if (filepath != NULL)
|
2012-05-30 23:32:25 +00:00
|
|
|
FileIO(TRUE, filepath, &log_buffer, &log_size);
|
|
|
|
safe_free(filepath);
|
|
|
|
}
|
|
|
|
safe_free(log_buffer);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
|
|
ShowWindow(hDlg, SW_HIDE);
|
2013-10-15 21:58:27 +00:00
|
|
|
reset_localization(IDD_LOG);
|
2012-05-30 23:32:25 +00:00
|
|
|
log_displayed = FALSE;
|
2018-05-16 11:56:31 +00:00
|
|
|
// Set focus to the Cancel button on the main dialog
|
2021-11-01 16:00:02 +00:00
|
|
|
// This avoids intempestive tooltip display from the log toolbar button
|
2018-05-16 11:56:31 +00:00
|
|
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDCANCEL), TRUE);
|
2012-05-30 23:32:25 +00:00
|
|
|
return TRUE;
|
2018-03-22 23:14:20 +00:00
|
|
|
case UM_RESIZE_BUTTONS:
|
|
|
|
// Resize our buttons for low scaling factors
|
|
|
|
ResizeButtonHeight(hDlg, IDCANCEL);
|
|
|
|
ResizeButtonHeight(hDlg, IDC_LOG_SAVE);
|
|
|
|
ResizeButtonHeight(hDlg, IDC_LOG_CLEAR);
|
|
|
|
return TRUE;
|
2012-05-30 23:32:25 +00:00
|
|
|
}
|
2013-12-27 16:06:59 +00:00
|
|
|
return FALSE;
|
2012-05-30 23:32:25 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Timer in the right part of the status area
|
2011-12-08 12:14:21 +00:00
|
|
|
static void CALLBACK ClockTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
|
|
|
{
|
|
|
|
timer++;
|
2017-08-10 18:43:04 +00:00
|
|
|
static_sprintf(szTimer, "%02d:%02d:%02d", timer/3600, (timer%3600)/60, timer%60);
|
2015-06-30 22:22:10 +00:00
|
|
|
SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer);
|
2011-12-08 12:14:21 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Device Refresh Timer
|
2013-02-10 21:54:47 +00:00
|
|
|
static void CALLBACK RefreshTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
|
|
|
{
|
2014-02-09 02:54:07 +00:00
|
|
|
// DO NOT USE WM_DEVICECHANGE - IT MAY BE FILTERED OUT BY WINDOWS!
|
|
|
|
SendMessage(hWnd, UM_MEDIA_CHANGE, 0, 0);
|
2013-02-10 21:54:47 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Detect and notify about a blocking operation during ISO extraction cancellation
|
2012-02-07 16:17:14 +00:00
|
|
|
static void CALLBACK BlockingTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
|
|
|
{
|
|
|
|
if (iso_blocking_status < 0) {
|
|
|
|
KillTimer(hMainDialog, TID_BLOCKING_TIMER);
|
|
|
|
user_notified = FALSE;
|
|
|
|
uprintf("Killed blocking I/O timer\n");
|
|
|
|
} else if(!user_notified) {
|
|
|
|
if (last_iso_blocking_status == iso_blocking_status) {
|
2014-01-24 02:46:06 +00:00
|
|
|
// A write or close operation hasn't made any progress since our last check
|
|
|
|
user_notified = TRUE;
|
|
|
|
uprintf("Blocking I/O operation detected\n");
|
2015-10-18 20:31:47 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_080), lmprintf(MSG_048),
|
|
|
|
MB_OK|MB_ICONINFORMATION|MB_IS_RTL, selected_langid);
|
2012-02-07 16:17:14 +00:00
|
|
|
} else {
|
|
|
|
last_iso_blocking_status = iso_blocking_status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-14 23:40:00 +00:00
|
|
|
// Report the features of the selected ISO images
|
2016-02-22 12:51:27 +00:00
|
|
|
#define PRINT_ISO_PROP(b, ...) do {if (b) uprintf(__VA_ARGS__);} while(0)
|
2014-11-14 23:40:00 +00:00
|
|
|
static void DisplayISOProps(void)
|
|
|
|
{
|
2019-01-31 13:50:03 +00:00
|
|
|
static char inst_str[] = " [1/#]";
|
2014-11-14 23:40:00 +00:00
|
|
|
int i;
|
|
|
|
|
2015-09-02 22:20:00 +00:00
|
|
|
uprintf("ISO label: '%s'", img_report.label);
|
2021-10-08 10:14:29 +00:00
|
|
|
if (img_report.win_version.major != 0) {
|
|
|
|
if (img_report.win_version.minor == 0)
|
|
|
|
uprintf(" Detected: Windows %d ISO (Build %d.%d)", img_report.win_version.major,
|
|
|
|
img_report.win_version.build, img_report.win_version.revision);
|
|
|
|
else
|
|
|
|
uprintf(" Detected: Windows %d.%d ISO (Build %d.%d)", img_report.win_version.major,
|
|
|
|
img_report.win_version.minor, img_report.win_version.build, img_report.win_version.revision);
|
|
|
|
}
|
|
|
|
|
2017-05-01 15:22:34 +00:00
|
|
|
uprintf(" Size: %s (Projected)", SizeToHumanReadable(img_report.projected_size, FALSE, FALSE));
|
2017-06-24 16:23:06 +00:00
|
|
|
if (img_report.mismatch_size > 0) {
|
|
|
|
uprintf(" ERROR: Detected that file on disk has been truncated by %s!",
|
|
|
|
SizeToHumanReadable(img_report.mismatch_size, FALSE, FALSE));
|
2017-07-29 16:34:11 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_298, SizeToHumanReadable(img_report.mismatch_size, FALSE, FALSE)),
|
|
|
|
lmprintf(MSG_297), MB_ICONWARNING | MB_IS_RTL, selected_langid);
|
2017-06-24 16:23:06 +00:00
|
|
|
} else if (img_report.mismatch_size < 0) {
|
|
|
|
// Not an error (ISOHybrid?), but we report it just in case
|
|
|
|
uprintf(" Note: File on disk is larger than reported ISO size by %s...",
|
|
|
|
SizeToHumanReadable(-img_report.mismatch_size, FALSE, FALSE));
|
|
|
|
}
|
|
|
|
|
2016-02-22 12:51:27 +00:00
|
|
|
PRINT_ISO_PROP(img_report.has_4GB_file, " Has a >4GB file");
|
|
|
|
PRINT_ISO_PROP(img_report.has_long_filename, " Has a >64 chars filename");
|
2020-05-29 11:21:56 +00:00
|
|
|
PRINT_ISO_PROP(img_report.has_deep_directories, " Has a Rock Ridge deep directory");
|
2016-02-22 12:51:27 +00:00
|
|
|
PRINT_ISO_PROP(HAS_SYSLINUX(img_report), " Uses: Syslinux/Isolinux v%s", img_report.sl_version_str);
|
2015-09-02 22:20:00 +00:00
|
|
|
if (HAS_SYSLINUX(img_report) && (SL_MAJOR(img_report.sl_version) < 5)) {
|
2014-11-14 23:40:00 +00:00
|
|
|
for (i = 0; i<NB_OLD_C32; i++) {
|
2016-02-22 12:51:27 +00:00
|
|
|
PRINT_ISO_PROP(img_report.has_old_c32[i], " With an old %s", old_c32_name[i]);
|
2014-11-14 23:40:00 +00:00
|
|
|
}
|
|
|
|
}
|
2016-12-14 23:27:04 +00:00
|
|
|
PRINT_ISO_PROP(HAS_KOLIBRIOS(img_report), " Uses: KolibriOS");
|
|
|
|
PRINT_ISO_PROP(HAS_REACTOS(img_report), " Uses: ReactOS");
|
2016-02-22 12:51:27 +00:00
|
|
|
PRINT_ISO_PROP(img_report.has_grub4dos, " Uses: Grub4DOS");
|
|
|
|
PRINT_ISO_PROP(img_report.has_grub2, " Uses: GRUB2");
|
2017-08-09 15:27:11 +00:00
|
|
|
if (img_report.has_efi == 0x80)
|
|
|
|
uprintf(" Uses: EFI (through '%s')", img_report.efi_img_path);
|
|
|
|
else
|
|
|
|
PRINT_ISO_PROP(img_report.has_efi, " Uses: EFI %s", HAS_WIN7_EFI(img_report) ? "(win7_x64)" : "");
|
2018-09-14 13:10:40 +00:00
|
|
|
PRINT_ISO_PROP(HAS_BOOTMGR(img_report), " Uses: Bootmgr (%s)",
|
|
|
|
HAS_BOOTMGR_BIOS(img_report) ? (HAS_BOOTMGR_EFI(img_report) ? "BIOS and UEFI" : "BIOS only") : "UEFI only");
|
2016-12-14 23:27:04 +00:00
|
|
|
PRINT_ISO_PROP(HAS_WINPE(img_report), " Uses: WinPE %s", (img_report.uses_minint) ? "(with /minint)" : "");
|
2019-01-08 18:30:07 +00:00
|
|
|
if (HAS_WININST(img_report)) {
|
2019-01-31 13:50:03 +00:00
|
|
|
inst_str[4] = '0' + img_report.wininst_index;
|
2022-01-05 11:57:26 +00:00
|
|
|
assert(strlen(img_report.wininst_path[0]) >= 3);
|
2019-01-08 18:30:07 +00:00
|
|
|
uprintf(" Uses: Install.%s%s (version %d.%d.%d%s)", &img_report.wininst_path[0][strlen(img_report.wininst_path[0]) - 3],
|
|
|
|
(img_report.wininst_index > 1) ? inst_str : "", (img_report.wininst_version >> 24) & 0xff,
|
|
|
|
(img_report.wininst_version >> 16) & 0xff, (img_report.wininst_version >> 8) & 0xff,
|
|
|
|
(img_report.wininst_version >= SPECIAL_WIM_VERSION) ? "+": "");
|
2015-08-27 17:22:27 +00:00
|
|
|
}
|
2020-02-05 13:23:49 +00:00
|
|
|
PRINT_ISO_PROP(img_report.has_symlinks,
|
2020-10-12 18:33:54 +00:00
|
|
|
" Note: This ISO uses symbolic links, which will not be replicated due to file system");
|
2020-02-05 13:23:49 +00:00
|
|
|
PRINT_ISO_PROP((img_report.has_symlinks == SYMLINKS_RR),
|
2020-10-12 18:33:54 +00:00
|
|
|
" limitations. Because of this, some features from this image may not work...");
|
2020-02-05 13:23:49 +00:00
|
|
|
PRINT_ISO_PROP((img_report.has_symlinks == SYMLINKS_UDF),
|
2020-10-12 18:33:54 +00:00
|
|
|
" limitations. Because of this, the size required for the target media may be much\r\n"
|
|
|
|
" larger than size of the ISO...");
|
2018-03-22 23:14:20 +00:00
|
|
|
}
|
|
|
|
|
2020-07-19 21:35:30 +00:00
|
|
|
// Insert the image name into the Boot selection dropdown and (re)populate the Image option dropdown
|
|
|
|
static void UpdateImage(BOOL update_image_option_only)
|
2018-03-22 23:14:20 +00:00
|
|
|
{
|
2018-10-30 16:14:07 +00:00
|
|
|
assert(image_index != 0);
|
2018-03-22 23:14:20 +00:00
|
|
|
|
2020-07-19 21:35:30 +00:00
|
|
|
if (!update_image_option_only) {
|
|
|
|
if (ComboBox_GetItemData(hBootType, image_index) == BT_IMAGE)
|
|
|
|
ComboBox_DeleteString(hBootType, image_index);
|
|
|
|
ComboBox_InsertStringU(hBootType, image_index,
|
|
|
|
(image_path == NULL) ? lmprintf(MSG_281, lmprintf(MSG_280)) : short_image_path);
|
|
|
|
ComboBox_SetItemData(hBootType, image_index, BT_IMAGE);
|
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, image_index));
|
|
|
|
boot_type = (int)ComboBox_GetCurItemData(hBootType);
|
|
|
|
SetBootTypeDropdownWidth();
|
|
|
|
}
|
|
|
|
|
|
|
|
ComboBox_ResetContent(hImageOption);
|
2021-10-08 18:22:33 +00:00
|
|
|
|
2022-06-23 12:34:24 +00:00
|
|
|
if (!img_report.is_windows_img) // Straight install.wim/install.esd only have Windows To Go option
|
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_117)), IMOP_WIN_STANDARD));
|
2021-10-08 18:22:33 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hImageOption, ComboBox_AddStringU(hImageOption, lmprintf(MSG_118)), IMOP_WIN_TO_GO));
|
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hImageOption, imop_win_sel));
|
2020-07-19 21:35:30 +00:00
|
|
|
}
|
|
|
|
|
2022-07-25 12:18:14 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Parse a PE executable file and return its CPU architecture.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="path">The path of the PE executable to parse.</param>
|
|
|
|
/// <returns>An enum ArchType value (as defined in rufus.h)</returns>
|
|
|
|
static uint8_t FindArch(const char* path)
|
2020-07-19 21:35:30 +00:00
|
|
|
{
|
2022-06-23 12:34:24 +00:00
|
|
|
uint8_t ret = ARCH_UNKNOWN;
|
2020-07-19 21:35:30 +00:00
|
|
|
HANDLE hFile = NULL, hFileMapping = NULL;
|
|
|
|
PIMAGE_DOS_HEADER pImageDOSHeader = NULL;
|
|
|
|
// NB: The field we are after is at the same location for 32 and 64-bit
|
|
|
|
// PE headers, so we don't need to care about using PIMAGE_NT_HEADERS[32|64]
|
|
|
|
PIMAGE_NT_HEADERS pImageNTHeader = NULL;
|
|
|
|
|
2022-07-25 12:18:14 +00:00
|
|
|
hFile = CreateFileU(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
2020-07-19 21:35:30 +00:00
|
|
|
if (hFile == NULL) {
|
2022-07-25 12:18:14 +00:00
|
|
|
uprintf("FindArch: Could not open file '%s': %s", path, WindowsErrorString());
|
2020-07-19 21:35:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
|
|
if (hFileMapping == NULL) {
|
|
|
|
uprintf("FindArch: Could not create file mapping: %s", WindowsErrorString());
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
pImageDOSHeader = (PIMAGE_DOS_HEADER)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if (pImageDOSHeader == NULL) {
|
|
|
|
uprintf("FindArch: Could not get mapped view address: %s", WindowsErrorString());
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (pImageDOSHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
|
|
|
uprintf("FindArch: DOS header not found");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
pImageNTHeader = (PIMAGE_NT_HEADERS)((uintptr_t)pImageDOSHeader + pImageDOSHeader->e_lfanew);
|
|
|
|
if (pImageNTHeader->Signature != IMAGE_NT_SIGNATURE) {
|
|
|
|
uprintf("FindArch: NT header not found");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (pImageNTHeader->FileHeader.Machine) {
|
|
|
|
case IMAGE_FILE_MACHINE_I386:
|
2022-06-23 12:34:24 +00:00
|
|
|
ret = ARCH_X86_32;
|
2020-07-19 21:35:30 +00:00
|
|
|
break;
|
|
|
|
case IMAGE_FILE_MACHINE_AMD64:
|
2022-06-23 12:34:24 +00:00
|
|
|
ret = ARCH_X86_64;
|
2020-07-19 21:35:30 +00:00
|
|
|
break;
|
|
|
|
case IMAGE_FILE_MACHINE_ARM:
|
2022-06-23 12:34:24 +00:00
|
|
|
ret = ARCH_ARM_32;
|
2020-07-19 21:35:30 +00:00
|
|
|
break;
|
|
|
|
case IMAGE_FILE_MACHINE_ARM64:
|
2022-06-23 12:34:24 +00:00
|
|
|
ret = ARCH_ARM_64;
|
2020-07-19 21:35:30 +00:00
|
|
|
break;
|
2022-06-23 12:34:24 +00:00
|
|
|
case IMAGE_FILE_MACHINE_IA64:
|
|
|
|
ret = ARCH_IA_64;
|
2020-07-19 21:35:30 +00:00
|
|
|
break;
|
2020-07-29 18:32:32 +00:00
|
|
|
case IMAGE_FILE_MACHINE_RISCV32:
|
2022-06-23 12:34:24 +00:00
|
|
|
ret = ARCH_RISCV_32;
|
2020-07-29 18:32:32 +00:00
|
|
|
break;
|
|
|
|
case IMAGE_FILE_MACHINE_RISCV64:
|
2022-06-23 12:34:24 +00:00
|
|
|
ret = ARCH_RISCV_64;
|
2020-07-29 18:32:32 +00:00
|
|
|
break;
|
|
|
|
case IMAGE_FILE_MACHINE_RISCV128:
|
2022-06-23 12:34:24 +00:00
|
|
|
ret = ARCH_RISCV_128;
|
|
|
|
break;
|
|
|
|
case IMAGE_FILE_MACHINE_EBC:
|
|
|
|
ret = ARCH_EBC;
|
2020-07-29 18:32:32 +00:00
|
|
|
break;
|
2020-07-19 21:35:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (pImageDOSHeader != NULL)
|
|
|
|
UnmapViewOfFile(pImageDOSHeader);
|
|
|
|
safe_closehandle(hFileMapping);
|
|
|
|
safe_closehandle(hFile);
|
2022-06-23 12:34:24 +00:00
|
|
|
assert(ret < ARCH_MAX);
|
2020-07-19 21:35:30 +00:00
|
|
|
return ret;
|
2014-11-14 23:40:00 +00:00
|
|
|
}
|
|
|
|
|
2012-02-01 14:26:36 +00:00
|
|
|
// The scanning process can be blocking for message processing => use a thread
|
2020-07-19 21:35:30 +00:00
|
|
|
DWORD WINAPI ImageScanThread(LPVOID param)
|
2012-02-01 14:26:36 +00:00
|
|
|
{
|
2021-10-11 16:55:46 +00:00
|
|
|
// Regexp patterns used to match ISO labels for the Red Hat 8 derivatives
|
|
|
|
// where we should apply an inst.stage2 ➔ inst.repo workaround for ISO
|
|
|
|
// mode (per: https://github.com/rhinstaller/anaconda/pull/3529).
|
|
|
|
const char* redhat8_derivative[] = {
|
2022-06-07 15:19:47 +00:00
|
|
|
"^AlmaLinux-[8-9].*", // AlmaLinux 8.x and 9.x
|
|
|
|
"^Fedora.*-3[3-9].*", // Fedora 33-39
|
|
|
|
"^CentOS.*-[8-9].*", // CentOS and CentOS Stream 8.and 9.x
|
|
|
|
"^OL-[8-9].*", // Oracle Linux 8.x and 9.x
|
|
|
|
"^RHEL-[8-9].*", // Red Hat 8.x and 9.x
|
|
|
|
"^Rocky-[8-9].*", // Rocky Linux 8.x and 9.x
|
|
|
|
"^MIRACLE-LINUX-[8-9].*", // MIRACLE LINUX 8.x and 9.x
|
2021-10-11 16:55:46 +00:00
|
|
|
};
|
|
|
|
int i, len;
|
2020-07-19 21:35:30 +00:00
|
|
|
uint8_t arch;
|
2022-10-04 10:58:30 +00:00
|
|
|
char tmp_path[MAX_PATH], tmp_str[64];
|
2012-02-07 16:17:14 +00:00
|
|
|
|
2022-11-16 16:50:53 +00:00
|
|
|
// We may mount an ISO during the lookup of the Windows version, which
|
|
|
|
// produces DBT_DEVNODES_CHANGED messages that lead to unwanted device
|
|
|
|
// refreshes. So make sure to ignore DBT_DEVNODES_CHANGED while scanning.
|
|
|
|
dont_process_dbt_devnodes = TRUE;
|
2014-05-22 00:52:25 +00:00
|
|
|
if (image_path == NULL)
|
2012-02-07 16:17:14 +00:00
|
|
|
goto out;
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfoDebug(0, MSG_202);
|
2013-12-28 01:27:09 +00:00
|
|
|
user_notified = FALSE;
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(FALSE, FALSE);
|
2017-05-01 15:22:34 +00:00
|
|
|
memset(&img_report, 0, sizeof(img_report));
|
2015-09-04 12:53:35 +00:00
|
|
|
img_report.is_iso = (BOOLEAN)ExtractISO(image_path, "", TRUE);
|
2020-11-12 17:38:20 +00:00
|
|
|
img_report.is_bootable_img = IsBootableImage(image_path);
|
2022-10-04 10:58:30 +00:00
|
|
|
if (img_report.wininst_index > 0 || img_report.is_windows_img)
|
|
|
|
PopulateWindowsVersion();
|
2020-07-19 21:35:30 +00:00
|
|
|
ComboBox_ResetContent(hImageOption);
|
2021-10-08 18:22:33 +00:00
|
|
|
imop_win_sel = 0;
|
2017-05-01 15:22:34 +00:00
|
|
|
|
2018-09-13 10:49:51 +00:00
|
|
|
if ((FormatStatus == (ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_CANCELLED)) ||
|
2020-07-19 21:35:30 +00:00
|
|
|
(img_report.image_size == 0) ||
|
2022-01-07 13:25:46 +00:00
|
|
|
(!img_report.is_iso && (img_report.is_bootable_img <= 0) && !img_report.is_windows_img)) {
|
2016-02-06 23:46:30 +00:00
|
|
|
// Failed to scan image
|
2022-04-15 10:43:22 +00:00
|
|
|
if (img_report.is_bootable_img < 0)
|
2022-06-23 12:34:24 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_322, image_path), lmprintf(MSG_042), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid);
|
2022-04-15 10:43:22 +00:00
|
|
|
else
|
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_082), lmprintf(MSG_081), MB_OK | MB_ICONINFORMATION | MB_IS_RTL, selected_langid);
|
|
|
|
// Make sure to relinquish image_path before we call UpdateImage
|
|
|
|
// otherwise the boot selection dropdown won't be properly reset.
|
|
|
|
safe_free(image_path);
|
2015-01-01 23:39:28 +00:00
|
|
|
SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0);
|
2020-07-19 21:35:30 +00:00
|
|
|
UpdateImage(FALSE);
|
2015-02-11 23:22:18 +00:00
|
|
|
SetMBRProps();
|
2018-05-06 21:31:42 +00:00
|
|
|
PopulateProperties();
|
2018-03-22 23:14:20 +00:00
|
|
|
PrintInfoDebug(0, MSG_203);
|
|
|
|
PrintStatus(0, MSG_203);
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
2012-02-07 02:05:58 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2014-02-09 02:54:07 +00:00
|
|
|
|
2020-07-19 21:35:30 +00:00
|
|
|
if (img_report.is_windows_img) {
|
|
|
|
selection_default = BT_IMAGE;
|
2020-07-29 18:32:32 +00:00
|
|
|
// coverity[swapped_arguments]
|
2020-07-19 21:35:30 +00:00
|
|
|
if (GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, tmp_path) != 0) {
|
|
|
|
// Only look at index 1 for now. If people complain, we may look for more.
|
|
|
|
if (WimExtractFile(image_path, 1, "Windows\\Boot\\EFI\\bootmgr.efi", tmp_path, TRUE)) {
|
|
|
|
arch = FindArch(tmp_path);
|
|
|
|
if (arch != 0) {
|
2022-06-23 12:34:24 +00:00
|
|
|
uprintf(" Image contains a%s %s EFI boot manager",
|
|
|
|
(arch >= ARCH_RISCV_32 && arch <= ARCH_RISCV_128) ? "" : "n", arch_name[arch]);
|
2020-07-19 21:35:30 +00:00
|
|
|
img_report.has_efi = 1 | (1 << arch);
|
|
|
|
img_report.has_bootmgr_efi = TRUE;
|
|
|
|
img_report.wininst_index = 1;
|
|
|
|
} else {
|
|
|
|
uprintf(" Image does not contain an EFI boot manager");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DeleteFileU(tmp_path);
|
|
|
|
}
|
2022-10-04 10:58:30 +00:00
|
|
|
tmp_str[0] = 0;
|
|
|
|
if (img_report.win_version.major != 0) {
|
|
|
|
if (img_report.win_version.minor == 0)
|
|
|
|
static_sprintf(tmp_str, " %d (Build %d.%d)", img_report.win_version.major,
|
|
|
|
img_report.win_version.build, img_report.win_version.revision);
|
|
|
|
else
|
|
|
|
static_sprintf(tmp_str, " %d.%d (Build %d.%d)", img_report.win_version.major,
|
|
|
|
img_report.win_version.minor, img_report.win_version.build, img_report.win_version.revision);
|
|
|
|
}
|
|
|
|
uprintf(" Image is a %sUEFI bootable Windows%s installation image", img_report.has_efi ? "" : "NON-", tmp_str);
|
2022-01-07 13:25:46 +00:00
|
|
|
} else if (IS_DD_BOOTABLE(img_report)) {
|
2020-11-12 17:38:20 +00:00
|
|
|
if (img_report.is_bootable_img == 2)
|
|
|
|
uprintf(" Image is a FORCED non-bootable image");
|
|
|
|
else
|
|
|
|
uprintf(" Image is a %sbootable %s image",
|
|
|
|
(img_report.compression_type != BLED_COMPRESSION_NONE) ? "compressed " : "", img_report.is_vhd ? "VHD" : "disk");
|
2018-03-22 23:14:20 +00:00
|
|
|
selection_default = BT_IMAGE;
|
2015-08-22 14:18:25 +00:00
|
|
|
}
|
2016-02-06 23:46:30 +00:00
|
|
|
|
2015-09-02 22:20:00 +00:00
|
|
|
if (img_report.is_iso) {
|
2014-11-14 23:40:00 +00:00
|
|
|
DisplayISOProps();
|
[ui] add forced DD mode exceptions for Red Hat based distros
* Anaconda broke ISO compatibility, most likely with the following commit:
https://github.com/rhinstaller/anaconda/commit/84529204fe02300b9829da41099a8254dc2a1c54
* However, Ret Hat, and its followers, have drunk the "DD only" kool aid, and
appear to be blissfully unaware of the very real drawbacks that enforcing a
"DD only" mode for ISOHybrid can actually place on distro users.
* Rather than spend another wasted effort trying get people, who appear to be
impervious to even remotely consider the idea that DD imaging can have flaws,
to look into the possibility that Red Hat might indeed have introduced a
regression, and given the downright hostility I have been subjected to from
trying to state this *very verifiable* fact, we'll just force DD mode for the
affected Red Hat and derivatives, whilst trusting that users will be smart
enough to compare their more limited installation experience against the ones
from other distros (such as Arch, Debian or Ubuntu, which, unlike Red Hat and
co., appear to fully understand that the whole ISOHybrid vs DD mode situation
is not all black and white), and see for themselves which distros do actually
place *their* interests first, rather than just the interests of the distro
maintainers...
2021-04-23 16:04:55 +00:00
|
|
|
|
2021-10-11 16:55:46 +00:00
|
|
|
for (i = 0; i < ARRAYSIZE(redhat8_derivative); i++) {
|
|
|
|
if (re_match(redhat8_derivative[i], img_report.label, &len) >= 0) {
|
|
|
|
img_report.rh8_derivative = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-06 23:46:30 +00:00
|
|
|
// If we have an ISOHybrid, but without an ISO method we support, disable ISO support altogether
|
2019-07-03 22:07:24 +00:00
|
|
|
if (IS_DD_BOOTABLE(img_report) && (img_report.disable_iso ||
|
|
|
|
(!IS_BIOS_BOOTABLE(img_report) && !IS_EFI_BOOTABLE(img_report)))) {
|
2021-03-31 12:21:11 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_321), lmprintf(MSG_274, "ISOHybrid"),
|
|
|
|
MB_OK | MB_ICONINFORMATION | MB_IS_RTL, selected_langid);
|
2021-03-25 20:49:45 +00:00
|
|
|
uprintf("Note: DD image mode enforced since this ISOHybrid is not ISO mode compatible.");
|
2016-02-06 23:46:30 +00:00
|
|
|
img_report.is_iso = FALSE;
|
|
|
|
}
|
2018-03-22 23:14:20 +00:00
|
|
|
selection_default = BT_IMAGE;
|
2012-12-15 03:27:14 +00:00
|
|
|
}
|
2016-12-14 23:27:04 +00:00
|
|
|
if (!IS_DD_BOOTABLE(img_report) && !IS_BIOS_BOOTABLE(img_report) && !IS_EFI_BOOTABLE(img_report)) {
|
2016-02-06 23:46:30 +00:00
|
|
|
// No boot method that we support
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_081);
|
2014-05-22 00:52:25 +00:00
|
|
|
safe_free(image_path);
|
2018-03-22 23:14:20 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_082), lmprintf(MSG_081), MB_OK | MB_ICONINFORMATION | MB_IS_RTL, selected_langid);
|
2015-01-08 00:22:56 +00:00
|
|
|
PrintStatus(0, MSG_086);
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
2012-05-16 22:38:39 +00:00
|
|
|
SetMBRProps();
|
2014-02-09 02:54:07 +00:00
|
|
|
} else {
|
2018-03-22 23:14:20 +00:00
|
|
|
if (!dont_display_image_name) {
|
|
|
|
for (i = (int)safe_strlen(image_path); (i > 0) && (image_path[i] != '\\'); i--);
|
2018-10-22 21:28:20 +00:00
|
|
|
if (i != 0)
|
|
|
|
i++;
|
|
|
|
short_image_path = &image_path[i];
|
2018-03-22 23:14:20 +00:00
|
|
|
PrintStatus(0, MSG_205, short_image_path);
|
|
|
|
uprintf("Using image: %s (%s)", short_image_path, SizeToHumanReadable(img_report.image_size, FALSE, FALSE));
|
|
|
|
}
|
2020-07-19 21:35:30 +00:00
|
|
|
UpdateImage(dont_display_image_name);
|
2018-07-18 11:22:37 +00:00
|
|
|
ToggleImageOptions();
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
2018-03-22 23:14:20 +00:00
|
|
|
// Set Target and FS accordingly
|
2020-07-19 21:35:30 +00:00
|
|
|
if (img_report.is_iso || img_report.is_windows_img) {
|
2018-03-22 23:14:20 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, image_index));
|
|
|
|
SetPartitionSchemeAndTargetSystem(FALSE);
|
|
|
|
SetFileSystemAndClusterSize(NULL);
|
2014-02-09 02:54:07 +00:00
|
|
|
SetFSFromISO();
|
|
|
|
SetMBRProps();
|
2016-01-09 05:06:45 +00:00
|
|
|
SetProposedLabel(ComboBox_GetCurSel(hDeviceList));
|
2014-02-09 02:54:07 +00:00
|
|
|
} else {
|
2018-05-06 21:31:42 +00:00
|
|
|
SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE_INTERNAL<<16) | IDC_FILE_SYSTEM,
|
2014-02-09 02:54:07 +00:00
|
|
|
ComboBox_GetCurSel(hFileSystem));
|
|
|
|
}
|
2012-02-16 11:37:59 +00:00
|
|
|
// Lose the focus on the select ISO (but place it on Close)
|
2015-04-19 03:15:44 +00:00
|
|
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)FALSE, 0);
|
2012-02-16 11:37:59 +00:00
|
|
|
// Lose the focus from Close and set it back to Start
|
2015-04-19 03:15:44 +00:00
|
|
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)hStart, TRUE);
|
2012-02-07 02:05:58 +00:00
|
|
|
}
|
2015-10-18 20:31:47 +00:00
|
|
|
|
2015-01-13 02:11:57 +00:00
|
|
|
// Need to invalidate as we may have changed the UI and may get artifacts if we don't
|
2015-02-10 22:45:48 +00:00
|
|
|
// Oh and we need to invoke BOTH RedrawWindow() and InvalidateRect() because UI refresh
|
|
|
|
// in the Microsoft worlds SUCKS!!!! (we may lose the disabled "Start" button otherwise)
|
|
|
|
RedrawWindow(hMainDialog, NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
|
2015-01-13 02:11:57 +00:00
|
|
|
InvalidateRect(hMainDialog, NULL, TRUE);
|
2012-02-07 02:05:58 +00:00
|
|
|
|
|
|
|
out:
|
2015-08-14 22:09:45 +00:00
|
|
|
dont_display_image_name = FALSE;
|
2022-11-16 16:50:53 +00:00
|
|
|
dont_process_dbt_devnodes = FALSE;
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_210);
|
2012-02-07 02:05:58 +00:00
|
|
|
ExitThread(0);
|
2012-02-01 14:26:36 +00:00
|
|
|
}
|
|
|
|
|
2022-06-24 13:27:02 +00:00
|
|
|
#define MAP_BIT(bit) do { map[_log2(bit)] = b; b <<= 1; } while(0)
|
|
|
|
|
2018-07-04 21:50:26 +00:00
|
|
|
// Likewise, boot check will block message processing => use a thread
|
2018-07-03 21:54:06 +00:00
|
|
|
static DWORD WINAPI BootCheckThread(LPVOID param)
|
2013-01-25 01:38:10 +00:00
|
|
|
{
|
2022-10-18 12:58:38 +00:00
|
|
|
int i, r, username_index = -1;
|
2014-08-05 23:57:32 +00:00
|
|
|
FILE *fd;
|
2014-02-04 20:01:28 +00:00
|
|
|
DWORD len;
|
2020-02-03 12:35:49 +00:00
|
|
|
WPARAM ret = BOOTCHECK_CANCEL;
|
2021-04-08 16:29:13 +00:00
|
|
|
BOOL in_files_dir = FALSE, esp_already_asked = FALSE;
|
2022-07-05 13:08:26 +00:00
|
|
|
BOOL is_windows_to_go = ((image_options & IMOP_WINTOGO) && (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO));
|
2014-12-30 19:46:13 +00:00
|
|
|
const char* grub = "grub";
|
|
|
|
const char* core_img = "core.img";
|
2014-01-21 17:08:41 +00:00
|
|
|
const char* ldlinux = "ldlinux";
|
|
|
|
const char* syslinux = "syslinux";
|
|
|
|
const char* ldlinux_ext[3] = { "sys", "bss", "c32" };
|
2014-08-05 23:57:32 +00:00
|
|
|
char tmp[MAX_PATH], tmp2[MAX_PATH];
|
2013-01-25 01:38:10 +00:00
|
|
|
|
2014-01-21 17:08:41 +00:00
|
|
|
syslinux_ldlinux_len[0] = 0; syslinux_ldlinux_len[1] = 0;
|
2014-12-30 19:46:13 +00:00
|
|
|
safe_free(grub2_buf);
|
2018-07-03 21:54:06 +00:00
|
|
|
|
|
|
|
if (ComboBox_GetCurSel(hDeviceList) == CB_ERR)
|
|
|
|
goto out;
|
|
|
|
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((zero_drive) || (boot_type == BT_NON_BOOTABLE)) {
|
2018-07-03 21:54:06 +00:00
|
|
|
// Nothing to check
|
2020-02-03 12:35:49 +00:00
|
|
|
ret = BOOTCHECK_PROCEED;
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2019-04-13 14:29:27 +00:00
|
|
|
if (boot_type == BT_IMAGE) {
|
2018-06-30 21:45:15 +00:00
|
|
|
assert(image_path != NULL);
|
|
|
|
if (image_path == NULL)
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2015-09-02 22:20:00 +00:00
|
|
|
if ((size_check) && (img_report.projected_size > (uint64_t)SelectedDrive.DiskSize)) {
|
2013-10-31 22:59:53 +00:00
|
|
|
// This ISO image is too big for the selected target
|
2015-10-18 20:31:47 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_089), lmprintf(MSG_088), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2013-01-25 01:38:10 +00:00
|
|
|
}
|
2021-03-25 19:52:33 +00:00
|
|
|
if (IS_DD_BOOTABLE(img_report)) {
|
|
|
|
if (!img_report.is_iso) {
|
|
|
|
// Pure DD images are fine at this stage
|
|
|
|
write_as_image = TRUE;
|
|
|
|
} else if (persistence_size == 0) {
|
|
|
|
// Ask users how they want to write ISOHybrid images,
|
|
|
|
// but only do so if persistence has not been selected.
|
|
|
|
char* iso_image = lmprintf(MSG_036);
|
|
|
|
char* dd_image = lmprintf(MSG_095);
|
|
|
|
// If the ISO is small enough to be written as an ESP and we are using GPT add the ISO → ESP option
|
|
|
|
if ((img_report.projected_size < MAX_ISO_TO_ESP_SIZE * MB) && HAS_REGULAR_EFI(img_report) &&
|
|
|
|
(partition_type == PARTITION_STYLE_GPT) && IS_FAT(fs_type)) {
|
|
|
|
char* choices[3] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, "ISO → ESP"), lmprintf(MSG_277, dd_image) };
|
2022-10-18 12:58:38 +00:00
|
|
|
i = SelectionDialog(lmprintf(MSG_274, "ISOHybrid"), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), choices, 3);
|
2021-03-25 19:52:33 +00:00
|
|
|
if (i < 0) // Cancel
|
|
|
|
goto out;
|
2022-06-20 12:47:43 +00:00
|
|
|
write_as_esp = (i & 2);
|
|
|
|
write_as_image = (i & 4);
|
2021-04-08 16:29:13 +00:00
|
|
|
esp_already_asked = TRUE;
|
2021-03-25 19:52:33 +00:00
|
|
|
} else {
|
|
|
|
char* choices[2] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, dd_image) };
|
2022-10-18 12:58:38 +00:00
|
|
|
i = SelectionDialog(lmprintf(MSG_274, "ISOHybrid"), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), choices, 2);
|
2021-03-25 19:52:33 +00:00
|
|
|
if (i < 0) // Cancel
|
|
|
|
goto out;
|
2022-06-20 12:47:43 +00:00
|
|
|
write_as_image = (i & 2);
|
2021-03-25 19:52:33 +00:00
|
|
|
}
|
|
|
|
}
|
2014-02-09 02:54:07 +00:00
|
|
|
}
|
2021-03-25 19:52:33 +00:00
|
|
|
|
|
|
|
if (write_as_image) {
|
|
|
|
ret = BOOTCHECK_PROCEED;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2022-07-05 13:08:26 +00:00
|
|
|
if (is_windows_to_go) {
|
2019-04-13 14:29:27 +00:00
|
|
|
if (fs_type != FS_NTFS) {
|
2015-01-16 01:51:24 +00:00
|
|
|
// Windows To Go only works for NTFS
|
2015-10-18 20:31:47 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_097, "Windows To Go"), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2017-04-19 10:30:24 +00:00
|
|
|
}
|
|
|
|
if (SelectedDrive.MediaType != FixedMedia) {
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((target_type == TT_UEFI) && (partition_type == PARTITION_STYLE_GPT) && (nWindowsBuildNumber < 15000)) {
|
2019-09-14 22:33:46 +00:00
|
|
|
// Up to Windows 10 Creators Update (1703), we were screwed, since we need access to 2 partitions at the same time.
|
2017-04-19 10:30:24 +00:00
|
|
|
// Thankfully, the newer Windows allow mounting multiple partitions on the same REMOVABLE drive.
|
2015-10-18 20:31:47 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_198), lmprintf(MSG_190), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2015-01-20 21:50:24 +00:00
|
|
|
}
|
2015-01-16 01:51:24 +00:00
|
|
|
}
|
2016-12-15 12:04:19 +00:00
|
|
|
// If multiple versions are available, asks the user to select one before we commit to format the drive
|
2017-05-01 23:21:14 +00:00
|
|
|
switch(SetWinToGoIndex()) {
|
|
|
|
case -1:
|
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_073), lmprintf(MSG_291), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid);
|
|
|
|
// fall through
|
|
|
|
case -2:
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2017-05-01 23:21:14 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2022-07-27 10:49:26 +00:00
|
|
|
if ((nWindowsVersion >= WINDOWS_8) && IS_WINDOWS_1X(img_report)) {
|
2022-06-23 12:34:24 +00:00
|
|
|
StrArray options;
|
|
|
|
int arch = _log2(img_report.has_efi >> 1);
|
2022-06-24 13:27:02 +00:00
|
|
|
uint8_t map[8] = { 0 }, b = 1;
|
|
|
|
StrArrayCreate(&options, 2);
|
2022-10-18 12:58:38 +00:00
|
|
|
StrArrayAdd(&options, lmprintf(MSG_332), TRUE);
|
|
|
|
MAP_BIT(UNATTEND_OFFLINE_INTERNAL_DRIVES);
|
2022-06-24 13:27:02 +00:00
|
|
|
if (img_report.win_version.build >= 22500) {
|
|
|
|
StrArrayAdd(&options, lmprintf(MSG_330), TRUE);
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
MAP_BIT(UNATTEND_NO_ONLINE_ACCOUNT);
|
2022-06-24 13:27:02 +00:00
|
|
|
}
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
StrArrayAdd(&options, lmprintf(MSG_333), TRUE);
|
2022-10-18 12:58:38 +00:00
|
|
|
username_index = _log2(b);
|
|
|
|
MAP_BIT(UNATTEND_SET_USER);
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
StrArrayAdd(&options, lmprintf(MSG_334), TRUE);
|
|
|
|
MAP_BIT(UNATTEND_DUPLICATE_LOCALE);
|
2022-10-18 12:58:38 +00:00
|
|
|
StrArrayAdd(&options, lmprintf(MSG_331), TRUE);
|
|
|
|
MAP_BIT(UNATTEND_NO_DATA_COLLECTION);
|
|
|
|
i = CustomSelectionDialog(BS_AUTOCHECKBOX, lmprintf(MSG_327), lmprintf(MSG_328),
|
|
|
|
options.String, options.Index, remap8(unattend_xml_mask, map, FALSE), username_index);
|
2022-06-23 12:34:24 +00:00
|
|
|
StrArrayDestroy(&options);
|
|
|
|
if (i < 0)
|
|
|
|
goto out;
|
2022-06-24 13:27:02 +00:00
|
|
|
// Remap i to the correct bit positions before calling CreateUnattendXml()
|
|
|
|
i = remap8(i, map, TRUE);
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
unattend_xml_path = CreateUnattendXml(arch, i | UNATTEND_WINDOWS_TO_GO);
|
2022-06-24 13:27:02 +00:00
|
|
|
// Keep the bits we didn't process
|
|
|
|
unattend_xml_mask &= ~(remap8(0xff, map, TRUE));
|
|
|
|
// And add back the bits we did process
|
|
|
|
unattend_xml_mask |= i;
|
2022-07-07 10:22:39 +00:00
|
|
|
WriteSetting32(SETTING_WUE_OPTIONS, (UNATTEND_DEFAULT_MASK << 16) | unattend_xml_mask);
|
2022-06-23 12:34:24 +00:00
|
|
|
}
|
2019-04-13 14:29:27 +00:00
|
|
|
} else if (target_type == TT_UEFI) {
|
2016-12-14 23:27:04 +00:00
|
|
|
if (!IS_EFI_BOOTABLE(img_report)) {
|
2013-10-31 22:59:53 +00:00
|
|
|
// Unsupported ISO
|
2020-09-15 20:02:08 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_091), lmprintf(MSG_090), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2013-12-11 19:00:57 +00:00
|
|
|
}
|
2020-07-19 21:35:30 +00:00
|
|
|
if (HAS_WIN7_EFI(img_report) && (!WimExtractCheck(FALSE))) {
|
2013-12-11 19:00:57 +00:00
|
|
|
// Your platform cannot extract files from WIM archives => download 7-zip?
|
2020-09-15 20:02:08 +00:00
|
|
|
if (MessageBoxExU(hMainDialog, lmprintf(MSG_102), lmprintf(MSG_101), MB_YESNO | MB_ICONERROR | MB_IS_RTL, selected_langid) == IDYES)
|
2013-12-11 19:00:57 +00:00
|
|
|
ShellExecuteA(hMainDialog, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2013-01-25 01:38:10 +00:00
|
|
|
}
|
2019-04-13 14:29:27 +00:00
|
|
|
} else if ( ((fs_type == FS_NTFS) && !HAS_WINDOWS(img_report) && !HAS_GRUB(img_report) &&
|
2016-12-15 16:28:00 +00:00
|
|
|
(!HAS_SYSLINUX(img_report) || (SL_MAJOR(img_report.sl_version) <= 5)))
|
2019-04-13 14:29:27 +00:00
|
|
|
|| ((IS_FAT(fs_type)) && (!HAS_SYSLINUX(img_report)) && (!allow_dual_uefi_bios) && !IS_EFI_BOOTABLE(img_report) &&
|
2016-12-14 23:27:04 +00:00
|
|
|
(!HAS_REACTOS(img_report)) && !HAS_KOLIBRIOS(img_report) && (!HAS_GRUB(img_report)))
|
2019-04-13 14:29:27 +00:00
|
|
|
|| ((IS_FAT(fs_type)) && (HAS_WINDOWS(img_report) || HAS_WININST(img_report)) && (!allow_dual_uefi_bios)) ) {
|
2015-01-16 01:51:24 +00:00
|
|
|
// Incompatible FS and ISO
|
2020-09-15 20:02:08 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2019-04-13 14:29:27 +00:00
|
|
|
} else if ((fs_type == FS_FAT16) && HAS_KOLIBRIOS(img_report)) {
|
2014-05-15 20:17:12 +00:00
|
|
|
// KolibriOS doesn't support FAT16
|
2020-09-15 20:02:08 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_189), lmprintf(MSG_099), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2013-12-11 19:00:57 +00:00
|
|
|
}
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((IS_FAT(fs_type)) && (img_report.has_4GB_file)) {
|
2013-10-31 22:59:53 +00:00
|
|
|
// This ISO image contains a file larger than 4GB file (FAT32)
|
2020-09-15 20:02:08 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_100), lmprintf(MSG_099), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2013-01-25 01:38:10 +00:00
|
|
|
}
|
2022-07-27 10:49:26 +00:00
|
|
|
if ((nWindowsVersion >= WINDOWS_8) && IS_WINDOWS_1X(img_report) && (!is_windows_to_go)) {
|
2022-06-25 14:39:05 +00:00
|
|
|
StrArray options;
|
|
|
|
int arch = _log2(img_report.has_efi >> 1);
|
|
|
|
uint8_t map[8] = { 0 }, b = 1;
|
|
|
|
StrArrayCreate(&options, 4);
|
2022-07-27 10:49:26 +00:00
|
|
|
if (IS_WINDOWS_11(img_report)) {
|
|
|
|
StrArrayAdd(&options, lmprintf(MSG_329), TRUE);
|
|
|
|
MAP_BIT(UNATTEND_SECUREBOOT_TPM_MINRAM);
|
|
|
|
}
|
2022-06-25 14:39:05 +00:00
|
|
|
if (img_report.win_version.build >= 22500) {
|
|
|
|
StrArrayAdd(&options, lmprintf(MSG_330), TRUE);
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
MAP_BIT(UNATTEND_NO_ONLINE_ACCOUNT);
|
2022-06-25 14:39:05 +00:00
|
|
|
}
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
StrArrayAdd(&options, lmprintf(MSG_333), TRUE);
|
2022-10-18 12:58:38 +00:00
|
|
|
username_index = _log2(b);
|
|
|
|
MAP_BIT(UNATTEND_SET_USER);
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
StrArrayAdd(&options, lmprintf(MSG_334), TRUE);
|
|
|
|
MAP_BIT(UNATTEND_DUPLICATE_LOCALE);
|
2022-10-18 12:58:38 +00:00
|
|
|
StrArrayAdd(&options, lmprintf(MSG_331), TRUE);
|
|
|
|
MAP_BIT(UNATTEND_NO_DATA_COLLECTION);
|
|
|
|
i = CustomSelectionDialog(BS_AUTOCHECKBOX, lmprintf(MSG_327), lmprintf(MSG_328),
|
|
|
|
options.String, options.Index, remap8(unattend_xml_mask, map, FALSE), username_index);
|
2022-06-25 14:39:05 +00:00
|
|
|
StrArrayDestroy(&options);
|
|
|
|
if (i < 0)
|
|
|
|
goto out;
|
|
|
|
i = remap8(i, map, TRUE);
|
|
|
|
unattend_xml_path = CreateUnattendXml(arch, i);
|
|
|
|
// Remember the user preferences for the current session.
|
|
|
|
unattend_xml_mask &= ~(remap8(0xff, map, TRUE));
|
|
|
|
unattend_xml_mask |= i;
|
2022-07-07 10:22:39 +00:00
|
|
|
WriteSetting32(SETTING_WUE_OPTIONS, (UNATTEND_DEFAULT_MASK << 16) | unattend_xml_mask);
|
2022-06-25 14:39:05 +00:00
|
|
|
}
|
2014-02-04 20:01:28 +00:00
|
|
|
|
2021-03-25 19:52:33 +00:00
|
|
|
if ((img_report.projected_size < MAX_ISO_TO_ESP_SIZE * MB) && HAS_REGULAR_EFI(img_report) &&
|
2021-04-08 16:29:13 +00:00
|
|
|
(partition_type == PARTITION_STYLE_GPT) && IS_FAT(fs_type) && !esp_already_asked) {
|
2021-03-25 19:52:33 +00:00
|
|
|
// The ISO is small enough to be written as an ESP and we are using GPT
|
|
|
|
// so ask the users if they want to write it as an ESP.
|
|
|
|
char* iso_image = lmprintf(MSG_036);
|
|
|
|
char* choices[2] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, "ISO → ESP") };
|
2022-10-18 12:58:38 +00:00
|
|
|
i = SelectionDialog(lmprintf(MSG_274, "ESP"), lmprintf(MSG_310), choices, 2);
|
2021-03-25 19:52:33 +00:00
|
|
|
if (i < 0) // Cancel
|
|
|
|
goto out;
|
2022-06-20 12:47:43 +00:00
|
|
|
write_as_esp = (i & 2);
|
2021-03-25 19:52:33 +00:00
|
|
|
}
|
|
|
|
|
2021-03-31 11:27:19 +00:00
|
|
|
// If the selected target doesn't include BIOS, skip file downloads for GRUB/Syslinux
|
|
|
|
if (target_type != TT_BIOS)
|
|
|
|
goto uefi_target;
|
|
|
|
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((partition_type == PARTITION_STYLE_MBR) && (img_report.has_grub2) && (img_report.grub2_version[0] != 0) &&
|
2015-09-02 22:20:00 +00:00
|
|
|
(strcmp(img_report.grub2_version, GRUB2_PACKAGE_VERSION) != 0)) {
|
2014-12-30 19:46:13 +00:00
|
|
|
// We may have to download a different Grub2 version if we can find one
|
2021-05-31 15:54:11 +00:00
|
|
|
IGNORE_RETVAL(_chdirU(app_data_dir));
|
2014-12-30 19:46:13 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
|
|
|
IGNORE_RETVAL(_chdir(FILES_DIR));
|
2015-09-02 22:20:00 +00:00
|
|
|
static_sprintf(tmp, "%s-%s/%s", grub, img_report.grub2_version, core_img);
|
2014-12-30 19:46:13 +00:00
|
|
|
fd = fopen(tmp, "rb");
|
|
|
|
if (fd != NULL) {
|
|
|
|
// If a file already exists in the current directory, use that one
|
2021-10-21 00:59:03 +00:00
|
|
|
to_windows_path(tmp);
|
2021-10-11 19:08:04 +00:00
|
|
|
uprintf("Will reuse '%s' from '%s\\%s\\%s-%s\\' for Grub 2.x installation",
|
|
|
|
core_img, app_data_dir, FILES_DIR, grub, img_report.grub2_version);
|
2014-12-30 19:46:13 +00:00
|
|
|
fseek(fd, 0, SEEK_END);
|
|
|
|
grub2_len = ftell(fd);
|
|
|
|
fseek(fd, 0, SEEK_SET);
|
|
|
|
if (grub2_len > 0)
|
|
|
|
grub2_buf = malloc(grub2_len);
|
|
|
|
|
|
|
|
// grub2_buf was set to NULL at the beginning of this call
|
|
|
|
if ((grub2_buf == NULL) || (fread(grub2_buf, 1, (size_t)grub2_len, fd) != (size_t)grub2_len)) {
|
|
|
|
uprintf("Failed to read existing '%s' data - will use embedded version", core_img);
|
|
|
|
safe_free(grub2_buf);
|
|
|
|
}
|
|
|
|
fclose(fd);
|
|
|
|
} else {
|
2015-10-18 20:31:47 +00:00
|
|
|
r = MessageBoxExU(hMainDialog, lmprintf(MSG_116, img_report.grub2_version, GRUB2_PACKAGE_VERSION),
|
|
|
|
lmprintf(MSG_115), MB_YESNOCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid);
|
2014-12-30 19:46:13 +00:00
|
|
|
if (r == IDCANCEL)
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2014-12-30 19:46:13 +00:00
|
|
|
else if (r == IDYES) {
|
2015-09-02 22:20:00 +00:00
|
|
|
static_sprintf(tmp, "%s-%s", grub, img_report.grub2_version);
|
2014-12-30 19:46:13 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(tmp));
|
2017-01-06 16:15:31 +00:00
|
|
|
IGNORE_RETVAL(_chdir(tmp));
|
2015-09-02 22:20:00 +00:00
|
|
|
static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, img_report.grub2_version, core_img);
|
2018-06-30 21:45:15 +00:00
|
|
|
grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE);
|
2017-01-06 16:15:31 +00:00
|
|
|
if ((grub2_len == 0) && (DownloadStatus == 404)) {
|
2019-05-03 22:51:05 +00:00
|
|
|
// Manjaro (always them!) are using "2.03.5" as identifier, so we must detect first dot...
|
|
|
|
BOOL first_dot = TRUE;
|
2017-01-06 16:15:31 +00:00
|
|
|
// Couldn't locate the file on the server => try to download without the version extra
|
|
|
|
uprintf("Extended version was not found, trying main version...");
|
2017-08-10 18:43:04 +00:00
|
|
|
static_strcpy(tmp2, img_report.grub2_version);
|
2017-01-06 16:15:31 +00:00
|
|
|
// Isolate the #.### part
|
2019-05-03 22:51:05 +00:00
|
|
|
for (i = 0; ((tmp2[i] >= '0') && (tmp2[i] <= '9')) || ((tmp2[i] == '.') && first_dot); i++) {
|
|
|
|
if (tmp2[i] == '.')
|
|
|
|
first_dot = FALSE;
|
|
|
|
}
|
2017-01-06 16:15:31 +00:00
|
|
|
tmp2[i] = 0;
|
|
|
|
static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, tmp2, core_img);
|
2018-06-30 21:45:15 +00:00
|
|
|
grub2_len = (long)DownloadSignedFile(tmp, core_img, hMainDialog, FALSE);
|
2017-01-06 16:15:31 +00:00
|
|
|
static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, grub, img_report.grub2_version, core_img);
|
|
|
|
}
|
2015-01-08 00:22:56 +00:00
|
|
|
if (grub2_len <= 0) {
|
|
|
|
PrintInfo(0, MSG_195, "Grub2");
|
2017-01-06 16:15:31 +00:00
|
|
|
uprintf("%s was not found - will use embedded version", tmp);
|
2015-01-08 00:22:56 +00:00
|
|
|
} else {
|
|
|
|
PrintInfo(0, MSG_193, tmp);
|
2017-01-06 16:15:31 +00:00
|
|
|
fd = fopen(core_img, "rb");
|
2014-12-30 19:46:13 +00:00
|
|
|
grub2_buf = malloc(grub2_len);
|
|
|
|
if ((fd == NULL) || (grub2_buf == NULL) || (fread(grub2_buf, 1, (size_t)grub2_len, fd) != (size_t)grub2_len)) {
|
|
|
|
uprintf("Failed to read '%s' data - will use embedded version", core_img);
|
|
|
|
safe_free(grub2_buf);
|
|
|
|
}
|
|
|
|
if (fd != NULL)
|
|
|
|
fclose(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((partition_type == PARTITION_STYLE_MBR) && HAS_SYSLINUX(img_report)) {
|
2015-09-02 22:20:00 +00:00
|
|
|
if (SL_MAJOR(img_report.sl_version) < 5) {
|
2021-05-31 15:54:11 +00:00
|
|
|
IGNORE_RETVAL(_chdirU(app_data_dir));
|
2014-02-04 20:01:28 +00:00
|
|
|
for (i=0; i<NB_OLD_C32; i++) {
|
2015-09-02 22:20:00 +00:00
|
|
|
if (img_report.has_old_c32[i]) {
|
2014-03-13 22:13:46 +00:00
|
|
|
if (!in_files_dir) {
|
2014-02-04 20:01:28 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
|
|
|
IGNORE_RETVAL(_chdir(FILES_DIR));
|
2014-03-13 22:13:46 +00:00
|
|
|
in_files_dir = TRUE;
|
2014-02-04 20:01:28 +00:00
|
|
|
}
|
|
|
|
static_sprintf(tmp, "%s-%s/%s", syslinux, embedded_sl_version_str[0], old_c32_name[i]);
|
|
|
|
fd = fopen(tmp, "rb");
|
|
|
|
if (fd != NULL) {
|
|
|
|
// If a file already exists in the current directory, use that one
|
2021-10-11 19:08:04 +00:00
|
|
|
uprintf("Will replace obsolete '%s' from ISO with the one found in '%s\\%s\\%s'",
|
|
|
|
old_c32_name[i], app_data_dir, FILES_DIR, tmp);
|
2014-02-04 20:01:28 +00:00
|
|
|
fclose(fd);
|
|
|
|
use_own_c32[i] = TRUE;
|
|
|
|
} else {
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_204, old_c32_name[i]);
|
2015-10-18 20:31:47 +00:00
|
|
|
if (MessageBoxExU(hMainDialog, lmprintf(MSG_084, old_c32_name[i], old_c32_name[i]),
|
|
|
|
lmprintf(MSG_083, old_c32_name[i]), MB_YESNO|MB_ICONWARNING|MB_IS_RTL, selected_langid) == IDYES) {
|
2014-02-04 20:01:28 +00:00
|
|
|
static_sprintf(tmp, "%s-%s", syslinux, embedded_sl_version_str[0]);
|
|
|
|
IGNORE_RETVAL(_mkdir(tmp));
|
|
|
|
static_sprintf(tmp, "%s/%s-%s/%s", FILES_URL, syslinux, embedded_sl_version_str[0], old_c32_name[i]);
|
2018-06-30 21:45:15 +00:00
|
|
|
len = DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog, TRUE);
|
2014-02-04 20:01:28 +00:00
|
|
|
if (len == 0) {
|
2017-01-06 16:15:31 +00:00
|
|
|
uprintf("Could not download file - cancelling");
|
2020-02-03 12:35:49 +00:00
|
|
|
ret = BOOTCHECK_DOWNLOAD_ERROR;
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2014-02-04 20:01:28 +00:00
|
|
|
}
|
|
|
|
use_own_c32[i] = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-01-21 17:08:41 +00:00
|
|
|
}
|
2015-09-02 22:20:00 +00:00
|
|
|
} else if ((img_report.sl_version != embedded_sl_version[1]) ||
|
|
|
|
(safe_strcmp(img_report.sl_version_ext, embedded_sl_version_ext[1]) != 0)) {
|
2014-02-04 20:01:28 +00:00
|
|
|
// Unlike what was the case for v4 and earlier, Syslinux v5+ versions are INCOMPATIBLE with one another!
|
2021-05-31 15:54:11 +00:00
|
|
|
IGNORE_RETVAL(_chdirU(app_data_dir));
|
2014-02-04 20:01:28 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
|
|
|
IGNORE_RETVAL(_chdir(FILES_DIR));
|
2014-01-21 17:08:41 +00:00
|
|
|
for (i=0; i<2; i++) {
|
2014-02-04 20:01:28 +00:00
|
|
|
// Check if we already have the relevant ldlinux_v#.##.sys & ldlinux_v#.##.bss files
|
2021-10-21 00:59:03 +00:00
|
|
|
static_sprintf(tmp, "%s-%s%s\\%s.%s", syslinux, img_report.sl_version_str,
|
2015-09-02 22:20:00 +00:00
|
|
|
img_report.sl_version_ext, ldlinux, ldlinux_ext[i]);
|
2014-02-04 20:01:28 +00:00
|
|
|
fd = fopen(tmp, "rb");
|
|
|
|
if (fd != NULL) {
|
|
|
|
fseek(fd, 0, SEEK_END);
|
|
|
|
syslinux_ldlinux_len[i] = (DWORD)ftell(fd);
|
|
|
|
fclose(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((syslinux_ldlinux_len[0] != 0) && (syslinux_ldlinux_len[1] != 0)) {
|
2021-10-21 00:59:03 +00:00
|
|
|
to_windows_path(img_report.sl_version_ext);
|
2021-10-11 19:08:04 +00:00
|
|
|
uprintf("Will reuse '%s.%s' and '%s.%s' from '%s\\%s\\%s-%s%s\\' for Syslinux installation",
|
|
|
|
ldlinux, ldlinux_ext[0], ldlinux, ldlinux_ext[1], app_data_dir, FILES_DIR, syslinux,
|
2015-09-02 22:20:00 +00:00
|
|
|
img_report.sl_version_str, img_report.sl_version_ext);
|
2014-02-04 20:01:28 +00:00
|
|
|
} else {
|
2015-10-18 20:31:47 +00:00
|
|
|
r = MessageBoxExU(hMainDialog, lmprintf(MSG_114, img_report.sl_version_str, img_report.sl_version_ext,
|
2014-11-11 19:53:39 +00:00
|
|
|
embedded_sl_version_str[1], embedded_sl_version_ext[1]),
|
2015-10-18 20:31:47 +00:00
|
|
|
lmprintf(MSG_115), MB_YESNO|MB_ICONWARNING|MB_IS_RTL, selected_langid);
|
2014-02-04 20:01:28 +00:00
|
|
|
if (r != IDYES)
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2014-02-04 20:01:28 +00:00
|
|
|
for (i=0; i<2; i++) {
|
2015-09-02 22:20:00 +00:00
|
|
|
static_sprintf(tmp, "%s-%s", syslinux, img_report.sl_version_str);
|
2014-02-04 20:01:28 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(tmp));
|
2015-09-02 22:20:00 +00:00
|
|
|
if (*img_report.sl_version_ext != 0) {
|
2014-08-05 23:57:32 +00:00
|
|
|
IGNORE_RETVAL(_chdir(tmp));
|
2015-09-02 22:20:00 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(&img_report.sl_version_ext[1]));
|
2014-08-05 23:57:32 +00:00
|
|
|
IGNORE_RETVAL(_chdir(".."));
|
|
|
|
}
|
2015-09-02 22:20:00 +00:00
|
|
|
static_sprintf(tmp, "%s/%s-%s%s/%s.%s", FILES_URL, syslinux, img_report.sl_version_str,
|
|
|
|
img_report.sl_version_ext, ldlinux, ldlinux_ext[i]);
|
2018-06-30 21:45:15 +00:00
|
|
|
syslinux_ldlinux_len[i] = DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)],
|
|
|
|
hMainDialog, (*img_report.sl_version_ext == 0));
|
2015-09-02 22:20:00 +00:00
|
|
|
if ((syslinux_ldlinux_len[i] == 0) && (DownloadStatus == 404) && (*img_report.sl_version_ext != 0)) {
|
2014-08-05 23:57:32 +00:00
|
|
|
// Couldn't locate the file on the server => try to download without the version extra
|
2017-01-06 16:15:31 +00:00
|
|
|
uprintf("Extended version was not found, trying main version...");
|
2015-09-02 22:20:00 +00:00
|
|
|
static_sprintf(tmp, "%s/%s-%s/%s.%s", FILES_URL, syslinux, img_report.sl_version_str,
|
2014-08-05 23:57:32 +00:00
|
|
|
ldlinux, ldlinux_ext[i]);
|
2018-06-30 21:45:15 +00:00
|
|
|
syslinux_ldlinux_len[i] = DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)],
|
|
|
|
hMainDialog, (*img_report.sl_version_ext == 0));
|
2014-08-05 23:57:32 +00:00
|
|
|
if (syslinux_ldlinux_len[i] != 0) {
|
|
|
|
// Duplicate the file so that the user won't be prompted to download again
|
2015-09-02 22:20:00 +00:00
|
|
|
static_sprintf(tmp, "%s-%s\\%s.%s", syslinux, img_report.sl_version_str, ldlinux, ldlinux_ext[i]);
|
2015-10-18 20:31:47 +00:00
|
|
|
static_sprintf(tmp2, "%s-%s\\%s\\%s.%s", syslinux, img_report.sl_version_str,
|
2015-09-02 22:20:00 +00:00
|
|
|
&img_report.sl_version_ext[1], ldlinux, ldlinux_ext[i]);
|
2014-08-05 23:57:32 +00:00
|
|
|
CopyFileA(tmp, tmp2, FALSE);
|
|
|
|
}
|
|
|
|
}
|
2014-02-04 20:01:28 +00:00
|
|
|
if (syslinux_ldlinux_len[i] == 0) {
|
2016-03-08 17:28:45 +00:00
|
|
|
// If the version matches our embedded one, try to use that as a last ditch effort
|
|
|
|
if (img_report.sl_version == embedded_sl_version[1]) {
|
|
|
|
uprintf("Could not download the file - will try to use embedded %s version instead", img_report.sl_version_str);
|
|
|
|
} else {
|
2017-01-06 16:15:31 +00:00
|
|
|
uprintf("Could not download the file - cancelling");
|
2020-02-03 12:35:49 +00:00
|
|
|
ret = BOOTCHECK_DOWNLOAD_ERROR;
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2016-03-08 17:28:45 +00:00
|
|
|
}
|
2014-02-04 20:01:28 +00:00
|
|
|
}
|
2014-01-21 17:08:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-04-13 14:29:27 +00:00
|
|
|
} else if (boot_type == BT_SYSLINUX_V6) {
|
2021-05-31 15:54:11 +00:00
|
|
|
IGNORE_RETVAL(_chdirU(app_data_dir));
|
2014-01-14 20:17:07 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
|
|
|
IGNORE_RETVAL(_chdir(FILES_DIR));
|
2014-01-24 19:59:23 +00:00
|
|
|
static_sprintf(tmp, "%s-%s/%s.%s", syslinux, embedded_sl_version_str[1], ldlinux, ldlinux_ext[2]);
|
2014-01-21 17:08:41 +00:00
|
|
|
fd = fopenU(tmp, "rb");
|
2013-06-15 16:31:55 +00:00
|
|
|
if (fd != NULL) {
|
2021-10-21 00:59:03 +00:00
|
|
|
to_windows_path(tmp);
|
2021-10-11 19:08:04 +00:00
|
|
|
uprintf("Will reuse '%s\\%s\\%s' for Syslinux installation", app_data_dir, FILES_DIR, tmp);
|
2013-06-15 16:31:55 +00:00
|
|
|
fclose(fd);
|
|
|
|
} else {
|
2014-01-21 17:08:41 +00:00
|
|
|
static_sprintf(tmp, "%s.%s", ldlinux, ldlinux_ext[2]);
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_206, tmp);
|
2014-01-21 17:08:41 +00:00
|
|
|
// MSG_104: "Syslinux v5.0 or later requires a '%s' file to be installed"
|
2015-10-18 20:31:47 +00:00
|
|
|
r = MessageBoxExU(hMainDialog, lmprintf(MSG_104, "Syslinux v5.0", tmp, "Syslinux v5+", tmp),
|
|
|
|
lmprintf(MSG_103, tmp), MB_YESNOCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid);
|
2013-12-27 16:06:59 +00:00
|
|
|
if (r == IDCANCEL)
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2013-06-15 16:31:55 +00:00
|
|
|
if (r == IDYES) {
|
2014-01-24 19:59:23 +00:00
|
|
|
static_sprintf(tmp, "%s-%s", syslinux, embedded_sl_version_str[1]);
|
2014-01-14 20:17:07 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(tmp));
|
2014-01-24 19:59:23 +00:00
|
|
|
static_sprintf(tmp, "%s/%s-%s/%s.%s", FILES_URL, syslinux, embedded_sl_version_str[1], ldlinux, ldlinux_ext[2]);
|
2020-02-03 12:35:49 +00:00
|
|
|
if (DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog, TRUE) == 0) {
|
|
|
|
ret = BOOTCHECK_DOWNLOAD_ERROR;
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2020-02-03 12:35:49 +00:00
|
|
|
}
|
2013-06-15 16:31:55 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-13 14:29:27 +00:00
|
|
|
} else if (boot_type == BT_MSDOS) {
|
2020-07-17 20:51:15 +00:00
|
|
|
if ((size_check) && (ComboBox_GetCurItemData(hClusterSize) >= 65536)) {
|
2013-10-31 22:59:53 +00:00
|
|
|
// MS-DOS cannot boot from a drive using a 64 kilobytes Cluster size
|
2015-10-18 20:31:47 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_110), lmprintf(MSG_111), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2013-10-31 22:59:53 +00:00
|
|
|
}
|
2019-04-13 14:29:27 +00:00
|
|
|
} else if (boot_type == BT_GRUB4DOS) {
|
2021-05-31 15:54:11 +00:00
|
|
|
IGNORE_RETVAL(_chdirU(app_data_dir));
|
2014-11-14 23:40:00 +00:00
|
|
|
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
|
|
|
IGNORE_RETVAL(_chdir(FILES_DIR));
|
2015-02-16 22:29:23 +00:00
|
|
|
static_sprintf(tmp, "grub4dos-%s/grldr", GRUB4DOS_VERSION);
|
2014-11-14 23:40:00 +00:00
|
|
|
fd = fopenU(tmp, "rb");
|
|
|
|
if (fd != NULL) {
|
2021-10-21 00:59:03 +00:00
|
|
|
to_windows_path(tmp);
|
2021-10-11 19:08:04 +00:00
|
|
|
uprintf("Will reuse '%s\\%s\\%s' for Grub4DOS installation", app_data_dir, FILES_DIR, tmp);
|
2014-11-14 23:40:00 +00:00
|
|
|
fclose(fd);
|
|
|
|
} else {
|
|
|
|
static_sprintf(tmp, "grldr");
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_206, tmp);
|
2015-10-18 20:31:47 +00:00
|
|
|
r = MessageBoxExU(hMainDialog, lmprintf(MSG_104, "Grub4DOS 0.4", tmp, "Grub4DOS", tmp),
|
|
|
|
lmprintf(MSG_103, tmp), MB_YESNOCANCEL|MB_ICONWARNING|MB_IS_RTL, selected_langid);
|
2014-11-14 23:40:00 +00:00
|
|
|
if (r == IDCANCEL)
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2014-11-14 23:40:00 +00:00
|
|
|
if (r == IDYES) {
|
2015-02-16 22:29:23 +00:00
|
|
|
static_sprintf(tmp, "grub4dos-%s", GRUB4DOS_VERSION);
|
|
|
|
IGNORE_RETVAL(_mkdir(tmp));
|
|
|
|
static_sprintf(tmp, "%s/grub4dos-%s/grldr", FILES_URL, GRUB4DOS_VERSION);
|
2020-02-03 12:35:49 +00:00
|
|
|
if (DownloadSignedFile(tmp, &tmp[sizeof(FILES_URL)], hMainDialog, TRUE) == 0) {
|
|
|
|
ret = BOOTCHECK_DOWNLOAD_ERROR;
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2020-02-03 12:35:49 +00:00
|
|
|
}
|
2014-11-14 23:40:00 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-08 11:46:50 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
uefi_target:
|
2019-04-13 14:29:27 +00:00
|
|
|
if (boot_type == BT_UEFI_NTFS) {
|
2020-07-17 20:51:15 +00:00
|
|
|
fs_type = (int)ComboBox_GetCurItemData(hFileSystem);
|
2020-01-30 13:51:19 +00:00
|
|
|
if (fs_type != FS_NTFS && fs_type != FS_EXFAT) {
|
2018-03-22 23:14:20 +00:00
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_097, "UEFI:NTFS"), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
|
2018-07-03 21:54:06 +00:00
|
|
|
goto out;
|
2018-03-22 23:14:20 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-03 12:35:49 +00:00
|
|
|
ret = BOOTCHECK_PROCEED;
|
2018-07-03 21:54:06 +00:00
|
|
|
|
|
|
|
out:
|
|
|
|
PostMessage(hMainDialog, UM_FORMAT_START, ret, 0);
|
2018-07-04 21:50:26 +00:00
|
|
|
ExitThread((DWORD)ret);
|
2018-03-22 23:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline const char* IsAlphaOrBeta(void)
|
|
|
|
{
|
|
|
|
#if defined(ALPHA)
|
|
|
|
return " (Alpha) ";
|
|
|
|
#elif defined(BETA)
|
|
|
|
return " (Beta) ";
|
|
|
|
#elif defined(TEST)
|
|
|
|
# define TEST_STR(x) " (Test" STRINGIFY(x) ") "
|
|
|
|
return TEST_STR(TEST);
|
|
|
|
#else
|
|
|
|
return " ";
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-04-25 13:32:19 +00:00
|
|
|
static void InitDialog(HWND hDlg)
|
2012-02-02 13:16:49 +00:00
|
|
|
{
|
2014-01-21 17:08:41 +00:00
|
|
|
DWORD len;
|
2012-02-02 13:16:49 +00:00
|
|
|
HDC hDC;
|
2018-03-22 23:14:20 +00:00
|
|
|
int i, lfHeight;
|
2018-06-28 15:25:13 +00:00
|
|
|
char tmp[128], *token, *buf, *ext, *msg;
|
2014-11-11 19:53:39 +00:00
|
|
|
static char* resource[2] = { MAKEINTRESOURCEA(IDR_SL_LDLINUX_V4_SYS), MAKEINTRESOURCEA(IDR_SL_LDLINUX_V6_SYS) };
|
2012-02-02 13:16:49 +00:00
|
|
|
|
2012-02-07 02:05:58 +00:00
|
|
|
#ifdef RUFUS_TEST
|
|
|
|
ShowWindow(GetDlgItem(hDlg, IDC_TEST), SW_SHOW);
|
|
|
|
#endif
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
hDC = GetDC(hDlg);
|
|
|
|
lfHeight = -MulDiv(9, GetDeviceCaps(hDC, LOGPIXELSY), 72);
|
|
|
|
safe_release_dc(hDlg, hDC);
|
|
|
|
|
2012-02-02 13:16:49 +00:00
|
|
|
// Quite a burden to carry around as parameters
|
|
|
|
hMainDialog = hDlg;
|
2016-05-30 16:32:49 +00:00
|
|
|
MainThreadId = GetCurrentThreadId();
|
2012-02-02 13:16:49 +00:00
|
|
|
hDeviceList = GetDlgItem(hDlg, IDC_DEVICE);
|
2013-10-15 21:58:27 +00:00
|
|
|
hPartitionScheme = GetDlgItem(hDlg, IDC_PARTITION_TYPE);
|
2018-03-22 23:14:20 +00:00
|
|
|
hTargetSystem = GetDlgItem(hDlg, IDC_TARGET_SYSTEM);
|
|
|
|
hFileSystem = GetDlgItem(hDlg, IDC_FILE_SYSTEM);
|
|
|
|
hClusterSize = GetDlgItem(hDlg, IDC_CLUSTER_SIZE);
|
2012-02-02 13:16:49 +00:00
|
|
|
hLabel = GetDlgItem(hDlg, IDC_LABEL);
|
|
|
|
hProgress = GetDlgItem(hDlg, IDC_PROGRESS);
|
2018-03-22 23:14:20 +00:00
|
|
|
hBootType = GetDlgItem(hDlg, IDC_BOOT_SELECTION);
|
2020-07-17 20:51:15 +00:00
|
|
|
hImageOption = GetDlgItem(hDlg, IDC_IMAGE_OPTION);
|
2018-03-22 23:14:20 +00:00
|
|
|
hSelectImage = GetDlgItem(hDlg, IDC_SELECT);
|
|
|
|
hNBPasses = GetDlgItem(hDlg, IDC_NB_PASSES);
|
2012-05-16 22:38:39 +00:00
|
|
|
hDiskID = GetDlgItem(hDlg, IDC_DISK_ID);
|
2015-04-19 03:15:44 +00:00
|
|
|
hStart = GetDlgItem(hDlg, IDC_START);
|
2012-02-02 13:16:49 +00:00
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Convert the main button labels to uppercase
|
|
|
|
GetWindowTextU(hStart, uppercase_start, sizeof(uppercase_start));
|
|
|
|
CharUpperBuffU(uppercase_start, sizeof(uppercase_start));
|
|
|
|
SetWindowTextU(hStart, uppercase_start);
|
|
|
|
GetWindowTextU(GetDlgItem(hDlg, IDCANCEL), uppercase_close, sizeof(uppercase_close));
|
|
|
|
CharUpperBuffU(uppercase_close, sizeof(uppercase_close));
|
|
|
|
// Hardcoded exception for German
|
|
|
|
if (strcmp("SCHLIEßEN", uppercase_close) == 0)
|
|
|
|
strcpy(uppercase_close, "SCHLIESSEN");
|
|
|
|
SetWindowTextU(GetDlgItem(hDlg, IDCANCEL), uppercase_close);
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
GetWindowTextU(GetDlgItem(hDlg, IDC_SELECT), uppercase_select[0], sizeof(uppercase_select[0]));
|
|
|
|
static_strcpy(uppercase_select[1], lmprintf(MSG_040));
|
|
|
|
CharUpperBuffU(uppercase_select[0], sizeof(uppercase_select[0]));
|
|
|
|
CharUpperBuffU(uppercase_select[1], sizeof(uppercase_select[1]));
|
|
|
|
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECT), uppercase_select[0]);
|
2019-04-27 15:04:47 +00:00
|
|
|
static_strcpy(uppercase_cancel, lmprintf(MSG_007));
|
2018-03-22 23:14:20 +00:00
|
|
|
CharUpperBuffU(uppercase_cancel, sizeof(uppercase_cancel));
|
|
|
|
|
2018-05-01 17:07:07 +00:00
|
|
|
CreateSmallButtons(hDlg);
|
2018-03-22 23:14:20 +00:00
|
|
|
GetBasicControlsWidth(hDlg);
|
|
|
|
GetMainButtonsWidth(hDlg);
|
|
|
|
GetHalfDropwdownWidth(hDlg);
|
|
|
|
GetFullWidth(hDlg);
|
|
|
|
|
2020-07-02 21:55:01 +00:00
|
|
|
// Set some missing labels
|
|
|
|
SetAccessibleName(hNBPasses, lmprintf(MSG_316));
|
|
|
|
SetAccessibleName(hDiskID, lmprintf(MSG_317));
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Create the font and brush for the progress messages
|
2015-05-21 22:51:48 +00:00
|
|
|
hInfoFont = CreateFontA(lfHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
|
2017-11-13 14:29:48 +00:00
|
|
|
0, 0, PROOF_QUALITY, 0, "Segoe UI");
|
2015-01-01 23:39:28 +00:00
|
|
|
|
2012-02-02 13:16:49 +00:00
|
|
|
// Create the title bar icon
|
2012-12-05 01:53:10 +00:00
|
|
|
SetTitleBarIcon(hDlg);
|
2012-03-11 01:55:25 +00:00
|
|
|
GetWindowTextA(hDlg, tmp, sizeof(tmp));
|
2018-03-22 23:14:20 +00:00
|
|
|
// Count on Microsoft for making it more attractive to read a
|
2012-03-11 01:55:25 +00:00
|
|
|
// version using strtok() than using GetFileVersionInfo()
|
2014-01-24 19:59:23 +00:00
|
|
|
token = strtok(tmp, " ");
|
2020-07-29 18:32:32 +00:00
|
|
|
for (i = 0; (i < 3) && ((token = strtok(NULL, ".")) != NULL); i++)
|
2012-12-07 00:54:40 +00:00
|
|
|
rufus_version[i] = (uint16_t)atoi(token);
|
2014-11-20 22:57:22 +00:00
|
|
|
|
2018-08-18 16:38:23 +00:00
|
|
|
// Redefine the title to be able to add "Alpha" or "Beta"
|
|
|
|
static_sprintf(tmp, APPLICATION_NAME " %d.%d.%d%s%s", rufus_version[0], rufus_version[1], rufus_version[2],
|
|
|
|
IsAlphaOrBeta(), (ini_file != NULL)?"(Portable)":"");
|
2014-11-20 22:57:22 +00:00
|
|
|
SetWindowTextU(hDlg, tmp);
|
2017-07-04 13:51:25 +00:00
|
|
|
// Now that we have a title, we can find the handle of our Dialog
|
|
|
|
dialog_handle = FindWindowA(NULL, tmp);
|
2018-10-27 13:22:09 +00:00
|
|
|
uprintf(APPLICATION_NAME " " APPLICATION_ARCH " v%d.%d.%d%s%s", rufus_version[0], rufus_version[1], rufus_version[2],
|
2021-02-08 21:02:01 +00:00
|
|
|
IsAlphaOrBeta(), (ini_file != NULL)?"(Portable)": (appstore_version ? "(AppStore version)" : ""));
|
2020-07-29 18:32:32 +00:00
|
|
|
for (i = 0; i < ARRAYSIZE(resource); i++) {
|
2020-02-19 12:41:13 +00:00
|
|
|
len = 0;
|
2014-10-29 19:16:29 +00:00
|
|
|
buf = (char*)GetResource(hMainInstance, resource[i], _RT_RCDATA, "ldlinux_sys", &len, TRUE);
|
2014-08-05 23:57:32 +00:00
|
|
|
if (buf == NULL) {
|
2014-01-21 17:08:41 +00:00
|
|
|
uprintf("Warning: could not read embedded Syslinux v%d version", i+4);
|
|
|
|
} else {
|
2014-08-05 23:57:32 +00:00
|
|
|
embedded_sl_version[i] = GetSyslinuxVersion(buf, len, &ext);
|
2014-01-24 19:59:23 +00:00
|
|
|
static_sprintf(embedded_sl_version_str[i], "%d.%02d", SL_MAJOR(embedded_sl_version[i]), SL_MINOR(embedded_sl_version[i]));
|
2017-08-10 18:43:04 +00:00
|
|
|
static_strcpy(embedded_sl_version_ext[i], ext);
|
2014-10-29 19:16:29 +00:00
|
|
|
free(buf);
|
2014-01-21 17:08:41 +00:00
|
|
|
}
|
|
|
|
}
|
2015-01-25 00:56:38 +00:00
|
|
|
uprintf("Windows version: %s", WindowsVersionStr);
|
2014-08-05 23:57:32 +00:00
|
|
|
uprintf("Syslinux versions: %s%s, %s%s", embedded_sl_version_str[0], embedded_sl_version_ext[0],
|
|
|
|
embedded_sl_version_str[1], embedded_sl_version_ext[1]);
|
2015-02-16 22:29:23 +00:00
|
|
|
uprintf("Grub versions: %s, %s", GRUB4DOS_VERSION, GRUB2_PACKAGE_VERSION);
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
uprintf("System locale ID: 0x%04X (%s)", GetUserDefaultUILanguage(), ToLocaleName(GetUserDefaultUILanguage()));
|
2017-04-25 19:25:50 +00:00
|
|
|
ubflush();
|
2016-02-15 12:50:06 +00:00
|
|
|
if (selected_locale->ctrl_id & LOC_NEEDS_UPDATE) {
|
|
|
|
uprintf("NOTE: The %s translation requires an update, but the current translator hasn't submitted "
|
|
|
|
"one. Because of this, some messages will only be displayed in English.", selected_locale->txt[1]);
|
2016-02-16 17:47:07 +00:00
|
|
|
uprintf("If you think you can help update this translation, please e-mail the author of this application");
|
2016-02-15 12:50:06 +00:00
|
|
|
}
|
2021-10-03 13:50:53 +00:00
|
|
|
if (!is_vds_available)
|
|
|
|
uprintf("Notice: Windows VDS is unavailable");
|
2013-10-15 21:58:27 +00:00
|
|
|
|
2012-03-29 17:16:06 +00:00
|
|
|
CreateTaskbarList();
|
|
|
|
SetTaskbarProgressState(TASKBAR_NORMAL);
|
|
|
|
|
2012-02-02 13:16:49 +00:00
|
|
|
// Use maximum granularity for the progress bar
|
2013-01-09 21:54:28 +00:00
|
|
|
SendMessage(hProgress, PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000);
|
2018-03-22 23:14:20 +00:00
|
|
|
|
2012-02-02 13:16:49 +00:00
|
|
|
// Fill up the passes
|
2018-06-28 15:25:13 +00:00
|
|
|
for (i = 1; i <= 5; i++) {
|
|
|
|
msg = (i == 1) ? lmprintf(MSG_034, 1) : lmprintf(MSG_035, (i == 2) ? 2 : 4, (i == 2) ? "" : lmprintf(MSG_087, flash_type[i - 3]));
|
|
|
|
IGNORE_RETVAL(ComboBox_AddStringU(hNBPasses, msg));
|
2013-01-25 01:38:10 +00:00
|
|
|
}
|
2015-04-18 22:14:55 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hNBPasses, 0));
|
2013-01-25 01:38:10 +00:00
|
|
|
SetPassesTooltip();
|
2018-03-22 23:14:20 +00:00
|
|
|
|
|
|
|
// Fill up the boot options dropdown
|
|
|
|
SetBootOptions();
|
|
|
|
|
2012-05-22 11:30:22 +00:00
|
|
|
// Fill up the MBR masqueraded disk IDs ("8 disks should be enough for anybody")
|
2015-10-18 20:31:47 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, lmprintf(MSG_030, LEFT_TO_RIGHT_EMBEDDING "0x80" POP_DIRECTIONAL_FORMATTING)), 0x80));
|
2012-05-25 16:54:06 +00:00
|
|
|
for (i=1; i<=7; i++) {
|
2013-10-15 21:58:27 +00:00
|
|
|
IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, lmprintf(MSG_109, 0x80+i, i+1)), 0x80+i));
|
2012-05-16 22:38:39 +00:00
|
|
|
}
|
|
|
|
IGNORE_RETVAL(ComboBox_SetCurSel(hDiskID, 0));
|
|
|
|
|
2017-09-15 11:40:33 +00:00
|
|
|
// Create the string arrays
|
2017-07-11 16:43:51 +00:00
|
|
|
StrArrayCreate(&BlockingProcess, 16);
|
2018-03-22 23:14:20 +00:00
|
|
|
StrArrayCreate(&ImageList, 16);
|
2012-05-16 22:38:39 +00:00
|
|
|
// Set various checkboxes
|
2018-03-22 23:14:20 +00:00
|
|
|
CheckDlgButton(hDlg, IDC_QUICK_FORMAT, BST_CHECKED);
|
|
|
|
CheckDlgButton(hDlg, IDC_EXTENDED_LABEL, BST_CHECKED);
|
|
|
|
|
|
|
|
CreateAdditionalControls(hDlg);
|
|
|
|
SetSectionHeaders(hDlg);
|
2018-07-06 04:46:36 +00:00
|
|
|
PositionMainControls(hDlg);
|
2018-03-22 23:14:20 +00:00
|
|
|
AdjustForLowDPI(hDlg);
|
|
|
|
// Because we created the log dialog before we computed our sizes, we need to send a custom message
|
|
|
|
SendMessage(hLogDialog, UM_RESIZE_BUTTONS, 0, 0);
|
2018-07-06 10:23:57 +00:00
|
|
|
// Limit the amount of characters for the Persistence size field
|
|
|
|
SendMessage(GetDlgItem(hDlg, IDC_PERSISTENCE_SIZE), EM_LIMITTEXT, 7, 0);
|
2018-03-22 23:14:20 +00:00
|
|
|
// Create the status line and initialize the taskbar icon for progress overlay
|
|
|
|
CreateStatusBar();
|
2017-11-13 14:29:48 +00:00
|
|
|
|
2012-05-22 11:30:22 +00:00
|
|
|
// Set the various tooltips
|
2013-10-15 21:58:27 +00:00
|
|
|
CreateTooltip(hFileSystem, lmprintf(MSG_157), -1);
|
|
|
|
CreateTooltip(hClusterSize, lmprintf(MSG_158), -1);
|
|
|
|
CreateTooltip(hLabel, lmprintf(MSG_159), -1);
|
2018-03-22 23:14:20 +00:00
|
|
|
CreateTooltip(hAdvancedDeviceToolbar, lmprintf(MSG_160), -1);
|
|
|
|
CreateTooltip(hAdvancedFormatToolbar, lmprintf(MSG_160), -1);
|
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_BAD_BLOCKS), lmprintf(MSG_161), -1);
|
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_QUICK_FORMAT), lmprintf(MSG_162), -1);
|
2013-10-15 21:58:27 +00:00
|
|
|
CreateTooltip(hBootType, lmprintf(MSG_164), -1);
|
2018-03-22 23:14:20 +00:00
|
|
|
CreateTooltip(hSelectImage, lmprintf(MSG_165), -1);
|
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_EXTENDED_LABEL), lmprintf(MSG_166), 10000);
|
2013-10-15 21:58:27 +00:00
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_RUFUS_MBR), lmprintf(MSG_167), 10000);
|
|
|
|
CreateTooltip(hDiskID, lmprintf(MSG_168), 10000);
|
2018-03-22 23:14:20 +00:00
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_OLD_BIOS_FIXES), lmprintf(MSG_169), -1);
|
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_LIST_USB_HDD), lmprintf(MSG_170), -1);
|
2015-04-19 03:15:44 +00:00
|
|
|
CreateTooltip(hStart, lmprintf(MSG_171), -1);
|
2018-03-22 23:14:20 +00:00
|
|
|
CreateTooltip(hPartitionScheme, lmprintf(MSG_163), -1);
|
|
|
|
CreateTooltip(hTargetSystem, lmprintf(MSG_150), 30000);
|
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDS_CSM_HELP_TXT), lmprintf(MSG_151), 30000);
|
2020-07-17 20:51:15 +00:00
|
|
|
CreateTooltip(hImageOption, lmprintf(MSG_305), 30000);
|
2018-07-18 11:22:37 +00:00
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_PERSISTENCE_SLIDER), lmprintf(MSG_125), 30000);
|
2018-07-18 15:59:35 +00:00
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_PERSISTENCE_SIZE), lmprintf(MSG_125), 30000);
|
|
|
|
CreateTooltip(GetDlgItem(hDlg, IDC_PERSISTENCE_UNITS), lmprintf(MSG_126), 30000);
|
2018-03-22 23:14:20 +00:00
|
|
|
|
|
|
|
if (!advanced_mode_device) // Hide as needed, since we display the advanced controls by default
|
|
|
|
ToggleAdvancedDeviceOptions(FALSE);
|
|
|
|
if (!advanced_mode_format)
|
|
|
|
ToggleAdvancedFormatOptions(FALSE);
|
2018-07-18 11:22:37 +00:00
|
|
|
ToggleImageOptions();
|
2013-02-04 01:14:28 +00:00
|
|
|
|
|
|
|
// Process commandline parameters
|
2020-07-19 21:35:30 +00:00
|
|
|
if (img_provided) {
|
2018-03-22 23:14:20 +00:00
|
|
|
// Simulate a button click for image selection
|
|
|
|
PostMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
2013-02-04 01:14:28 +00:00
|
|
|
}
|
2018-03-22 23:14:20 +00:00
|
|
|
SetBootTypeDropdownWidth();
|
2015-01-01 23:39:28 +00:00
|
|
|
|
2018-10-30 16:14:07 +00:00
|
|
|
CheckDlgButton(hMainDialog, IDC_LIST_USB_HDD, enable_HDDs ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_210);
|
2012-02-02 13:16:49 +00:00
|
|
|
}
|
|
|
|
|
2016-05-09 12:40:54 +00:00
|
|
|
static void PrintStatusTimeout(const char* str, BOOL val)
|
2013-06-03 20:32:22 +00:00
|
|
|
{
|
2016-05-09 12:40:54 +00:00
|
|
|
PrintStatus(STATUS_MSG_TIMEOUT, (val)?MSG_250:MSG_251, str);
|
2013-06-03 20:32:22 +00:00
|
|
|
}
|
|
|
|
|
2017-04-25 13:32:19 +00:00
|
|
|
static void SaveVHD(void)
|
2015-08-14 22:09:45 +00:00
|
|
|
{
|
2016-12-06 11:47:19 +00:00
|
|
|
static IMG_SAVE img_save = { 0 };
|
2015-08-14 22:09:45 +00:00
|
|
|
char filename[128];
|
|
|
|
char path[MAX_PATH];
|
|
|
|
int DriveIndex = ComboBox_GetCurSel(hDeviceList);
|
2016-12-06 11:47:19 +00:00
|
|
|
EXT_DECL(img_ext, filename, __VA_GROUP__("*.vhd"), __VA_GROUP__(lmprintf(MSG_095)));
|
2015-09-04 13:15:22 +00:00
|
|
|
ULARGE_INTEGER free_space;
|
|
|
|
|
2020-07-10 10:55:29 +00:00
|
|
|
if ((DriveIndex < 0) || (format_thread != NULL))
|
2019-08-22 13:04:41 +00:00
|
|
|
return;
|
|
|
|
|
2022-05-25 12:21:36 +00:00
|
|
|
static_sprintf(filename, "%s.vhd", rufus_drive[DriveIndex].label);
|
2019-08-22 13:04:41 +00:00
|
|
|
img_save.Type = IMG_SAVE_TYPE_VHD;
|
|
|
|
img_save.DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, DriveIndex);
|
|
|
|
img_save.ImagePath = FileDialog(TRUE, NULL, &img_ext, 0);
|
|
|
|
img_save.BufSize = DD_BUFFER_SIZE;
|
|
|
|
img_save.DeviceSize = SelectedDrive.DiskSize;
|
|
|
|
if (img_save.ImagePath != NULL) {
|
|
|
|
// Reset all progress bars
|
|
|
|
SendMessage(hMainDialog, UM_PROGRESS_INIT, 0, 0);
|
|
|
|
FormatStatus = 0;
|
|
|
|
free_space.QuadPart = 0;
|
|
|
|
if ((GetVolumePathNameA(img_save.ImagePath, path, sizeof(path)))
|
|
|
|
&& (GetDiskFreeSpaceExA(path, &free_space, NULL, NULL))
|
|
|
|
&& ((LONGLONG)free_space.QuadPart > (SelectedDrive.DiskSize + 512))) {
|
|
|
|
// Disable all controls except cancel
|
|
|
|
EnableControls(FALSE, FALSE);
|
2015-08-14 22:09:45 +00:00
|
|
|
FormatStatus = 0;
|
2019-08-22 13:04:41 +00:00
|
|
|
InitProgress(TRUE);
|
2020-07-10 10:55:29 +00:00
|
|
|
format_thread = CreateThread(NULL, 0, SaveImageThread, &img_save, 0, NULL);
|
|
|
|
if (format_thread != NULL) {
|
2019-08-22 13:04:41 +00:00
|
|
|
uprintf("\r\nSave to VHD operation started");
|
|
|
|
PrintInfo(0, -1);
|
|
|
|
SendMessage(hMainDialog, UM_TIMER_START, 0, 0);
|
2016-12-06 11:47:19 +00:00
|
|
|
} else {
|
2019-08-22 13:04:41 +00:00
|
|
|
uprintf("Unable to start VHD save thread");
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
|
2016-12-06 11:47:19 +00:00
|
|
|
safe_free(img_save.ImagePath);
|
2015-08-14 22:09:45 +00:00
|
|
|
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
|
|
|
|
}
|
2019-08-22 13:04:41 +00:00
|
|
|
} else {
|
|
|
|
if (free_space.QuadPart == 0) {
|
|
|
|
uprintf("Unable to isolate drive name for VHD save");
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_PATH_NOT_FOUND;
|
|
|
|
} else {
|
|
|
|
uprintf("The VHD size is too large for the target drive");
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | ERROR_FILE_TOO_LARGE;
|
|
|
|
}
|
|
|
|
safe_free(img_save.ImagePath);
|
|
|
|
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
|
2015-08-14 22:09:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-25 13:32:19 +00:00
|
|
|
static void SaveISO(void)
|
2016-12-06 11:47:19 +00:00
|
|
|
{
|
|
|
|
static IMG_SAVE img_save = { 0 };
|
|
|
|
char filename[33] = "disc_image.iso";
|
|
|
|
EXT_DECL(img_ext, filename, __VA_GROUP__("*.iso"), __VA_GROUP__(lmprintf(MSG_036)));
|
|
|
|
|
2020-07-10 10:55:29 +00:00
|
|
|
if (op_in_progress || (format_thread != NULL))
|
2016-12-06 11:47:19 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
img_save.Type = IMG_SAVE_TYPE_ISO;
|
|
|
|
if (!GetOpticalMedia(&img_save)) {
|
|
|
|
uprintf("No dumpable optical media found.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Adjust the buffer size according to the disc size so that we get a decent speed.
|
|
|
|
for (img_save.BufSize = 32 * MB;
|
|
|
|
(img_save.BufSize > 8 * MB) && (img_save.DeviceSize <= img_save.BufSize * 64);
|
|
|
|
img_save.BufSize /= 2);
|
|
|
|
if ((img_save.Label != NULL) && (img_save.Label[0] != 0))
|
2017-08-10 18:43:04 +00:00
|
|
|
static_sprintf(filename, "%s.iso", img_save.Label);
|
2016-12-06 11:47:19 +00:00
|
|
|
uprintf("ISO media size %s", SizeToHumanReadable(img_save.DeviceSize, FALSE, FALSE));
|
|
|
|
|
|
|
|
img_save.ImagePath = FileDialog(TRUE, NULL, &img_ext, 0);
|
|
|
|
if (img_save.ImagePath == NULL)
|
|
|
|
return;
|
2019-03-07 16:29:43 +00:00
|
|
|
SendMessage(hMainDialog, UM_PROGRESS_INIT, 0, 0);
|
2016-12-06 11:47:19 +00:00
|
|
|
FormatStatus = 0;
|
|
|
|
// Disable all controls except cancel
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(FALSE, FALSE);
|
2016-12-06 11:47:19 +00:00
|
|
|
InitProgress(TRUE);
|
2020-07-10 10:55:29 +00:00
|
|
|
format_thread = CreateThread(NULL, 0, SaveImageThread, &img_save, 0, NULL);
|
|
|
|
if (format_thread != NULL) {
|
2016-12-06 11:47:19 +00:00
|
|
|
uprintf("\r\nSave to ISO operation started");
|
|
|
|
PrintInfo(0, -1);
|
2019-03-04 11:57:33 +00:00
|
|
|
SendMessage(hMainDialog, UM_TIMER_START, 0, 0);
|
2016-12-06 11:47:19 +00:00
|
|
|
} else {
|
|
|
|
uprintf("Unable to start ISO save thread");
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
|
|
|
|
safe_free(img_save.ImagePath);
|
|
|
|
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
|
|
|
|
}
|
|
|
|
}
|
2015-10-18 20:31:47 +00:00
|
|
|
|
2019-04-09 20:37:08 +00:00
|
|
|
// Check for conflicting processes accessing the drive.
|
|
|
|
// If bPrompt is true, ask the user whether they want to proceed.
|
|
|
|
// dwTimeOut is the maximum amount of time we allow for this call to execute (in ms)
|
|
|
|
// If bPrompt is false, the return value is the amount of time remaining before
|
|
|
|
// dwTimeOut would expire (or zero if we spent more than dwTimeout in this procedure).
|
2019-04-10 11:17:47 +00:00
|
|
|
// If bPrompt is true, the return value is 0 on error, dwTimeOut on success.
|
2019-04-09 20:37:08 +00:00
|
|
|
DWORD CheckDriveAccess(DWORD dwTimeOut, BOOL bPrompt)
|
2017-07-16 21:42:19 +00:00
|
|
|
{
|
|
|
|
uint32_t i, j;
|
2019-04-09 20:37:08 +00:00
|
|
|
DWORD ret = 0, proceed = TRUE;
|
2017-07-16 21:42:19 +00:00
|
|
|
BYTE access_mask;
|
2017-07-25 11:19:50 +00:00
|
|
|
char *PhysicalPath = NULL, DevPath[MAX_PATH];
|
2017-07-16 21:42:19 +00:00
|
|
|
char drive_letter[27], drive_name[] = "?:";
|
2019-01-09 15:53:44 +00:00
|
|
|
char title[128];
|
2019-04-09 20:37:08 +00:00
|
|
|
uint64_t start_time = GetTickCount64(), cur_time, end_time = start_time + dwTimeOut;
|
2017-07-16 21:42:19 +00:00
|
|
|
|
|
|
|
// Get the current selected device
|
2020-07-17 20:51:15 +00:00
|
|
|
DWORD DeviceNum = (DWORD)ComboBox_GetCurItemData(hDeviceList);
|
2017-07-16 21:42:19 +00:00
|
|
|
if ((DeviceNum < 0x80) || (DeviceNum == (DWORD)-1))
|
|
|
|
return FALSE;
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// "Checking for conflicting processes..."
|
2019-04-09 20:37:08 +00:00
|
|
|
if (bPrompt)
|
|
|
|
PrintInfo(0, MSG_278);
|
2017-07-24 10:36:06 +00:00
|
|
|
|
2017-07-16 21:42:19 +00:00
|
|
|
// Search for any blocking processes against the physical drive
|
|
|
|
PhysicalPath = GetPhysicalName(DeviceNum);
|
2017-07-25 11:19:50 +00:00
|
|
|
if (QueryDosDeviceA(&PhysicalPath[4], DevPath, sizeof(DevPath)) != 0) {
|
|
|
|
access_mask = SearchProcess(DevPath, dwTimeOut, TRUE, TRUE, TRUE);
|
|
|
|
CHECK_FOR_USER_CANCEL;
|
|
|
|
if (access_mask != 0) {
|
|
|
|
proceed = FALSE;
|
|
|
|
uprintf("Found potentially blocking process(es) against %s:", &PhysicalPath[4]);
|
|
|
|
for (j = 0; j < BlockingProcess.Index; j++)
|
|
|
|
uprintf(BlockingProcess.String[j]);
|
|
|
|
}
|
2017-07-16 21:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Search for any blocking processes against the logical volume(s)
|
|
|
|
GetDriveLetters(DeviceNum, drive_letter);
|
|
|
|
for (i = 0; drive_letter[i]; i++) {
|
|
|
|
drive_name[0] = drive_letter[i];
|
|
|
|
if (QueryDosDeviceA(drive_name, DevPath, sizeof(DevPath)) != 0) {
|
|
|
|
StrArrayClear(&BlockingProcess);
|
2017-11-13 14:29:48 +00:00
|
|
|
cur_time = GetTickCount64();
|
2017-07-24 10:36:06 +00:00
|
|
|
if (cur_time >= end_time)
|
|
|
|
break;
|
2017-11-13 14:29:48 +00:00
|
|
|
access_mask = SearchProcess(DevPath, (DWORD)(end_time - cur_time), TRUE, TRUE, TRUE);
|
2017-07-24 10:36:06 +00:00
|
|
|
CHECK_FOR_USER_CANCEL;
|
2017-07-16 21:42:19 +00:00
|
|
|
// Ignore if all we have is read-only
|
|
|
|
if ((access_mask & 0x06) || (access_mask == 0x80)) {
|
2017-07-25 11:19:50 +00:00
|
|
|
proceed = FALSE;
|
2017-07-16 21:42:19 +00:00
|
|
|
uprintf("Found potentially blocking process(es) against %s", drive_name);
|
|
|
|
for (j = 0; j < BlockingProcess.Index; j++)
|
|
|
|
uprintf(BlockingProcess.String[j]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Prompt the user if we detected blocking processes
|
2019-04-09 20:37:08 +00:00
|
|
|
if (bPrompt && !proceed) {
|
2019-01-09 15:53:44 +00:00
|
|
|
ComboBox_GetTextU(hDeviceList, title, sizeof(title));
|
|
|
|
proceed = Notification(MSG_WARNING_QUESTION, NULL, NULL, title, lmprintf(MSG_132));
|
2017-07-16 21:42:19 +00:00
|
|
|
}
|
2019-04-09 20:37:08 +00:00
|
|
|
if (bPrompt) {
|
2019-04-10 11:17:47 +00:00
|
|
|
ret = proceed ? dwTimeOut : 0;
|
2019-04-09 20:37:08 +00:00
|
|
|
} else {
|
|
|
|
ret = (DWORD)(GetTickCount64() - start_time);
|
|
|
|
ret = (dwTimeOut > ret) ? (dwTimeOut - ret) : 0;
|
|
|
|
}
|
2017-07-16 21:42:19 +00:00
|
|
|
|
2017-07-24 10:36:06 +00:00
|
|
|
out:
|
|
|
|
PrintInfo(0, MSG_210);
|
2017-07-25 11:19:50 +00:00
|
|
|
free(PhysicalPath);
|
|
|
|
return ret;
|
2017-07-16 21:42:19 +00:00
|
|
|
}
|
|
|
|
|
2011-11-17 01:43:06 +00:00
|
|
|
/*
|
2011-11-21 17:06:17 +00:00
|
|
|
* Main dialog callback
|
|
|
|
*/
|
2011-11-18 01:58:08 +00:00
|
|
|
static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
2011-11-13 20:53:23 +00:00
|
|
|
{
|
2016-02-24 16:10:54 +00:00
|
|
|
static DWORD DeviceNum = 0;
|
2018-07-18 11:22:37 +00:00
|
|
|
static uint64_t LastRefresh = 0;
|
2016-07-08 11:09:46 +00:00
|
|
|
static BOOL first_log_display = TRUE, isMarquee = FALSE, queued_hotplug_event = FALSE;
|
2013-12-20 18:32:10 +00:00
|
|
|
static ULONG ulRegister = 0;
|
|
|
|
static LPITEMIDLIST pidlDesktop = NULL;
|
2017-11-13 14:29:48 +00:00
|
|
|
static SHChangeNotifyEntry NotifyEntry;
|
2020-09-09 16:00:39 +00:00
|
|
|
static DWORD_PTR thread_affinity[CHECKSUM_MAX + 1];
|
2018-03-22 23:14:20 +00:00
|
|
|
static HFONT hyperlink_font = NULL;
|
2022-01-05 11:57:26 +00:00
|
|
|
static wchar_t wtooltip[128];
|
2018-07-18 11:22:37 +00:00
|
|
|
LONG lPos;
|
2018-05-06 21:31:42 +00:00
|
|
|
BOOL set_selected_fs;
|
2015-01-01 23:39:28 +00:00
|
|
|
DRAWITEMSTRUCT* pDI;
|
2018-03-22 23:14:20 +00:00
|
|
|
LPTOOLTIPTEXT lpttt;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
NMBCDROPDOWN* pDropDown;
|
2016-01-15 17:20:45 +00:00
|
|
|
HDROP droppedFileInfo;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
HMENU hMenu;
|
2015-01-01 23:39:28 +00:00
|
|
|
POINT Point;
|
2018-03-22 23:14:20 +00:00
|
|
|
RECT rc, DialogRect, DesktopRect;
|
2015-09-24 22:59:10 +00:00
|
|
|
HDC hDC;
|
2018-04-16 15:05:23 +00:00
|
|
|
PAINTSTRUCT ps;
|
2021-07-28 15:37:45 +00:00
|
|
|
DWORD log_size;
|
2019-03-07 16:29:43 +00:00
|
|
|
int nDeviceIndex, i, nWidth, nHeight, nb_devices, selected_language, offset, tb_state, tb_flags;
|
2021-07-28 15:37:45 +00:00
|
|
|
char tmp[MAX_PATH], *log_buffer = NULL;
|
2016-01-15 17:20:45 +00:00
|
|
|
wchar_t* wbuffer = NULL;
|
2013-10-24 21:57:34 +00:00
|
|
|
loc_cmd* lcmd = NULL;
|
2011-11-21 17:06:17 +00:00
|
|
|
|
2011-11-13 20:53:23 +00:00
|
|
|
switch (message) {
|
|
|
|
|
2016-07-09 15:20:58 +00:00
|
|
|
case WM_COMMAND:
|
|
|
|
#ifdef RUFUS_TEST
|
|
|
|
if (LOWORD(wParam) == IDC_TEST) {
|
|
|
|
break;
|
2013-12-20 18:32:10 +00:00
|
|
|
}
|
2014-11-20 22:57:22 +00:00
|
|
|
#endif
|
2011-11-13 20:53:23 +00:00
|
|
|
|
2013-10-24 21:57:34 +00:00
|
|
|
if ((LOWORD(wParam) >= UM_LANGUAGE_MENU) && (LOWORD(wParam) < UM_LANGUAGE_MENU_MAX)) {
|
|
|
|
selected_language = LOWORD(wParam) - UM_LANGUAGE_MENU;
|
|
|
|
i = 0;
|
|
|
|
list_for_each_entry(lcmd, &locale_list, loc_cmd, list) {
|
|
|
|
if (i++ == selected_language) {
|
|
|
|
if (selected_locale != lcmd) {
|
|
|
|
selected_locale = lcmd;
|
2015-10-18 20:31:47 +00:00
|
|
|
selected_langid = get_language_id(lcmd);
|
2018-10-23 21:35:39 +00:00
|
|
|
// Avoid the FS being reset on language change
|
2020-07-17 20:51:15 +00:00
|
|
|
selected_fs = (int)ComboBox_GetCurItemData(hFileSystem);
|
2013-10-24 21:57:34 +00:00
|
|
|
relaunch = TRUE;
|
|
|
|
PostMessage(hDlg, WM_COMMAND, IDCANCEL, 0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-11-13 20:53:23 +00:00
|
|
|
switch(LOWORD(wParam)) {
|
2011-11-21 20:12:23 +00:00
|
|
|
case IDOK: // close application
|
|
|
|
case IDCANCEL:
|
2012-02-07 16:17:14 +00:00
|
|
|
EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
|
2020-07-10 10:55:29 +00:00
|
|
|
if (format_thread != NULL) {
|
2015-10-18 20:31:47 +00:00
|
|
|
if ((no_confirmation_on_cancel) || (MessageBoxExU(hMainDialog, lmprintf(MSG_105), lmprintf(MSG_049),
|
|
|
|
MB_YESNO|MB_ICONWARNING|MB_IS_RTL, selected_langid) == IDYES)) {
|
2011-11-28 12:37:58 +00:00
|
|
|
// Operation may have completed in the meantime
|
2020-07-10 10:55:29 +00:00
|
|
|
if (format_thread != NULL) {
|
2011-11-28 12:37:58 +00:00
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_201);
|
|
|
|
uprintf("Cancelling");
|
2012-02-07 16:17:14 +00:00
|
|
|
// Start a timer to detect blocking operations during ISO file extraction
|
|
|
|
if (iso_blocking_status >= 0) {
|
|
|
|
last_iso_blocking_status = iso_blocking_status;
|
|
|
|
SetTimer(hMainDialog, TID_BLOCKING_TIMER, 3000, BlockingTimer);
|
|
|
|
}
|
2011-11-28 01:32:18 +00:00
|
|
|
}
|
2012-02-07 16:17:14 +00:00
|
|
|
} else {
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE);
|
2011-11-28 01:32:18 +00:00
|
|
|
}
|
2015-06-29 22:43:49 +00:00
|
|
|
no_confirmation_on_cancel = FALSE;
|
2011-11-28 01:32:18 +00:00
|
|
|
return (INT_PTR)TRUE;
|
2019-08-22 13:04:41 +00:00
|
|
|
} else if (op_in_progress) {
|
2017-07-24 10:36:06 +00:00
|
|
|
// User might be trying to cancel during preliminary checks
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED;
|
|
|
|
PrintInfo(0, MSG_201);
|
2018-07-04 21:50:26 +00:00
|
|
|
EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE);
|
2017-07-24 10:36:06 +00:00
|
|
|
return (INT_PTR)TRUE;
|
2011-11-28 01:32:18 +00:00
|
|
|
}
|
2021-07-28 15:37:45 +00:00
|
|
|
|
|
|
|
// Save the current log to %LocalAppData%\Rufus\rufus.log
|
|
|
|
log_size = GetWindowTextLengthU(hLog);
|
2021-09-19 20:01:45 +00:00
|
|
|
if ((!user_deleted_rufus_dir) && (log_size > 0) && ((log_buffer = (char*)malloc(log_size)) != NULL)) {
|
2021-07-28 15:37:45 +00:00
|
|
|
log_size = GetDlgItemTextU(hLogDialog, IDC_LOG_EDIT, log_buffer, log_size);
|
|
|
|
if (log_size-- > 1) {
|
2021-09-19 20:01:45 +00:00
|
|
|
IGNORE_RETVAL(_chdirU(app_data_dir));
|
|
|
|
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
|
|
|
IGNORE_RETVAL(_chdir(FILES_DIR));
|
|
|
|
FileIO(TRUE, "rufus.log", &log_buffer, &log_size);
|
2021-07-28 15:37:45 +00:00
|
|
|
}
|
|
|
|
safe_free(log_buffer);
|
|
|
|
}
|
|
|
|
|
2017-11-13 14:29:48 +00:00
|
|
|
if (ulRegister != 0)
|
|
|
|
SHChangeNotifyDeregister(ulRegister);
|
2011-11-21 20:12:23 +00:00
|
|
|
PostQuitMessage(0);
|
2022-05-25 12:21:36 +00:00
|
|
|
ClearDrives();
|
2017-07-11 16:43:51 +00:00
|
|
|
StrArrayDestroy(&BlockingProcess);
|
2018-03-22 23:14:20 +00:00
|
|
|
StrArrayDestroy(&ImageList);
|
2011-11-21 20:25:32 +00:00
|
|
|
DestroyAllTooltips();
|
2018-03-22 23:14:20 +00:00
|
|
|
DestroyWindow(hLogDialog);
|
2013-10-24 21:57:34 +00:00
|
|
|
GetWindowRect(hDlg, &relaunch_rc);
|
2011-11-21 20:12:23 +00:00
|
|
|
EndDialog(hDlg, 0);
|
|
|
|
break;
|
2011-11-21 17:06:17 +00:00
|
|
|
case IDC_ABOUT:
|
|
|
|
CreateAboutBox();
|
|
|
|
break;
|
2012-05-30 23:32:25 +00:00
|
|
|
case IDC_LOG:
|
2014-01-24 02:46:06 +00:00
|
|
|
// Place the log Window to the right (or left for RTL) of our dialog on first display
|
2012-05-30 23:32:25 +00:00
|
|
|
if (first_log_display) {
|
|
|
|
GetClientRect(GetDesktopWindow(), &DesktopRect);
|
2018-03-22 23:14:20 +00:00
|
|
|
GetWindowRect(hLogDialog, &DialogRect);
|
2012-05-30 23:32:25 +00:00
|
|
|
nWidth = DialogRect.right - DialogRect.left;
|
|
|
|
nHeight = DialogRect.bottom - DialogRect.top;
|
|
|
|
GetWindowRect(hDlg, &DialogRect);
|
2018-05-09 14:55:30 +00:00
|
|
|
offset = GetSystemMetrics(SM_CXBORDER);
|
|
|
|
if (nWindowsVersion >= WINDOWS_10) {
|
|
|
|
// See https://stackoverflow.com/a/42491227/1069307
|
|
|
|
// I agree with Stephen Hazel: Whoever at Microsoft thought it would be a great idea to
|
|
|
|
// add a *FRIGGING INVISIBLE BORDER* in Windows 10 should face the harshest punishment!
|
2022-04-12 12:55:33 +00:00
|
|
|
// Also calling this API will create DLL sideloading issues through 'dwmapi.dll' so make
|
|
|
|
// sure you delay-load it in your application.
|
|
|
|
DwmGetWindowAttribute(hDlg, DWMWA_EXTENDED_FRAME_BOUNDS, &rc, sizeof(RECT));
|
|
|
|
offset += 2 * (DialogRect.left - rc.left);
|
2018-05-09 14:55:30 +00:00
|
|
|
}
|
2014-01-24 02:46:06 +00:00
|
|
|
if (right_to_left_mode)
|
2015-02-08 00:38:21 +00:00
|
|
|
Point.x = max(DialogRect.left - offset - nWidth, 0);
|
2014-01-24 02:46:06 +00:00
|
|
|
else
|
2015-02-08 00:38:21 +00:00
|
|
|
Point.x = min(DialogRect.right + offset, DesktopRect.right - nWidth);
|
2015-10-18 20:31:47 +00:00
|
|
|
|
2012-05-30 23:32:25 +00:00
|
|
|
Point.y = max(DialogRect.top, DesktopRect.top - nHeight);
|
2018-03-22 23:14:20 +00:00
|
|
|
MoveWindow(hLogDialog, Point.x, Point.y, nWidth, nHeight, FALSE);
|
2014-01-24 02:46:06 +00:00
|
|
|
// The log may have been recentered to fit the screen, in which case, try to shift our main dialog left (or right for RTL)
|
2013-06-25 21:50:22 +00:00
|
|
|
nWidth = DialogRect.right - DialogRect.left;
|
|
|
|
nHeight = DialogRect.bottom - DialogRect.top;
|
2014-01-24 02:46:06 +00:00
|
|
|
if (right_to_left_mode) {
|
|
|
|
Point.x = DialogRect.left;
|
2018-03-22 23:14:20 +00:00
|
|
|
GetWindowRect(hLogDialog, &DialogRect);
|
2015-02-08 00:38:21 +00:00
|
|
|
Point.x = max(Point.x, DialogRect.right - DialogRect.left + offset);
|
2014-01-24 02:46:06 +00:00
|
|
|
} else {
|
2015-02-08 00:38:21 +00:00
|
|
|
Point.x = max((DialogRect.left<0)?DialogRect.left:0, Point.x - offset - nWidth);
|
2014-01-24 02:46:06 +00:00
|
|
|
}
|
|
|
|
MoveWindow(hDlg, Point.x, Point.y, nWidth, nHeight, TRUE);
|
2012-05-30 23:32:25 +00:00
|
|
|
first_log_display = FALSE;
|
|
|
|
}
|
|
|
|
// Display the log Window
|
|
|
|
log_displayed = !log_displayed;
|
|
|
|
// Set focus on the start button
|
|
|
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)FALSE, 0);
|
2015-04-19 03:15:44 +00:00
|
|
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)hStart, TRUE);
|
2013-06-25 21:50:22 +00:00
|
|
|
// Must come last for the log window to get focus
|
2018-03-22 23:14:20 +00:00
|
|
|
ShowWindow(hLogDialog, log_displayed?SW_SHOW:SW_HIDE);
|
2012-05-30 23:32:25 +00:00
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_ADVANCED_DRIVE_PROPERTIES:
|
|
|
|
advanced_mode_device = !advanced_mode_device;
|
|
|
|
WriteSettingBool(SETTING_ADVANCED_MODE_DEVICE, advanced_mode_device);
|
|
|
|
ToggleAdvancedDeviceOptions(advanced_mode_device);
|
|
|
|
SetBootOptions();
|
2020-07-17 20:51:15 +00:00
|
|
|
boot_type = (int)ComboBox_GetCurItemData(hBootType);
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
2018-03-22 23:14:20 +00:00
|
|
|
SetFileSystemAndClusterSize(NULL);
|
2018-05-06 21:31:42 +00:00
|
|
|
SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE_INTERNAL<<16) | IDC_FILE_SYSTEM,
|
2012-05-16 22:38:39 +00:00
|
|
|
ComboBox_GetCurSel(hFileSystem));
|
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_ADVANCED_FORMAT_OPTIONS:
|
|
|
|
advanced_mode_format = !advanced_mode_format;
|
|
|
|
WriteSettingBool(SETTING_ADVANCED_MODE_FORMAT, advanced_mode_format);
|
|
|
|
ToggleAdvancedFormatOptions(advanced_mode_format);
|
2019-05-03 22:51:05 +00:00
|
|
|
if (selected_fs == FS_UNKNOWN)
|
2020-07-17 20:51:15 +00:00
|
|
|
selected_fs = (int)ComboBox_GetCurItemData(hFileSystem);
|
2019-05-03 22:51:05 +00:00
|
|
|
SetFileSystemAndClusterSize(NULL);
|
|
|
|
SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE_INTERNAL << 16) | IDC_FILE_SYSTEM,
|
|
|
|
ComboBox_GetCurSel(hFileSystem));
|
2018-03-22 23:14:20 +00:00
|
|
|
break;
|
2012-11-04 21:39:25 +00:00
|
|
|
case IDC_LABEL:
|
2016-01-09 05:06:45 +00:00
|
|
|
if (HIWORD(wParam) == EN_CHANGE) {
|
|
|
|
// We will get EN_CHANGE when we change the label automatically, so we need to detect that
|
|
|
|
if (!app_changed_label)
|
|
|
|
user_changed_label = TRUE;
|
|
|
|
app_changed_label = FALSE;
|
|
|
|
}
|
2012-11-04 21:39:25 +00:00
|
|
|
break;
|
2011-11-24 02:24:50 +00:00
|
|
|
case IDC_DEVICE:
|
2012-03-03 23:12:48 +00:00
|
|
|
if (HIWORD(wParam) != CBN_SELCHANGE)
|
2011-11-18 23:41:28 +00:00
|
|
|
break;
|
2013-10-15 21:58:27 +00:00
|
|
|
nb_devices = ComboBox_GetCount(hDeviceList);
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintStatusDebug(0, (nb_devices==1)?MSG_208:MSG_209, nb_devices);
|
2018-05-06 21:31:42 +00:00
|
|
|
PopulateProperties();
|
2017-10-23 16:09:18 +00:00
|
|
|
nDeviceIndex = ComboBox_GetCurSel(hDeviceList);
|
|
|
|
DeviceNum = (nDeviceIndex == CB_ERR) ? 0 : (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex);
|
2018-05-06 21:31:42 +00:00
|
|
|
SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE_INTERNAL << 16) | IDC_FILE_SYSTEM,
|
|
|
|
ComboBox_GetCurSel(hFileSystem));
|
2011-11-27 23:40:28 +00:00
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_IMAGE_OPTION:
|
2018-04-13 10:17:09 +00:00
|
|
|
if (HIWORD(wParam) != CBN_SELCHANGE)
|
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
SetFileSystemAndClusterSize(NULL);
|
2021-10-08 18:22:33 +00:00
|
|
|
imop_win_sel = ComboBox_GetCurSel(hImageOption);
|
2018-03-22 23:14:20 +00:00
|
|
|
break;
|
2018-07-18 11:22:37 +00:00
|
|
|
case IDC_PERSISTENCE_SIZE:
|
|
|
|
if (HIWORD(wParam) == EN_CHANGE) {
|
|
|
|
uint64_t pos;
|
|
|
|
// We get EN_CHANGE when we change the size automatically, so we need to detect that
|
|
|
|
if (app_changed_size) {
|
|
|
|
app_changed_size = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
GetWindowTextA(GetDlgItem(hDlg, IDC_PERSISTENCE_SIZE), tmp, sizeof(tmp));
|
|
|
|
lPos = atol(tmp);
|
|
|
|
persistence_unit_selection = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_PERSISTENCE_UNITS));
|
|
|
|
persistence_size = lPos * MB;
|
|
|
|
for (i = 0; i < persistence_unit_selection; i++)
|
|
|
|
persistence_size *= 1024;
|
2021-06-10 16:18:40 +00:00
|
|
|
if (persistence_size > SelectedDrive.DiskSize - PERCENTAGE(PROJECTED_SIZE_RATIO, img_report.projected_size))
|
|
|
|
persistence_size = SelectedDrive.DiskSize - PERCENTAGE(PROJECTED_SIZE_RATIO, img_report.projected_size);
|
2018-07-18 11:22:37 +00:00
|
|
|
pos = persistence_size / MB;
|
|
|
|
for (i = 0; i < persistence_unit_selection; i++)
|
|
|
|
pos /= 1024;
|
|
|
|
lPos = (LONG)pos;
|
|
|
|
SendMessage(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SLIDER), TBM_SETPOS, TRUE, lPos);
|
2021-06-10 16:18:40 +00:00
|
|
|
if (persistence_size >= (SelectedDrive.DiskSize - PERCENTAGE(PROJECTED_SIZE_RATIO, img_report.projected_size))) {
|
2018-07-18 15:59:35 +00:00
|
|
|
static_sprintf(tmp, "%ld", lPos);
|
2018-07-18 11:22:37 +00:00
|
|
|
app_changed_size = TRUE;
|
|
|
|
SetWindowTextU(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SIZE), tmp);
|
|
|
|
}
|
|
|
|
} else if (HIWORD(wParam) == EN_KILLFOCUS) {
|
|
|
|
if (persistence_size == 0) {
|
|
|
|
TogglePersistenceControls(FALSE);
|
|
|
|
static_sprintf(tmp, "0 (%s)", lmprintf(MSG_124));
|
|
|
|
app_changed_size = TRUE;
|
|
|
|
SetWindowTextU(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SIZE), tmp);
|
2020-10-02 12:58:15 +00:00
|
|
|
} else if (persistence_size < MIN_EXT_SIZE) {
|
|
|
|
persistence_size = MIN_EXT_SIZE;
|
|
|
|
uint64_t pos = persistence_size / MB;
|
|
|
|
for (i = 0; i < persistence_unit_selection; i++)
|
|
|
|
pos /= 1024;
|
|
|
|
lPos = (LONG)pos;
|
|
|
|
SendMessage(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SLIDER), TBM_SETPOS, TRUE, lPos);
|
|
|
|
static_sprintf(tmp, "%ld", lPos);
|
|
|
|
app_changed_size = TRUE;
|
|
|
|
SetWindowTextU(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SIZE), tmp);
|
2018-07-18 11:22:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2018-07-06 10:23:57 +00:00
|
|
|
case IDC_PERSISTENCE_UNITS:
|
|
|
|
if (HIWORD(wParam) != CBN_SELCHANGE)
|
|
|
|
break;
|
|
|
|
if (ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_PERSISTENCE_UNITS)) == persistence_unit_selection)
|
|
|
|
break;
|
|
|
|
GetWindowTextA(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SIZE), tmp, sizeof(tmp));
|
2018-07-18 11:22:37 +00:00
|
|
|
persistence_size = atol(tmp) * MB;
|
2018-07-06 10:23:57 +00:00
|
|
|
for (i = 0; i < persistence_unit_selection; i++)
|
2018-07-18 11:22:37 +00:00
|
|
|
persistence_size *= 1024;
|
2018-07-06 10:23:57 +00:00
|
|
|
persistence_unit_selection = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_PERSISTENCE_UNITS));
|
2018-08-14 22:05:52 +00:00
|
|
|
SetPersistenceSize();
|
2018-07-06 10:23:57 +00:00
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_NB_PASSES:
|
2012-03-03 23:12:48 +00:00
|
|
|
if (HIWORD(wParam) != CBN_SELCHANGE)
|
|
|
|
break;
|
2013-01-25 01:38:10 +00:00
|
|
|
SetPassesTooltip();
|
2012-02-07 23:16:15 +00:00
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_TARGET_SYSTEM:
|
|
|
|
if (HIWORD(wParam) != CBN_SELCHANGE)
|
|
|
|
break;
|
2020-07-17 20:51:15 +00:00
|
|
|
target_type = (int)ComboBox_GetCurItemData(hTargetSystem);
|
2018-03-22 23:14:20 +00:00
|
|
|
SendMessage(hMainDialog, UM_UPDATE_CSM_TOOLTIP, 0, 0);
|
|
|
|
SetFileSystemAndClusterSize(NULL);
|
|
|
|
break;
|
2013-10-15 21:58:27 +00:00
|
|
|
case IDC_PARTITION_TYPE:
|
2013-01-27 01:40:09 +00:00
|
|
|
if (HIWORD(wParam) != CBN_SELCHANGE)
|
|
|
|
break;
|
2020-07-17 20:51:15 +00:00
|
|
|
partition_type = (int)ComboBox_GetCurItemData(hPartitionScheme);
|
2018-03-22 23:14:20 +00:00
|
|
|
SetPartitionSchemeAndTargetSystem(TRUE);
|
|
|
|
SetFileSystemAndClusterSize(NULL);
|
2021-04-08 16:29:13 +00:00
|
|
|
SetMBRProps();
|
2019-07-02 16:49:33 +00:00
|
|
|
EnableMBRBootOptions(TRUE, TRUE);
|
2019-04-13 14:29:27 +00:00
|
|
|
selected_pt = partition_type;
|
2018-03-22 23:14:20 +00:00
|
|
|
break;
|
|
|
|
case IDC_FILE_SYSTEM:
|
2018-05-06 21:31:42 +00:00
|
|
|
if ((HIWORD(wParam) != CBN_SELCHANGE) && (HIWORD(wParam) != CBN_SELCHANGE_INTERNAL))
|
2012-02-02 13:16:49 +00:00
|
|
|
break;
|
2018-05-06 21:31:42 +00:00
|
|
|
set_selected_fs = (HIWORD(wParam) == CBN_SELCHANGE);
|
2020-07-17 20:51:15 +00:00
|
|
|
fs_type = (int)ComboBox_GetCurItemData(hFileSystem);
|
2019-04-13 14:29:27 +00:00
|
|
|
SetClusterSizes(fs_type);
|
|
|
|
if (set_selected_fs && (fs_type > 0))
|
|
|
|
selected_fs = fs_type;
|
2019-08-24 22:45:53 +00:00
|
|
|
// Some FS's (such as ReFS or Large FAT32) only have QuickFormat so make sure we reflect that
|
|
|
|
EnableQuickFormat(TRUE, TRUE);
|
2019-07-02 16:49:33 +00:00
|
|
|
EnableMBRBootOptions(TRUE, TRUE);
|
2012-05-16 22:38:39 +00:00
|
|
|
SetMBRProps();
|
2019-08-24 22:45:53 +00:00
|
|
|
EnableExtendedLabel(TRUE, TRUE);
|
2012-02-16 11:37:59 +00:00
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_BOOT_SELECTION:
|
2018-04-13 10:17:09 +00:00
|
|
|
if (HIWORD(wParam) != CBN_SELCHANGE)
|
|
|
|
break;
|
2020-07-17 20:51:15 +00:00
|
|
|
boot_type = (int)ComboBox_GetCurItemData(hBootType);
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((HIWORD(wParam) != CBN_SELCHANGE) || (boot_type == selection_default))
|
2012-02-07 23:16:15 +00:00
|
|
|
break;
|
2019-04-13 14:29:27 +00:00
|
|
|
selection_default = boot_type;
|
2018-03-22 23:14:20 +00:00
|
|
|
SetPartitionSchemeAndTargetSystem(FALSE);
|
2018-05-06 21:31:42 +00:00
|
|
|
// Try to reselect current FS from the drive for non-bootable
|
|
|
|
tmp[0] = 0;
|
2018-10-23 19:10:52 +00:00
|
|
|
if ((selected_fs == FS_UNKNOWN) && (SelectedDrive.DeviceNumber != 0))
|
2020-07-03 14:24:37 +00:00
|
|
|
GetDrivePartitionData(SelectedDrive.DeviceNumber, tmp, sizeof(tmp), !usb_debug);
|
2018-05-06 21:31:42 +00:00
|
|
|
SetFileSystemAndClusterSize(tmp);
|
2018-07-18 11:22:37 +00:00
|
|
|
ToggleImageOptions();
|
2016-01-09 05:06:45 +00:00
|
|
|
SetProposedLabel(ComboBox_GetCurSel(hDeviceList));
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, TRUE);
|
2020-07-17 20:51:15 +00:00
|
|
|
target_type = (int)ComboBox_GetCurItemData(hPartitionScheme);
|
|
|
|
partition_type = (int)ComboBox_GetCurItemData(hTargetSystem);
|
2012-02-16 11:37:59 +00:00
|
|
|
return (INT_PTR)TRUE;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_SELECT:
|
2020-06-10 20:25:33 +00:00
|
|
|
// Ctrl-SELECT is used to select an additional archive of files to extract
|
|
|
|
// For now only zip archives are supported.
|
|
|
|
if (GetKeyState(VK_CONTROL) & 0x8000) {
|
|
|
|
EXT_DECL(arch_ext, NULL, __VA_GROUP__("*.zip"), __VA_GROUP__(lmprintf(MSG_309)));
|
|
|
|
if (image_path == NULL)
|
|
|
|
break;
|
|
|
|
archive_path = FileDialog(FALSE, NULL, &arch_ext, 0);
|
|
|
|
if (archive_path != NULL) {
|
|
|
|
struct __stat64 stat64 = { 0 };
|
|
|
|
_stat64U(archive_path, &stat64);
|
|
|
|
img_report.projected_size -= img_report.archive_size;
|
|
|
|
img_report.archive_size = stat64.st_size;
|
|
|
|
img_report.projected_size += img_report.archive_size;
|
|
|
|
uprintf("Using archive: %s (%s)", _filenameU(archive_path),
|
|
|
|
SizeToHumanReadable(img_report.archive_size, FALSE, FALSE));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
if (select_index == 1) {
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(FALSE, FALSE);
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
DownloadISO();
|
2013-02-04 01:14:28 +00:00
|
|
|
} else {
|
2020-07-19 21:35:30 +00:00
|
|
|
if (img_provided) {
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
uprintf("\r\nImage provided: '%s'", image_path);
|
2020-07-19 21:35:30 +00:00
|
|
|
img_provided = FALSE; // One off thing...
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
} else {
|
|
|
|
char* old_image_path = image_path;
|
|
|
|
// If declared globaly, lmprintf(MSG_036) would be called on each message...
|
2021-06-22 18:05:29 +00:00
|
|
|
EXT_DECL(img_ext, NULL, __VA_GROUP__("*.iso;*.img;*.vhd;*.usb;*.bz2;*.bzip2;*.gz;*.lzma;*.xz;*.Z;*.zip;*.wim;*.esd;*.vtsi"),
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
__VA_GROUP__(lmprintf(MSG_036)));
|
|
|
|
image_path = FileDialog(FALSE, NULL, &img_ext, 0);
|
|
|
|
if (image_path == NULL) {
|
|
|
|
if (old_image_path != NULL) {
|
|
|
|
// Reselect previous image
|
|
|
|
image_path = old_image_path;
|
|
|
|
} else {
|
|
|
|
CreateTooltip(hSelectImage, lmprintf(MSG_173), -1);
|
|
|
|
PrintStatus(0, MSG_086);
|
|
|
|
}
|
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
} else {
|
2020-06-10 20:25:33 +00:00
|
|
|
safe_free(archive_path);
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
free(old_image_path);
|
2018-03-22 23:14:20 +00:00
|
|
|
}
|
2013-02-04 01:14:28 +00:00
|
|
|
}
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
FormatStatus = 0;
|
2020-07-19 21:35:30 +00:00
|
|
|
if (CreateThread(NULL, 0, ImageScanThread, NULL, 0, NULL) == NULL) {
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
uprintf("Unable to start ISO scanning thread");
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
|
|
|
|
}
|
2012-02-02 13:16:49 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-05-25 16:54:06 +00:00
|
|
|
case IDC_RUFUS_MBR:
|
|
|
|
if ((HIWORD(wParam)) == BN_CLICKED)
|
|
|
|
mbr_selected_by_user = IsChecked(IDC_RUFUS_MBR);
|
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_LIST_USB_HDD:
|
2013-06-03 20:32:22 +00:00
|
|
|
if ((HIWORD(wParam)) == BN_CLICKED) {
|
2013-11-14 01:21:50 +00:00
|
|
|
enable_HDDs = !enable_HDDs;
|
2016-05-09 12:40:54 +00:00
|
|
|
PrintStatusTimeout(lmprintf(MSG_253), enable_HDDs);
|
2016-04-26 12:57:07 +00:00
|
|
|
GetDevices(0);
|
2013-06-03 20:32:22 +00:00
|
|
|
}
|
|
|
|
break;
|
2011-11-23 12:27:51 +00:00
|
|
|
case IDC_START:
|
2020-07-10 10:55:29 +00:00
|
|
|
if (format_thread != NULL)
|
2011-11-27 23:40:28 +00:00
|
|
|
return (INT_PTR)TRUE;
|
2018-03-22 23:14:20 +00:00
|
|
|
// Just in case
|
2020-07-17 20:51:15 +00:00
|
|
|
boot_type = (int)ComboBox_GetCurItemData(hBootType);
|
|
|
|
partition_type = (int)ComboBox_GetCurItemData(hPartitionScheme);
|
|
|
|
target_type = (int)ComboBox_GetCurItemData(hTargetSystem);
|
|
|
|
fs_type = (int)ComboBox_GetCurItemData(hFileSystem);
|
2018-03-22 23:14:20 +00:00
|
|
|
write_as_image = FALSE;
|
2020-06-06 21:19:20 +00:00
|
|
|
write_as_esp = FALSE;
|
[wue] add automatic local account creation and regional settings duplication
* Local account is created with the same name as the current user along with an *empty* password
(which we force the user to change on next logon). This is done to assuage users who might be
weary of entering a password in a third party application, and has the benefit of enabling
autologon when the install is complete.
* Note that the creation of a local account through an answer file prevents Windows 11 22H2
from bugging users about MSA *even with an active network connection*.
* For convenience reasons, only duplication of the current username is enabled. We *may* add a
dialog to enter any random username in a future version, but for 3.20, this is all you get.
* Likewise, the locale duplication is only carried out during OOBE and *not* WinPE (which means
that you still get the initial "Windows setup language and user preferences" prompt). This is
intentional as otherwise the default screen and "Repair Windows" options are not presented.
* It's not my fault that the Windows password change screen is super ill conceived, whereas it
doesn't hide the current password field as it should when the current password is blank, and
one needs to click on a very small arrow to get the changes applied, instead of a PROMINENT
button that should intuitively have been positioned right next to "Cancel".
* If you want to complain that we should just "present the user with XYZ and be done with it",
please bear in mind that we can't add new dialogs to Rufus as willy-nilly as you believe we
can. *ANY* new UI interface requires major planning, which is the reason why, for the time
being, we are limited to reusing a simple dissociated list of checkboxes for all WUE options.
2022-07-19 18:06:42 +00:00
|
|
|
unattend_xml_flags = 0;
|
2017-07-22 14:17:24 +00:00
|
|
|
// Disable all controls except Cancel
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(FALSE, FALSE);
|
2012-02-01 14:26:36 +00:00
|
|
|
FormatStatus = 0;
|
2019-04-09 20:37:08 +00:00
|
|
|
LastWriteError = 0;
|
2017-07-11 16:43:51 +00:00
|
|
|
StrArrayClear(&BlockingProcess);
|
2015-06-29 22:43:49 +00:00
|
|
|
no_confirmation_on_cancel = FALSE;
|
2019-03-07 16:29:43 +00:00
|
|
|
SendMessage(hMainDialog, UM_PROGRESS_INIT, 0, 0);
|
2020-07-17 20:51:15 +00:00
|
|
|
selection_default = (int)ComboBox_GetCurItemData(hBootType);
|
2018-07-03 21:54:06 +00:00
|
|
|
// Create a thread to validate options and download files as needed (so that we can update the UI).
|
|
|
|
// On exit, this thread sends message UM_FORMAT_START back to this dialog.
|
|
|
|
if (CreateThread(NULL, 0, BootCheckThread, NULL, 0, NULL) == NULL) {
|
|
|
|
uprintf("Unable to start boot check thread");
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
|
|
|
|
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
|
2015-12-11 23:17:12 +00:00
|
|
|
}
|
2011-11-27 23:40:28 +00:00
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_LANG:
|
|
|
|
// Show the language menu such that it doesn't overlap the button
|
|
|
|
SendMessage(hMultiToolbar, TB_GETRECT, (WPARAM)IDC_ABOUT, (LPARAM)&rc);
|
|
|
|
MapWindowPoints(hDlg, NULL, (POINT*)&rc, 2);
|
|
|
|
rc.left += cbw / 2;
|
|
|
|
ShowLanguageMenu(rc);
|
|
|
|
break;
|
|
|
|
case IDC_SETTINGS:
|
|
|
|
MyDialogBox(hMainInstance, IDD_UPDATE_POLICY, hDlg, UpdateCallback);
|
|
|
|
break;
|
2015-07-02 21:46:26 +00:00
|
|
|
case IDC_HASH:
|
2020-07-10 10:55:29 +00:00
|
|
|
if ((format_thread == NULL) && (image_path != NULL)) {
|
2015-07-02 21:46:26 +00:00
|
|
|
FormatStatus = 0;
|
|
|
|
no_confirmation_on_cancel = TRUE;
|
2019-03-07 16:29:43 +00:00
|
|
|
SendMessage(hMainDialog, UM_PROGRESS_INIT, 0, 0);
|
2015-07-02 21:46:26 +00:00
|
|
|
// Disable all controls except cancel
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(FALSE, FALSE);
|
2015-07-02 21:46:26 +00:00
|
|
|
InitProgress(FALSE);
|
2016-05-24 12:21:23 +00:00
|
|
|
SetThreadAffinity(thread_affinity, CHECKSUM_MAX + 1);
|
2020-07-10 10:55:29 +00:00
|
|
|
format_thread = CreateThread(NULL, 0, SumThread, (LPVOID)thread_affinity, 0, NULL);
|
|
|
|
if (format_thread != NULL) {
|
|
|
|
SetThreadPriority(format_thread, default_thread_priority);
|
2015-07-02 21:46:26 +00:00
|
|
|
PrintInfo(0, -1);
|
2019-03-04 11:57:33 +00:00
|
|
|
SendMessage(hMainDialog, UM_TIMER_START, 0, 0);
|
2015-07-02 21:46:26 +00:00
|
|
|
} else {
|
|
|
|
uprintf("Unable to start checksum thread");
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
|
|
|
|
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2018-03-22 23:14:20 +00:00
|
|
|
case IDC_SAVE:
|
|
|
|
SaveVHD();
|
|
|
|
break;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
case IDM_SELECT:
|
|
|
|
case IDM_DOWNLOAD:
|
|
|
|
select_index = LOWORD(wParam) - IDM_SELECT;
|
|
|
|
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECT), uppercase_select[select_index]);
|
|
|
|
break;
|
2011-11-13 20:53:23 +00:00
|
|
|
default:
|
|
|
|
return (INT_PTR)FALSE;
|
|
|
|
}
|
|
|
|
return (INT_PTR)TRUE;
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
case UM_UPDATE_CSM_TOOLTIP:
|
2019-04-13 14:29:27 +00:00
|
|
|
ShowWindow(GetDlgItem(hMainDialog, IDS_CSM_HELP_TXT), ((target_type == TT_UEFI) || has_uefi_csm) ? SW_SHOW : SW_HIDE);
|
|
|
|
CreateTooltip(GetDlgItem(hMainDialog, IDS_CSM_HELP_TXT), lmprintf((target_type == TT_UEFI) ? MSG_152 : MSG_151), 30000);
|
2018-03-22 23:14:20 +00:00
|
|
|
break;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
case UM_ENABLE_CONTROLS:
|
2019-03-04 11:57:33 +00:00
|
|
|
KillTimer(hMainDialog, TID_APP_TIMER);
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
if (!IS_ERROR(FormatStatus))
|
|
|
|
PrintInfo(0, MSG_210);
|
2019-03-12 14:20:19 +00:00
|
|
|
else switch (SCODE_CODE(FormatStatus)) {
|
|
|
|
case ERROR_CANCELLED:
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
PrintInfo(0, MSG_211);
|
2019-03-12 14:20:19 +00:00
|
|
|
break;
|
|
|
|
case ERROR_BAD_SIGNATURE:
|
|
|
|
PrintInfo(0, MSG_283);
|
|
|
|
break;
|
|
|
|
default:
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
PrintInfo(0, MSG_212);
|
2019-03-12 14:20:19 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
break;
|
2019-03-04 11:57:33 +00:00
|
|
|
case UM_TIMER_START:
|
|
|
|
PrintInfo(0, -1);
|
|
|
|
timer = 0;
|
|
|
|
static_sprintf(szTimer, "00:00:00");
|
|
|
|
SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer);
|
|
|
|
SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer);
|
|
|
|
break;
|
|
|
|
case UM_SELECT_ISO:
|
|
|
|
select_index = 0;
|
2020-07-19 21:35:30 +00:00
|
|
|
img_provided = TRUE;
|
2019-03-04 11:57:33 +00:00
|
|
|
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECT), uppercase_select[0]);
|
|
|
|
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
|
|
|
break;
|
2016-07-09 15:20:58 +00:00
|
|
|
case UM_MEDIA_CHANGE:
|
|
|
|
wParam = DBT_CUSTOMEVENT;
|
|
|
|
// Fall through
|
|
|
|
case WM_DEVICECHANGE:
|
|
|
|
// The Windows hotplug subsystem sucks. Among other things, if you insert a GPT partitioned
|
|
|
|
// USB drive with zero partitions, the only device messages you will get are a stream of
|
|
|
|
// DBT_DEVNODES_CHANGED and that's it. But those messages are also issued when you get a
|
|
|
|
// DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE, and there's a whole slew of them so we
|
|
|
|
// can't really issue a refresh for each one we receive
|
|
|
|
// What we do then is arm a timer on DBT_DEVNODES_CHANGED, if it's been more than 1 second
|
|
|
|
// since last refresh/arm timer, and have that timer send DBT_CUSTOMEVENT when it expires.
|
|
|
|
// DO *NOT* USE WM_DEVICECHANGE AS THE MESSAGE FROM THE TIMER PROC, as it may be filtered!
|
|
|
|
// For instance filtering will occur when (un)plugging in a FreeBSD UFD on Windows 8.
|
|
|
|
// Instead, use a custom user message, such as UM_MEDIA_CHANGE, to set DBT_CUSTOMEVENT.
|
2020-07-10 10:55:29 +00:00
|
|
|
if (format_thread == NULL) {
|
2016-07-09 15:20:58 +00:00
|
|
|
switch (wParam) {
|
|
|
|
case DBT_DEVICEARRIVAL:
|
|
|
|
case DBT_DEVICEREMOVECOMPLETE:
|
|
|
|
case DBT_CUSTOMEVENT: // Sent by our timer refresh function or for card reader media change
|
2017-11-13 14:29:48 +00:00
|
|
|
LastRefresh = GetTickCount64();
|
2016-07-09 15:20:58 +00:00
|
|
|
KillTimer(hMainDialog, TID_REFRESH_TIMER);
|
2019-08-22 13:04:41 +00:00
|
|
|
if (!op_in_progress) {
|
2016-07-09 15:20:58 +00:00
|
|
|
queued_hotplug_event = FALSE;
|
2020-07-17 20:51:15 +00:00
|
|
|
GetDevices((DWORD)ComboBox_GetCurItemData(hDeviceList));
|
2016-07-09 15:20:58 +00:00
|
|
|
user_changed_label = FALSE;
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
2018-03-22 23:14:20 +00:00
|
|
|
if (ComboBox_GetCurSel(hDeviceList) < 0) {
|
|
|
|
SetPartitionSchemeAndTargetSystem(FALSE);
|
|
|
|
SetFileSystemAndClusterSize(NULL);
|
|
|
|
ShowWindow(GetDlgItem(hDlg, IDS_CSM_HELP_TXT), SW_HIDE);
|
2018-08-14 22:05:52 +00:00
|
|
|
persistence_unit_selection = -1;
|
2018-03-22 23:14:20 +00:00
|
|
|
}
|
|
|
|
} else {
|
2016-07-09 15:20:58 +00:00
|
|
|
queued_hotplug_event = TRUE;
|
|
|
|
}
|
|
|
|
return (INT_PTR)TRUE;
|
|
|
|
case DBT_DEVNODES_CHANGED:
|
|
|
|
// If it's been more than a second since last device refresh, arm a refresh timer
|
2022-11-16 16:50:53 +00:00
|
|
|
if (dont_process_dbt_devnodes) {
|
|
|
|
// This ensures we don't get unwanted refreshes while scanning an image.
|
|
|
|
LastRefresh = GetTickCount64();
|
|
|
|
} else if (GetTickCount64() > LastRefresh + 1000) {
|
2017-11-13 14:29:48 +00:00
|
|
|
LastRefresh = GetTickCount64();
|
2016-07-09 15:20:58 +00:00
|
|
|
SetTimer(hMainDialog, TID_REFRESH_TIMER, 1000, RefreshTimer);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
// Make sure fScale is set before the first call to apply localization, so that move/resize scale appropriately
|
|
|
|
hDC = GetDC(hDlg);
|
|
|
|
fScale = GetDeviceCaps(hDC, LOGPIXELSX) / 96.0f;
|
2018-03-22 23:14:20 +00:00
|
|
|
safe_release_dc(hDlg, hDC);
|
2016-07-09 15:20:58 +00:00
|
|
|
apply_localization(IDD_DIALOG, hDlg);
|
2021-02-08 21:02:01 +00:00
|
|
|
// The AppStore version always enables Fido
|
|
|
|
if (appstore_version)
|
|
|
|
SetFidoCheck();
|
|
|
|
else
|
|
|
|
SetUpdateCheck();
|
2016-07-09 15:20:58 +00:00
|
|
|
first_log_display = TRUE;
|
|
|
|
log_displayed = FALSE;
|
2018-03-22 23:14:20 +00:00
|
|
|
hLogDialog = MyCreateDialog(hMainInstance, IDD_LOG, hDlg, (DLGPROC)LogCallback);
|
2016-07-09 15:20:58 +00:00
|
|
|
InitDialog(hDlg);
|
|
|
|
GetDevices(0);
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
2021-10-09 15:15:21 +00:00
|
|
|
UpdateImage(FALSE);
|
2021-02-08 21:02:01 +00:00
|
|
|
// The AppStore version does not need the internal check for updates
|
|
|
|
if (!appstore_version)
|
|
|
|
CheckForUpdates(FALSE);
|
2016-07-09 15:20:58 +00:00
|
|
|
// Register MEDIA_INSERTED/MEDIA_REMOVED notifications for card readers
|
2017-11-13 14:29:48 +00:00
|
|
|
if (SUCCEEDED(SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &pidlDesktop))) {
|
2016-07-09 15:20:58 +00:00
|
|
|
NotifyEntry.pidl = pidlDesktop;
|
|
|
|
NotifyEntry.fRecursive = TRUE;
|
|
|
|
// NB: The following only works if the media is already formatted.
|
|
|
|
// If you insert a blank card, notifications will not be sent... :(
|
2017-11-13 14:29:48 +00:00
|
|
|
ulRegister = SHChangeNotifyRegister(hDlg, 0x0001 | 0x0002 | 0x8000,
|
2016-07-09 15:20:58 +00:00
|
|
|
SHCNE_MEDIAINSERTED | SHCNE_MEDIAREMOVED, UM_MEDIA_CHANGE, 1, &NotifyEntry);
|
|
|
|
}
|
|
|
|
// Bring our Window on top. We have to go through all *THREE* of these, or Far Manager hides our window :(
|
|
|
|
SetWindowPos(hMainDialog, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
SetWindowPos(hMainDialog, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
SetWindowPos(hMainDialog, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
// Set 'START' as the selected button if it's enabled, otherwise use 'SELECT', instead
|
|
|
|
SendMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)(IsWindowEnabled(hStart) ? hStart : hSelectImage), TRUE);
|
2016-07-09 15:20:58 +00:00
|
|
|
|
|
|
|
#if defined(ALPHA)
|
|
|
|
// Add a VERY ANNOYING popup for Alpha releases, so that people don't start redistributing them
|
|
|
|
MessageBoxA(NULL, "This is an Alpha version of " APPLICATION_NAME " - It is meant to be used for "
|
|
|
|
"testing ONLY and should NOT be distributed as a release.", "ALPHA VERSION", MSG_INFO);
|
|
|
|
#elif defined(TEST)
|
|
|
|
// Same thing for Test releases
|
|
|
|
MessageBoxA(NULL, "This is a Test version of " APPLICATION_NAME " - It is meant to be used for "
|
|
|
|
"testing ONLY and should NOT be distributed as a release.", "TEST VERSION", MSG_INFO);
|
|
|
|
#endif
|
2020-06-03 15:06:47 +00:00
|
|
|
// Let's not take any risk: Ask Windows to redraw the whole dialog before we exit init
|
|
|
|
RedrawWindow(hMainDialog, NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);
|
|
|
|
InvalidateRect(hMainDialog, NULL, TRUE);
|
|
|
|
|
2016-07-09 15:20:58 +00:00
|
|
|
return (INT_PTR)FALSE;
|
|
|
|
|
|
|
|
case WM_DRAWITEM:
|
2020-06-03 15:06:47 +00:00
|
|
|
// The things one must do to get an ellipsis and text alignment on the status bar...
|
2016-07-09 15:20:58 +00:00
|
|
|
if (wParam == IDC_STATUS) {
|
|
|
|
pDI = (DRAWITEMSTRUCT*)lParam;
|
2018-05-01 22:11:19 +00:00
|
|
|
if (nWindowsVersion >= WINDOWS_10)
|
|
|
|
pDI->rcItem.top += (int)(1.0f * fScale);
|
|
|
|
else if (fScale >= 1.49f)
|
|
|
|
pDI->rcItem.top -= (int)(1.5f * fScale);
|
2018-03-22 23:14:20 +00:00
|
|
|
pDI->rcItem.left += (int)(4.0f * fScale);
|
2016-07-09 15:20:58 +00:00
|
|
|
SetBkMode(pDI->hDC, TRANSPARENT);
|
|
|
|
switch (pDI->itemID) {
|
|
|
|
case SB_SECTION_LEFT:
|
|
|
|
SetTextColor(pDI->hDC, GetSysColor(COLOR_BTNTEXT));
|
|
|
|
DrawTextExU(pDI->hDC, szStatusMessage, -1, &pDI->rcItem,
|
|
|
|
DT_LEFT | DT_END_ELLIPSIS | DT_PATH_ELLIPSIS, NULL);
|
|
|
|
return (INT_PTR)TRUE;
|
|
|
|
case SB_SECTION_RIGHT:
|
|
|
|
SetTextColor(pDI->hDC, GetSysColor(COLOR_3DSHADOW));
|
|
|
|
DrawTextExA(pDI->hDC, szTimer, -1, &pDI->rcItem, DT_LEFT, NULL);
|
|
|
|
return (INT_PTR)TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2018-03-22 23:14:20 +00:00
|
|
|
case WM_PAINT:
|
2018-04-16 15:05:23 +00:00
|
|
|
hDC = BeginPaint(hDlg, &ps);
|
2018-03-22 23:14:20 +00:00
|
|
|
OnPaint(hDC);
|
2018-04-16 15:05:23 +00:00
|
|
|
EndPaint(hDlg, &ps);
|
2018-03-22 23:14:20 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_CTLCOLORSTATIC:
|
|
|
|
if ((HWND)lParam != GetDlgItem(hDlg, IDS_CSM_HELP_TXT))
|
|
|
|
return FALSE;
|
|
|
|
SetBkMode((HDC)wParam, TRANSPARENT);
|
|
|
|
CreateStaticFont((HDC)wParam, &hyperlink_font, FALSE);
|
|
|
|
SelectObject((HDC)wParam, hyperlink_font);
|
2018-05-11 08:29:14 +00:00
|
|
|
SetTextColor((HDC)wParam, TOOLBAR_ICON_COLOR);
|
2018-03-22 23:14:20 +00:00
|
|
|
return (INT_PTR)CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
|
|
|
|
|
2015-04-18 07:04:29 +00:00
|
|
|
case WM_NOTIFY:
|
|
|
|
switch (((LPNMHDR)lParam)->code) {
|
2018-03-22 23:14:20 +00:00
|
|
|
case TTN_GETDISPINFO:
|
|
|
|
lpttt = (LPTOOLTIPTEXT)lParam;
|
|
|
|
switch (lpttt->hdr.idFrom) {
|
|
|
|
case IDC_ABOUT:
|
|
|
|
utf8_to_wchar_no_alloc(lmprintf(MSG_302), wtooltip, ARRAYSIZE(wtooltip));
|
|
|
|
lpttt->lpszText = wtooltip;
|
|
|
|
break;
|
|
|
|
case IDC_SETTINGS:
|
|
|
|
utf8_to_wchar_no_alloc(lmprintf(MSG_301), wtooltip, ARRAYSIZE(wtooltip));
|
|
|
|
lpttt->lpszText = wtooltip;
|
|
|
|
break;
|
|
|
|
case IDC_LANG:
|
|
|
|
utf8_to_wchar_no_alloc(lmprintf(MSG_273), wtooltip, ARRAYSIZE(wtooltip));
|
|
|
|
lpttt->lpszText = wtooltip;
|
|
|
|
break;
|
|
|
|
case IDC_LOG:
|
|
|
|
utf8_to_wchar_no_alloc(lmprintf(MSG_303), wtooltip, ARRAYSIZE(wtooltip));
|
|
|
|
lpttt->lpszText = wtooltip;
|
|
|
|
break;
|
2018-10-05 08:55:00 +00:00
|
|
|
case IDC_SAVE:
|
|
|
|
utf8_to_wchar_no_alloc(lmprintf(MSG_304), wtooltip, ARRAYSIZE(wtooltip));
|
|
|
|
lpttt->lpszText = wtooltip;
|
|
|
|
break;
|
|
|
|
case IDC_HASH:
|
|
|
|
utf8_to_wchar_no_alloc(lmprintf(MSG_272), wtooltip, ARRAYSIZE(wtooltip));
|
|
|
|
lpttt->lpszText = wtooltip;
|
|
|
|
break;
|
2015-04-18 07:04:29 +00:00
|
|
|
}
|
|
|
|
break;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
case BCN_DROPDOWN:
|
|
|
|
pDropDown = (LPNMBCDROPDOWN)lParam;
|
|
|
|
Point.x = pDropDown->rcButton.left;
|
|
|
|
Point.y = pDropDown->rcButton.bottom;
|
|
|
|
ClientToScreen(pDropDown->hdr.hwndFrom, &Point);
|
|
|
|
hMenu = CreatePopupMenu();
|
|
|
|
InsertMenuU(hMenu, -1, MF_BYPOSITION | ((select_index == 0) ? MF_CHECKED : 0), IDM_SELECT, uppercase_select[0]);
|
|
|
|
InsertMenuU(hMenu, -1, MF_BYPOSITION | ((select_index == 1) ? MF_CHECKED : 0), IDM_DOWNLOAD, uppercase_select[1]);
|
|
|
|
TrackPopupMenuEx(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN, Point.x, Point.y, hMainDialog, NULL);
|
|
|
|
DestroyMenu(hMenu);
|
|
|
|
break;
|
2015-04-18 07:04:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2018-07-06 10:23:57 +00:00
|
|
|
case WM_HSCROLL:
|
|
|
|
lPos = (LONG)SendMessage(GetDlgItem(hMainDialog, IDC_PERSISTENCE_SLIDER), TBM_GETPOS, 0, 0);
|
2019-06-05 16:00:21 +00:00
|
|
|
SetPersistencePos(lPos);
|
2018-07-18 11:22:37 +00:00
|
|
|
persistence_size = lPos * MB;
|
|
|
|
for (i = 0; i < persistence_unit_selection; i++)
|
|
|
|
persistence_size *= 1024;
|
2018-07-06 10:23:57 +00:00
|
|
|
break;
|
|
|
|
|
2016-01-15 17:20:45 +00:00
|
|
|
case WM_DROPFILES:
|
2021-04-08 16:29:13 +00:00
|
|
|
if (format_thread == NULL) {
|
|
|
|
droppedFileInfo = (HDROP)wParam;
|
|
|
|
wbuffer = calloc(MAX_PATH, sizeof(wchar_t));
|
|
|
|
if (wbuffer == NULL) {
|
|
|
|
uprintf("Failed to alloc buffer for drag-n-drop");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
DragQueryFileW(droppedFileInfo, 0, wbuffer, MAX_PATH);
|
|
|
|
safe_free(image_path);
|
|
|
|
image_path = wchar_to_utf8(wbuffer);
|
|
|
|
safe_free(wbuffer);
|
|
|
|
|
|
|
|
if (image_path != NULL) {
|
|
|
|
img_provided = TRUE;
|
|
|
|
// Simulate image selection click
|
|
|
|
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
|
|
|
}
|
2016-01-15 17:20:45 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2016-02-02 16:14:22 +00:00
|
|
|
// This is >>>SUPER WEIRD<<<. After a successful ISO or DD write (e.g. Arch 2016.01)
|
|
|
|
// we no longer receive WM_QUERYENDSESSION messages, only WM_ENDSESSION.
|
|
|
|
// But if we do a FreeDOS format, WM_QUERYENDSESSION is still sent to us alright.
|
|
|
|
// What the heck is going on here?!?
|
|
|
|
// Also, even as we try to work around this, WM_ENDSESSION comes too late in the game
|
|
|
|
// to prevent shutdown block. So we need to handle the _undocumented_ WM_CLIENTSHUTDOWN.
|
2011-11-13 20:53:23 +00:00
|
|
|
case WM_CLOSE:
|
2016-02-02 16:14:22 +00:00
|
|
|
case WM_CLIENTSHUTDOWN:
|
|
|
|
case WM_QUERYENDSESSION:
|
2015-05-21 23:01:42 +00:00
|
|
|
case WM_ENDSESSION:
|
2021-07-28 15:37:45 +00:00
|
|
|
if (op_in_progress)
|
2011-11-28 01:32:18 +00:00
|
|
|
return (INT_PTR)TRUE;
|
2017-01-30 17:52:37 +00:00
|
|
|
if (message == WM_CLOSE) {
|
2019-03-07 16:29:43 +00:00
|
|
|
// We must use PostQuitMessage() on WM_CLOSE, to prevent notification sound...
|
2017-01-30 17:52:37 +00:00
|
|
|
PostQuitMessage(0);
|
|
|
|
} else {
|
|
|
|
// ...but we must simulate Cancel on shutdown requests, else the app freezes.
|
|
|
|
SendMessage(hDlg, WM_COMMAND, (WPARAM)IDCANCEL, (LPARAM)0);
|
|
|
|
}
|
2011-11-13 20:53:23 +00:00
|
|
|
break;
|
|
|
|
|
2015-01-01 23:39:28 +00:00
|
|
|
case UM_PROGRESS_INIT:
|
2015-02-02 21:16:53 +00:00
|
|
|
isMarquee = (wParam == PBS_MARQUEE);
|
2019-03-15 10:57:17 +00:00
|
|
|
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0);
|
2020-11-10 19:46:53 +00:00
|
|
|
if (isMarquee) {
|
2015-01-01 23:39:28 +00:00
|
|
|
SendMessage(hProgress, PBM_SETMARQUEE, TRUE, 0);
|
2020-11-10 19:46:53 +00:00
|
|
|
SetTaskbarProgressState(TASKBAR_INDETERMINATE);
|
|
|
|
} else {
|
2015-01-01 23:39:28 +00:00
|
|
|
SendMessage(hProgress, PBM_SETPOS, 0, 0);
|
2020-11-10 19:46:53 +00:00
|
|
|
SetTaskbarProgressState(TASKBAR_NORMAL);
|
|
|
|
SetTaskbarProgressValue(0, MAX_PROGRESS);
|
|
|
|
}
|
2015-01-01 23:39:28 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case UM_PROGRESS_EXIT:
|
2019-03-07 16:29:43 +00:00
|
|
|
tb_state = PBST_NORMAL;
|
|
|
|
tb_flags = TASKBAR_NORMAL;
|
2015-02-02 21:16:53 +00:00
|
|
|
if (isMarquee) {
|
2018-04-19 11:25:11 +00:00
|
|
|
SendMessage(hProgress, PBM_SETMARQUEE, FALSE, 0);
|
2015-02-02 21:16:53 +00:00
|
|
|
SetTaskbarProgressValue(0, MAX_PROGRESS);
|
|
|
|
} else if (!IS_ERROR(FormatStatus)) {
|
|
|
|
SetTaskbarProgressValue(MAX_PROGRESS, MAX_PROGRESS);
|
2019-03-07 16:29:43 +00:00
|
|
|
} else if (SCODE_CODE(FormatStatus) == ERROR_CANCELLED) {
|
|
|
|
tb_state = PBST_PAUSED;
|
|
|
|
tb_flags = TASKBAR_PAUSED;
|
|
|
|
} else {
|
|
|
|
tb_state = PBST_ERROR;
|
|
|
|
tb_flags = TASKBAR_ERROR;
|
|
|
|
MessageBeep(MB_ICONERROR);
|
|
|
|
FlashTaskbar(dialog_handle);
|
2015-02-02 21:16:53 +00:00
|
|
|
}
|
2019-03-07 16:29:43 +00:00
|
|
|
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)tb_state, 0);
|
|
|
|
SetTaskbarProgressState(tb_flags);
|
2015-01-01 23:39:28 +00:00
|
|
|
break;
|
2012-12-04 01:47:45 +00:00
|
|
|
|
2015-03-09 02:49:11 +00:00
|
|
|
case UM_NO_UPDATE:
|
2018-11-20 12:28:20 +00:00
|
|
|
Notification(MSG_INFO, NULL, NULL, lmprintf(MSG_243), lmprintf(MSG_247));
|
2015-05-08 22:37:22 +00:00
|
|
|
// Need to manually set focus back to "Check Now" for tabbing to work
|
|
|
|
SendMessage(hUpdatesDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hUpdatesDlg, IDC_CHECK_NOW), TRUE);
|
2015-03-09 02:49:11 +00:00
|
|
|
break;
|
|
|
|
|
2018-07-03 21:54:06 +00:00
|
|
|
case UM_FORMAT_START:
|
2020-02-03 12:35:49 +00:00
|
|
|
if (wParam != BOOTCHECK_PROCEED)
|
2018-07-03 21:54:06 +00:00
|
|
|
goto aborted_start;
|
2020-02-03 12:35:49 +00:00
|
|
|
// All subsequent aborts below translate to a user cancellation
|
|
|
|
wParam = BOOTCHECK_CANCEL;
|
2018-07-03 21:54:06 +00:00
|
|
|
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((partition_type == PARTITION_STYLE_MBR) && (SelectedDrive.DiskSize > 2 * TB)) {
|
2019-02-01 12:34:01 +00:00
|
|
|
if (MessageBoxExU(hMainDialog, lmprintf(MSG_134, SizeToHumanReadable(SelectedDrive.DiskSize - 2 * TB, FALSE, FALSE)),
|
|
|
|
lmprintf(MSG_128, "MBR"), MB_YESNO | MB_ICONWARNING | MB_IS_RTL, selected_langid) != IDYES)
|
|
|
|
goto aborted_start;
|
|
|
|
}
|
|
|
|
|
2021-03-25 19:52:33 +00:00
|
|
|
if (!zero_drive && (fs_type == FS_UDF)) {
|
2018-07-03 21:54:06 +00:00
|
|
|
// Display a warning about UDF formatting times
|
2021-03-25 19:52:33 +00:00
|
|
|
dur_secs = (uint32_t)(((double)SelectedDrive.DiskSize) / 1073741824.0f / UDF_FORMAT_SPEED);
|
|
|
|
if (dur_secs > UDF_FORMAT_WARN) {
|
|
|
|
dur_mins = dur_secs / 60;
|
|
|
|
dur_secs -= dur_mins * 60;
|
|
|
|
MessageBoxExU(hMainDialog, lmprintf(MSG_112, dur_mins, dur_secs), lmprintf(MSG_113),
|
|
|
|
MB_OK | MB_ICONASTERISK | MB_IS_RTL, selected_langid);
|
|
|
|
} else {
|
|
|
|
dur_secs = 0;
|
|
|
|
dur_mins = 0;
|
2018-07-03 21:54:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-09 16:00:39 +00:00
|
|
|
if (!CheckDriveAccess(SEARCH_PROCESS_TIMEOUT, TRUE))
|
2018-07-03 21:54:06 +00:00
|
|
|
goto aborted_start;
|
|
|
|
|
|
|
|
GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp));
|
|
|
|
if (MessageBoxExU(hMainDialog, lmprintf(MSG_003, tmp),
|
|
|
|
APPLICATION_NAME, MB_OKCANCEL | MB_ICONWARNING | MB_IS_RTL, selected_langid) == IDCANCEL)
|
|
|
|
goto aborted_start;
|
|
|
|
if ((SelectedDrive.nPartitions > 1) && (MessageBoxExU(hMainDialog, lmprintf(MSG_093),
|
|
|
|
lmprintf(MSG_094), MB_OKCANCEL | MB_ICONWARNING | MB_IS_RTL, selected_langid) == IDCANCEL))
|
|
|
|
goto aborted_start;
|
2019-04-13 14:29:27 +00:00
|
|
|
if ((!zero_drive) && (boot_type != BT_NON_BOOTABLE) && (SelectedDrive.SectorSize != 512) &&
|
2018-07-03 21:54:06 +00:00
|
|
|
(MessageBoxExU(hMainDialog, lmprintf(MSG_196, SelectedDrive.SectorSize),
|
|
|
|
lmprintf(MSG_197), MB_OKCANCEL | MB_ICONWARNING | MB_IS_RTL, selected_langid) == IDCANCEL))
|
|
|
|
goto aborted_start;
|
|
|
|
|
|
|
|
nDeviceIndex = ComboBox_GetCurSel(hDeviceList);
|
|
|
|
DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex);
|
|
|
|
InitProgress(zero_drive || write_as_image);
|
2020-07-10 10:55:29 +00:00
|
|
|
format_thread = CreateThread(NULL, 0, FormatThread, (LPVOID)(uintptr_t)DeviceNum, 0, NULL);
|
|
|
|
if (format_thread == NULL) {
|
2018-07-03 21:54:06 +00:00
|
|
|
uprintf("Unable to start formatting thread");
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD);
|
|
|
|
PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0);
|
|
|
|
} else {
|
2020-07-10 10:55:29 +00:00
|
|
|
SetThreadPriority(format_thread, default_thread_priority);
|
2018-07-03 21:54:06 +00:00
|
|
|
uprintf("\r\nFormat operation started");
|
2019-03-04 11:57:33 +00:00
|
|
|
SendMessage(hMainDialog, UM_TIMER_START, 0, 0);
|
2018-07-03 21:54:06 +00:00
|
|
|
// Set focus to the Cancel button
|
|
|
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDCANCEL), TRUE);
|
|
|
|
}
|
2020-07-10 10:55:29 +00:00
|
|
|
if (format_thread != NULL)
|
2018-07-03 21:54:06 +00:00
|
|
|
break;
|
|
|
|
aborted_start:
|
|
|
|
zero_drive = FALSE;
|
|
|
|
if (queued_hotplug_event)
|
|
|
|
SendMessage(hDlg, UM_MEDIA_CHANGE, 0, 0);
|
2020-02-03 12:35:49 +00:00
|
|
|
if (wParam == BOOTCHECK_CANCEL) {
|
2022-06-23 12:34:24 +00:00
|
|
|
if (unattend_xml_path != NULL) {
|
|
|
|
DeleteFileU(unattend_xml_path);
|
|
|
|
unattend_xml_path = NULL;
|
|
|
|
}
|
2020-02-03 12:35:49 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) |
|
|
|
|
((wParam == BOOTCHECK_DOWNLOAD_ERROR) ? APPERR(ERROR_CANT_DOWNLOAD) : ERROR_GEN_FAILURE);
|
|
|
|
// Fall through
|
2018-07-03 21:54:06 +00:00
|
|
|
|
2011-11-27 23:40:28 +00:00
|
|
|
case UM_FORMAT_COMPLETED:
|
2020-02-03 12:35:49 +00:00
|
|
|
zero_drive = FALSE;
|
2020-07-10 10:55:29 +00:00
|
|
|
format_thread = NULL;
|
2022-06-23 12:34:24 +00:00
|
|
|
if (unattend_xml_path != NULL) {
|
|
|
|
DeleteFileU(unattend_xml_path);
|
|
|
|
unattend_xml_path = NULL;
|
|
|
|
}
|
2011-12-08 12:14:21 +00:00
|
|
|
// Stop the timer
|
2011-12-09 01:39:13 +00:00
|
|
|
KillTimer(hMainDialog, TID_APP_TIMER);
|
2012-02-07 16:17:14 +00:00
|
|
|
// Close the cancel MessageBox and Blocking notification if active
|
2013-10-15 21:58:27 +00:00
|
|
|
SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), lmprintf(MSG_049)), WM_COMMAND, IDNO, 0);
|
|
|
|
SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), lmprintf(MSG_049)), WM_COMMAND, IDYES, 0);
|
2012-02-07 16:17:14 +00:00
|
|
|
EnableWindow(GetDlgItem(hMainDialog, IDCANCEL), TRUE);
|
2019-07-30 10:41:04 +00:00
|
|
|
EnableControls(TRUE, FALSE);
|
2015-06-29 22:43:49 +00:00
|
|
|
if (wParam) {
|
|
|
|
uprintf("\r\n");
|
2016-04-26 12:57:07 +00:00
|
|
|
GetDevices(DeviceNum);
|
2015-06-29 22:43:49 +00:00
|
|
|
}
|
2011-12-04 19:47:27 +00:00
|
|
|
if (!IS_ERROR(FormatStatus)) {
|
2018-04-19 11:25:11 +00:00
|
|
|
SendMessage(hProgress, PBM_SETPOS, MAX_PROGRESS, 0);
|
2012-03-29 17:16:06 +00:00
|
|
|
SetTaskbarProgressState(TASKBAR_NOPROGRESS);
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_210);
|
2017-07-04 13:51:25 +00:00
|
|
|
MessageBeep(MB_OK);
|
|
|
|
FlashTaskbar(dialog_handle);
|
2011-12-04 19:47:27 +00:00
|
|
|
} else if (SCODE_CODE(FormatStatus) == ERROR_CANCELLED) {
|
2012-03-29 17:16:06 +00:00
|
|
|
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_PAUSED, 0);
|
|
|
|
SetTaskbarProgressState(TASKBAR_PAUSED);
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_211);
|
2018-11-20 12:28:20 +00:00
|
|
|
Notification(MSG_INFO, NULL, NULL, lmprintf(MSG_211), lmprintf(MSG_041));
|
2011-12-04 19:47:27 +00:00
|
|
|
} else {
|
2012-03-29 17:16:06 +00:00
|
|
|
SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_ERROR, 0);
|
|
|
|
SetTaskbarProgressState(TASKBAR_ERROR);
|
2015-01-01 23:39:28 +00:00
|
|
|
PrintInfo(0, MSG_212);
|
2017-07-04 13:51:25 +00:00
|
|
|
MessageBeep(MB_ICONERROR);
|
|
|
|
FlashTaskbar(dialog_handle);
|
2018-06-11 13:02:23 +00:00
|
|
|
if (BlockingProcess.Index > 0) {
|
2017-07-11 16:43:51 +00:00
|
|
|
ListDialog(lmprintf(MSG_042), lmprintf(MSG_055), BlockingProcess.String, BlockingProcess.Index);
|
2018-06-11 13:02:23 +00:00
|
|
|
} else {
|
|
|
|
if (nWindowsVersion >= WINDOWS_10) {
|
|
|
|
// Try to detect if 'Controlled Folder Access' is enabled on Windows 10 or later. See also:
|
|
|
|
// http://www.winhelponline.com/blog/use-controlled-folder-access-windows-10-windows-defender
|
2018-06-12 15:01:14 +00:00
|
|
|
char cmdline[256];
|
|
|
|
static const char* ps_cmd[2] = {
|
|
|
|
// Return 1 if the 'Get-MpPreference' PowerShell cmdlet exists
|
|
|
|
"If (Get-Command -Commandtype Function Get-MpPreference -ErrorAction SilentlyContinue) { Exit 1 } Else { Exit 0 }",
|
|
|
|
// Return 1 if Controlled Folder Access is enabled
|
|
|
|
"Exit (Get-MpPreference).EnableControlledFolderAccess" };
|
2018-06-11 13:02:23 +00:00
|
|
|
switch (SCODE_CODE(FormatStatus)) {
|
|
|
|
case ERROR_PARTITION_FAILURE:
|
|
|
|
case ERROR_WRITE_FAULT:
|
2018-06-12 15:01:14 +00:00
|
|
|
// Find if PowerShell is available at its expected location
|
|
|
|
static_sprintf(tmp, "%s\\WindowsPowerShell\\v1.0\\powershell.exe", system_dir);
|
|
|
|
if (PathFileExistsU(tmp)) {
|
|
|
|
for (i = 0; i < ARRAYSIZE(ps_cmd); i++) {
|
|
|
|
// Run the PowerShell commands
|
|
|
|
static_sprintf(cmdline, "%s -NonInteractive -NoProfile -Command %s", tmp, ps_cmd[i]);
|
2021-05-31 15:54:11 +00:00
|
|
|
if (RunCommand(cmdline, app_data_dir, TRUE) != 1)
|
2018-06-12 15:01:14 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == ARRAYSIZE(ps_cmd)) {
|
|
|
|
uprintf("\r\nWARNING: 'Controlled Folder Access' appears to be enabled on this system");
|
|
|
|
uprintf("You may need to disable this feature, or add an exception, for Rufus to to work...\n");
|
|
|
|
}
|
2018-06-11 13:02:23 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-04-09 20:37:08 +00:00
|
|
|
if (SCODE_CODE(FormatStatus) == ERROR_NOT_READY) {
|
|
|
|
// A port cycle usually helps with a device not ready
|
|
|
|
int index = ComboBox_GetCurSel(hDeviceList);
|
|
|
|
if (index >= 0) {
|
|
|
|
uprintf("Device not ready → Trying to cycle port...");
|
2019-05-23 12:09:25 +00:00
|
|
|
CyclePort(index);
|
2019-04-09 20:37:08 +00:00
|
|
|
}
|
|
|
|
}
|
2018-11-20 12:28:20 +00:00
|
|
|
Notification(MSG_ERROR, NULL, NULL, lmprintf(MSG_042), lmprintf(MSG_043, StrError(FormatStatus, FALSE)));
|
2018-06-11 13:02:23 +00:00
|
|
|
}
|
2011-12-04 19:47:27 +00:00
|
|
|
}
|
2012-12-04 01:47:45 +00:00
|
|
|
FormatStatus = 0;
|
2019-04-09 20:37:08 +00:00
|
|
|
LastWriteError = 0;
|
2011-11-27 23:40:28 +00:00
|
|
|
return (INT_PTR)TRUE;
|
2016-05-30 16:32:49 +00:00
|
|
|
|
2011-11-13 20:53:23 +00:00
|
|
|
}
|
|
|
|
return (INT_PTR)FALSE;
|
|
|
|
}
|
|
|
|
|
2013-02-04 01:14:28 +00:00
|
|
|
static void PrintUsage(char* appname)
|
|
|
|
{
|
|
|
|
char fname[_MAX_FNAME];
|
|
|
|
|
|
|
|
_splitpath(appname, NULL, NULL, fname, NULL);
|
2018-10-23 19:10:52 +00:00
|
|
|
printf("\nUsage: %s [-x] [-g] [-h] [-f FILESYSTEM] [-i PATH] [-l LOCALE] [-w TIMEOUT]\n", fname);
|
|
|
|
printf(" -x, --extra-devs\n");
|
|
|
|
printf(" List extra devices, such as USB HDDs\n");
|
2015-02-22 01:14:00 +00:00
|
|
|
printf(" -g, --gui\n");
|
|
|
|
printf(" Start in GUI mode (disable the 'rufus.com' commandline hogger)\n");
|
2013-02-04 23:15:11 +00:00
|
|
|
printf(" -i PATH, --iso=PATH\n");
|
|
|
|
printf(" Select the ISO image pointed by PATH to be used on startup\n");
|
2015-02-22 01:14:00 +00:00
|
|
|
printf(" -l LOCALE, --locale=LOCALE\n");
|
|
|
|
printf(" Select the locale to be used on startup\n");
|
2018-10-23 19:10:52 +00:00
|
|
|
printf(" -f FILESYSTEM, --filesystem=FILESYSTEM\n");
|
|
|
|
printf(" Preselect the file system to be preferred when formatting\n");
|
2013-02-04 23:15:11 +00:00
|
|
|
printf(" -w TIMEOUT, --wait=TIMEOUT\n");
|
2015-02-22 01:14:00 +00:00
|
|
|
printf(" Wait TIMEOUT tens of seconds for the global application mutex to be released.\n");
|
2013-02-04 23:15:11 +00:00
|
|
|
printf(" Used when launching a newer version of " APPLICATION_NAME " from a running application.\n");
|
|
|
|
printf(" -h, --help\n");
|
|
|
|
printf(" This usage guide.\n");
|
2013-02-04 01:14:28 +00:00
|
|
|
}
|
|
|
|
|
2018-11-10 19:52:58 +00:00
|
|
|
static HANDLE SetHogger(void)
|
2015-02-22 01:14:00 +00:00
|
|
|
{
|
|
|
|
INPUT* input;
|
|
|
|
BYTE* hog_data;
|
|
|
|
DWORD hog_size, Size;
|
|
|
|
HANDLE hogmutex = NULL, hFile = NULL;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
hog_data = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_XT_HOGGER),
|
|
|
|
_RT_RCDATA, cmdline_hogger, &hog_size, FALSE);
|
2018-11-10 19:52:58 +00:00
|
|
|
if (hog_data != NULL) {
|
2015-02-22 01:14:00 +00:00
|
|
|
// Create our synchronisation mutex
|
|
|
|
hogmutex = CreateMutexA(NULL, TRUE, "Global/Rufus_CmdLine");
|
|
|
|
|
|
|
|
// Extract the hogger resource
|
2017-02-16 14:13:30 +00:00
|
|
|
hFile = CreateFileA(cmdline_hogger, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,
|
2015-02-22 01:14:00 +00:00
|
|
|
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE) {
|
|
|
|
// coverity[check_return]
|
|
|
|
WriteFile(hFile, hog_data, hog_size, &Size, NULL);
|
|
|
|
}
|
|
|
|
safe_closehandle(hFile);
|
|
|
|
|
|
|
|
// Now launch the file from the commandline, by simulating keypresses
|
|
|
|
input = (INPUT*)calloc(strlen(cmdline_hogger)+1, sizeof(INPUT));
|
2016-06-08 15:32:31 +00:00
|
|
|
if (input != NULL) {
|
|
|
|
for (i = 0; i < (int)strlen(cmdline_hogger); i++) {
|
|
|
|
input[i].type = INPUT_KEYBOARD;
|
|
|
|
input[i].ki.dwFlags = KEYEVENTF_UNICODE;
|
|
|
|
input[i].ki.wScan = (wchar_t)cmdline_hogger[i];
|
|
|
|
}
|
2015-02-22 01:14:00 +00:00
|
|
|
input[i].type = INPUT_KEYBOARD;
|
2016-06-08 15:32:31 +00:00
|
|
|
input[i].ki.wVk = VK_RETURN;
|
|
|
|
SendInput(i + 1, input, sizeof(INPUT));
|
|
|
|
free(input);
|
2015-02-22 01:14:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (hogmutex != NULL)
|
|
|
|
Sleep(200); // Need to add a delay, otherwise we may get some printout before the hogger
|
|
|
|
return hogmutex;
|
|
|
|
}
|
|
|
|
|
2021-12-12 00:57:26 +00:00
|
|
|
// For delay-loaded DLLs, use LOAD_LIBRARY_SEARCH_SYSTEM32 to avoid DLL search order hijacking.
|
|
|
|
FARPROC WINAPI dllDelayLoadHook(unsigned dliNotify, PDelayLoadInfo pdli)
|
|
|
|
{
|
|
|
|
if (dliNotify == dliNotePreLoadLibrary) {
|
|
|
|
// Windows 7 without KB2533623 does not support the LOAD_LIBRARY_SEARCH_SYSTEM32 flag.
|
|
|
|
// That is is OK, because the delay load handler will interrupt the NULL return value
|
|
|
|
// to mean that it should perform a normal LoadLibrary.
|
|
|
|
return (FARPROC)LoadLibraryExA(pdli->szDll, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(_MSC_VER)
|
|
|
|
// By default the Windows SDK headers have a `const` while MinGW does not.
|
|
|
|
const
|
|
|
|
#endif
|
|
|
|
PfnDliHook __pfnDliNotifyHook2 = dllDelayLoadHook;
|
2015-07-03 22:42:45 +00:00
|
|
|
|
2011-11-13 20:53:23 +00:00
|
|
|
/*
|
|
|
|
* Application Entrypoint
|
|
|
|
*/
|
2013-01-09 21:54:28 +00:00
|
|
|
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
|
|
|
|
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
|
|
|
|
#else
|
2011-11-13 20:53:23 +00:00
|
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
2013-01-09 21:54:28 +00:00
|
|
|
#endif
|
2011-11-13 20:53:23 +00:00
|
|
|
{
|
2014-01-05 01:39:41 +00:00
|
|
|
const char* rufus_loc = "rufus.loc";
|
2013-12-20 02:59:44 +00:00
|
|
|
int i, opt, option_index = 0, argc = 0, si = 0, lcid = GetUserDefaultUILanguage();
|
2022-11-22 13:35:50 +00:00
|
|
|
int wait_for_mutex = 0, forced_windows_version = 0;
|
2022-07-07 10:22:39 +00:00
|
|
|
uint32_t wue_options;
|
2015-01-25 00:56:38 +00:00
|
|
|
FILE* fd;
|
2017-03-08 20:22:24 +00:00
|
|
|
BOOL attached_console = FALSE, external_loc_file = FALSE, lgp_set = FALSE, automount = TRUE;
|
2017-06-15 16:25:13 +00:00
|
|
|
BOOL disable_hogger = FALSE, previous_enable_HDDs = FALSE, vc = IsRegistryNode(REGKEY_HKCU, vs_reg);
|
2019-08-20 17:06:07 +00:00
|
|
|
BOOL alt_pressed = FALSE, alt_command = FALSE;
|
2015-02-22 01:14:00 +00:00
|
|
|
BYTE *loc_data;
|
2021-08-02 12:22:49 +00:00
|
|
|
DWORD loc_size, u = 0, size = sizeof(u);
|
2016-04-28 08:09:43 +00:00
|
|
|
char tmp_path[MAX_PATH] = "", loc_file[MAX_PATH] = "", ini_path[MAX_PATH] = "", ini_flags[] = "rb";
|
2015-01-25 00:56:38 +00:00
|
|
|
char *tmp, *locale_name = NULL, **argv = NULL;
|
2013-02-04 01:14:28 +00:00
|
|
|
wchar_t **wenv, **wargv;
|
2015-07-03 22:42:45 +00:00
|
|
|
PF_TYPE_DECL(CDECL, int, __wgetmainargs, (int*, wchar_t***, wchar_t***, int, int*));
|
2018-06-05 12:02:28 +00:00
|
|
|
PF_TYPE_DECL(WINAPI, BOOL, SetDefaultDllDirectories, (DWORD));
|
2014-05-27 01:02:50 +00:00
|
|
|
HANDLE mutex = NULL, hogmutex = NULL, hFile = NULL;
|
2011-11-13 20:53:23 +00:00
|
|
|
HWND hDlg = NULL;
|
2015-09-27 18:59:28 +00:00
|
|
|
HDC hDC;
|
2011-11-13 20:53:23 +00:00
|
|
|
MSG msg;
|
2013-02-04 01:14:28 +00:00
|
|
|
struct option long_options[] = {
|
2018-10-23 19:10:52 +00:00
|
|
|
{"extra-devs", no_argument, NULL, 'x'},
|
|
|
|
{"gui", no_argument, NULL, 'g'},
|
|
|
|
{"help", no_argument, NULL, 'h'},
|
|
|
|
{"iso", required_argument, NULL, 'i'},
|
|
|
|
{"locale", required_argument, NULL, 'l'},
|
|
|
|
{"filesystem", required_argument, NULL, 'f'},
|
|
|
|
{"wait", required_argument, NULL, 'w'},
|
2013-02-04 01:14:28 +00:00
|
|
|
{0, 0, NULL, 0}
|
|
|
|
};
|
2011-11-13 20:53:23 +00:00
|
|
|
|
2016-02-09 12:38:09 +00:00
|
|
|
// Disable loading system DLLs from the current directory (sideloading mitigation)
|
2018-06-05 12:02:28 +00:00
|
|
|
// PS: You know that official MSDN documentation for SetDllDirectory() that explicitly
|
|
|
|
// indicates that "If the parameter is an empty string (""), the call removes the current
|
|
|
|
// directory from the default DLL search order"? Yeah, that doesn't work. At all.
|
2019-09-21 21:39:00 +00:00
|
|
|
// Still, we invoke it, for platforms where the following call might actually work...
|
2016-02-09 12:38:09 +00:00
|
|
|
SetDllDirectoryA("");
|
|
|
|
|
2021-12-12 00:57:26 +00:00
|
|
|
// For libraries on the KnownDLLs list, the system will always load them from System32.
|
|
|
|
// For other DLLs we link directly to, we can delay load the DLL and use a delay load
|
|
|
|
// hook to load them from System32. Note that, for this to work, something like:
|
|
|
|
// 'somelib.dll;%(DelayLoadDLLs)' must be added to the 'Delay Loaded Dlls' option of
|
|
|
|
// the linker properties in Visual Studio (which means this won't work with MinGW).
|
|
|
|
// For all other DLLs, use SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32).
|
2018-06-05 12:02:28 +00:00
|
|
|
// Finally, we need to perform the whole gymkhana below, where we can't call on
|
|
|
|
// SetDefaultDllDirectories() directly, because Windows 7 doesn't have the API exposed.
|
2021-12-12 00:57:26 +00:00
|
|
|
// Also, no, Coverity, we never need to care about freeing kernel32 as a library.
|
2018-06-15 15:50:37 +00:00
|
|
|
// coverity[leaked_storage]
|
2018-06-05 12:02:28 +00:00
|
|
|
pfSetDefaultDllDirectories = (SetDefaultDllDirectories_t)
|
2021-12-12 00:57:26 +00:00
|
|
|
GetProcAddress(LoadLibraryW(L"kernel32.dll"), "SetDefaultDllDirectories");
|
2018-06-05 12:02:28 +00:00
|
|
|
if (pfSetDefaultDllDirectories != NULL)
|
|
|
|
pfSetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
|
|
|
|
|
2013-06-06 22:40:37 +00:00
|
|
|
uprintf("*** " APPLICATION_NAME " init ***\n");
|
2019-09-21 21:39:00 +00:00
|
|
|
its_a_me_mario = GetUserNameA((char*)(uintptr_t)&u, &size) && (u == 7104878);
|
2019-03-15 10:57:17 +00:00
|
|
|
// coverity[pointless_string_compare]
|
2019-02-05 17:49:27 +00:00
|
|
|
is_x86_32 = (strcmp(APPLICATION_ARCH, "x86") == 0);
|
2013-06-06 22:40:37 +00:00
|
|
|
|
2021-02-07 20:25:21 +00:00
|
|
|
// Retrieve various app & system directories.
|
|
|
|
if (GetCurrentDirectoryU(sizeof(app_dir), app_dir) == 0) {
|
|
|
|
uprintf("Could not get current directory: %s", WindowsErrorString());
|
|
|
|
app_dir[0] = 0;
|
|
|
|
}
|
2021-06-10 16:18:40 +00:00
|
|
|
// Microsoft has a bad habit of making some of its APIs (_chdir/_wchdir) break
|
|
|
|
// when app_dir is a drive letter that doesn't have a trailing backslash. For
|
|
|
|
// instance _chdir("F:") does not change the directory, whereas _chdir("F:\\")
|
|
|
|
// does. So make sure we add a trailing backslash if the app_dir is a drive.
|
|
|
|
if ((app_dir[1] == ':') && (app_dir[2] == 0)) {
|
|
|
|
app_dir[2] = '\\';
|
|
|
|
app_dir[3] = 0;
|
|
|
|
}
|
2021-02-07 20:25:21 +00:00
|
|
|
if (GetSystemDirectoryU(system_dir, sizeof(system_dir)) == 0) {
|
|
|
|
uprintf("Could not get system directory: %s", WindowsErrorString());
|
|
|
|
static_strcpy(system_dir, "C:\\Windows\\System32");
|
|
|
|
}
|
|
|
|
if (GetTempPathU(sizeof(temp_dir), temp_dir) == 0) {
|
|
|
|
uprintf("Could not get temp directory: %s", WindowsErrorString());
|
|
|
|
static_strcpy(temp_dir, ".\\");
|
|
|
|
}
|
2021-05-31 15:54:11 +00:00
|
|
|
if (!SHGetSpecialFolderPathU(NULL, app_data_dir, CSIDL_LOCAL_APPDATA, FALSE)) {
|
|
|
|
uprintf("Could not get app data directory: %s", WindowsErrorString());
|
|
|
|
static_strcpy(app_data_dir, temp_dir);
|
|
|
|
}
|
2021-07-28 15:37:45 +00:00
|
|
|
if (!SHGetSpecialFolderPathU(NULL, user_dir, CSIDL_PROFILE, FALSE)) {
|
|
|
|
uprintf("Could not get user directory: %s", WindowsErrorString());
|
|
|
|
static_strcpy(user_dir, temp_dir);
|
|
|
|
}
|
2021-02-07 20:25:21 +00:00
|
|
|
// Construct Sysnative ourselves as there is no GetSysnativeDirectory() call
|
|
|
|
// By default (64bit app running on 64 bit OS or 32 bit app running on 32 bit OS)
|
|
|
|
// Sysnative and System32 are the same
|
|
|
|
static_strcpy(sysnative_dir, system_dir);
|
|
|
|
// But if the app is 32 bit and the OS is 64 bit, Sysnative must differ from System32
|
|
|
|
#if (!defined(_WIN64) && !defined(BUILD64))
|
|
|
|
if (is_x64()) {
|
|
|
|
if (GetSystemWindowsDirectoryU(sysnative_dir, sizeof(sysnative_dir)) == 0) {
|
|
|
|
uprintf("Could not get Windows directory: %s", WindowsErrorString());
|
|
|
|
static_strcpy(sysnative_dir, "C:\\Windows");
|
|
|
|
}
|
|
|
|
static_strcat(sysnative_dir, "\\Sysnative");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-08-01 20:48:54 +00:00
|
|
|
// Look for a rufus.app file in the current app directory
|
|
|
|
// Since Microsoft makes it downright impossible to pass an arg in the app manifest
|
|
|
|
// and the automated VS2019 package building process doesn't like renaming the .exe
|
|
|
|
// right under its nose (else we would use the same trick as for portable vs regular)
|
|
|
|
// we use yet another workaround to detect if we are running the AppStore version...
|
|
|
|
static_sprintf(ini_path, "%s\\rufus.app", app_dir);
|
|
|
|
if (PathFileExistsU(ini_path)) {
|
|
|
|
appstore_version = TRUE;
|
|
|
|
goto skip_args_processing;
|
|
|
|
}
|
2021-02-07 20:25:21 +00:00
|
|
|
|
2013-10-15 21:58:27 +00:00
|
|
|
// We have to process the arguments before we acquire the lock and process the locale
|
2014-05-12 21:44:10 +00:00
|
|
|
PF_INIT(__wgetmainargs, Msvcrt);
|
2013-02-04 01:14:28 +00:00
|
|
|
if (pf__wgetmainargs != NULL) {
|
2021-02-07 20:25:21 +00:00
|
|
|
BOOL list_params = FALSE;
|
2013-02-04 01:14:28 +00:00
|
|
|
pf__wgetmainargs(&argc, &wargv, &wenv, 1, &si);
|
|
|
|
argv = (char**)calloc(argc, sizeof(char*));
|
2016-06-08 15:32:31 +00:00
|
|
|
if (argv != NULL) {
|
|
|
|
// Non getopt parameter check
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
|
|
argv[i] = wchar_to_utf8(wargv[i]);
|
2021-02-05 17:20:54 +00:00
|
|
|
// Check for "/W" (wait for mutex release for pre 1.3.3 versions)
|
2016-06-08 15:32:31 +00:00
|
|
|
if (strcmp(argv[i], "/W") == 0)
|
|
|
|
wait_for_mutex = 150; // Try to acquire the mutex for 15 seconds
|
|
|
|
// We need to find if we need to disable the hogger BEFORE we start
|
|
|
|
// processing arguments with getopt, as we may want to print messages
|
|
|
|
// on the commandline then, which the hogger makes more intuitive.
|
|
|
|
if ((strcmp(argv[i], "-g") == 0) || (strcmp(argv[i], "--gui") == 0))
|
|
|
|
disable_hogger = TRUE;
|
2021-02-07 20:25:21 +00:00
|
|
|
// Check for "/InvokerPRAID", which may *STUPIDLY* be added by Microsoft
|
2021-02-05 17:20:54 +00:00
|
|
|
// when starting an app that was installed from the Windows store...
|
2021-02-07 20:25:21 +00:00
|
|
|
if (stricmp(argv[i], "/InvokerPRAID") == 0) {
|
2021-02-05 17:20:54 +00:00
|
|
|
appstore_version = TRUE;
|
|
|
|
goto skip_args_processing;
|
|
|
|
}
|
2016-06-08 15:32:31 +00:00
|
|
|
}
|
|
|
|
// If our application name contains a 'p' (for "portable") create a 'rufus.ini'
|
|
|
|
// NB: argv[0] is populated in the previous loop
|
|
|
|
tmp = &argv[0][strlen(argv[0]) - 1];
|
|
|
|
while ((((uintptr_t)tmp) > ((uintptr_t)argv[0])) && (*tmp != '\\'))
|
|
|
|
tmp--;
|
2018-03-27 12:13:23 +00:00
|
|
|
// Need to take 'ALPHA' into account
|
|
|
|
if ((strchr(tmp, 'p') != NULL) || ((strchr(tmp, 'P') != NULL) && (strchr(tmp, 'P')[1] != 'H')))
|
2016-06-08 15:32:31 +00:00
|
|
|
ini_flags[0] = 'a';
|
|
|
|
|
|
|
|
// Now enable the hogger before processing the rest of the arguments
|
2018-11-10 19:52:58 +00:00
|
|
|
if (!disable_hogger) {
|
|
|
|
// Reattach the console, if we were started from commandline
|
|
|
|
if (AttachConsole(ATTACH_PARENT_PROCESS) != 0) {
|
2021-02-05 17:20:54 +00:00
|
|
|
uprintf("Enabling console line hogger");
|
2018-11-10 19:52:58 +00:00
|
|
|
attached_console = TRUE;
|
|
|
|
IGNORE_RETVAL(freopen("CONIN$", "r", stdin));
|
|
|
|
IGNORE_RETVAL(freopen("CONOUT$", "w", stdout));
|
|
|
|
IGNORE_RETVAL(freopen("CONOUT$", "w", stderr));
|
|
|
|
_flushall();
|
|
|
|
hogmutex = SetHogger();
|
|
|
|
}
|
|
|
|
}
|
2016-06-08 15:32:31 +00:00
|
|
|
|
2022-11-22 13:35:50 +00:00
|
|
|
while ((opt = getopt_long(argc, argv, "ghxf:i:l:w:z:", long_options, &option_index)) != EOF) {
|
2016-06-08 15:32:31 +00:00
|
|
|
switch (opt) {
|
2018-10-23 19:10:52 +00:00
|
|
|
case 'x':
|
2016-06-08 15:32:31 +00:00
|
|
|
enable_HDDs = TRUE;
|
|
|
|
break;
|
2021-02-05 17:20:54 +00:00
|
|
|
case 'a':
|
2016-06-08 15:32:31 +00:00
|
|
|
case 'g':
|
|
|
|
// No need to reprocess that option
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
if (_access(optarg, 0) != -1) {
|
2017-03-08 20:22:24 +00:00
|
|
|
safe_free(image_path);
|
2016-06-08 15:32:31 +00:00
|
|
|
image_path = safe_strdup(optarg);
|
2020-07-19 21:35:30 +00:00
|
|
|
img_provided = TRUE;
|
2016-06-08 15:32:31 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("Could not find ISO image '%s'\n", optarg);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
if (isdigitU(optarg[0])) {
|
|
|
|
lcid = (int)strtol(optarg, NULL, 0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
safe_free(locale_name);
|
|
|
|
locale_name = safe_strdup(optarg);
|
|
|
|
}
|
|
|
|
break;
|
2018-10-23 19:10:52 +00:00
|
|
|
case 'f':
|
|
|
|
if (isdigitU(optarg[0])) {
|
|
|
|
preselected_fs = (int)strtol(optarg, NULL, 0);
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < ARRAYSIZE(FileSystemLabel); i++) {
|
|
|
|
if (safe_stricmp(optarg, FileSystemLabel[i]) == 0) {
|
|
|
|
preselected_fs = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((preselected_fs < FS_UNKNOWN) || (preselected_fs >= FS_MAX))
|
|
|
|
preselected_fs = FS_UNKNOWN;
|
|
|
|
selected_fs = preselected_fs;
|
|
|
|
break;
|
2016-06-08 15:32:31 +00:00
|
|
|
case 'w':
|
|
|
|
wait_for_mutex = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
PrintUsage(argv[0]);
|
|
|
|
goto out;
|
2022-11-22 13:35:50 +00:00
|
|
|
case 'z':
|
|
|
|
forced_windows_version = (int)strtol(optarg, NULL, 16);
|
|
|
|
break;
|
2021-02-05 17:20:54 +00:00
|
|
|
// getopt_long returns '?' for any option it doesn't recognize
|
|
|
|
default:
|
|
|
|
list_params = TRUE;
|
|
|
|
break;
|
2013-10-16 19:45:34 +00:00
|
|
|
}
|
2016-06-08 15:32:31 +00:00
|
|
|
}
|
2021-02-05 17:20:54 +00:00
|
|
|
if (list_params) {
|
|
|
|
uprintf("Command line arguments:");
|
|
|
|
for (i = 1; i < argc; i++)
|
|
|
|
uprintf(argv[i]);
|
|
|
|
}
|
2013-02-04 01:14:28 +00:00
|
|
|
}
|
|
|
|
} else {
|
2015-06-27 21:12:30 +00:00
|
|
|
uprintf("Could not access UTF-16 args");
|
2013-02-04 01:14:28 +00:00
|
|
|
}
|
2012-12-06 01:40:44 +00:00
|
|
|
|
2021-02-05 17:20:54 +00:00
|
|
|
skip_args_processing:
|
2021-02-07 20:25:21 +00:00
|
|
|
if (appstore_version)
|
|
|
|
uprintf("AppStore version detected");
|
2013-10-15 21:58:27 +00:00
|
|
|
|
2015-01-25 00:56:38 +00:00
|
|
|
// Look for a .ini file in the current app directory
|
|
|
|
static_sprintf(ini_path, "%s\\rufus.ini", app_dir);
|
|
|
|
fd = fopenU(ini_path, ini_flags); // Will create the file if portable mode is requested
|
2021-02-06 18:58:42 +00:00
|
|
|
// Using the string directly in safe_strcmp() would call GetSignatureName() twice
|
2021-05-26 23:18:05 +00:00
|
|
|
tmp = GetSignatureName(NULL, NULL, FALSE);
|
2021-02-06 18:58:42 +00:00
|
|
|
vc |= (safe_strcmp(tmp, cert_name[0]) == 0);
|
2015-01-25 00:56:38 +00:00
|
|
|
if (fd != NULL) {
|
|
|
|
ini_file = ini_path;
|
2021-10-11 19:08:04 +00:00
|
|
|
// In portable mode, use the app directory for all local storage
|
|
|
|
static_strcpy(app_data_dir, app_dir);
|
2015-01-25 00:56:38 +00:00
|
|
|
fclose(fd);
|
|
|
|
}
|
|
|
|
uprintf("Will use settings from %s", (ini_file != NULL)?"INI file":"registry");
|
|
|
|
|
|
|
|
// Use the locale specified by the settings, if any
|
|
|
|
tmp = ReadSettingStr(SETTING_LOCALE);
|
|
|
|
if (tmp[0] != 0) {
|
|
|
|
locale_name = safe_strdup(tmp);
|
|
|
|
uprintf("found locale '%s'", locale_name);
|
|
|
|
}
|
|
|
|
|
2015-09-16 23:20:22 +00:00
|
|
|
// Restore user-saved settings
|
2018-03-22 23:14:20 +00:00
|
|
|
advanced_mode_device = ReadSettingBool(SETTING_ADVANCED_MODE_DEVICE);
|
|
|
|
advanced_mode_format = ReadSettingBool(SETTING_ADVANCED_MODE_FORMAT);
|
2015-09-16 23:20:22 +00:00
|
|
|
preserve_timestamps = ReadSettingBool(SETTING_PRESERVE_TIMESTAMPS);
|
|
|
|
use_fake_units = !ReadSettingBool(SETTING_USE_PROPER_SIZE_UNITS);
|
2021-10-03 13:50:53 +00:00
|
|
|
is_vds_available = IsVdsAvailable(FALSE);
|
|
|
|
use_vds = ReadSettingBool(SETTING_USE_VDS) && is_vds_available;
|
2015-09-16 23:20:22 +00:00
|
|
|
usb_debug = ReadSettingBool(SETTING_ENABLE_USB_DEBUG);
|
2020-05-12 13:13:44 +00:00
|
|
|
cdio_loglevel_default = usb_debug ? CDIO_LOG_DEBUG : CDIO_LOG_WARN;
|
2015-09-16 23:20:22 +00:00
|
|
|
detect_fakes = !ReadSettingBool(SETTING_DISABLE_FAKE_DRIVES_CHECK);
|
|
|
|
allow_dual_uefi_bios = ReadSettingBool(SETTING_ENABLE_WIN_DUAL_EFI_BIOS);
|
|
|
|
force_large_fat32 = ReadSettingBool(SETTING_FORCE_LARGE_FAT32_FORMAT);
|
|
|
|
enable_vmdk = ReadSettingBool(SETTING_ENABLE_VMDK_DETECTION);
|
2018-04-19 15:02:07 +00:00
|
|
|
enable_file_indexing = ReadSettingBool(SETTING_ENABLE_FILE_INDEXING);
|
2020-04-27 09:28:00 +00:00
|
|
|
enable_VHDs = !ReadSettingBool(SETTING_DISABLE_VHDS);
|
2020-06-25 10:58:56 +00:00
|
|
|
enable_extra_hashes = ReadSettingBool(SETTING_ENABLE_EXTRA_HASHES);
|
2020-11-12 17:38:20 +00:00
|
|
|
ignore_boot_marker = ReadSettingBool(SETTING_IGNORE_BOOT_MARKER);
|
2022-07-07 10:22:39 +00:00
|
|
|
// This restores the Windows User Experience/unattend.xml mask from the saved user
|
|
|
|
// settings, and is designed to work even if we add new options later.
|
|
|
|
wue_options = ReadSetting32(SETTING_WUE_OPTIONS);
|
|
|
|
if ((wue_options >> 16) != 0) {
|
|
|
|
uint32_t mask = wue_options >> 16;
|
|
|
|
unattend_xml_mask &= ~mask;
|
|
|
|
unattend_xml_mask |= (wue_options & mask);
|
|
|
|
}
|
2020-07-10 10:55:29 +00:00
|
|
|
// We want above normal priority by default, so we offset the value.
|
|
|
|
default_thread_priority = ReadSetting32(SETTING_DEFAULT_THREAD_PRIORITY) + THREAD_PRIORITY_ABOVE_NORMAL;
|
2015-09-16 23:20:22 +00:00
|
|
|
|
2015-09-27 18:59:28 +00:00
|
|
|
// Initialize the global scaling, in case we need it before we initialize the dialog
|
|
|
|
hDC = GetDC(NULL);
|
|
|
|
fScale = GetDeviceCaps(hDC, LOGPIXELSX) / 96.0f;
|
2018-03-22 23:14:20 +00:00
|
|
|
safe_release_dc(NULL, hDC);
|
2015-09-27 18:59:28 +00:00
|
|
|
|
2013-10-15 21:58:27 +00:00
|
|
|
// Init localization
|
|
|
|
init_localization();
|
2015-10-18 20:31:47 +00:00
|
|
|
|
2013-10-15 21:58:27 +00:00
|
|
|
// Seek for a loc file in the current directory
|
2014-01-05 01:39:41 +00:00
|
|
|
if (GetFileAttributesU(rufus_loc) == INVALID_FILE_ATTRIBUTES) {
|
2013-10-15 21:58:27 +00:00
|
|
|
uprintf("loc file not found in current directory - embedded one will be used");
|
|
|
|
|
2013-11-01 19:17:46 +00:00
|
|
|
loc_data = (BYTE*)GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_LC_RUFUS_LOC), _RT_RCDATA, "embedded.loc", &loc_size, FALSE);
|
2017-07-18 11:57:22 +00:00
|
|
|
if ( (GetTempFileNameU(temp_dir, APPLICATION_NAME, 0, loc_file) == 0) || (loc_file[0] == 0) ) {
|
2022-09-19 08:37:23 +00:00
|
|
|
// If we don't have a working temp API, forget it
|
|
|
|
uprintf("FATAL: Unable to create temp loc file: %s", WindowsErrorString());
|
|
|
|
MessageBoxA(NULL, "Unable to create temporary localization file. This application will now exit.",
|
|
|
|
"Fatal error", MB_ICONSTOP | MB_SYSTEMMODAL);
|
|
|
|
goto out;
|
2014-01-05 01:39:41 +00:00
|
|
|
}
|
2013-10-15 21:58:27 +00:00
|
|
|
|
2017-02-16 14:13:30 +00:00
|
|
|
hFile = CreateFileU(loc_file, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,
|
2014-11-11 19:17:39 +00:00
|
|
|
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
2016-01-14 17:43:02 +00:00
|
|
|
if ((hFile == INVALID_HANDLE_VALUE) || (!WriteFileWithRetry(hFile, loc_data, loc_size, &size, WRITE_RETRIES))) {
|
2022-09-19 08:37:23 +00:00
|
|
|
uprintf("FATAL: Unable to extract loc file '%s': %s", loc_file, WindowsErrorString());
|
2013-10-15 21:58:27 +00:00
|
|
|
safe_closehandle(hFile);
|
2022-09-19 08:37:23 +00:00
|
|
|
MessageBoxA(NULL, "Unable to extract localization file. This application will now exit.",
|
|
|
|
"Fatal error", MB_ICONSTOP | MB_SYSTEMMODAL);
|
2014-01-05 01:39:41 +00:00
|
|
|
goto out;
|
2013-10-15 21:58:27 +00:00
|
|
|
}
|
2016-01-15 12:26:31 +00:00
|
|
|
uprintf("localization: extracted data to '%s'", loc_file);
|
2014-01-05 01:39:41 +00:00
|
|
|
safe_closehandle(hFile);
|
2013-10-15 21:58:27 +00:00
|
|
|
} else {
|
2017-08-10 18:43:04 +00:00
|
|
|
static_sprintf(loc_file, "%s\\%s", app_dir, rufus_loc);
|
2013-10-16 19:45:34 +00:00
|
|
|
external_loc_file = TRUE;
|
2013-10-15 21:58:27 +00:00
|
|
|
uprintf("using external loc file '%s'", loc_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (!get_supported_locales(loc_file))
|
2013-10-18 22:08:49 +00:00
|
|
|
|| ((selected_locale = ((locale_name == NULL)?get_locale_from_lcid(lcid, TRUE):get_locale_from_name(locale_name, TRUE))) == NULL) ) {
|
2016-01-15 12:26:31 +00:00
|
|
|
uprintf("FATAL: Could not access locale!");
|
2017-07-29 16:34:11 +00:00
|
|
|
MessageBoxA(NULL, "The locale data is missing or invalid. This application will now exit.",
|
2015-10-18 20:31:47 +00:00
|
|
|
"Fatal error", MB_ICONSTOP|MB_SYSTEMMODAL);
|
2013-10-15 21:58:27 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2015-10-18 20:31:47 +00:00
|
|
|
selected_langid = get_language_id(selected_locale);
|
2013-10-15 21:58:27 +00:00
|
|
|
|
2017-11-13 14:29:48 +00:00
|
|
|
// Set the Windows version
|
|
|
|
GetWindowsVersion();
|
2022-11-22 13:35:50 +00:00
|
|
|
// Force a version if specified as parameter, but without allowing folks running
|
|
|
|
// a version of Windows we no longer support to use the option as a bypass!
|
|
|
|
if (nWindowsVersion > WINDOWS_7 && forced_windows_version != 0)
|
|
|
|
nWindowsVersion = forced_windows_version;
|
2017-11-13 14:29:48 +00:00
|
|
|
|
|
|
|
// ...and nothing of value was lost
|
2022-11-22 13:35:50 +00:00
|
|
|
// TODO: Set to <= for 3.22
|
2017-11-13 14:29:48 +00:00
|
|
|
if (nWindowsVersion < WINDOWS_7) {
|
|
|
|
// Load the translation before we print the error
|
|
|
|
get_loc_data_file(loc_file, selected_locale);
|
|
|
|
right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT);
|
|
|
|
// Set MB_SYSTEMMODAL to prevent Far Manager from stealing focus...
|
2022-11-22 13:35:50 +00:00
|
|
|
MessageBoxExU(NULL,
|
|
|
|
lmprintf(MSG_294, (nWindowsVersion == WINDOWS_7) ? 3 : 2, (nWindowsVersion == WINDOWS_7) ? 21 : 18),
|
|
|
|
lmprintf(MSG_293), MB_ICONSTOP | MB_IS_RTL | MB_SYSTEMMODAL, selected_langid);
|
2017-11-13 14:29:48 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2016-05-26 20:47:01 +00:00
|
|
|
// This is needed as there appears to be a *FLAW* in Windows allowing the app to run unelevated with some
|
|
|
|
// weirdly configured user accounts, even as we explicitly set 'requireAdministrator' in the manifest...
|
|
|
|
if (!IsCurrentProcessElevated()) {
|
|
|
|
uprintf("FATAL: No administrative privileges!");
|
|
|
|
// Load the translation before we print the error
|
|
|
|
get_loc_data_file(loc_file, selected_locale);
|
|
|
|
right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT);
|
|
|
|
MessageBoxExU(NULL, lmprintf(MSG_289), lmprintf(MSG_288), MB_ICONSTOP | MB_IS_RTL | MB_SYSTEMMODAL, selected_langid);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2012-12-06 01:40:44 +00:00
|
|
|
// Prevent 2 applications from running at the same time, unless "/W" is passed as an option
|
|
|
|
// in which case we wait for the mutex to be relinquished
|
|
|
|
if ((safe_strlen(lpCmdLine)==2) && (lpCmdLine[0] == '/') && (lpCmdLine[1] == 'W'))
|
|
|
|
wait_for_mutex = 150; // Try to acquire the mutex for 15 seconds
|
2013-06-06 22:40:37 +00:00
|
|
|
mutex = CreateMutexA(NULL, TRUE, "Global/" APPLICATION_NAME);
|
2012-12-06 01:40:44 +00:00
|
|
|
for (;(wait_for_mutex>0) && (mutex != NULL) && (GetLastError() == ERROR_ALREADY_EXISTS); wait_for_mutex--) {
|
|
|
|
CloseHandle(mutex);
|
|
|
|
Sleep(100);
|
2013-06-06 22:40:37 +00:00
|
|
|
mutex = CreateMutexA(NULL, TRUE, "Global/" APPLICATION_NAME);
|
2012-12-06 01:40:44 +00:00
|
|
|
}
|
2021-02-05 17:20:54 +00:00
|
|
|
if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) {
|
|
|
|
// Load the translation before we print the error
|
|
|
|
get_loc_data_file(loc_file, selected_locale);
|
|
|
|
right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT);
|
|
|
|
// Set MB_SYSTEMMODAL to prevent Far Manager from stealing focus...
|
|
|
|
MessageBoxExU(NULL, lmprintf(MSG_002), lmprintf(MSG_001), MB_ICONSTOP|MB_IS_RTL|MB_SYSTEMMODAL, selected_langid);
|
|
|
|
goto out;
|
|
|
|
}
|
2011-11-13 20:53:23 +00:00
|
|
|
|
|
|
|
// Save instance of the application for further reference
|
2011-11-18 23:41:28 +00:00
|
|
|
hMainInstance = hInstance;
|
2011-11-13 20:53:23 +00:00
|
|
|
|
|
|
|
// Initialize COM for folder selection
|
2017-05-02 13:07:04 +00:00
|
|
|
IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));
|
2011-11-13 20:53:23 +00:00
|
|
|
|
2012-11-29 02:59:52 +00:00
|
|
|
// Some dialogs have Rich Edit controls and won't display without this
|
2014-05-12 21:44:10 +00:00
|
|
|
if (GetLibraryHandle("Riched20") == NULL) {
|
2012-11-29 02:59:52 +00:00
|
|
|
uprintf("Could not load RichEdit library - some dialogs may not display: %s\n", WindowsErrorString());
|
|
|
|
}
|
|
|
|
|
2017-05-02 13:07:04 +00:00
|
|
|
// Increase the application privileges (SE_DEBUG_PRIVILEGE), so that we can report
|
|
|
|
// the Windows Services preventing access to the disk or volume we want to format.
|
|
|
|
EnablePrivileges();
|
|
|
|
|
2011-12-11 23:38:16 +00:00
|
|
|
// We use local group policies rather than direct registry manipulation
|
|
|
|
// 0x9e disables removable and fixed drive notifications
|
2017-04-12 19:40:43 +00:00
|
|
|
lgp_set = SetLGP(FALSE, &existing_key, ep_reg, "NoDriveTypeAutorun", 0x9e);
|
2013-12-19 23:56:40 +00:00
|
|
|
|
2017-11-13 14:29:48 +00:00
|
|
|
// Re-enable AutoMount if needed
|
|
|
|
if (!GetAutoMount(&automount)) {
|
|
|
|
uprintf("Could not get AutoMount status");
|
|
|
|
automount = TRUE; // So that we don't try to change its status on exit
|
|
|
|
} else if (!automount) {
|
|
|
|
uprintf("AutoMount was detected as disabled - temporarily re-enabling it");
|
|
|
|
if (!SetAutoMount(TRUE))
|
|
|
|
uprintf("Failed to enable AutoMount");
|
2014-11-11 19:17:39 +00:00
|
|
|
}
|
|
|
|
|
2013-10-24 21:57:34 +00:00
|
|
|
relaunch:
|
2017-04-25 19:25:50 +00:00
|
|
|
ubprintf("Localization set to '%s'", selected_locale->txt[0]);
|
2014-01-24 02:46:06 +00:00
|
|
|
right_to_left_mode = ((selected_locale->ctrl_id) & LOC_RIGHT_TO_LEFT);
|
2018-07-18 11:22:37 +00:00
|
|
|
// We always launch with the image options displaying
|
|
|
|
image_options = IMOP_WINTOGO;
|
|
|
|
image_option_txt[0] = 0;
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
select_index = 0;
|
2019-03-12 14:20:19 +00:00
|
|
|
safe_free(fido_url);
|
2020-06-13 12:17:35 +00:00
|
|
|
SetProcessDefaultLayout(right_to_left_mode ? LAYOUT_RTL : 0);
|
2013-12-22 18:28:38 +00:00
|
|
|
if (get_loc_data_file(loc_file, selected_locale))
|
2015-01-25 00:56:38 +00:00
|
|
|
WriteSettingStr(SETTING_LOCALE, selected_locale->txt[0]);
|
2013-10-24 21:57:34 +00:00
|
|
|
|
2017-08-27 14:07:35 +00:00
|
|
|
if (!vc) {
|
|
|
|
if (MessageBoxExU(NULL, lmprintf(MSG_296), lmprintf(MSG_295),
|
|
|
|
MB_YESNO | MB_ICONWARNING | MB_IS_RTL | MB_SYSTEMMODAL, selected_langid) != IDYES)
|
|
|
|
goto out;
|
|
|
|
vc = TRUE;
|
|
|
|
}
|
|
|
|
|
2014-01-24 02:46:06 +00:00
|
|
|
/*
|
|
|
|
* Create the main Window
|
|
|
|
*/
|
2018-06-06 22:15:41 +00:00
|
|
|
if (hDlg != NULL)
|
|
|
|
// Make sure any previous dialog is destroyed (e.g. when switching languages)
|
|
|
|
DestroyWindow(hDlg);
|
2015-07-03 22:42:45 +00:00
|
|
|
hDlg = MyCreateDialog(hInstance, IDD_DIALOG, NULL, MainCallback);
|
2013-10-15 21:58:27 +00:00
|
|
|
if (hDlg == NULL) {
|
2015-10-18 20:31:47 +00:00
|
|
|
MessageBoxExU(NULL, "Could not create Window", "DialogBox failure",
|
|
|
|
MB_ICONSTOP|MB_IS_RTL|MB_SYSTEMMODAL, selected_langid);
|
2011-11-13 20:53:23 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2013-10-24 21:57:34 +00:00
|
|
|
if ((relaunch_rc.left > -65536) && (relaunch_rc.top > -65536))
|
|
|
|
SetWindowPos(hDlg, HWND_TOP, relaunch_rc.left, relaunch_rc.top, 0, 0, SWP_NOSIZE);
|
2016-01-15 17:20:45 +00:00
|
|
|
|
2017-11-13 14:29:48 +00:00
|
|
|
// Enable drag-n-drop through the message filter
|
2019-07-02 16:49:33 +00:00
|
|
|
ChangeWindowMessageFilterEx(hDlg, WM_DROPFILES, MSGFLT_ADD, NULL);
|
|
|
|
ChangeWindowMessageFilterEx(hDlg, WM_COPYDATA, MSGFLT_ADD, NULL);
|
|
|
|
// CopyGlobalData is needed since we are running elevated
|
|
|
|
ChangeWindowMessageFilterEx(hDlg, WM_COPYGLOBALDATA, MSGFLT_ADD, NULL);
|
2016-01-15 17:20:45 +00:00
|
|
|
|
2016-07-09 15:20:58 +00:00
|
|
|
// Set the hook to automatically close Windows' "You need to format the disk in drive..." prompt
|
2019-03-13 17:01:26 +00:00
|
|
|
SetAlertPromptMessages();
|
2019-03-05 12:41:10 +00:00
|
|
|
if (!SetAlertPromptHook())
|
2019-03-13 17:01:26 +00:00
|
|
|
uprintf("Warning: Could not set alert prompt hook");
|
2016-07-09 15:20:58 +00:00
|
|
|
|
2011-11-13 20:53:23 +00:00
|
|
|
ShowWindow(hDlg, SW_SHOWNORMAL);
|
|
|
|
UpdateWindow(hDlg);
|
|
|
|
|
2011-12-30 17:58:18 +00:00
|
|
|
// Do our own event processing and process "magic" commands
|
2011-11-13 20:53:23 +00:00
|
|
|
while(GetMessage(&msg, NULL, 0, 0)) {
|
2019-08-22 13:04:41 +00:00
|
|
|
static BOOL ctrl_without_focus = FALSE;
|
|
|
|
BOOL no_focus = (msg.message == WM_SYSKEYDOWN) && !(msg.lParam & 0x20000000);
|
2020-11-12 17:38:20 +00:00
|
|
|
// ** ***************************
|
2020-07-10 10:55:29 +00:00
|
|
|
// .,ABCDEFGHIJKLMNOPQRSTUVWXYZ+-
|
2015-01-01 23:39:28 +00:00
|
|
|
|
2019-08-20 17:06:07 +00:00
|
|
|
// Sigh... The things one need to do to detect standalone use of the 'Alt' key.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam != VK_MENU))
|
|
|
|
alt_command = TRUE;
|
2019-08-22 13:04:41 +00:00
|
|
|
else if (GetKeyState(VK_MENU) & 0x8000)
|
2019-08-20 17:06:07 +00:00
|
|
|
alt_pressed = TRUE;
|
|
|
|
|
2015-01-01 23:39:28 +00:00
|
|
|
// Ctrl-A => Select the log data
|
2019-08-22 13:04:41 +00:00
|
|
|
if ((IsWindowVisible(hLogDialog)) && (GetKeyState(VK_CONTROL) & 0x8000) &&
|
|
|
|
(msg.message == WM_KEYDOWN) && (msg.wParam == 'A')) {
|
2015-01-01 23:39:28 +00:00
|
|
|
// Might also need ES_NOHIDESEL property if you want to select when not active
|
2017-07-24 10:36:06 +00:00
|
|
|
Edit_SetSel(hLog, 0, -1);
|
2017-09-15 11:40:33 +00:00
|
|
|
continue;
|
2015-01-01 23:39:28 +00:00
|
|
|
}
|
2019-08-22 13:04:41 +00:00
|
|
|
|
|
|
|
// Detecting Ctrl combination keypress while an operation is in progress is a super-mess
|
|
|
|
// because Windows considers that our dialog doesn't have keyboard focus (WHYYYYYY?!?!?)
|
|
|
|
// and therefore first sends a WM_SYSKEYDOWN (i.e. the message that is supposed to tell
|
|
|
|
// you that Alt is being pressed, because why not also use it for a COMPLETELY DIFFERENT
|
|
|
|
// FRIGGING KEY!!!) with bit 29 of msg.lParam cleared, along with the code for the Ctrl
|
|
|
|
// key and *THEN* a subsequent message (still using WM_SYSKEYDOWN without Alt) with the
|
|
|
|
// other key. So we need to detect both the messages in sequence...
|
|
|
|
if (no_focus && (msg.wParam == VK_CONTROL))
|
|
|
|
ctrl_without_focus = op_in_progress;
|
|
|
|
|
2018-10-23 21:35:39 +00:00
|
|
|
// Ctrl-L => Open/Close the log
|
2019-08-22 13:04:41 +00:00
|
|
|
if ((ctrl_without_focus || ((GetKeyState(VK_CONTROL) & 0x8000) && (msg.message == WM_KEYDOWN)))
|
|
|
|
&& (msg.wParam == 'L')) {
|
|
|
|
ctrl_without_focus = FALSE;
|
2018-10-23 21:35:39 +00:00
|
|
|
SendMessage(hMainDialog, WM_COMMAND, IDC_LOG, 0);
|
|
|
|
continue;
|
|
|
|
}
|
2020-08-13 13:49:34 +00:00
|
|
|
#if defined(_DEBUG) || defined(TEST)
|
2020-04-12 22:45:09 +00:00
|
|
|
// Ctrl-T => Alternate Test mode that doesn't require a full rebuild
|
|
|
|
if ((ctrl_without_focus || ((GetKeyState(VK_CONTROL) & 0x8000) && (msg.message == WM_KEYDOWN)))
|
|
|
|
&& (msg.wParam == 'T')) {
|
2022-11-28 16:41:27 +00:00
|
|
|
TestChecksum();
|
2020-04-12 22:45:09 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif
|
2019-08-22 13:04:41 +00:00
|
|
|
|
|
|
|
if (no_focus && (msg.wParam != VK_CONTROL))
|
|
|
|
ctrl_without_focus = FALSE;
|
|
|
|
|
|
|
|
if (no_focus)
|
2015-01-01 23:39:28 +00:00
|
|
|
continue;
|
2019-08-22 13:04:41 +00:00
|
|
|
|
2020-07-10 10:55:29 +00:00
|
|
|
// Alt +/- => Increase or decrease thread priority for format/file-copy/wim-apply operations
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && ((msg.wParam == VK_OEM_PLUS) || (msg.wParam == VK_OEM_MINUS) ||
|
|
|
|
(msg.wParam == VK_ADD) || (msg.wParam == VK_SUBTRACT))) {
|
|
|
|
int delta = ((msg.wParam == VK_OEM_PLUS) || (msg.wParam == VK_ADD)) ? +1 : -1;
|
|
|
|
if (((delta == +1) && (default_thread_priority < THREAD_PRIORITY_HIGHEST)) ||
|
|
|
|
((delta == -1) && (default_thread_priority > THREAD_PRIORITY_LOWEST))) {
|
|
|
|
default_thread_priority += delta;
|
|
|
|
WriteSetting32(SETTING_DEFAULT_THREAD_PRIORITY, default_thread_priority - THREAD_PRIORITY_ABOVE_NORMAL);
|
|
|
|
if (format_thread != NULL)
|
|
|
|
SetThreadPriority(format_thread, default_thread_priority);
|
2021-10-08 18:22:33 +00:00
|
|
|
if (wim_thread != NULL)
|
|
|
|
SetThreadPriority(wim_thread, default_thread_priority);
|
2020-07-10 10:55:29 +00:00
|
|
|
}
|
|
|
|
PrintStatus(STATUS_MSG_TIMEOUT, MSG_318, default_thread_priority);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-08-22 13:04:41 +00:00
|
|
|
// The following cheat modes should not be enacted when an operation is in progress
|
|
|
|
if (!op_in_progress) {
|
|
|
|
// Alt-. => Enable USB enumeration debug
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == VK_OEM_PERIOD)) {
|
|
|
|
usb_debug = !usb_debug;
|
2020-05-12 13:13:44 +00:00
|
|
|
cdio_loglevel_default = usb_debug ? CDIO_LOG_DEBUG : CDIO_LOG_WARN;
|
2019-08-22 13:04:41 +00:00
|
|
|
WriteSettingBool(SETTING_ENABLE_USB_DEBUG, usb_debug);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_270), usb_debug);
|
|
|
|
GetDevices(0);
|
|
|
|
continue;
|
2013-10-22 21:46:59 +00:00
|
|
|
}
|
2019-08-22 13:04:41 +00:00
|
|
|
// Alt-, => Disable physical drive locking
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == VK_OEM_COMMA)) {
|
|
|
|
lock_drive = !lock_drive;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_282), lock_drive);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-B => Toggle fake drive detection during bad blocks check
|
|
|
|
// By default, Rufus will check for fake USB flash drives that mistakenly present
|
|
|
|
// more capacity than they already have by looping over the flash. This check which
|
|
|
|
// is enabled by default is performed by writing the block number sequence and reading
|
|
|
|
// it back during the bad block check.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'B')) {
|
|
|
|
detect_fakes = !detect_fakes;
|
|
|
|
WriteSettingBool(SETTING_DISABLE_FAKE_DRIVES_CHECK, !detect_fakes);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_256), detect_fakes);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-C => Cycle USB port for currently selected device
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'C')) {
|
|
|
|
int index = ComboBox_GetCurSel(hDeviceList);
|
|
|
|
if (index >= 0)
|
|
|
|
CyclePort(index);
|
|
|
|
continue;
|
|
|
|
}
|
2021-09-19 20:01:45 +00:00
|
|
|
// Alt-D => Delete the subdirectory where Rufus keeps its files
|
2019-08-22 13:04:41 +00:00
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'D')) {
|
2021-05-31 15:54:11 +00:00
|
|
|
static_sprintf(tmp_path, "%s\\%s", app_data_dir, FILES_DIR);
|
2021-09-19 20:01:45 +00:00
|
|
|
PrintStatusDebug(STATUS_MSG_TIMEOUT, MSG_264, tmp_path);
|
2019-08-22 13:04:41 +00:00
|
|
|
SHDeleteDirectoryExU(NULL, tmp_path, FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION);
|
2021-09-19 20:01:45 +00:00
|
|
|
user_deleted_rufus_dir = TRUE;
|
2019-08-22 13:04:41 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-E => Enhanced installation mode (allow dual UEFI/BIOS mode and FAT32 for Windows)
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'E')) {
|
|
|
|
allow_dual_uefi_bios = !allow_dual_uefi_bios;
|
|
|
|
WriteSettingBool(SETTING_ENABLE_WIN_DUAL_EFI_BIOS, allow_dual_uefi_bios);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_266), allow_dual_uefi_bios);
|
|
|
|
SetPartitionSchemeAndTargetSystem(FALSE);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-F => Toggle detection of USB HDDs
|
|
|
|
// By default Rufus does not list USB HDDs. This is a safety feature aimed at avoiding
|
|
|
|
// unintentional formatting of backup drives instead of USB keys.
|
|
|
|
// When enabled, Rufus will list and allow the formatting of USB HDDs.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'F')) {
|
|
|
|
enable_HDDs = !enable_HDDs;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_253), enable_HDDs);
|
|
|
|
GetDevices(0);
|
|
|
|
CheckDlgButton(hMainDialog, IDC_LIST_USB_HDD, enable_HDDs ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
continue;
|
|
|
|
}
|
2020-04-27 09:28:00 +00:00
|
|
|
// Alt-G => Toggle detection of Virtual Disks
|
|
|
|
// By default Rufus list Virtual Disks but some people use them for backup.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'G')) {
|
|
|
|
enable_VHDs = !enable_VHDs;
|
|
|
|
WriteSettingBool(SETTING_DISABLE_VHDS, !enable_VHDs);
|
2020-06-03 15:03:20 +00:00
|
|
|
PrintStatusTimeout(lmprintf(MSG_308), enable_VHDs);
|
2020-04-27 09:28:00 +00:00
|
|
|
GetDevices(0);
|
|
|
|
continue;
|
|
|
|
}
|
2020-06-25 10:58:56 +00:00
|
|
|
// Alt-H => Toggle computation of SHA512 digest
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'H')) {
|
|
|
|
enable_extra_hashes = !enable_extra_hashes;
|
|
|
|
WriteSettingBool(SETTING_ENABLE_EXTRA_HASHES, enable_extra_hashes);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_312), enable_extra_hashes);
|
|
|
|
continue;
|
|
|
|
}
|
2019-08-22 13:04:41 +00:00
|
|
|
// Alt-I => Toggle ISO support
|
|
|
|
// This is useful if you have an ISOHybrid image and you want to force Rufus to use
|
|
|
|
// DD-mode when writing the data.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'I')) {
|
|
|
|
enable_iso = !enable_iso;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_262), enable_iso);
|
|
|
|
if (image_path != NULL) {
|
2020-07-19 21:35:30 +00:00
|
|
|
img_provided = TRUE;
|
2019-08-22 13:04:41 +00:00
|
|
|
dont_display_image_name = TRUE;
|
|
|
|
SendMessage(hDlg, WM_COMMAND, IDC_SELECT, 0);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt J => Toggle Joliet support for ISO9660 images
|
|
|
|
// Some ISOs (Ubuntu) have Joliet extensions but expect applications not to use them,
|
|
|
|
// due to their reliance on filenames that are > 64 chars (the Joliet max length for
|
|
|
|
// a file name). This option allows users to ignore Joliet when using such images.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'J')) {
|
|
|
|
enable_joliet = !enable_joliet;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_257), enable_joliet);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt K => Toggle Rock Ridge support for ISO9660 images
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'K')) {
|
|
|
|
enable_rockridge = !enable_rockridge;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_258), enable_rockridge);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-L => Force Large FAT32 format to be used on < 32 GB drives
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'L')) {
|
|
|
|
force_large_fat32 = !force_large_fat32;
|
|
|
|
WriteSettingBool(SETTING_FORCE_LARGE_FAT32_FORMAT, force_large_fat32);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_254), force_large_fat32);
|
|
|
|
GetDevices(0);
|
|
|
|
continue;
|
|
|
|
}
|
2020-11-12 17:38:20 +00:00
|
|
|
// Alt-M => Toggle the check for the 0x55 0xAA boot marker at offset 0x1fe.
|
|
|
|
// This means that Rufus treats anything selected as a writeable DD image.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'M')) {
|
|
|
|
ignore_boot_marker = !ignore_boot_marker;
|
|
|
|
WriteSettingBool(SETTING_IGNORE_BOOT_MARKER, ignore_boot_marker);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_319), ignore_boot_marker);
|
|
|
|
continue;
|
|
|
|
}
|
2019-08-22 13:04:41 +00:00
|
|
|
// Alt N => Enable NTFS compression
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'N')) {
|
|
|
|
enable_ntfs_compression = !enable_ntfs_compression;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_260), enable_ntfs_compression);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-O => Save from Optical drive to ISO
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'O')) {
|
|
|
|
SaveISO();
|
|
|
|
continue;
|
|
|
|
}
|
2020-06-06 15:34:17 +00:00
|
|
|
// Alt-P => Toggle GPT ESP to and from Basic Data type (Windows 10 or later)
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'P')) {
|
|
|
|
int index = ComboBox_GetCurSel(hDeviceList);
|
|
|
|
DWORD DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, index);
|
2020-08-15 13:57:48 +00:00
|
|
|
if (ToggleEsp(DeviceNum, 0))
|
2020-06-06 15:34:17 +00:00
|
|
|
CyclePort(index);
|
|
|
|
continue;
|
|
|
|
}
|
2019-08-22 13:04:41 +00:00
|
|
|
// Alt-Q => Enable file indexing (for file systems that support it)
|
|
|
|
// For multiple reasons, file indexing is disabled by default
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'Q')) {
|
|
|
|
enable_file_indexing = !enable_file_indexing;
|
|
|
|
WriteSettingBool(SETTING_ENABLE_FILE_INDEXING, enable_file_indexing);
|
2022-06-14 22:29:33 +00:00
|
|
|
PrintStatusTimeout(lmprintf(MSG_290), enable_file_indexing);
|
2019-08-22 13:04:41 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-R => Remove all the registry keys that may have been created by Rufus
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'R')) {
|
2020-07-10 10:55:29 +00:00
|
|
|
PrintStatus(STATUS_MSG_TIMEOUT, DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME "\\" APPLICATION_NAME) ? MSG_248 : MSG_249);
|
2019-08-22 13:04:41 +00:00
|
|
|
// Also try to delete the upper key (company name) if it's empty (don't care about the result)
|
|
|
|
DeleteRegistryKey(REGKEY_HKCU, COMPANY_NAME);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-S => Disable size limit for ISOs
|
|
|
|
// By default, Rufus will not copy ISOs that are larger than in size than
|
|
|
|
// the target USB drive. If this is enabled, the size check is disabled.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'S')) {
|
|
|
|
size_check = !size_check;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_252), size_check);
|
|
|
|
GetDevices(0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-T => Preserve timestamps when extracting ISO files
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'T')) {
|
|
|
|
preserve_timestamps = !preserve_timestamps;
|
|
|
|
WriteSettingBool(SETTING_PRESERVE_TIMESTAMPS, preserve_timestamps);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_269), preserve_timestamps);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-U => Use PROPER size units, instead of this whole Kibi/Gibi nonsense
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'U')) {
|
|
|
|
use_fake_units = !use_fake_units;
|
|
|
|
WriteSettingBool(SETTING_USE_PROPER_SIZE_UNITS, !use_fake_units);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_263), !use_fake_units);
|
|
|
|
GetDevices(0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-V => Use VDS facilities for formatting
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'V')) {
|
2021-10-03 13:50:53 +00:00
|
|
|
if (is_vds_available) {
|
|
|
|
use_vds = !use_vds;
|
|
|
|
WriteSettingBool(SETTING_USE_VDS, use_vds);
|
|
|
|
PrintStatusTimeout("VDS", use_vds);
|
|
|
|
}
|
2019-08-22 13:04:41 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-W => Enable VMWare disk detection
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'W')) {
|
|
|
|
enable_vmdk = !enable_vmdk;
|
|
|
|
WriteSettingBool(SETTING_ENABLE_VMDK_DETECTION, enable_vmdk);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_265), enable_vmdk);
|
|
|
|
GetDevices(0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-X => Delete the NoDriveTypeAutorun key on exit (useful if the app crashed)
|
|
|
|
// This key is used to disable Windows popup messages when an USB drive is plugged in.
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'X')) {
|
|
|
|
PrintStatus(2000, MSG_255);
|
|
|
|
existing_key = FALSE;
|
|
|
|
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 > 0) ? 0 : 1;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_259), force_update);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Alt-Z => Zero the drive
|
|
|
|
if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'Z')) {
|
|
|
|
zero_drive = TRUE;
|
|
|
|
fast_zeroing = FALSE;
|
|
|
|
// Simulate a button click for Start
|
|
|
|
PostMessage(hDlg, WM_COMMAND, (WPARAM)IDC_START, 0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Ctrl-Alt-Z => Zero the drive while trying to skip empty blocks
|
|
|
|
if ((msg.message == WM_KEYDOWN) && (msg.wParam == 'Z') &&
|
|
|
|
(GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_MENU) & 0x8000)) {
|
|
|
|
zero_drive = TRUE;
|
|
|
|
fast_zeroing = TRUE;
|
|
|
|
// Simulate a button click for Start
|
|
|
|
PostMessage(hDlg, WM_COMMAND, (WPARAM)IDC_START, 0);
|
|
|
|
continue;
|
|
|
|
}
|
2016-02-16 17:47:07 +00:00
|
|
|
|
2019-08-22 13:04:41 +00:00
|
|
|
// Other hazardous cheat modes require Ctrl + Alt
|
|
|
|
// Ctrl-Alt-F => List non USB removable drives such as eSATA, etc - CAUTION!!!
|
|
|
|
if ((msg.message == WM_KEYDOWN) && (msg.wParam == 'F') &&
|
|
|
|
(GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_MENU) & 0x8000)) {
|
|
|
|
list_non_usb_removable_drives = !list_non_usb_removable_drives;
|
|
|
|
if (list_non_usb_removable_drives) {
|
|
|
|
previous_enable_HDDs = enable_HDDs;
|
|
|
|
enable_HDDs = TRUE;
|
|
|
|
} else {
|
|
|
|
enable_HDDs = previous_enable_HDDs;
|
|
|
|
}
|
|
|
|
CheckDlgButton(hMainDialog, IDC_LIST_USB_HDD, enable_HDDs ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_287), list_non_usb_removable_drives);
|
|
|
|
uprintf("%sListing of non-USB removable drives %s",
|
|
|
|
(list_non_usb_removable_drives) ? "CAUTION: " : "", (list_non_usb_removable_drives) ? "enabled" : "disabled");
|
|
|
|
if (list_non_usb_removable_drives)
|
|
|
|
uprintf("By using this unofficial cheat mode you forfeit ANY RIGHT to complain if you lose valuable data!");
|
|
|
|
GetDevices(0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ctrl-Alt-Y => Force update check to be successful and ignore timestamp errors
|
|
|
|
if ((msg.message == WM_KEYDOWN) && (msg.wParam == 'Y') &&
|
|
|
|
(GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_MENU) & 0x8000)) {
|
|
|
|
force_update = (force_update > 0) ? 0 : 2;
|
|
|
|
PrintStatusTimeout(lmprintf(MSG_259), force_update);
|
|
|
|
continue;
|
|
|
|
}
|
2019-04-01 15:37:43 +00:00
|
|
|
}
|
|
|
|
|
2019-08-20 17:06:07 +00:00
|
|
|
// Standalone 'Alt' key toggles progress report between percent, rate (if available)
|
2021-11-01 16:00:02 +00:00
|
|
|
// and remaining time (if available)
|
2019-08-22 13:04:41 +00:00
|
|
|
if (alt_pressed && !(GetKeyState(VK_MENU) & 0x8000)) {
|
2019-08-20 17:06:07 +00:00
|
|
|
alt_pressed = FALSE;
|
|
|
|
if (!alt_command)
|
|
|
|
update_progress_type = (update_progress_type + 1) % UPT_MAX;
|
|
|
|
alt_command = FALSE;
|
|
|
|
}
|
|
|
|
|
2015-04-19 03:15:44 +00:00
|
|
|
// Let the system handle dialog messages (e.g. those from the tab key)
|
2018-03-22 23:14:20 +00:00
|
|
|
if (!IsDialogMessage(hDlg, &msg) && !IsDialogMessage(hLogDialog, &msg)) {
|
2015-04-19 03:15:44 +00:00
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
2011-11-13 20:53:23 +00:00
|
|
|
}
|
2019-03-07 16:29:43 +00:00
|
|
|
if (hFidoDlg != NULL)
|
|
|
|
SendMessage(hFidoDlg, WM_CLOSE, 0, 0);
|
2013-10-24 21:57:34 +00:00
|
|
|
if (relaunch) {
|
|
|
|
relaunch = FALSE;
|
|
|
|
reinit_localization();
|
|
|
|
goto relaunch;
|
|
|
|
}
|
2011-11-13 20:53:23 +00:00
|
|
|
|
|
|
|
out:
|
2014-06-01 23:51:35 +00:00
|
|
|
// Destroy the hogger mutex first, so that the cmdline app can exit and we can delete it
|
2015-02-22 01:14:00 +00:00
|
|
|
if (attached_console && !disable_hogger) {
|
2014-06-01 23:51:35 +00:00
|
|
|
ReleaseMutex(hogmutex);
|
|
|
|
safe_closehandle(hogmutex);
|
|
|
|
}
|
2019-04-01 15:37:43 +00:00
|
|
|
// Kill the update check thread if running
|
|
|
|
if (update_check_thread != NULL)
|
|
|
|
TerminateThread(update_check_thread, 1);
|
2013-10-16 19:45:34 +00:00
|
|
|
if ((!external_loc_file) && (loc_file[0] != 0))
|
2013-10-15 21:58:27 +00:00
|
|
|
DeleteFileU(loc_file);
|
2012-02-07 02:05:58 +00:00
|
|
|
DestroyAllTooltips();
|
2019-03-05 12:41:10 +00:00
|
|
|
ClrAlertPromptHook();
|
2013-10-15 21:58:27 +00:00
|
|
|
exit_localization();
|
2014-05-22 00:52:25 +00:00
|
|
|
safe_free(image_path);
|
2020-06-10 20:25:33 +00:00
|
|
|
safe_free(archive_path);
|
2013-12-15 21:27:25 +00:00
|
|
|
safe_free(locale_name);
|
2012-12-07 00:54:40 +00:00
|
|
|
safe_free(update.download_url);
|
|
|
|
safe_free(update.release_notes);
|
2015-02-02 21:16:53 +00:00
|
|
|
safe_free(grub2_buf);
|
2019-03-12 14:20:19 +00:00
|
|
|
safe_free(fido_url);
|
[net] add Windows retail ISO downloads
* This is accomplished through Fido (https://github.com/pbatard/Fido), a *SIGNED*
PowerShell script, that is downloaded from GitHub and that resides in memory for
the duration of a session.
* The reason we use a downloaded PS script, rather than an embedded on, is because:
- Microsoft have regularly been changing the deal with regards to how retail ISOs
can be downloaded, and not for the better, so we can't simply embed a static
means of downloading ISOs and expect that to work forever.
- By using an external script, we can immediately respond to whatever new means of
*ANNOYING* their legitimate users Microsoft will come up with next, as well as
make sure that, the minute a new retail version of Windows becomes available, it
also becomes available for download in Rufus.
* Note that if you are concerned about downloading a remote PS script that is being
run at the same level as an elevated application, you should understand that:
- Only scripts downloaded from GitHub, from an account that is protected with 2FA,
are allowed to run (i.e. someone would first have to steal a *physical* 2FA key
to be in a position to upload a malicious script).
- On top of this, only scripts that are signed with a separate private key (RSA +
AES-256), that is itself also protected with a strong unique password which only
a single person knows (and must manually enter each time they want to make a new
version of the script available for download), are allowed to run.
The above means that there's about as much chance for someone to manage to upload
a malicious script on the GitHub servers, that Rufus would allow to run, as there
is for someone to upload a malicious version of Rufus itself.
Still, if you are paranoid and have concerns that, even as you can validate from
its source that Rufus does not attempt to execute any remote script unless a user
actively selected and clicked the DOWNLOAD button, you can also completely disable
the remote script download feature, if you just set the update check to disabled
(which, by the way, Rufus *EXPLICITLY* asks you to choose whether you want to
enable or not, the very first time you run the application).
* Also remove _unlinkU() which duplicates what DeleteFileU() already does.
2019-03-02 23:28:56 +00:00
|
|
|
safe_free(fido_script);
|
2013-02-04 01:14:28 +00:00
|
|
|
if (argv != NULL) {
|
|
|
|
for (i=0; i<argc; i++) safe_free(argv[i]);
|
|
|
|
safe_free(argv);
|
|
|
|
}
|
2013-12-28 16:48:02 +00:00
|
|
|
if (lgp_set)
|
2017-04-12 19:40:43 +00:00
|
|
|
SetLGP(TRUE, &existing_key, ep_reg, "NoDriveTypeAutorun", 0);
|
2017-11-13 14:29:48 +00:00
|
|
|
if ((!automount) && (!SetAutoMount(FALSE)))
|
2014-11-11 19:17:39 +00:00
|
|
|
uprintf("Failed to restore AutoMount to disabled");
|
2017-04-25 19:25:50 +00:00
|
|
|
ubflush();
|
2021-10-23 14:14:46 +00:00
|
|
|
_chdirU(app_dir);
|
2016-05-02 11:06:38 +00:00
|
|
|
// Unconditional delete with retry, just in case...
|
|
|
|
for (i = 0; (!DeleteFileA(cmdline_hogger)) && (i <= 10); i++)
|
|
|
|
Sleep(200);
|
|
|
|
CloseHandle(mutex);
|
2021-04-09 11:36:30 +00:00
|
|
|
CoUninitialize();
|
2016-05-02 11:06:38 +00:00
|
|
|
CLOSE_OPENED_LIBRARIES;
|
2014-05-27 01:02:50 +00:00
|
|
|
if (attached_console) {
|
|
|
|
SetWindowPos(GetConsoleWindow(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
FreeConsole();
|
|
|
|
}
|
2013-06-06 22:40:37 +00:00
|
|
|
uprintf("*** " APPLICATION_NAME " exit ***\n");
|
2011-11-21 20:12:23 +00:00
|
|
|
#ifdef _CRTDBG_MAP_ALLOC
|
|
|
|
_CrtDumpMemoryLeaks();
|
|
|
|
#endif
|
|
|
|
|
2011-11-13 20:53:23 +00:00
|
|
|
return 0;
|
|
|
|
}
|