Home | History | Annotate | Download | only in win
      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