OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "chrome/installer/gcapi/gcapi.h" | 5 #include "chrome/installer/gcapi/gcapi.h" |
6 | 6 |
7 #include <atlbase.h> | 7 #include <atlbase.h> |
8 #include <atlcom.h> | 8 #include <atlcom.h> |
9 #include <windows.h> | 9 #include <windows.h> |
10 #include <sddl.h> | 10 #include <sddl.h> |
11 #include <stdlib.h> | 11 #define STRSAFE_NO_DEPRECATE |
12 #include <strsafe.h> | 12 #include <strsafe.h> |
13 #include <tlhelp32.h> | 13 #include <tlhelp32.h> |
14 | 14 |
15 #include <cstdlib> | |
16 | |
15 #include "google_update_idl.h" | 17 #include "google_update_idl.h" |
16 | 18 |
17 namespace { | 19 namespace { |
18 | 20 |
19 const wchar_t kChromeRegClientsKey[] = | 21 const wchar_t kChromeRegClientsKey[] = |
20 L"Software\\Google\\Update\\Clients\\" | 22 L"Software\\Google\\Update\\Clients\\" |
21 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; | 23 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; |
22 const wchar_t kChromeRegClientStateKey[] = | 24 const wchar_t kChromeRegClientStateKey[] = |
23 L"Software\\Google\\Update\\ClientState\\" | 25 L"Software\\Google\\Update\\ClientState\\" |
24 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; | 26 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 reinterpret_cast<LPDWORD>(size)) == ERROR_SUCCESS)) { | 151 reinterpret_cast<LPDWORD>(size)) == ERROR_SUCCESS)) { |
150 ::RegCloseKey(key); | 152 ::RegCloseKey(key); |
151 return true; | 153 return true; |
152 } | 154 } |
153 return false; | 155 return false; |
154 } | 156 } |
155 | 157 |
156 bool IsChromeInstalled(HKEY root_key) { | 158 bool IsChromeInstalled(HKEY root_key) { |
157 wchar_t version[64]; | 159 wchar_t version[64]; |
158 size_t size = _countof(version); | 160 size_t size = _countof(version); |
159 if (ReadValueFromRegistry(root_key, kChromeRegClientsKey, kChromeRegVersion, | 161 return ReadValueFromRegistry(root_key, kChromeRegClientsKey, |
160 version, &size)) | 162 kChromeRegVersion, version, &size); |
161 return true; | |
162 return false; | |
163 } | 163 } |
164 | 164 |
165 bool IsWinXPSp2OrLater(bool* is_vista_or_later) { | 165 enum WindowsVersion { |
166 OSVERSIONINFOEX osviex = { sizeof(OSVERSIONINFOEX) }; | 166 VERSION_BELOW_XP_SP2, |
167 int r = ::GetVersionEx((LPOSVERSIONINFO)&osviex); | 167 VERSION_XP_SP2_UP_TO_VISTA, // "but not including" |
168 // If this failed we're on Win9X or a pre NT4SP6 OS. | 168 VERSION_VISTA_OR_HIGHER, |
169 if (!r) | 169 }; |
170 return false; | 170 WindowsVersion GetWindowsVersion() { |
171 | 171 OSVERSIONINFOEX version_info = { sizeof version_info }; |
172 if (osviex.dwMajorVersion < 5) | 172 GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info)); |
173 return false; | 173 if (version_info.dwMajorVersion > 5) |
174 | 174 return VERSION_VISTA_OR_HIGHER; |
175 if (osviex.dwMajorVersion > 5) { | 175 return (version_info.dwMajorVersion < 5) || |
brettw
2011/04/06 04:27:47
I can't follow this at all, and I found the old ve
Peter Kasting
2011/04/06 04:52:43
Um... OK... the old code happened to be wrong, tho
| |
176 *is_vista_or_later = true; | 176 (version_info.dwMinorVersion == 0) || |
177 return true; // way beyond Windows XP; | 177 ((version_info.dwMinorVersion == 1) && |
178 } | 178 (version_info.wServicePackMajor < 2)) ? |
179 | 179 VERSION_BELOW_XP_SP2 : VERSION_XP_SP2_UP_TO_VISTA; |
180 if (osviex.dwMinorVersion >= 1 && osviex.wServicePackMajor >= 2) | |
181 return true; // Windows XP SP2 or better. | |
182 | |
183 return false; // Windows 2000, WinXP no Service Pack. | |
184 } | 180 } |
185 | 181 |
186 // Note this function should not be called on old Windows versions where these | 182 // Note this function should not be called on old Windows versions where these |
187 // Windows API are not available. We always invoke this function after checking | 183 // Windows API are not available. We always invoke this function after checking |
188 // that current OS is Vista or later. | 184 // that current OS is Vista or later. |
189 bool VerifyAdminGroup() { | 185 bool VerifyAdminGroup() { |
190 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; | 186 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; |
191 PSID Group; | 187 PSID Group; |
192 BOOL check = ::AllocateAndInitializeSid(&NtAuthority, 2, | 188 BOOL check = ::AllocateAndInitializeSid(&NtAuthority, 2, |
193 SECURITY_BUILTIN_DOMAIN_RID, | 189 SECURITY_BUILTIN_DOMAIN_RID, |
(...skipping 29 matching lines...) Expand all Loading... | |
223 RegDeleteKey(key, NULL); | 219 RegDeleteKey(key, NULL); |
224 | 220 |
225 RegCloseKey(key); | 221 RegCloseKey(key); |
226 } | 222 } |
227 | 223 |
228 return result; | 224 return result; |
229 } | 225 } |
230 | 226 |
231 bool IsRunningElevated() { | 227 bool IsRunningElevated() { |
232 // This method should be called only for Vista or later. | 228 // This method should be called only for Vista or later. |
233 bool is_vista_or_later = false; | 229 if ((GetWindowsVersion() < VERSION_VISTA_OR_HIGHER) || |
234 IsWinXPSp2OrLater(&is_vista_or_later); | 230 !VerifyAdminGroup()) |
235 if (!is_vista_or_later || !VerifyAdminGroup()) | |
236 return false; | 231 return false; |
237 | 232 |
238 HANDLE process_token; | 233 HANDLE process_token; |
239 if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token)) | 234 if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token)) |
240 return false; | 235 return false; |
241 | 236 |
242 TOKEN_ELEVATION_TYPE elevation_type = TokenElevationTypeDefault; | 237 TOKEN_ELEVATION_TYPE elevation_type = TokenElevationTypeDefault; |
243 DWORD size_returned = 0; | 238 DWORD size_returned = 0; |
244 if (!::GetTokenInformation(process_token, TokenElevationType, | 239 if (!::GetTokenInformation(process_token, TokenElevationType, |
245 &elevation_type, sizeof(elevation_type), | 240 &elevation_type, sizeof(elevation_type), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 ::CloseHandle(process_handle); | 275 ::CloseHandle(process_handle); |
281 return result; | 276 return result; |
282 } | 277 } |
283 } // namespace | 278 } // namespace |
284 | 279 |
285 #pragma comment(linker, "/EXPORT:GoogleChromeCompatibilityCheck=_GoogleChromeCom patibilityCheck@8,PRIVATE") | 280 #pragma comment(linker, "/EXPORT:GoogleChromeCompatibilityCheck=_GoogleChromeCom patibilityCheck@8,PRIVATE") |
286 DLLEXPORT BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, | 281 DLLEXPORT BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, |
287 DWORD *reasons) { | 282 DWORD *reasons) { |
288 DWORD local_reasons = 0; | 283 DWORD local_reasons = 0; |
289 | 284 |
290 bool is_vista_or_later = false; | 285 WindowsVersion windows_version = GetWindowsVersion(); |
291 // System requirements? | 286 // System requirements? |
292 if (!IsWinXPSp2OrLater(&is_vista_or_later)) | 287 if (windows_version == VERSION_BELOW_XP_SP2) |
293 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED; | 288 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED; |
294 | 289 |
295 if (IsChromeInstalled(HKEY_LOCAL_MACHINE)) | 290 if (IsChromeInstalled(HKEY_LOCAL_MACHINE)) |
296 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT; | 291 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT; |
297 | 292 |
298 if (IsChromeInstalled(HKEY_CURRENT_USER)) | 293 if (IsChromeInstalled(HKEY_CURRENT_USER)) |
299 local_reasons |= GCCC_ERROR_USERLEVELALREADYPRESENT; | 294 local_reasons |= GCCC_ERROR_USERLEVELALREADYPRESENT; |
300 | 295 |
301 if (!VerifyHKLMAccess(kChromeRegClientsKey)) { | 296 if (!VerifyHKLMAccess(kChromeRegClientsKey)) { |
302 local_reasons |= GCCC_ERROR_ACCESSDENIED; | 297 local_reasons |= GCCC_ERROR_ACCESSDENIED; |
303 } else if (is_vista_or_later && !VerifyAdminGroup()) { | 298 } else if ((windows_version == VERSION_VISTA_OR_HIGHER) && |
299 !VerifyAdminGroup()) { | |
304 // For Vista or later check for elevation since even for admin user we could | 300 // For Vista or later check for elevation since even for admin user we could |
305 // be running in non-elevated mode. We require integrity level High. | 301 // be running in non-elevated mode. We require integrity level High. |
306 local_reasons |= GCCC_ERROR_INTEGRITYLEVEL; | 302 local_reasons |= GCCC_ERROR_INTEGRITYLEVEL; |
307 } | 303 } |
308 | 304 |
309 // Then only check whether we can re-offer, if everything else is OK. | 305 // Then only check whether we can re-offer, if everything else is OK. |
310 if (local_reasons == 0 && !CanReOfferChrome(set_flag)) | 306 if (local_reasons == 0 && !CanReOfferChrome(set_flag)) |
311 local_reasons |= GCCC_ERROR_ALREADYOFFERED; | 307 local_reasons |= GCCC_ERROR_ALREADYOFFERED; |
312 | 308 |
313 // Done. Copy/return results. | 309 // Done. Copy/return results. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 // This loop iterates through all of the top-level Windows named | 438 // This loop iterates through all of the top-level Windows named |
443 // Chrome_WindowImpl_0, and looks for the first one with any children. | 439 // Chrome_WindowImpl_0, and looks for the first one with any children. |
444 while (handle && !FindWindowEx(handle, NULL, L"Chrome_WindowImpl_0", NULL)) { | 440 while (handle && !FindWindowEx(handle, NULL, L"Chrome_WindowImpl_0", NULL)) { |
445 // Get the next top-level Chrome window. | 441 // Get the next top-level Chrome window. |
446 handle = FindWindowEx(NULL, handle, L"Chrome_WindowImpl_0", NULL); | 442 handle = FindWindowEx(NULL, handle, L"Chrome_WindowImpl_0", NULL); |
447 } | 443 } |
448 | 444 |
449 return (handle && | 445 return (handle && |
450 SetWindowPos(handle, 0, x, y, width, height, SWP_NOZORDER)); | 446 SetWindowPos(handle, 0, x, y, width, height, SWP_NOZORDER)); |
451 } | 447 } |
OLD | NEW |