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

Side by Side Diff: chrome_elf/chrome_elf_util.cc

Issue 154653002: Breakpad coverage for chrome_elf start up (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add policy checks and headlessness Created 6 years, 10 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
(Empty)
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.
4
5 #include "chrome_elf/chrome_elf_util.h"
6
7 #include <windows.h>
8
9 #include "base/macros.h"
10 #include "base/strings/string16.h"
11
12 namespace {
13
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";
19 #else
20 const wchar_t kRegPathChromePolicy[] = L"SOFTWARE\\Policies\\Chromium";
21 #endif // defined(GOOGLE_CHROME_BUILD)
22
23 const wchar_t kRegValueUsageStats[] = L"usagestats";
24 const wchar_t kUninstallArgumentsField[] = L"UninstallArguments";
25 const wchar_t kMetricsReportingEnabled[] =L"MetricsReportingEnabled";
26
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}";
33
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) {
37 HKEY h_key = NULL;
38 value_out->clear();
39
40 base::string16 full_key_path(key_path);
41 full_key_path.append(1, L'\\');
42 full_key_path.append(guid);
43
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, &h_key) !=
47 ERROR_SUCCESS) {
48 return false;
49 }
50
51 const size_t kMaxStringLength = 1024;
52 wchar_t raw_value[kMaxStringLength] = {};
53 DWORD size = sizeof(raw_value);
54 DWORD type = REG_SZ;
55 LONG result = ::RegQueryValueEx(h_key, value_to_read, 0, &type,
56 reinterpret_cast<LPBYTE>(raw_value), &size);
57
58 if (result == ERROR_SUCCESS) {
59 if (type != REG_SZ || (size & 1) != 0) {
60 result = ERROR_NOT_SUPPORTED;
61 } else if (size == 0) {
62 *raw_value = L'\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';
66 else
67 result = ERROR_MORE_DATA;
68 }
69 }
70
71 *value_out = raw_value;
grt (UTC plus 2) 2014/02/17 20:49:39 only make this assignment when result == ERROR_SUC
Cait (Slow) 2014/02/18 23:03:12 Done.
72
73 ::RegCloseKey(h_key);
74
75 return result == ERROR_SUCCESS;
76 }
77
78 bool ReadKeyValueDW(bool system_install, const wchar_t* key_path,
79 base::string16 guid, const wchar_t* value_to_read,
80 DWORD* value_out) {
81 HKEY h_key = NULL;
82 *value_out = 0;
83
84 base::string16 full_key_path(key_path);
85 full_key_path.append(1, L'\\');
86 full_key_path.append(guid);
87
88 if (::RegOpenKeyEx(system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
89 full_key_path.c_str(), 0,
90 KEY_QUERY_VALUE | KEY_WOW64_32KEY, &h_key) !=
91 ERROR_SUCCESS) {
92 return false;
93 }
94
95 DWORD size = sizeof(DWORD);
grt (UTC plus 2) 2014/02/17 20:49:39 sizeof(*value_out)
Cait (Slow) 2014/02/18 23:03:12 Done.
96 DWORD type = REG_DWORD;
97 LONG result = ::RegQueryValueEx(h_key, value_to_read, 0, &type,
98 reinterpret_cast<BYTE*>(value_out), &size);
99
100 ::RegCloseKey(h_key);
101
102 return result == ERROR_SUCCESS;
grt (UTC plus 2) 2014/02/17 20:49:39 result == ERROR_SUCCESS && size == sizeof(*value_o
Cait (Slow) 2014/02/18 23:03:12 Done.
103 }
104
105 } // namespace
106
107 bool IsCanary(const wchar_t* exe_path) {
108 return wcsstr(exe_path, L"Chrome SxS\\Application") != NULL;
109 }
110
111 bool IsSystemInstall(const wchar_t* exe_path) {
112 wchar_t program_dir[MAX_PATH] = {};
113 DWORD ret = ::GetEnvironmentVariable(L"PROGRAMFILES", program_dir,
114 arraysize(program_dir));
115 if (ret && ret < MAX_PATH && !wcsncmp(exe_path, program_dir, ret))
116 return true;
117
118 ret = ::GetEnvironmentVariable(L"PROGRAMFILES(X86)", program_dir,
119 arraysize(program_dir));
120 if (ret && ret < MAX_PATH && !wcsncmp(exe_path, program_dir, ret))
121 return true;
122
123 return false;
124 }
125
126 bool IsMultiInstall(bool is_system_install) {
127 base::string16 args;
128 if (!ReadKeyValueString(is_system_install, kRegPathClientState,
129 kAppGuidGoogleChrome, kUninstallArgumentsField,
130 &args)) {
131 return false;
132 }
133 return args.find(L"--multi-install") != base::string16::npos;
134 }
135
136 bool AreUsageStatsEnabled(const wchar_t* exe_path) {
137 #if !defined(GOOGLE_CHROME_BUILD)
138 return false;
139 #else
140 bool enabled = true;
141 bool controlled_by_policy = ReportingIsEnforcedByPolicy(&enabled);
142
143 if (controlled_by_policy && !enabled)
144 return false;
145
146 // TODO(caitkp): If enabled by policy but manually disabled, what happens?
147
148 bool system_install = IsSystemInstall(exe_path);
149 base::string16 app_guid;
150
151 if (IsCanary(exe_path)) {
152 app_guid = kAppGuidCanary;
153 } else {
154 app_guid = IsMultiInstall(system_install) ? kAppGuidGoogleBinaries :
155 kAppGuidGoogleChrome;
156 }
157
158 DWORD out_value = 0;
159 if (system_install &&
160 ReadKeyValueDW(system_install, kRegPathClientStateMedium, app_guid,
161 kRegValueUsageStats, &out_value)) {
162 return out_value == 1;
163 }
164
165 return ReadKeyValueDW(system_install, kRegPathClientState, app_guid,
166 kRegValueUsageStats, &out_value) && out_value == 1;
167 #endif // defined(GOOGLE_CHROME_BUILD)
168 }
169
170 bool ReportingIsEnforcedByPolicy(bool* breakpad_enabled) {
171 HKEY h_key = NULL;
grt (UTC plus 2) 2014/02/17 20:49:39 don't prefix this with h_ (and elsewhere in this f
172 DWORD value = 0;
173 BYTE* value_bytes = reinterpret_cast<BYTE*>(value);
grt (UTC plus 2) 2014/02/17 20:49:39 value -> &value
Cait (Slow) 2014/02/18 23:03:12 Done.
174 DWORD size = sizeof(DWORD);
grt (UTC plus 2) 2014/02/17 20:49:39 sizeof(value)
Cait (Slow) 2014/02/18 23:03:12 Done.
175 DWORD type = REG_DWORD;
176
177 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, kRegPathChromePolicy, 0,
grt (UTC plus 2) 2014/02/17 20:49:39 be sure to close the key regardless as to whether
Cait (Slow) 2014/02/18 23:03:12 Done.
178 KEY_READ | KEY_WOW64_32KEY, &h_key) == ERROR_SUCCESS &&
grt (UTC plus 2) 2014/02/17 20:49:39 KEY_WOW64_32KEY is not called for here.
grt (UTC plus 2) 2014/02/17 20:49:39 KEY_READ -> KEY_QUERY_VALUE
Cait (Slow) 2014/02/18 23:03:12 Done.
Cait (Slow) 2014/02/18 23:03:12 Done.
179 ::RegQueryValueEx(h_key, kMetricsReportingEnabled, 0, &type,
180 value_bytes, &size) == ERROR_SUCCESS) {
181 *breakpad_enabled = value != 0;
182 ::RegCloseKey(h_key);
183 return true;
184 }
185
186 if (::RegOpenKeyEx(HKEY_CURRENT_USER, kRegPathChromePolicy, 0,
187 KEY_READ | KEY_WOW64_32KEY, &h_key) == ERROR_SUCCESS &&
188 ::RegQueryValueEx(h_key, kMetricsReportingEnabled, 0, &type,
189 value_bytes, &size) == ERROR_SUCCESS) {
190 *breakpad_enabled = value != 0;
191 ::RegCloseKey(h_key);
192 return true;
193 }
194
195 return false;
196 }
197
198
grt (UTC plus 2) 2014/02/17 20:49:39 nit: remove extra newlines at end of file
Cait (Slow) 2014/02/18 23:03:12 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698