#2581: Vista UAC/elevation support for bdist_wininst
diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py
index 02542af..7c43e74 100644
--- a/Lib/distutils/command/bdist_wininst.py
+++ b/Lib/distutils/command/bdist_wininst.py
@@ -50,6 +50,10 @@
                      "Fully qualified filename of a script to be run before "
                      "any files are installed.  This script need not be in the "
                      "distribution"),
+                    ('user-access-control=', None,
+                     "specify Vista's UAC handling - 'none'/default=no "
+                     "handling, 'auto'=use UAC if target Python installed for "
+                     "all users, 'force'=always use UAC"),
                    ]
 
     boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
@@ -68,6 +72,7 @@
         self.skip_build = 0
         self.install_script = None
         self.pre_install_script = None
+        self.user_access_control = None
 
     # initialize_options()
 
@@ -220,6 +225,8 @@
         lines.append("target_optimize=%d" % (not self.no_target_optimize))
         if self.target_version:
             lines.append("target_version=%s" % self.target_version)
+        if self.user_access_control:
+            lines.append("user_access_control=%s" % self.user_access_control)
 
         title = self.title or self.distribution.get_fullname()
         lines.append("title=%s" % escape(title))
diff --git a/Lib/distutils/command/wininst-6.0.exe b/Lib/distutils/command/wininst-6.0.exe
index bd71525..10c9819 100644
--- a/Lib/distutils/command/wininst-6.0.exe
+++ b/Lib/distutils/command/wininst-6.0.exe
Binary files differ
diff --git a/Lib/distutils/command/wininst-7.1.exe b/Lib/distutils/command/wininst-7.1.exe
index ee35713..6779aa8 100644
--- a/Lib/distutils/command/wininst-7.1.exe
+++ b/Lib/distutils/command/wininst-7.1.exe
Binary files differ
diff --git a/Lib/distutils/command/wininst-9.0-amd64.exe b/Lib/distutils/command/wininst-9.0-amd64.exe
index c99ede4..b4cb062 100644
--- a/Lib/distutils/command/wininst-9.0-amd64.exe
+++ b/Lib/distutils/command/wininst-9.0-amd64.exe
Binary files differ
diff --git a/Lib/distutils/command/wininst-9.0.exe b/Lib/distutils/command/wininst-9.0.exe
index 5e0144c..0d04a66 100644
--- a/Lib/distutils/command/wininst-9.0.exe
+++ b/Lib/distutils/command/wininst-9.0.exe
Binary files differ
diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py
index 8b1cf9a..c8d52c4 100644
--- a/Lib/distutils/msvc9compiler.py
+++ b/Lib/distutils/msvc9compiler.py
@@ -594,14 +594,25 @@
             # needed! Make sure they are generated in the temporary build
             # directory. Since they have different names for debug and release
             # builds, they can go into the same directory.
+            build_temp = os.path.dirname(objects[0])
             if export_symbols is not None:
                 (dll_name, dll_ext) = os.path.splitext(
                     os.path.basename(output_filename))
                 implib_file = os.path.join(
-                    os.path.dirname(objects[0]),
+                    build_temp,
                     self.library_filename(dll_name))
                 ld_args.append ('/IMPLIB:' + implib_file)
 
+            # Embedded manifests are recommended - see MSDN article titled
+            # "How to: Embed a Manifest Inside a C/C++ Application"
+            # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx)
+            # Ask the linker to generate the manifest in the temp dir, so
+            # we can embed it later.
+            temp_manifest = os.path.join(
+                    build_temp,
+                    os.path.basename(output_filename) + ".manifest")
+            ld_args.append('/MANIFESTFILE:' + temp_manifest)
+
             if extra_preargs:
                 ld_args[:0] = extra_preargs
             if extra_postargs:
@@ -613,6 +624,18 @@
             except DistutilsExecError as msg:
                 raise LinkError(msg)
 
+            # embed the manifest
+            # XXX - this is somewhat fragile - if mt.exe fails, distutils
+            # will still consider the DLL up-to-date, but it will not have a
+            # manifest.  Maybe we should link to a temp file?  OTOH, that
+            # implies a build environment error that shouldn't go undetected.
+            mfid = 1 if target_desc == CCompiler.EXECUTABLE else 2
+            out_arg = '-outputresource:%s;%s' % (output_filename, mfid)
+            try:
+                self.spawn(['mt.exe', '-nologo', '-manifest',
+                            temp_manifest, out_arg])
+            except DistutilsExecError as msg:
+                raise LinkError(msg)
         else:
             log.debug("skipping %s (up-to-date)", output_filename)