winecfg: Add support for '/v' parameter allowing Windows version to be changed.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=41559
Signed-off-by: Owen Rudge <orudge@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Owen Rudge 2020-04-16 15:06:27 +01:00 committed by Alexandre Julliard
parent 6eb05dab7c
commit 90c0123533
3 changed files with 87 additions and 52 deletions

View File

@ -34,7 +34,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
static const struct
struct win_version
{
const char *szVersion;
const char *szDescription;
@ -46,7 +46,9 @@ static const struct
WORD wServicePackMajor;
WORD wServicePackMinor;
const char *szProductType;
} win_versions[] =
};
static const struct win_version win_versions[] =
{
{ "win10", "Windows 10", 10, 0, 0x42EE,VER_PLATFORM_WIN32_NT, "", 0, 0, "WinNT"},
{ "win81", "Windows 8.1", 6, 3, 0x2580,VER_PLATFORM_WIN32_NT, "", 0, 0, "WinNT"},
@ -396,37 +398,20 @@ static void on_remove_app_click(HWND dialog)
SendMessageW(GetParent(dialog), PSM_CHANGED, (WPARAM) dialog, 0);
}
static void on_winver_change(HWND dialog)
static void set_winver(const struct win_version *version)
{
int selection = SendDlgItemMessageW(dialog, IDC_WINVER, CB_GETCURSEL, 0, 0);
static const char szKeyWindNT[] = "System\\CurrentControlSet\\Control\\Windows";
static const char szKeyEnvNT[] = "System\\CurrentControlSet\\Control\\Session Manager\\Environment";
char Buffer[40];
if (current_app)
switch (version->dwPlatformId)
{
if (!selection)
{
WINE_TRACE("default selected so removing current setting\n");
set_reg_key(config_key, keypath(""), "Version", NULL);
}
else
{
WINE_TRACE("setting Version key to value '%s'\n", win_versions[selection-1].szVersion);
set_reg_key(config_key, keypath(""), "Version", win_versions[selection-1].szVersion);
}
}
else /* global version only */
{
static const char szKeyWindNT[] = "System\\CurrentControlSet\\Control\\Windows";
static const char szKeyEnvNT[] = "System\\CurrentControlSet\\Control\\Session Manager\\Environment";
char Buffer[40];
switch (win_versions[selection].dwPlatformId)
{
case VER_PLATFORM_WIN32_WINDOWS:
snprintf(Buffer, sizeof(Buffer), "%d.%d.%d", win_versions[selection].dwMajorVersion,
win_versions[selection].dwMinorVersion, win_versions[selection].dwBuildNumber);
snprintf(Buffer, sizeof(Buffer), "%d.%d.%d", version->dwMajorVersion,
version->dwMinorVersion, version->dwBuildNumber);
set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "VersionNumber", Buffer);
set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "SubVersionNumber", win_versions[selection].szCSDVersion);
snprintf(Buffer, sizeof(Buffer), "Microsoft %s", win_versions[selection].szDescription);
set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "SubVersionNumber", version->szCSDVersion);
snprintf(Buffer, sizeof(Buffer), "Microsoft %s", version->szDescription);
set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "ProductName", Buffer);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CSDVersion", NULL);
@ -441,19 +426,19 @@ static void on_winver_change(HWND dialog)
break;
case VER_PLATFORM_WIN32_NT:
snprintf(Buffer, sizeof(Buffer), "%d.%d", win_versions[selection].dwMajorVersion,
win_versions[selection].dwMinorVersion);
snprintf(Buffer, sizeof(Buffer), "%d.%d", version->dwMajorVersion,
version->dwMinorVersion);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentVersion", Buffer);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CSDVersion", win_versions[selection].szCSDVersion);
snprintf(Buffer, sizeof(Buffer), "%d", win_versions[selection].dwBuildNumber);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CSDVersion", version->szCSDVersion);
snprintf(Buffer, sizeof(Buffer), "%d", version->dwBuildNumber);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentBuild", Buffer);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "CurrentBuildNumber", Buffer);
snprintf(Buffer, sizeof(Buffer), "Microsoft %s", win_versions[selection].szDescription);
snprintf(Buffer, sizeof(Buffer), "Microsoft %s", version->szDescription);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyNT, "ProductName", Buffer);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyProdNT, "ProductType", win_versions[selection].szProductType);
set_reg_key(HKEY_LOCAL_MACHINE, szKeyProdNT, "ProductType", version->szProductType);
set_reg_key_dword(HKEY_LOCAL_MACHINE, szKeyWindNT, "CSDVersion",
MAKEWORD( win_versions[selection].wServicePackMinor,
win_versions[selection].wServicePackMajor ));
MAKEWORD( version->wServicePackMinor,
version->wServicePackMajor ));
set_reg_key(HKEY_LOCAL_MACHINE, szKeyEnvNT, "OS", "Windows_NT");
set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "VersionNumber", NULL);
@ -474,11 +459,53 @@ static void on_winver_change(HWND dialog)
set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "VersionNumber", NULL);
set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "SubVersionNumber", NULL);
set_reg_key(HKEY_LOCAL_MACHINE, szKey9x, "ProductName", NULL);
set_reg_key(config_key, keypath(""), "Version", win_versions[selection].szVersion);
set_reg_key(config_key, keypath(""), "Version", version->szVersion);
break;
}
}
BOOL set_winver_from_string(const char *version)
{
int i;
WINE_TRACE("desired winver: '%s'\n", version);
for (i = 0; i < ARRAY_SIZE(win_versions); i++)
{
if (!lstrcmpiA(win_versions[i].szVersion, version))
{
WINE_TRACE("match with %s\n", win_versions[i].szVersion);
set_winver(&win_versions[i]);
apply();
return TRUE;
}
}
return FALSE;
}
static void on_winver_change(HWND dialog)
{
int selection = SendDlgItemMessageW(dialog, IDC_WINVER, CB_GETCURSEL, 0, 0);
if (current_app)
{
if (!selection)
{
WINE_TRACE("default selected so removing current setting\n");
set_reg_key(config_key, keypath(""), "Version", NULL);
}
else
{
WINE_TRACE("setting Version key to value '%s'\n", win_versions[selection-1].szVersion);
set_reg_key(config_key, keypath(""), "Version", win_versions[selection-1].szVersion);
}
}
else /* global version only */
{
set_winver(&win_versions[selection]);
}
/* enable the apply button */
SendMessageW(GetParent(dialog), PSM_CHANGED, (WPARAM) dialog, 0);
}

View File

@ -175,29 +175,34 @@ doPropertySheet (HINSTANCE hInstance, HWND hOwner)
/******************************************************************************
* Name : ProcessCmdLine
* Description: Checks command line parameters for 'autodetect drives' option
* Description: Checks command line parameters
* Parameters : lpCmdLine - the command line
* Returns : TRUE - if '/D' was found. Drive autodetection was carried out.
* FALSE - no '/D' option found in command line
* Notes : This is a very simple implementation, which only works
* correctly if the one and only cmd line option is '/D' or
* no option at all. Has to be reworked, if more options are to
* be supported.
* Returns : The return value to return from WinMain, or -1 to continue
* program execution.
*/
static BOOL
static int
ProcessCmdLine(LPSTR lpCmdLine)
{
if ((lpCmdLine[0] == '/' || lpCmdLine[0] == '-') &&
(lpCmdLine[1] == 'D' || lpCmdLine[1] == 'd'))
if (!(lpCmdLine[0] == '/' || lpCmdLine[0] == '-'))
{
return -1;
}
if ((lpCmdLine[1] == 'D' || lpCmdLine[1] == 'd'))
{
gui_mode = FALSE;
if (autodetect_drives()) {
apply_drive_changes();
}
return TRUE;
return 0;
}
return FALSE;
if ((lpCmdLine[1] == 'V' || lpCmdLine[1] == 'v') && (lstrlenA(lpCmdLine) > 4))
{
return set_winver_from_string(&lpCmdLine[3]);
}
return -1;
}
/*****************************************************************************
@ -213,6 +218,7 @@ int WINAPI
WinMain (HINSTANCE hInstance, HINSTANCE hPrev, LPSTR szCmdLine, int nShow)
{
BOOL is_wow64;
int cmd_ret;
if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64)
{
@ -238,9 +244,8 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrev, LPSTR szCmdLine, int nShow)
Wow64RevertWow64FsRedirection( redir );
}
if (ProcessCmdLine(szCmdLine)) {
return 0;
}
cmd_ret = ProcessCmdLine(szCmdLine);
if (cmd_ret >= 0) return cmd_ret;
if (initialize(hInstance)) {
WINE_ERR("initialization failed, aborting\n");

View File

@ -89,6 +89,9 @@ INT_PTR CALLBACK AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
INT_PTR CALLBACK ThemeDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK AboutDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
/* Windows version management */
BOOL set_winver_from_string(const char *version);
/* Drive management */
BOOL load_drives(void);
BOOL autodetect_drives(void);