bool ff::MoveFile(StringRef pathFrom, StringRef pathTo, bool bAllowOverwrite) { String szCheckPathFrom = CanonicalizePath(pathFrom, true); String szCheckPathTo = CanonicalizePath(pathTo, true); return ::MoveFileEx( szCheckPathFrom.c_str(), szCheckPathTo.c_str(), MOVEFILE_COPY_ALLOWED | (bAllowOverwrite ? MOVEFILE_REPLACE_EXISTING : 0)) ? true : false; }
bool ff::PathsEqual(StringRef path1, StringRef path2, bool bCheckShortPath) { String szCheckPath1 = CanonicalizePath(path1, false, true); String szCheckPath2 = CanonicalizePath(path2, false, true); #if !METRO_APP if (bCheckShortPath && szCheckPath1 != szCheckPath2) { szCheckPath1 = GetShortPath(path1); szCheckPath2 = GetShortPath(path2); } #endif return szCheckPath1 == szCheckPath2; }
ff::String ff::GetLongPath(StringRef path) { String szCheckPath = CanonicalizePath(path, true); StackCharVector512 stackPath; stackPath.Resize(512); DWORD size = ::GetLongPathName(szCheckPath.c_str(), stackPath.Data(), (DWORD)stackPath.Size()); if (size > stackPath.Size()) { stackPath.Resize(size); size = ::GetLongPathName(szCheckPath.c_str(), stackPath.Data(), (DWORD)stackPath.Size()); } if (size) { szCheckPath = stackPath.Data(); StripSuperLongPrefix(szCheckPath); } else { szCheckPath.empty(); } return szCheckPath; }
bool ff::File::OpenWrite(StringRef path, bool bAppend) { String szCheckPath = CanonicalizePath(path, true); Close(); #if METRO_APP _file = ::CreateFile2(szCheckPath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, bAppend ? OPEN_ALWAYS : CREATE_ALWAYS, nullptr); #else _file = ::CreateFile(szCheckPath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, bAppend ? OPEN_ALWAYS : CREATE_ALWAYS, 0, nullptr); #endif if (_file == INVALID_HANDLE_VALUE) { _file = nullptr; } if (_file && bAppend) { SetFilePointerToEnd(_file); } return _file != nullptr; }
NS_IMETHODIMP nsUrlClassifierUtils::GetKeyForURI(nsIURI * uri, nsACString & _retval) { nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(uri); if (!innerURI) innerURI = uri; nsAutoCString host; innerURI->GetAsciiHost(host); if (host.IsEmpty()) { return NS_ERROR_MALFORMED_URI; } nsresult rv = CanonicalizeHostname(host, _retval); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString path; rv = innerURI->GetPath(path); NS_ENSURE_SUCCESS(rv, rv); // strip out anchors int32_t ref = path.FindChar('#'); if (ref != kNotFound) path.SetLength(ref); nsAutoCString temp; rv = CanonicalizePath(path, temp); NS_ENSURE_SUCCESS(rv, rv); _retval.Append(temp); return NS_OK; }
void ff::SetTempSubDirectory(StringRef name) { SettingTempPath(); LockMutex crit(GCS_FILE_UTIL); s_tempSubName = CanonicalizePath(name); }
bool ff::DeleteDirectory(StringRef path, bool bMustBeEmpty) { if (bMustBeEmpty) { String szRealPath = CanonicalizePath(path, true); return ::RemoveDirectory(szRealPath.c_str()) ? true : false; } else if (DirectoryExists(path)) { Vector<String> dirs; Vector<String> files; if (GetDirectoryContents(path, dirs, files)) { String szRealPath = CanonicalizePath(path, true); for (size_t i = 0; i < files.Size(); i++) { String szDelete = szRealPath; AppendPathTail(szDelete, files[i]); if (!DeleteFile(szDelete)) { return false; } } for (size_t i = 0; i < dirs.Size(); i++) { String szDelete = szRealPath; AppendPathTail(szDelete, dirs[i]); if (!DeleteDirectory(szDelete, false)) { return false; } } return DeleteDirectory(path, true); } } return false; }
bool ff::CopyFile(StringRef pathFrom, StringRef pathTo, bool bAllowOverwrite) { String szCheckPathFrom = CanonicalizePath(pathFrom, true); String szCheckPathTo = CanonicalizePath(pathTo, true); #if METRO_APP BOOL bCancel = FALSE; COPYFILE2_EXTENDED_PARAMETERS cp; ZeroObject(cp); cp.dwSize = sizeof(cp); cp.dwCopyFlags = bAllowOverwrite ? 0 : COPY_FILE_FAIL_IF_EXISTS; cp.pfCancel = &bCancel; return SUCCEEDED(::CopyFile2(szCheckPathFrom.c_str(), szCheckPathTo.c_str(), &cp)) ? true : false; #else return ::CopyFile(szCheckPathFrom.c_str(), szCheckPathTo.c_str(), !bAllowOverwrite) ? true : false; #endif }
bool ff::PathInPath(StringRef parent, StringRef child, bool bCheckShortPath) { #if !METRO_APP String szCheckParent = bCheckShortPath ? GetShortPath(parent) : CanonicalizePath(parent, false, true); String szCheckChild = bCheckShortPath ? GetShortPath(child) : CanonicalizePath(child, false, true); #else String szCheckParent = CanonicalizePath(parent, false, true); String szCheckChild = CanonicalizePath(child, false, true); #endif if (szCheckChild.size() > szCheckParent.size() && szCheckChild[szCheckParent.size()] == '\\' && !_wcsnicmp(szCheckChild.c_str(), szCheckParent.c_str(), szCheckParent.size())) { return true; } return false; }
bool ff::GetFileAttributes(StringRef path, DWORD &attribs) { String szCheckPath = CanonicalizePath(path, true); WIN32_FILE_ATTRIBUTE_DATA data; attribs = ::GetFileAttributesEx(szCheckPath.c_str(), GetFileExInfoStandard, &data) ? data.dwFileAttributes : INVALID_FILE_ATTRIBUTES; return attribs != INVALID_FILE_ATTRIBUTES; }
bool ff::DeleteFile(StringRef path) { if (FileExists(path)) { String szCheckPath = CanonicalizePath(path, true); return ::DeleteFile(szCheckPath.c_str()) ? true : false; } return false; }
ff::String ff::GetTempDirectory() { LockMutex crit(GCS_FILE_UTIL); if(!s_tempPath.empty() && s_oldTempSubName == s_tempSubName) { return s_tempPath; } SettingTempPath(); s_tempPath.clear(); s_oldTempSubName = s_tempSubName; #if METRO_APP s_tempPath = String::from_pstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path); #else StackCharVector512 stackPath; stackPath.Resize(512); DWORD size = ::GetTempPath((DWORD)stackPath.Size(), stackPath.Data()); if (size > stackPath.Size()) { stackPath.Resize(size); size = ::GetTempPath((DWORD)stackPath.Size(), stackPath.Data()); } if (size) { s_tempPath = CanonicalizePath(String(stackPath.Data())); StripSuperLongPrefix(s_tempPath); static StaticString defaultTail(L"Ferret Face"); AppendPathTail(s_tempPath, defaultTail); } #endif if (!s_tempPath.empty()) { AppendPathTail(s_tempPath, s_tempSubName); if (!DirectoryExists(s_tempPath)) { CreateDirectory(s_tempPath); } } return s_tempPath; }
bool ff::DirectoryExists(StringRef path, WIN32_FIND_DATA *pFindData) { String szCheckPath = CanonicalizePath(path, true); WIN32_FIND_DATA data; pFindData = pFindData ? pFindData : &data; HANDLE hFind = FindFirstFileEx(szCheckPath.c_str(), FindExInfoStandard, pFindData, FindExSearchLimitToDirectories, nullptr, 0); if (hFind != INVALID_HANDLE_VALUE) { FindClose(hFind); return (pFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } return false; }
bool ff::File::OpenRead(StringRef path) { String szCheckPath = CanonicalizePath(path, true); Close(); #if METRO_APP _file = ::CreateFile2(szCheckPath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, nullptr); #else _file = ::CreateFile(szCheckPath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); #endif if (_file == INVALID_HANDLE_VALUE) { _file = nullptr; } return _file != nullptr; }
bool ff::GetDirectoryContents(StringRef path, Vector<String> &dirs, Vector<String> &files, Vector<FILETIME> *fileTimes) { dirs.Clear(); files.Clear(); if (fileTimes) { fileTimes->Clear(); } String szFilter = CanonicalizePath(path, true); assertRetVal(szFilter.size(), false); AppendPathTail(szFilter, String(L"*")); WIN32_FIND_DATA data; ZeroObject(data); HANDLE hFind = FindFirstFileEx(szFilter.c_str(), FindExInfoStandard, &data, FindExSearchNameMatch, nullptr, 0); for (BOOL bDone = FALSE; !bDone && hFind != INVALID_HANDLE_VALUE; bDone = !FindNextFile(hFind, &data)) { if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { files.Push(String(data.cFileName)); if (fileTimes) { fileTimes->Push(data.ftLastWriteTime); } } else if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) { dirs.Push(String(data.cFileName)); } } if (hFind != INVALID_HANDLE_VALUE) { FindClose(hFind); } return hFind != INVALID_HANDLE_VALUE; }
HANDLE ff::FindFirstChangeNotification(StringRef path, BOOL subDirs, DWORD filter) { ff::String canon = CanonicalizePath(path, true); return ::FindFirstChangeNotification(canon.c_str(), subDirs, filter); }
bool ff::SetFileAttributes(StringRef path, DWORD attribs) { String szCheckPath = CanonicalizePath(path, true); return ::SetFileAttributes(szCheckPath.c_str(), attribs) ? true : false; }
bool ff::SetCurrentDirectory(StringRef path) { String szRealPath = CanonicalizePath(path, true); return ::SetCurrentDirectory(szRealPath.c_str()) ? true : false; }
// This is all fancy because it only creates one directory at a time, // starting with the first missing subdirectory bool ff::CreateDirectory(StringRef path) { String szDrive; String szRealPath = CanonicalizePath(path); Vector<String> paths; if (szRealPath.empty()) { return false; } else if (!wcsncmp(szRealPath.c_str(), L"\\\\.\\", 4)) { // ignore physical paths return false; } else if (!wcsncmp(szRealPath.c_str(), L"\\\\", 2)) { // UNC share, find the slash after the share name const wchar_t *szSlash = wcschr(szRealPath.c_str() + 2, '\\'); szSlash = szSlash ? wcschr(szSlash + 1, '\\') : nullptr; if (!szSlash) { // can't create a server or share name return false; } szDrive = szRealPath.substr(0, szSlash - szRealPath.c_str() + 1); szRealPath.erase(0, szDrive.size()); } else if (isalpha(szRealPath[0]) && szRealPath[1] == ':' && szRealPath[2] == '\\') { // absolute drive path szDrive = szRealPath.substr(0, 3); szRealPath.erase(0, 3); } else if (szRealPath[0] == '\\') { // relative drive path szDrive = L"\\"; szRealPath.erase(0, 1); } else { // relative to the current directory } if (szRealPath.empty()) { // nothing to create return false; } // Create the chain of parent directories { LockMutex crit(GCS_FILE_UTIL); for (; szRealPath.size() && !DirectoryExists(szDrive + szRealPath); StripPathTail(szRealPath)) { paths.Push(szDrive + szRealPath); } for (size_t i = PreviousSize(paths.Size()); i != INVALID_SIZE; i = PreviousSize(i)) { szRealPath = CanonicalizePath(paths[i], true); if (!::CreateDirectory(szRealPath.c_str(), nullptr)) { assertRetVal(::GetLastError() == ERROR_ALREADY_EXISTS, false); } } } return true; }