OLD | NEW |
| (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 | |
OLD | NEW |