Index: base/shell.cc |
diff --git a/base/shell.cc b/base/shell.cc |
deleted file mode 100644 |
index 7483b03f78b9609706d745329cd72faa0277c376..0000000000000000000000000000000000000000 |
--- a/base/shell.cc |
+++ /dev/null |
@@ -1,397 +0,0 @@ |
-// Copyright 2003-2009 Google Inc. |
-// |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
-// you may not use this file except in compliance with the License. |
-// You may obtain a copy of the License at |
-// |
-// http://www.apache.org/licenses/LICENSE-2.0 |
-// |
-// Unless required by applicable law or agreed to in writing, software |
-// distributed under the License is distributed on an "AS IS" BASIS, |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-// See the License for the specific language governing permissions and |
-// limitations under the License. |
-// ======================================================================== |
-// |
-// Shell functions |
- |
-#include "omaha/base/shell.h" |
- |
-#include <shlobj.h> |
-#include <shellapi.h> |
-#include "omaha/base/app_util.h" |
-#include "omaha/base/browser_utils.h" |
-#include "omaha/base/const_utils.h" |
-#include "omaha/base/debug.h" |
-#include "omaha/base/error.h" |
-#include "omaha/base/file.h" |
-#include "omaha/base/logging.h" |
-#include "omaha/base/path.h" |
-#include "omaha/base/reg_key.h" |
-#include "omaha/base/scoped_any.h" |
-#include "omaha/base/string.h" |
-#include "omaha/base/system.h" |
-#include "omaha/base/utils.h" |
- |
-namespace omaha { |
- |
-// create and store a shortcut |
-// uses shell IShellLink and IPersistFile interfaces |
-HRESULT Shell::CreateLink(const TCHAR *source, |
- const TCHAR *destination, |
- const TCHAR *working_dir, |
- const TCHAR *arguments, |
- const TCHAR *description, |
- WORD hotkey_virtual_key_code, |
- WORD hotkey_modifiers, |
- const TCHAR *icon) { |
- ASSERT1(source); |
- ASSERT1(destination); |
- ASSERT1(working_dir); |
- ASSERT1(arguments); |
- ASSERT1(description); |
- |
- scoped_co_init co_init(COINIT_APARTMENTTHREADED); |
- HRESULT hr = co_init.hresult(); |
- if (FAILED(hr) && hr != RPC_E_CHANGED_MODE) { |
- UTIL_LOG(LEVEL_ERROR, (_T("[Shell::CreateLink - failed to co_init]"), hr)); |
- return hr; |
- } |
- |
- UTIL_LOG(L1, (_T("[Create shell link]") |
- _T("[source %s dest %s dir %s arg %s desc %s hotkey %x:%x]"), |
- source, destination, working_dir, arguments, description, |
- hotkey_modifiers, hotkey_virtual_key_code)); |
- |
- // Get a pointer to the IShellLink interface |
- CComPtr<IShellLink> shell_link; |
- |
- RET_IF_FAILED(shell_link.CoCreateInstance(CLSID_ShellLink)); |
- ASSERT(shell_link, (L"")); |
- |
- // Set the path to the shortcut target and add the description |
- VERIFY1(SUCCEEDED(shell_link->SetPath(source))); |
- VERIFY1(SUCCEEDED(shell_link->SetArguments(arguments))); |
- VERIFY1(SUCCEEDED(shell_link->SetDescription(description))); |
- VERIFY1(SUCCEEDED(shell_link->SetWorkingDirectory(working_dir))); |
- |
- // If we are given an icon, then set it |
- // For now, we always use the first icon if this happens to have multiple ones |
- if (icon) { |
- VERIFY1(SUCCEEDED(shell_link->SetIconLocation(icon, 0))); |
- } |
- |
-// C4201: nonstandard extension used : nameless struct/union |
-#pragma warning(disable : 4201) |
- union { |
- WORD flags; |
- struct { // little-endian machine: |
- WORD virtual_key:8; // low order byte |
- WORD modifiers:8; // high order byte |
- }; |
- } hot_key; |
-#pragma warning(default : 4201) |
- |
- hot_key.virtual_key = hotkey_virtual_key_code; |
- hot_key.modifiers = hotkey_modifiers; |
- |
- if (hot_key.flags) { |
- shell_link->SetHotkey(hot_key.flags); |
- } |
- |
- // Query IShellLink for the IPersistFile interface for saving the shortcut in |
- // persistent storage |
- CComQIPtr<IPersistFile> persist_file(shell_link); |
- if (!persist_file) |
- return E_FAIL; |
- |
- // Save the link by calling IPersistFile::Save |
- RET_IF_FAILED(persist_file->Save(destination, TRUE)); |
- |
- return S_OK; |
-} |
- |
-HRESULT Shell::RemoveLink(const TCHAR *link) { |
- ASSERT(link, (L"")); |
- ASSERT(*link, (L"")); |
- |
- return File::Remove(link); |
-} |
- |
-// Open a URL in a new browser window |
-HRESULT Shell::OpenLinkInNewWindow(const TCHAR* url, UseBrowser use_browser) { |
- ASSERT1(url); |
- |
- HRESULT hr = S_OK; |
- CString browser_path; |
- |
- // Try to open with default browser |
- if (use_browser == USE_DEFAULT_BROWSER) { |
- // Load full browser path from regkey |
- hr = GetDefaultBrowserPath(&browser_path); |
- |
- // If there is a default browser and it is not AOL, load the url in that |
- // browser |
- if (SUCCEEDED(hr) && !String_Contains(browser_path, _T("aol"))) { |
- if (!browser_path.IsEmpty()) { |
- // Have we figured out how to append the URL onto the browser path? |
- bool acceptable_url = false; |
- |
- if (ReplaceCString(browser_path, _T("\"%1\""), url)) { |
- // the "browser.exe "%1"" case |
- acceptable_url = true; |
- } else if (ReplaceCString(browser_path, _T("%1"), url)) { |
- // the "browser.exe %1 "case |
- acceptable_url = true; |
- } else if (ReplaceCString(browser_path, _T("-nohome"), url)) { |
- // the "browser.exe -nohome" case |
- acceptable_url = true; |
- } else { |
- // the browser.exe case. |
- // simply append the quoted url. |
- EnclosePath(&browser_path); |
- browser_path.AppendChar(_T(' ')); |
- CString quoted_url(url); |
- EnclosePath("ed_url); |
- browser_path.Append(quoted_url); |
- acceptable_url = true; |
- } |
- |
- if (acceptable_url) { |
- hr = System::ShellExecuteCommandLine(browser_path, NULL, NULL); |
- if (SUCCEEDED(hr)) { |
- return S_OK; |
- } else { |
- UTIL_LOG(LE, (_T("[Shell::OpenLinkInNewWindow]") |
- _T("[failed to start default browser to open url]") |
- _T("[%s][0x%x]"), url, hr)); |
- } |
- } |
- } |
- } |
- } |
- |
- // Try to open with IE if can't open with default browser or required |
- if (use_browser == USE_DEFAULT_BROWSER || |
- use_browser == USE_INTERNET_EXPLORER) { |
- hr = RegKey::GetValue(kRegKeyIeClass, kRegValueIeClass, &browser_path); |
- if (SUCCEEDED(hr)) { |
- hr = System::ShellExecuteProcess(browser_path, url, NULL, NULL); |
- if (SUCCEEDED(hr)) { |
- return S_OK; |
- } else { |
- UTIL_LOG(LE, (_T("[Shell::OpenLinkInNewWindow]") |
- _T("[failed to start IE to open url][%s][0x%x]"), |
- url, hr)); |
- } |
- } |
- } |
- |
- // Try to open with Firefox if can't open with default browser or required |
- if (use_browser == USE_DEFAULT_BROWSER || use_browser == USE_FIREFOX) { |
- hr = RegKey::GetValue(kRegKeyFirefox, kRegValueFirefox, &browser_path); |
- if (SUCCEEDED(hr) && !browser_path.IsEmpty()) { |
- ReplaceCString(browser_path, _T("%1"), url); |
- hr = System::ShellExecuteCommandLine(browser_path, NULL, NULL); |
- if (SUCCEEDED(hr)) { |
- return S_OK; |
- } else { |
- UTIL_LOG(LE, (_T("[Shell::OpenLinkInNewWindow]") |
- _T("[failed to start Firefox to open url][%s][0x%x]"), |
- url, hr)); |
- } |
- } |
- } |
- |
- // ShellExecute the url directly as a last resort |
- hr = Shell::Execute(url); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[Shell::OpenLinkInNewWindow]") |
- _T("[failed to run ShellExecute to open url][%s][0x%x]"), |
- url, hr)); |
- } |
- |
- return hr; |
-} |
- |
-HRESULT Shell::Execute(const TCHAR* file) { |
- ASSERT1(file); |
- |
- // Prepare everything required for ::ShellExecuteEx(). |
- SHELLEXECUTEINFO sei; |
- SetZero(sei); |
- sei.cbSize = sizeof(sei); |
- sei.fMask = SEE_MASK_FLAG_NO_UI | // Do not display an error message box. |
- SEE_MASK_NOZONECHECKS | // Do not perform a zone check. |
- SEE_MASK_NOASYNC; // Wait to complete before returning. |
- // Pass NULL for hwnd. This will have ShellExecuteExEnsureParent() |
- // create a dummy parent window for us. |
- // sei.hwnd = NULL; |
- sei.lpVerb = _T("open"); |
- sei.lpFile = file; |
- // No parameters to pass |
- // sei.lpParameters = NULL; |
- // Use parent's starting directory |
- // sei.lpDirectory = NULL; |
- sei.nShow = SW_SHOWNORMAL; |
- |
- // Use ShellExecuteExEnsureParent to ensure that we always have a parent HWND. |
- // We need to use the HWND Property to be acknowledged as a Foreground |
- // Application on Vista. Otherwise, the elevation prompt will appear minimized |
- // on the taskbar. |
- if (!ShellExecuteExEnsureParent(&sei)) { |
- HRESULT hr(HRESULTFromLastError()); |
- ASSERT(false, |
- (_T("Shell::Execute - ShellExecuteEx failed][%s][0x%x]"), file, hr)); |
- return hr; |
- } |
- |
- return S_OK; |
-} |
- |
-HRESULT Shell::BasicGetSpecialFolder(DWORD csidl, CString* folder_path) { |
- ASSERT1(folder_path); |
- |
- // Get a ITEMIDLIST* (called a PIDL in the MSDN documentation) to the |
- // special folder |
- scoped_any<ITEMIDLIST*, close_co_task_free> folder_location; |
- RET_IF_FAILED(::SHGetFolderLocation(NULL, |
- csidl, |
- NULL, |
- 0, |
- address(folder_location))); |
- ASSERT(get(folder_location), (_T(""))); |
- |
- // Get an interface to the Desktop folder |
- CComPtr<IShellFolder> desktop_folder; |
- RET_IF_FAILED(::SHGetDesktopFolder(&desktop_folder)); |
- ASSERT1(desktop_folder); |
- |
- // Ask the desktop for the display name of the special folder |
- STRRET str_return; |
- SetZero(str_return); |
- str_return.uType = STRRET_WSTR; |
- RET_IF_FAILED(desktop_folder->GetDisplayNameOf(get(folder_location), |
- SHGDN_FORPARSING, |
- &str_return)); |
- |
- // Get the display name of the special folder and return it |
- scoped_any<wchar_t*, close_co_task_free> folder_name; |
- RET_IF_FAILED(::StrRetToStr(&str_return, |
- get(folder_location), |
- address(folder_name))); |
- *folder_path = get(folder_name); |
- |
- return S_OK; |
-} |
- |
-HRESULT Shell::GetSpecialFolder(DWORD csidl, |
- bool create_if_missing, |
- CString* folder_path) { |
- ASSERT(folder_path, (L"")); |
- |
- HRESULT hr = Shell::BasicGetSpecialFolder(csidl, folder_path); |
- |
- // If the folder does not exist, ::SHGetFolderLocation may return error |
- // code ERROR_FILE_NOT_FOUND. |
- if (create_if_missing) { |
- if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || |
- (SUCCEEDED(hr) && !File::Exists(*folder_path))) { |
- hr = Shell::BasicGetSpecialFolder(csidl | CSIDL_FLAG_CREATE, folder_path); |
- } |
- } |
- ASSERT(FAILED(hr) || File::Exists(*folder_path), (_T(""))); |
- |
- return hr; |
-} |
- |
-#pragma warning(disable : 4510 4610) |
-// C4510: default constructor could not be generated |
-// C4610: struct can never be instantiated - user defined constructor required |
-struct { |
- const TCHAR* name; |
- const DWORD csidl; |
-} const folder_mappings[] = { |
- L"APPDATA", CSIDL_APPDATA, |
- L"DESKTOP", CSIDL_DESKTOPDIRECTORY, |
- L"LOCALAPPDATA", CSIDL_LOCAL_APPDATA, |
- L"MYMUSIC", CSIDL_MYMUSIC, |
- L"MYPICTURES", CSIDL_MYPICTURES, |
- L"PROGRAMFILES", CSIDL_PROGRAM_FILES, |
- L"PROGRAMFILESCOMMON", CSIDL_PROGRAM_FILES_COMMON, |
- L"PROGRAMS", CSIDL_PROGRAMS, |
- L"STARTMENU", CSIDL_STARTMENU, |
- L"STARTUP", CSIDL_STARTUP, |
- L"SYSTEM", CSIDL_SYSTEM, |
- L"WINDOWS", CSIDL_WINDOWS, |
-}; |
-#pragma warning(default : 4510 4610) |
- |
-HRESULT Shell::GetSpecialFolderKeywordsMapping( |
- std::map<CString, CString>* special_folders_map) { |
- ASSERT1(special_folders_map); |
- |
- special_folders_map->clear(); |
- |
- for (size_t i = 0; i < arraysize(folder_mappings); ++i) { |
- CString name(folder_mappings[i].name); |
- DWORD csidl(folder_mappings[i].csidl); |
- CString folder; |
- HRESULT hr = GetSpecialFolder(csidl, false, &folder); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[Shell::GetSpecialFolderKeywordsMapping]") |
- _T("[failed to retrieve %s]"), name)); |
- continue; |
- } |
- special_folders_map->insert(std::make_pair(name, folder)); |
- } |
- |
- // Get the current module directory |
- CString module_dir = app_util::GetModuleDirectory(::GetModuleHandle(NULL)); |
- ASSERT1(module_dir.GetLength() > 0); |
- special_folders_map->insert(std::make_pair(_T("CURRENTMODULEDIR"), |
- module_dir)); |
- |
- return S_OK; |
-} |
- |
-HRESULT Shell::DeleteDirectory(const TCHAR* dir) { |
- ASSERT1(dir && *dir); |
- |
- if (!SafeDirectoryNameForDeletion(dir)) { |
- return E_INVALIDARG; |
- } |
- |
- uint32 dir_len = lstrlen(dir); |
- if (dir_len >= MAX_PATH) { |
- return E_INVALIDARG; |
- } |
- |
- // the 'from' must be double-terminated with 0. Reserve space for one more |
- // zero at the end |
- TCHAR from[MAX_PATH + 1] = {0}; |
- lstrcpyn(from, dir, MAX_PATH); |
- from[1 + dir_len] = 0; // the second zero terminator. |
- |
- SHFILEOPSTRUCT file_op = {0}; |
- |
- file_op.hwnd = 0; |
- file_op.wFunc = FO_DELETE; |
- file_op.pFrom = from; |
- file_op.pTo = 0; |
- file_op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; |
- |
- // ::SHFileOperation returns non-zero on errors |
- return ::SHFileOperation(&file_op) ? HRESULTFromLastError() : S_OK; |
-} |
- |
-HRESULT Shell::GetApplicationExecutablePath(const CString& exe, |
- CString* path) { |
- ASSERT1(path); |
- |
- CString reg_key_name = AppendRegKeyPath(kRegKeyApplicationPath, exe); |
- return RegKey::GetValue(reg_key_name, kRegKeyPathValue, path); |
-} |
- |
-} // namespace omaha |
- |