OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 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 <shlobj.h> |
| 6 |
| 7 #include "chrome_frame/html_utils.h" |
| 8 #include "chrome_frame/utils.h" |
| 9 |
| 10 #include "base/file_util.h" |
| 11 #include "base/file_version_info.h" |
| 12 #include "base/logging.h" |
| 13 #include "base/path_service.h" |
| 14 #include "base/registry.h" |
| 15 #include "base/scoped_comptr_win.h" |
| 16 #include "base/string_util.h" |
| 17 #include "chrome/common/chrome_constants.h" |
| 18 #include "chrome/installer/util/google_update_constants.h" |
| 19 #include "googleurl/src/gurl.h" |
| 20 #include "grit/chrome_frame_resources.h" |
| 21 #include "chrome_frame/resource.h" |
| 22 |
| 23 // Note that these values are all lower case and are compared to |
| 24 // lower-case-transformed values. |
| 25 const wchar_t kMetaTag[] = L"meta"; |
| 26 const wchar_t kHttpEquivAttribName[] = L"http-equiv"; |
| 27 const wchar_t kContentAttribName[] = L"content"; |
| 28 const wchar_t kXUACompatValue[] = L"x-ua-compatible"; |
| 29 const wchar_t kBodyTag[] = L"body"; |
| 30 const wchar_t kChromeContentPrefix[] = L"chrome="; |
| 31 const wchar_t kChromeProtocolPrefix[] = L"cf:"; |
| 32 |
| 33 static const wchar_t kChromeFrameConfigKey[] = |
| 34 L"Software\\Google\\ChromeFrame"; |
| 35 static const wchar_t kChromeFrameOptinUrlsKey[] = L"OptinUrls"; |
| 36 |
| 37 // Used to isolate chrome frame builds from google chrome release channels. |
| 38 const wchar_t kChromeFrameOmahaSuffix[] = L"-cf"; |
| 39 const wchar_t kDevChannelName[] = L"-dev"; |
| 40 |
| 41 const wchar_t kChromeAttachExternalTabPrefix[] = L"attach_external_tab"; |
| 42 |
| 43 HRESULT UtilRegisterTypeLib(HINSTANCE tlb_instance, |
| 44 LPCOLESTR index, |
| 45 bool for_current_user_only) { |
| 46 CComBSTR path; |
| 47 CComPtr<ITypeLib> type_lib; |
| 48 HRESULT hr = AtlLoadTypeLib(tlb_instance, index, &path, &type_lib); |
| 49 if (SUCCEEDED(hr)) { |
| 50 hr = UtilRegisterTypeLib(type_lib, path, NULL, for_current_user_only); |
| 51 } |
| 52 return hr; |
| 53 } |
| 54 |
| 55 HRESULT UtilUnRegisterTypeLib(HINSTANCE tlb_instance, |
| 56 LPCOLESTR index, |
| 57 bool for_current_user_only) { |
| 58 CComBSTR path; |
| 59 CComPtr<ITypeLib> type_lib; |
| 60 HRESULT hr = AtlLoadTypeLib(tlb_instance, index, &path, &type_lib); |
| 61 if (SUCCEEDED(hr)) { |
| 62 hr = UtilUnRegisterTypeLib(type_lib, for_current_user_only); |
| 63 } |
| 64 return hr; |
| 65 } |
| 66 |
| 67 HRESULT UtilRegisterTypeLib(LPCWSTR typelib_path, |
| 68 bool for_current_user_only) { |
| 69 if (NULL == typelib_path) { |
| 70 return E_INVALIDARG; |
| 71 } |
| 72 CComBSTR path; |
| 73 CComPtr<ITypeLib> type_lib; |
| 74 HRESULT hr = ::LoadTypeLib(typelib_path, &type_lib); |
| 75 if (SUCCEEDED(hr)) { |
| 76 hr = UtilRegisterTypeLib(type_lib, |
| 77 typelib_path, |
| 78 NULL, |
| 79 for_current_user_only); |
| 80 } |
| 81 return hr; |
| 82 } |
| 83 |
| 84 HRESULT UtilUnRegisterTypeLib(LPCWSTR typelib_path, |
| 85 bool for_current_user_only) { |
| 86 CComPtr<ITypeLib> type_lib; |
| 87 HRESULT hr = ::LoadTypeLib(typelib_path, &type_lib); |
| 88 if (SUCCEEDED(hr)) { |
| 89 hr = UtilUnRegisterTypeLib(type_lib, for_current_user_only); |
| 90 } |
| 91 return hr; |
| 92 } |
| 93 |
| 94 HRESULT UtilRegisterTypeLib(ITypeLib* typelib, |
| 95 LPCWSTR typelib_path, |
| 96 LPCWSTR help_dir, |
| 97 bool for_current_user_only) { |
| 98 typedef HRESULT(WINAPI *RegisterTypeLibPrototype)(ITypeLib FAR* type_lib, |
| 99 OLECHAR FAR* full_path, |
| 100 OLECHAR FAR* help_dir); |
| 101 LPCSTR function_name = |
| 102 for_current_user_only ? "RegisterTypeLibForUser" : "RegisterTypeLib"; |
| 103 RegisterTypeLibPrototype reg_tlb = |
| 104 reinterpret_cast<RegisterTypeLibPrototype>( |
| 105 GetProcAddress(GetModuleHandle(_T("oleaut32.dll")), |
| 106 function_name)); |
| 107 if (NULL == reg_tlb) { |
| 108 return E_FAIL; |
| 109 } |
| 110 return reg_tlb(typelib, |
| 111 const_cast<OLECHAR*>(typelib_path), |
| 112 const_cast<OLECHAR*>(help_dir)); |
| 113 } |
| 114 |
| 115 HRESULT UtilUnRegisterTypeLib(ITypeLib* typelib, |
| 116 bool for_current_user_only) { |
| 117 if (NULL == typelib) { |
| 118 return E_INVALIDARG; |
| 119 } |
| 120 typedef HRESULT(WINAPI *UnRegisterTypeLibPrototype)( |
| 121 REFGUID libID, |
| 122 unsigned short wVerMajor, // NOLINT |
| 123 unsigned short wVerMinor, // NOLINT |
| 124 LCID lcid, |
| 125 SYSKIND syskind); |
| 126 LPCSTR function_name = |
| 127 for_current_user_only ? "UnRegisterTypeLibForUser" : "UnRegisterTypeLib"; |
| 128 |
| 129 UnRegisterTypeLibPrototype unreg_tlb = |
| 130 reinterpret_cast<UnRegisterTypeLibPrototype>( |
| 131 GetProcAddress(GetModuleHandle(_T("oleaut32.dll")), |
| 132 function_name)); |
| 133 if (NULL == unreg_tlb) { |
| 134 return E_FAIL; |
| 135 } |
| 136 TLIBATTR* tla = NULL; |
| 137 HRESULT hr = typelib->GetLibAttr(&tla); |
| 138 if (SUCCEEDED(hr)) { |
| 139 hr = unreg_tlb(tla->guid, |
| 140 tla->wMajorVerNum, |
| 141 tla->wMinorVerNum, |
| 142 tla->lcid, |
| 143 tla->syskind); |
| 144 typelib->ReleaseTLibAttr(tla); |
| 145 } |
| 146 return hr; |
| 147 } |
| 148 |
| 149 HRESULT UtilGetXUACompatContentValue(const std::wstring& html_string, |
| 150 std::wstring* content_value) { |
| 151 if (!content_value) { |
| 152 return E_POINTER; |
| 153 } |
| 154 |
| 155 // Fail fast if the string X-UA-Compatible isn't in html_string |
| 156 if (StringToLowerASCII(html_string).find(kXUACompatValue) == |
| 157 std::wstring::npos) { |
| 158 return E_FAIL; |
| 159 } |
| 160 |
| 161 HTMLScanner scanner(html_string.c_str()); |
| 162 |
| 163 // Build the list of meta tags that occur before the body tag is hit. |
| 164 HTMLScanner::StringRangeList tag_list; |
| 165 scanner.GetTagsByName(kMetaTag, &tag_list, kBodyTag); |
| 166 |
| 167 // Search the list of meta tags for one with an http-equiv="X-UA-Compatible" |
| 168 // attribute. |
| 169 HTMLScanner::StringRange attribute; |
| 170 std::string search_attribute_ascii(WideToASCII(kXUACompatValue)); |
| 171 HTMLScanner::StringRangeList::const_iterator tag_list_iter(tag_list.begin()); |
| 172 for (; tag_list_iter != tag_list.end(); tag_list_iter++) { |
| 173 if (!tag_list_iter->GetTagAttribute(kHttpEquivAttribName, &attribute)) { |
| 174 continue; |
| 175 } |
| 176 |
| 177 // We found an http-equiv meta tag, check its value using the ascii |
| 178 // case-insensitive comparison method. |
| 179 if (!attribute.LowerCaseEqualsASCII(search_attribute_ascii.c_str())) { |
| 180 continue; |
| 181 } |
| 182 |
| 183 // We found our X-UA-Compatible meta tag so look for and extract |
| 184 // the value of the content attribute. |
| 185 if (!tag_list_iter->GetTagAttribute(kContentAttribName, &attribute)) { |
| 186 continue; |
| 187 } |
| 188 |
| 189 // Found the content string, copy and return. |
| 190 content_value->assign(attribute.Copy()); |
| 191 return S_OK; |
| 192 } |
| 193 |
| 194 return E_FAIL; |
| 195 } |
| 196 |
| 197 bool AppendSuffixToChannelName(std::wstring* string, |
| 198 const std::wstring& channel_name, |
| 199 const std::wstring& suffix) { |
| 200 size_t pos = string->find(channel_name); |
| 201 // Append the suffix only if we find the channel name. |
| 202 if (pos != std::wstring::npos) { |
| 203 pos += channel_name.size(); |
| 204 // Append the suffix only to the channel name only if the name is not |
| 205 // already followed by suffix. |
| 206 if (string->find(suffix, pos) != pos) { |
| 207 string->insert(pos, suffix); |
| 208 return true; |
| 209 } |
| 210 } |
| 211 return false; |
| 212 } |
| 213 |
| 214 bool RemoveSuffixFromChannelName(std::wstring* string, |
| 215 const std::wstring& channel_name, |
| 216 const std::wstring& suffix) { |
| 217 std::wstring decorated_channel(channel_name + suffix); |
| 218 size_t pos = string->find(decorated_channel); |
| 219 // TODO(robertshield): Remove the suffix iff the suffix is the last thing in |
| 220 // the string or is followed by another suffix that starts with '-'. |
| 221 if (pos != std::wstring::npos) { |
| 222 pos += channel_name.size(); |
| 223 string->erase(pos, suffix.size()); |
| 224 return true; |
| 225 } |
| 226 return false; |
| 227 } |
| 228 |
| 229 HRESULT UtilUpdateOmahaConfig(bool add_cf_suffix) { |
| 230 HKEY reg_root = HKEY_LOCAL_MACHINE; |
| 231 |
| 232 RegKey key; |
| 233 std::wstring ap_key_value; |
| 234 std::wstring reg_key(google_update::kRegPathClientState); |
| 235 reg_key.append(L"\\"); |
| 236 reg_key.append(google_update::kChromeGuid); |
| 237 if (!key.Open(reg_root, reg_key.c_str(), KEY_READ | KEY_WRITE) || |
| 238 !key.ReadValue(google_update::kRegApField, &ap_key_value)) { |
| 239 // Can't read the Omaha config. |
| 240 return REGDB_E_READREGDB; |
| 241 } |
| 242 |
| 243 HRESULT result = S_OK; |
| 244 // We've read the key in, try and modify it then write it back. |
| 245 if (add_cf_suffix && AppendSuffixToChannelName(&ap_key_value, |
| 246 kDevChannelName, |
| 247 kChromeFrameOmahaSuffix)) { |
| 248 if (!key.WriteValue(google_update::kRegApField, ap_key_value.c_str())) { |
| 249 DLOG(ERROR) << "Failed to add suffix to omaha ap key value."; |
| 250 result = REGDB_E_WRITEREGDB; |
| 251 } |
| 252 } else if (!add_cf_suffix && |
| 253 RemoveSuffixFromChannelName(&ap_key_value, |
| 254 kDevChannelName, |
| 255 kChromeFrameOmahaSuffix)) { |
| 256 if (!key.WriteValue(google_update::kRegApField, ap_key_value.c_str())) { |
| 257 DLOG(ERROR) << "Failed to remove suffix from omaha ap key value."; |
| 258 result = REGDB_E_WRITEREGDB; |
| 259 } |
| 260 } else { |
| 261 // Getting here means that no modifications needed to be made. |
| 262 result = S_FALSE; |
| 263 } |
| 264 |
| 265 return result; |
| 266 } |
| 267 |
| 268 std::wstring GetResourceString(int resource_id) { |
| 269 std::wstring resource_string; |
| 270 HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); |
| 271 const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage( |
| 272 this_module, resource_id); |
| 273 if (image) { |
| 274 resource_string.assign(image->achString, image->nLength); |
| 275 } else { |
| 276 NOTREACHED() << "Unable to find resource id " << resource_id; |
| 277 } |
| 278 return resource_string; |
| 279 } |
| 280 |
| 281 void DisplayVersionMismatchWarning(HWND parent, |
| 282 const std::string& server_version) { |
| 283 // Obtain the current module version. |
| 284 FileVersionInfo* file_version_info = |
| 285 FileVersionInfo::CreateFileVersionInfoForCurrentModule(); |
| 286 DCHECK(file_version_info); |
| 287 std::wstring version_string(file_version_info->file_version()); |
| 288 std::wstring wide_server_version; |
| 289 if (server_version.empty()) { |
| 290 wide_server_version = GetResourceString(IDS_VERSIONUNKNOWN); |
| 291 } else { |
| 292 wide_server_version = ASCIIToWide(server_version); |
| 293 } |
| 294 std::wstring title = GetResourceString(IDS_VERSIONMISMATCH_HEADER); |
| 295 std::wstring message; |
| 296 SStringPrintf(&message, GetResourceString(IDS_VERSIONMISMATCH).c_str(), |
| 297 wide_server_version.c_str(), version_string.c_str()); |
| 298 |
| 299 ::MessageBox(parent, message.c_str(), title.c_str(), MB_OK); |
| 300 } |
| 301 |
| 302 std::string CreateJavascript(const std::string& function_name, |
| 303 const std::string args) { |
| 304 std::string script_string = "javascript:"; |
| 305 script_string += function_name + "("; |
| 306 if (!args.empty()) { |
| 307 script_string += "'"; |
| 308 script_string += args; |
| 309 script_string += "'"; |
| 310 } |
| 311 script_string += ")"; |
| 312 return script_string; |
| 313 } |
| 314 |
| 315 AddRefModule::AddRefModule() { |
| 316 // TODO(tommi): Override the module's Lock/Unlock methods to call |
| 317 // npapi::SetValue(NPPVpluginKeepLibraryInMemory) and keep the dll loaded |
| 318 // while the module's refcount is > 0. Only do this when we're being |
| 319 // used as an NPAPI module. |
| 320 _pAtlModule->Lock(); |
| 321 } |
| 322 |
| 323 |
| 324 AddRefModule::~AddRefModule() { |
| 325 _pAtlModule->Unlock(); |
| 326 } |
| 327 |
| 328 namespace { |
| 329 const char kIEImageName[] = "iexplore.exe"; |
| 330 const char kFirefoxImageName[] = "firefox.exe"; |
| 331 const char kOperaImageName[] = "opera.exe"; |
| 332 } // namespace |
| 333 |
| 334 std::wstring GetHostProcessName(bool include_extension) { |
| 335 FilePath exe; |
| 336 if (PathService::Get(base::FILE_EXE, &exe)) |
| 337 exe = exe.BaseName(); |
| 338 if (!include_extension) { |
| 339 exe = exe.RemoveExtension(); |
| 340 } |
| 341 return exe.ToWStringHack(); |
| 342 } |
| 343 |
| 344 BrowserType GetBrowserType() { |
| 345 static BrowserType browser_type = BROWSER_INVALID; |
| 346 |
| 347 if (browser_type == BROWSER_INVALID) { |
| 348 std::wstring exe(GetHostProcessName(true)); |
| 349 if (!exe.empty()) { |
| 350 std::wstring::const_iterator begin = exe.begin(); |
| 351 std::wstring::const_iterator end = exe.end(); |
| 352 if (LowerCaseEqualsASCII(begin, end, kIEImageName)) { |
| 353 browser_type = BROWSER_IE; |
| 354 } else if (LowerCaseEqualsASCII(begin, end, kFirefoxImageName)) { |
| 355 browser_type = BROWSER_FIREFOX; |
| 356 } else if (LowerCaseEqualsASCII(begin, end, kOperaImageName)) { |
| 357 browser_type = BROWSER_OPERA; |
| 358 } else { |
| 359 browser_type = BROWSER_UNKNOWN; |
| 360 } |
| 361 } else { |
| 362 NOTREACHED(); |
| 363 } |
| 364 } |
| 365 |
| 366 return browser_type; |
| 367 } |
| 368 |
| 369 IEVersion GetIEVersion() { |
| 370 static IEVersion ie_version = IE_INVALID; |
| 371 |
| 372 if (ie_version == IE_INVALID) { |
| 373 wchar_t exe_path[MAX_PATH]; |
| 374 HMODULE mod = GetModuleHandle(NULL); |
| 375 GetModuleFileName(mod, exe_path, arraysize(exe_path) - 1); |
| 376 std::wstring exe_name(file_util::GetFilenameFromPath(exe_path)); |
| 377 if (!LowerCaseEqualsASCII(exe_name, kIEImageName)) { |
| 378 ie_version = NON_IE; |
| 379 } else { |
| 380 uint32 high = 0; |
| 381 uint32 low = 0; |
| 382 if (GetModuleVersion(mod, &high, &low)) { |
| 383 switch (HIWORD(high)) { |
| 384 case 6: |
| 385 ie_version = IE_6; |
| 386 break; |
| 387 case 7: |
| 388 ie_version = IE_7; |
| 389 break; |
| 390 default: |
| 391 ie_version = HIWORD(high) >= 8 ? IE_8 : IE_UNSUPPORTED; |
| 392 break; |
| 393 } |
| 394 } else { |
| 395 NOTREACHED() << "Can't get IE version"; |
| 396 } |
| 397 } |
| 398 } |
| 399 |
| 400 return ie_version; |
| 401 } |
| 402 |
| 403 bool IsIEInPrivate() { |
| 404 typedef BOOL (WINAPI* IEIsInPrivateBrowsingPtr)(); |
| 405 bool incognito_mode = false; |
| 406 HMODULE h = GetModuleHandle(L"ieframe.dll"); |
| 407 if (h) { |
| 408 IEIsInPrivateBrowsingPtr IsInPrivate = |
| 409 reinterpret_cast<IEIsInPrivateBrowsingPtr>(GetProcAddress(h, |
| 410 "IEIsInPrivateBrowsing")); |
| 411 if (IsInPrivate) { |
| 412 incognito_mode = !!IsInPrivate(); |
| 413 } |
| 414 } |
| 415 |
| 416 return incognito_mode; |
| 417 } |
| 418 |
| 419 bool GetModuleVersion(HMODULE module, uint32* high, uint32* low) { |
| 420 DCHECK(module != NULL) |
| 421 << "Please use GetModuleHandle(NULL) to get the process name"; |
| 422 DCHECK(high); |
| 423 |
| 424 bool ok = false; |
| 425 |
| 426 HRSRC res = FindResource(module, |
| 427 reinterpret_cast<const wchar_t*>(VS_VERSION_INFO), RT_VERSION); |
| 428 if (res) { |
| 429 HGLOBAL res_data = LoadResource(module, res); |
| 430 DWORD version_resource_size = SizeofResource(module, res); |
| 431 const void* readonly_resource_data = LockResource(res_data); |
| 432 if (readonly_resource_data && version_resource_size) { |
| 433 // Copy data as VerQueryValue tries to modify the data. This causes |
| 434 // exceptions and heap corruption errors if debugger is attached. |
| 435 scoped_ptr<char> data(new char[version_resource_size]); |
| 436 memcpy(data.get(), readonly_resource_data, version_resource_size); |
| 437 if (data.get()) { |
| 438 VS_FIXEDFILEINFO* ver_info = NULL; |
| 439 UINT info_size = 0; |
| 440 if (VerQueryValue(data.get(), L"\\", |
| 441 reinterpret_cast<void**>(&ver_info), &info_size)) { |
| 442 *high = ver_info->dwFileVersionMS; |
| 443 if (low != NULL) |
| 444 *low = ver_info->dwFileVersionLS; |
| 445 ok = true; |
| 446 } |
| 447 |
| 448 UnlockResource(res_data); |
| 449 } |
| 450 FreeResource(res_data); |
| 451 } |
| 452 } |
| 453 |
| 454 return ok; |
| 455 } |
| 456 |
| 457 namespace { |
| 458 |
| 459 const int kMaxSubmenuDepth = 10; |
| 460 |
| 461 // Copies original_menu and returns the copy. The caller is responsible for |
| 462 // closing the returned HMENU. This does not currently copy over bitmaps |
| 463 // (e.g. hbmpChecked, hbmpUnchecked or hbmpItem), so checkmarks, radio buttons, |
| 464 // and custom icons won't work. |
| 465 // It also copies over submenus up to a maximum depth of kMaxSubMenuDepth. |
| 466 // |
| 467 // TODO(robertshield): Add support for the bitmap fields if need be. |
| 468 HMENU UtilCloneContextMenuImpl(HMENU original_menu, int depth) { |
| 469 DCHECK(IsMenu(original_menu)); |
| 470 |
| 471 if (depth >= kMaxSubmenuDepth) |
| 472 return NULL; |
| 473 |
| 474 HMENU new_menu = CreatePopupMenu(); |
| 475 int item_count = GetMenuItemCount(original_menu); |
| 476 if (item_count <= 0) { |
| 477 NOTREACHED(); |
| 478 } else { |
| 479 for (int i = 0; i < item_count; i++) { |
| 480 MENUITEMINFO item_info = { 0 }; |
| 481 item_info.cbSize = sizeof(MENUITEMINFO); |
| 482 item_info.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE | |
| 483 MIIM_STATE | MIIM_DATA | MIIM_SUBMENU | |
| 484 MIIM_CHECKMARKS | MIIM_BITMAP; |
| 485 |
| 486 // Call GetMenuItemInfo a first time to obtain the buffer size for |
| 487 // the label. |
| 488 if (GetMenuItemInfo(original_menu, i, TRUE, &item_info)) { |
| 489 item_info.cch++; // Increment this as per MSDN |
| 490 std::vector<wchar_t> buffer(item_info.cch, 0); |
| 491 item_info.dwTypeData = &buffer[0]; |
| 492 |
| 493 // Call GetMenuItemInfo a second time with dwTypeData set to a buffer |
| 494 // of a correct size to get the label. |
| 495 GetMenuItemInfo(original_menu, i, TRUE, &item_info); |
| 496 |
| 497 // Clone any submenus. Within reason. |
| 498 if (item_info.hSubMenu) { |
| 499 HMENU new_submenu = UtilCloneContextMenuImpl(item_info.hSubMenu, |
| 500 depth + 1); |
| 501 item_info.hSubMenu = new_submenu; |
| 502 } |
| 503 |
| 504 // Now insert the item into the new menu. |
| 505 InsertMenuItem(new_menu, i, TRUE, &item_info); |
| 506 } |
| 507 } |
| 508 } |
| 509 return new_menu; |
| 510 } |
| 511 |
| 512 } // namespace |
| 513 |
| 514 HMENU UtilCloneContextMenu(HMENU original_menu) { |
| 515 return UtilCloneContextMenuImpl(original_menu, 0); |
| 516 } |
| 517 |
| 518 std::string ResolveURL(const std::string& document, |
| 519 const std::string& relative) { |
| 520 if (document.empty()) { |
| 521 return GURL(relative).spec(); |
| 522 } else { |
| 523 return GURL(document).Resolve(relative).spec(); |
| 524 } |
| 525 } |
| 526 |
| 527 bool HaveSameOrigin(const std::string& url1, const std::string& url2) { |
| 528 GURL a(url1), b(url2); |
| 529 bool ret; |
| 530 if (a.is_valid() != b.is_valid()) { |
| 531 // Either (but not both) url is invalid, so they can't match. |
| 532 ret = false; |
| 533 } else if (!a.is_valid()) { |
| 534 // Both URLs are invalid (see first check). Just check if the opaque |
| 535 // strings match exactly. |
| 536 ret = url1.compare(url2) == 0; |
| 537 } else if (a.GetOrigin() != b.GetOrigin()) { |
| 538 // The origins don't match. |
| 539 ret = false; |
| 540 } else { |
| 541 // we have a match. |
| 542 ret = true; |
| 543 } |
| 544 |
| 545 return ret; |
| 546 } |
| 547 |
| 548 int GetConfigInt(int default_value, const wchar_t* value_name) { |
| 549 int ret = default_value; |
| 550 RegKey config_key; |
| 551 if (config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey, |
| 552 KEY_QUERY_VALUE)) { |
| 553 int value = FALSE; |
| 554 if (config_key.ReadValueDW(value_name, reinterpret_cast<DWORD*>(&value))) { |
| 555 ret = value; |
| 556 } |
| 557 } |
| 558 |
| 559 return ret; |
| 560 } |
| 561 |
| 562 bool GetConfigBool(bool default_value, const wchar_t* value_name) { |
| 563 DWORD value = GetConfigInt(default_value, value_name); |
| 564 return (value != FALSE); |
| 565 } |
| 566 |
| 567 bool IsOptInUrl(const wchar_t* url) { |
| 568 RegKey config_key; |
| 569 if (!config_key.Open(HKEY_CURRENT_USER, kChromeFrameConfigKey, KEY_READ)) |
| 570 return false; |
| 571 |
| 572 RegistryValueIterator optin_urls_list(config_key.Handle(), |
| 573 kChromeFrameOptinUrlsKey); |
| 574 while (optin_urls_list.Valid()) { |
| 575 if (MatchPattern(url, optin_urls_list.Name())) |
| 576 return true; |
| 577 ++optin_urls_list; |
| 578 } |
| 579 |
| 580 return false; |
| 581 } |
| 582 |
| 583 HRESULT GetUrlFromMoniker(IMoniker* moniker, IBindCtx* bind_context, |
| 584 std::wstring* url) { |
| 585 if (!moniker || !url) { |
| 586 NOTREACHED(); |
| 587 return E_INVALIDARG; |
| 588 } |
| 589 |
| 590 ScopedComPtr<IBindCtx> temp_bind_context; |
| 591 if (!bind_context) { |
| 592 CreateBindCtx(0, temp_bind_context.Receive()); |
| 593 bind_context = temp_bind_context; |
| 594 } |
| 595 |
| 596 CComHeapPtr<WCHAR> display_name; |
| 597 HRESULT hr = moniker->GetDisplayName(bind_context, NULL, &display_name); |
| 598 if (display_name) |
| 599 *url = display_name; |
| 600 |
| 601 return hr; |
| 602 } |
| 603 |
| 604 bool IsValidUrlScheme(const std::wstring& url) { |
| 605 if (url.empty()) |
| 606 return false; |
| 607 |
| 608 GURL crack_url(url); |
| 609 |
| 610 if (crack_url.SchemeIs("http") || crack_url.SchemeIs("https") || |
| 611 crack_url.SchemeIs("about") || crack_url.SchemeIs("view-source")) |
| 612 return true; |
| 613 |
| 614 if (StartsWith(url, kChromeAttachExternalTabPrefix, false)) |
| 615 return true; |
| 616 |
| 617 return false; |
| 618 } |
| 619 |
| 620 // TODO(robertshield): Register and use Chrome's PathProviders. |
| 621 // - Note that this function is used by unit tests as well to override |
| 622 // PathService paths, so please test when addressing todo. |
| 623 bool GetUserProfileBaseDirectory(std::wstring* path) { |
| 624 DCHECK(path); |
| 625 wchar_t path_buffer[MAX_PATH * 4]; |
| 626 path_buffer[0] = 0; |
| 627 // TODO(robertshield): Ideally we should use SHGetFolderLocation and then |
| 628 // get a path via PIDL. |
| 629 HRESULT hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, |
| 630 SHGFP_TYPE_CURRENT, path_buffer); |
| 631 |
| 632 if (SUCCEEDED(hr)) { |
| 633 *path = path_buffer; |
| 634 #if defined(GOOGLE_CHROME_BUILD) |
| 635 file_util::AppendToPath(path, FILE_PATH_LITERAL("Google")); |
| 636 #endif |
| 637 file_util::AppendToPath(path, chrome::kBrowserAppName); |
| 638 file_util::AppendToPath(path, chrome::kUserDataDirname); |
| 639 return true; |
| 640 } |
| 641 |
| 642 return false; |
| 643 } |
OLD | NEW |