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_frame/test/ie_configurator.cc

Issue 126143005: Remove Chrome Frame code and resources. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync to r244038 Created 6 years, 11 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_frame/test/ie_configurator.h ('k') | chrome_frame/test/ie_event_sink.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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_frame/test/ie_configurator.h"
6
7 #include <windows.h>
8 #include <objbase.h>
9
10 #include <ios>
11 #include <list>
12 #include <vector>
13
14 #include "base/compiler_specific.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/strings/string16.h"
17 #include "base/time/time.h"
18 #include "base/win/registry.h"
19 #include "chrome_frame/chrome_tab.h"
20 #include "chrome_frame/test/chrome_frame_test_utils.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace chrome_frame_test {
24
25 namespace {
26
27 const wchar_t kKeyIEApprovedExtensions[] =
28 L"Software\\Microsoft\\Internet Explorer\\Approved Extensions\\";
29 const wchar_t kKeyIEInformationBar[] =
30 L"Software\\Microsoft\\Internet Explorer\\InformationBar";
31 const wchar_t kKeyIEMain[] =
32 L"Software\\Microsoft\\Internet Explorer\\Main";
33 const wchar_t kKeyIEPhishingFilter[] =
34 L"Software\\Microsoft\\Internet Explorer\\PhishingFilter";
35 const wchar_t kKeyIEBrowserEmulation[] =
36 L"Software\\Microsoft\\Internet Explorer\\BrowserEmulation";
37 const wchar_t kKeyPoliciesExt[] =
38 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Ext";
39 const wchar_t kValueEnabledV8[] = L"EnabledV8";
40 const wchar_t kValueEnabledV9[] = L"EnabledV9";
41 const wchar_t kValueFirstTime[] = L"FirstTime";
42 const wchar_t kValueIE8Completed[] = L"IE8RunOncePerInstallCompleted";
43 const wchar_t kValueIE8CompletionTime[] = L"IE8RunOnceCompletionTime";
44 const wchar_t kValueIE8RunOnceLastShown[] = L"IE8RunOnceLastShown";
45 const wchar_t kValueIE8RunOnceLastShownTimestamp[] =
46 L"IE8RunOnceLastShown_TIMESTAMP";
47 const wchar_t kValueIE8TourNoShow[] = L"IE8TourNoShow";
48 const wchar_t kValueIE9Completed[] = L"IE9RunOncePerInstallCompleted";
49 const wchar_t kValueIE9CompletionTime[] = L"IE9RunOnceCompletionTime";
50 const wchar_t kValueIE9RunOnceLastShown[] = L"IE9RunOnceLastShown";
51 const wchar_t kValueIE9RunOnceLastShownTimestamp[] =
52 L"IE9RunOnceLastShown_TIMESTAMP";
53 const wchar_t kValueIE9TourNoShow[] = L"IE9TourNoShow";
54 const wchar_t kValueIE10Completed[] = L"IE10RunOncePerInstallCompleted";
55 const wchar_t kValueIE10CompletionTime[] = L"IE10RunOnceCompletionTime";
56 const wchar_t kValueIE10RunOnceLastShown[] = L"IE10RunOnceLastShown";
57 const wchar_t kValueIE10RunOnceLastShownTimestamp[] =
58 L"IE10RunOnceLastShown_TIMESTAMP";
59 const wchar_t kValueIgnoreFrameApprovalCheck[] = L"IgnoreFrameApprovalCheck";
60 const wchar_t kValueMSCompatibilityMode[] = L"MSCompatibilityMode";
61
62 // A helper class that accumulate a set of registry mutations and corresponding
63 // undo data via calls to its Add*() methods. The mutations can be applied to
64 // the registry (repeatedly, if desired) via a call to Apply(). Revert() can be
65 // called to apply the accumulated undo data.
66 class RegistrySetter {
67 public:
68 RegistrySetter();
69 ~RegistrySetter();
70
71 // Adds a mutation that sets a REG_DWORD registry value, creating any
72 // intermediate keys as necessary. |key| and |value| must remain valid
73 // throughout all calls to Apply().
74 void AddDWORDValue(HKEY root, const wchar_t* key, const wchar_t* value,
75 DWORD data);
76
77 // Adds a mutation that assigns a FILETIME to a REG_BINARY registry value,
78 // creating any intermediate keys as necessary. |key| and |value| must remain
79 // valid throughout all calls to Apply().
80 void AddFILETIMEValue(HKEY root, const wchar_t* key, const wchar_t* value,
81 FILETIME data);
82
83 // Applies all mutations in the order they were added. Errors encountered
84 // along the way are logged, but do not stop progress.
85 void Apply() const;
86
87 // Applies the undo data in the reverse order that their corresponding
88 // mutations were added.
89 void Revert() const;
90
91 private:
92 // The data for an individual registry value. A non-existent value is
93 // indicated by type = REG_NONE and empty data.
94 struct RegistryData {
95 HKEY root;
96 const wchar_t* key;
97 const wchar_t* value;
98 DWORD type;
99 std::vector<uint8> data;
100 };
101
102 typedef std::list<RegistryData> RegistryDataList;
103
104 // Adds a mutation to the end of the apply list with the given data, and a
105 // mutation to the revert list with the current state of the value.
106 void AddValue(HKEY root, const wchar_t* key, const wchar_t* value, DWORD type,
107 const uint8* value_begin, size_t value_len);
108
109 // Add a mutation to the revert list that restores a registry value to its
110 // current state. This only adds entries to set or remove |value|. If
111 // portions of the hierarchy identified by |key| do not exist, but are created
112 // between the invocation of this method and the time the revert list is
113 // applied, only |value| is deleted upon revert (intermediate keys are not
114 // deleted).
115 void SaveCurrentValue(HKEY root, const wchar_t* key, const wchar_t* value);
116
117 // Applies all mutations in |data_list| in order.
118 static void ApplyList(const RegistryDataList& data_list);
119
120 RegistryDataList apply_list_;
121 RegistryDataList revert_list_;
122
123 DISALLOW_COPY_AND_ASSIGN(RegistrySetter);
124 };
125
126 // A Google Test event listener that delegates to a configurator.
127 class ConfiguratorDriver : public testing::EmptyTestEventListener {
128 public:
129 explicit ConfiguratorDriver(IEConfigurator* configurator);
130 virtual ~ConfiguratorDriver();
131
132 virtual void OnTestProgramStart(const testing::UnitTest& unit_test) OVERRIDE;
133 virtual void OnTestStart(const testing::TestInfo& test_info) OVERRIDE;
134 virtual void OnTestProgramEnd(const testing::UnitTest& unit_test) OVERRIDE;
135
136 private:
137 scoped_ptr<IEConfigurator> configurator_;
138 DISALLOW_COPY_AND_ASSIGN(ConfiguratorDriver);
139 };
140
141 // A configurator for Internet Explorer 7.
142 class IE7Configurator : public IEConfigurator {
143 public:
144 IE7Configurator();
145 virtual ~IE7Configurator();
146
147 virtual void Initialize() OVERRIDE;
148 virtual void ApplySettings() OVERRIDE;
149 virtual void RevertSettings() OVERRIDE;
150
151 private:
152 RegistrySetter setter_;
153
154 DISALLOW_COPY_AND_ASSIGN(IE7Configurator);
155 };
156
157 // A configurator for Internet Explorer 8, 9, and 10.
158 class ModernIEConfigurator : public IEConfigurator {
159 public:
160 explicit ModernIEConfigurator(IEVersion ie_version);
161 virtual ~ModernIEConfigurator();
162
163 virtual void Initialize() OVERRIDE;
164 virtual void ApplySettings() OVERRIDE;
165 virtual void RevertSettings() OVERRIDE;
166
167 private:
168 // The names of the registry values used to determine if IE's one-time
169 // initialization has been completed.
170 struct RunOnceValueNames {
171 // This DWORD value is non-zero once initialization has been completed.
172 const wchar_t* completed;
173 // This 8-byte binary value is the FILETIME of completion.
174 const wchar_t* completion_time;
175 // This DWORD value is non-zero if run-once was previously deferred.
176 const wchar_t* last_shown;
177 // This 8-byte binary value is the FILETIME of run-once deferral.
178 const wchar_t* last_shown_timestamp;
179 };
180
181 static const RunOnceValueNames kIE8ValueNames;
182 static const RunOnceValueNames kIE9ValueNames;
183 static const RunOnceValueNames kIE10ValueNames;
184
185 static const RunOnceValueNames* RunOnceNamesForVersion(IEVersion ie_version);
186 bool IsPerUserSetupComplete();
187 static base::string16 GetChromeFrameBHOCLSID();
188 static bool IsAddonPromptDisabledForChromeFrame();
189
190 const IEVersion ie_version_;
191 const RunOnceValueNames* run_once_value_names_;
192 RegistrySetter setter_;
193
194 DISALLOW_COPY_AND_ASSIGN(ModernIEConfigurator);
195 };
196
197 // RegistrySetter implementation.
198
199 RegistrySetter::RegistrySetter() {
200 }
201
202 RegistrySetter::~RegistrySetter() {
203 }
204
205 void RegistrySetter::AddValue(HKEY root,
206 const wchar_t* key,
207 const wchar_t* value,
208 DWORD type,
209 const uint8* value_begin,
210 size_t value_len) {
211 RegistryData the_data = {
212 root,
213 key,
214 value,
215 type,
216 std::vector<uint8>(value_begin, value_begin + value_len)
217 };
218 apply_list_.push_back(the_data);
219 SaveCurrentValue(root, key, value);
220 }
221
222 void RegistrySetter::SaveCurrentValue(HKEY root,
223 const wchar_t* key,
224 const wchar_t* value) {
225 base::win::RegKey the_key;
226 RegistryData the_data = { root, key, value, REG_NONE };
227
228 LONG result = the_key.Open(root, key, KEY_QUERY_VALUE);
229 if (result == ERROR_SUCCESS) {
230 DWORD size = 0;
231 result = the_key.ReadValue(value, NULL, &size, &the_data.type);
232 if (result == ERROR_FILE_NOT_FOUND) {
233 // Add a mutation to delete the value.
234 the_data.type = REG_NONE;
235 revert_list_.push_front(the_data);
236 } else if (result == ERROR_SUCCESS) {
237 the_data.data.resize(size);
238 result = the_key.ReadValue(value, &the_data.data[0], &size,
239 &the_data.type);
240 if (result == ERROR_SUCCESS) {
241 revert_list_.push_front(the_data);
242 } else {
243 ::SetLastError(result);
244 PLOG(ERROR) << __FUNCTION__ << " unexpected error reading data for "
245 << value << " from key " << key
246 << ". The current value will not be restored upon revert.";
247 }
248 } else {
249 ::SetLastError(result);
250 PLOG(ERROR) << __FUNCTION__ << " unexpected error reading " << value
251 << " from key " << key
252 << ". The current value will not be restored upon revert.";
253 }
254 } else if (result == ERROR_FILE_NOT_FOUND) {
255 // Add a mutation to delete the value (but not any keys).
256 revert_list_.push_front(the_data);
257 } else {
258 ::SetLastError(result);
259 PLOG(ERROR) << __FUNCTION__ << " unexpected error opening key " << key
260 << " to read value " << value
261 << ". The current value will not be restored upon revert.";
262 }
263 }
264
265 void RegistrySetter::AddDWORDValue(HKEY root,
266 const wchar_t* key,
267 const wchar_t* value,
268 DWORD data) {
269 const uint8* data_ptr = reinterpret_cast<uint8*>(&data);
270 AddValue(root, key, value, REG_DWORD, data_ptr, sizeof(data));
271 }
272
273 void RegistrySetter::AddFILETIMEValue(HKEY root,
274 const wchar_t* key,
275 const wchar_t* value,
276 FILETIME data) {
277 const uint8* data_ptr = reinterpret_cast<uint8*>(&data);
278 AddValue(root, key, value, REG_BINARY, data_ptr, sizeof(data));
279 }
280
281 // static
282 void RegistrySetter::ApplyList(const RegistryDataList& data_list) {
283 base::win::RegKey key;
284 LONG result = ERROR_SUCCESS;
285 for (RegistryDataList::const_iterator scan(data_list.begin());
286 scan != data_list.end(); ++scan) {
287 const RegistryData& data = *scan;
288 const bool do_delete = (data.type == REG_NONE && data.data.empty());
289 result = do_delete ?
290 key.Open(data.root, data.key, KEY_SET_VALUE) :
291 key.Create(data.root, data.key, KEY_SET_VALUE);
292 if (result == ERROR_SUCCESS) {
293 if (do_delete) {
294 result = key.DeleteValue(data.value);
295 } else {
296 result = key.WriteValue(data.value,
297 data.data.empty() ? NULL : &data.data[0],
298 data.data.size(), data.type);
299 }
300 if (result != ERROR_SUCCESS) {
301 ::SetLastError(result);
302 PLOG(ERROR) << "Failed to " << (do_delete ? "delete" : "set")
303 << " value " << data.value
304 << " in registry key " << data.key
305 << " in hive " << std::hex <<data.root << std::dec;
306 }
307 } else if (!do_delete || result != ERROR_FILE_NOT_FOUND) {
308 ::SetLastError(result);
309 PLOG(ERROR) << "Failed to create/open registry key " << data.key
310 << " in hive " << std::hex << data.root << std::dec;
311 }
312 }
313 }
314
315 void RegistrySetter::Apply() const {
316 ApplyList(apply_list_);
317 }
318
319 void RegistrySetter::Revert() const {
320 ApplyList(revert_list_);
321 }
322
323 // ConfiguratorDriver implementation.
324
325 ConfiguratorDriver::ConfiguratorDriver(IEConfigurator* configurator)
326 : configurator_(configurator) {
327 DCHECK(configurator);
328 }
329
330 ConfiguratorDriver::~ConfiguratorDriver() {
331 }
332
333 void ConfiguratorDriver::OnTestProgramStart(
334 const testing::UnitTest& unit_test) {
335 configurator_->Initialize();
336 }
337
338 void ConfiguratorDriver::OnTestStart(const testing::TestInfo& test_info) {
339 configurator_->ApplySettings();
340 }
341
342 void ConfiguratorDriver::OnTestProgramEnd(const testing::UnitTest& unit_test) {
343 configurator_->RevertSettings();
344 }
345
346 // IE7Configurator implementation
347
348 IE7Configurator::IE7Configurator() {
349 }
350
351 IE7Configurator::~IE7Configurator() {
352 }
353
354 void IE7Configurator::Initialize() {
355 // Suppress the friendly "Hi! I popped up an info bar for you. Did you see
356 // the info bar I just showed you? There's a yellow thing in your IE window
357 // that wasn't there before! I call it an Information Bar. Did you notice
358 // the Information Bar?" dialog that it likes to show.
359 setter_.AddDWORDValue(HKEY_CURRENT_USER, kKeyIEInformationBar,
360 kValueFirstTime, 0);
361 }
362
363 void IE7Configurator::ApplySettings() {
364 setter_.Apply();
365 }
366
367 void IE7Configurator::RevertSettings() {
368 setter_.Revert();
369 }
370
371 // ModernIEConfigurator implementation
372
373 const ModernIEConfigurator::RunOnceValueNames
374 ModernIEConfigurator::kIE8ValueNames = {
375 kValueIE8Completed,
376 kValueIE8CompletionTime,
377 kValueIE8RunOnceLastShown,
378 kValueIE8RunOnceLastShownTimestamp,
379 };
380
381 const ModernIEConfigurator::RunOnceValueNames
382 ModernIEConfigurator::kIE9ValueNames = {
383 kValueIE9Completed,
384 kValueIE9CompletionTime,
385 kValueIE9RunOnceLastShown,
386 kValueIE9RunOnceLastShownTimestamp,
387 };
388
389 const ModernIEConfigurator::RunOnceValueNames
390 ModernIEConfigurator::kIE10ValueNames = {
391 kValueIE10Completed,
392 kValueIE10CompletionTime,
393 kValueIE10RunOnceLastShown,
394 kValueIE10RunOnceLastShownTimestamp,
395 };
396
397 ModernIEConfigurator::ModernIEConfigurator(IEVersion ie_version)
398 : ie_version_(ie_version),
399 run_once_value_names_(RunOnceNamesForVersion(ie_version)) {
400 }
401
402 ModernIEConfigurator::~ModernIEConfigurator() {
403 }
404
405 // static
406 const ModernIEConfigurator::RunOnceValueNames*
407 ModernIEConfigurator::RunOnceNamesForVersion(
408 IEVersion ie_version) {
409 switch (ie_version) {
410 case IE_8:
411 return &kIE8ValueNames;
412 break;
413 case IE_9:
414 return &kIE9ValueNames;
415 break;
416 case IE_10:
417 return &kIE10ValueNames;
418 break;
419 default:
420 NOTREACHED();
421 }
422 return NULL;
423 }
424
425 // Returns true if the per-user setup is complete.
426 bool ModernIEConfigurator::IsPerUserSetupComplete() {
427 bool is_complete = false;
428 base::win::RegKey key_main;
429
430 if (key_main.Open(HKEY_CURRENT_USER, kKeyIEMain,
431 KEY_QUERY_VALUE) != ERROR_SUCCESS) {
432 return false;
433 }
434
435 DWORD dword_value = 0;
436 FILETIME shown_time = {};
437 FILETIME completion_time = {};
438 DWORD size = sizeof(completion_time);
439
440 // See if the user has seen the first-run prompt.
441 if (key_main.ReadValue(run_once_value_names_->last_shown_timestamp,
442 &shown_time, &size, NULL) != ERROR_SUCCESS ||
443 size != sizeof(shown_time)) {
444 return false;
445 }
446
447 // See if setup was completed.
448 if (key_main.ReadValue(run_once_value_names_->completion_time,
449 &completion_time, &size, NULL) != ERROR_SUCCESS ||
450 size != sizeof(completion_time)) {
451 return false;
452 }
453
454 // See if setup was completed after the last time the prompt was shown.
455 base::Time time_shown = base::Time::FromFileTime(shown_time);
456 base::Time time_completed = base::Time::FromFileTime(completion_time);
457 if (time_shown >= time_completed)
458 return false;
459
460 return true;
461 }
462
463 // Returns the path to the IE9 Approved Extensions key for Chrome Frame.
464 // static
465 base::string16 ModernIEConfigurator::GetChromeFrameBHOCLSID() {
466 base::string16 bho_guid(39, L'\0');
467 int guid_len = StringFromGUID2(CLSID_ChromeFrameBHO, &bho_guid[0],
468 bho_guid.size());
469 DCHECK_EQ(guid_len, static_cast<int>(bho_guid.size()));
470 bho_guid.resize(guid_len - 1);
471 return bho_guid;
472 }
473
474 // Returns true if the add-on enablement prompt is disabled by Group Policy.
475 // static
476 bool ModernIEConfigurator::IsAddonPromptDisabledForChromeFrame() {
477 bool is_disabled = false;
478 base::win::RegKey key;
479
480 // See if the prompt is disabled for this user of IE.
481 if (key.Open(HKEY_CURRENT_USER, kKeyIEApprovedExtensions,
482 KEY_QUERY_VALUE) == ERROR_SUCCESS) {
483 DWORD type = REG_NONE;
484 DWORD size = 0;
485 if (key.ReadValue(GetChromeFrameBHOCLSID().c_str(), NULL, &size,
486 &type) == ERROR_SUCCESS &&
487 type == REG_BINARY) {
488 is_disabled = true;
489 }
490 }
491
492 // Now check if the prompt is disabled for all add-ons via Group Policy.
493 if (!is_disabled &&
494 key.Open(HKEY_LOCAL_MACHINE, kKeyPoliciesExt,
495 KEY_QUERY_VALUE) == ERROR_SUCCESS) {
496 DWORD ignore = 0;
497 if (key.ReadValueDW(kValueIgnoreFrameApprovalCheck,
498 &ignore) == ERROR_SUCCESS &&
499 ignore != 0) {
500 is_disabled = true;
501 }
502 }
503
504 return is_disabled;
505 }
506
507 void ModernIEConfigurator::Initialize() {
508 // Check for per-user IE setup.
509 if (!IsPerUserSetupComplete()) {
510 base::Time time(base::Time::Now());
511 const HKEY root = HKEY_CURRENT_USER;
512 // Suppress the "Set up Internet Explorer" dialog.
513 setter_.AddDWORDValue(root, kKeyIEMain, run_once_value_names_->last_shown,
514 1);
515 setter_.AddDWORDValue(root, kKeyIEMain, run_once_value_names_->completed,
516 1);
517 setter_.AddFILETIMEValue(root, kKeyIEMain,
518 run_once_value_names_->last_shown_timestamp,
519 time.ToFileTime());
520 time += base::TimeDelta::FromMilliseconds(10);
521 setter_.AddFILETIMEValue(root, kKeyIEMain,
522 run_once_value_names_->completion_time,
523 time.ToFileTime());
524 if (ie_version_ < IE_10) {
525 // Don't show a tour of IE 8 and 9.
526 setter_.AddDWORDValue(
527 root,
528 kKeyIEMain,
529 (ie_version_ == IE_8 ? kValueIE8TourNoShow : kValueIE9TourNoShow),
530 1);
531 }
532 // Turn off the phishing filter.
533 setter_.AddDWORDValue(
534 root,
535 kKeyIEPhishingFilter,
536 (ie_version_ == IE_8 ? kValueEnabledV8 : kValueEnabledV9),
537 0);
538 // Don't download compatibility view lists.
539 setter_.AddDWORDValue(root, kKeyIEBrowserEmulation,
540 kValueMSCompatibilityMode, 0);
541 }
542
543 // Turn off the "'Foo' add-on from 'Bar' is ready for use." prompt via Group
544 // Policy.
545 if (!IsAddonPromptDisabledForChromeFrame()) {
546 setter_.AddDWORDValue(HKEY_LOCAL_MACHINE, kKeyPoliciesExt,
547 kValueIgnoreFrameApprovalCheck, 1);
548 }
549 }
550
551 void ModernIEConfigurator::ApplySettings() {
552 setter_.Apply();
553 }
554
555 void ModernIEConfigurator::RevertSettings() {
556 setter_.Revert();
557 }
558
559 } // namespace
560
561 // Configurator implementation.
562
563 IEConfigurator::IEConfigurator() {
564 }
565
566 IEConfigurator::~IEConfigurator() {
567 }
568
569 IEConfigurator* CreateConfigurator() {
570 IEConfigurator* configurator = NULL;
571
572 IEVersion ie_version = GetInstalledIEVersion();
573 switch (ie_version) {
574 case IE_7:
575 configurator = new IE7Configurator();
576 break;
577 case IE_8:
578 case IE_9:
579 case IE_10:
580 configurator = new ModernIEConfigurator(ie_version);
581 break;
582 default:
583 break;
584 }
585
586 return configurator;
587 }
588
589 void InstallIEConfigurator() {
590 IEConfigurator* configurator = CreateConfigurator();
591
592 if (configurator != NULL) {
593 testing::UnitTest::GetInstance()->listeners().Append(
594 new ConfiguratorDriver(configurator));
595 }
596 }
597
598 } // namespace chrome_frame_test
OLDNEW
« no previous file with comments | « chrome_frame/test/ie_configurator.h ('k') | chrome_frame/test/ie_event_sink.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698