Index: base/path.cc |
diff --git a/base/path.cc b/base/path.cc |
deleted file mode 100644 |
index 1035b7c6ec34d81135502274e468283180f5da9d..0000000000000000000000000000000000000000 |
--- a/base/path.cc |
+++ /dev/null |
@@ -1,461 +0,0 @@ |
-// Copyright 2007-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. |
-// ======================================================================== |
-// |
-// Path utility functions. |
- |
-#include "omaha/base/path.h" |
- |
-#include <atlbase.h> |
-#include <atlstr.h> |
-#include <atlpath.h> |
-#include <map> |
-#include <vector> |
-#include "omaha/base/error.h" |
-#include "omaha/base/file.h" |
-#include "omaha/base/shell.h" |
-#include "omaha/base/string.h" |
-#include "omaha/base/utils.h" |
- |
-namespace omaha { |
- |
-const TCHAR* const kRegSvr32Cmd1 = _T("regsvr32 "); |
-const TCHAR* const kRegSvr32Cmd2 = _T("regsvr32.exe "); |
-const TCHAR* const kRunDll32Cmd1 = _T("rundll32 "); |
-const TCHAR* const kRunDll32Cmd2 = _T("rundll32.exe "); |
-const TCHAR* const kMsiExecCmd1 = _T("msiexec "); |
-const TCHAR* const kMsiExecCmd2 = _T("msiexec.exe "); |
-const TCHAR* const kDotExe = _T(".exe"); |
- |
- |
-namespace detail { |
- |
-typedef bool (*Filter)(const WIN32_FIND_DATA&); |
- |
-bool IsFile(const WIN32_FIND_DATA& find_data) { |
- return (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; |
-} |
- |
-bool IsDirectory(const WIN32_FIND_DATA& find_data) { |
- return (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; |
-} |
- |
-bool AllFiles(const WIN32_FIND_DATA&) { |
- return true; |
-} |
- |
-HRESULT FindFilesEx(const CString& dir, |
- const CString& pattern, |
- std::vector<CString>* files, |
- Filter func) { |
- ASSERT1(files); |
- |
- files->clear(); |
- if (!File::Exists(dir)) { |
- return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND); |
- } |
- |
- CString files_to_find = ConcatenatePath(dir, pattern); |
- WIN32_FIND_DATA find_data = {0}; |
- scoped_hfind hfind(::FindFirstFile(files_to_find, &find_data)); |
- if (!hfind) { |
- HRESULT hr = HRESULTFromLastError(); |
- UTIL_LOG(L5, (_T("[File::GetWildcards - FindFirstFile failed][0x%x]"), hr)); |
- return hr; |
- } |
- |
- do { |
- if (func(find_data)) { |
- files->push_back(find_data.cFileName); |
- } |
- } while (::FindNextFile(get(hfind), &find_data)); |
- |
- return S_OK; |
-} |
- |
-} // namespace detail. |
- |
-// Get the starting path from the command string |
-CString GetStartingPathFromString(const CString& s) { |
- CString path; |
- CString str(s); |
- TrimCString(str); |
- |
- int len = str.GetLength(); |
- if (len > 0) { |
- if (str[0] == _T('"')) { |
- // For something like: "c:\Program Files\...\" ... |
- int idx = String_FindChar(str.GetString() + 1, _T('"')); |
- if (idx != -1) |
- path.SetString(str.GetString() + 1, idx); |
- } else { |
- // For something like: c:\PRGRA~1\... ... |
- int idx = String_FindChar(str, _T(' ')); |
- path.SetString(str, idx == -1 ? len : idx); |
- } |
- } |
- |
- return path; |
-} |
- |
-// Get the trailing path from the command string |
-CString GetTrailingPathFromString(const CString& s) { |
- CString path; |
- CString str(s); |
- TrimCString(str); |
- |
- int len = str.GetLength(); |
- if (len > 0) { |
- if (str[len - 1] == _T('"')) { |
- // For something like: regsvr32 /u /s "c:\Program Files\..." |
- str.Truncate(len - 1); |
- int idx = String_ReverseFindChar(str, _T('"')); |
- if (idx != -1) |
- path.SetString(str.GetString() + idx + 1, len - idx - 1); |
- } else { |
- // For something like: regsvr32 /u /s c:\PRGRA~1\... |
- int idx = String_ReverseFindChar(str, _T(' ')); |
- if (idx != -1) |
- path.SetString(str.GetString() + idx + 1, len - idx - 1); |
- } |
- } |
- |
- return path; |
-} |
- |
-// Get the file from the command string |
-HRESULT GetFileFromCommandString(const TCHAR* s, CString* file) { |
- ASSERT1(file); |
- |
- if (!s || !*s) { |
- return E_INVALIDARG; |
- } |
- |
- CString str(s); |
- TrimCString(str); |
- |
- // Handle the string starting with quotation mark |
- // For example: "C:\Program Files\WinZip\WINZIP32.EXE" /uninstall |
- if (str[0] == _T('"')) { |
- int idx_quote = str.Find(_T('"'), 1); |
- if (idx_quote != -1) { |
- file->SetString(str.GetString() + 1, idx_quote - 1); |
- return S_OK; |
- } else { |
- return E_FAIL; |
- } |
- } |
- |
- // Handle the string starting with "regsvr32" |
- // For example: regsvr32 /u /s "c:\program files\google\googletoolbar3.dll" |
- if (String_StartsWith(str, kRegSvr32Cmd1, true) || |
- String_StartsWith(str, kRegSvr32Cmd2, true)) { |
- file->SetString(GetTrailingPathFromString(str)); |
- return S_OK; |
- } |
- |
- // Handle the string starting with "rundll32" |
- // For example: "rundll32.exe setupapi.dll,InstallHinfSection DefaultUninstall 132 C:\WINDOWS\INF\PCHealth.inf" // NOLINT |
- if (String_StartsWith(str, kRunDll32Cmd1, true) || |
- String_StartsWith(str, kRunDll32Cmd2, true)) { |
- int idx_space = str.Find(_T(' ')); |
- ASSERT1(idx_space != -1); |
- int idx_comma = str.Find(_T(','), idx_space + 1); |
- if (idx_comma != -1) { |
- file->SetString(str.GetString() + idx_space + 1, |
- idx_comma - idx_space - 1); |
- TrimCString(*file); |
- return S_OK; |
- } else { |
- return E_FAIL; |
- } |
- } |
- |
- // Handle the string starting with "msiexec" |
- // For example: MsiExec.exe /I{25A13826-8E4A-4FBF-AD2B-776447FE9646} |
- if (String_StartsWith(str, kMsiExecCmd1, true) || |
- String_StartsWith(str, kMsiExecCmd2, true)) { |
- return E_FAIL; |
- } |
- |
- // Otherwise, try to find the file till reaching ".exe" |
- // For example: "C:\Program Files\Google\Google Desktop Search\GoogleDesktopSetup.exe -uninstall" // NOLINT |
- for (int i = 0; i < str.GetLength(); ++i) { |
- if (String_StartsWith(str.GetString() + i, kDotExe, true)) { |
- file->SetString(str, i + _tcslen(kDotExe)); |
- return S_OK; |
- } |
- } |
- |
- // As last resort, return the part from the beginning to first space found. |
- int idx = str.Find(_T(' ')); |
- if (idx == -1) { |
- file->SetString(str); |
- } else { |
- file->SetString(str, idx); |
- } |
- |
- return S_OK; |
-} |
- |
-// Expands the string with embedded special folder variables. |
-// TODO(omaha): This function seems to have a very specific purpose, which |
-// is not used in our code base. Consider removing it. |
-HRESULT ExpandStringWithSpecialFolders(CString* str) { |
- ASSERT(str, (L"")); |
- |
-#pragma warning(push) |
-// construction of local static object is not thread-safe |
-#pragma warning(disable : 4640) |
- static std::map<CString, CString> g_special_folders_mapping; |
-#pragma warning(pop) |
- |
- if (g_special_folders_mapping.size() == 0) { |
- RET_IF_FAILED( |
- Shell::GetSpecialFolderKeywordsMapping(&g_special_folders_mapping)); |
- } |
- |
- CString expanded_str; |
- RET_IF_FAILED( |
- ExpandEnvLikeStrings(*str, g_special_folders_mapping, &expanded_str)); |
- |
- str->SetString(expanded_str); |
- |
- return S_OK; |
-} |
- |
-// Internal helper method for normalizing a path |
-HRESULT NormalizePathInternal(const TCHAR* path, CString* normalized_path) { |
- // We use '|' to separate fields |
- CString field; |
- int bar_idx = String_FindChar(path, _T('|')); |
- if (bar_idx == -1) |
- field = path; |
- else |
- field.SetString(path, bar_idx); |
- |
- if (IsRegistryPath(field)) { |
- CString key_name, value_name; |
- RET_IF_FAILED(RegSplitKeyvalueName(field, &key_name, &value_name)); |
- |
- CString reg_value; |
- RET_IF_FAILED(RegKey::GetValue(key_name, value_name, ®_value)); |
- normalized_path->Append(reg_value); |
- } else { |
- RET_IF_FAILED(ExpandStringWithSpecialFolders(&field)); |
- normalized_path->Append(field); |
- } |
- |
- if (bar_idx != -1) |
- return NormalizePathInternal(path + bar_idx + 1, normalized_path); |
- else |
- return S_OK; |
-} |
- |
-// Normalize a path |
-HRESULT NormalizePath(const TCHAR* path, CString* normalized_path) { |
- ASSERT1(normalized_path); |
- |
- normalized_path->Empty(); |
- |
- if (path) { |
- HRESULT hr = NormalizePathInternal(path, normalized_path); |
- if (FAILED(hr)) { |
- normalized_path->Empty(); |
- UTIL_LOG(LE, (_T("[NormalizePath - unable to normalize path][%s][0x%x]"), |
- path, hr)); |
- } |
- return hr; |
- } else { |
- return S_OK; |
- } |
-} |
- |
-CString ConcatenatePath(const CString& path1, const CString& path2) { |
- CString ret(path1); |
- |
- // Append the file path using the PathAppend. |
- VERIFY1(::PathAppend(CStrBuf(ret, MAX_PATH), path2)); |
- |
- return ret; |
-} |
- |
-// Get the filename from the path |
-// "C:\TEST\sample.txt" returns "sample.txt" |
-CString GetFileFromPath(const CString& path) { |
- CPath path1(path); |
- path1.StripPath(); |
- return static_cast<CString>(path1); |
-} |
- |
-// Get the directory from the path |
-// "C:\TEST\sample.txt" returns "C:\TEST" |
-// Get the directory out of the file path |
-CString GetDirectoryFromPath(const CString& path) { |
- CPath path1(path); |
- path1.RemoveFileSpec(); |
- return static_cast<CString>(path1); |
-} |
- |
-// Remove the extension from the path. |
-// "C:\TEST\sample.txt" returns "C:\TEST\sample" |
-CString GetPathRemoveExtension(const CString& path) { |
- CPath path1(path); |
- path1.RemoveExtension(); |
- return static_cast<CString>(path1); |
-} |
- |
-// Basically, an absolute path starts with X:\ or \\ (a UNC name) |
-bool IsAbsolutePath(const TCHAR* path) { |
- ASSERT1(path); |
- |
- int len = ::_tcslen(path); |
- if (len < 3) |
- return false; |
- if (*path == _T('"')) |
- path++; |
- if (String_StartsWith(path+1, _T(":\\"), false)) |
- return true; |
- if (String_StartsWith(path, _T("\\\\"), false)) |
- return true; |
- return false; |
-} |
- |
-void EnclosePath(CString* path) { |
- ASSERT1(path); |
- |
- if (path->IsEmpty()) { |
- return; |
- } |
- |
- bool starts_with_quote = (_T('"') == path->GetAt(0)); |
- bool ends_with_quote = (_T('"') == path->GetAt(path->GetLength() - 1)); |
- ASSERT(starts_with_quote == ends_with_quote, (_T("%s"), path->GetString())); |
- bool is_enclosed = starts_with_quote && ends_with_quote; |
- if (is_enclosed) { |
- return; |
- } |
- |
- path->Insert(0, _T('"')); |
- path->AppendChar(_T('"')); |
-} |
- |
-CString EnclosePathIfExe(const CString& module_path) { |
- if (!String_EndsWith(module_path, _T(".exe"), true)) { |
- return module_path; |
- } |
- |
- CString enclosed_path(module_path); |
- EnclosePath(&enclosed_path); |
- return enclosed_path; |
-} |
- |
-// remove any double quotation masks from an enclosed path |
-void UnenclosePath(CString* path) { |
- ASSERT1(path); |
- |
- if (path->GetLength() > 1 && path->GetAt(0) == _T('"')) { |
- bool right_quote_exists = (path->GetAt(path->GetLength() - 1) == _T('"')); |
- ASSERT(right_quote_exists, |
- (_T("[UnenclosePath - double quote mismatches]"))); |
- if (right_quote_exists) { |
- // Remove the double quotation masks |
- path->Delete(0); |
- path->Truncate(path->GetLength() - 1); |
- } |
- } |
-} |
- |
-void RemoveMismatchedEndQuoteInDirectoryPath(CString* directory_path) { |
- ASSERT1(directory_path); |
- |
- if (directory_path->GetLength() <= 1) { |
- return; |
- } |
- |
- ASSERT1(directory_path->GetAt(0) != _T('"')); |
- if (directory_path->GetAt(directory_path->GetLength() - 1) == _T('"')) { |
- directory_path->Truncate(directory_path->GetLength() - 1); |
- } |
-} |
- |
-HRESULT ShortPathToLongPath(const CString& short_path, CString* long_path) { |
- ASSERT1(long_path); |
- |
- TCHAR long_name[MAX_PATH] = {0}; |
- if (!::GetLongPathName(short_path, long_name, MAX_PATH)) { |
- return HRESULTFromLastError(); |
- } |
- |
- *long_path = long_name; |
- return S_OK; |
-} |
- |
-HRESULT FindFilesEx(const CString& dir, |
- const CString& pattern, |
- std::vector<CString>* files) { |
- return detail::FindFilesEx(dir, pattern, files, &detail::IsFile); |
-} |
- |
-HRESULT FindFiles(const CString& dir, |
- const CString& pattern, |
- std::vector<CString>* files) { |
- return detail::FindFilesEx(dir, pattern, files, &detail::AllFiles); |
-} |
- |
-HRESULT FindSubDirectories(const CString& dir, |
- const CString& pattern, |
- std::vector<CString>* files) { |
- return detail::FindFilesEx(dir, pattern, files, &detail::IsDirectory); |
-} |
- |
-HRESULT FindFileRecursive(const CString& dir, |
- const CString& pattern, |
- std::vector<CString>* files) { |
- ASSERT1(files); |
- |
- std::vector<CString> temp_files; |
- HRESULT hr = FindFilesEx(dir, pattern, &temp_files); |
- if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) && FAILED(hr)) { |
- return hr; |
- } |
- |
- for (size_t i = 0; i < temp_files.size(); ++i) { |
- files->push_back(ConcatenatePath(dir, temp_files[i])); |
- } |
- |
- std::vector<CString> sub_dirs; |
- hr = FindSubDirectories(dir, _T("*"), &sub_dirs); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- for (size_t i = 0; i < sub_dirs.size(); ++i) { |
- const CString& sub_dir = sub_dirs[i]; |
- if (sub_dir == _T(".") || sub_dir == _T("..")) { |
- continue; |
- } |
- |
- CString path = ConcatenatePath(dir, sub_dir); |
- hr = FindFileRecursive(path, pattern, files); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- } |
- |
- return S_OK; |
-} |
- |
-} // namespace omaha |
- |