diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@78cadc50-ecff-11dd-a971-7dbc132099af> | 2013-07-15 17:55:47 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@78cadc50-ecff-11dd-a971-7dbc132099af> | 2013-07-15 17:55:47 +0000 |
commit | 32ece93b4a75830df422f67434d8804127db1b8b (patch) | |
tree | 035ef999160dbd1bc23933e3d2b2c917648b92c5 | |
parent | b8c2ab69b417009ab5d2a4228368563b33c19d37 (diff) | |
download | gyp-32ece93b4a75830df422f67434d8804127db1b8b.tar.gz |
Added support of 'EnableUAC', 'UACExecutionLevel' and 'UACUIAccess' linker options.
R=scottmg@chromium.org
Review URL: https://codereview.chromium.org/18810003
git-svn-id: http://gyp.googlecode.com/svn/trunk@1673 78cadc50-ecff-11dd-a971-7dbc132099af
-rw-r--r-- | pylib/gyp/msvs_emulation.py | 27 | ||||
-rw-r--r-- | test/win/gyptest-link-enable-uac.py | 95 | ||||
-rw-r--r-- | test/win/linker-flags/enable-uac.gyp | 45 |
3 files changed, 161 insertions, 6 deletions
diff --git a/pylib/gyp/msvs_emulation.py b/pylib/gyp/msvs_emulation.py index 6f78d096..342ee36e 100644 --- a/pylib/gyp/msvs_emulation.py +++ b/pylib/gyp/msvs_emulation.py @@ -487,17 +487,32 @@ class MsvsSettings(object): def _GetLdManifestFlags(self, config, name, allow_isolation): """Returns the set of flags that need to be added to the link to generate a default manifest, as well as the name of the generated file.""" - # Add manifest flags that mirror the defaults in VS. Chromium dev builds - # do not currently use any non-default settings, but we could parse - # VCManifestTool blocks if Chromium or other projects need them in the - # future. Of particular note, we do not yet support EmbedManifest because - # it complicates incremental linking. + # The manifest is generated by default. output_name = name + '.intermediate.manifest' flags = [ '/MANIFEST', '/ManifestFile:' + output_name, - '''/MANIFESTUAC:"level='asInvoker' uiAccess='false'"''' ] + + config = self._TargetConfig(config) + enable_uac = self._Setting(('VCLinkerTool', 'EnableUAC'), config, + default='true') + if enable_uac == 'true': + execution_level = self._Setting(('VCLinkerTool', 'UACExecutionLevel'), + config, default='0') + execution_level_map = { + '0': 'asInvoker', + '1': 'highestAvailable', + '2': 'requireAdministrator' + } + + ui_access = self._Setting(('VCLinkerTool', 'UACUIAccess'), config, + default='false') + flags.append('''/MANIFESTUAC:"level='%s' uiAccess='%s'"''' % + (execution_level_map[execution_level], ui_access)) + else: + flags.append('/MANIFESTUAC:NO') + if allow_isolation: flags.append('/ALLOWISOLATION') return flags, output_name diff --git a/test/win/gyptest-link-enable-uac.py b/test/win/gyptest-link-enable-uac.py new file mode 100644 index 00000000..131e07ec --- /dev/null +++ b/test/win/gyptest-link-enable-uac.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +# Copyright 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +Verifies that embedding UAC information into the manifest works. +""" + +import TestGyp + +import sys +from xml.dom.minidom import parseString + +if sys.platform == 'win32': + import pywintypes + import win32api + import winerror + + RT_MANIFEST = 24 + + class LoadLibrary(object): + """Context manager for loading and releasing binaries in Windows. + Yields the handle of the binary loaded.""" + def __init__(self, path): + self._path = path + self._handle = None + + def __enter__(self): + self._handle = win32api.LoadLibrary(self._path) + return self._handle + + def __exit__(self, type, value, traceback): + win32api.FreeLibrary(self._handle) + + + def extract_manifest(path, resource_name): + """Reads manifest from |path| and returns it as a string. + Returns None is there is no such manifest.""" + with LoadLibrary(path) as handle: + try: + return win32api.LoadResource(handle, RT_MANIFEST, resource_name) + except pywintypes.error as error: + if error.args[0] == winerror.ERROR_RESOURCE_DATA_NOT_FOUND: + return None + else: + raise + + test = TestGyp.TestGyp(formats=['msvs', 'ninja']) + CHDIR = 'linker-flags' + test.run_gyp('enable-uac.gyp', chdir=CHDIR) + test.build('enable-uac.gyp', test.ALL, chdir=CHDIR) + + # The following binaries must contain a manifest embedded. + test.fail_test(not extract_manifest(test.built_file_path( + 'enable_uac.exe', chdir=CHDIR), 1)) + test.fail_test(not extract_manifest(test.built_file_path( + 'enable_uac_no.exe', chdir=CHDIR), 1)) + test.fail_test(not extract_manifest(test.built_file_path( + 'enable_uac_admin.exe', chdir=CHDIR), 1)) + + # Verify that <requestedExecutionLevel level="asInvoker" uiAccess="false" /> + # is present. + manifest = parseString(extract_manifest( + test.built_file_path('enable_uac.exe', chdir=CHDIR), 1)) + execution_level = manifest.getElementsByTagName('requestedExecutionLevel') + test.fail_test(len(execution_level) != 1) + execution_level = execution_level[0].attributes + test.fail_test(not ( + execution_level.has_key('level') and + execution_level.has_key('uiAccess') and + execution_level['level'].nodeValue == 'asInvoker' and + execution_level['uiAccess'].nodeValue == 'false')) + + # Verify that <requestedExecutionLevel> is not in the menifest. + manifest = parseString(extract_manifest( + test.built_file_path('enable_uac_no.exe', chdir=CHDIR), 1)) + execution_level = manifest.getElementsByTagName('requestedExecutionLevel') + test.fail_test(len(execution_level) != 0) + + # Verify that <requestedExecutionLevel level="requireAdministrator" + # uiAccess="true" /> is present. + manifest = parseString(extract_manifest( + test.built_file_path('enable_uac_admin.exe', chdir=CHDIR), 1)) + execution_level = manifest.getElementsByTagName('requestedExecutionLevel') + test.fail_test(len(execution_level) != 1) + execution_level = execution_level[0].attributes + test.fail_test(not ( + execution_level.has_key('level') and + execution_level.has_key('uiAccess') and + execution_level['level'].nodeValue == 'requireAdministrator' and + execution_level['uiAccess'].nodeValue == 'true')) + + test.pass_test() diff --git a/test/win/linker-flags/enable-uac.gyp b/test/win/linker-flags/enable-uac.gyp new file mode 100644 index 00000000..08243efe --- /dev/null +++ b/test/win/linker-flags/enable-uac.gyp @@ -0,0 +1,45 @@ +# Copyright (c) 2013 Yandex LLC. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'targets': [ + { + 'target_name': 'enable_uac', + 'type': 'executable', + 'sources': ['hello.cc'], + 'msvs_settings': { + 'VCManifestTool': { + 'EmbedManifest': 'true', + } + }, + }, + { + 'target_name': 'enable_uac_no', + 'type': 'executable', + 'sources': ['hello.cc'], + 'msvs_settings': { + 'VCLinkerTool': { + 'EnableUAC': 'false', + }, + 'VCManifestTool': { + 'EmbedManifest': 'true', + } + }, + }, + { + 'target_name': 'enable_uac_admin', + 'type': 'executable', + 'sources': ['hello.cc'], + 'msvs_settings': { + 'VCLinkerTool': { + 'UACExecutionLevel': 2, + 'UACUIAccess': 'true', + }, + 'VCManifestTool': { + 'EmbedManifest': 'true', + } + }, + }, + ] +} |