summaryrefslogtreecommitdiffstats
path: root/chrome/installer/mini_installer
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/installer/mini_installer
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer/mini_installer')
-rw-r--r--chrome/installer/mini_installer/SConscript302
-rw-r--r--chrome/installer/mini_installer/chrome.release40
-rw-r--r--chrome/installer/mini_installer/mini_installer.cc392
-rw-r--r--chrome/installer/mini_installer/mini_installer.exe.manifest11
-rw-r--r--chrome/installer/mini_installer/mini_installer.h68
-rw-r--r--chrome/installer/mini_installer/mini_installer.icobin0 -> 318 bytes
-rw-r--r--chrome/installer/mini_installer/mini_installer.rc76
-rw-r--r--chrome/installer/mini_installer/mini_installer.vcproj125
-rw-r--r--chrome/installer/mini_installer/mini_installer.vsprops31
-rw-r--r--chrome/installer/mini_installer/mini_installer_debug.vsprops13
-rw-r--r--chrome/installer/mini_installer/mini_installer_exe_version.rc.version40
-rw-r--r--chrome/installer/mini_installer/mini_installer_release.vsprops13
-rw-r--r--chrome/installer/mini_installer/mini_installer_resource.h18
-rw-r--r--chrome/installer/mini_installer/pe_resource.cc73
-rw-r--r--chrome/installer/mini_installer/pe_resource.h66
15 files changed, 1268 insertions, 0 deletions
diff --git a/chrome/installer/mini_installer/SConscript b/chrome/installer/mini_installer/SConscript
new file mode 100644
index 0000000..37cc692
--- /dev/null
+++ b/chrome/installer/mini_installer/SConscript
@@ -0,0 +1,302 @@
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Import('env', 'env_res', 'env_test')
+
+
+env = env.Clone()
+env_res = env_res.Clone()
+env_test = env_test.Clone()
+
+
+env_res.Append(
+ CPPPATH = [
+ "$TARGET_ROOT",
+ ".",
+ "#/..",
+ ],
+ RCFLAGS = [
+ ["/l", "0x409"],
+ ],
+)
+
+resources = env_res.RES('mini_installer.rc')
+
+
+env.Prepend(
+ CPPPATH = [
+ '$GTEST_DIR/include',
+ '$GTEST_DIR',
+ '#/..',
+ ],
+ CPPDEFINES = [
+ 'CERT_CHAIN_PARA_HAS_EXTRA_FIELDS',
+ 'WIN32_LEAN_AND_MEAN',
+ ],
+ CCFLAGS = [
+ '/TP',
+
+ '/Wp64',
+
+ '/wd4503',
+ '/wd4819',
+
+ '/GS-', # because we link with /NODEFAULTLIB
+ ],
+ LINKFLAGS = [
+ '/INCREMENTAL',
+ '/NODEFAULTLIB',
+ '/DEBUG',
+ '/SUBSYSTEM:WINDOWS',
+ '/OPT:NOWIN98',
+ '/ENTRY:"MainEntryPoint"',
+ '/MACHINE:X86',
+ '/FIXED:No',
+
+ '/SAFESEH:NO',
+ '/NXCOMPAT',
+ '/DYNAMICBASE:NO',
+
+ '/PDB:${TARGETS[1]}',
+ '/MAP:${TARGETS[2]}',
+ ],
+)
+
+env['CCFLAGS'].remove('/RTC1')
+
+env.Append(
+ LIBS = [
+ 'shlwapi.lib',
+ 'wininet.lib',
+ 'version.lib',
+ 'msimg32.lib',
+ 'ws2_32.lib',
+ 'usp10.lib',
+ 'psapi.lib',
+ 'kernel32.lib',
+ 'user32.lib',
+ 'gdi32.lib',
+ 'winspool.lib',
+ 'comdlg32.lib',
+ 'advapi32.lib',
+ 'shell32.lib',
+ 'ole32.lib',
+ 'oleaut32.lib',
+ 'uuid.lib',
+ 'odbc32.lib',
+ 'odbccp32.lib',
+ ],
+)
+
+components = [
+ "$VISUAL_STUDIO/VC/crt/src/intel/mt_lib/memset.obj",
+ "$VISUAL_STUDIO/VC/crt/src/intel/mt_lib/P4_memset.obj",
+ "$TARGET_ROOT/chrome_dll.lib",
+]
+
+input_files = [
+ "mini_installer.cc",
+ "pe_resource.cc",
+]
+
+exe = env.Program(['mini_installer',
+ 'mini_installer.pdb',
+ 'mini_installer.map'],
+ components + resources + input_files)
+i = env.Install('$TARGET_ROOT', exe)
+env.Alias('chrome', i)
+
+
+env.AppendENVPath('PATH', r'C:\WINDOWS\system32')
+
+packed = env.Command('$TARGET_ROOT/packed_files.txt',
+ ['$CHROME_DIR/tools/build/win/create_installer_archive.py',
+ '$CHROME_DIR/installer/mini_installer/chrome.release'],
+ ('$PYTHON ${SOURCES[0]}'
+ ' --output_dir=${TARGET.dir}'
+ ' --input_file=${SOURCES[1]}'))
+env.Depends(packed, '$TARGET_ROOT/setup.exe')
+
+
+env_version = env.Clone(
+ VERSION_BAT = File('#/../chrome/tools/build/win/version.bat'),
+ CHROMEDIR = Dir('#/../chrome'),
+ PWD = Dir('.'),
+)
+
+env_version.Command('mini_installer_exe_version.rc',
+ ['mini_installer_exe_version.rc.version',
+ '$CHROMEDIR/VERSION',
+ '$CHROMEDIR/BRANDING'],
+ "$VERSION_BAT $SOURCE $CHROMEDIR $PWD $TARGET")
+
+
+#/Od
+#/I
+#"C:\src\trunk-vs\chrome\..\testing\gtest\include"
+#/I
+#"C:\src\trunk-vs\chrome\..\testing\gtest"
+#/I
+#"C:\src\trunk-vs\chrome\.."
+#/I
+#"C:\src\trunk-vs\chrome\third_party\wtl\include"
+#/I
+#"C:\src\trunk-vs\chrome\..\third_party\platformsdk_vista_6_0\files\Include"
+#/I
+#"C:\src\trunk-vs\chrome\..\third_party\platformsdk_vista_6_0\files\VC\INCLUDE"
+#/I
+#"C:\Program
+#Files\Microsoft
+#Visual
+#Studio
+#8\\VC\atlmfc\include"
+#/D
+#"UNIT_TEST"
+#/D
+#"_DEBUG"
+#/D
+#"_WIN32_WINNT=0x0600"
+#/D
+#"WINVER=0x0600"
+#/D
+#"WIN32"
+#/D
+#"_WINDOWS"
+#/D
+#"_HAS_EXCEPTIONS=0"
+#/D
+#"NOMINMAX"
+#/D
+#"_CRT_RAND_S"
+#/D
+#"CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"
+#/D
+#"WIN32_LEAN_AND_MEAN"
+#/D
+#"_UNICODE"
+#/D
+#"UNICODE"
+#/FD
+#/RTC1
+#/MTd
+#/Gy
+#/GR-
+#/Fo"C:\src\trunk-vs\chrome\Debug\obj\installer_unittests\\"
+#/Fd"C:\src\trunk-vs\chrome\Debug\obj\installer_unittests\vc80.pdb"
+#/W3
+#/WX
+#/c
+#/Wp64
+#/Zi
+#/TP
+#/wd4503
+#/wd4819
+
+env_test.Prepend(
+ CPPDEFINES = [
+ 'UNIT_TEST',
+ 'CERT_CHAIN_PARA_HAS_EXTRA_FIELDS',
+ 'WIN32_LEAN_AND_MEAN',
+ ],
+ CPPPATH = [
+ '$GTEST_DIR/include',
+ '$GTEST_DIR',
+ '#/..',
+ ],
+ LINKFLAGS = [
+ '/INCREMENTAL',
+ '/DEBUG',
+
+ '/DELAYLOAD:"dwmapi.dll"',
+ '/DELAYLOAD:"uxtheme.dll"',
+
+ '/MACHINE:X86',
+ '/FIXED:No',
+
+ '/safeseh',
+ '/dynamicbase',
+ '/ignore:4199',
+ '/nxcompat',
+ ],
+ LIBS = [
+ 'shlwapi.lib',
+ 'rpcrt4.lib',
+ 'oleacc.lib',
+ 'comsupp.lib',
+
+ 'wininet.lib',
+ 'version.lib',
+ 'msimg32.lib',
+ 'ws2_32.lib',
+ 'usp10.lib',
+ 'psapi.lib',
+ 'kernel32.lib',
+ 'user32.lib',
+ 'gdi32.lib',
+ 'winspool.lib',
+ 'comdlg32.lib',
+ 'advapi32.lib',
+ 'shell32.lib',
+ 'ole32.lib',
+ 'oleaut32.lib',
+ 'uuid.lib',
+ 'odbc32.lib',
+ 'odbccp32.lib',
+
+ 'DelayImp.lib',
+ ],
+)
+
+input_files = [
+ '../setup/setup_constants$OBJSUFFIX',
+ '../util/copy_tree_work_item_unittest.cc',
+ '../util/create_dir_work_item_unittest.cc',
+ '../util/create_reg_key_work_item_unittest.cc',
+ '../util/delete_tree_work_item_unittest.cc',
+ '../util/helper_unittest.cc',
+ '../util/install_util_unittest.cc',
+ '../util/run_all_unittests.cc',
+ '../util/set_reg_value_work_item_unittest.cc',
+ '../util/work_item_list_unittest.cc',
+]
+
+libs = [
+ '../util/util.lib',
+ '$TESTING_DIR/gtest.lib',
+ '$ICU38_DIR/icuuc.lib',
+ '$CHROME_DIR/common/common.lib',
+ '$BASE_DIR/base.lib',
+]
+
+exe = env_test.Program(['installer_unittests',
+ 'installer_unittests.pdb'],
+ input_files + libs)
+i = env_test.Install('$TARGET_ROOT', exe)
+
+env.Alias('chrome', i)
diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release
new file mode 100644
index 0000000..e9fc438
--- /dev/null
+++ b/chrome/installer/mini_installer/chrome.release
@@ -0,0 +1,40 @@
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+[FILES]
+chrome.exe: %(ChromeDir)s\
+wow_helper.exe: %(ChromeDir)s\
+Dictionaries\en-US.bdic: %(ChromeDir)s\Dictionaries
+rlz.dll: %(VersionDir)s\
+chrome.dll: %(VersionDir)s\
+icudt38.dll: %(VersionDir)s\
+Themes\default.dll: %(VersionDir)s\Themes
+locales\*.dll: %(VersionDir)s\Locales
+Resources\Inspector\*.*: %(VersionDir)s\Resources\Inspector
+Resources\Inspector\Images\*.*: %(VersionDir)s\Resources\Inspector\Images
diff --git a/chrome/installer/mini_installer/mini_installer.cc b/chrome/installer/mini_installer/mini_installer.cc
new file mode 100644
index 0000000..7c1650e
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer.cc
@@ -0,0 +1,392 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// mini_installer.exe is the first exe that is run when chrome is being
+// installed or upgraded. It is designed to be extremely small (~5KB with no
+// extra resources linked) and it has two main jobs:
+// 1) unpack the resources (possibly decompressing some)
+// 2) run the real installer (setup.exe) with appropiate flags.
+//
+// In order to be really small we don't link against the CRT and we define the
+// following compiler/linker flags:
+// EnableIntrinsicFunctions="true" compiler: /Oi
+// BasicRuntimeChecks="0"
+// BufferSecurityCheck="false" compiler: /GS-
+// EntryPointSymbol="MainEntryPoint" linker: /ENTRY
+// IgnoreAllDefaultLibraries="true" linker: /NODEFAULTLIB
+// OptimizeForWindows98="1" liker: /OPT:NOWIN98
+// linker: /SAFESEH:NO
+// Also some built-in code that the compiler relies on is not defined so we
+// are forced to manually link against it. It comes in the form of two
+// object files that exist in $(VCInstallDir)\crt\src which are memset.obj and
+// P4_memset.obj. These two object files rely on the existence of a static
+// variable named __sse2_available which indicates the presence of intel sse2
+// extensions. We define it to false which causes a slower but safe code for
+// memcpy and memset intrinsics.
+
+// having the linker merge the sections is saving us ~500 bytes.
+#pragma comment(linker, "/MERGE:.rdata=.text")
+
+#include <windows.h>
+#include <shlwapi.h>
+#include <stdlib.h>
+
+#include "chrome/installer/mini_installer/mini_installer.h"
+#include "chrome/installer/mini_installer/pe_resource.h"
+
+// Required linker symbol. See remarks above.
+extern "C" unsigned int __sse2_available = 0;
+
+namespace mini_installer {
+
+// This structure passes data back and forth for the processing
+// of resource callbacks.
+struct Context {
+ // We really have a single string that is used for all operations.
+ // We keep two pointers to it as follows:
+ // [uncompress command]' '[path to exe]\[name of file]
+ // | |
+ // Context->full_path Context->name
+ wchar_t* full_path; // input to the call back method
+ wchar_t* name; // input/output from the call back method (contains file name)
+ size_t max_name_size; // input (contains the size of buffer "name")
+};
+
+
+// Takes the path to file and returns a pointer to the filename component. For
+// exmaple for input of c:\full\path\to\file.ext it returns pointer to file.ext.
+// It also checks that there is an extension (of length 3) in file name and
+// the size of path is at least 7. It returns NULL if extension or path
+// separator is not found.
+wchar_t* GetNameFromPathExt(wchar_t* path, size_t size) {
+ const int kMinPath = 7;
+ const int kExtSize = 4;
+ if ((size < kMinPath) || (path[size - kExtSize] != L'.')) {
+ return NULL;
+ }
+ wchar_t* current = &path[size - kExtSize];
+ while (L'\\' != *current) {
+ --current;
+ if (current == path) {
+ return NULL;
+ }
+ }
+ return (current + 1);
+}
+
+
+// Simple replacement for CRT string copy method that does not overflow.
+// Returns true if the source was copied successfully otherwise returns false.
+// Parameter src is assumed to be NULL terminated and the NULL character is
+// copied over to string dest.
+bool SafeStrCopy(wchar_t* dest, const wchar_t* src, size_t dest_size) {
+ for (size_t length = 0; length < dest_size; ++dest, ++src, ++length) {
+ *dest = *src;
+ if (L'\0' == *src) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+// Helper function to read a value from registry. Returns true if value
+// is read successfully and stored in parameter value. Returns false otherwise.
+bool ReadValueFromRegistry(HKEY root_key, const wchar_t *sub_key,
+ const wchar_t *value_name, wchar_t *value,
+ size_t size) {
+ HKEY key;
+
+ if ((::RegOpenKeyEx(root_key, sub_key, NULL,
+ KEY_READ, &key) == ERROR_SUCCESS) &&
+ (::RegQueryValueEx(key, value_name, NULL, NULL,
+ reinterpret_cast<LPBYTE>(value),
+ reinterpret_cast<LPDWORD>(&size)) == ERROR_SUCCESS)) {
+ ::RegCloseKey(key);
+ return true;
+ }
+ return false;
+}
+
+
+// Gets the setup.exe path from Registry by looking the value of Uninstall
+// string, strips the arguments for uninstall and returns only the full path
+// to setup.exe.
+bool GetSetupExePathFromRegistry(wchar_t *path, size_t size) {
+ if (!ReadValueFromRegistry(HKEY_CURRENT_USER, kUninstallRegistryKey,
+ kUninstallRegistryValueName, path, size)) {
+ if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kUninstallRegistryKey,
+ kUninstallRegistryValueName, path, size)) {
+ return false;
+ }
+ }
+ wchar_t *tmp = StrStr(path, L" --");
+ if (tmp) {
+ *tmp = L'\0';
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+
+// Calls CreateProcess with good default parameters and waits for the process
+// to terminate returning the process exit code.
+bool RunProcessAndWait(const wchar_t* exe_path, wchar_t* cmdline,
+ int* exit_code) {
+ STARTUPINFOW si = {sizeof(si)};
+ PROCESS_INFORMATION pi = {0};
+ if (!::CreateProcessW(exe_path, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW,
+ NULL, NULL, &si, &pi)) {
+ return false;
+ }
+ DWORD wr = ::WaitForSingleObject(pi.hProcess, INFINITE);
+ if (WAIT_OBJECT_0 != wr) {
+ return false;
+ }
+
+ bool ret = true;
+ if (exit_code) {
+ if (!::GetExitCodeProcess(pi.hProcess,
+ reinterpret_cast<DWORD*>(exit_code))) {
+ ret = false;
+ }
+ }
+ ::CloseHandle(pi.hProcess);
+ ::CloseHandle(pi.hThread);
+ return ret;
+}
+
+
+// Windows defined callback used in the EnumResourceNamesW call. For each
+// matching resource found, the callback is invoked and at this point we write
+// it to disk and possibly uncompress it. Resources of type BL
+// are assumed to be LZ compressed and are uncompressed using 'expand.exe'.
+BOOL CALLBACK OnResourceFound(HMODULE module, const wchar_t* type,
+ wchar_t* name, LONG_PTR context) {
+ if (NULL == context) {
+ return FALSE;
+ }
+ Context* ctx = reinterpret_cast<Context*>(context);
+
+ PEResource resource(name, type, module);
+ if ((!resource.IsValid()) ||
+ (resource.Size() < 1 ) ||
+ (resource.Size() > kMaxResourceSize)) {
+ return FALSE;
+ }
+
+ // Note that the copy operation actually replaces the file name part of
+ // ctx->full_path
+ if ((!SafeStrCopy(ctx->name, name, ctx->max_name_size)) ||
+ (!resource.WriteToDisk(ctx->full_path))) {
+ return FALSE;
+ }
+
+ // If this is LZ compressed resource, uncompress it using the existing
+ // program in the system32 folder named 'expand.exe'.
+ if (0 == ::lstrcmpiW(type, kLZCResourceType)) {
+ wchar_t expand_cmd[MAX_PATH * 2] = UNCOMPRESS_CMD;
+ ::lstrcatW(expand_cmd, L"\"");
+ ::lstrcatW(expand_cmd, ctx->full_path);
+ ::lstrcatW(expand_cmd, L"\"");
+ if (!RunProcessAndWait(NULL, expand_cmd, NULL)) {
+ // Somehow we failed to uncompress the file. Exit now and leave the file
+ // behind for postmortem analysis.
+ return FALSE;
+ }
+ // Uncompression was successful, delete the source but it is not critical
+ // if that fails.
+ ::DeleteFileW(ctx->full_path);
+ }
+ return TRUE;
+}
+
+
+// Finds and writes to disk all resources of various types. Returns false
+// if there is a problem in writing any resource to disk.
+bool UnpackBinaryResources(HMODULE module, const wchar_t* base_path,
+ bool* unpacked_setup, wchar_t* archive_name) {
+ *unpacked_setup = false;
+
+ // Prepare the input to OnResourceFound method that needs a location where
+ // it will write all the resources.
+ wchar_t module_path[MAX_PATH];
+ if (!SafeStrCopy(module_path, base_path, _countof(module_path))) {
+ return false;
+ }
+ size_t length = ::lstrlen(module_path);
+ wchar_t* name = (wchar_t *) module_path + length;
+ Context context = {module_path, name, MAX_PATH - length};
+
+ // Get the resources of type 'B7'
+ if (!::EnumResourceNamesW(module, kLZMAResourceType, OnResourceFound,
+ LONG_PTR(&context))) {
+ // We need a compressed archive to do the installation. So if there
+ // is a problem in fetching B7 resource, just return error.
+ return false;
+ } else {
+ ::lstrcpy(archive_name, name);
+ }
+
+ // Get the resources of type 'BL'. setup.exe can be sent as 'BL' or 'BN'.
+ // So if we get 'resource not found' error just ignore it.
+ if (!::EnumResourceNamesW(module, kLZCResourceType, OnResourceFound,
+ LONG_PTR(&context))) {
+ if (::GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND) {
+ return false;
+ }
+ } else if (0 == ::lstrcmpiW(name, kSetupLZName)) {
+ *unpacked_setup = true;
+ }
+
+ if (!::EnumResourceNamesW(module, kBinResourceType, OnResourceFound,
+ LONG_PTR(&context))) {
+ if (::GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND) {
+ return false;
+ }
+ } else if (0 == ::lstrcmpiW(name, kSetupName)) {
+ *unpacked_setup = true;
+ }
+
+ return true;
+}
+
+
+// Executes setup.exe, waits for it to finish and returns the exit code.
+bool RunSetup(bool have_upacked_setup, const wchar_t* base_path,
+ const wchar_t* archive_name, int* exit_code) {
+ wchar_t cmd_line[MAX_PATH * 2];
+ wchar_t cmd_args[MAX_PATH * 2];
+
+ if (!SafeStrCopy(cmd_args, L" --install-archive=\"", _countof(cmd_args)) ||
+ !::lstrcat(cmd_args, base_path) ||
+ !::lstrcat(cmd_args, archive_name) ||
+ !::lstrcat(cmd_args, L"\"")) {
+ return false;
+ }
+
+ if (have_upacked_setup) {
+ if (!SafeStrCopy(cmd_line, L"\"", _countof(cmd_line)) ||
+ !::lstrcat(cmd_line, base_path) ||
+ !::lstrcat(cmd_line, kSetupName) ||
+ !::lstrcat(cmd_line, L"\"")) {
+ return false;
+ }
+ } else {
+ if (!GetSetupExePathFromRegistry(cmd_line, sizeof(cmd_line))) {
+ return false;
+ }
+ }
+
+ return (::lstrcat(cmd_line, cmd_args) &&
+ RunProcessAndWait(NULL, cmd_line, exit_code));
+}
+
+
+void DeleteExtractedFiles(const wchar_t* base_path,
+ const wchar_t* archive_name) {
+ wchar_t file_path[MAX_PATH];
+ // Delete setup.exe.
+ SafeStrCopy(file_path, base_path, MAX_PATH);
+ ::lstrcat(file_path, kSetupName);
+ ::DeleteFile(file_path);
+ // Delete chrome archive file.
+ SafeStrCopy(file_path, base_path, MAX_PATH);
+ ::lstrcat(file_path, archive_name);
+ ::DeleteFile(file_path);
+ // Delete the temp dir (if it is empty, otherwise fail).
+ ::RemoveDirectory(base_path);
+}
+
+// Creates and returns a temporary directory that can be used to extract
+// mini_installer payload.
+bool GetWorkDir(HMODULE module, wchar_t* work_dir) {
+ wchar_t base_path[MAX_PATH];
+ DWORD len = ::GetTempPath(MAX_PATH, base_path);
+ if (len >= MAX_PATH || len <= 0) {
+ // Problem in getting TEMP path so just use current directory as base path
+ len = ::GetModuleFileNameW(module, base_path, MAX_PATH);
+ if (len >= MAX_PATH || len <= 0)
+ return false; // Can't even get current directory? Return with error.
+ wchar_t* name = GetNameFromPathExt(base_path, len);
+ *name = L'\0';
+ }
+
+ wchar_t temp_name[MAX_PATH + 1];
+ if (!GetTempFileName(base_path, L"CR_", 0, temp_name))
+ return false; // Didn't get any temp name to use. Return error.
+ len = GetLongPathName(temp_name, work_dir, MAX_PATH);
+ if (len > MAX_PATH + 1 || len == 0)
+ return false; // Couldn't get full path to temp dir. Return error.
+
+ // GetTempFileName creates the file as well so delete it before creating
+ // the directory in its place.
+ if (!::DeleteFile(work_dir) || !::CreateDirectory(work_dir, NULL))
+ return false; // What's the use of temp dir if we can not create it?
+ ::lstrcat(work_dir, L"\\");
+ return true;
+}
+
+int WMain(HMODULE module) {
+ // First get a path where we can extract payload
+ wchar_t base_path[MAX_PATH];
+ if (!GetWorkDir(module, base_path))
+ return 1;
+
+ wchar_t archive_name[MAX_PATH];
+ bool have_upacked_setup;
+ if (!UnpackBinaryResources(module, base_path,
+ &have_upacked_setup, archive_name)) {
+ return 1;
+ }
+
+ int setup_exit_code = 0;
+ if (!RunSetup(have_upacked_setup, base_path,
+ archive_name, &setup_exit_code)) {
+ return 2;
+ }
+
+ wchar_t value[4];
+ if ((!ReadValueFromRegistry(HKEY_CURRENT_USER, kCleanupRegistryKey,
+ kCleanupRegistryValueName, value, 4)) ||
+ (value[0] != L'0')) {
+ DeleteExtractedFiles(base_path, archive_name);
+ }
+
+ return setup_exit_code;
+}
+} // namespace mini_installer
+
+
+int MainEntryPoint() {
+ int result = mini_installer::WMain(::GetModuleHandle(NULL));
+ ::ExitProcess(result);
+}
diff --git a/chrome/installer/mini_installer/mini_installer.exe.manifest b/chrome/installer/mini_installer/mini_installer.exe.manifest
new file mode 100644
index 0000000..28469a3
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer.exe.manifest
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
+ <ms_asmv2:security>
+ <ms_asmv2:requestedPrivileges>
+ <ms_asmv2:requestedExecutionLevel level="asInvoker">
+ </ms_asmv2:requestedExecutionLevel>
+ </ms_asmv2:requestedPrivileges>
+ </ms_asmv2:security>
+ </ms_asmv2:trustInfo>
+</assembly>
diff --git a/chrome/installer/mini_installer/mini_installer.h b/chrome/installer/mini_installer/mini_installer.h
new file mode 100644
index 0000000..785749e
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer.h
@@ -0,0 +1,68 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CHROME_INSTALLER_MINI_INSTALLER__
+#define CHROME_INSTALLER_MINI_INSTALLER__
+
+// The windows command line to uncompress a LZ compressed file. It is a define
+// because we need the string to be writable. We don't need the full path
+// since it is located in windows\system32 and is available since windows2k.
+#define UNCOMPRESS_CMD L"expand.exe -r "
+
+namespace mini_installer {
+
+// The installer filename. The installer can be compressed or uncompressed.
+const wchar_t kSetupName[] = L"setup.exe";
+const wchar_t kSetupLZName[] = L"setup.ex_";
+
+// The resource types that would be unpacked from the mini installer.
+// 'BN' is uncompressed binary and 'BL' is LZ compressed binary.
+const wchar_t kBinResourceType[] = L"BN";
+const wchar_t kLZCResourceType[] = L"BL";
+const wchar_t kLZMAResourceType[] = L"B7";
+
+// Uninstall registry location
+const wchar_t kUninstallRegistryKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Chrome";
+const wchar_t kUninstallRegistryValueName[] = L"UninstallString";
+
+// Uninstall registry key that lets user tell Chrome installer not to delete
+// extracted files.
+const wchar_t kCleanupRegistryKey[] = L"Software\\Google";
+const wchar_t kCleanupRegistryValueName[] = L"ChromeInstallerCleanup";
+
+// One gigabyte is the biggest resource size that it can handle.
+const int kMaxResourceSize = 1024*1024*1024;
+
+// This is the file that contains the list of files to be linked in the
+// executable. This file is updated by the installer generator tool chain.
+const wchar_t kManifestFilename[] = L"packed_files.txt";
+
+} // namespace mini_installer
+
+#endif // CHROME_INSTALLER_MINI_INSTALLER__
diff --git a/chrome/installer/mini_installer/mini_installer.ico b/chrome/installer/mini_installer/mini_installer.ico
new file mode 100644
index 0000000..6612f2d
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer.ico
Binary files differ
diff --git a/chrome/installer/mini_installer/mini_installer.rc b/chrome/installer/mini_installer/mini_installer.rc
new file mode 100644
index 0000000..420dea9
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer.rc
@@ -0,0 +1,76 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "mini_installer_resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_MINI_INSTALLER ICON "mini_installer.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "mini_installer_resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOL\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""mini_installer_exe_version.rc""\r\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+// This file lists the resources that are going to be packed with the exe.
+#include "packed_files.txt"
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "mini_installer_exe_version.rc"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/chrome/installer/mini_installer/mini_installer.vcproj b/chrome/installer/mini_installer/mini_installer.vcproj
new file mode 100644
index 0000000..96cfe0a
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer.vcproj
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mini_installer"
+ ProjectGUID="{24A5AC7C-280B-4899-9153-6BA570A081E7}"
+ RootNamespace="mini_installer"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ <ToolFile
+ RelativePath="..\..\tools\build\win\release.rules"
+ />
+ <ToolFile
+ RelativePath="..\..\tools\build\win\version.rules"
+ />
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\mini_installer_debug.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
+ >
+ <Tool
+ Name="create installer archive"
+ LastChromeInstaller="$(LAST_CHROME_INSTALLER)"
+ LastChromeVersion="$(LAST_CHROME_VERSION)"
+ RebuildArchive="$(REBUILD_CHROME_ARCHIVE)"
+ />
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\mini_installer_release.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
+ >
+ <Tool
+ Name="create installer archive"
+ LastChromeInstaller="$(LAST_CHROME_INSTALLER)"
+ LastChromeVersion="$(LAST_CHROME_VERSION)"
+ RebuildArchive="$(REBUILD_CHROME_ARCHIVE)"
+ />
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="resources"
+ >
+ <File
+ RelativePath=".\mini_installer.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\mini_installer.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\mini_installer_exe_version.rc.version"
+ >
+ </File>
+ <File
+ RelativePath=".\mini_installer_resource.h"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\chrome.release"
+ >
+ </File>
+ <File
+ RelativePath=".\mini_installer.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\mini_installer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\pe_resource.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\pe_resource.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/chrome/installer/mini_installer/mini_installer.vsprops b/chrome/installer/mini_installer/mini_installer.vsprops
new file mode 100644
index 0000000..c3920b0
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer.vsprops
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mini_installer"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ EnableIntrinsicFunctions="true"
+ BasicRuntimeChecks="0"
+ BufferSecurityCheck="false"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="&quot;$(VCInstallDir)crt\src\intel\mt_lib\memset.obj&quot; &quot;$(VCInstallDir)crt\src\intel\mt_lib\P4_memset.obj&quot; shlwapi.lib"
+ IgnoreAllDefaultLibraries="true"
+ GenerateMapFile="true"
+ SubSystem="2"
+ OptimizeForWindows98="1"
+ EntryPointSymbol="MainEntryPoint"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="$(OutDir);$(IntDir)"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AdditionalManifestFiles="$(SolutionDir)installer\mini_installer\mini_installer.exe.manifest"
+ />
+</VisualStudioPropertySheet>
diff --git a/chrome/installer/mini_installer/mini_installer_debug.vsprops b/chrome/installer/mini_installer/mini_installer_debug.vsprops
new file mode 100644
index 0000000..9b43a5a
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer_debug.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mini_installer_debug"
+ InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\mini_installer.vsprops"
+ >
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="$(NoInherit) /SAFESEH:NO /NXCOMPAT /DYNAMICBASE:NO /FIXED"
+ DelayLoadDLLs="$(NoInherit)"
+ />
+</VisualStudioPropertySheet>
diff --git a/chrome/installer/mini_installer/mini_installer_exe_version.rc.version b/chrome/installer/mini_installer/mini_installer_exe_version.rc.version
new file mode 100644
index 0000000..3b024d1
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer_exe_version.rc.version
@@ -0,0 +1,40 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @MAJOR@,@MINOR@,@BUILD@,@PATCH@
+ PRODUCTVERSION @MAJOR@,@MINOR@,@BUILD@,@PATCH@
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "@COMPANY_FULLNAME@"
+ VALUE "FileDescription", "@PRODUCT_FULLNAME@"
+ VALUE "FileVersion", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"
+ VALUE "InternalName", "mini_installer"
+ VALUE "LegalCopyright", "@COPYRIGHT@"
+ VALUE "ProductName", "@PRODUCT_FULLNAME@"
+ VALUE "ProductVersion", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"
+ VALUE "CompanyShortName", "@COMPANY_SHORTNAME@"
+ VALUE "ProductShortName", "@PRODUCT_SHORTNAME@"
+ VALUE "LastChange", "@LASTCHANGE@"
+ VALUE "Official Build", "@OFFICIAL_BUILD@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/chrome/installer/mini_installer/mini_installer_release.vsprops b/chrome/installer/mini_installer/mini_installer_release.vsprops
new file mode 100644
index 0000000..339f174
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer_release.vsprops
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mini_installer_release"
+ InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\mini_installer.vsprops"
+ >
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="$(NoInherit) /SAFESEH:NO /NXCOMPAT /DYNAMICBASE:NO /FIXED"
+ DelayLoadDLLs="$(NoInherit)"
+ />
+</VisualStudioPropertySheet>
diff --git a/chrome/installer/mini_installer/mini_installer_resource.h b/chrome/installer/mini_installer/mini_installer_resource.h
new file mode 100644
index 0000000..ca01e39
--- /dev/null
+++ b/chrome/installer/mini_installer/mini_installer_resource.h
@@ -0,0 +1,18 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by mini_installer.rc
+//
+#define IDI_MINI_INSTALLER 107
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 129
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 110
+#endif
+#endif
diff --git a/chrome/installer/mini_installer/pe_resource.cc b/chrome/installer/mini_installer/pe_resource.cc
new file mode 100644
index 0000000..6084fd3
--- /dev/null
+++ b/chrome/installer/mini_installer/pe_resource.cc
@@ -0,0 +1,73 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/installer/mini_installer/pe_resource.h"
+
+PEResource::PEResource(HRSRC resource, HMODULE module)
+ : resource_(resource), module_(module) {
+}
+
+PEResource::PEResource(const wchar_t* name, const wchar_t* type, HMODULE module)
+ : resource_(NULL), module_(module) {
+ resource_ = ::FindResourceW(module, name, type);
+}
+
+bool PEResource::IsValid() {
+ return (NULL != resource_);
+}
+
+size_t PEResource::Size() {
+ return ::SizeofResource(module_, resource_);
+}
+
+bool PEResource::WriteToDisk(const wchar_t* full_path) {
+ // Resource handles are not real HGLOBALs so do not attempt to close them.
+ // Windows frees them whenever there is memory pressure.
+ HGLOBAL data_handle = ::LoadResource(module_, resource_);
+ if (NULL == data_handle) {
+ return false;
+ }
+ void* data = ::LockResource(data_handle);
+ if (NULL == data) {
+ return false;
+ }
+ size_t resource_size = Size();
+ HANDLE out_file = ::CreateFileW(full_path, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (INVALID_HANDLE_VALUE == out_file) {
+ return false;
+ }
+ DWORD written = 0;
+ if (!::WriteFile(out_file, data, static_cast<DWORD>(resource_size),
+ &written, NULL)) {
+ ::CloseHandle(out_file);
+ return false;
+ }
+ return ::CloseHandle(out_file) ? true : false;
+}
diff --git a/chrome/installer/mini_installer/pe_resource.h b/chrome/installer/mini_installer/pe_resource.h
new file mode 100644
index 0000000..10c892c
--- /dev/null
+++ b/chrome/installer/mini_installer/pe_resource.h
@@ -0,0 +1,66 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CHROME_INSTALLER_MINI_INSTALLER_PE_RESOURCE__
+#define CHROME_INSTALLER_MINI_INSTALLER_PE_RESOURCE__
+
+#include <windows.h>
+
+// This class models a windows PE resource. It does not pretend to be a full
+// API wrapper and it is just concerned with loading it to memory and writing
+// it to disk. Each resource is unique only in the context of a loaded module,
+// that is why you need to specify one on each constructor.
+class PEResource {
+ public:
+ // This ctor takes the handle to the resource and the module where it was
+ // found. Ownership of the resource is transfered to this object.
+ PEResource(HRSRC resource, HMODULE module);
+
+ // This ctor takes the resource name, the resource type and the module where
+ // to look for the resource. If the resource is found IsValid() returns true.
+ PEResource(const wchar_t* name, const wchar_t* type, HMODULE module);
+
+ // Returns true if the resource is valid.
+ bool IsValid();
+
+ // Returns the size in bytes of the resource. Returns zero if the resource is
+ // not valid.
+ size_t Size();
+
+ // Creates a file in 'path' with a copy of the resource. If the resource can
+ // not be loaded into memory or if it cannot be written to disk it returns
+ // false.
+ bool WriteToDisk(const wchar_t* path);
+
+ private:
+ HRSRC resource_;
+ HMODULE module_;
+};
+
+#endif // CHROME_INSTALLER_MINI_INSTALLER_PE_RESOURCE__