1 #!/usr/bin/env python 2 3 # Copyright (c) 2013 Yandex LLC. 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 Make sure manifests are embedded in binaries properly. Handling of 9 AdditionalManifestFiles is tested too. 10 """ 11 12 import TestGyp 13 14 import sys 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('embed-manifest.gyp', chdir=CHDIR) 53 test.build('embed-manifest.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 'test_manifest_exe.exe', chdir=CHDIR), 1)) 58 test.fail_test(not extract_manifest(test.built_file_path( 59 'test_manifest_exe_inc.exe', chdir=CHDIR), 1)) 60 test.fail_test(not extract_manifest(test.built_file_path( 61 'test_manifest_dll.dll', chdir=CHDIR), 2)) 62 test.fail_test(not extract_manifest(test.built_file_path( 63 'test_manifest_dll_inc.dll', chdir=CHDIR), 2)) 64 65 # Must contain the Win7 support GUID, but not the Vista one (from 66 # extra2.manifest). 67 test.fail_test( 68 '35138b9a-5d96-4fbd-8e2d-a2440225f93a' not in 69 extract_manifest(test.built_file_path('test_manifest_extra1.exe', 70 chdir=CHDIR), 1)) 71 test.fail_test( 72 'e2011457-1546-43c5-a5fe-008deee3d3f0' in 73 extract_manifest(test.built_file_path('test_manifest_extra1.exe', 74 chdir=CHDIR), 1)) 75 # Must contain both. 76 test.fail_test( 77 '35138b9a-5d96-4fbd-8e2d-a2440225f93a' not in 78 extract_manifest(test.built_file_path('test_manifest_extra2.exe', 79 chdir=CHDIR), 1)) 80 test.fail_test( 81 'e2011457-1546-43c5-a5fe-008deee3d3f0' not in 82 extract_manifest(test.built_file_path('test_manifest_extra2.exe', 83 chdir=CHDIR), 1)) 84 85 # Same as extra2, but using list syntax instead. 86 test.fail_test( 87 '35138b9a-5d96-4fbd-8e2d-a2440225f93a' not in 88 extract_manifest(test.built_file_path('test_manifest_extra_list.exe', 89 chdir=CHDIR), 1)) 90 test.fail_test( 91 'e2011457-1546-43c5-a5fe-008deee3d3f0' not in 92 extract_manifest(test.built_file_path('test_manifest_extra_list.exe', 93 chdir=CHDIR), 1)) 94 95 # Test that incremental linking doesn't force manifest embedding. 96 test.fail_test(extract_manifest(test.built_file_path( 97 'test_manifest_exe_inc_no_embed.exe', chdir=CHDIR), 1)) 98 99 test.pass_test() 100