void ff::ClearTempSubDirectory() { #if !METRO_APP if (GetTempSubDirectory().empty()) { // don't clear the root temp path return; } #endif ff::String szFilter = ff::GetTempDirectory(); 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)) { ff::String szFile = ff::GetTempDirectory(); AppendPathTail(szFile, String(data.cFileName)); DeleteFile(szFile); } } if (hFind != INVALID_HANDLE_VALUE) { FindClose(hFind); } }
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::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; }
ff::String ff::CreateTempFile(StringRef base, StringRef extension) { LockMutex crit(GCS_FILE_UTIL); // STATIC_DATA (pod) static UINT nUnique = 0; const int maxTries = 1000; String szFinal; static StaticString defaultBase(L"TempFile"); static StaticString defaultExt(L"tmp"); String szBase = base.size() ? szBase : defaultBase; String szExtension = extension.size() ? szExtension : defaultExt; for (int nTry = 0; nTry < maxTries; nTry++, nUnique++) { wchar_t szUnique[20]; _snwprintf_s(szUnique, _countof(szUnique), _TRUNCATE, L"%u", nUnique); ff::String szTry = GetTempDirectory(); AppendPathTail(szTry, szBase); szTry += szUnique; szTry += L"."; szTry += szExtension; if (!FileExists(szTry)) { szFinal = szTry; break; } } if (szFinal.size()) { nUnique++; // Create the file to reserve it File file; if (!file.OpenWrite(szFinal)) { szFinal.empty(); } } assertSz(szFinal.size(), L"Can't create a file in the temp folder"); return szFinal; }
ff::String ff::Module::GetPath() const { #if METRO_APP // Assume that the name is a DLL in the application directory Windows::ApplicationModel::Package ^package = Windows::ApplicationModel::Package::Current; String path = String::from_pstring(package->InstalledLocation->Path); AppendPathTail(path, _name); ChangePathExtension(path, ff::String(L"dll")); assert(FileExists(path)); return path; #else assert(_instance != nullptr); return GetModulePath(_instance); #endif }
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; }