1 // Copyright 2014 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.
5 #include "chrome_elf/chrome_elf_util.h"
9 #include "base/macros.h"
10 #include "base/strings/string16.h"
14 const wchar_t kRegPathClientState
[] = L
"Software\\Google\\Update\\ClientState";
15 const wchar_t kRegPathClientStateMedium
[] =
16 L
"Software\\Google\\Update\\ClientStateMedium";
17 #if defined(GOOGLE_CHROME_BUILD)
18 const wchar_t kRegPathChromePolicy
[] = L
"SOFTWARE\\Policies\\Google\\Chrome";
20 const wchar_t kRegPathChromePolicy
[] = L
"SOFTWARE\\Policies\\Chromium";
21 #endif // defined(GOOGLE_CHROME_BUILD)
23 const wchar_t kRegValueUsageStats
[] = L
"usagestats";
24 const wchar_t kUninstallArgumentsField
[] = L
"UninstallArguments";
25 const wchar_t kMetricsReportingEnabled
[] =L
"MetricsReportingEnabled";
27 const wchar_t kAppGuidCanary
[] =
28 L
"{4ea16ac7-fd5a-47c3-875b-dbf4a2008c20}";
29 const wchar_t kAppGuidGoogleChrome
[] =
30 L
"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
31 const wchar_t kAppGuidGoogleBinaries
[] =
32 L
"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
34 bool ReadKeyValueString(bool system_install
, const wchar_t* key_path
,
35 const wchar_t* guid
, const wchar_t* value_to_read
,
36 base::string16
* value_out
) {
40 base::string16
full_key_path(key_path
);
41 full_key_path
.append(1, L
'\\');
42 full_key_path
.append(guid
);
44 if (::RegOpenKeyEx(system_install
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
45 full_key_path
.c_str(), 0,
46 KEY_QUERY_VALUE
| KEY_WOW64_32KEY
, &key
) !=
51 const size_t kMaxStringLength
= 1024;
52 wchar_t raw_value
[kMaxStringLength
] = {};
53 DWORD size
= sizeof(raw_value
);
55 LONG result
= ::RegQueryValueEx(key
, value_to_read
, 0, &type
,
56 reinterpret_cast<LPBYTE
>(raw_value
), &size
);
58 if (result
== ERROR_SUCCESS
) {
59 if (type
!= REG_SZ
|| (size
& 1) != 0) {
60 result
= ERROR_NOT_SUPPORTED
;
61 } else if (size
== 0) {
63 } else if (raw_value
[size
/ sizeof(wchar_t) - 1] != L
'\0') {
64 if ((size
/ sizeof(wchar_t)) < kMaxStringLength
)
65 raw_value
[size
/ sizeof(wchar_t)] = L
'\0';
67 result
= ERROR_MORE_DATA
;
71 if (result
== ERROR_SUCCESS
)
72 *value_out
= raw_value
;
76 return result
== ERROR_SUCCESS
;
79 bool ReadKeyValueDW(bool system_install
, const wchar_t* key_path
,
80 base::string16 guid
, const wchar_t* value_to_read
,
85 base::string16
full_key_path(key_path
);
86 full_key_path
.append(1, L
'\\');
87 full_key_path
.append(guid
);
89 if (::RegOpenKeyEx(system_install
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
90 full_key_path
.c_str(), 0,
91 KEY_QUERY_VALUE
| KEY_WOW64_32KEY
, &key
) !=
96 DWORD size
= sizeof(*value_out
);
97 DWORD type
= REG_DWORD
;
98 LONG result
= ::RegQueryValueEx(key
, value_to_read
, 0, &type
,
99 reinterpret_cast<BYTE
*>(value_out
), &size
);
103 return result
== ERROR_SUCCESS
&& size
== sizeof(*value_out
);
108 bool IsCanary(const wchar_t* exe_path
) {
109 return wcsstr(exe_path
, L
"Chrome SxS\\Application") != NULL
;
112 bool IsSystemInstall(const wchar_t* exe_path
) {
113 wchar_t program_dir
[MAX_PATH
] = {};
114 DWORD ret
= ::GetEnvironmentVariable(L
"PROGRAMFILES", program_dir
,
115 arraysize(program_dir
));
116 if (ret
&& ret
< MAX_PATH
&& !wcsncmp(exe_path
, program_dir
, ret
))
119 ret
= ::GetEnvironmentVariable(L
"PROGRAMFILES(X86)", program_dir
,
120 arraysize(program_dir
));
121 if (ret
&& ret
< MAX_PATH
&& !wcsncmp(exe_path
, program_dir
, ret
))
127 bool IsMultiInstall(bool is_system_install
) {
129 if (!ReadKeyValueString(is_system_install
, kRegPathClientState
,
130 kAppGuidGoogleChrome
, kUninstallArgumentsField
,
134 return args
.find(L
"--multi-install") != base::string16::npos
;
137 bool AreUsageStatsEnabled(const wchar_t* exe_path
) {
139 bool controlled_by_policy
= ReportingIsEnforcedByPolicy(&enabled
);
141 if (controlled_by_policy
&& !enabled
)
144 bool system_install
= IsSystemInstall(exe_path
);
145 base::string16 app_guid
;
147 if (IsCanary(exe_path
)) {
148 app_guid
= kAppGuidCanary
;
150 app_guid
= IsMultiInstall(system_install
) ? kAppGuidGoogleBinaries
:
151 kAppGuidGoogleChrome
;
155 if (system_install
&&
156 ReadKeyValueDW(system_install
, kRegPathClientStateMedium
, app_guid
,
157 kRegValueUsageStats
, &out_value
)) {
158 return out_value
== 1;
161 return ReadKeyValueDW(system_install
, kRegPathClientState
, app_guid
,
162 kRegValueUsageStats
, &out_value
) && out_value
== 1;
165 bool ReportingIsEnforcedByPolicy(bool* breakpad_enabled
) {
168 BYTE
* value_bytes
= reinterpret_cast<BYTE
*>(&value
);
169 DWORD size
= sizeof(value
);
170 DWORD type
= REG_DWORD
;
172 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE
, kRegPathChromePolicy
, 0,
173 KEY_QUERY_VALUE
, &key
) == ERROR_SUCCESS
) {
174 if (::RegQueryValueEx(key
, kMetricsReportingEnabled
, 0, &type
,
175 value_bytes
, &size
) == ERROR_SUCCESS
) {
176 *breakpad_enabled
= value
!= 0;
179 return size
== sizeof(value
);
182 if (::RegOpenKeyEx(HKEY_CURRENT_USER
, kRegPathChromePolicy
, 0,
183 KEY_QUERY_VALUE
, &key
) == ERROR_SUCCESS
) {
184 if (::RegQueryValueEx(key
, kMetricsReportingEnabled
, 0, &type
,
185 value_bytes
, &size
) == ERROR_SUCCESS
) {
186 *breakpad_enabled
= value
!= 0;
189 return size
== sizeof(value
);
195 bool IsNonBrowserProcess() {
196 typedef bool (*IsSandboxedProcessFunc
)();
197 IsSandboxedProcessFunc is_sandboxed_process_func
=
198 reinterpret_cast<IsSandboxedProcessFunc
>(
199 GetProcAddress(GetModuleHandle(NULL
), "IsSandboxedProcess"));
200 bool is_sandboxed_process
=
201 is_sandboxed_process_func
&& is_sandboxed_process_func();
203 // TODO(robertshield): Drop the command line check when we drop support for
204 // enabling chrome_elf in unsandboxed processes.
205 wchar_t* command_line
= GetCommandLine();
206 bool has_process_type_flag
= command_line
&& wcsstr(command_line
, L
"--type");
208 return (has_process_type_flag
|| is_sandboxed_process
);