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

[wue] allow the provision of an arbitrary local account username

* This is required because, even though it's easy to change a local account name
  post install, doing so does not change the directory name in C:\Users\
This commit is contained in:
Pete Batard 2022-10-18 13:58:38 +01:00
parent cee21b1981
commit c19ef1125d
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
10 changed files with 151 additions and 105 deletions

View file

@ -17,6 +17,8 @@ o v3.20 (2022.??.??)
- *NEW* MSG_330 "Remove requirement for an online Microsoft account"
- *NEW* MSG_331 "Disable data collection (Skip privacy questions)"
- *NEW* MSG_332 "Prevent Windows To Go from accessing internal disks"
- *NEW* MSG_333 "Create a local account with username:"
- *NEW* MSG_334 "Set regional options to the same values as this user's"
o v3.14 (2021.03.31)
- *UPDATED* MSG_068 "Error while partitioning drive." -> "Could not partition drive."

View file

@ -1825,9 +1825,9 @@ msgid "Prevent Windows To Go from accessing internal disks"
msgstr "Empêcher Windows To Go d'accéder aux disques internes"
#. • MSG_333
msgid "Set a local account using the same name as this user's"
msgstr "Définir un compte local utilisant le même nom que celui de cet utilisateur"
msgid "Create a local account with username:"
msgstr "Créer un compte local avec le nom :"
#. • MSG_334
msgid "Set regional options using the same values as this user's"
msgid "Set regional options to the same values as this user's"
msgstr "Définir les options régionales avec les mêmes valeurs que celles de cet utilisateur"

View file

@ -590,8 +590,8 @@ t MSG_329 "Remove requirement for 4GB+ RAM, Secure Boot and TPM 2.0"
t MSG_330 "Remove requirement for an online Microsoft account"
t MSG_331 "Disable data collection (Skip privacy questions)"
t MSG_332 "Prevent Windows To Go from accessing internal disks"
t MSG_333 "Set a local account using the same name as this user's"
t MSG_334 "Set regional options using the same values as this user's"
t MSG_333 "Create a local account with username:"
t MSG_334 "Set regional options to the same values as this user's"
#########################################################################
l "ar-SA" "Arabic (العربية)" 0x0401, 0x0801, 0x0c01, 0x1001, 0x1401, 0x1801, 0x1c01, 0x2001, 0x2401, 0x2801, 0x2c01, 0x3001, 0x3401, 0x3801, 0x3c01, 0x4001
@ -4313,7 +4313,7 @@ t MSG_329 "Supprimer la nécessité d'avoir 4Go+ de RAM, Secure Boot et TPM 2.0"
t MSG_330 "Supprimer la nécessité d'utiliser un compte Microsoft en ligne"
t MSG_331 "Désactiver la collecte de données (Supprime les questions de confidentialité)"
t MSG_332 "Empêcher Windows To Go d'accéder aux disques internes"
t MSG_333 "Définir un compte local utilisant le même nom que celui de cet utilisateur"
t MSG_333 "Créer un compte local avec le nom :"
t MSG_334 "Définir les options régionales avec les mêmes valeurs que celles de cet utilisateur"
#########################################################################

View file

@ -345,6 +345,8 @@ static __inline int GetWindowTextU(HWND hWnd, char* lpString, int nMaxCount)
{
int ret = 0;
DWORD err = ERROR_INVALID_DATA;
if (nMaxCount < 0)
return 0;
// Handle the empty string as GetWindowTextW() returns 0 then
if ((lpString != NULL) && (nMaxCount > 0))
lpString[0] = 0;
@ -357,6 +359,7 @@ static __inline int GetWindowTextU(HWND hWnd, char* lpString, int nMaxCount)
err = GetLastError();
}
wfree(lpString);
lpString[nMaxCount - 1] = 0;
SetLastError(err);
return ret;
}

View file

@ -135,45 +135,46 @@
#define IDC_MD5 1071
#define IDC_SHA1 1072
#define IDC_SHA256 1073
#define IDC_SHA512 1112
#define IDC_SELECTION_ICON 1074
#define IDC_SELECTION_TEXT 1075
#define IDC_SELECTION_LINE 1076
#define IDC_SELECTION_CHOICE1 1077
#define IDC_SELECTION_CHOICE2 1078
#define IDC_SELECTION_CHOICE3 1079
#define IDC_SELECTION_CHOICE4 1080
#define IDC_SELECTION_CHOICE5 1081
#define IDC_SELECTION_CHOICE6 1082
#define IDC_SELECTION_CHOICE7 1083
#define IDC_SELECTION_CHOICE8 1084
#define IDC_SELECTION_CHOICE9 1085
#define IDC_SELECTION_CHOICE10 1086
#define IDC_SELECTION_CHOICE11 1087
#define IDC_SELECTION_CHOICE12 1088
#define IDC_SELECTION_CHOICE13 1089
#define IDC_SELECTION_CHOICE14 1090
#define IDC_SELECTION_CHOICE15 1091
#define IDC_SELECTION_CHOICEMAX 1092
#define IDC_LIST_ICON 1093
#define IDC_LIST_TEXT 1094
#define IDC_LIST_LINE 1095
#define IDC_LIST_ITEM1 1096
#define IDC_LIST_ITEM2 1097
#define IDC_LIST_ITEM3 1098
#define IDC_LIST_ITEM4 1099
#define IDC_LIST_ITEM5 1100
#define IDC_LIST_ITEM6 1101
#define IDC_LIST_ITEM7 1102
#define IDC_LIST_ITEM8 1103
#define IDC_LIST_ITEM9 1104
#define IDC_LIST_ITEM10 1105
#define IDC_LIST_ITEM11 1106
#define IDC_LIST_ITEM12 1107
#define IDC_LIST_ITEM13 1108
#define IDC_LIST_ITEM14 1109
#define IDC_LIST_ITEM15 1110
#define IDC_LIST_ITEMMAX 1111
#define IDC_SHA512 1074
#define IDC_SELECTION_ICON 1075
#define IDC_SELECTION_TEXT 1076
#define IDC_SELECTION_LINE 1077
#define IDC_SELECTION_CHOICE1 1078
#define IDC_SELECTION_CHOICE2 1079
#define IDC_SELECTION_CHOICE3 1080
#define IDC_SELECTION_CHOICE4 1081
#define IDC_SELECTION_CHOICE5 1082
#define IDC_SELECTION_CHOICE6 1083
#define IDC_SELECTION_CHOICE7 1084
#define IDC_SELECTION_CHOICE8 1085
#define IDC_SELECTION_CHOICE9 1086
#define IDC_SELECTION_CHOICE10 1087
#define IDC_SELECTION_CHOICE11 1088
#define IDC_SELECTION_CHOICE12 1089
#define IDC_SELECTION_CHOICE13 1090
#define IDC_SELECTION_CHOICE14 1091
#define IDC_SELECTION_CHOICE15 1092
#define IDC_SELECTION_CHOICEMAX 1093
#define IDC_SELECTION_USERNAME 1094
#define IDC_LIST_ICON 1095
#define IDC_LIST_TEXT 1096
#define IDC_LIST_LINE 1097
#define IDC_LIST_ITEM1 1098
#define IDC_LIST_ITEM2 1099
#define IDC_LIST_ITEM3 1100
#define IDC_LIST_ITEM4 1101
#define IDC_LIST_ITEM5 1102
#define IDC_LIST_ITEM6 1103
#define IDC_LIST_ITEM7 1104
#define IDC_LIST_ITEM8 1105
#define IDC_LIST_ITEM9 1106
#define IDC_LIST_ITEM10 1107
#define IDC_LIST_ITEM11 1108
#define IDC_LIST_ITEM12 1109
#define IDC_LIST_ITEM13 1110
#define IDC_LIST_ITEM14 1111
#define IDC_LIST_ITEM15 1112
#define IDC_LIST_ITEMMAX 1113
#define IDS_DEVICE_TXT 2000
#define IDS_PARTITION_TYPE_TXT 2001
#define IDS_FILE_SYSTEM_TXT 2002
@ -553,7 +554,7 @@
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 505
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1112
#define _APS_NEXT_CONTROL_VALUE 1114
#define _APS_NEXT_SYMED_VALUE 4000
#endif
#endif

View file

@ -1423,7 +1423,7 @@ out:
// Likewise, boot check will block message processing => use a thread
static DWORD WINAPI BootCheckThread(LPVOID param)
{
int i, r;
int i, r, username_index = -1;
FILE *fd;
DWORD len;
WPARAM ret = BOOTCHECK_CANCEL;
@ -1470,8 +1470,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
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) };
i = SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_274, "ISOHybrid"),
lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), choices, 3, 1);
i = SelectionDialog(lmprintf(MSG_274, "ISOHybrid"), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), choices, 3);
if (i < 0) // Cancel
goto out;
write_as_esp = (i & 2);
@ -1479,8 +1478,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
esp_already_asked = TRUE;
} else {
char* choices[2] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, dd_image) };
i = SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_274, "ISOHybrid"),
lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), choices, 2, 1);
i = SelectionDialog(lmprintf(MSG_274, "ISOHybrid"), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), choices, 2);
if (i < 0) // Cancel
goto out;
write_as_image = (i & 2);
@ -1522,20 +1520,21 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
int arch = _log2(img_report.has_efi >> 1);
uint8_t map[8] = { 0 }, b = 1;
StrArrayCreate(&options, 2);
StrArrayAdd(&options, lmprintf(MSG_332), TRUE);
MAP_BIT(UNATTEND_OFFLINE_INTERNAL_DRIVES);
if (img_report.win_version.build >= 22500) {
StrArrayAdd(&options, lmprintf(MSG_330), TRUE);
MAP_BIT(UNATTEND_NO_ONLINE_ACCOUNT);
}
StrArrayAdd(&options, lmprintf(MSG_331), TRUE);
MAP_BIT(UNATTEND_NO_DATA_COLLECTION);
StrArrayAdd(&options, lmprintf(MSG_332), TRUE);
MAP_BIT(UNATTEND_OFFLINE_INTERNAL_DRIVES);
StrArrayAdd(&options, lmprintf(MSG_333), TRUE);
MAP_BIT(UNATTEND_DUPLICATE_USER);
username_index = _log2(b);
MAP_BIT(UNATTEND_SET_USER);
StrArrayAdd(&options, lmprintf(MSG_334), TRUE);
MAP_BIT(UNATTEND_DUPLICATE_LOCALE);
i = SelectionDialog(BS_AUTOCHECKBOX, lmprintf(MSG_327), lmprintf(MSG_328),
options.String, options.Index, remap8(unattend_xml_mask, map, FALSE));
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);
StrArrayDestroy(&options);
if (i < 0)
goto out;
@ -1591,14 +1590,15 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
StrArrayAdd(&options, lmprintf(MSG_330), TRUE);
MAP_BIT(UNATTEND_NO_ONLINE_ACCOUNT);
}
StrArrayAdd(&options, lmprintf(MSG_331), TRUE);
MAP_BIT(UNATTEND_NO_DATA_COLLECTION);
StrArrayAdd(&options, lmprintf(MSG_333), TRUE);
MAP_BIT(UNATTEND_DUPLICATE_USER);
username_index = _log2(b);
MAP_BIT(UNATTEND_SET_USER);
StrArrayAdd(&options, lmprintf(MSG_334), TRUE);
MAP_BIT(UNATTEND_DUPLICATE_LOCALE);
i = SelectionDialog(BS_AUTOCHECKBOX, lmprintf(MSG_327), lmprintf(MSG_328),
options.String, options.Index, remap8(unattend_xml_mask, map, FALSE));
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);
StrArrayDestroy(&options);
if (i < 0)
goto out;
@ -1616,7 +1616,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
// 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") };
i = SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_274, "ESP"), lmprintf(MSG_310), choices, 2, 1);
i = SelectionDialog(lmprintf(MSG_274, "ESP"), lmprintf(MSG_310), choices, 2);
if (i < 0) // Cancel
goto out;
write_as_esp = (i & 2);

View file

@ -78,6 +78,7 @@
#define MAX_ISO_TO_ESP_SIZE 512 // Maximum size we allow for the ISO → ESP option (in MB)
#define MAX_DEFAULT_LIST_CARD_SIZE 200 // Size above which we don't list a card without enable HDD or Alt-F (in GB)
#define MAX_SECTORS_TO_CLEAR 128 // nb sectors to zap when clearing the MBR/GPT (must be >34)
#define MAX_USERNAME_LENGTH 128 // Maximum size we'll accept for a WUE specified username
#define MAX_WININST 4 // Max number of install[.wim|.esd] we can handle on an image
#define MBR_UEFI_MARKER 0x49464555 // 'U', 'E', 'F', 'I', as a 32 bit little endian longword
#define MORE_INFO_URL 0xFFFF
@ -505,13 +506,13 @@ enum ArchType {
#define UNATTEND_NO_DATA_COLLECTION 0x00008
#define UNATTEND_OFFLINE_INTERNAL_DRIVES 0x00010
#define UNATTEND_DUPLICATE_LOCALE 0x00020
#define UNATTEND_DUPLICATE_USER 0x00040
#define UNATTEND_SET_USER 0x00040
#define UNATTEND_DEFAULT_MASK 0x0007F
#define UNATTEND_WINDOWS_TO_GO 0x10000 // Special flag for Windows To Go
#define UNATTEND_WINPE_SETUP_MASK (UNATTEND_SECUREBOOT_TPM_MINRAM)
#define UNATTEND_SPECIALIZE_DEPLOYMENT_MASK (UNATTEND_NO_ONLINE_ACCOUNT)
#define UNATTEND_OOBE_SHELL_SETUP_MASK (UNATTEND_NO_DATA_COLLECTION | UNATTEND_DUPLICATE_USER)
#define UNATTEND_OOBE_SHELL_SETUP_MASK (UNATTEND_NO_DATA_COLLECTION | UNATTEND_SET_USER)
#define UNATTEND_OOBE_INTERNATIONAL_MASK (UNATTEND_DUPLICATE_LOCALE)
#define UNATTEND_OOBE_MASK (UNATTEND_OOBE_SHELL_SETUP_MASK | UNATTEND_OOBE_INTERNATIONAL_MASK)
#define UNATTEND_OFFLINE_SERVICING_MASK (UNATTEND_OFFLINE_INTERNAL_DRIVES)
@ -583,7 +584,8 @@ extern BOOL CreateTooltip(HWND hControl, const char* message, int duration);
extern void DestroyTooltip(HWND hWnd);
extern void DestroyAllTooltips(void);
extern BOOL Notification(int type, const char* dont_display_setting, const notification_info* more_info, char* title, char* format, ...);
extern int SelectionDialog(int style, char* title, char* message, char** choices, int size, int mask);
extern int CustomSelectionDialog(int style, char* title, char* message, char** choices, int size, int mask, int username_index);
#define SelectionDialog(title, message, choices, size) CustomSelectionDialog(BS_AUTORADIOBUTTON, title, message, choices, size, 1, -1)
extern void ListDialog(char* title, char* message, char** items, int size);
extern SIZE GetTextSize(HWND hCtrl, char* txt);
extern BOOL ExtractAppIcon(const char* filename, BOOL bSilent);

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 3.21.1940"
CAPTION "Rufus 3.21.1941"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -174,6 +174,7 @@ BEGIN
CONTROL "Choice 14",IDC_SELECTION_CHOICE14,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,35,187,269,10,WS_EX_TRANSPARENT
CONTROL "Choice 15",IDC_SELECTION_CHOICE15,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,35,200,269,10,WS_EX_TRANSPARENT
CONTROL "Choice 16",IDC_SELECTION_CHOICEMAX,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,35,213,269,10,WS_EX_TRANSPARENT
EDITTEXT IDC_SELECTION_USERNAME,197,57,0,9,ES_AUTOHSCROLL | NOT WS_VISIBLE | WS_TABSTOP | WS_BORDER
END
IDD_LIST DIALOGEX 0, 0, 312, 59
@ -395,8 +396,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,21,1940,0
PRODUCTVERSION 3,21,1940,0
FILEVERSION 3,21,1941,0
PRODUCTVERSION 3,21,1941,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -414,13 +415,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "3.21.1940"
VALUE "FileVersion", "3.21.1941"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-3.21.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.21.1940"
VALUE "ProductVersion", "3.21.1941"
END
END
BLOCK "VarFileInfo"

View file

@ -46,6 +46,7 @@
/* Globals */
extern BOOL is_x86_32, appstore_version;
extern char unattend_username[MAX_USERNAME_LENGTH];
static HICON hMessageIcon = (HICON)INVALID_HANDLE_VALUE;
static char* szMessageText = NULL;
static char* szMessageTitle = NULL;
@ -53,7 +54,7 @@ static char **szDialogItem;
static int nDialogItems;
static HWND hBrowseEdit, hUpdatesDlg;
static WNDPROC pOrgBrowseWndproc;
static const SETTEXTEX friggin_microsoft_unicode_amateurs = {ST_DEFAULT, CP_UTF8};
static const SETTEXTEX friggin_microsoft_unicode_amateurs = { ST_DEFAULT, CP_UTF8 };
static BOOL notification_is_question;
static const notification_info* notification_more_info;
static const char* notification_dont_display_setting;
@ -564,9 +565,9 @@ INT_PTR CALLBACK LicenseCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM
INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int i, dy;
const int edit_id[2] = {IDC_ABOUT_BLURB, IDC_ABOUT_COPYRIGHTS};
const int edit_id[2] = { IDC_ABOUT_BLURB, IDC_ABOUT_COPYRIGHTS };
char about_blurb[2048];
const char* edit_text[2] = {about_blurb, additional_copyrights};
const char* edit_text[2] = { about_blurb, additional_copyrights };
HWND hEdit[2], hCtrl;
TEXTRANGEW tr;
ENLINK* enl;
@ -596,7 +597,7 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
lmprintf(MSG_175|MSG_RTF, rufus_version[0], rufus_version[1], rufus_version[2]),
"Copyright © 2011-2022 Pete Batard",
lmprintf(MSG_176|MSG_RTF), lmprintf(MSG_177|MSG_RTF), lmprintf(MSG_178|MSG_RTF));
for (i=0; i<ARRAYSIZE(hEdit); i++) {
for (i = 0; i < ARRAYSIZE(hEdit); i++) {
hEdit[i] = GetDlgItem(hDlg, edit_id[i]);
SendMessage(hEdit[i], EM_AUTOURLDETECT, 1, 0);
/* Can't use SetDlgItemText, because it only works with RichEdit20A... and VS insists
@ -605,7 +606,7 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
* http://blog.kowalczyk.info/article/eny/Setting-unicode-rtf-text-in-rich-edit-control.html */
SendMessageA(hEdit[i], EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)edit_text[i]);
SendMessage(hEdit[i], EM_SETSEL, -1, -1);
SendMessage(hEdit[i], EM_SETEVENTMASK, 0, ENM_LINK|((i==0)?ENM_REQUESTRESIZE:0));
SendMessage(hEdit[i], EM_SETEVENTMASK, 0, ENM_LINK | ((i == 0) ? ENM_REQUESTRESIZE : 0));
SendMessage(hEdit[i], EM_SETBKGNDCOLOR, 0, (LPARAM)GetSysColor(COLOR_BTNFACE));
}
// Need to send an explicit SetSel to avoid being positioned at the end of richedit control when tabstop is used
@ -860,19 +861,25 @@ BOOL Notification(int type, const char* dont_display_setting, const notification
}
// We only ever display one selection dialog, so set some params as globals
static int selection_dialog_style, selection_dialog_mask;
static int selection_dialog_style, selection_dialog_mask, selection_dialog_username_index;
/*
* Custom dialog for radio button selection dialog
*/
INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
static INT_PTR CALLBACK CustomSelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT loc;
int i, m, dw, dh, r = -1, mw;
// This "Mooo" is designed to give us enough space for a regular username length
static const char* base_username = "MOOOOOOOOOOO"; // 🐮
// https://learn.microsoft.com/en-us/previous-versions/cc722458(v=technet.10)#user-name-policies
static const char* username_invalid_chars = "/\\[]:;|=,+*?<>\"";
// Prevent resizing
static LRESULT disabled[9] = { HTLEFT, HTRIGHT, HTTOP, HTBOTTOM, HTSIZE,
HTTOPLEFT, HTTOPRIGHT, HTBOTTOMLEFT, HTBOTTOMRIGHT };
static HBRUSH background_brush, separator_brush;
char username[128] = { 0 };
int i, m, dw, dh, r = -1, mw;
DWORD size = sizeof(username);
LRESULT loc;
// To use the system message font
NONCLIENTMETRICS ncm;
RECT rc, rc2;
@ -894,7 +901,7 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA
// Get the system message box font. See http://stackoverflow.com/a/6057761
ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
hDlgFont = CreateFontIndirect(&(ncm.lfMessageFont));
hDlgFont = CreateFontIndirect(&ncm.lfMessageFont);
// Set the dialog to use the system message box font
SendMessage(hDlg, WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(TRUE, 0));
SendMessage(GetDlgItem(hDlg, IDC_SELECTION_TEXT), WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(TRUE, 0));
@ -921,10 +928,17 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA
SetWindowTextU(GetDlgItem(hDlg, IDCANCEL), lmprintf(MSG_007));
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_TEXT), szMessageText);
for (i = 0; i < nDialogItems; i++) {
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), szDialogItem[i]);
char *str = szDialogItem[i];
SetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), str);
ShowWindow(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), SW_SHOW);
// Compute the maximum line's width
mw = max(mw, GetTextSize(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), szDialogItem[i]).cx);
// Compute the maximum line's width (with some extra for the username field if needed)
if (i == selection_dialog_username_index) {
str = calloc(strlen(szDialogItem[i]) + strlen(base_username) + 8, 1);
sprintf(str, "%s __%s__", szDialogItem[i], base_username);
}
mw = max(mw, GetTextSize(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), str).cx);
if (i == selection_dialog_username_index)
free(str);
}
// If our maximum line's width is greater than the default, set a nonzero delta width
dw = (mw <= dw) ? 0: mw - dw;
@ -941,6 +955,26 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA
ResizeMoveCtrl(hDlg, hCtrl, 0, 0, 0, dh, 1.0f);
for (i = 0; i < nDialogItems; i++)
ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), 0, dh, dw, 0, 1.0f);
// If required, set up the the username edit box
if (selection_dialog_username_index != -1) {
unattend_username[0] = 0;
hCtrl = GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + selection_dialog_username_index);
GetClientRect(hCtrl, &rc);
ResizeMoveCtrl(hDlg, hCtrl, 0, 0,
(rc.left - rc.right) + GetTextSize(hCtrl, szDialogItem[selection_dialog_username_index]).cx + ddw, 0, 1.0f);
GetWindowRect(hCtrl, &rc);
SetWindowPos(GetDlgItem(hDlg, IDC_SELECTION_USERNAME), hCtrl, rc.left, rc.top, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
hCtrl = GetDlgItem(hDlg, IDC_SELECTION_USERNAME);
GetWindowRect(hCtrl, &rc2);
ResizeMoveCtrl(hDlg, hCtrl, right_to_left_mode ? rc2.right - rc.left : rc.right - rc2.left, rc.top - rc2.top,
GetTextSize(hCtrl, (char*)base_username).cx, 0, 1.0f);
if (!GetUserNameU(username, &size) || username[0] == 0)
static_strcpy(username, "User");
SetWindowTextU(hCtrl, username);
ShowWindow(hCtrl, SW_SHOW);
}
if (nDialogItems > 2) {
GetWindowRect(GetDlgItem(hDlg, IDC_SELECTION_CHOICE2), &rc);
GetWindowRect(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + nDialogItems - 1), &rc2);
@ -982,6 +1016,14 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA
for (r = 0, i = 0, m = 1; i < nDialogItems; i++, m <<= 1)
if (Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i)) == BST_CHECKED)
r += m;
if (selection_dialog_username_index != -1) {
GetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_USERNAME), unattend_username, MAX_USERNAME_LENGTH);
// Perform string sanitization (NB: GetWindowTextU always terminates the string)
for (i = 0; unattend_username[i] != 0; i++) {
if (strchr(username_invalid_chars, unattend_username[i]) != NULL)
unattend_username[i] = '_';
}
}
// Fall through
case IDNO:
case IDCANCEL:
@ -996,7 +1038,7 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA
/*
* Display an item selection dialog
*/
int SelectionDialog(int style, char* title, char* message, char** choices, int size, int mask)
int CustomSelectionDialog(int style, char* title, char* message, char** choices, int size, int mask, int username_index)
{
int ret;
@ -1007,8 +1049,9 @@ int SelectionDialog(int style, char* title, char* message, char** choices, int s
nDialogItems = size;
selection_dialog_style = style;
selection_dialog_mask = mask;
selection_dialog_username_index = username_index;
assert(selection_dialog_style == BS_AUTORADIOBUTTON || selection_dialog_style == BS_AUTOCHECKBOX);
ret = (int)MyDialogBox(hMainInstance, IDD_SELECTION, hMainDialog, SelectionCallback);
ret = (int)MyDialogBox(hMainInstance, IDD_SELECTION, hMainDialog, CustomSelectionCallback);
dialog_showing--;
return ret;

View file

@ -43,7 +43,7 @@ const char* bypass_name[] = { "BypassTPMCheck", "BypassSecureBootCheck", "Bypass
int unattend_xml_flags = 0, wintogo_index = -1, wininst_index = 0;
int unattend_xml_mask = UNATTEND_DEFAULT_SELECTION_MASK;
char* unattend_xml_path = NULL;
char *unattend_xml_path = NULL, unattend_username[MAX_USERNAME_LENGTH];
extern uint32_t wim_nb_files, wim_proc_files, wim_extra_files;
@ -138,21 +138,19 @@ char* CreateUnattendXml(int arch, int flags)
fprintf(fd, " <ProtectYourPC>3</ProtectYourPC>\n");
fprintf(fd, " </OOBE>\n");
}
if (flags & UNATTEND_DUPLICATE_USER) {
order = 1;
char username[128] = { 0 };
DWORD size = sizeof(username);
if (GetUserNameU(username, &size) && username[0] != 0) {
// Administrator and Guest are default accounts that we shouldn't touch
if ((stricmp(username, "Administrator") == 0) || (stricmp(username, "Guest") == 0))
static_strcpy(username, "User");
if (flags & UNATTEND_SET_USER) {
if ((unattend_username[0] == 0) || (stricmp(unattend_username, "Administrator") == 0) ||
(stricmp(unattend_username, "Guest") == 0)) {
uprintf("WARNING: '%s' is not allowed as local account name - Option ignored", unattend_username);
} else {
uprintf("Will use '%s' for local account name", unattend_username);
// If we create a local account in unattend.xml, then we can get Windows 11
// 22H2 to skip MSA even if the network is connected during installation.
fprintf(fd, " <UserAccounts>\n");
fprintf(fd, " <LocalAccounts>\n");
fprintf(fd, " <LocalAccount wcm:action=\"add\">\n");
fprintf(fd, " <Name>%s</Name>\n", username);
fprintf(fd, " <DisplayName>%s</DisplayName>\n", username);
fprintf(fd, " <Name>%s</Name>\n", unattend_username);
fprintf(fd, " <DisplayName>%s</DisplayName>\n", unattend_username);
fprintf(fd, " <Group>Administrators;Power Users</Group>\n");
// Sets an empty password for the account (which, in Microsoft's convoluted ways,
// needs to be initialized to the Base64 encoded UTF-16 string "Password").
@ -170,11 +168,9 @@ char* CreateUnattendXml(int arch, int flags)
fprintf(fd, " <FirstLogonCommands>\n");
fprintf(fd, " <SynchronousCommand wcm:action=\"add\">\n");
fprintf(fd, " <Order>%d</Order>\n", order++);
fprintf(fd, " <CommandLine>net user &quot;%s&quot; /logonpasswordchg:yes</CommandLine>\n", username);
fprintf(fd, " <CommandLine>net user &quot;%s&quot; /logonpasswordchg:yes</CommandLine>\n", unattend_username);
fprintf(fd, " </SynchronousCommand>\n");
fprintf(fd, " </FirstLogonCommands>\n");
} else {
uprintf("Warning: Could not retreive current user name. Local Account was not created");
}
}
fprintf(fd, " </component>\n");
@ -483,8 +479,7 @@ int SetWinToGoIndex(void)
if (img_report.wininst_index > 1) {
for (i = 0; i < img_report.wininst_index; i++)
install_names[i] = &img_report.wininst_path[i][2];
wininst_index = _log2(SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_130),
lmprintf(MSG_131), install_names, img_report.wininst_index, 1));
wininst_index = _log2(SelectionDialog(lmprintf(MSG_130), lmprintf(MSG_131), install_names, img_report.wininst_index));
if (wininst_index < 0)
return -2;
if (wininst_index >= MAX_WININST)
@ -539,8 +534,7 @@ int SetWinToGoIndex(void)
if (i > 1)
// NB: _log2 returns -2 if SelectionDialog() returns negative (user cancelled)
i = _log2(SelectionDialog(BS_AUTORADIOBUTTON,
lmprintf(MSG_291), lmprintf(MSG_292), version_name.String, i, 1)) + 1;
i = _log2(SelectionDialog(lmprintf(MSG_291), lmprintf(MSG_292), version_name.String, i)) + 1;
if (i < 0)
wintogo_index = -2; // Cancelled by the user
else if (i == 0)