OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // Implementation of ChromeActiveDocument | 5 // Implementation of ChromeActiveDocument |
6 #include "chrome_frame/chrome_active_document.h" | 6 #include "chrome_frame/chrome_active_document.h" |
7 | 7 |
8 #include <hlink.h> | 8 #include <hlink.h> |
9 #include <htiface.h> | 9 #include <htiface.h> |
10 #include <initguid.h> | 10 #include <initguid.h> |
11 #include <mshtmcid.h> | 11 #include <mshtmcid.h> |
12 #include <shdeprecated.h> | 12 #include <shdeprecated.h> |
13 #include <shlguid.h> | 13 #include <shlguid.h> |
14 #include <shobjidl.h> | 14 #include <shobjidl.h> |
15 #include <tlogstg.h> | 15 #include <tlogstg.h> |
16 #include <urlmon.h> | 16 #include <urlmon.h> |
17 #include <wininet.h> | 17 #include <wininet.h> |
18 | 18 |
19 #include "base/command_line.h" | 19 #include "base/command_line.h" |
20 #include "base/file_util.h" | 20 #include "base/file_util.h" |
21 #include "base/file_version_info.h" | |
22 #include "base/logging.h" | 21 #include "base/logging.h" |
23 #include "base/path_service.h" | 22 #include "base/path_service.h" |
24 #include "base/process_util.h" | 23 #include "base/process_util.h" |
25 #include "base/registry.h" | 24 #include "base/registry.h" |
26 #include "base/scoped_variant_win.h" | 25 #include "base/scoped_variant_win.h" |
27 #include "base/string_tokenizer.h" | 26 #include "base/string_tokenizer.h" |
28 #include "base/string_util.h" | 27 #include "base/string_util.h" |
29 #include "base/thread.h" | 28 #include "base/thread.h" |
30 #include "base/thread_local.h" | 29 #include "base/thread_local.h" |
31 #include "base/trace_event.h" | 30 #include "base/trace_event.h" |
32 | 31 |
33 #include "grit/generated_resources.h" | 32 #include "grit/generated_resources.h" |
34 #include "chrome/app/chrome_dll_resource.h" | 33 #include "chrome/app/chrome_dll_resource.h" |
35 #include "chrome/browser/tab_contents/tab_contents.h" | 34 #include "chrome/browser/tab_contents/tab_contents.h" |
36 #include "chrome/common/chrome_constants.h" | 35 #include "chrome/common/chrome_constants.h" |
37 #include "chrome/common/navigation_types.h" | 36 #include "chrome/common/navigation_types.h" |
38 #include "chrome/test/automation/browser_proxy.h" | 37 #include "chrome/test/automation/browser_proxy.h" |
39 #include "chrome/test/automation/tab_proxy.h" | 38 #include "chrome/test/automation/tab_proxy.h" |
40 #include "chrome_frame/bho.h" | 39 #include "chrome_frame/bho.h" |
41 #include "chrome_frame/bind_context_info.h" | 40 #include "chrome_frame/bind_context_info.h" |
| 41 #include "chrome_frame/buggy_bho_handling.h" |
42 #include "chrome_frame/crash_reporting/crash_metrics.h" | 42 #include "chrome_frame/crash_reporting/crash_metrics.h" |
43 #include "chrome_frame/utils.h" | 43 #include "chrome_frame/utils.h" |
44 | 44 |
45 const wchar_t kChromeAttachExternalTabPrefix[] = L"attach_external_tab"; | 45 const wchar_t kChromeAttachExternalTabPrefix[] = L"attach_external_tab"; |
46 | 46 |
47 static const wchar_t kUseChromeNetworking[] = L"UseChromeNetworking"; | 47 static const wchar_t kUseChromeNetworking[] = L"UseChromeNetworking"; |
48 static const wchar_t kHandleTopLevelRequests[] = L"HandleTopLevelRequests"; | 48 static const wchar_t kHandleTopLevelRequests[] = L"HandleTopLevelRequests"; |
49 | 49 |
50 DEFINE_GUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, | 50 DEFINE_GUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, |
51 0x46); | 51 0x46); |
52 | 52 |
53 | |
54 base::ThreadLocalPointer<ChromeActiveDocument> g_active_doc_cache; | 53 base::ThreadLocalPointer<ChromeActiveDocument> g_active_doc_cache; |
55 | 54 |
56 bool g_first_launch_by_process_ = true; | 55 bool g_first_launch_by_process_ = true; |
57 | 56 |
58 const DWORD kIEEncodingIdArray[] = { | 57 const DWORD kIEEncodingIdArray[] = { |
59 #define DEFINE_ENCODING_ID_ARRAY(encoding_name, id, chrome_name) encoding_name, | 58 #define DEFINE_ENCODING_ID_ARRAY(encoding_name, id, chrome_name) encoding_name, |
60 INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID_ARRAY) | 59 INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID_ARRAY) |
61 #undef DEFINE_ENCODING_ID_ARRAY | 60 #undef DEFINE_ENCODING_ID_ARRAY |
62 0 // The Last data must be 0 to indicate the end of the encoding id array. | 61 0 // The Last data must be 0 to indicate the end of the encoding id array. |
63 }; | 62 }; |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 StartsWith(static_cast<BSTR>(url_), kChromeAttachExternalTabPrefix, | 716 StartsWith(static_cast<BSTR>(url_), kChromeAttachExternalTabPrefix, |
718 false); | 717 false); |
719 | 718 |
720 if (new_navigation_info.url.is_valid()) | 719 if (new_navigation_info.url.is_valid()) |
721 url_.Allocate(UTF8ToWide(new_navigation_info.url.spec()).c_str()); | 720 url_.Allocate(UTF8ToWide(new_navigation_info.url.spec()).c_str()); |
722 | 721 |
723 if (is_internal_navigation) { | 722 if (is_internal_navigation) { |
724 ScopedComPtr<IDocObjectService> doc_object_svc; | 723 ScopedComPtr<IDocObjectService> doc_object_svc; |
725 ScopedComPtr<IWebBrowserEventsService> web_browser_events_svc; | 724 ScopedComPtr<IWebBrowserEventsService> web_browser_events_svc; |
726 | 725 |
| 726 buggy_bho::BuggyBhoTls bad_bho_tls; |
| 727 if (GetConfigBool(true, kEnableBuggyBhoIntercept)) { |
| 728 ScopedComPtr<IWebBrowser2> wb2; |
| 729 DoQueryService(SID_SWebBrowserApp, m_spClientSite, wb2.Receive()); |
| 730 if (wb2) { |
| 731 buggy_bho::BuggyBhoTls::PatchBuggyBHOs(wb2); |
| 732 } |
| 733 } |
| 734 |
727 DoQueryService(__uuidof(web_browser_events_svc), m_spClientSite, | 735 DoQueryService(__uuidof(web_browser_events_svc), m_spClientSite, |
728 web_browser_events_svc.Receive()); | 736 web_browser_events_svc.Receive()); |
729 | 737 |
730 if (!web_browser_events_svc.get()) { | 738 if (!web_browser_events_svc.get()) { |
731 DoQueryService(SID_SShellBrowser, m_spClientSite, | 739 DoQueryService(SID_SShellBrowser, m_spClientSite, |
732 doc_object_svc.Receive()); | 740 doc_object_svc.Receive()); |
733 } | 741 } |
734 | 742 |
735 // web_browser_events_svc can be NULL on IE6. | 743 // web_browser_events_svc can be NULL on IE6. |
736 if (web_browser_events_svc) { | 744 if (web_browser_events_svc) { |
(...skipping 20 matching lines...) Expand all Loading... |
757 internal_navigation.AsInput(), NULL); | 765 internal_navigation.AsInput(), NULL); |
758 | 766 |
759 // We no longer need to lie to IE. If we lie persistently to IE, then | 767 // We no longer need to lie to IE. If we lie persistently to IE, then |
760 // IE reuses us for new navigations. | 768 // IE reuses us for new navigations. |
761 IEExec(&CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, NULL, NULL); | 769 IEExec(&CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, NULL, NULL); |
762 | 770 |
763 if (doc_object_svc) { | 771 if (doc_object_svc) { |
764 // Now call the FireNavigateCompleteEvent which makes IE update the text | 772 // Now call the FireNavigateCompleteEvent which makes IE update the text |
765 // in the address-bar. | 773 // in the address-bar. |
766 doc_object_svc->FireNavigateComplete2(this, 0); | 774 doc_object_svc->FireNavigateComplete2(this, 0); |
767 if (ShouldFireDocumentComplete()) | 775 doc_object_svc->FireDocumentComplete(this, 0); |
768 doc_object_svc->FireDocumentComplete(this, 0); | |
769 } else if (web_browser_events_svc) { | 776 } else if (web_browser_events_svc) { |
770 web_browser_events_svc->FireNavigateComplete2Event(); | 777 web_browser_events_svc->FireNavigateComplete2Event(); |
771 if (ShouldFireDocumentComplete()) | 778 web_browser_events_svc->FireDocumentCompleteEvent(); |
772 web_browser_events_svc->FireDocumentCompleteEvent(); | |
773 } | 779 } |
774 } | 780 } |
775 | 781 |
776 if (is_title_changed) { | 782 if (is_title_changed) { |
777 ScopedVariant title(new_navigation_info.title.c_str()); | 783 ScopedVariant title(new_navigation_info.title.c_str()); |
778 IEExec(NULL, OLECMDID_SETTITLE, OLECMDEXECOPT_DONTPROMPTUSER, | 784 IEExec(NULL, OLECMDID_SETTITLE, OLECMDEXECOPT_DONTPROMPTUSER, |
779 title.AsInput(), NULL); | 785 title.AsInput(), NULL); |
780 } | 786 } |
781 | 787 |
782 // It is important that we only update the navigation_info_ after we have | 788 // It is important that we only update the navigation_info_ after we have |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 DCHECK(shell_browser.get() != NULL); | 1263 DCHECK(shell_browser.get() != NULL); |
1258 ScopedComPtr<ITridentService2> trident_services; | 1264 ScopedComPtr<ITridentService2> trident_services; |
1259 trident_services.QueryFrom(shell_browser); | 1265 trident_services.QueryFrom(shell_browser); |
1260 if (trident_services) | 1266 if (trident_services) |
1261 trident_services->FirePrivacyImpactedStateChange(wparam); | 1267 trident_services->FirePrivacyImpactedStateChange(wparam); |
1262 else | 1268 else |
1263 NOTREACHED() << "Failed to retrieve IWebBrowser2 interface."; | 1269 NOTREACHED() << "Failed to retrieve IWebBrowser2 interface."; |
1264 return 0; | 1270 return 0; |
1265 } | 1271 } |
1266 | 1272 |
1267 namespace { | |
1268 struct ModuleAndVersion { | |
1269 const char* module_name_; | |
1270 const uint32 major_version_; | |
1271 const uint32 minor_version_; | |
1272 }; | |
1273 } // end namespace | |
1274 | |
1275 // static | |
1276 bool ChromeActiveDocument::ShouldFireDocumentComplete() { | |
1277 typedef enum ModuleCheckResult { | |
1278 CHECK_NOT_DONE, | |
1279 DOCUMENT_COMPLETE_OK, | |
1280 DOCUMENT_COMPLETE_NOT_OK | |
1281 }; | |
1282 | |
1283 static ModuleCheckResult results = CHECK_NOT_DONE; | |
1284 | |
1285 if (results == CHECK_NOT_DONE) { | |
1286 // These modules are missing some checks in their DocumentComplete | |
1287 // implementation that causes a crash. | |
1288 static const ModuleAndVersion buggy_modules[] = { | |
1289 { "askbar.dll", 4, 1 }, // biggest troublemaker: 4.1.0.5. | |
1290 { "gbieh.dll", 3, 8 }, // biggest troublemaker: 3.8.14.12 | |
1291 { "gbiehcef.dll", 3, 8 }, // biggest troublemaker: 3.8.11.23 | |
1292 { "gbiehUni.dll", 3, 8 }, // Another Banco DLL. | |
1293 }; | |
1294 | |
1295 for (size_t i = 0; results == CHECK_NOT_DONE && | |
1296 i < arraysize(buggy_modules); ++i) { | |
1297 const ModuleAndVersion& module = buggy_modules[i]; | |
1298 HMODULE mod = ::GetModuleHandleA(module.module_name_); | |
1299 if (mod) { | |
1300 wchar_t path[MAX_PATH * 2] = {0}; | |
1301 ::GetModuleFileNameW(mod, path, arraysize(path)); | |
1302 scoped_ptr<FileVersionInfo> version_info( | |
1303 FileVersionInfo::CreateFileVersionInfo(FilePath(path))); | |
1304 DCHECK(version_info.get()); | |
1305 if (version_info.get()) { | |
1306 uint32 major = 0, minor = 0; | |
1307 if (!ParseVersion(version_info->file_version(), &major, &minor)) | |
1308 ParseVersion(version_info->product_version(), &major, &minor); | |
1309 if (major < module.major_version_ || | |
1310 (major == module.major_version_ && | |
1311 minor <= module.minor_version_)) { | |
1312 DLOG(WARNING) << "Buggy module found: " << module.module_name_; | |
1313 results = DOCUMENT_COMPLETE_NOT_OK; | |
1314 } | |
1315 } | |
1316 } | |
1317 } | |
1318 | |
1319 if (results == CHECK_NOT_DONE) | |
1320 results = DOCUMENT_COMPLETE_OK; | |
1321 } | |
1322 | |
1323 return results == DOCUMENT_COMPLETE_OK; | |
1324 } | |
1325 | |
OLD | NEW |