| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <windows.h> | 5 #include <windows.h> |
| 6 #include <shlwapi.h> | 6 #include <shlwapi.h> |
| 7 | 7 |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/environment.h" | 10 #include "base/environment.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 COMPILE_ASSERT(kDefaultPercentage % 5 == 0, default_percentage_not_mult_5); | 107 COMPILE_ASSERT(kDefaultPercentage % 5 == 0, default_percentage_not_mult_5); |
| 108 | 108 |
| 109 // Roll the dice to determine if this user is in the experiment and if so, | 109 // Roll the dice to determine if this user is in the experiment and if so, |
| 110 // in which experimental group. | 110 // in which experimental group. |
| 111 double population = 0.0; | 111 double population = 0.0; |
| 112 double group = 0.0; | 112 double group = 0.0; |
| 113 GetPreReadPopulationAndGroup(&population, &group); | 113 GetPreReadPopulationAndGroup(&population, &group); |
| 114 | 114 |
| 115 // We limit experiment populations to 1% of the Stable and 10% of each of | 115 // We limit experiment populations to 1% of the Stable and 10% of each of |
| 116 // the other channels. | 116 // the other channels. |
| 117 const string16 channel(GoogleUpdateSettings::GetChromeChannel( | 117 const base::string16 channel(GoogleUpdateSettings::GetChromeChannel( |
| 118 GoogleUpdateSettings::IsSystemInstall())); | 118 GoogleUpdateSettings::IsSystemInstall())); |
| 119 double threshold = (channel == installer::kChromeChannelStable) ? 0.01 : 0.10; | 119 double threshold = (channel == installer::kChromeChannelStable) ? 0.01 : 0.10; |
| 120 | 120 |
| 121 // If the experiment has expired use the default pre-read level. Otherwise, | 121 // If the experiment has expired use the default pre-read level. Otherwise, |
| 122 // those not in the experiment population also use the default pre-read level. | 122 // those not in the experiment population also use the default pre-read level. |
| 123 size_t value = kDefaultPercentage; | 123 size_t value = kDefaultPercentage; |
| 124 const char* format_str = kDefaultFormatStr; | 124 const char* format_str = kDefaultFormatStr; |
| 125 if (PreReadExperimentIsActive() && (population <= threshold)) { | 125 if (PreReadExperimentIsActive() && (population <= threshold)) { |
| 126 // We divide the experiment population into groups pre-reading at 5 percent | 126 // We divide the experiment population into groups pre-reading at 5 percent |
| 127 // increments in the range [0, 100]. | 127 // increments in the range [0, 100]. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 141 scoped_ptr<base::Environment> env(base::Environment::Create()); | 141 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 142 env->SetVar(chrome::kPreReadEnvironmentVariable, group_name); | 142 env->SetVar(chrome::kPreReadEnvironmentVariable, group_name); |
| 143 | 143 |
| 144 // Return the percentage value to be used. | 144 // Return the percentage value to be used. |
| 145 return value; | 145 return value; |
| 146 } | 146 } |
| 147 | 147 |
| 148 // Expects that |dir| has a trailing backslash. |dir| is modified so it | 148 // Expects that |dir| has a trailing backslash. |dir| is modified so it |
| 149 // contains the full path that was tried. Caller must check for the return | 149 // contains the full path that was tried. Caller must check for the return |
| 150 // value not being null to determine if this path contains a valid dll. | 150 // value not being null to determine if this path contains a valid dll. |
| 151 HMODULE LoadChromeWithDirectory(string16* dir) { | 151 HMODULE LoadChromeWithDirectory(base::string16* dir) { |
| 152 ::SetCurrentDirectoryW(dir->c_str()); | 152 ::SetCurrentDirectoryW(dir->c_str()); |
| 153 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); | 153 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); |
| 154 #if !defined(CHROME_MULTIPLE_DLL) | 154 #if !defined(CHROME_MULTIPLE_DLL) |
| 155 const wchar_t* dll_name = installer::kChromeDll; | 155 const wchar_t* dll_name = installer::kChromeDll; |
| 156 #else | 156 #else |
| 157 const wchar_t* dll_name = | 157 const wchar_t* dll_name = |
| 158 cmd_line.HasSwitch(switches::kProcessType) && | 158 cmd_line.HasSwitch(switches::kProcessType) && |
| 159 cmd_line.GetSwitchValueASCII(switches::kProcessType) != "service" | 159 cmd_line.GetSwitchValueASCII(switches::kProcessType) != "service" |
| 160 ? installer::kChromeChildDll | 160 ? installer::kChromeChildDll |
| 161 : installer::kChromeDll; | 161 : installer::kChromeDll; |
| 162 #endif | 162 #endif |
| 163 dir->append(dll_name); | 163 dir->append(dll_name); |
| 164 | 164 |
| 165 #if !defined(WIN_DISABLE_PREREAD) | 165 #if !defined(WIN_DISABLE_PREREAD) |
| 166 // We pre-read the binary to warm the memory caches (fewer hard faults to | 166 // We pre-read the binary to warm the memory caches (fewer hard faults to |
| 167 // page parts of the binary in). | 167 // page parts of the binary in). |
| 168 if (!cmd_line.HasSwitch(switches::kProcessType)) { | 168 if (!cmd_line.HasSwitch(switches::kProcessType)) { |
| 169 const size_t kStepSize = 1024 * 1024; | 169 const size_t kStepSize = 1024 * 1024; |
| 170 size_t percentage = InitPreReadPercentage(); | 170 size_t percentage = InitPreReadPercentage(); |
| 171 ImagePreReader::PartialPreReadImage(dir->c_str(), percentage, kStepSize); | 171 ImagePreReader::PartialPreReadImage(dir->c_str(), percentage, kStepSize); |
| 172 } | 172 } |
| 173 #endif | 173 #endif |
| 174 | 174 |
| 175 return ::LoadLibraryExW(dir->c_str(), NULL, | 175 return ::LoadLibraryExW(dir->c_str(), NULL, |
| 176 LOAD_WITH_ALTERED_SEARCH_PATH); | 176 LOAD_WITH_ALTERED_SEARCH_PATH); |
| 177 } | 177 } |
| 178 | 178 |
| 179 void RecordDidRun(const string16& dll_path) { | 179 void RecordDidRun(const base::string16& dll_path) { |
| 180 bool system_level = !InstallUtil::IsPerUserInstall(dll_path.c_str()); | 180 bool system_level = !InstallUtil::IsPerUserInstall(dll_path.c_str()); |
| 181 GoogleUpdateSettings::UpdateDidRunState(true, system_level); | 181 GoogleUpdateSettings::UpdateDidRunState(true, system_level); |
| 182 } | 182 } |
| 183 | 183 |
| 184 void ClearDidRun(const string16& dll_path) { | 184 void ClearDidRun(const base::string16& dll_path) { |
| 185 bool system_level = !InstallUtil::IsPerUserInstall(dll_path.c_str()); | 185 bool system_level = !InstallUtil::IsPerUserInstall(dll_path.c_str()); |
| 186 GoogleUpdateSettings::UpdateDidRunState(false, system_level); | 186 GoogleUpdateSettings::UpdateDidRunState(false, system_level); |
| 187 } | 187 } |
| 188 | 188 |
| 189 } // namespace | 189 } // namespace |
| 190 | 190 |
| 191 string16 GetExecutablePath() { | 191 base::string16 GetExecutablePath() { |
| 192 wchar_t path[MAX_PATH]; | 192 wchar_t path[MAX_PATH]; |
| 193 ::GetModuleFileNameW(NULL, path, MAX_PATH); | 193 ::GetModuleFileNameW(NULL, path, MAX_PATH); |
| 194 if (!::PathRemoveFileSpecW(path)) | 194 if (!::PathRemoveFileSpecW(path)) |
| 195 return string16(); | 195 return base::string16(); |
| 196 string16 exe_path(path); | 196 base::string16 exe_path(path); |
| 197 return exe_path.append(1, L'\\'); | 197 return exe_path.append(1, L'\\'); |
| 198 } | 198 } |
| 199 | 199 |
| 200 string16 GetCurrentModuleVersion() { | 200 base::string16 GetCurrentModuleVersion() { |
| 201 scoped_ptr<FileVersionInfo> file_version_info( | 201 scoped_ptr<FileVersionInfo> file_version_info( |
| 202 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); | 202 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); |
| 203 if (file_version_info.get()) { | 203 if (file_version_info.get()) { |
| 204 string16 version_string(file_version_info->file_version()); | 204 base::string16 version_string(file_version_info->file_version()); |
| 205 if (Version(WideToASCII(version_string)).IsValid()) | 205 if (Version(WideToASCII(version_string)).IsValid()) |
| 206 return version_string; | 206 return version_string; |
| 207 } | 207 } |
| 208 return string16(); | 208 return base::string16(); |
| 209 } | 209 } |
| 210 | 210 |
| 211 //============================================================================= | 211 //============================================================================= |
| 212 | 212 |
| 213 MainDllLoader::MainDllLoader() : dll_(NULL) { | 213 MainDllLoader::MainDllLoader() : dll_(NULL) { |
| 214 } | 214 } |
| 215 | 215 |
| 216 MainDllLoader::~MainDllLoader() { | 216 MainDllLoader::~MainDllLoader() { |
| 217 } | 217 } |
| 218 | 218 |
| 219 // Loading chrome is an interesting affair. First we try loading from the | 219 // Loading chrome is an interesting affair. First we try loading from the |
| 220 // current directory to support run-what-you-compile and other development | 220 // current directory to support run-what-you-compile and other development |
| 221 // scenarios. | 221 // scenarios. |
| 222 // If that fails then we look at the --chrome-version command line flag to | 222 // If that fails then we look at the --chrome-version command line flag to |
| 223 // determine if we should stick with an older dll version even if a new one is | 223 // determine if we should stick with an older dll version even if a new one is |
| 224 // available to support upgrade-in-place scenarios. | 224 // available to support upgrade-in-place scenarios. |
| 225 // If that fails then finally we look at the version resource in the current | 225 // If that fails then finally we look at the version resource in the current |
| 226 // module. This is the expected path for chrome.exe browser instances in an | 226 // module. This is the expected path for chrome.exe browser instances in an |
| 227 // installed build. | 227 // installed build. |
| 228 HMODULE MainDllLoader::Load(string16* out_version, string16* out_file) { | 228 HMODULE MainDllLoader::Load(base::string16* out_version, |
| 229 base::string16* out_file) { |
| 229 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); | 230 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess(); |
| 230 const string16 dir(GetExecutablePath()); | 231 const base::string16 dir(GetExecutablePath()); |
| 231 *out_file = dir; | 232 *out_file = dir; |
| 232 HMODULE dll = LoadChromeWithDirectory(out_file); | 233 HMODULE dll = LoadChromeWithDirectory(out_file); |
| 233 if (!dll) { | 234 if (!dll) { |
| 234 // Loading from same directory (for developers) failed. | 235 // Loading from same directory (for developers) failed. |
| 235 string16 version_string; | 236 base::string16 version_string; |
| 236 if (cmd_line.HasSwitch(switches::kChromeVersion)) { | 237 if (cmd_line.HasSwitch(switches::kChromeVersion)) { |
| 237 // This is used to support Chrome Frame, see http://crbug.com/88589. | 238 // This is used to support Chrome Frame, see http://crbug.com/88589. |
| 238 version_string = cmd_line.GetSwitchValueNative(switches::kChromeVersion); | 239 version_string = cmd_line.GetSwitchValueNative(switches::kChromeVersion); |
| 239 | 240 |
| 240 if (!Version(WideToASCII(version_string)).IsValid()) { | 241 if (!Version(WideToASCII(version_string)).IsValid()) { |
| 241 // If a bogus command line flag was given, then abort. | 242 // If a bogus command line flag was given, then abort. |
| 242 LOG(ERROR) << "Invalid command line version: " << version_string; | 243 LOG(ERROR) << "Invalid command line version: " << version_string; |
| 243 return NULL; | 244 return NULL; |
| 244 } | 245 } |
| 245 } | 246 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 267 DCHECK(dll); | 268 DCHECK(dll); |
| 268 | 269 |
| 269 return dll; | 270 return dll; |
| 270 } | 271 } |
| 271 | 272 |
| 272 // Launching is a matter of loading the right dll, setting the CHROME_VERSION | 273 // Launching is a matter of loading the right dll, setting the CHROME_VERSION |
| 273 // environment variable and just calling the entry point. Derived classes can | 274 // environment variable and just calling the entry point. Derived classes can |
| 274 // add custom code in the OnBeforeLaunch callback. | 275 // add custom code in the OnBeforeLaunch callback. |
| 275 int MainDllLoader::Launch(HINSTANCE instance, | 276 int MainDllLoader::Launch(HINSTANCE instance, |
| 276 sandbox::SandboxInterfaceInfo* sbox_info) { | 277 sandbox::SandboxInterfaceInfo* sbox_info) { |
| 277 string16 version; | 278 base::string16 version; |
| 278 string16 file; | 279 base::string16 file; |
| 279 dll_ = Load(&version, &file); | 280 dll_ = Load(&version, &file); |
| 280 if (!dll_) | 281 if (!dll_) |
| 281 return chrome::RESULT_CODE_MISSING_DATA; | 282 return chrome::RESULT_CODE_MISSING_DATA; |
| 282 | 283 |
| 283 scoped_ptr<base::Environment> env(base::Environment::Create()); | 284 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 284 env->SetVar(chrome::kChromeVersionEnvVar, WideToUTF8(version)); | 285 env->SetVar(chrome::kChromeVersionEnvVar, WideToUTF8(version)); |
| 285 // TODO(erikwright): Remove this when http://crbug.com/174953 is fixed and | 286 // TODO(erikwright): Remove this when http://crbug.com/174953 is fixed and |
| 286 // widely deployed. | 287 // widely deployed. |
| 287 env->UnSetVar(env_vars::kGoogleUpdateIsMachineEnvVar); | 288 env->UnSetVar(env_vars::kGoogleUpdateIsMachineEnvVar); |
| 288 | 289 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 311 << "RelaunchChromeBrowserWithNewCommandLineIfNeeded"; | 312 << "RelaunchChromeBrowserWithNewCommandLineIfNeeded"; |
| 312 } else { | 313 } else { |
| 313 relaunch_function(); | 314 relaunch_function(); |
| 314 } | 315 } |
| 315 } | 316 } |
| 316 | 317 |
| 317 //============================================================================= | 318 //============================================================================= |
| 318 | 319 |
| 319 class ChromeDllLoader : public MainDllLoader { | 320 class ChromeDllLoader : public MainDllLoader { |
| 320 public: | 321 public: |
| 321 virtual string16 GetRegistryPath() { | 322 virtual base::string16 GetRegistryPath() { |
| 322 string16 key(google_update::kRegPathClients); | 323 base::string16 key(google_update::kRegPathClients); |
| 323 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 324 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| 324 key.append(L"\\").append(dist->GetAppGuid()); | 325 key.append(L"\\").append(dist->GetAppGuid()); |
| 325 return key; | 326 return key; |
| 326 } | 327 } |
| 327 | 328 |
| 328 virtual void OnBeforeLaunch(const string16& dll_path) { | 329 virtual void OnBeforeLaunch(const base::string16& dll_path) { |
| 329 RecordDidRun(dll_path); | 330 RecordDidRun(dll_path); |
| 330 } | 331 } |
| 331 | 332 |
| 332 virtual int OnBeforeExit(int return_code, const string16& dll_path) { | 333 virtual int OnBeforeExit(int return_code, const base::string16& dll_path) { |
| 333 // NORMAL_EXIT_CANCEL is used for experiments when the user cancels | 334 // NORMAL_EXIT_CANCEL is used for experiments when the user cancels |
| 334 // so we need to reset the did_run signal so omaha does not count | 335 // so we need to reset the did_run signal so omaha does not count |
| 335 // this run as active usage. | 336 // this run as active usage. |
| 336 if (chrome::RESULT_CODE_NORMAL_EXIT_CANCEL == return_code) { | 337 if (chrome::RESULT_CODE_NORMAL_EXIT_CANCEL == return_code) { |
| 337 ClearDidRun(dll_path); | 338 ClearDidRun(dll_path); |
| 338 } | 339 } |
| 339 return return_code; | 340 return return_code; |
| 340 } | 341 } |
| 341 }; | 342 }; |
| 342 | 343 |
| 343 //============================================================================= | 344 //============================================================================= |
| 344 | 345 |
| 345 class ChromiumDllLoader : public MainDllLoader { | 346 class ChromiumDllLoader : public MainDllLoader { |
| 346 public: | 347 public: |
| 347 virtual string16 GetRegistryPath() { | 348 virtual base::string16 GetRegistryPath() { |
| 348 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 349 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| 349 return dist->GetVersionKey(); | 350 return dist->GetVersionKey(); |
| 350 } | 351 } |
| 351 }; | 352 }; |
| 352 | 353 |
| 353 MainDllLoader* MakeMainDllLoader() { | 354 MainDllLoader* MakeMainDllLoader() { |
| 354 #if defined(GOOGLE_CHROME_BUILD) | 355 #if defined(GOOGLE_CHROME_BUILD) |
| 355 return new ChromeDllLoader(); | 356 return new ChromeDllLoader(); |
| 356 #else | 357 #else |
| 357 return new ChromiumDllLoader(); | 358 return new ChromiumDllLoader(); |
| 358 #endif | 359 #endif |
| 359 } | 360 } |
| OLD | NEW |