diff options
author | caitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-13 10:01:01 +0000 |
---|---|---|
committer | caitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-13 10:01:01 +0000 |
commit | 91f0755c0f15ae1f49dc2d38309f9c5882945a18 (patch) | |
tree | 7072b3d791f6f811300eafac5b55b71d87340085 | |
parent | a644bc199536de369b6a9feb66dba1b4f2b69e0a (diff) | |
download | chromium_src-91f0755c0f15ae1f49dc2d38309f9c5882945a18.zip chromium_src-91f0755c0f15ae1f49dc2d38309f9c5882945a18.tar.gz chromium_src-91f0755c0f15ae1f49dc2d38309f9c5882945a18.tar.bz2 |
Chrome Early Loading Framework
chrome_elf.dll is shipped in Chrome's version directory to
ease updates, and is loaded early in chrome.exe's lifetime
by making it a private assembly in a subfolder of
chrome.exe's folder (see
http://msdn.microsoft.com/library/aa374224.aspx).
BUG= http://crosbug.com/p/23889
Review URL: https://codereview.chromium.org/53793002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234795 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/DEPS | 1 | ||||
-rw-r--r-- | chrome/app/chrome_exe_main_win.cc | 5 | ||||
-rw-r--r-- | chrome/chrome_exe.gypi | 14 | ||||
-rw-r--r-- | chrome/installer/mini_installer/chrome.release | 8 | ||||
-rw-r--r-- | chrome/test/mini_installer/config/chrome_system_installed.prop | 4 | ||||
-rw-r--r-- | chrome/test/mini_installer/config/chrome_user_installed.prop | 4 | ||||
-rw-r--r-- | chrome_elf/DEPS | 2 | ||||
-rw-r--r-- | chrome_elf/OWNERS | 3 | ||||
-rw-r--r-- | chrome_elf/README | 15 | ||||
-rw-r--r-- | chrome_elf/chrome_elf.def | 4 | ||||
-rw-r--r-- | chrome_elf/chrome_elf.gyp | 26 | ||||
-rw-r--r-- | chrome_elf/chrome_elf_main.cc | 16 | ||||
-rw-r--r-- | chrome_elf/chrome_elf_main.h | 10 | ||||
-rw-r--r-- | chrome_elf/chrome_exe_manifest.template | 10 | ||||
-rw-r--r-- | chrome_elf/chrome_exe_manifest_action.gypi | 34 | ||||
-rw-r--r-- | chrome_elf/version_assembly_manifest.template | 8 | ||||
-rw-r--r-- | chrome_elf/version_assembly_manifest_action.gypi | 37 |
17 files changed, 201 insertions, 0 deletions
diff --git a/chrome/app/DEPS b/chrome/app/DEPS index 4d39b78..c58a555 100644 --- a/chrome/app/DEPS +++ b/chrome/app/DEPS @@ -6,6 +6,7 @@ include_rules = [ "+chrome/plugin/chrome_content_plugin_client.h", "+chrome/renderer/chrome_content_renderer_client.h", "+chrome/utility/chrome_content_utility_client.h", + "+chrome_elf/chrome_elf_main.h", "+chromeos/chromeos_paths.h", "+chromeos/chromeos_switches.h", "+components/breakpad", diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc index 5c1d0d88b..0a22aad 100644 --- a/chrome/app/chrome_exe_main_win.cc +++ b/chrome/app/chrome_exe_main_win.cc @@ -19,6 +19,7 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_switches.h" +#include "chrome_elf/chrome_elf_main.h" #include "components/breakpad/app/breakpad_client.h" #include "components/breakpad/app/breakpad_win.h" #include "content/public/app/startup_helper_win.h" @@ -119,6 +120,10 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) { if (AttemptFastNotify(*CommandLine::ForCurrentProcess())) return 0; + // The purpose of this call is to force the addition of an entry in the IAT + // for chrome_elf.dll to force a load time dependency. + InitChromeElf(); + MetroDriver metro_driver; if (metro_driver.in_metro_mode()) return metro_driver.RunInMetro(instance, &RunChrome); diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index 0f95552..1f5db5b 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi @@ -470,6 +470,7 @@ '../base/base.gyp:base', '../breakpad/breakpad.gyp:breakpad_handler', '../breakpad/breakpad.gyp:breakpad_sender', + '../chrome_elf/chrome_elf.gyp:chrome_elf', '../components/components.gyp:breakpad_component', '../sandbox/sandbox.gyp:sandbox', 'app/policy/cloud_policy_codegen.gyp:policy', @@ -498,6 +499,7 @@ 'VCManifestTool': { 'AdditionalManifestFiles': [ '$(ProjectDir)\\app\\chrome.exe.manifest', + '<(SHARED_INTERMEDIATE_DIR)/chrome_elf/version_assembly.manifest', ], }, }, @@ -514,6 +516,18 @@ 'message': 'Copy first run complete sentinel file', 'msvs_cygwin_shell': 1, }, + { + 'action_name': 'chrome_exe_manifest', + 'includes': [ + '../chrome_elf/chrome_exe_manifest_action.gypi', + ], + }, + { + 'action_name': 'version_assembly_manifest', + 'includes': [ + '../chrome_elf/version_assembly_manifest_action.gypi', + ], + }, ], }, { # 'OS!="win" 'sources!': [ diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release index 2a6ce2a..105ab0a 100644 --- a/chrome/installer/mini_installer/chrome.release +++ b/chrome/installer/mini_installer/chrome.release @@ -9,10 +9,18 @@ chrome.exe: %(ChromeDir)s\ wow_helper.exe: %(ChromeDir)s\ # +# Chrome version dir aseembly manifest. +# The name of this file must match the name of the version dir, so we cannot +# hard-code it. +# // TODO(caitkp): Find a way to do this without wildcards. +# +*.*.*.*.manifest: %(VersionDir)s\ +# # Chrome version dir entries, sorted alphabetically. # chrome.dll: %(VersionDir)s\ chrome_100_percent.pak: %(VersionDir)s\ +chrome_elf.dll: %(VersionDir)s\ chrome_child.dll: %(VersionDir)s\ chrome_frame_helper.dll: %(VersionDir)s\ chrome_frame_helper.exe: %(VersionDir)s\ diff --git a/chrome/test/mini_installer/config/chrome_system_installed.prop b/chrome/test/mini_installer/config/chrome_system_installed.prop index a1bd479..ed6876d 100644 --- a/chrome/test/mini_installer/config/chrome_system_installed.prop +++ b/chrome/test/mini_installer/config/chrome_system_installed.prop @@ -3,9 +3,13 @@ "$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe": {"exists": true}, "$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\chrome.dll": {"exists": true}, + "$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\chrome_elf.dll": + {"exists": true}, "$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\Installer\\chrome.7z": {"exists": true}, "$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\Installer\\setup.exe": + {"exists": true}, + "$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\$MINI_INSTALLER_FILE_VERSION.manifest": {"exists": true} }, "RegistryEntries": { diff --git a/chrome/test/mini_installer/config/chrome_user_installed.prop b/chrome/test/mini_installer/config/chrome_user_installed.prop index 993ddc4..78944b8 100644 --- a/chrome/test/mini_installer/config/chrome_user_installed.prop +++ b/chrome/test/mini_installer/config/chrome_user_installed.prop @@ -3,9 +3,13 @@ "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe": {"exists": true}, "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\chrome.dll": {"exists": true}, + "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\chrome_elf.dll": + {"exists": true}, "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\Installer\\chrome.7z": {"exists": true}, "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\Installer\\setup.exe": + {"exists": true}, + "$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\$MINI_INSTALLER_FILE_VERSION.manifest": {"exists": true} }, "RegistryEntries": { diff --git a/chrome_elf/DEPS b/chrome_elf/DEPS new file mode 100644 index 0000000..48e8875 --- /dev/null +++ b/chrome_elf/DEPS @@ -0,0 +1,2 @@ +include_rules = [ +] diff --git a/chrome_elf/OWNERS b/chrome_elf/OWNERS new file mode 100644 index 0000000..d2e52d6 --- /dev/null +++ b/chrome_elf/OWNERS @@ -0,0 +1,3 @@ + caitkp@chromium.org + gab@chromium.org + robertshield@chromium.org
\ No newline at end of file diff --git a/chrome_elf/README b/chrome_elf/README new file mode 100644 index 0000000..b657437 --- /dev/null +++ b/chrome_elf/README @@ -0,0 +1,15 @@ +Chrome Early Loading Framework (aka ChromeELF) + +chrome_elf.dll is shipped in Chrome's version directory to ease updates, +and is loaded early in chrome.exe's lifetime. This is done by turning the +version directory into a private assembly which refers to chrome_elf.dll +(http://msdn.microsoft.com/library/aa374224.aspx). + +In an ideal world, this would be done by embedding an application config in +chrome.exe that would refer to the proper version directory via a +probing\privatePath attribute (http://msdn.microsoft.com/library/aa374182.aspx). +This would allow us to refer to dlls in the version directory without having to +make the version directory itself into an assembly. It would also avoid naming +conflicts (as the WinSxS dir and GAC both take precedence over private +assemblies when searching for dlls). Unfortunately, the probing\privatePath +attribute is only supported for Windows 7 and later. diff --git a/chrome_elf/chrome_elf.def b/chrome_elf/chrome_elf.def new file mode 100644 index 0000000..1703016 --- /dev/null +++ b/chrome_elf/chrome_elf.def @@ -0,0 +1,4 @@ +LIBRARY "chrome_elf.dll" + +EXPORTS + InitChromeElf diff --git a/chrome_elf/chrome_elf.gyp b/chrome_elf/chrome_elf.gyp new file mode 100644 index 0000000..c32f710 --- /dev/null +++ b/chrome_elf/chrome_elf.gyp @@ -0,0 +1,26 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'variables': { + 'chromium_code': 1, + }, + 'includes': [ + '../build/win_precompile.gypi', + '../chrome/version.gypi', + ], + 'targets': [ + { + 'target_name': 'chrome_elf', + 'type': 'shared_library', + 'include_dirs': [ + '..', + ], + 'sources': [ + 'chrome_elf.def', + 'chrome_elf_main.cc', + 'chrome_elf_main.h', + ], + }, + ], +}
\ No newline at end of file diff --git a/chrome_elf/chrome_elf_main.cc b/chrome_elf/chrome_elf_main.cc new file mode 100644 index 0000000..c6715ba --- /dev/null +++ b/chrome_elf/chrome_elf_main.cc @@ -0,0 +1,16 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <windows.h> + +#include "chrome_elf/chrome_elf_main.h" + +void InitChromeElf() { + // This method is a no-op which may be called to force a load-time dependency + // on chrome_elf.dll. +} + +BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) { + return TRUE; +} diff --git a/chrome_elf/chrome_elf_main.h b/chrome_elf/chrome_elf_main.h new file mode 100644 index 0000000..7d02ddd --- /dev/null +++ b/chrome_elf/chrome_elf_main.h @@ -0,0 +1,10 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_ELF_CHROME_ELF_MAIN_H_ +#define CHROME_ELF_CHROME_ELF_MAIN_H_ + +extern "C" void InitChromeElf(); + +#endif // CHROME_ELF_CHROME_ELF_MAIN_H_ diff --git a/chrome_elf/chrome_exe_manifest.template b/chrome_elf/chrome_exe_manifest.template new file mode 100644 index 0000000..7c66328 --- /dev/null +++ b/chrome_elf/chrome_exe_manifest.template @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <dependency> + <dependentAssembly> + <assemblyIdentity type='win32' + name='@MAJOR@.@MINOR@.@BUILD@.@PATCH@' + version='@MAJOR@.@MINOR@.@BUILD@.@PATCH@' language='*'/> + </dependentAssembly> + </dependency> +</assembly>
\ No newline at end of file diff --git a/chrome_elf/chrome_exe_manifest_action.gypi b/chrome_elf/chrome_exe_manifest_action.gypi new file mode 100644 index 0000000..89453db --- /dev/null +++ b/chrome_elf/chrome_exe_manifest_action.gypi @@ -0,0 +1,34 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file contains an action which can be used to construct a manifest file +# declaring a dependency on chrome_elf.dll. This manifest can then be merged +# into the manifest of the executable and embedded into it when it is built. + +# To use this the following variables need to be defined: +# version_path: string: path to file containing version data (e.g. +# chrome/VERSION). +# version_py_path: string: path to file containing version script (e.g. +# chrome/tools/build/version.py). + +{ + 'variables': { + 'template_input_path': + '<(DEPTH)/chrome_elf/chrome_exe_manifest.template', + }, + 'inputs': [ + '<(template_input_path)', + '<(version_path)', + ], + 'outputs': [ + '<(SHARED_INTERMEDIATE_DIR)/chrome_elf/version_assembly.manifest', + ], + 'action': [ + 'python', '<(version_py_path)', + '-f', '<(version_path)', + '<(template_input_path)', + '<@(_outputs)', + ], + 'message': 'Generating <@(_outputs)', +}
\ No newline at end of file diff --git a/chrome_elf/version_assembly_manifest.template b/chrome_elf/version_assembly_manifest.template new file mode 100644 index 0000000..153194c --- /dev/null +++ b/chrome_elf/version_assembly_manifest.template @@ -0,0 +1,8 @@ +<assembly + xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> + <assemblyIdentity + name='@MAJOR@.@MINOR@.@BUILD@.@PATCH@' + version='@MAJOR@.@MINOR@.@BUILD@.@PATCH@' + type='win32'/> + <file name='chrome_elf.dll'/> +</assembly>
\ No newline at end of file diff --git a/chrome_elf/version_assembly_manifest_action.gypi b/chrome_elf/version_assembly_manifest_action.gypi new file mode 100644 index 0000000..9c44315 --- /dev/null +++ b/chrome_elf/version_assembly_manifest_action.gypi @@ -0,0 +1,37 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file contains an action which can be used to construct a manifest file +# with the same name as the version directory so that chrome.exe identifies the +# version directory as an assembly. This will be copied over to the version +# directory by the installer script. + +# To use this the following variables need to be defined: +# version_path: string: path to file containing version data (e.g. +# chrome/VERSION). +# version_py_path: string: path to file containing version script (e.g. +# chrome/tools/build/version.py). +# version_full: string: version string in W.X.Y.Z form. + + +{ + 'variables': { + 'template_input_path': + '<(DEPTH)/chrome_elf/version_assembly_manifest.template', + }, + 'inputs': [ + '<(template_input_path)', + '<(version_path)', + ], + 'outputs': [ + '<(PRODUCT_DIR)/<(version_full).manifest', + ], + 'action': [ + 'python', '<(version_py_path)', + '-f', '<(version_path)', + '<(template_input_path)', + '<@(_outputs)', + ], + 'message': 'Generating <@(_outputs)', +}
\ No newline at end of file |