Chromium Code Reviews| Index: chrome/installer/mini_installer/mini_installer.cc |
| diff --git a/chrome/installer/mini_installer/mini_installer.cc b/chrome/installer/mini_installer/mini_installer.cc |
| index acbdc260ac6c8ed2c744bb29a7e25897dc6d3d1f..226040a43d3fefe64eea7b62592e83fccd01bc64 100644 |
| --- a/chrome/installer/mini_installer/mini_installer.cc |
| +++ b/chrome/installer/mini_installer/mini_installer.cc |
| @@ -32,13 +32,26 @@ |
| #include "chrome/installer/mini_installer/mini_installer_constants.h" |
| #include "chrome/installer/mini_installer/mini_string.h" |
| #include "chrome/installer/mini_installer/pe_resource.h" |
| +#include "chrome/installer/mini_installer/regkey.h" |
| namespace mini_installer { |
| -typedef DWORD ProcessExitCode; |
| typedef StackString<MAX_PATH> PathString; |
| typedef StackString<MAX_PATH * 4> CommandString; |
| +struct ProcessExitCode { |
|
robertshield
2015/08/04 03:11:36
This isn't a just an exit code anymore, suggest ca
bcwhite
2015/08/04 19:34:30
Done.
|
| + DWORD exit_code; |
| + DWORD windows_code; |
|
robertshield
2015/08/04 03:11:36
It isn't clear to a Windows dev what "windows_code
bcwhite
2015/08/04 19:34:31
It's usually the result of ::GetLastError() but so
robertshield
2015/08/05 18:39:48
Ok.
|
| + |
| + explicit ProcessExitCode(DWORD exit) : exit_code(exit), windows_code(0) {} |
| + ProcessExitCode(DWORD exit, DWORD win) : exit_code(exit), windows_code(win) { |
| + } |
| + |
| + bool IsSuccess() { |
| + return exit_code == ERROR_SUCCESS; |
|
robertshield
2015/08/04 03:11:36
Nit: ERROR_SUCCESS is a windows error code, not a
bcwhite
2015/08/04 19:34:30
Done.
|
| + } |
| +}; |
| + |
| // This structure passes data back and forth for the processing |
| // of resource callbacks. |
| struct Context { |
| @@ -50,167 +63,61 @@ struct Context { |
| PathString* setup_resource_path; |
| }; |
| -// A helper class used to manipulate the Windows registry. Typically, members |
| -// return Windows last-error codes a la the Win32 registry API. |
| -class RegKey { |
| - public: |
| - RegKey() : key_(NULL) { } |
| - ~RegKey() { Close(); } |
| - |
| - // Opens the key named |sub_key| with given |access| rights. Returns |
| - // ERROR_SUCCESS or some other error. |
| - LONG Open(HKEY key, const wchar_t* sub_key, REGSAM access); |
| - |
| - // Returns true if a key is open. |
| - bool is_valid() const { return key_ != NULL; } |
| - |
| - // Read a REG_SZ value from the registry into the memory indicated by |value| |
| - // (of |value_size| wchar_t units). Returns ERROR_SUCCESS, |
| - // ERROR_FILE_NOT_FOUND, ERROR_MORE_DATA, or some other error. |value| is |
| - // guaranteed to be null-terminated on success. |
| - LONG ReadValue(const wchar_t* value_name, |
| - wchar_t* value, |
| - size_t value_size) const; |
| - |
| - // Write a REG_SZ value to the registry. |value| must be null-terminated. |
| - // Returns ERROR_SUCCESS or an error code. |
| - LONG WriteValue(const wchar_t* value_name, const wchar_t* value); |
| - |
| - // Closes the key if it was open. |
| - void Close(); |
| - |
| - private: |
| - RegKey(const RegKey&); |
| - RegKey& operator=(const RegKey&); |
| - |
| - HKEY key_; |
| -}; // class RegKey |
| - |
| -LONG RegKey::Open(HKEY key, const wchar_t* sub_key, REGSAM access) { |
| - Close(); |
| - return ::RegOpenKeyEx(key, sub_key, NULL, access, &key_); |
| -} |
| -LONG RegKey::ReadValue(const wchar_t* value_name, |
| - wchar_t* value, |
| - size_t value_size) const { |
| - DWORD type; |
| - DWORD byte_length = static_cast<DWORD>(value_size * sizeof(wchar_t)); |
| - LONG result = ::RegQueryValueEx(key_, value_name, NULL, &type, |
| - reinterpret_cast<BYTE*>(value), |
| - &byte_length); |
| - if (result == ERROR_SUCCESS) { |
| - if (type != REG_SZ) { |
| - result = ERROR_NOT_SUPPORTED; |
| - } else if (byte_length == 0) { |
| - *value = L'\0'; |
| - } else if (value[byte_length/sizeof(wchar_t) - 1] != L'\0') { |
| - if ((byte_length / sizeof(wchar_t)) < value_size) |
| - value[byte_length / sizeof(wchar_t)] = L'\0'; |
| - else |
| - result = ERROR_MORE_DATA; |
| - } |
| - } |
| - return result; |
| -} |
| +// Opens the Google Update ClientState key for the current install |
| +// configuration. This includes locating the correct key in the face of |
| +// multi-install. The flag will by default be written to HKCU, but if |
| +// --system-level is included in the command line, it will be written to |
| +// HKLM instead. |
| +bool OpenInstallStateKey(const Configuration& configuration, RegKey* key) { |
| + const HKEY root_key = |
| + configuration.is_system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| + const wchar_t* app_guid = configuration.chrome_app_guid(); |
| + const REGSAM key_access = KEY_QUERY_VALUE | KEY_SET_VALUE; |
| + LONG ret = ERROR_SUCCESS; |
| -LONG RegKey::WriteValue(const wchar_t* value_name, const wchar_t* value) { |
| - return ::RegSetValueEx(key_, value_name, 0, REG_SZ, |
| - reinterpret_cast<const BYTE*>(value), |
| - (lstrlen(value) + 1) * sizeof(wchar_t)); |
| + return RegKey::OpenClientStateKey(root_key, app_guid, key_access, key); |
| } |
| -void RegKey::Close() { |
| - if (key_ != NULL) { |
| - ::RegCloseKey(key_); |
| - key_ = NULL; |
| - } |
| -} |
| +// Writes install results into registry where it is read by Google Update. |
| +// Don't write anything if there is already a result present, likely |
| +// written by setup.exe. |
| +void WriteInstallResults(const Configuration& configuration, |
| + ProcessExitCode result) { |
| +#if defined(GOOGLE_CHROME_BUILD) |
| + // Calls to setup.exe will write a "success" result if everything was good |
| + // so we don't need to write anything from here. |
| + if (result.IsSuccess()) |
| + return; |
| -// Helper function to read a value from registry. Returns true if value |
| -// is read successfully and stored in parameter value. Returns false otherwise. |
| -// |size| is measured in wchar_t units. |
| -bool ReadValueFromRegistry(HKEY root_key, const wchar_t *sub_key, |
| - const wchar_t *value_name, wchar_t *value, |
| - size_t size) { |
| RegKey key; |
| - |
| - if (key.Open(root_key, sub_key, KEY_QUERY_VALUE) == ERROR_SUCCESS && |
| - key.ReadValue(value_name, value, size) == ERROR_SUCCESS) { |
| - return true; |
| + DWORD value; |
| + if (OpenInstallStateKey(configuration, &key)) { |
| + if (key.ReadDWValue(kInstallerResultRegistryValue, &value) |
| + != ERROR_SUCCESS || value == 0) { |
| + key.WriteDWValue(kInstallerResultRegistryValue, |
| + result.exit_code ? 1 /* FAILED_CUSTOM_ERROR */ |
| + : 0 /* SUCCESS */); |
| + key.WriteDWValue(kInstallerErrorRegistryValue, result.exit_code); |
| + key.WriteDWValue(kInstallerExtraCode1RegistryValue, result.windows_code); |
| + } |
| + key.Close(); |
| } |
| - return false; |
| -} |
| - |
| -// Opens the Google Update ClientState key for a product. This finds only |
| -// registry entries for Chrome; it does not support the Chromium registry |
| -// layout. |
| -bool OpenClientStateKey(HKEY root_key, const wchar_t* app_guid, REGSAM access, |
| - RegKey* key) { |
| - PathString client_state_key; |
| - return client_state_key.assign(kClientStateKeyBase) && |
| - client_state_key.append(app_guid) && |
| - (key->Open(root_key, |
| - client_state_key.get(), |
| - access | KEY_WOW64_32KEY) == ERROR_SUCCESS); |
| +#endif |
| } |
| // This function sets the flag in registry to indicate that Google Update |
| // should try full installer next time. If the current installer works, this |
| -// flag is cleared by setup.exe at the end of install. The flag will by default |
| -// be written to HKCU, but if --system-level is included in the command line, |
| -// it will be written to HKLM instead. |
| -// TODO(grt): Write a unit test for this that uses registry virtualization. |
| +// flag is cleared by setup.exe at the end of install. |
| void SetInstallerFlags(const Configuration& configuration) { |
| RegKey key; |
| - const REGSAM key_access = KEY_QUERY_VALUE | KEY_SET_VALUE; |
| - const HKEY root_key = |
| - configuration.is_system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| - // This is ignored if multi-install is true. |
| - const wchar_t* app_guid = |
| - configuration.has_chrome_frame() ? |
| - google_update::kChromeFrameAppGuid : |
| - configuration.chrome_app_guid(); |
| StackString<128> value; |
| LONG ret = ERROR_SUCCESS; |
| - // When multi_install is true, we are potentially: |
| - // 1. Performing a multi-install of some product(s) on a clean machine. |
| - // Neither the product(s) nor the multi-installer will have a ClientState |
| - // key in the registry, so there is nothing to be done. |
| - // 2. Upgrading an existing multi-install. The multi-installer will have a |
| - // ClientState key in the registry. Only it need be modified. |
| - // 3. Migrating a single-install into a multi-install. The product will have |
| - // a ClientState key in the registry. Only it need be modified. |
| - // To handle all cases, we inspect the product's ClientState to see if it |
| - // exists and its "ap" value does not contain "-multi". This is case 3, so we |
| - // modify the product's ClientState. Otherwise, we check the |
| - // multi-installer's ClientState and modify it if it exists. |
| - if (configuration.is_multi_install()) { |
| - if (OpenClientStateKey(root_key, app_guid, key_access, &key)) { |
| - // The product has a client state key. See if it's a single-install. |
| - ret = key.ReadValue(kApRegistryValue, value.get(), value.capacity()); |
| - if (ret != ERROR_FILE_NOT_FOUND && |
| - (ret != ERROR_SUCCESS || |
| - FindTagInStr(value.get(), kMultiInstallTag, NULL))) { |
| - // Error or case 2: modify the multi-installer's value. |
| - key.Close(); |
| - app_guid = google_update::kMultiInstallAppGuid; |
| - } // else case 3: modify this value. |
| - } else { |
| - // case 1 or 2: modify the multi-installer's value. |
| - key.Close(); |
| - app_guid = google_update::kMultiInstallAppGuid; |
| - } |
| - } |
| + if (!OpenInstallStateKey(configuration, &key)) |
| + return; |
| - if (!key.is_valid()) { |
| - if (!OpenClientStateKey(root_key, app_guid, key_access, &key)) |
| - return; |
| - |
| - value.clear(); |
| - ret = key.ReadValue(kApRegistryValue, value.get(), value.capacity()); |
| - } |
| + ret = key.ReadSZValue(kApRegistryValue, value.get(), value.capacity()); |
| // The conditions below are handling two cases: |
| // 1. When ap value is present, we want to add the required tag only if it is |
| @@ -223,7 +130,7 @@ void SetInstallerFlags(const Configuration& configuration) { |
| if (!StrEndsWith(value.get(), kFullInstallerSuffix) && |
| value.append(kFullInstallerSuffix)) { |
| - key.WriteValue(kApRegistryValue, value.get()); |
| + key.WriteSZValue(kApRegistryValue, value.get()); |
| } |
| } |
| } |
| @@ -237,18 +144,19 @@ ProcessExitCode GetSetupExePathForAppGuid(bool system_level, |
| size_t size) { |
| const HKEY root_key = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| RegKey key; |
| - if (!OpenClientStateKey(root_key, app_guid, KEY_QUERY_VALUE, &key) || |
| - (key.ReadValue(kUninstallRegistryValue, path, size) != ERROR_SUCCESS)) { |
| - return UNABLE_TO_FIND_REGISTRY_KEY; |
| - } |
| + if (!RegKey::OpenClientStateKey(root_key, app_guid, KEY_QUERY_VALUE, &key)) |
| + return ProcessExitCode(UNABLE_TO_FIND_REGISTRY_KEY); |
| + DWORD result = key.ReadSZValue(kUninstallRegistryValue, path, size); |
| + if (result != ERROR_SUCCESS) |
| + return ProcessExitCode(UNABLE_TO_FIND_REGISTRY_KEY, result); |
| // Check that the path to the existing installer includes the expected |
| // version number. It's not necessary for accuracy to verify before/after |
| // delimiters. |
| if (!SearchStringI(path, previous_version)) |
| - return PATCH_NOT_FOR_INSTALLED_VERSION; |
| + return ProcessExitCode(PATCH_NOT_FOR_INSTALLED_VERSION); |
| - return SUCCESS_EXIT_CODE; |
| + return ProcessExitCode(SUCCESS_EXIT_CODE); |
| } |
| // Gets the path to setup.exe of the previous version. The overall path is found |
| @@ -259,7 +167,7 @@ ProcessExitCode GetPreviousSetupExePath(const Configuration& configuration, |
| size_t size) { |
| bool system_level = configuration.is_system_level(); |
| const wchar_t* previous_version = configuration.previous_version(); |
| - ProcessExitCode exit_code = GENERIC_ERROR; |
| + ProcessExitCode exit_code = ProcessExitCode(GENERIC_ERROR); |
| // If this is a multi install, first try looking in the binaries for the path. |
| if (configuration.is_multi_install()) { |
| @@ -270,14 +178,14 @@ ProcessExitCode GetPreviousSetupExePath(const Configuration& configuration, |
| // Failing that, look in Chrome Frame's client state key if --chrome-frame was |
| // specified. |
| - if (exit_code != SUCCESS_EXIT_CODE && configuration.has_chrome_frame()) { |
| + if (!exit_code.IsSuccess() && configuration.has_chrome_frame()) { |
| exit_code = GetSetupExePathForAppGuid( |
| system_level, google_update::kChromeFrameAppGuid, previous_version, |
| path, size); |
| } |
| // Make a last-ditch effort to look in the Chrome client state key. |
| - if (exit_code != SUCCESS_EXIT_CODE) { |
| + if (!exit_code.IsSuccess()) { |
| exit_code = GetSetupExePathForAppGuid( |
| system_level, configuration.chrome_app_guid(), previous_version, |
| path, size); |
| @@ -294,19 +202,23 @@ ProcessExitCode RunProcessAndWait(const wchar_t* exe_path, wchar_t* cmdline) { |
| PROCESS_INFORMATION pi = {0}; |
| if (!::CreateProcess(exe_path, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, |
| NULL, NULL, &si, &pi)) { |
| - return COULD_NOT_CREATE_PROCESS; |
| + return ProcessExitCode(COULD_NOT_CREATE_PROCESS, ::GetLastError()); |
| } |
| ::CloseHandle(pi.hThread); |
| - ProcessExitCode exit_code = SUCCESS_EXIT_CODE; |
| + DWORD exit_code = SUCCESS_EXIT_CODE; |
| DWORD wr = ::WaitForSingleObject(pi.hProcess, INFINITE); |
| - if (WAIT_OBJECT_0 != wr || !::GetExitCodeProcess(pi.hProcess, &exit_code)) |
| - exit_code = WAIT_FOR_PROCESS_FAILED; |
| + if (WAIT_OBJECT_0 != wr || !::GetExitCodeProcess(pi.hProcess, &exit_code)) { |
| + // Note: We've assumed that WAIT_OBJCT_0 != wr means a failure. The call |
| + // could return a different object but since we never spawn more than one |
| + // sub-process at a time that case should never happen. |
| + return ProcessExitCode(WAIT_FOR_PROCESS_FAILED, ::GetLastError()); |
| + } |
| ::CloseHandle(pi.hProcess); |
| - return exit_code; |
| + return ProcessExitCode(exit_code); |
| } |
| // Appends any command line params passed to mini_installer to the given buffer |
| @@ -436,7 +348,7 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| PathString setup_dest_path; |
| if (!setup_dest_path.assign(base_path) || |
| !setup_dest_path.append(kSetupExe)) |
| - return PATH_STRING_OVERFLOW; |
| + return ProcessExitCode(PATH_STRING_OVERFLOW); |
| // Prepare the input to OnResourceFound method that needs a location where |
| // it will write all the resources. |
| @@ -450,11 +362,14 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| // We need a chrome archive to do the installation. So if there |
| // is a problem in fetching B7 resource, just return an error. |
| if (!::EnumResourceNames(module, kLZMAResourceType, OnResourceFound, |
| - reinterpret_cast<LONG_PTR>(&context)) || |
| - archive_path->length() == 0) |
| - return UNABLE_TO_EXTRACT_CHROME_ARCHIVE; |
| + reinterpret_cast<LONG_PTR>(&context))) { |
| + return ProcessExitCode(UNABLE_TO_EXTRACT_CHROME_ARCHIVE, ::GetLastError()); |
| + } |
| + if (archive_path->length() == 0) { |
| + return ProcessExitCode(UNABLE_TO_EXTRACT_CHROME_ARCHIVE); |
| + } |
| - ProcessExitCode exit_code = SUCCESS_EXIT_CODE; |
| + ProcessExitCode exit_code = ProcessExitCode(SUCCESS_EXIT_CODE); |
| // If we found setup 'B7' resource (used for differential updates), handle |
| // it. Note that this is only for Chrome; Chromium installs are always |
| @@ -465,7 +380,7 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| // Get the path to setup.exe first. |
| exit_code = GetPreviousSetupExePath(configuration, exe_path.get(), |
| exe_path.capacity()); |
| - if (exit_code == SUCCESS_EXIT_CODE) { |
| + if (exit_code.IsSuccess()) { |
| if (!cmd_line.append(exe_path.get()) || |
| !cmd_line.append(L" --") || |
| !cmd_line.append(kCmdUpdateSetupExe) || |
| @@ -476,7 +391,7 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| !cmd_line.append(L"=\"") || |
| !cmd_line.append(setup_dest_path.get()) || |
| !cmd_line.append(L"\"")) { |
| - exit_code = COMMAND_STRING_OVERFLOW; |
| + exit_code = ProcessExitCode(COMMAND_STRING_OVERFLOW); |
| } |
| } |
| @@ -486,13 +401,13 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| // installer results for consumption by Google Update. |
| AppendCommandLineFlags(configuration, &cmd_line); |
| - if (exit_code == SUCCESS_EXIT_CODE) |
| + if (exit_code.IsSuccess()) |
| exit_code = RunProcessAndWait(exe_path.get(), cmd_line.get()); |
| - if (exit_code != SUCCESS_EXIT_CODE) |
| + if (!exit_code.IsSuccess()) |
| DeleteFile(setup_path->get()); |
| else if (!setup_path->assign(setup_dest_path.get())) |
| - exit_code = PATH_STRING_OVERFLOW; |
| + exit_code = ProcessExitCode(PATH_STRING_OVERFLOW); |
| return exit_code; |
| } |
| @@ -501,8 +416,9 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| // (compressed setup). |
| if (!::EnumResourceNames(module, kLZCResourceType, OnResourceFound, |
| reinterpret_cast<LONG_PTR>(&context)) && |
| - ::GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND) |
| - return UNABLE_TO_EXTRACT_SETUP_B7; |
| + ::GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND) { |
| + return ProcessExitCode(UNABLE_TO_EXTRACT_SETUP_B7, ::GetLastError()); |
| + } |
| if (setup_path->length() > 0) { |
| // Uncompress LZ compressed resource. Setup is packed with 'MSCF' |
| @@ -513,17 +429,18 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| if (success) { |
| if (!setup_path->assign(setup_dest_path.get())) { |
| ::DeleteFile(setup_dest_path.get()); |
| - exit_code = PATH_STRING_OVERFLOW; |
| + exit_code = ProcessExitCode(PATH_STRING_OVERFLOW); |
| } |
| } else { |
| - exit_code = UNABLE_TO_EXTRACT_SETUP_EXE; |
| + exit_code = ProcessExitCode(UNABLE_TO_EXTRACT_SETUP_EXE); |
| } |
| #if defined(COMPONENT_BUILD) |
| // Extract the (uncompressed) modules required by setup.exe. |
| if (!::EnumResourceNames(module, kBinResourceType, WriteResourceToDirectory, |
| - reinterpret_cast<LONG_PTR>(base_path))) |
| - return UNABLE_TO_EXTRACT_SETUP; |
| + reinterpret_cast<LONG_PTR>(base_path))) { |
| + return ProcessExitCode(UNABLE_TO_EXTRACT_SETUP, ::GetLastError()); |
| + } |
| #endif |
| return exit_code; |
| @@ -535,8 +452,9 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| // it from create_installer_archive.py). |
| if (!::EnumResourceNames(module, kBinResourceType, OnResourceFound, |
| reinterpret_cast<LONG_PTR>(&context)) && |
| - ::GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND) |
| - return UNABLE_TO_EXTRACT_SETUP_BN; |
| + ::GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND) { |
| + return ProcessExitCode(UNABLE_TO_EXTRACT_SETUP_BN, ::GetLastError()); |
| + } |
| if (setup_path->length() > 0) { |
| if (setup_path->comparei(setup_dest_path.get()) != 0) { |
| @@ -551,7 +469,7 @@ ProcessExitCode UnpackBinaryResources(const Configuration& configuration, |
| } |
| if (setup_path->length() == 0) |
| - exit_code = UNABLE_TO_EXTRACT_SETUP; |
| + exit_code = ProcessExitCode(UNABLE_TO_EXTRACT_SETUP); |
| return exit_code; |
| } |
| @@ -570,11 +488,11 @@ ProcessExitCode RunSetup(const Configuration& configuration, |
| if (!cmd_line.assign(L"\"") || |
| !cmd_line.append(setup_path) || |
| !cmd_line.append(L"\"")) |
| - return COMMAND_STRING_OVERFLOW; |
| + return ProcessExitCode(COMMAND_STRING_OVERFLOW); |
| } else { |
| ProcessExitCode exit_code = GetPreviousSetupExePath( |
| configuration, cmd_line.get(), cmd_line.capacity()); |
| - if (exit_code != SUCCESS_EXIT_CODE) |
| + if (!exit_code.IsSuccess()) |
| return exit_code; |
| } |
| @@ -590,7 +508,7 @@ ProcessExitCode RunSetup(const Configuration& configuration, |
| !cmd_line.append(L"=\"") || |
| !cmd_line.append(archive_path) || |
| !cmd_line.append(L"\"")) |
| - return COMMAND_STRING_OVERFLOW; |
| + return ProcessExitCode(COMMAND_STRING_OVERFLOW); |
| // Append the command line param for chrome previous version. |
| if (configuration.previous_version() && |
| @@ -599,7 +517,7 @@ ProcessExitCode RunSetup(const Configuration& configuration, |
| !cmd_line.append(L"=\"") || |
| !cmd_line.append(configuration.previous_version()) || |
| !cmd_line.append(L"\""))) { |
| - return COMMAND_STRING_OVERFLOW; |
| + return ProcessExitCode(COMMAND_STRING_OVERFLOW); |
| } |
| // Get any command line option specified for mini_installer and pass them |
| @@ -810,7 +728,7 @@ bool ProcessNonInstallOperations(const Configuration& configuration, |
| case Configuration::CLEANUP: |
| // Cleanup has already taken place in DeleteOldChromeTempDirectories at |
| // this point, so just tell our caller to exit early. |
| - *exit_code = SUCCESS_EXIT_CODE; |
| + *exit_code = ProcessExitCode(SUCCESS_EXIT_CODE); |
| return true; |
| default: |
| @@ -827,8 +745,8 @@ bool ProcessNonInstallOperations(const Configuration& configuration, |
| // we continue to support it. |
| bool ShouldDeleteExtractedFiles() { |
| wchar_t value[2] = {0}; |
| - if (ReadValueFromRegistry(HKEY_CURRENT_USER, kCleanupRegistryKey, |
| - kCleanupRegistryValue, value, _countof(value)) && |
| + if (RegKey::ReadSZValue(HKEY_CURRENT_USER, kCleanupRegistryKey, |
| + kCleanupRegistryValue, value, _countof(value)) && |
| value[0] == L'0') { |
| return false; |
| } |
| @@ -845,12 +763,12 @@ ProcessExitCode WMain(HMODULE module) { |
| // so this could buy us some space. |
| DeleteOldChromeTempDirectories(); |
| - ProcessExitCode exit_code = SUCCESS_EXIT_CODE; |
| + ProcessExitCode exit_code = ProcessExitCode(SUCCESS_EXIT_CODE); |
| // Parse configuration from the command line and resources. |
| Configuration configuration; |
| if (!configuration.Initialize(module)) |
| - return GENERIC_INITIALIZATION_FAILURE; |
| + return ProcessExitCode(GENERIC_INITIALIZATION_FAILURE); |
| // If the --cleanup switch was specified on the command line, then that means |
| // we should only do the cleanup and then exit. |
| @@ -860,7 +778,7 @@ ProcessExitCode WMain(HMODULE module) { |
| // First get a path where we can extract payload |
| PathString base_path; |
| if (!GetWorkDir(module, &base_path)) |
| - return UNABLE_TO_GET_WORK_DIRECTORY; |
| + return ProcessExitCode(UNABLE_TO_GET_WORK_DIRECTORY); |
| #if defined(GOOGLE_CHROME_BUILD) |
| // Set the magic suffix in registry to try full installer next time. We ignore |
| @@ -880,12 +798,13 @@ ProcessExitCode WMain(HMODULE module) { |
| // setup. |
| ::SetProcessWorkingSetSize(::GetCurrentProcess(), -1, -1); |
| - if (exit_code == SUCCESS_EXIT_CODE) |
| + if (exit_code.IsSuccess()) |
| exit_code = RunSetup(configuration, archive_path.get(), setup_path.get()); |
| if (ShouldDeleteExtractedFiles()) |
| DeleteExtractedFiles(base_path.get(), archive_path.get(), setup_path.get()); |
| + WriteInstallResults(configuration, exit_code); |
| return exit_code; |
| } |
| @@ -894,7 +813,8 @@ ProcessExitCode WMain(HMODULE module) { |
| int MainEntryPoint() { |
| mini_installer::ProcessExitCode result = |
| mini_installer::WMain(::GetModuleHandle(NULL)); |
| - ::ExitProcess(result); |
| + |
| + ::ExitProcess(result.exit_code); |
| } |
| // VC Express editions don't come with the memset CRT obj file and linking to |