1 #!/usr/bin/env python 2 3 # Copyright 2013 Google Inc. All rights reserved. 4 # Use of this source code is governed by a BSD-style license that can be 5 # found in the LICENSE file. 6 7 """ 8 Verifies that embedding UAC information into the manifest works. 9 """ 10 11 import TestGyp 12 13 import sys 14 from xml.dom.minidom import parseString 15 16 if sys.platform == 'win32': 17 import pywintypes 18 import win32api 19 import winerror 20 21 RT_MANIFEST = 24 22 23 class LoadLibrary(object): 24 """Context manager for loading and releasing binaries in Windows. 25 Yields the handle of the binary loaded.""" 26 def __init__(self, path): 27 self._path = path 28 self._handle = None 29 30 def __enter__(self): 31 self._handle = win32api.LoadLibrary(self._path) 32 return self._handle 33 34 def __exit__(self, type, value, traceback): 35 win32api.FreeLibrary(self._handle) 36 37 38 def extract_manifest(path, resource_name): 39 """Reads manifest from |path| and returns it as a string. 40 Returns None is there is no such manifest.""" 41 with LoadLibrary(path) as handle: 42 try: 43 return win32api.LoadResource(handle, RT_MANIFEST, resource_name) 44 except pywintypes.error as error: 45 if error.args[0] == winerror.ERROR_RESOURCE_DATA_NOT_FOUND: 46 return None 47 else: 48 raise 49 50 test = TestGyp.TestGyp(formats=['msvs', 'ninja']) 51 CHDIR = 'linker-flags' 52 test.run_gyp('enable-uac.gyp', chdir=CHDIR) 53 test.build('enable-uac.gyp', test.ALL, chdir=CHDIR) 54 55 # The following binaries must contain a manifest embedded. 56 test.fail_test(not extract_manifest(test.built_file_path( 57 'enable_uac.exe', chdir=CHDIR), 1)) 58 test.fail_test(not extract_manifest(test.built_file_path( 59 'enable_uac_no.exe', chdir=CHDIR), 1)) 60 test.fail_test(not extract_manifest(test.built_file_path( 61 'enable_uac_admin.exe', chdir=CHDIR), 1)) 62 63 # Verify that <requestedExecutionLevel level="asInvoker" uiAccess="false" /> 64 # is present. 65 manifest = parseString(extract_manifest( 66 test.built_file_path('enable_uac.exe', chdir=CHDIR), 1)) 67 execution_level = manifest.getElementsByTagName('requestedExecutionLevel') 68 test.fail_test(len(execution_level) != 1) 69 execution_level = execution_level[0].attributes 70 test.fail_test(not ( 71 execution_level.has_key('level') and 72 execution_level.has_key('uiAccess') and 73 execution_level['level'].nodeValue == 'asInvoker' and 74 execution_level['uiAccess'].nodeValue == 'false')) 75 76 # Verify that <requestedExecutionLevel> is not in the menifest. 77 manifest = parseString(extract_manifest( 78 test.built_file_path('enable_uac_no.exe', chdir=CHDIR), 1)) 79 execution_level = manifest.getElementsByTagName('requestedExecutionLevel') 80 test.fail_test(len(execution_level) != 0) 81 82 # Verify that <requestedExecutionLevel level="requireAdministrator" 83 # uiAccess="true" /> is present. 84 manifest = parseString(extract_manifest( 85 test.built_file_path('enable_uac_admin.exe', chdir=CHDIR), 1)) 86 execution_level = manifest.getElementsByTagName('requestedExecutionLevel') 87 test.fail_test(len(execution_level) != 1) 88 execution_level = execution_level[0].attributes 89 test.fail_test(not ( 90 execution_level.has_key('level') and 91 execution_level.has_key('uiAccess') and 92 execution_level['level'].nodeValue == 'requireAdministrator' and 93 execution_level['uiAccess'].nodeValue == 'true')) 94 95 test.pass_test() 96