15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/platform_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <commdlg.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <dwmapi.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shellapi.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/metrics/field_trial.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_co_mem.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_comptr.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/windows_version.h" 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h" 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/common/chrome_utility_messages.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/browser/utility_process_host.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/utility_process_host_client.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/win/shell.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/native_widget_types.h" 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShowItemInFolderOnFileThread(const base::FilePath& full_path) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath dir = full_path.DirName().AsEndingWithSeparator(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ParseDisplayName will fail if the directory is "C:", it must be "C:\\". 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (dir.empty()) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef HRESULT (WINAPI *SHOpenFolderAndSelectItemsFuncPtr)( 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PCIDLIST_ABSOLUTE pidl_Folder, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT cidl, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PCUITEMID_CHILD_ARRAY pidls, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD flags); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SHOpenFolderAndSelectItemsFuncPtr open_folder_and_select_itemsPtr = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool initialize_open_folder_proc = true; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialize_open_folder_proc) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialize_open_folder_proc = false; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The SHOpenFolderAndSelectItems API is exposed by shell32 version 6 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and does not exist in Win2K. We attempt to retrieve this function export 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from shell32 and if it does not exist, we just invoke ShellExecute to 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // open the folder thus losing the functionality to select the item in 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the process. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE shell32_base = GetModuleHandle(L"shell32.dll"); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shell32_base) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << " " << __FUNCTION__ << "(): Can't open shell32.dll"; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open_folder_and_select_itemsPtr = 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<SHOpenFolderAndSelectItemsFuncPtr> 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (GetProcAddress(shell32_base, "SHOpenFolderAndSelectItems")); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!open_folder_and_select_itemsPtr) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShellExecute(NULL, L"open", dir.value().c_str(), NULL, NULL, SW_SHOW); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IShellFolder> desktop; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = SHGetDesktopFolder(desktop.Receive()); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedCoMem<ITEMIDLIST> dir_item; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = desktop->ParseDisplayName(NULL, NULL, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<wchar_t *>(dir.value().c_str()), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, &dir_item, NULL); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedCoMem<ITEMIDLIST> file_item; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = desktop->ParseDisplayName(NULL, NULL, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<wchar_t *>(full_path.value().c_str()), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, &file_item, NULL); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const ITEMIDLIST* highlight[] = { file_item }; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = (*open_folder_and_select_itemsPtr)(dir_item, arraysize(highlight), 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) highlight, NULL); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On some systems, the above call mysteriously fails with "file not 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // found" even though the file is there. In these cases, ShellExecute() 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // seems to work as a fallback (although it won't select the file). 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hr == ERROR_FILE_NOT_FOUND) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShellExecute(NULL, L"open", dir.value().c_str(), NULL, NULL, SW_SHOW); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << " " << __FUNCTION__ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "(): Can't open full_path = \"" 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << full_path.value() << "\"" 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << " hr = " << logging::SystemErrorCodeToString(hr); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Old ShellExecute crashes the process when the command for a given scheme 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is empty. This function tells if it is. 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ValidateShellCommandForScheme(const std::string& scheme) { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::win::RegKey key; 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::wstring registry_path = base::ASCIIToWide(scheme) + 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) L"\\shell\\open\\command"; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key.Open(HKEY_CLASSES_ROOT, registry_path.c_str(), KEY_READ); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!key.Valid()) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DWORD size = 0; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) key.ReadValue(NULL, NULL, &size, NULL); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size <= 2) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OpenExternalOnFileThread(const GURL& url) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Quote the input scheme to be sure that the command does not have 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameters unexpected by the external program. This url should already 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have been escaped. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string escaped_url = url.spec(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) escaped_url.insert(0, "\""); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) escaped_url += "\""; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // According to Mozilla in uriloader/exthandler/win/nsOSHelperAppService.cpp: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // support URLS of 2083 chars in length, 2K is safe." 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kMaxUrlLength = 2048; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (escaped_url.length() > kMaxUrlLength) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_WIN7) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!ValidateShellCommandForScheme(url.scheme())) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reinterpret_cast<ULONG_PTR>(ShellExecuteA(NULL, "open", 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) escaped_url.c_str(), NULL, NULL, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SW_SHOWNORMAL)) <= 32) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We fail to execute the call. We could display a message to the user. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(nsylvain): we should also add a dialog to warn on errors. See 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bug 1136923. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void OpenItemViaShellInUtilityProcess(const base::FilePath& full_path) { 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::WeakPtr<content::UtilityProcessHost> utility_process_host( 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) content::UtilityProcessHost::Create(NULL, NULL)->AsWeakPtr()); 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) utility_process_host->DisableSandbox(); 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) utility_process_host->Send(new ChromeUtilityMsg_OpenItemViaShell(full_path)); 16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace platform_util { 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) { 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::ActivateDesktopHelper(chrome::ASH_KEEP_RUNNING); 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ShowItemInFolderOnFileThread, full_path)); 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OpenItem(Profile* profile, const base::FilePath& full_path) { 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::ActivateDesktopHelper(chrome::ASH_KEEP_RUNNING); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (base::FieldTrialList::FindFullName("IsolateShellOperations") == 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "Enabled") { 19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) BrowserThread::PostTask( 19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) BrowserThread::IO, 19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) FROM_HERE, 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(&OpenItemViaShellInUtilityProcess, full_path)); 19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) BrowserThread::PostTask( 19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) BrowserThread::FILE, 19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) FROM_HERE, 19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(base::IgnoreResult(&ui::win::OpenItemViaShell), full_path)); 20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OpenExternal(Profile* profile, const GURL& url) { 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH && 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !url.SchemeIsHTTPOrHTTPS()) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::ActivateDesktopHelper(chrome::ASH_KEEP_RUNNING); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&OpenExternalOnFileThread, url)); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeWindow GetTopLevel(gfx::NativeView view) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::GetAncestor(view, GA_ROOT); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeView GetParent(gfx::NativeView view) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::GetParent(view); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsWindowActive(gfx::NativeWindow window) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::GetForegroundWindow() == window; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ActivateWindow(gfx::NativeWindow window) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetForegroundWindow(window); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsVisible(gfx::NativeView view) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MSVC complains if we don't include != 0. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::IsWindowVisible(view) != 0; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace platform_util 238