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

Side by Side Diff: chrome/installer/gcapi/gcapi.cc

Issue 18490: Adds the 6-month flag functionality back into the criteria checker,... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 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
« no previous file with comments | « chrome/installer/gcapi/gcapi.h ('k') | chrome/installer/gcapi/gcapi_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 #include <stdlib.h>
12 #include <strsafe.h> 12 #include <strsafe.h>
13 #include <tlhelp32.h> 13 #include <tlhelp32.h>
14 14
15 #include "google_update_idl.h" 15 #include "google_update_idl.h"
16 16
17 namespace { 17 namespace {
18 18
19 const wchar_t kChromeRegClientsKey[] = L"Software\\Google\\Update\\Clients\\{8A6 9D345-D564-463c-AFF1-A69D9E530F96}"; 19 const wchar_t kChromeRegClientsKey[] = L"Software\\Google\\Update\\Clients\\{8A6 9D345-D564-463c-AFF1-A69D9E530F96}";
20 const wchar_t kChromeRegClientStateKey[] = L"Software\\Google\\Update\\ClientSta te\\{8A69D345-D564-463c-AFF1-A69D9E530F96}"; 20 const wchar_t kChromeRegClientStateKey[] = L"Software\\Google\\Update\\ClientSta te\\{8A69D345-D564-463c-AFF1-A69D9E530F96}";
21 const wchar_t kChromeRegLaunchCmd[] = L"InstallerSuccessLaunchCmdLine"; 21 const wchar_t kChromeRegLaunchCmd[] = L"InstallerSuccessLaunchCmdLine";
22 const wchar_t kChromeRegLastLaunchCmd[] = L"LastInstallerSuccessLaunchCmdLine"; 22 const wchar_t kChromeRegLastLaunchCmd[] = L"LastInstallerSuccessLaunchCmdLine";
23 const wchar_t kChromeRegVersion[] = L"pv"; 23 const wchar_t kChromeRegVersion[] = L"pv";
24 const wchar_t kNoChromeOfferUntil[] = L"SOFTWARE\\Google\\No Chrome Offer Until" ;
25
26 // Remove any registry key with non-numeric value or with the numeric value
27 // equal or less than today's date represented in YYYYMMDD form.
28 void CleanUpRegistryValues() {
29 HKEY key = NULL;
30 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, kNoChromeOfferUntil,
31 0, KEY_ALL_ACCESS, &key) != ERROR_SUCCESS)
32 return;
33
34 DWORD index = 0;
35 wchar_t value_name[260];
36 DWORD value_name_len = _countof(value_name);
37 DWORD value_type = REG_DWORD;
38 DWORD value_data = 0;
39 DWORD value_len = sizeof(DWORD);
40
41 // First, remove any value whose type is not DWORD.
42 while (::RegEnumValue(key, index, value_name, &value_name_len, NULL,
43 &value_type, NULL, &value_len) == ERROR_SUCCESS) {
44 if (value_type == REG_DWORD)
45 index++;
46 else
47 ::RegDeleteValue(key, value_name);
48
49 value_name_len = _countof(value_name);
50 value_type = REG_DWORD;
51 value_len = sizeof(DWORD);
52 }
53
54 // Get today's date, and format it as YYYYMMDD numeric value.
55 SYSTEMTIME now;
56 ::GetLocalTime(&now);
57 DWORD expiration_date = now.wYear * 10000 + now.wMonth * 100 + now.wDay;
58
59 // Remove any DWORD value smaller than the number represent the
60 // expiration date (YYYYMMDD).
61 index = 0;
62 while (::RegEnumValue(key, index, value_name, &value_name_len, NULL,
63 &value_type, (LPBYTE) &value_data,
64 &value_len) == ERROR_SUCCESS) {
65 if (value_type == REG_DWORD && value_data > expiration_date)
66 index++; // move on to next value.
67 else
68 ::RegDeleteValue(key, value_name); // delete this value.
69
70 value_name_len = _countof(value_name);
71 value_type = REG_DWORD;
72 value_data = 0;
73 value_len = sizeof(DWORD);
74 }
75
76 ::RegCloseKey(key);
77 }
78
79 // Return the company name specified in the file version info resource.
80 bool GetCompanyName(const wchar_t* filename, wchar_t* buffer, DWORD out_len) {
81 wchar_t file_version_info[8192];
82 DWORD handle = 0;
83 DWORD buffer_size = 0;
84
85 buffer_size = ::GetFileVersionInfoSize(filename, &handle);
86 // Cannot stats the file or our buffer size is too small (very unlikely).
87 if (buffer_size == 0 || buffer_size > _countof(file_version_info))
88 return false;
89
90 buffer_size = _countof(file_version_info);
91 memset(file_version_info, 0, buffer_size);
92 if (!::GetFileVersionInfo(filename, handle, buffer_size, file_version_info))
93 return false;
94
95 DWORD data_len = 0;
96 LPVOID data = NULL;
97 // Retrieve the language and codepage code if exists.
98 buffer_size = 0;
99 if (!::VerQueryValue(file_version_info, TEXT("\\VarFileInfo\\Translation"),
100 reinterpret_cast<LPVOID *>(&data), reinterpret_cast<UINT *>(&data_len)))
101 return false;
102 if (data_len != 4)
103 return false;
104
105 wchar_t info_name[256];
106 DWORD lang = 0;
107 // Formulate the string to retrieve the company name of the specific
108 // language codepage.
109 memcpy(&lang, data, 4);
110 ::StringCchPrintf(info_name, _countof(info_name),
111 L"\\StringFileInfo\\%02X%02X%02X%02X\\CompanyName",
112 (lang & 0xff00)>>8, (lang & 0xff), (lang & 0xff000000)>>24,
113 (lang & 0xff0000)>>16);
114
115 data_len = 0;
116 if (!::VerQueryValue(file_version_info, info_name,
117 reinterpret_cast<LPVOID *>(&data), reinterpret_cast<UINT *>(&data_len)))
118 return false;
119 if (data_len <= 0 || data_len >= out_len)
120 return false;
121
122 memset(buffer, 0, out_len);
123 ::StringCchCopyN(buffer, out_len, (const wchar_t*)data, data_len);
124 return true;
125 }
126
127 // Return true if we can re-offer Chrome; false, otherwise.
128 // Each partner can only offer Chrome once every six months.
129 bool CanReOfferChrome(BOOL set_flag) {
130 wchar_t filename[MAX_PATH+1];
131 wchar_t company[MAX_PATH];
132
133 // If we cannot retrieve the version info of the executable or company
134 // name, we allow the Chrome to be offered because there is no past
135 // history to be found.
136 if (::GetModuleFileName(NULL, filename, MAX_PATH) == 0)
137 return true;
138 if (!GetCompanyName(filename, company, sizeof(company)))
139 return true;
140
141 bool can_re_offer = true;
142 DWORD disposition = 0;
143 HKEY key = NULL;
144 if (::RegCreateKeyEx(HKEY_LOCAL_MACHINE, kNoChromeOfferUntil,
145 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
146 NULL, &key, &disposition) == ERROR_SUCCESS) {
147 // Cannot re-offer, if the timer already exists and is not expired yet.
148 if (::RegQueryValueEx(key, company, 0, 0, 0, 0) == ERROR_SUCCESS) {
149 // The expired timers were already removed in CleanUpRegistryValues.
150 // So if the key is not found, we can offer the Chrome.
151 can_re_offer = false;
152 } else if (set_flag) {
153 // Set expiration date for offer as six months from today,
154 // represented as a YYYYMMDD numeric value.
155 SYSTEMTIME timer;
156 ::GetLocalTime(&timer);
157 timer.wMonth = timer.wMonth + 6;
158 if (timer.wMonth > 12) {
159 timer.wMonth = timer.wMonth - 12;
160 timer.wYear = timer.wYear + 1;
161 }
162 DWORD value = timer.wYear * 10000 + timer.wMonth * 100 + timer.wDay;
163 ::RegSetValueEx(key, company, 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD)) ;
164 }
165
166 ::RegCloseKey(key);
167 }
168
169 return can_re_offer;
170 }
24 171
25 // Helper function to read a value from registry. Returns true if value 172 // Helper function to read a value from registry. Returns true if value
26 // is read successfully and stored in parameter value. Returns false otherwise. 173 // is read successfully and stored in parameter value. Returns false otherwise.
27 bool ReadValueFromRegistry(HKEY root_key, const wchar_t *sub_key, 174 bool ReadValueFromRegistry(HKEY root_key, const wchar_t *sub_key,
28 const wchar_t *value_name, wchar_t *value, 175 const wchar_t *value_name, wchar_t *value,
29 size_t *size) { 176 size_t *size) {
30 HKEY key; 177 HKEY key;
31 if ((::RegOpenKeyEx(root_key, sub_key, NULL, 178 if ((::RegOpenKeyEx(root_key, sub_key, NULL,
32 KEY_READ, &key) == ERROR_SUCCESS) && 179 KEY_READ, &key) == ERROR_SUCCESS) &&
33 (::RegQueryValueEx(key, value_name, NULL, NULL, 180 (::RegQueryValueEx(key, value_name, NULL, NULL,
(...skipping 10 matching lines...) Expand all
44 size_t size = _countof(version); 191 size_t size = _countof(version);
45 if (ReadValueFromRegistry(root_key, kChromeRegClientsKey, kChromeRegVersion, 192 if (ReadValueFromRegistry(root_key, kChromeRegClientsKey, kChromeRegVersion,
46 version, &size)) 193 version, &size))
47 return true; 194 return true;
48 return false; 195 return false;
49 } 196 }
50 197
51 bool IsWinXPSp1OrLater(bool* is_vista_or_later) { 198 bool IsWinXPSp1OrLater(bool* is_vista_or_later) {
52 OSVERSIONINFOEX osviex = { sizeof(OSVERSIONINFOEX) }; 199 OSVERSIONINFOEX osviex = { sizeof(OSVERSIONINFOEX) };
53 int r = ::GetVersionEx((LPOSVERSIONINFO)&osviex); 200 int r = ::GetVersionEx((LPOSVERSIONINFO)&osviex);
54 // If this failed we're on Win9X or a pre NT4SP6 OS 201 // If this failed we're on Win9X or a pre NT4SP6 OS.
55 if (!r) 202 if (!r)
56 return false; 203 return false;
57 204
58 if (osviex.dwMajorVersion < 5) 205 if (osviex.dwMajorVersion < 5)
59 return false; 206 return false;
60 207
61 if (osviex.dwMajorVersion > 5) { 208 if (osviex.dwMajorVersion > 5) {
62 *is_vista_or_later = true; 209 *is_vista_or_later = true;
63 return true; // way beyond Windows XP; 210 return true; // way beyond Windows XP;
64 } 211 }
65 212
66 if (osviex.dwMinorVersion >= 1 && osviex.wServicePackMajor >= 1) 213 if (osviex.dwMinorVersion >= 1 && osviex.wServicePackMajor >= 1)
67 return true; // Windows XP SP1 or better 214 return true; // Windows XP SP1 or better.
68 215
69 return false; // Windows 2000, WinXP no Service Pack 216 return false; // Windows 2000, WinXP no Service Pack.
70 } 217 }
71 218
72 // Note this function should not be called on old Windows versions where these 219 // Note this function should not be called on old Windows versions where these
73 // Windows API are not available. We always invoke this function after checking 220 // Windows API are not available. We always invoke this function after checking
74 // that current OS is Vista or later. 221 // that current OS is Vista or later.
75 bool VerifyAdminGroup() { 222 bool VerifyAdminGroup() {
76 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; 223 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
77 PSID Group; 224 PSID Group;
78 BOOL check = ::AllocateAndInitializeSid(&NtAuthority, 2, 225 BOOL check = ::AllocateAndInitializeSid(&NtAuthority, 2,
79 SECURITY_BUILTIN_DOMAIN_RID, 226 SECURITY_BUILTIN_DOMAIN_RID,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 308 }
162 delete[] token_user; 309 delete[] token_user;
163 } 310 }
164 ::CloseHandle(process_token); 311 ::CloseHandle(process_token);
165 } 312 }
166 ::CloseHandle(process_handle); 313 ::CloseHandle(process_handle);
167 return result; 314 return result;
168 } 315 }
169 } // namespace 316 } // namespace
170 317
171 #pragma comment(linker, "/EXPORT:GoogleChromeCompatibilityCheck=_GoogleChromeCom patibilityCheck@4,PRIVATE") 318 #pragma comment(linker, "/EXPORT:GoogleChromeCompatibilityCheck=_GoogleChromeCom patibilityCheck@8,PRIVATE")
172 DLLEXPORT BOOL __stdcall GoogleChromeCompatibilityCheck(DWORD *reasons) { 319 DLLEXPORT BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, DWORD *re asons) {
173 DWORD local_reasons = 0; 320 DWORD local_reasons = 0;
174 321
175 bool is_vista_or_later = false; 322 bool is_vista_or_later = false;
176 // System requirements? 323 // System requirements?
177 if (!IsWinXPSp1OrLater(&is_vista_or_later)) 324 if (!IsWinXPSp1OrLater(&is_vista_or_later))
178 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED; 325 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED;
179 326
180 if (IsChromeInstalled(HKEY_LOCAL_MACHINE)) 327 if (IsChromeInstalled(HKEY_LOCAL_MACHINE))
181 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT; 328 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT;
182 329
183 if (IsChromeInstalled(HKEY_CURRENT_USER)) 330 if (IsChromeInstalled(HKEY_CURRENT_USER))
184 local_reasons |= GCCC_ERROR_USERLEVELALREADYPRESENT; 331 local_reasons |= GCCC_ERROR_USERLEVELALREADYPRESENT;
185 332
186 if (!VerifyHKLMAccess(kChromeRegClientsKey)) { 333 if (!VerifyHKLMAccess(kChromeRegClientsKey)) {
187 local_reasons |= GCCC_ERROR_ACCESSDENIED; 334 local_reasons |= GCCC_ERROR_ACCESSDENIED;
188 } else if (is_vista_or_later && !VerifyAdminGroup()) { 335 } else if (is_vista_or_later && !VerifyAdminGroup()) {
189 // For Vista or later check for elevation since even for admin user we could 336 // For Vista or later check for elevation since even for admin user we could
190 // be running in non-elevated mode. We require integrity level High. 337 // be running in non-elevated mode. We require integrity level High.
191 local_reasons |= GCCC_ERROR_INTEGRITYLEVEL; 338 local_reasons |= GCCC_ERROR_INTEGRITYLEVEL;
192 } 339 }
193 340
341 // First clean up the registry keys left over previously.
342 // Then only check whether we can re-offer, if everything else is OK.
343 CleanUpRegistryValues();
344 if (local_reasons == 0 && !CanReOfferChrome(set_flag))
345 local_reasons |= GCCC_ERROR_ALREADYOFFERED;
346
194 // Done. Copy/return results. 347 // Done. Copy/return results.
195 if (reasons != NULL) 348 if (reasons != NULL)
196 *reasons = local_reasons; 349 *reasons = local_reasons;
197 350
198 return (*reasons == 0); 351 return (*reasons == 0);
199 } 352 }
200 353
201 #pragma comment(linker, "/EXPORT:LaunchGoogleChrome=_LaunchGoogleChrome@0,PRIVAT E") 354 #pragma comment(linker, "/EXPORT:LaunchGoogleChrome=_LaunchGoogleChrome@0,PRIVAT E")
202 DLLEXPORT BOOL __stdcall LaunchGoogleChrome() { 355 DLLEXPORT BOOL __stdcall LaunchGoogleChrome() {
203 wchar_t launch_cmd[MAX_PATH]; 356 wchar_t launch_cmd[MAX_PATH];
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 if (!FAILED(ipl->LaunchCmdLine(launch_cmd))) 435 if (!FAILED(ipl->LaunchCmdLine(launch_cmd)))
283 ret = true; 436 ret = true;
284 ipl.Release(); 437 ipl.Release();
285 } 438 }
286 439
287 if (impersonation_success) 440 if (impersonation_success)
288 ::RevertToSelf(); 441 ::RevertToSelf();
289 ::CoUninitialize(); 442 ::CoUninitialize();
290 return ret; 443 return ret;
291 } 444 }
OLDNEW
« no previous file with comments | « chrome/installer/gcapi/gcapi.h ('k') | chrome/installer/gcapi/gcapi_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698