Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: chrome/installer/util/install_util.cc

Issue 10446095: Move ProgramCompare from setup_util to install_util. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: move tests Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 // See the corresponding header file for description of the functions in this 5 // See the corresponding header file for description of the functions in this
6 // file. 6 // file.
7 7
8 #include "chrome/installer/util/install_util.h" 8 #include "chrome/installer/util/install_util.h"
9 9
10 #include <shellapi.h> 10 #include <shellapi.h>
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 } 172 }
173 173
174 Version* InstallUtil::GetChromeVersion(BrowserDistribution* dist, 174 Version* InstallUtil::GetChromeVersion(BrowserDistribution* dist,
175 bool system_install) { 175 bool system_install) {
176 DCHECK(dist); 176 DCHECK(dist);
177 RegKey key; 177 RegKey key;
178 HKEY reg_root = (system_install) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 178 HKEY reg_root = (system_install) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
179 LONG result = key.Open(reg_root, dist->GetVersionKey().c_str(), 179 LONG result = key.Open(reg_root, dist->GetVersionKey().c_str(),
180 KEY_QUERY_VALUE); 180 KEY_QUERY_VALUE);
181 181
182 std::wstring version_str; 182 string16 version_str;
183 if (result == ERROR_SUCCESS) 183 if (result == ERROR_SUCCESS)
184 result = key.ReadValue(google_update::kRegVersionField, &version_str); 184 result = key.ReadValue(google_update::kRegVersionField, &version_str);
185 185
186 Version* ret = NULL; 186 Version* ret = NULL;
187 if (result == ERROR_SUCCESS && !version_str.empty()) { 187 if (result == ERROR_SUCCESS && !version_str.empty()) {
188 VLOG(1) << "Existing " << dist->GetApplicationName() 188 VLOG(1) << "Existing " << dist->GetApplicationName()
189 << " version found " << version_str; 189 << " version found " << version_str;
190 ret = Version::GetVersionFromString(WideToASCII(version_str)); 190 ret = Version::GetVersionFromString(WideToASCII(version_str));
191 } else { 191 } else {
192 DCHECK_EQ(ERROR_FILE_NOT_FOUND, result); 192 DCHECK_EQ(ERROR_FILE_NOT_FOUND, result);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 // We do not support Win2K or older, or XP without service pack 2. 228 // We do not support Win2K or older, or XP without service pack 2.
229 VLOG(1) << base::SysInfo::OperatingSystemName() << ' ' 229 VLOG(1) << base::SysInfo::OperatingSystemName() << ' '
230 << base::SysInfo::OperatingSystemVersion(); 230 << base::SysInfo::OperatingSystemVersion();
231 base::win::Version version = base::win::GetVersion(); 231 base::win::Version version = base::win::GetVersion();
232 return (version > base::win::VERSION_XP) || 232 return (version > base::win::VERSION_XP) ||
233 ((version == base::win::VERSION_XP) && 233 ((version == base::win::VERSION_XP) &&
234 (base::win::OSInfo::GetInstance()->service_pack().major >= 2)); 234 (base::win::OSInfo::GetInstance()->service_pack().major >= 2));
235 } 235 }
236 236
237 void InstallUtil::AddInstallerResultItems(bool system_install, 237 void InstallUtil::AddInstallerResultItems(bool system_install,
238 const std::wstring& state_key, 238 const string16& state_key,
239 installer::InstallStatus status, 239 installer::InstallStatus status,
240 int string_resource_id, 240 int string_resource_id,
241 const std::wstring* const launch_cmd, 241 const string16* const launch_cmd,
242 WorkItemList* install_list) { 242 WorkItemList* install_list) {
243 DCHECK(install_list); 243 DCHECK(install_list);
244 const HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 244 const HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
245 DWORD installer_result = (GetInstallReturnCode(status) == 0) ? 0 : 1; 245 DWORD installer_result = (GetInstallReturnCode(status) == 0) ? 0 : 1;
246 install_list->AddCreateRegKeyWorkItem(root, state_key); 246 install_list->AddCreateRegKeyWorkItem(root, state_key);
247 install_list->AddSetRegValueWorkItem(root, state_key, 247 install_list->AddSetRegValueWorkItem(root, state_key,
248 installer::kInstallerResult, 248 installer::kInstallerResult,
249 installer_result, true); 249 installer_result, true);
250 install_list->AddSetRegValueWorkItem(root, state_key, 250 install_list->AddSetRegValueWorkItem(root, state_key,
251 installer::kInstallerError, 251 installer::kInstallerError,
252 static_cast<DWORD>(status), true); 252 static_cast<DWORD>(status), true);
253 if (string_resource_id != 0) { 253 if (string_resource_id != 0) {
254 std::wstring msg = installer::GetLocalizedString(string_resource_id); 254 string16 msg = installer::GetLocalizedString(string_resource_id);
255 install_list->AddSetRegValueWorkItem(root, state_key, 255 install_list->AddSetRegValueWorkItem(root, state_key,
256 installer::kInstallerResultUIString, msg, true); 256 installer::kInstallerResultUIString, msg, true);
257 } 257 }
258 if (launch_cmd != NULL && !launch_cmd->empty()) { 258 if (launch_cmd != NULL && !launch_cmd->empty()) {
259 install_list->AddSetRegValueWorkItem(root, state_key, 259 install_list->AddSetRegValueWorkItem(root, state_key,
260 installer::kInstallerSuccessLaunchCmdLine, *launch_cmd, true); 260 installer::kInstallerSuccessLaunchCmdLine, *launch_cmd, true);
261 } 261 }
262 } 262 }
263 263
264 void InstallUtil::UpdateInstallerStage(bool system_install, 264 void InstallUtil::UpdateInstallerStage(bool system_install,
265 const std::wstring& state_key_path, 265 const string16& state_key_path,
266 installer::InstallerStage stage) { 266 installer::InstallerStage stage) {
267 DCHECK_LE(static_cast<installer::InstallerStage>(0), stage); 267 DCHECK_LE(static_cast<installer::InstallerStage>(0), stage);
268 DCHECK_GT(installer::NUM_STAGES, stage); 268 DCHECK_GT(installer::NUM_STAGES, stage);
269 const HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 269 const HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
270 RegKey state_key; 270 RegKey state_key;
271 LONG result = state_key.Open(root, state_key_path.c_str(), 271 LONG result = state_key.Open(root, state_key_path.c_str(),
272 KEY_QUERY_VALUE | KEY_SET_VALUE); 272 KEY_QUERY_VALUE | KEY_SET_VALUE);
273 if (result == ERROR_SUCCESS) { 273 if (result == ERROR_SUCCESS) {
274 if (stage == installer::NO_STAGE) { 274 if (stage == installer::NO_STAGE) {
275 result = state_key.DeleteValue(installer::kInstallerExtraCode1); 275 result = state_key.DeleteValue(installer::kInstallerExtraCode1);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 bool CheckIsChromeSxSProcess() { 321 bool CheckIsChromeSxSProcess() {
322 CommandLine* command_line = CommandLine::ForCurrentProcess(); 322 CommandLine* command_line = CommandLine::ForCurrentProcess();
323 CHECK(command_line); 323 CHECK(command_line);
324 324
325 if (command_line->HasSwitch(installer::switches::kChromeSxS)) 325 if (command_line->HasSwitch(installer::switches::kChromeSxS))
326 return true; 326 return true;
327 327
328 // Also return true if we are running from Chrome SxS installed path. 328 // Also return true if we are running from Chrome SxS installed path.
329 FilePath exe_dir; 329 FilePath exe_dir;
330 PathService::Get(base::DIR_EXE, &exe_dir); 330 PathService::Get(base::DIR_EXE, &exe_dir);
331 std::wstring chrome_sxs_dir(installer::kGoogleChromeInstallSubDir2); 331 string16 chrome_sxs_dir(installer::kGoogleChromeInstallSubDir2);
332 chrome_sxs_dir.append(installer::kSxSSuffix); 332 chrome_sxs_dir.append(installer::kSxSSuffix);
333 return FilePath::CompareEqualIgnoreCase(exe_dir.BaseName().value(), 333 return FilePath::CompareEqualIgnoreCase(exe_dir.BaseName().value(),
334 installer::kInstallBinaryDir) && 334 installer::kInstallBinaryDir) &&
335 FilePath::CompareEqualIgnoreCase(exe_dir.DirName().BaseName().value(), 335 FilePath::CompareEqualIgnoreCase(exe_dir.DirName().BaseName().value(),
336 chrome_sxs_dir); 336 chrome_sxs_dir);
337 } 337 }
338 338
339 bool InstallUtil::IsChromeSxSProcess() { 339 bool InstallUtil::IsChromeSxSProcess() {
340 static bool sxs = CheckIsChromeSxSProcess(); 340 static bool sxs = CheckIsChromeSxSProcess();
341 return sxs; 341 return sxs;
(...skipping 14 matching lines...) Expand all
356 .Append(installer::kDelegateExecuteExe)); 356 .Append(installer::kDelegateExecuteExe));
357 found = file_util::PathExists(handler); 357 found = file_util::PathExists(handler);
358 } 358 }
359 return found; 359 return found;
360 } 360 }
361 361
362 // This method tries to delete a registry key and logs an error message 362 // This method tries to delete a registry key and logs an error message
363 // in case of failure. It returns true if deletion is successful, 363 // in case of failure. It returns true if deletion is successful,
364 // otherwise false. 364 // otherwise false.
365 bool InstallUtil::DeleteRegistryKey(HKEY root_key, 365 bool InstallUtil::DeleteRegistryKey(HKEY root_key,
366 const std::wstring& key_path) { 366 const string16& key_path) {
367 VLOG(1) << "Deleting registry key " << key_path; 367 VLOG(1) << "Deleting registry key " << key_path;
368 LONG result = ::SHDeleteKey(root_key, key_path.c_str()); 368 LONG result = ::SHDeleteKey(root_key, key_path.c_str());
369 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) { 369 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
370 LOG(ERROR) << "Failed to delete registry key: " << key_path 370 LOG(ERROR) << "Failed to delete registry key: " << key_path
371 << " error: " << result; 371 << " error: " << result;
372 return false; 372 return false;
373 } 373 }
374 return true; 374 return true;
375 } 375 }
376 376
377 // This method tries to delete a registry value and logs an error message 377 // This method tries to delete a registry value and logs an error message
378 // in case of failure. It returns true if deletion is successful, 378 // in case of failure. It returns true if deletion is successful,
379 // otherwise false. 379 // otherwise false.
380 bool InstallUtil::DeleteRegistryValue(HKEY reg_root, 380 bool InstallUtil::DeleteRegistryValue(HKEY reg_root,
381 const std::wstring& key_path, 381 const string16& key_path,
382 const std::wstring& value_name) { 382 const string16& value_name) {
383 RegKey key(reg_root, key_path.c_str(), KEY_ALL_ACCESS); 383 RegKey key(reg_root, key_path.c_str(), KEY_ALL_ACCESS);
384 VLOG(1) << "Deleting registry value " << value_name; 384 VLOG(1) << "Deleting registry value " << value_name;
385 if (key.HasValue(value_name.c_str())) { 385 if (key.HasValue(value_name.c_str())) {
386 LONG result = key.DeleteValue(value_name.c_str()); 386 LONG result = key.DeleteValue(value_name.c_str());
387 if (result != ERROR_SUCCESS) { 387 if (result != ERROR_SUCCESS) {
388 LOG(ERROR) << "Failed to delete registry value: " << value_name 388 LOG(ERROR) << "Failed to delete registry value: " << value_name
389 << " error: " << result; 389 << " error: " << result;
390 return false; 390 return false;
391 } 391 }
392 } 392 }
393 return true; 393 return true;
394 } 394 }
395 395
396 // static 396 // static
397 InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryKeyIf( 397 InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryKeyIf(
398 HKEY root_key, 398 HKEY root_key,
399 const std::wstring& key_to_delete_path, 399 const string16& key_to_delete_path,
400 const std::wstring& key_to_test_path, 400 const string16& key_to_test_path,
401 const wchar_t* value_name, 401 const wchar_t* value_name,
402 const RegistryValuePredicate& predicate) { 402 const RegistryValuePredicate& predicate) {
403 DCHECK(root_key); 403 DCHECK(root_key);
404 DCHECK(value_name); 404 DCHECK(value_name);
405 ConditionalDeleteResult delete_result = NOT_FOUND; 405 ConditionalDeleteResult delete_result = NOT_FOUND;
406 RegKey key; 406 RegKey key;
407 std::wstring actual_value; 407 string16 actual_value;
408 if (key.Open(root_key, key_to_test_path.c_str(), 408 if (key.Open(root_key, key_to_test_path.c_str(),
409 KEY_QUERY_VALUE) == ERROR_SUCCESS && 409 KEY_QUERY_VALUE) == ERROR_SUCCESS &&
410 key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS && 410 key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS &&
411 predicate.Evaluate(actual_value)) { 411 predicate.Evaluate(actual_value)) {
412 key.Close(); 412 key.Close();
413 delete_result = DeleteRegistryKey(root_key, key_to_delete_path) 413 delete_result = DeleteRegistryKey(root_key, key_to_delete_path)
414 ? DELETED : DELETE_FAILED; 414 ? DELETED : DELETE_FAILED;
415 } 415 }
416 return delete_result; 416 return delete_result;
417 } 417 }
418 418
419 // static 419 // static
420 InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryValueIf( 420 InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryValueIf(
421 HKEY root_key, 421 HKEY root_key,
422 const wchar_t* key_path, 422 const wchar_t* key_path,
423 const wchar_t* value_name, 423 const wchar_t* value_name,
424 const RegistryValuePredicate& predicate) { 424 const RegistryValuePredicate& predicate) {
425 DCHECK(root_key); 425 DCHECK(root_key);
426 DCHECK(key_path); 426 DCHECK(key_path);
427 DCHECK(value_name); 427 DCHECK(value_name);
428 ConditionalDeleteResult delete_result = NOT_FOUND; 428 ConditionalDeleteResult delete_result = NOT_FOUND;
429 RegKey key; 429 RegKey key;
430 std::wstring actual_value; 430 string16 actual_value;
431 if (key.Open(root_key, key_path, 431 if (key.Open(root_key, key_path,
432 KEY_QUERY_VALUE | KEY_SET_VALUE) == ERROR_SUCCESS && 432 KEY_QUERY_VALUE | KEY_SET_VALUE) == ERROR_SUCCESS &&
433 key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS && 433 key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS &&
434 predicate.Evaluate(actual_value)) { 434 predicate.Evaluate(actual_value)) {
435 LONG result = key.DeleteValue(value_name); 435 LONG result = key.DeleteValue(value_name);
436 if (result != ERROR_SUCCESS) { 436 if (result != ERROR_SUCCESS) {
437 LOG(ERROR) << "Failed to delete registry value: " << value_name 437 LOG(ERROR) << "Failed to delete registry value: " << value_name
438 << " error: " << result; 438 << " error: " << result;
439 delete_result = DELETE_FAILED; 439 delete_result = DELETE_FAILED;
440 } 440 }
441 delete_result = DELETED; 441 delete_result = DELETED;
442 } 442 }
443 return delete_result; 443 return delete_result;
444 } 444 }
445 445
446 bool InstallUtil::ValueEquals::Evaluate(const std::wstring& value) const { 446 bool InstallUtil::ValueEquals::Evaluate(const string16& value) const {
447 return value == value_to_match_; 447 return value == value_to_match_;
448 } 448 }
449 449
450 // static 450 // static
451 int InstallUtil::GetInstallReturnCode(installer::InstallStatus status) { 451 int InstallUtil::GetInstallReturnCode(installer::InstallStatus status) {
452 switch (status) { 452 switch (status) {
453 case installer::FIRST_INSTALL_SUCCESS: 453 case installer::FIRST_INSTALL_SUCCESS:
454 case installer::INSTALL_REPAIRED: 454 case installer::INSTALL_REPAIRED:
455 case installer::NEW_VERSION_UPDATED: 455 case installer::NEW_VERSION_UPDATED:
456 case installer::IN_USE_UPDATED: 456 case installer::IN_USE_UPDATED:
457 return 0; 457 return 0;
458 default: 458 default:
459 return status; 459 return status;
460 } 460 }
461 } 461 }
462 462
463 // static 463 // static
464 void InstallUtil::MakeUninstallCommand(const std::wstring& program, 464 void InstallUtil::MakeUninstallCommand(const string16& program,
465 const std::wstring& arguments, 465 const string16& arguments,
466 CommandLine* command_line) { 466 CommandLine* command_line) {
467 *command_line = CommandLine::FromString(L"\"" + program + L"\" " + arguments); 467 *command_line = CommandLine::FromString(L"\"" + program + L"\" " + arguments);
468 } 468 }
469 469
470 std::wstring InstallUtil::GetCurrentDate() { 470 string16 InstallUtil::GetCurrentDate() {
471 static const wchar_t kDateFormat[] = L"yyyyMMdd"; 471 static const wchar_t kDateFormat[] = L"yyyyMMdd";
472 wchar_t date_str[arraysize(kDateFormat)] = {0}; 472 wchar_t date_str[arraysize(kDateFormat)] = {0};
473 int len = GetDateFormatW(LOCALE_INVARIANT, 0, NULL, kDateFormat, 473 int len = GetDateFormatW(LOCALE_INVARIANT, 0, NULL, kDateFormat,
474 date_str, arraysize(date_str)); 474 date_str, arraysize(date_str));
475 if (len) { 475 if (len) {
476 --len; // Subtract terminating \0. 476 --len; // Subtract terminating \0.
477 } else { 477 } else {
478 PLOG(DFATAL) << "GetDateFormat"; 478 PLOG(DFATAL) << "GetDateFormat";
479 } 479 }
480 480
481 return std::wstring(date_str, len); 481 return string16(date_str, len);
482 } 482 }
483
484 // Open |path| with minimal access to obtain information about it, returning
485 // true and populating |handle| on success.
486 // static
487 bool InstallUtil::ProgramCompare::OpenForInfo(const FilePath& path,
488 base::win::ScopedHandle* handle) {
489 DCHECK(handle);
490 handle->Set(base::CreatePlatformFile(path, base::PLATFORM_FILE_OPEN, NULL,
491 NULL));
492 return handle->IsValid();
493 }
494
495 // Populate |info| for |handle|, returning true on success.
496 // static
497 bool InstallUtil::ProgramCompare::GetInfo(const base::win::ScopedHandle& handle,
498 BY_HANDLE_FILE_INFORMATION* info) {
499 DCHECK(handle.IsValid());
500 return GetFileInformationByHandle(
501 const_cast<base::win::ScopedHandle&>(handle), info) != 0;
502 }
503
504 InstallUtil::ProgramCompare::ProgramCompare(const FilePath& path_to_match)
505 : path_to_match_(path_to_match),
506 file_handle_(base::kInvalidPlatformFileValue),
507 file_info_() {
508 DCHECK(!path_to_match_.empty());
509 if (!OpenForInfo(path_to_match_, &file_handle_)) {
510 PLOG(WARNING) << "Failed opening " << path_to_match_.value()
511 << "; falling back to path string comparisons.";
512 } else if (!GetInfo(file_handle_, &file_info_)) {
513 PLOG(WARNING) << "Failed getting information for "
514 << path_to_match_.value()
515 << "; falling back to path string comparisons.";
516 file_handle_.Close();
517 }
518 }
519
520 InstallUtil::ProgramCompare::~ProgramCompare() {
521 }
522
523 bool InstallUtil::ProgramCompare::Evaluate(const string16& value) const {
524 // Suss out the exe portion of the value, which is expected to be a command
525 // line kinda (or exactly) like:
526 // "c:\foo\bar\chrome.exe" -- "%1"
527 FilePath program(CommandLine::FromString(value).GetProgram());
528 if (program.empty()) {
529 LOG(WARNING) << "Failed to parse an executable name from command line: \""
530 << value << "\"";
531 return false;
532 }
533
534 // Try the simple thing first: do the paths happen to match?
535 if (FilePath::CompareEqualIgnoreCase(path_to_match_.value(), program.value()))
536 return true;
537
538 // If the paths don't match and we couldn't open the expected file, we've done
539 // our best.
540 if (!file_handle_.IsValid())
541 return false;
542
543 // Open the program and see if it references the expected file.
544 base::win::ScopedHandle handle;
545 BY_HANDLE_FILE_INFORMATION info = {};
546
547 return (OpenForInfo(program, &handle) &&
548 GetInfo(handle, &info) &&
549 info.dwVolumeSerialNumber == file_info_.dwVolumeSerialNumber &&
550 info.nFileIndexHigh == file_info_.nFileIndexHigh &&
551 info.nFileIndexLow == file_info_.nFileIndexLow);
552 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698