| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/common/platform_util.h" | |
| 6 | |
| 7 #include <commdlg.h> | |
| 8 #include <dwmapi.h> | |
| 9 #include <shellapi.h> | |
| 10 #include <shlobj.h> | |
| 11 | |
| 12 #include "app/win_util.h" | |
| 13 #include "base/file_path.h" | |
| 14 #include "base/file_util.h" | |
| 15 #include "base/path_service.h" | |
| 16 #include "base/logging.h" | |
| 17 #include "base/registry.h" | |
| 18 #include "base/scoped_comptr_win.h" | |
| 19 #include "base/string_util.h" | |
| 20 #include "chrome/installer/util/google_update_settings.h" | |
| 21 #include "chrome/installer/util/google_update_constants.h" | |
| 22 #include "chrome/installer/util/install_util.h" | |
| 23 #include "gfx/native_widget_types.h" | |
| 24 #include "googleurl/src/gurl.h" | |
| 25 | |
| 26 namespace platform_util { | |
| 27 | |
| 28 void ShowItemInFolder(const FilePath& full_path) { | |
| 29 FilePath dir = full_path.DirName(); | |
| 30 // ParseDisplayName will fail if the directory is "C:", it must be "C:\\". | |
| 31 if (dir.value() == L"" || !file_util::EnsureEndsWithSeparator(&dir)) | |
| 32 return; | |
| 33 | |
| 34 typedef HRESULT (WINAPI *SHOpenFolderAndSelectItemsFuncPtr)( | |
| 35 PCIDLIST_ABSOLUTE pidl_Folder, | |
| 36 UINT cidl, | |
| 37 PCUITEMID_CHILD_ARRAY pidls, | |
| 38 DWORD flags); | |
| 39 | |
| 40 static SHOpenFolderAndSelectItemsFuncPtr open_folder_and_select_itemsPtr = | |
| 41 NULL; | |
| 42 static bool initialize_open_folder_proc = true; | |
| 43 if (initialize_open_folder_proc) { | |
| 44 initialize_open_folder_proc = false; | |
| 45 // The SHOpenFolderAndSelectItems API is exposed by shell32 version 6 | |
| 46 // and does not exist in Win2K. We attempt to retrieve this function export | |
| 47 // from shell32 and if it does not exist, we just invoke ShellExecute to | |
| 48 // open the folder thus losing the functionality to select the item in | |
| 49 // the process. | |
| 50 HMODULE shell32_base = GetModuleHandle(L"shell32.dll"); | |
| 51 if (!shell32_base) { | |
| 52 NOTREACHED(); | |
| 53 return; | |
| 54 } | |
| 55 open_folder_and_select_itemsPtr = | |
| 56 reinterpret_cast<SHOpenFolderAndSelectItemsFuncPtr> | |
| 57 (GetProcAddress(shell32_base, "SHOpenFolderAndSelectItems")); | |
| 58 } | |
| 59 if (!open_folder_and_select_itemsPtr) { | |
| 60 ShellExecute(NULL, _T("open"), dir.value().c_str(), NULL, NULL, SW_SHOW); | |
| 61 return; | |
| 62 } | |
| 63 | |
| 64 ScopedComPtr<IShellFolder> desktop; | |
| 65 HRESULT hr = SHGetDesktopFolder(desktop.Receive()); | |
| 66 if (FAILED(hr)) | |
| 67 return; | |
| 68 | |
| 69 win_util::CoMemReleaser<ITEMIDLIST> dir_item; | |
| 70 hr = desktop->ParseDisplayName(NULL, NULL, | |
| 71 const_cast<wchar_t *>(dir.value().c_str()), | |
| 72 NULL, &dir_item, NULL); | |
| 73 if (FAILED(hr)) | |
| 74 return; | |
| 75 | |
| 76 win_util::CoMemReleaser<ITEMIDLIST> file_item; | |
| 77 hr = desktop->ParseDisplayName(NULL, NULL, | |
| 78 const_cast<wchar_t *>(full_path.value().c_str()), | |
| 79 NULL, &file_item, NULL); | |
| 80 if (FAILED(hr)) | |
| 81 return; | |
| 82 | |
| 83 const ITEMIDLIST* highlight[] = { | |
| 84 {file_item}, | |
| 85 }; | |
| 86 (*open_folder_and_select_itemsPtr)(dir_item, arraysize(highlight), | |
| 87 highlight, NULL); | |
| 88 } | |
| 89 | |
| 90 void OpenItem(const FilePath& full_path) { | |
| 91 win_util::OpenItemViaShell(full_path); | |
| 92 } | |
| 93 | |
| 94 void OpenExternal(const GURL& url) { | |
| 95 // Quote the input scheme to be sure that the command does not have | |
| 96 // parameters unexpected by the external program. This url should already | |
| 97 // have been escaped. | |
| 98 std::string escaped_url = url.spec(); | |
| 99 escaped_url.insert(0, "\""); | |
| 100 escaped_url += "\""; | |
| 101 | |
| 102 // According to Mozilla in uriloader/exthandler/win/nsOSHelperAppService.cpp: | |
| 103 // "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in | |
| 104 // ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6 | |
| 105 // support URLS of 2083 chars in length, 2K is safe." | |
| 106 const size_t kMaxUrlLength = 2048; | |
| 107 if (escaped_url.length() > kMaxUrlLength) { | |
| 108 NOTREACHED(); | |
| 109 return; | |
| 110 } | |
| 111 | |
| 112 RegKey key; | |
| 113 std::wstring registry_path = ASCIIToWide(url.scheme()) + | |
| 114 L"\\shell\\open\\command"; | |
| 115 key.Open(HKEY_CLASSES_ROOT, registry_path.c_str()); | |
| 116 if (key.Valid()) { | |
| 117 DWORD size = 0; | |
| 118 key.ReadValue(NULL, NULL, &size); | |
| 119 if (size <= 2) { | |
| 120 // ShellExecute crashes the process when the command is empty. | |
| 121 // We check for "2" because it always returns the trailing NULL. | |
| 122 // TODO(nsylvain): we should also add a dialog to warn on errors. See | |
| 123 // bug 1136923. | |
| 124 return; | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 if (reinterpret_cast<ULONG_PTR>(ShellExecuteA(NULL, "open", | |
| 129 escaped_url.c_str(), NULL, NULL, | |
| 130 SW_SHOWNORMAL)) <= 32) { | |
| 131 // We fail to execute the call. We could display a message to the user. | |
| 132 // TODO(nsylvain): we should also add a dialog to warn on errors. See | |
| 133 // bug 1136923. | |
| 134 return; | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 gfx::NativeWindow GetTopLevel(gfx::NativeView view) { | |
| 139 return GetAncestor(view, GA_ROOT); | |
| 140 } | |
| 141 | |
| 142 bool IsWindowActive(gfx::NativeWindow window) { | |
| 143 return ::GetForegroundWindow() == window; | |
| 144 } | |
| 145 | |
| 146 bool IsVisible(gfx::NativeView view) { | |
| 147 // MSVC complains if we don't include != 0. | |
| 148 return ::IsWindowVisible(view) != 0; | |
| 149 } | |
| 150 | |
| 151 void SimpleErrorBox(gfx::NativeWindow parent, | |
| 152 const string16& title, | |
| 153 const string16& message) { | |
| 154 win_util::MessageBox(parent, message, title, MB_OK | MB_SETFOREGROUND); | |
| 155 } | |
| 156 | |
| 157 string16 GetVersionStringModifier() { | |
| 158 #if defined(GOOGLE_CHROME_BUILD) | |
| 159 FilePath module; | |
| 160 string16 channel; | |
| 161 if (PathService::Get(base::FILE_MODULE, &module)) { | |
| 162 bool is_system_install = | |
| 163 !InstallUtil::IsPerUserInstall(module.value().c_str()); | |
| 164 | |
| 165 GoogleUpdateSettings::GetChromeChannel(is_system_install, &channel); | |
| 166 } | |
| 167 return channel; | |
| 168 #else | |
| 169 return string16(); | |
| 170 #endif | |
| 171 } | |
| 172 | |
| 173 } // namespace platform_util | |
| OLD | NEW |