[PATCH setup 0/2] Use a separate Start Menu folder for WoW64 installs

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH setup 0/2] Use a separate Start Menu folder for WoW64 installs

Jon TURNEY
This avoids setup trying to make shortcuts with the same pathname, when both
32-bit and 64-bit installs exist on a 64-bit system.

Jon Turney (2):
  Factor out WoW detection
  Rename Start Menu folder for 32-bit installs on WoW64

 desktop.cc | 13 ++++++++++---
 nio-ie5.cc | 45 ++++++++++++++++-----------------------------
 win32.cc   | 26 ++++++++++++++++++++++++++
 win32.h    |  2 ++
 4 files changed, 54 insertions(+), 32 deletions(-)

--
2.21.0

Reply | Threaded
Open this post in threaded view
|

[PATCH setup 1/2] Factor out WoW detection

Jon TURNEY
Factor out WoW detection as a separate function
---
 nio-ie5.cc | 45 ++++++++++++++++-----------------------------
 win32.cc   | 26 ++++++++++++++++++++++++++
 win32.h    |  2 ++
 3 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/nio-ie5.cc b/nio-ie5.cc
index f5ad020..fe61b77 100644
--- a/nio-ie5.cc
+++ b/nio-ie5.cc
@@ -52,37 +52,24 @@ determine_default_useragent(void)
 #ifdef __x86_64__
   bitness = "Win64";
 #else
-  typedef BOOL (WINAPI *PFNISWOW64PROCESS2)(HANDLE, USHORT *, USHORT *);
-  PFNISWOW64PROCESS2 pfnIsWow64Process2 = (PFNISWOW64PROCESS2)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process2");
-
-  typedef BOOL (WINAPI *PFNISWOW64PROCESS)(HANDLE, PBOOL);
-  PFNISWOW64PROCESS pfnIsWow64Process = (PFNISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
-
+  USHORT nativeMachine = WowNativeMachine();
   std::stringstream native_desc;
 
-  USHORT processMachine, nativeMachine;
-  if ((pfnIsWow64Process2) &&
-      (pfnIsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine))) {
-    switch (nativeMachine)
-      {
-      case IMAGE_FILE_MACHINE_I386:
-        bitness = "Win32";
-        break;
-      case IMAGE_FILE_MACHINE_AMD64:
-        bitness = "WoW64";
-        break;
-      case IMAGE_FILE_MACHINE_ARM64:
-        bitness = "WoW64-ARM64";
-        break;
-      default:
-        native_desc << "WoW64-" << std::hex << nativeMachine;
-        bitness = native_desc.str();
-      }
-  } else if (pfnIsWow64Process) {
-    BOOL bIsWow64 = FALSE;
-    if (pfnIsWow64Process(GetCurrentProcess(), &bIsWow64))
-      bitness = bIsWow64 ? "WoW64" : "Win32";
-  }
+  switch (nativeMachine)
+    {
+    case IMAGE_FILE_MACHINE_I386:
+      bitness = "Win32";
+      break;
+    case IMAGE_FILE_MACHINE_AMD64:
+      bitness = "WoW64";
+      break;
+    case IMAGE_FILE_MACHINE_ARM64:
+      bitness = "WoW64-ARM64";
+      break;
+    default:
+      native_desc << "WoW64-" << std::hex << nativeMachine;
+      bitness = native_desc.str();
+    }
 #endif
   default_useragent = std::string("Cygwin-Setup/") + setup_version + " (" + os.str() + ";" + bitness + ")";
   return default_useragent;
diff --git a/win32.cc b/win32.cc
index 6a551ba..45c7bf1 100644
--- a/win32.cc
+++ b/win32.cc
@@ -393,3 +393,29 @@ VersionInfo& GetVer ()
   static VersionInfo *vi = new VersionInfo ();
   return *vi;
 }
+
+/* Identify native machine arch if we are running under WoW */
+USHORT
+WowNativeMachine ()
+{
+#ifdef __x86_64__
+  return IMAGE_FILE_MACHINE_AMD64;
+#else
+  typedef BOOL (WINAPI *PFNISWOW64PROCESS2)(HANDLE, USHORT *, USHORT *);
+  PFNISWOW64PROCESS2 pfnIsWow64Process2 = (PFNISWOW64PROCESS2)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process2");
+
+  typedef BOOL (WINAPI *PFNISWOW64PROCESS)(HANDLE, PBOOL);
+  PFNISWOW64PROCESS pfnIsWow64Process = (PFNISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
+
+  USHORT processMachine, nativeMachine;
+  if ((pfnIsWow64Process2) &&
+      (pfnIsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine)))
+    return nativeMachine;
+  else if (pfnIsWow64Process) {
+    BOOL bIsWow64 = FALSE;
+    if (pfnIsWow64Process(GetCurrentProcess(), &bIsWow64))
+      return bIsWow64 ? IMAGE_FILE_MACHINE_AMD64 : IMAGE_FILE_MACHINE_I386;
+  }
+  return IMAGE_FILE_MACHINE_I386;
+#endif
+}
diff --git a/win32.h b/win32.h
index 1b9db49..a7d025d 100644
--- a/win32.h
+++ b/win32.h
@@ -177,6 +177,8 @@ VersionInfo& GetVer ();
 #define OSMinorVersion() (GetVer ().minor ())
 #define OSBuildNumber() (GetVer ().buildNumber ())
 
+USHORT WowNativeMachine ();
+
 static inline void
 GetDlgItemRect (HWND h, int item, LPRECT r)
 {
--
2.21.0

Reply | Threaded
Open this post in threaded view
|

[PATCH setup 2/2] Rename Start Menu folder for 32-bit installs on WoW64

Jon TURNEY
In reply to this post by Jon TURNEY
This is not totally straightforward: Since setup can install Cygwin with
either bitness (using the '--arch 32|64' option), we must do the right
thing if this is a 64-bit installer being used to install 32-bit Cygwin,
which will run under WoW, even if the installer isn't...

(Naming things like this makes things consistent with Cygwin-X, which
already names it's Start Menu folder 'Cygwin-X (32-bit)' on WoW64. It
also ensures that there aren't collisions between any setup created
shortcuts for 32-bit and 64-bits.)

The desktop icon is already named 'Cygwin Terminal' or 'Cygwin64
Terminal' so doesn't need attention.

Start menu links made in the 'Cygwin' folder by cygwin-doc, and possibly
other packages will also need adjusting.
---
 desktop.cc | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/desktop.cc b/desktop.cc
index eec8ca9..29dbf63 100644
--- a/desktop.cc
+++ b/desktop.cc
@@ -95,6 +95,14 @@ make_link (const std::string& linkpath,
        icon.c_str(), fname.c_str());
 }
 
+static const char *startmenudir()
+{
+  if (!is_64bit && (WowNativeMachine() != IMAGE_FILE_MACHINE_I386))
+    return "/Cygwin (32-bit)";
+  else
+    return "/Cygwin";
+}
+
 static void
 start_menu (const std::string& title, const std::string& target,
     const std::string& arg, const std::string& iconpath)
@@ -107,7 +115,7 @@ start_menu (const std::string& title, const std::string& target,
       issystem ? CSIDL_COMMON_PROGRAMS :
       CSIDL_PROGRAMS, &id);
   SHGetPathFromIDList (id, path);
-  strncat (path, "/Cygwin", MAX_PATH - strlen(path) - 1);
+  strncat (path, startmenudir(), MAX_PATH - strlen(path) - 1);
   LogBabblePrintf ("Program directory for program link: %s", path);
   make_link (path, title, target, arg, iconpath);
 }
@@ -194,7 +202,6 @@ save_icon (std::string &iconpath, const char *resource_name)
 #define TERMINALICON "/Cygwin-Terminal.ico"
 #define TERMINALTITLE (is_64bit ? "Cygwin64 Terminal" \
   : "Cygwin Terminal")
-#define STARTMENUDIR "/Cygwin"
 
 static void
 do_desktop_setup ()
@@ -300,7 +307,7 @@ check_startmenu (const std::string title, const std::string target)
       CSIDL_PROGRAMS, &id);
   SHGetPathFromIDList (id, path);
   LogBabblePrintf ("Program directory for program link: %s", path);
-  strcat (path, STARTMENUDIR);
+  strcat (path, startmenudir());
   std::string fname = std::string(path) + "/" + title + ".lnk";
 
   if (_access (fname.c_str(), 0) == 0)
--
2.21.0