| OLD | NEW |
| 1 // Copyright (c) 2010 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_frame/utils.h" | 5 #include "chrome_frame/utils.h" |
| 6 | 6 |
| 7 #include <atlsafe.h> | 7 #include <atlsafe.h> |
| 8 #include <atlsecurity.h> | 8 #include <atlsecurity.h> |
| 9 #include <htiframe.h> | 9 #include <htiframe.h> |
| 10 #include <mshtml.h> | 10 #include <mshtml.h> |
| 11 #include <shlobj.h> | 11 #include <shlobj.h> |
| (...skipping 23 matching lines...) Expand all Loading... |
| 35 #include "chrome_frame/simple_resource_loader.h" | 35 #include "chrome_frame/simple_resource_loader.h" |
| 36 #include "googleurl/src/gurl.h" | 36 #include "googleurl/src/gurl.h" |
| 37 #include "googleurl/src/url_canon.h" | 37 #include "googleurl/src/url_canon.h" |
| 38 #include "grit/chromium_strings.h" | 38 #include "grit/chromium_strings.h" |
| 39 #include "net/base/escape.h" | 39 #include "net/base/escape.h" |
| 40 #include "net/http/http_util.h" | 40 #include "net/http/http_util.h" |
| 41 | 41 |
| 42 #include "chrome_tab.h" // NOLINT | 42 #include "chrome_tab.h" // NOLINT |
| 43 | 43 |
| 44 using base::win::RegKey; | 44 using base::win::RegKey; |
| 45 using base::win::ScopedComPtr; | |
| 46 | 45 |
| 47 // Note that these values are all lower case and are compared to | 46 // Note that these values are all lower case and are compared to |
| 48 // lower-case-transformed values. | 47 // lower-case-transformed values. |
| 49 const wchar_t kMetaTag[] = L"meta"; | 48 const wchar_t kMetaTag[] = L"meta"; |
| 50 const wchar_t kHttpEquivAttribName[] = L"http-equiv"; | 49 const wchar_t kHttpEquivAttribName[] = L"http-equiv"; |
| 51 const wchar_t kContentAttribName[] = L"content"; | 50 const wchar_t kContentAttribName[] = L"content"; |
| 52 const wchar_t kXUACompatValue[] = L"x-ua-compatible"; | 51 const wchar_t kXUACompatValue[] = L"x-ua-compatible"; |
| 53 const wchar_t kBodyTag[] = L"body"; | 52 const wchar_t kBodyTag[] = L"body"; |
| 54 const wchar_t kChromeContentPrefix[] = L"chrome="; | 53 const wchar_t kChromeContentPrefix[] = L"chrome="; |
| 55 const char kGCFProtocol[] = "gcf"; | 54 const char kGCFProtocol[] = "gcf"; |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 } | 459 } |
| 461 | 460 |
| 462 return ie_version; | 461 return ie_version; |
| 463 } | 462 } |
| 464 | 463 |
| 465 FilePath GetIETemporaryFilesFolder() { | 464 FilePath GetIETemporaryFilesFolder() { |
| 466 LPITEMIDLIST tif_pidl = NULL; | 465 LPITEMIDLIST tif_pidl = NULL; |
| 467 HRESULT hr = SHGetFolderLocation(NULL, CSIDL_INTERNET_CACHE, NULL, | 466 HRESULT hr = SHGetFolderLocation(NULL, CSIDL_INTERNET_CACHE, NULL, |
| 468 SHGFP_TYPE_CURRENT, &tif_pidl); | 467 SHGFP_TYPE_CURRENT, &tif_pidl); |
| 469 if (SUCCEEDED(hr) && tif_pidl) { | 468 if (SUCCEEDED(hr) && tif_pidl) { |
| 470 ScopedComPtr<IShellFolder> parent_folder; | 469 base::win::ScopedComPtr<IShellFolder> parent_folder; |
| 471 LPITEMIDLIST relative_pidl = NULL; | 470 LPITEMIDLIST relative_pidl = NULL; |
| 472 hr = SHBindToParent(tif_pidl, IID_IShellFolder, | 471 hr = SHBindToParent(tif_pidl, IID_IShellFolder, |
| 473 reinterpret_cast<void**>(parent_folder.Receive()), | 472 reinterpret_cast<void**>(parent_folder.Receive()), |
| 474 const_cast<LPCITEMIDLIST*>(&relative_pidl)); | 473 const_cast<LPCITEMIDLIST*>(&relative_pidl)); |
| 475 if (SUCCEEDED(hr) && relative_pidl) { | 474 if (SUCCEEDED(hr) && relative_pidl) { |
| 476 STRRET path = {0}; | 475 STRRET path = {0}; |
| 477 hr = parent_folder->GetDisplayNameOf(relative_pidl, | 476 hr = parent_folder->GetDisplayNameOf(relative_pidl, |
| 478 SHGDN_NORMAL | SHGDN_FORPARSING, | 477 SHGDN_NORMAL | SHGDN_FORPARSING, |
| 479 &path); | 478 &path); |
| 480 DCHECK(SUCCEEDED(hr)); | 479 DCHECK(SUCCEEDED(hr)); |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 return renderer_type; | 790 return renderer_type; |
| 792 } | 791 } |
| 793 | 792 |
| 794 HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker, | 793 HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker, |
| 795 const wchar_t* headers, IBindCtx* bind_ctx, | 794 const wchar_t* headers, IBindCtx* bind_ctx, |
| 796 const wchar_t* fragment, IStream* post_data) { | 795 const wchar_t* fragment, IStream* post_data) { |
| 797 DCHECK(browser); | 796 DCHECK(browser); |
| 798 DCHECK(moniker); | 797 DCHECK(moniker); |
| 799 DCHECK(bind_ctx); | 798 DCHECK(bind_ctx); |
| 800 | 799 |
| 801 ScopedComPtr<IWebBrowser2> web_browser2; | 800 base::win::ScopedComPtr<IWebBrowser2> web_browser2; |
| 802 HRESULT hr = DoQueryService(SID_SWebBrowserApp, browser, | 801 HRESULT hr = DoQueryService(SID_SWebBrowserApp, browser, |
| 803 web_browser2.Receive()); | 802 web_browser2.Receive()); |
| 804 DCHECK(web_browser2); | 803 DCHECK(web_browser2); |
| 805 DLOG_IF(WARNING, FAILED(hr)) << base::StringPrintf(L"SWebBrowserApp 0x%08X", | 804 DLOG_IF(WARNING, FAILED(hr)) << base::StringPrintf(L"SWebBrowserApp 0x%08X", |
| 806 hr); | 805 hr); |
| 807 if (FAILED(hr)) | 806 if (FAILED(hr)) |
| 808 return hr; | 807 return hr; |
| 809 | 808 |
| 810 // Always issue the download request in a new window to ensure that the | 809 // Always issue the download request in a new window to ensure that the |
| 811 // currently loaded ChromeFrame document does not inadvarently see an unload | 810 // currently loaded ChromeFrame document does not inadvarently see an unload |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 // is then used to determine if the moniker is already running and via | 854 // is then used to determine if the moniker is already running and via |
| 856 // that mechanism is associated with the same internet request as has already | 855 // that mechanism is associated with the same internet request as has already |
| 857 // been issued. | 856 // been issued. |
| 858 | 857 |
| 859 // TODO(tommi): See if we can get HlinkSimpleNavigateToMoniker to work | 858 // TODO(tommi): See if we can get HlinkSimpleNavigateToMoniker to work |
| 860 // instead. Looks like we'll need to support IHTMLDocument2 (get_URL in | 859 // instead. Looks like we'll need to support IHTMLDocument2 (get_URL in |
| 861 // particular), access to IWebBrowser2 etc. | 860 // particular), access to IWebBrowser2 etc. |
| 862 // HlinkSimpleNavigateToMoniker(moniker, url, NULL, host, bind_context, | 861 // HlinkSimpleNavigateToMoniker(moniker, url, NULL, host, bind_context, |
| 863 // NULL, 0, 0); | 862 // NULL, 0, 0); |
| 864 | 863 |
| 865 ScopedComPtr<IUriContainer> uri_container; | 864 base::win::ScopedComPtr<IUriContainer> uri_container; |
| 866 hr = uri_container.QueryFrom(moniker); | 865 hr = uri_container.QueryFrom(moniker); |
| 867 | 866 |
| 868 base::win::ScopedVariant headers_var; | 867 base::win::ScopedVariant headers_var; |
| 869 if (headers && headers[0]) | 868 if (headers && headers[0]) |
| 870 headers_var.Set(headers); | 869 headers_var.Set(headers); |
| 871 | 870 |
| 872 if (uri_container) { | 871 if (uri_container) { |
| 873 // IE7 and IE8. | 872 // IE7 and IE8. |
| 874 const IID* interface_ids[] = { | 873 const IID* interface_ids[] = { |
| 875 &IID_IWebBrowserPriv2IE7, | 874 &IID_IWebBrowserPriv2IE7, |
| 876 &IID_IWebBrowserPriv2IE8, | 875 &IID_IWebBrowserPriv2IE8, |
| 877 &IID_IWebBrowserPriv2IE8XP, | 876 &IID_IWebBrowserPriv2IE8XP, |
| 878 &IID_IWebBrowserPriv2IE8XPBeta, | 877 &IID_IWebBrowserPriv2IE8XPBeta, |
| 879 }; | 878 }; |
| 880 | 879 |
| 881 ScopedComPtr<IWebBrowserPriv2Common, NULL> browser_priv2; | 880 base::win::ScopedComPtr<IWebBrowserPriv2Common, NULL> browser_priv2; |
| 882 for (int i = 0; i < arraysize(interface_ids) && browser_priv2 == NULL; | 881 for (int i = 0; i < arraysize(interface_ids) && browser_priv2 == NULL; |
| 883 ++i) { | 882 ++i) { |
| 884 hr = web_browser2.QueryInterface(*interface_ids[i], | 883 hr = web_browser2.QueryInterface(*interface_ids[i], |
| 885 reinterpret_cast<void**>(browser_priv2.Receive())); | 884 reinterpret_cast<void**>(browser_priv2.Receive())); |
| 886 } | 885 } |
| 887 | 886 |
| 888 DCHECK(browser_priv2); | 887 DCHECK(browser_priv2); |
| 889 | 888 |
| 890 if (browser_priv2) { | 889 if (browser_priv2) { |
| 891 ScopedComPtr<IUri> uri_obj; | 890 base::win::ScopedComPtr<IUri> uri_obj; |
| 892 uri_container->GetIUri(uri_obj.Receive()); | 891 uri_container->GetIUri(uri_obj.Receive()); |
| 893 DCHECK(uri_obj); | 892 DCHECK(uri_obj); |
| 894 | 893 |
| 895 if (GetIEVersion() < IE_9) { | 894 if (GetIEVersion() < IE_9) { |
| 896 hr = browser_priv2->NavigateWithBindCtx2( | 895 hr = browser_priv2->NavigateWithBindCtx2( |
| 897 uri_obj, &flags, NULL, post_data_variant.AsInput(), | 896 uri_obj, &flags, NULL, post_data_variant.AsInput(), |
| 898 headers_var.AsInput(), bind_ctx, | 897 headers_var.AsInput(), bind_ctx, |
| 899 const_cast<wchar_t*>(fragment)); | 898 const_cast<wchar_t*>(fragment)); |
| 900 } else { | 899 } else { |
| 901 IWebBrowserPriv2CommonIE9* browser_priv2_ie9 = | 900 IWebBrowserPriv2CommonIE9* browser_priv2_ie9 = |
| 902 reinterpret_cast<IWebBrowserPriv2CommonIE9*>(browser_priv2.get()); | 901 reinterpret_cast<IWebBrowserPriv2CommonIE9*>(browser_priv2.get()); |
| 903 hr = browser_priv2_ie9->NavigateWithBindCtx2( | 902 hr = browser_priv2_ie9->NavigateWithBindCtx2( |
| 904 uri_obj, &flags, NULL, post_data_variant.AsInput(), | 903 uri_obj, &flags, NULL, post_data_variant.AsInput(), |
| 905 headers_var.AsInput(), bind_ctx, | 904 headers_var.AsInput(), bind_ctx, |
| 906 const_cast<wchar_t*>(fragment), 0); | 905 const_cast<wchar_t*>(fragment), 0); |
| 907 } | 906 } |
| 908 DLOG_IF(WARNING, FAILED(hr)) | 907 DLOG_IF(WARNING, FAILED(hr)) |
| 909 << base::StringPrintf(L"NavigateWithBindCtx2 0x%08X", hr); | 908 << base::StringPrintf(L"NavigateWithBindCtx2 0x%08X", hr); |
| 910 } | 909 } |
| 911 } else { | 910 } else { |
| 912 // IE6 | 911 // IE6 |
| 913 LPOLESTR url = NULL; | 912 LPOLESTR url = NULL; |
| 914 if (SUCCEEDED(hr = moniker->GetDisplayName(bind_ctx, NULL, &url))) { | 913 if (SUCCEEDED(hr = moniker->GetDisplayName(bind_ctx, NULL, &url))) { |
| 915 DVLOG(1) << __FUNCTION__ << " " << url; | 914 DVLOG(1) << __FUNCTION__ << " " << url; |
| 916 ScopedComPtr<IWebBrowserPriv> browser_priv; | 915 base::win::ScopedComPtr<IWebBrowserPriv> browser_priv; |
| 917 if (SUCCEEDED(hr = browser_priv.QueryFrom(web_browser2))) { | 916 if (SUCCEEDED(hr = browser_priv.QueryFrom(web_browser2))) { |
| 918 GURL target_url(url); | 917 GURL target_url(url); |
| 919 // On IE6 if the original URL has a fragment then the navigation | 918 // On IE6 if the original URL has a fragment then the navigation |
| 920 // attempt is ignored. To workaround this we strip the fragment from | 919 // attempt is ignored. To workaround this we strip the fragment from |
| 921 // the url and initiate the navigation. When the active document loads | 920 // the url and initiate the navigation. When the active document loads |
| 922 // we retrieve the original url with the fragment from the Navigation | 921 // we retrieve the original url with the fragment from the Navigation |
| 923 // manager and use it. | 922 // manager and use it. |
| 924 if (target_url.has_ref()) { | 923 if (target_url.has_ref()) { |
| 925 url_parse::Component comp; | 924 url_parse::Component comp; |
| 926 GURL::Replacements replacements; | 925 GURL::Replacements replacements; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 } | 1013 } |
| 1015 | 1014 |
| 1016 return buffer; | 1015 return buffer; |
| 1017 } | 1016 } |
| 1018 | 1017 |
| 1019 bool IsSubFrameRequest(IUnknown* service_provider) { | 1018 bool IsSubFrameRequest(IUnknown* service_provider) { |
| 1020 DCHECK(service_provider); | 1019 DCHECK(service_provider); |
| 1021 | 1020 |
| 1022 // We need to be able to get at an IWebBrowser2 if we are to decide whether | 1021 // We need to be able to get at an IWebBrowser2 if we are to decide whether |
| 1023 // this request originates from a non-top-level frame. | 1022 // this request originates from a non-top-level frame. |
| 1024 ScopedComPtr<IWebBrowser2> web_browser; | 1023 base::win::ScopedComPtr<IWebBrowser2> web_browser; |
| 1025 HRESULT hr = DoQueryService(IID_ITargetFrame2, service_provider, | 1024 HRESULT hr = DoQueryService(IID_ITargetFrame2, service_provider, |
| 1026 web_browser.Receive()); | 1025 web_browser.Receive()); |
| 1027 | 1026 |
| 1028 bool is_sub_frame_request = false; | 1027 bool is_sub_frame_request = false; |
| 1029 if (web_browser) { | 1028 if (web_browser) { |
| 1030 // Now check to see if we are in a sub-frame. | 1029 // Now check to see if we are in a sub-frame. |
| 1031 ScopedComPtr<IHTMLWindow2> current_frame, parent_frame; | 1030 base::win::ScopedComPtr<IHTMLWindow2> current_frame, parent_frame; |
| 1032 hr = DoQueryService(IID_IHTMLWindow2, service_provider, | 1031 hr = DoQueryService(IID_IHTMLWindow2, service_provider, |
| 1033 current_frame.Receive()); | 1032 current_frame.Receive()); |
| 1034 if (current_frame) { | 1033 if (current_frame) { |
| 1035 // Only the top level window will return self when get_parent is called. | 1034 // Only the top level window will return self when get_parent is called. |
| 1036 current_frame->get_parent(parent_frame.Receive()); | 1035 current_frame->get_parent(parent_frame.Receive()); |
| 1037 if (parent_frame != current_frame) { | 1036 if (parent_frame != current_frame) { |
| 1038 DVLOG(1) << "Sub frame detected"; | 1037 DVLOG(1) << "Sub frame detected"; |
| 1039 is_sub_frame_request = true; | 1038 is_sub_frame_request = true; |
| 1040 } | 1039 } |
| 1041 } | 1040 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 | 1173 |
| 1175 return referrer; | 1174 return referrer; |
| 1176 } | 1175 } |
| 1177 | 1176 |
| 1178 std::string GetHttpHeadersFromBinding(IBinding* binding) { | 1177 std::string GetHttpHeadersFromBinding(IBinding* binding) { |
| 1179 if (binding == NULL) { | 1178 if (binding == NULL) { |
| 1180 DLOG(WARNING) << "GetHttpResponseStatus - no binding_"; | 1179 DLOG(WARNING) << "GetHttpResponseStatus - no binding_"; |
| 1181 return std::string(); | 1180 return std::string(); |
| 1182 } | 1181 } |
| 1183 | 1182 |
| 1184 ScopedComPtr<IWinInetHttpInfo> info; | 1183 base::win::ScopedComPtr<IWinInetHttpInfo> info; |
| 1185 if (FAILED(info.QueryFrom(binding))) { | 1184 if (FAILED(info.QueryFrom(binding))) { |
| 1186 DLOG(WARNING) << "Failed to QI for IWinInetHttpInfo"; | 1185 DLOG(WARNING) << "Failed to QI for IWinInetHttpInfo"; |
| 1187 return std::string(); | 1186 return std::string(); |
| 1188 } | 1187 } |
| 1189 | 1188 |
| 1190 return GetRawHttpHeaders(info); | 1189 return GetRawHttpHeaders(info); |
| 1191 } | 1190 } |
| 1192 | 1191 |
| 1193 int GetHttpResponseStatusFromBinding(IBinding* binding) { | 1192 int GetHttpResponseStatusFromBinding(IBinding* binding) { |
| 1194 DVLOG(1) << __FUNCTION__; | 1193 DVLOG(1) << __FUNCTION__; |
| 1195 if (binding == NULL) { | 1194 if (binding == NULL) { |
| 1196 DLOG(WARNING) << "GetHttpResponseStatus - no binding_"; | 1195 DLOG(WARNING) << "GetHttpResponseStatus - no binding_"; |
| 1197 return 0; | 1196 return 0; |
| 1198 } | 1197 } |
| 1199 | 1198 |
| 1200 int http_status = 0; | 1199 int http_status = 0; |
| 1201 | 1200 |
| 1202 ScopedComPtr<IWinInetHttpInfo> info; | 1201 base::win::ScopedComPtr<IWinInetHttpInfo> info; |
| 1203 if (SUCCEEDED(info.QueryFrom(binding))) { | 1202 if (SUCCEEDED(info.QueryFrom(binding))) { |
| 1204 char status[10] = {0}; | 1203 char status[10] = {0}; |
| 1205 DWORD buf_size = sizeof(status); | 1204 DWORD buf_size = sizeof(status); |
| 1206 DWORD flags = 0; | 1205 DWORD flags = 0; |
| 1207 DWORD reserved = 0; | 1206 DWORD reserved = 0; |
| 1208 if (SUCCEEDED(info->QueryInfo(HTTP_QUERY_STATUS_CODE, status, &buf_size, | 1207 if (SUCCEEDED(info->QueryInfo(HTTP_QUERY_STATUS_CODE, status, &buf_size, |
| 1209 &flags, &reserved))) { | 1208 &flags, &reserved))) { |
| 1210 base::StringToInt(status, &http_status); | 1209 base::StringToInt(status, &http_status); |
| 1211 } else { | 1210 } else { |
| 1212 NOTREACHED() << "Failed to get HTTP status"; | 1211 NOTREACHED() << "Failed to get HTTP status"; |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1625 scoped_ptr<FileVersionInfo> module_version_info( | 1624 scoped_ptr<FileVersionInfo> module_version_info( |
| 1626 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); | 1625 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); |
| 1627 DCHECK(module_version_info.get() != NULL); | 1626 DCHECK(module_version_info.get() != NULL); |
| 1628 return module_version_info->file_version(); | 1627 return module_version_info->file_version(); |
| 1629 } | 1628 } |
| 1630 | 1629 |
| 1631 bool IsChromeFrameDocument(IWebBrowser2* web_browser) { | 1630 bool IsChromeFrameDocument(IWebBrowser2* web_browser) { |
| 1632 if (!web_browser) | 1631 if (!web_browser) |
| 1633 return false; | 1632 return false; |
| 1634 | 1633 |
| 1635 ScopedComPtr<IDispatch> doc; | 1634 base::win::ScopedComPtr<IDispatch> doc; |
| 1636 web_browser->get_Document(doc.Receive()); | 1635 web_browser->get_Document(doc.Receive()); |
| 1637 if (doc) { | 1636 if (doc) { |
| 1638 // Detect if CF is rendering based on whether the document is a | 1637 // Detect if CF is rendering based on whether the document is a |
| 1639 // ChromeActiveDocument. Detecting based on hwnd is problematic as | 1638 // ChromeActiveDocument. Detecting based on hwnd is problematic as |
| 1640 // the CF Active Document window may not have been created yet. | 1639 // the CF Active Document window may not have been created yet. |
| 1641 ScopedComPtr<IChromeFrame> chrome_frame; | 1640 base::win::ScopedComPtr<IChromeFrame> chrome_frame; |
| 1642 chrome_frame.QueryFrom(doc); | 1641 chrome_frame.QueryFrom(doc); |
| 1643 return chrome_frame.get() != NULL; | 1642 return chrome_frame.get() != NULL; |
| 1644 } | 1643 } |
| 1645 return false; | 1644 return false; |
| 1646 } | 1645 } |
| 1647 | 1646 |
| 1648 bool IncreaseWinInetConnections(DWORD connections) { | 1647 bool IncreaseWinInetConnections(DWORD connections) { |
| 1649 static bool wininet_connection_count_updated = false; | 1648 static bool wininet_connection_count_updated = false; |
| 1650 if (wininet_connection_count_updated) { | 1649 if (wininet_connection_count_updated) { |
| 1651 return true; | 1650 return true; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1671 ret = InternetSetOption(NULL, connection_options[option_index], | 1670 ret = InternetSetOption(NULL, connection_options[option_index], |
| 1672 &connections, connection_value_size); | 1671 &connections, connection_value_size); |
| 1673 if (!ret) { | 1672 if (!ret) { |
| 1674 return false; | 1673 return false; |
| 1675 } | 1674 } |
| 1676 } | 1675 } |
| 1677 wininet_connection_count_updated = true; | 1676 wininet_connection_count_updated = true; |
| 1678 return true; | 1677 return true; |
| 1679 } | 1678 } |
| 1680 | 1679 |
| OLD | NEW |