Diff:
---
desktop.cc | 41 +++++++++++++++++++++-------
desktop.h | 2 +-
fromcwd.cc | 8 +++---
ini.cc | 22 +++++++++++----
ini.h | 6 ++---
main.cc | 46 +++++++++++---------------------
mount.cc | 23 +++++++++++++++-
mount.h | 2 +-
res.pot | 8 +++---
res/en/res.rc | 8 +++---
root.cc | 86 +++++++++++++++++++++++++++++------------------------------
script.cc | 2 +-
state.cc | 2 ++
state.h | 2 ++
win32.cc | 5 ++--
15 files changed, 152 insertions(+), 111 deletions(-)
diff --git a/desktop.cc b/desktop.cc
index be7cc6ec..7795aada 100644
--- a/desktop.cc
+++ b/desktop.cc
@@ -95,14 +95,13 @@ make_link (const std::string& linkpath,
icon.c_str(), fname.c_str());
}
-const char *startmenusuffix()
+const std::string
+startmenusuffix()
{
- if (!is_64bit && (WowNativeMachine() != IMAGE_FILE_MACHINE_I386))
+ if ((installArch == IMAGE_FILE_MACHINE_I386) && (WowNativeMachine() !=
IMAGE_FILE_MACHINE_I386))
return " (32-bit)";
-#ifdef __x86_64__
- if (WowNativeMachine() != IMAGE_FILE_MACHINE_AMD64)
- return " (x86_64)";
-#endif
+ if (WowNativeMachine() != installArch)
+ return " (" + machine_name(installArch) + ")";
else
return "";
}
@@ -125,7 +124,7 @@ start_menu (const std::string& title, const std::string&
target,
CSIDL_PROGRAMS, &id);
SHGetPathFromIDList (id, path);
strncat (path, startmenudir(), MAX_PATH - strlen(path) - 1);
- strncat (path, startmenusuffix(), MAX_PATH - strlen(path) - 1);
+ strncat (path, startmenusuffix().c_str(), MAX_PATH - strlen(path) - 1);
LogBabblePrintf ("Program directory for program link: %s", path);
make_link (path, title, target, arg, iconpath);
}
@@ -212,8 +211,30 @@ save_icon (std::string &iconpath, const char
*resource_name)
#define TARGET "/bin/mintty"
#define DEFAULTICON "/Cygwin.ico"
#define TERMINALICON "/Cygwin-Terminal.ico"
-#define TERMINALTITLE (is_64bit ? "Cygwin64 Terminal" \
- : "Cygwin Terminal")
+#define TERMINALTITLE terminaltitle()
+
+static const std::string
+terminaltitle()
+{
+ /* The x86_64 terminal is always called "Cygwin64 Terminal" */
+ if (installArch == IMAGE_FILE_MACHINE_AMD64)
+ return "Cygwin64 Terminal";
+
+ /* Otherwise, just use the plain name when arches match */
+ if (WowNativeMachine() == installArch)
+ return "Cygwin Terminal";
+
+ /* Likewise, the x86 terminal is called just "Cygwin Terminal" on x86_64 */
+ if (installArch == IMAGE_FILE_MACHINE_I386)
+ {
+ if (WowNativeMachine() == IMAGE_FILE_MACHINE_AMD64)
+ return "Cygwin Terminal";
+ else
+ return "Cygwin32 Terminal";
+ }
+
+ return "Cygwin Terminal (" + machine_name(installArch) + ")";
+}
static void
do_desktop_setup ()
@@ -312,7 +333,7 @@ check_startmenu (const std::string title, const std::string
target)
SHGetPathFromIDList (id, path);
LogBabblePrintf ("Program directory for program link: %s", path);
strcat (path, startmenudir());
- strcat (path, startmenusuffix());
+ strcat (path, startmenusuffix().c_str());
std::string fname = std::string(path) + "/" + title + ".lnk";
if (_access (fname.c_str(), 0) == 0)
diff --git a/desktop.h b/desktop.h
index d4ce72de..4e6f5cac 100644
--- a/desktop.h
+++ b/desktop.h
@@ -43,7 +43,7 @@ public:
virtual bool OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam);
};
-const char *startmenusuffix();
+const std::string startmenusuffix();
extern BoolOption NoShortcutsOption;
extern BoolOption NoStartMenuOption;
diff --git a/fromcwd.cc b/fromcwd.cc
index 3e77ad37..7acc0ecb 100644
--- a/fromcwd.cc
+++ b/fromcwd.cc
@@ -53,7 +53,7 @@ public:
ext != setup_ext_list.end ();
ext++, fi++)
{
- if (!casecompare (SetupBaseName + "." + *ext, theFile->cFileName))
+ if (!casecompare (SetupBaseName() + "." + *ext,
theFile->cFileName))
*fi = true;
}
}
@@ -63,7 +63,7 @@ public:
{
if (level <= 0)
return;
- inidir = !casecompare (SetupArch, aDir->cFileName);
+ inidir = !casecompare (SetupArch(), aDir->cFileName);
if (level == 1 && !inidir)
return;
Find aFinder (basePath + aDir->cFileName);
@@ -75,8 +75,8 @@ public:
{
if (*fi)
{
- found_ini_list.push_back (basePath + SetupArch + "/"
- + SetupBaseName + "." + *ext);
+ found_ini_list.push_back (basePath + SetupArch() + "/"
+ + SetupBaseName() + "." + *ext);
/*
* Terminate the search after the first setup file
* found, which shadows any setup files with
diff --git a/ini.cc b/ini.cc
index 3ef13118..d919d450 100644
--- a/ini.cc
+++ b/ini.cc
@@ -47,6 +47,7 @@
#include "threebar.h"
#include "getopt++/BoolOption.h"
+#include "getopt++/StringOption.h"
#include "IniDBBuilderPackage.h"
#include "compress.h"
#include "Exception.h"
@@ -61,6 +62,7 @@ std::string ini_setup_version;
IniList setup_ext_list (setup_exts,
setup_exts + (sizeof(setup_exts) /
sizeof(*setup_exts)));
+static StringOption SetupBaseNameOption ("setup", 'i', "ini-basename",
IDS_HELPTEXT_INI_BASENAME, false);
static BoolOption NoVerifyOption (false, 'X', "no-verify",
IDS_HELPTEXT_NO_VERIFY);
static BoolOption NoVersionCheckOption (false, '\0', "no-version-check",
IDS_HELPTEXT_NO_VERSION_CHECK);
@@ -146,6 +148,16 @@ private:
int yyerror_count;
};
+std::string SetupArch()
+{
+ return machine_name(installArch);
+}
+
+std::string SetupBaseName()
+{
+ return SetupBaseNameOption;
+}
+
static io_stream*
decompress_ini (io_stream *ini_file, std::string ¤t_ini_name)
{
@@ -255,7 +267,7 @@ do_local_ini (HWND owner)
if (!ini_file || sig_fail)
{
// no setup found or signature invalid
- note (owner, IDS_SETUPINI_MISSING, SetupBaseName.c_str (),
+ note (owner, IDS_SETUPINI_MISSING, SetupBaseName().c_str (),
"localdir");
ini_error = true;
}
@@ -265,7 +277,7 @@ do_local_ini (HWND owner)
myFeedback.babble ("Found ini file - " + current_ini_name);
myFeedback.iniName (current_ini_name);
int ldl = local_dir.length () + 1;
- int cap = current_ini_name.rfind ("/" + SetupArch);
+ int cap = current_ini_name.rfind ("/" + SetupArch());
aBuilder.parse_mirror =
rfc1738_unescape (current_ini_name.substr (ldl, cap - ldl));
ini_init (ini_file, &aBuilder, myFeedback);
@@ -311,7 +323,7 @@ do_remote_ini (HWND owner)
ext++)
{
current_ini_ext = *ext;
- current_ini_name = n->url + SetupIniDir + SetupBaseName + "." +
current_ini_ext;
+ current_ini_name = n->url + SetupArch() + "/" + SetupBaseName() + "."
+ current_ini_ext;
current_ini_sig_name = current_ini_name + ".sig";
ini_sig_file = get_url_to_membuf (current_ini_sig_name, owner);
ini_file = get_url_to_membuf (current_ini_name, owner);
@@ -326,7 +338,7 @@ do_remote_ini (HWND owner)
if (!ini_file || sig_fail)
{
// no setup found or signature invalid
- note (owner, IDS_SETUPINI_MISSING, SetupBaseName.c_str (),
n->url.c_str ());
+ note (owner, IDS_SETUPINI_MISSING, SetupBaseName().c_str (),
n->url.c_str ());
ini_error = true;
}
else
@@ -346,7 +358,7 @@ do_remote_ini (HWND owner)
/* save known-good setup.ini locally */
const std::string fp = "file://" + local_dir + "/" +
rfc1738_escape_part (n->url) +
- "/" + SetupIniDir + SetupBaseName +
".ini";
+ "/" + SetupArch() + "/" + SetupBaseName()
+ ".ini";
io_stream::mkpath_p (PATH_TO_FILE, fp, 0);
if (io_stream *out = io_stream::open (fp, "wb", 0))
{
diff --git a/ini.h b/ini.h
index ecc4b78e..e318a8ab 100644
--- a/ini.h
+++ b/ini.h
@@ -23,11 +23,9 @@ class io_stream;
typedef std::vector <std::string> IniList;
extern IniList found_ini_list, setup_ext_list;
const std::string setup_exts[] = { "zst", "xz", "bz2", "ini" };
-extern bool is_64bit;
extern bool is_new_install;
-extern std::string SetupArch;
-extern std::string SetupIniDir;
-extern std::string SetupBaseName;
+std::string SetupArch();
+std::string SetupBaseName();
class IniState;
class IniDBBuilder;
diff --git a/main.cc b/main.cc
index cf9e3234..91d0eca0 100644
--- a/main.cc
+++ b/main.cc
@@ -82,9 +82,7 @@
extern char **_argv;
#endif
-bool is_64bit;
bool is_new_install = false;
-std::string SetupArch;
std::string SetupIniDir;
HINSTANCE hinstance;
@@ -102,21 +100,28 @@ static StringChoiceOption::StringChoices quiet_types({
{"hidden", QuietHidden},
});
-static StringOption Arch ("", 'a', "arch", IDS_HELPTEXT_ARCH, false);
+static StringChoiceOption::StringChoices arch_choices({
+ {"64", IMAGE_FILE_MACHINE_AMD64},
+ {"x86_64", IMAGE_FILE_MACHINE_AMD64},
+ {"amd64", IMAGE_FILE_MACHINE_AMD64},
+ {"32", IMAGE_FILE_MACHINE_I386},
+ {"x86", IMAGE_FILE_MACHINE_I386},
+ {"aarch64", IMAGE_FILE_MACHINE_ARM64},
+ {"arm64", IMAGE_FILE_MACHINE_ARM64},
+ });
+
+static StringChoiceOption Arch (arch_choices, 'a', "arch", IDS_HELPTEXT_ARCH,
false);
StringChoiceOption UnattendedOption (quiet_types, 'q', "quiet-mode",
IDS_HELPTEXT_QUIET_MODE, true, -1, QuietUnattended);
static BoolOption PackageManagerOption (false, 'M', "package-manager",
IDS_HELPTEXT_PACKAGE_MANAGER);
static BoolOption NoAdminOption (false, 'B', "no-admin",
IDS_HELPTEXT_NO_ADMIN);
static BoolOption WaitOption (false, 'W', "wait", IDS_HELPTEXT_WAIT);
static BoolOption HelpOption (false, 'h', "help", IDS_HELPTEXT_HELP);
static BoolOption VersionOption (false, 'V', "version", IDS_HELPTEXT_VERSION);
-static StringOption SetupBaseNameOpt ("setup", 'i', "ini-basename",
IDS_HELPTEXT_INI_BASENAME, false);
BoolOption UnsupportedOption (false, '\0', "allow-unsupported-windows",
IDS_HELPTEXT_ALLOW_UNSUPPORTED_WINDOWS);
static BoolOption DeprecatedOption (false, 'w', "no-warn-deprecated-windows",
IDS_HELPTEXT_NO_WARN_DEPRECATED_WINDOWS);
static StringChoiceOption SymlinkTypeOption(symlink_types, '\0',
"symlink-type", IDS_HELPTEXT_SYMLINK_TYPE, false, SymlinkTypeMagic);
static StringOption GuiLangOption ("", '\0', "lang", IDS_HELPTEXT_LANG);
-std::string SetupBaseName;
-
static void inline
set_cout ()
{
@@ -262,27 +267,10 @@ WinMain (HINSTANCE h,
else if (HelpOption)
help_option = true;
- if (!((std::string) Arch).size ())
- {
-#ifdef __x86_64__
- is_64bit = true;
-#else
- is_64bit = false;
-#endif
- }
- else if (((std::string) Arch).find ("64") != std::string::npos)
- is_64bit = true;
- else if (((std::string) Arch).find ("32") != std::string::npos
- || ((std::string) Arch).find ("x86") != std::string::npos)
- is_64bit = false;
+ if (Arch.isPresent())
+ installArch = Arch;
else
- {
- char buff[80 + ((std::string) Arch).size ()];
- sprintf (buff, "Invalid option for --arch: \"%s\"",
- ((std::string) Arch).c_str ());
- fprintf (stderr, "*** %s\n", buff);
- exit (1);
- }
+ installArch = WindowsProcessMachine();
if (GuiLangOption.isPresent())
{
@@ -303,10 +291,6 @@ WinMain (HINSTANCE h,
bool output_only = help_option || VersionOption;
- SetupBaseName = SetupBaseNameOpt;
- SetupArch = is_64bit ? "x86_64" : "x86";
- SetupIniDir = SetupArch+"/";
-
/* Initialize well known SIDs. We need the admin SID to test if we're
supposed to elevate. */
nt_sec.initialiseWellKnownSIDs ();
@@ -364,7 +348,7 @@ WinMain (HINSTANCE h,
#ifdef _X86_
(TRUE)
#else
- (!is_64bit)
+ (installArch == IMAGE_FILE_MACHINE_I386)
#endif
{
mbox (NULL, IDS_UNSUPPORTED_WINDOWS_ARCH,
diff --git a/mount.cc b/mount.cc
index a38f52ce..0d15c713 100644
--- a/mount.cc
+++ b/mount.cc
@@ -356,13 +356,34 @@ read_mounts (const std::string val)
}
}
+ /*
+ The default root directory: for historical reasons (you could already have
a
+ x86 install in cygwin), it's always cygwin64 for an x86_64 install.
+
+ It isn't critical that these are unique by arch, as we'll later check and
+ warn if it already contains a cygwin install for a different arch.
+ */
if (!root_here)
{
/* Affected path always < MAX_PATH. */
char windir[MAX_PATH];
GetSystemWindowsDirectory (windir, sizeof (windir));
windir[2] = 0;
- m->native = std::string (windir) + (is_64bit ? "\\cygwin64" :
"\\cygwin");
+
+ std::string rootdir;
+ if (installArch == IMAGE_FILE_MACHINE_AMD64)
+ rootdir = "\\cygwin64";
+ else if (WowNativeMachine() == installArch)
+ rootdir = "\\cygwin";
+ else if (installArch == IMAGE_FILE_MACHINE_I386)
+ if (WowNativeMachine() == IMAGE_FILE_MACHINE_AMD64)
+ rootdir = "\\cygwin";
+ else
+ rootdir = "\\cygwin32";
+ else
+ rootdir = "\\cygwin_" + machine_name(installArch);
+
+ m->native = std::string (windir) + rootdir;
m->posix = "/";
root_here = m;
add_usr_mnts (++m);
diff --git a/mount.h b/mount.h
index c451a02d..b0ff2510 100644
--- a/mount.h
+++ b/mount.h
@@ -18,7 +18,7 @@
#include <string>
#include "String++.h"
-#define SETUP_KEY_WOW64 (is_64bit ? KEY_WOW64_64KEY : KEY_WOW64_32KEY)
+#define SETUP_KEY_WOW64 ((installArch != IMAGE_FILE_MACHINE_I386) ?
KEY_WOW64_64KEY : KEY_WOW64_32KEY)
void create_install_root ();
void read_mounts (const std::string);
diff --git a/res.pot b/res.pot
index a4994e41..040923af 100644
--- a/res.pot
+++ b/res.pot
@@ -1061,12 +1061,12 @@ msgstr ""
msgid ""
"Target CPU mismatch\n"
"\n"
-"You're trying to install a %s bit version of Cygwin into a directory "
-"containing a %s bit version of Cygwin. Continuing to do so would break the "
+"You're trying to install the %s version of Cygwin into a directory "
+"containing the %s version of Cygwin. Continuing to do so would break the "
"existing installation.\n"
"\n"
-"Either run setup-%s.exe to update your existing %s bit installation of "
-"Cygwin, or choose another directory for your %s bit installation."
+"Either run setup-%s.exe to update your existing %s installation of Cygwin, "
+"or choose another directory for your %s installation."
msgstr ""
#: STRINGTABLE.IDS_GET_SITELIST_ERROR
diff --git a/res/en/res.rc b/res/en/res.rc
index e526b99d..0bdd4c7d 100644
--- a/res/en/res.rc
+++ b/res/en/res.rc
@@ -613,12 +613,12 @@ BEGIN
IDS_MIXED_BITNESS_ERROR
"Target CPU mismatch"
"\n\n"
- "You're trying to install a %s bit version of Cygwin into a directory "
- "containing a %s bit version of Cygwin. Continuing to do so would "
+ "You're trying to install the %s version of Cygwin into a directory "
+ "containing the %s version of Cygwin. Continuing to do so would "
"break the existing installation."
"\n\n"
- "Either run setup-%s.exe to update your existing %s bit installation
of Cygwin, "
- "or choose another directory for your %s bit installation."
+ "Either run setup-%s.exe to update your existing %s installation of
Cygwin, "
+ "or choose another directory for your %s installation."
IDS_GET_SITELIST_ERROR
"Can't get list of download sites.\n"
"Make sure your network settings are correct and try again."
diff --git a/root.cc b/root.cc
index ccbd6ae3..83af9eab 100644
--- a/root.cc
+++ b/root.cc
@@ -152,70 +152,70 @@ directory_has_spaces ()
return 0;
}
-static int
-directory_contains_wrong_version (HWND h)
+static USHORT
+read_fileheader_machine_type(std::string fn)
{
HANDLE fh;
- std::string cygwin_dll = get_root_dir() + "\\bin\\cygwin1.dll";
-
- /* Check if we have a cygwin1.dll. If not, this is a new install.
- If yes, check if the target machine type of this setup version is the
- same as the machine type of the install Cygwin DLL. If yes, just go
- ahead. If not, show a message and indicate this to the caller.
-
- If anything goes wrong reading the header of cygwin1.dll, we check
- cygcheck.exe's binary type. This also covers the situation that the
- installed cygwin1.dll is broken for some reason. */
- fh = CreateFileA (cygwin_dll.c_str (), GENERIC_READ, FILE_SHARE_VALID_FLAGS,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ fh = CreateFileA (fn.c_str (), GENERIC_READ, FILE_SHARE_VALID_FLAGS,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (fh != INVALID_HANDLE_VALUE)
{
DWORD read = 0;
struct {
- LONG dos_header[32];
- IMAGE_NT_HEADERS32 nt_header;
+ LONG dos_header[32];
+ IMAGE_NT_HEADERS32 nt_header;
} hdr;
ReadFile (fh, &hdr, sizeof hdr, &read, NULL);
CloseHandle (fh);
- if (read != sizeof hdr)
- fh = INVALID_HANDLE_VALUE;
- else
- {
- /* 32 bit setup and 32 bit inst? */
- if (hdr.nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386
- && !is_64bit)
- return 0;
- /* 64 bit setup and 64 bit inst? */
- if (hdr.nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64
- && is_64bit)
- return 0;
- }
+ if (read == sizeof hdr)
+ {
+ return hdr.nt_header.FileHeader.Machine;
+ }
}
- if (fh == INVALID_HANDLE_VALUE)
+ return IMAGE_FILE_MACHINE_UNKNOWN;
+}
+
+static int
+directory_contains_wrong_version (HWND h)
+{
+ /*
+ Check if we have a cygwin1.dll. If not, this is a new install.
+
+ If yes, check if the target machine type for setup is the same as the
+ machine type of the installed Cygwin DLL. If yes, just go ahead. If not,
+ show a message and indicate this to the caller.
+
+ If anything goes wrong reading the header of cygwin1.dll, we check
+ cygcheck.exe's binary type. This also covers the situation that the
+ installed cygwin1.dll is broken for some reason.
+ */
+
+ std::string cygwin_dll = get_root_dir() + "\\bin\\cygwin1.dll";
+ USHORT headerArch = read_fileheader_machine_type(cygwin_dll);
+
+ if (headerArch == IMAGE_FILE_MACHINE_UNKNOWN)
{
- DWORD type;
std::string cygcheck_exe = get_root_dir() + "\\bin\\cygcheck.exe";
+ headerArch = read_fileheader_machine_type(cygcheck_exe);
- /* Probably new installation */
- if (!GetBinaryType (cygcheck_exe.c_str (), &type))
+ if (headerArch == IMAGE_FILE_MACHINE_UNKNOWN)
{
+ /* No cygcheck either, probably a new installation */
is_new_install = true;
return 0;
}
- /* 64 bit setup and 64 bit inst? */
- if (type == SCS_32BIT_BINARY && !is_64bit)
- return 0;
- /* 32 bit setup and 32 bit inst? */
- if (type == SCS_64BIT_BINARY && is_64bit)
- return 0;
}
+ /* machine type matches */
+ if (headerArch == installArch)
+ return 0;
+
/* Forestall mixing. */
- const char *setup_ver = is_64bit ? "64" : "32";
- const char *inst_ver = is_64bit ? "32" : "64";
- mbox (h, IDS_MIXED_BITNESS_ERROR, MB_OK,
- setup_ver, inst_ver, is_64bit ? "x86" : "x86_64", inst_ver, setup_ver);
+ const char *setup_ver = machine_name(installArch).c_str();
+ const char *inst_ver = machine_name(headerArch).c_str();
+ mbox (h, IDS_MIXED_BITNESS_ERROR, MB_OK, setup_ver, inst_ver, inst_ver,
+ inst_ver, setup_ver);
return 1;
}
diff --git a/script.cc b/script.cc
index f578ea60..fbc7e279 100644
--- a/script.cc
+++ b/script.cc
@@ -142,7 +142,7 @@ init_run_script ()
SetEnvironmentVariable ("CYGWINFORALL",
(root_scope == IDC_ROOT_SYSTEM) ? "-A" : NULL);
- const char *sms = startmenusuffix();
+ const char *sms = startmenusuffix().c_str();
if (strlen(sms) > 0)
SetEnvironmentVariable ("CYGWIN_START_MENU_SUFFIX", sms);
diff --git a/state.cc b/state.cc
index 111b890a..7e07a59a 100644
--- a/state.cc
+++ b/state.cc
@@ -29,3 +29,5 @@ int root_menu;
int root_desktop;
LANGID langid;
+
+USHORT installArch;
diff --git a/state.h b/state.h
index b211de38..9c0e7068 100644
--- a/state.h
+++ b/state.h
@@ -48,4 +48,6 @@ extern int root_desktop;
extern LANGID langid;
+extern USHORT installArch;
+
#endif /* SETUP_STATE_H */
diff --git a/win32.cc b/win32.cc
index cd7fec51..eb709b1e 100644
--- a/win32.cc
+++ b/win32.cc
@@ -21,6 +21,7 @@
#include "ini.h"
#include <sys/stat.h>
#include "String++.h"
+#include <iomanip>
NTSecurity nt_sec;
@@ -483,11 +484,11 @@ machine_name(USHORT machine)
return "x86_64";
break;
case IMAGE_FILE_MACHINE_ARM64:
- return "ARM64";
+ return "arm64";
break;
default:
std::stringstream machine_desc;
- machine_desc << std::hex << machine;
+ machine_desc << std::hex << std::setw(4) << std::setfill('0') << machine;
return machine_desc.str();
}
}
[setup - the official Cygwin setup program] branch master, updated. release_2.934-3-g0e685064
Jon Turney via Cygwin-apps-cvs Fri, 23 May 2025 12:22:41 -0700
