public inbox for cygwin-apps-cvs@sourceware.org
help / color / mirror / Atom feed
* [setup - the official Cygwin setup program] branch master, updated. release_2.903-5-ga7f2d458
@ 2020-03-21 17:22 Jon TURNEY
  0 siblings, 0 replies; only message in thread
From: Jon TURNEY @ 2020-03-21 17:22 UTC (permalink / raw)
  To: cygwin-apps-cvs




https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/setup.git;h=a7f2d458db2ed508959d2a425d326b0cc94806da

commit a7f2d458db2ed508959d2a425d326b0cc94806da
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date:   Wed Mar 18 22:04:47 2020 +0000

    Fix an allocation length error
    
    Allow for the terminating null.

https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/setup.git;h=2fd5251b66ff0634579c3bfd8c0d0109fc0116b7

commit 2fd5251b66ff0634579c3bfd8c0d0109fc0116b7
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date:   Tue Mar 17 15:21:50 2020 +0000

    Disable old Cygwin setup signing key by default
    
    Add a new option '--enable-old-keys', for if you really need to install
    from an old mirror for some reason.
    
    '--disable-old-keys' is still accepted, but is the default now.

https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/setup.git;h=8effde7afc285895e7a4d40a944ab2a7b9e51af1

commit 8effde7afc285895e7a4d40a944ab2a7b9e51af1
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date:   Tue Mar 17 14:27:02 2020 +0000

    Implement paired boolean options
    
    Add some infrastructure for options which may appear with multiple
    prefixes.
    
    Add an implementation of paired boolean options like '--enable-foo' and
    '--disable-foo', or '--bar' and '--no-bar'.
    
    Add/fix tests

https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/setup.git;h=9a7997b94b5e9cf382e5094f91163f76b64ccb0f

commit 9a7997b94b5e9cf382e5094f91163f76b64ccb0f
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date:   Tue Mar 17 13:54:16 2020 +0000

    Rename Start Menu folder for 32-bit installs on WoW64
    
    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.

https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/setup.git;h=e73fb694a2d21f3cf36e658d9dd066b8ceaaa330

commit e73fb694a2d21f3cf36e658d9dd066b8ceaaa330
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date:   Tue Mar 17 13:52:55 2020 +0000

    Factor out WoW detection
    
    Factor out WoW detection as a separate function


Diff:
---
 archive.cc                                       |  2 +-
 crypto.cc                                        |  7 ++--
 desktop.cc                                       | 13 ++++--
 libgetopt++/include/getopt++/BoolOption.h        | 17 ++++++--
 libgetopt++/include/getopt++/Option.h            |  6 ++-
 libgetopt++/include/getopt++/OptionSet.h         |  3 +-
 libgetopt++/include/getopt++/StringArrayOption.h |  2 +-
 libgetopt++/include/getopt++/StringOption.h      |  2 +-
 libgetopt++/src/BoolOption.cc                    | 40 ++++++++++++++++---
 libgetopt++/src/Option.cc                        |  7 ++++
 libgetopt++/src/OptionSet.cc                     | 50 +++++++++++++++---------
 libgetopt++/src/StringArrayOption.cc             |  2 +-
 libgetopt++/src/StringOption.cc                  |  2 +-
 libgetopt++/tests/BoolOptionTest.cc              | 26 +++++++++---
 libgetopt++/tests/OptionSet.cc                   |  4 +-
 nio-ie5.cc                                       | 45 ++++++++-------------
 win32.cc                                         | 26 ++++++++++++
 win32.h                                          |  2 +
 18 files changed, 177 insertions(+), 79 deletions(-)

diff --git a/archive.cc b/archive.cc
index e4af4f7b..1ceb3552 100644
--- a/archive.cc
+++ b/archive.cc
@@ -173,7 +173,7 @@ archive::extract_file (archive * source, const std::string& prefixURL,
 	  break;
 	case ARCHIVE_FILE_DIRECTORY:
 	  {
-	    char *path = (char *) alloca (destfilename.size());
+	    char *path = (char *) alloca (destfilename.size() + 1);
 	    strcpy (path, destfilename.c_str());
 	    while (path[0] && path[strlen (path) - 1] == '/')
 	      path[strlen (path) - 1] = 0;
diff --git a/crypto.cc b/crypto.cc
index 2e4ba218..88ced387 100644
--- a/crypto.cc
+++ b/crypto.cc
@@ -52,8 +52,9 @@ static BoolOption UntrustedKeysOption (false, 'u', "untrusted-keys",
 			"Use untrusted saved extra keys");
 static BoolOption KeepUntrustedKeysOption (false, 'U', "keep-untrusted-keys",
 			"Use untrusted keys and retain all");
-static BoolOption DisableOldKeysOption (false, '\0', "disable-old-keys",
-                                        "Disable old cygwin.com keys");
+static BoolOption EnableOldKeysOption (false, '\0', "old-keys",
+                                       "Enable old cygwin.com keys",
+                                       BoolOption::BoolOptionType::pairedAble);
 
 /*  Embedded public half of Cygwin signing key.  */
 static const char *cygwin_pubkey_sexpr =
@@ -708,7 +709,7 @@ verify_ini_file_sig (io_stream *ini_file, io_stream *ini_sig_file, HWND owner)
 
   /* If not disabled, also try the old built-in key */
   gcry_sexp_t cygwin_old_key;
-  if (!DisableOldKeysOption)
+  if (EnableOldKeysOption)
     {
       rv = gcry_sexp_new (&cygwin_old_key, cygwin_old_pubkey_sexpr, strlen (cygwin_old_pubkey_sexpr), 1);
       if (rv != GPG_ERR_NO_ERROR)
diff --git a/desktop.cc b/desktop.cc
index eec8ca91..29dbf635 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)
diff --git a/libgetopt++/include/getopt++/BoolOption.h b/libgetopt++/include/getopt++/BoolOption.h
index 35227cb1..8b20e1cc 100644
--- a/libgetopt++/include/getopt++/BoolOption.h
+++ b/libgetopt++/include/getopt++/BoolOption.h
@@ -23,17 +23,25 @@
 class BoolOption : public Option
 {
 public:
+  enum class BoolOptionType
+    {
+     simple,
+     pairedAble,
+     pairedNo,
+    };
+
   BoolOption(bool const defaultvalue, char shortopt, char const *longopt = 0,
-	     std::string const &shorthelp = std::string(), 
-	     OptionSet &owner=GetOption::GetInstance());
+             std::string const &shorthelp = std::string(),
+             BoolOptionType type = BoolOptionType::simple,
+             OptionSet &owner=GetOption::GetInstance());
   virtual ~ BoolOption ();
   virtual std::string const shortOption () const;
   virtual std::string const longOption () const;
+  virtual std::vector<std::string> const & longOptionPrefixes () const;
   virtual std::string const shortHelp () const;
-  virtual Result Process (char const *);
+  virtual Result Process (char const *, int);
   virtual Argument argument () const;
   operator bool () const;
- 
 
 private:
   bool _value;
@@ -41,6 +49,7 @@ private:
   char _shortopt;
   char const *_longopt;
   std::string _shorthelp;
+  BoolOptionType _type;
 };
 
 #endif // _BOOLOPTION_H_
diff --git a/libgetopt++/include/getopt++/Option.h b/libgetopt++/include/getopt++/Option.h
index a32f9495..b3b140ff 100644
--- a/libgetopt++/include/getopt++/Option.h
+++ b/libgetopt++/include/getopt++/Option.h
@@ -21,9 +21,10 @@
 #endif
 #if HAVE_STRING_H
 #include <string>
-#else 
+#else
 #error "<string> required"
 #endif
+#include <vector>
 
 // Each registered option must implement this class.
 class Option
@@ -32,13 +33,14 @@ public:
   virtual ~ Option ();
   virtual std::string const shortOption () const = 0;
   virtual std::string const longOption () const = 0;
+  virtual std::vector<std::string> const & longOptionPrefixes () const;
   virtual std::string const shortHelp () const = 0;
   enum Result {
       Failed,
       Ok,
       Stop
   };
-  virtual Result Process (char const *) = 0;
+  virtual Result Process (char const *, int) = 0;
   enum Argument {
       None,
       Optional,
diff --git a/libgetopt++/include/getopt++/OptionSet.h b/libgetopt++/include/getopt++/OptionSet.h
index 4ccaddaf..dbd8046b 100644
--- a/libgetopt++/include/getopt++/OptionSet.h
+++ b/libgetopt++/include/getopt++/OptionSet.h
@@ -44,7 +44,8 @@ private:
   bool isOption(std::string::size_type) const;
   void doOption(std::string &option, std::string::size_type const &pos);
   bool doNoArgumentOption(std::string &option, std::string::size_type const &pos);
-  Option * findOption(std::string &option, std::string::size_type const &pos) const;
+  void findOption(std::string &option, std::string::size_type const &pos,
+                  Option *&theOption, int & prefixIndex) const;
   std::vector<Option *> options;
   std::vector<std::string> argv;
   std::vector<std::string> nonoptions;
diff --git a/libgetopt++/include/getopt++/StringArrayOption.h b/libgetopt++/include/getopt++/StringArrayOption.h
index d3f87c0d..b589d283 100644
--- a/libgetopt++/include/getopt++/StringArrayOption.h
+++ b/libgetopt++/include/getopt++/StringArrayOption.h
@@ -29,7 +29,7 @@ public:
   virtual std::string const shortOption () const;
   virtual std::string const longOption () const;
   virtual std::string const shortHelp () const;
-  virtual Result Process (char const *);
+  virtual Result Process (char const *, int);
   virtual Argument argument () const;
   operator std::vector<std::string> () const;
 
diff --git a/libgetopt++/include/getopt++/StringOption.h b/libgetopt++/include/getopt++/StringOption.h
index f13be8cb..37e723a6 100644
--- a/libgetopt++/include/getopt++/StringOption.h
+++ b/libgetopt++/include/getopt++/StringOption.h
@@ -30,7 +30,7 @@ public:
   virtual std::string const shortOption () const;
   virtual std::string const longOption () const;
   virtual std::string const shortHelp () const;
-  virtual Result Process (char const *);
+  virtual Result Process (char const *, int);
   virtual Argument argument () const;
   operator const std::string& () const;
 
diff --git a/libgetopt++/src/BoolOption.cc b/libgetopt++/src/BoolOption.cc
index 4b265539..37d9a229 100644
--- a/libgetopt++/src/BoolOption.cc
+++ b/libgetopt++/src/BoolOption.cc
@@ -16,10 +16,10 @@
 #include <getopt++/BoolOption.h>
 
 BoolOption::BoolOption(bool const defaultvalue, char shortopt,
-		       char const *longopt, std::string const &shorthelp,
-		       OptionSet &owner) : _value (defaultvalue) ,
-		       _ovalue (defaultvalue), _shortopt(shortopt),
-		       _longopt (longopt), _shorthelp (shorthelp)
+                       char const *longopt, std::string const &shorthelp,
+                       BoolOptionType type, OptionSet &owner) :
+  _value (defaultvalue), _ovalue (defaultvalue), _shortopt(shortopt),
+  _longopt (longopt), _shorthelp (shorthelp), _type(type)
 {
   owner.Register (this);
 };
@@ -38,6 +38,24 @@ BoolOption::longOption () const
   return _longopt;
 }
 
+std::vector<std::string> const &
+BoolOption::longOptionPrefixes () const
+{
+  switch (_type)
+    {
+    default:
+    case BoolOption::BoolOptionType::simple:
+      static std::vector<std::string> simple = {""};
+      return simple;
+    case BoolOption::BoolOptionType::pairedAble:
+      static std::vector<std::string> able = {"enable-", "disable-"};
+      return able;
+    case BoolOption::BoolOptionType::pairedNo:
+      static std::vector<std::string> no = {"", "no-"};
+      return no;
+    }
+}
+
 std::string const
 BoolOption::shortHelp () const
 {
@@ -45,9 +63,19 @@ BoolOption::shortHelp () const
 }
 
 Option::Result
-BoolOption::Process (char const *)
+BoolOption::Process (char const *, int prefixIndex)
 {
-  _value = !_ovalue;
+  switch (_type)
+    {
+    default:
+    case BoolOption::BoolOptionType::simple:
+      _value = !_ovalue;
+    case BoolOption::BoolOptionType::pairedAble:
+      _value = (prefixIndex == 0);
+    case BoolOption::BoolOptionType::pairedNo:
+      _value = (prefixIndex == 0);
+    }
+
   return Ok;
 }
 
diff --git a/libgetopt++/src/Option.cc b/libgetopt++/src/Option.cc
index 7c61ebad..2e6e9d8f 100644
--- a/libgetopt++/src/Option.cc
+++ b/libgetopt++/src/Option.cc
@@ -22,3 +22,10 @@ Option::Option () : present(false)
 Option::~Option ()
 {
 }
+
+std::vector<std::string> const &
+Option::longOptionPrefixes () const
+{
+  static std::vector<std::string> noprefix = {""};
+  return noprefix;
+}
diff --git a/libgetopt++/src/OptionSet.cc b/libgetopt++/src/OptionSet.cc
index a8f02e82..5a8ddee4 100644
--- a/libgetopt++/src/OptionSet.cc
+++ b/libgetopt++/src/OptionSet.cc
@@ -38,37 +38,47 @@ OptionSet::processOne()
 
     if (!isOption(pos)) {
         /* Push the non option into storage */
-	if (nonOptionHandler) {
-	    lastResult = nonOptionHandler->Process(option.c_str());
-	} else {
-	    nonoptions.push_back(option);
-	    lastResult = Option::Ok;
-	}
+      if (nonOptionHandler) {
+        lastResult = nonOptionHandler->Process(option.c_str(), 0);
+      } else {
+        nonoptions.push_back(option);
+        lastResult = Option::Ok;
+      }
     } else {
-	doOption(option, pos);
+      doOption(option, pos);
     }
 }
 
-Option *
-OptionSet::findOption(std::string &option, std::string::size_type const &pos) const
+void
+OptionSet::findOption(std::string &option, std::string::size_type const &pos,
+                      Option *&theOption, int & prefixIndex) const
 {
-    Option *theOption = NULL;
+    theOption = NULL;
+    prefixIndex = 0;
 
     for (std::vector<Option *>::const_iterator i = options.begin(); i != options.end(); 
             ++i) {
         if (pos == 1) {
             if (option[0] == (*i)->shortOption()[0]) {
                 theOption = (*i);
+                return;
             }
         } else {
-            /* pos == 2 : todo - prefix matches */
-
-            if (option.find((*i)->longOption()) == 0) {
+          /* pos == 2 */
+          std::vector<std::string> prefixes = (*i)->longOptionPrefixes();
+          for (std::vector<std::string>::const_iterator j = prefixes.begin();
+               j != prefixes.end();
+               j++)
+            {
+              std::string prefixedOption = *j + (*i)->longOption();
+              if (option.find(prefixedOption) == 0) {
                 theOption = (*i);
+                prefixIndex = j - prefixes.begin();
+                return;
+              }
             }
         }
     }
-    return theOption;
 }
 
 bool
@@ -98,7 +108,9 @@ OptionSet::doOption(std::string &option, std::string::size_type const &pos)
 {
     lastResult = Option::Failed;
     option.erase(0, pos);
-    Option *theOption = findOption(option, pos);
+    Option *theOption = NULL;
+    int prefixIndex = 0;
+    findOption(option, pos, theOption, prefixIndex);
     char const *optionValue = NULL;
     std::string value;
 
@@ -108,9 +120,9 @@ OptionSet::doOption(std::string &option, std::string::size_type const &pos)
     switch (theOption->argument()) {
 
     case Option::None:
-        if (!doNoArgumentOption (option, pos))
-	    return;
-	break;
+      if (!doNoArgumentOption (option, pos))
+        return;
+      break;
 
     case Option::Optional: {
             if (pos == 1) {
@@ -231,7 +243,7 @@ OptionSet::doOption(std::string &option, std::string::size_type const &pos)
 	break;
     }
     theOption->setPresent(true);
-    lastResult = theOption->Process(optionValue);
+    lastResult = theOption->Process(optionValue, prefixIndex);
 }
 
 OptionSet::OptionSet () {}
diff --git a/libgetopt++/src/StringArrayOption.cc b/libgetopt++/src/StringArrayOption.cc
index 7cbee201..fe6f6131 100644
--- a/libgetopt++/src/StringArrayOption.cc
+++ b/libgetopt++/src/StringArrayOption.cc
@@ -44,7 +44,7 @@ StringArrayOption::shortHelp () const
 }
 
 Option::Result
-StringArrayOption::Process (char const *optarg)
+StringArrayOption::Process (char const *optarg, int prefixIndex)
 {
   if (optarg)
     {
diff --git a/libgetopt++/src/StringOption.cc b/libgetopt++/src/StringOption.cc
index d3592366..e3c4af64 100644
--- a/libgetopt++/src/StringOption.cc
+++ b/libgetopt++/src/StringOption.cc
@@ -49,7 +49,7 @@ StringOption::shortHelp () const
 }
 
 Option::Result
-StringOption::Process (char const *optarg)
+StringOption::Process (char const *optarg, int prefixIndex)
 {
   if (optarg)
     _value = optarg;
diff --git a/libgetopt++/tests/BoolOptionTest.cc b/libgetopt++/tests/BoolOptionTest.cc
index d2c51909..7fdd2591 100644
--- a/libgetopt++/tests/BoolOptionTest.cc
+++ b/libgetopt++/tests/BoolOptionTest.cc
@@ -20,16 +20,18 @@
 #include <iostream>
 #include <string.h>
 
-static BoolOption testoption (false, 't', "testoption", "Tests the use of boolean options");
 int
 main (int anargc, char **anargv)
 {
+  BoolOption helpoption (false, 'h', "help", "Tests the use of help output.");
+  BoolOption helpoption2 (false, 'o', "help2", "Tests the use of help output.");
+  BoolOption ableoption (false, '\0', "foo", "Tests the use of paired option.", BoolOption::BoolOptionType::pairedAble);
+
   int argc=2;
   char *argv[4];
   argv[0] = strdup("BoolOptionTest");
   argv[1] = strdup("-h");
     {
-      BoolOption helpoption (false, 'h', "help", "Tests the use of help output.");
       if (!GetOption::GetInstance().Process (argc, argv, NULL))
 	{
 	  std::cout << "Failed to process options" << std::endl;
@@ -44,17 +46,31 @@ main (int anargc, char **anargv)
       argc = 0;
     }
     {
-      BoolOption helpoption (false, 'h', "help", "Tests the use of help output.");
       if (!GetOption::GetInstance().Process (argc, argv, NULL))
 	{
 	  std::cout << "Failed to process options (2) " << std::endl;
 	  return 1;
 	}
-      if (helpoption)
+      if (helpoption2)
 	{
-	  std::cout << "Recieved unexpected  help option" << std::endl;
+	  std::cout << "Received unexpected help option" << std::endl;
 	  return 1;
 	}
     }
+  argc=2;
+  argv[0] = strdup("BoolOptionTest");
+  argv[1] = strdup("--enable-foo");
+    {
+      if (!GetOption::GetInstance().Process (argc, argv, NULL))
+        {
+          std::cout << "Failed to process options (3) " << std::endl;
+          return 1;
+        }
+      if (!ableoption)
+        {
+          std::cout << "Did not receive expected enable-foo option" << std::endl;
+          return 1;
+        }
+    }
   return 0;
 }
diff --git a/libgetopt++/tests/OptionSet.cc b/libgetopt++/tests/OptionSet.cc
index ff63e390..4eac880c 100644
--- a/libgetopt++/tests/OptionSet.cc
+++ b/libgetopt++/tests/OptionSet.cc
@@ -36,7 +36,7 @@ class StringCollector : public Option
        {
 	 return "";
        }
-     virtual Option::Result Process(const char * value);
+     virtual Option::Result Process(const char * value, int index);
      virtual Option::Argument argument() const
        {
 	 return Required;
@@ -46,7 +46,7 @@ class StringCollector : public Option
 };
 
 Option::Result
-StringCollector::Process(const char * value)
+StringCollector::Process(const char * value, int index)
 {
     values.push_back(value);
     if (values.size() == 1)
diff --git a/nio-ie5.cc b/nio-ie5.cc
index f5ad020c..fe61b778 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 6a551bac..45c7bf1b 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 1b9db490..a7d025d2 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)
 {



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-03-21 17:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-21 17:22 [setup - the official Cygwin setup program] branch master, updated. release_2.903-5-ga7f2d458 Jon TURNEY

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).