diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/installer/mini_installer | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_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')
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 Binary files differnew file mode 100644 index 0000000..6612f2d --- /dev/null +++ b/chrome/installer/mini_installer/mini_installer.ico 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=""$(VCInstallDir)crt\src\intel\mt_lib\memset.obj" "$(VCInstallDir)crt\src\intel\mt_lib\P4_memset.obj" 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__ |