Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / installer / launcher_support / chrome_launcher_support.cc
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
3 // found in the LICENSE file.
4
5 #include "chrome/installer/launcher_support/chrome_launcher_support.h"
6
7 #include <windows.h>
8
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/strings/string16.h"
12 #include "base/win/registry.h"
13
14 namespace chrome_launcher_support {
15
16 namespace {
17
18 // TODO(huangs) Refactor the constants: http://crbug.com/148538
19 #if defined(GOOGLE_CHROME_BUILD)
20 const wchar_t kInstallationRegKey[] =
21     L"Software\\Google\\Update\\ClientState";
22
23 // Copied from chrome_appid.cc.
24 const wchar_t kBinariesAppGuid[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
25
26 // Copied from google_chrome_distribution.cc.
27 const wchar_t kBrowserAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
28
29 // Copied frome google_chrome_sxs_distribution.cc.
30 const wchar_t kSxSBrowserAppGuid[] = L"{4ea16ac7-fd5a-47c3-875b-dbf4a2008c20}";
31 #else
32 const wchar_t kInstallationRegKey[] = L"Software\\Chromium";
33 #endif
34
35 // Copied from util_constants.cc.
36 const wchar_t kChromeExe[] = L"chrome.exe";
37 const wchar_t kUninstallStringField[] = L"UninstallString";
38
39 // Reads a string value from the specified product's registry key. Returns true
40 // iff the value is present and successfully read.
41 bool GetClientStateValue(InstallationLevel level,
42                          const wchar_t* app_guid,
43                          const wchar_t* value_name,
44                          base::string16* value) {
45   HKEY root_key = (level == USER_LEVEL_INSTALLATION) ?
46       HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
47   base::string16 subkey(kInstallationRegKey);
48   if (app_guid)
49     subkey.append(1, L'\\').append(app_guid);
50   base::win::RegKey reg_key;
51   // Google Update always uses 32bit hive.
52   if (reg_key.Open(root_key, subkey.c_str(),
53                    KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) {
54     if (reg_key.ReadValue(value_name, value) == ERROR_SUCCESS) {
55       return true;
56     }
57   }
58   return false;
59 }
60
61 // Reads the path to setup.exe from the value "UninstallString" within the
62 // specified product's registry key. Returns an empty FilePath if an error
63 // occurs or the product is not installed at the specified level.
64 base::FilePath GetSetupExeFromRegistry(InstallationLevel level,
65                                        const wchar_t* app_guid) {
66   base::string16 uninstall;
67   if (GetClientStateValue(level, app_guid, kUninstallStringField, &uninstall)) {
68     base::FilePath setup_exe_path(uninstall);
69     if (base::PathExists(setup_exe_path))
70       return setup_exe_path;
71   }
72   return base::FilePath();
73 }
74
75 // Returns the path to an existing setup.exe at the specified level, if it can
76 // be found via the registry.
77 base::FilePath GetSetupExeForInstallationLevel(InstallationLevel level) {
78   base::FilePath setup_exe_path;
79 #if defined(GOOGLE_CHROME_BUILD)
80   // Look in the registry for Chrome Binaries first.
81   setup_exe_path = GetSetupExeFromRegistry(level, kBinariesAppGuid);
82   // If the above fails, look in the registry for Chrome next.
83   if (setup_exe_path.empty())
84     setup_exe_path = GetSetupExeFromRegistry(level, kBrowserAppGuid);
85   // If we fail again, then setup_exe_path would be empty.
86 #else
87   // For Chromium, there are no GUIDs. Just look in the Chromium registry key.
88   setup_exe_path = GetSetupExeFromRegistry(level, nullptr);
89 #endif
90
91   return setup_exe_path;
92 }
93
94 // Returns the path to an installed |exe_file| (e.g. chrome.exe) at the
95 // specified level, given |setup_exe_path| from the registry.  Returns empty
96 // base::FilePath if none found, or if |setup_exe_path| is empty.
97 base::FilePath FindExeRelativeToSetupExe(const base::FilePath setup_exe_path,
98                                          const wchar_t* exe_file) {
99   if (!setup_exe_path.empty()) {
100     // The uninstall path contains the path to setup.exe, which is two levels
101     // down from |exe_file|. Move up two levels (plus one to drop the file
102     // name) and look for chrome.exe from there.
103     base::FilePath exe_path(
104         setup_exe_path.DirName().DirName().DirName().Append(exe_file));
105     if (base::PathExists(exe_path))
106       return exe_path;
107     // By way of mild future proofing, look up one to see if there's a
108     // |exe_file| in the version directory
109     exe_path = setup_exe_path.DirName().DirName().Append(exe_file);
110     if (base::PathExists(exe_path))
111       return exe_path;
112   }
113   return base::FilePath();
114 }
115
116 // Returns the path to an installed SxS chrome.exe at the specified level, if
117 // it can be found via the registry.
118 base::FilePath GetChromeSxSPathForInstallationLevel(InstallationLevel level) {
119 #if defined(GOOGLE_CHROME_BUILD)
120   return FindExeRelativeToSetupExe(
121       GetSetupExeFromRegistry(level, kSxSBrowserAppGuid), kChromeExe);
122 #else
123   // There is no SxS build for Chromium.
124   return base::FilePath();
125 #endif
126 }
127
128 }  // namespace
129
130 base::FilePath GetChromePathForInstallationLevel(InstallationLevel level) {
131   return FindExeRelativeToSetupExe(
132       GetSetupExeForInstallationLevel(level), kChromeExe);
133 }
134
135 base::FilePath GetAnyChromePath() {
136   base::FilePath chrome_path;
137   if (chrome_path.empty())
138     chrome_path = GetChromePathForInstallationLevel(SYSTEM_LEVEL_INSTALLATION);
139   if (chrome_path.empty())
140     chrome_path = GetChromePathForInstallationLevel(USER_LEVEL_INSTALLATION);
141   return chrome_path;
142 }
143
144 base::FilePath GetAnyChromeSxSPath() {
145   base::FilePath path =
146       GetChromeSxSPathForInstallationLevel(USER_LEVEL_INSTALLATION);
147   if (path.empty())
148     path = GetChromeSxSPathForInstallationLevel(SYSTEM_LEVEL_INSTALLATION);
149   return path;
150 }
151
152 }  // namespace chrome_launcher_support