summaryrefslogtreecommitdiffstats
path: root/chrome/installer/util/helper.cc
blob: af18e9efc96c155912da82874e8a2e1369743e2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <windows.h>

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/scoped_ptr.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/delete_tree_work_item.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/logging_installer.h"
#include "chrome/installer/util/util_constants.h"
#include "chrome/installer/util/version.h"
#include "chrome/installer/util/work_item_list.h"

namespace {

std::wstring GetChromeInstallBasePath(bool system_install,
                                      const wchar_t* subpath) {
  FilePath install_path;
  if (system_install) {
    PathService::Get(base::DIR_PROGRAM_FILES, &install_path);
  } else {
    PathService::Get(base::DIR_LOCAL_APP_DATA, &install_path);
  }
  if (!install_path.empty()) {
    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    install_path = install_path.Append(dist->GetInstallSubDir());
    install_path = install_path.Append(subpath);
  }
  return install_path.ToWStringHack();
}

}  // namespace

std::wstring installer::GetChromeInstallPath(bool system_install) {
  return GetChromeInstallBasePath(system_install,
                                  installer_util::kInstallBinaryDir);
}

std::wstring installer::GetChromeUserDataPath() {
  return GetChromeInstallBasePath(false, installer_util::kInstallUserDataDir);
}

bool installer::LaunchChrome(bool system_install) {
  std::wstring chrome_exe(L"\"");
  chrome_exe.append(installer::GetChromeInstallPath(system_install));
  file_util::AppendToPath(&chrome_exe, installer_util::kChromeExe);
  chrome_exe.append(L"\"");
  return base::LaunchApp(chrome_exe, false, false, NULL);
}

bool installer::LaunchChromeAndWaitForResult(bool system_install,
                                             const std::wstring& options,
                                             int32* exit_code) {
  std::wstring chrome_exe(installer::GetChromeInstallPath(system_install));
  if (chrome_exe.empty())
    return false;
  file_util::AppendToPath(&chrome_exe, installer_util::kChromeExe);

  std::wstring command_line(L"\"" + chrome_exe + L"\"");
  command_line.append(options);
  STARTUPINFOW si = {sizeof(si)};
  PROCESS_INFORMATION pi = {0};
  if (!::CreateProcessW(chrome_exe.c_str(),
                        const_cast<wchar_t*>(command_line.c_str()),
                        NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL,
                        &si, &pi)) {
    return false;
  }

  DWORD wr = ::WaitForSingleObject(pi.hProcess, INFINITE);
  DWORD ret;
  if (::GetExitCodeProcess(pi.hProcess, &ret) == 0)
    return false;

  if (exit_code)
    *exit_code = ret;

  ::CloseHandle(pi.hProcess);
  ::CloseHandle(pi.hThread);
  return true;
}

void installer::RemoveOldVersionDirs(const std::wstring& chrome_path,
                                     const std::wstring& latest_version_str) {
  std::wstring search_path(chrome_path);
  file_util::AppendToPath(&search_path, L"*");

  WIN32_FIND_DATA find_file_data;
  HANDLE file_handle = FindFirstFile(search_path.c_str(), &find_file_data);
  if (file_handle == INVALID_HANDLE_VALUE)
    return;

  BOOL ret = TRUE;
  scoped_ptr<installer::Version> version;
  scoped_ptr<installer::Version> latest_version(
      installer::Version::GetVersionFromString(latest_version_str));

  // We try to delete all directories whose versions are lower than
  // latest_version.
  while (ret) {
    if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
      LOG(INFO) << "directory found: " << find_file_data.cFileName;
      version.reset(
          installer::Version::GetVersionFromString(find_file_data.cFileName));
      if (version.get() && latest_version->IsHigherThan(version.get())) {
        std::wstring remove_dir(chrome_path);
        file_util::AppendToPath(&remove_dir, find_file_data.cFileName);
        std::wstring chrome_dll_path(remove_dir);
        file_util::AppendToPath(&chrome_dll_path, installer_util::kChromeDll);
        LOG(INFO) << "deleting directory " << remove_dir;
        scoped_ptr<DeleteTreeWorkItem> item;
        item.reset(WorkItem::CreateDeleteTreeWorkItem(remove_dir,
                                                      chrome_dll_path));
        item->Do();
      }
    }
    ret = FindNextFile(file_handle, &find_file_data);
  }

  FindClose(file_handle);
}