// Copyright (c) 2014, The Monero Project // // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. // // 3. Neither the name of the copyright holder nor the names of its contributors may be // used to endorse or promote products derived from this software without specific // prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Parts of this file are originally copyright (c) 2006-2013, Andrey N. Sabelnikov #ifndef _FILE_IO_UTILS_H_ #define _FILE_IO_UTILS_H_ //#include //#include #include #include #ifndef MAKE64 #define MAKE64(low,high) ((__int64)(((DWORD)(low)) | ((__int64)((DWORD)(high))) << 32)) #endif #ifdef WINDOWS_PLATFORM #include #include #include #include #endif namespace epee { namespace file_io_utils { #ifdef WINDOWS_PLATFORM inline std::string get_temp_file_name_a() { std::string str_result; char sz_temp[MAX_PATH*2] = {0}; if(!::GetTempPathA( sizeof( sz_temp ), sz_temp )) return str_result; char sz_temp_file[MAX_PATH*2] = {0}; if(!::GetTempFileNameA( sz_temp, "mail", 0, sz_temp_file)) return str_result; sz_temp_file[sizeof(sz_temp_file)-1] = 0; //be happy! str_result = sz_temp_file; return str_result; } #ifdef BOOST_LEXICAL_CAST_INCLUDED inline bool get_not_used_filename(const std::string& folder, OUT std::string& result_name) { DWORD folder_attr = ::GetFileAttributesA(folder.c_str()); if(folder_attr == INVALID_FILE_ATTRIBUTES) return false; if(!(folder_attr&FILE_ATTRIBUTE_DIRECTORY)) return false; std::string base_name = folder + "\\tmp"; std::string tmp_name; bool name_found = false; int current_index = 0; tmp_name = base_name + boost::lexical_cast(current_index) + ".tmp"; while(!name_found) { if(INVALID_FILE_ATTRIBUTES == ::GetFileAttributesA(tmp_name.c_str())) name_found = true; else { current_index++; tmp_name = base_name + boost::lexical_cast(current_index) + ".tmp"; } } result_name = tmp_name; return true; } #endif inline std::string get_temp_folder_a() { std::string str_result; char sz_temp[MAX_PATH*2] = {0}; if(!::GetTempPathA( sizeof( sz_temp ), sz_temp )) return str_result; sz_temp[(sizeof(sz_temp)/sizeof(sz_temp[0])) -1] = 0; str_result = sz_temp; return str_result; } std::string convert_from_device_path_to_standart(const std::string& path) { STRSAFE_LPSTR pszFilename = (STRSAFE_LPSTR)path.c_str(); // Translate path with device name to drive letters. char szTemp[4000] = {0}; if (::GetLogicalDriveStringsA(sizeof(szTemp)-1, szTemp)) { char szName[MAX_PATH]; char szDrive[3] = " :"; BOOL bFound = FALSE; char* p = szTemp; do { // Copy the drive letter to the template string *szDrive = *p; // Look up each device name if (::QueryDosDeviceA(szDrive, szName, sizeof(szName))) { UINT uNameLen = strlen(szName); if (uNameLen < MAX_PATH) { bFound = _mbsnbicmp((const unsigned char*)pszFilename, (const unsigned char*)szName, uNameLen) == 0; if (bFound) { // Reconstruct pszFilename using szTempFile // Replace device path with DOS path char szTempFile[MAX_PATH] = {0}; StringCchPrintfA(szTempFile, MAX_PATH, "%s%s", szDrive, pszFilename+uNameLen); return szTempFile; //::StringCchCopyNA(pszFilename, MAX_PATH+1, szTempFile, strlen(szTempFile)); } } } // Go to the next NULL character. while (*p++); } while (!bFound && *p); // end of string } return ""; } inline std::string get_process_path_by_pid(DWORD pid) { std::string res; HANDLE hprocess = 0; if( hprocess = ::OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, pid) ) { char buff[MAX_PATH]= {0}; if(!::GetModuleFileNameExA( hprocess, 0, buff, MAX_PATH - 1 )) res = "Unknown_b"; else { buff[MAX_PATH - 1]=0; //be happy! res = buff; std::string::size_type a = res.rfind( '\\' ); if ( a != std::string::npos ) res.erase( 0, a+1); } ::CloseHandle( hprocess ); }else res = "Unknown_a"; return res; } inline std::wstring get_temp_file_name_w() { std::wstring str_result; wchar_t sz_temp[MAX_PATH*2] = {0}; if(!::GetTempPathW( sizeof(sz_temp)/sizeof(sz_temp[0]), sz_temp )) return str_result; wchar_t sz_temp_file[MAX_PATH+1] = {0}; if(!::GetTempFileNameW( sz_temp, L"mail", 0, sz_temp_file)) return str_result; sz_temp_file[(sizeof(sz_temp_file)/sizeof(sz_temp_file[0]))-1] = 0; //be happy! str_result = sz_temp_file; return str_result; } #endif inline bool is_file_exist(const std::string& path) { boost::filesystem::path p(path); return boost::filesystem::exists(p); } /* inline bool save_string_to_handle(HANDLE hfile, const std::string& str) { if( INVALID_HANDLE_VALUE != hfile ) { DWORD dw; if( !::WriteFile( hfile, str.data(), (DWORD) str.size(), &dw, NULL) ) { int err_code = GetLastError(); //LOG_PRINT("Failed to write to file handle: " << hfile<< " Last error code:" << err_code << " : " << log_space::get_win32_err_descr(err_code), LOG_LEVEL_2); return false; } ::CloseHandle(hfile); return true; }else { //LOG_WIN32_ERROR(::GetLastError()); return false; } return false; }*/ inline bool save_string_to_file(const std::string& path_to_file, const std::string& str) { try { std::ofstream fstream; fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit); fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc); fstream << str; fstream.close(); return true; } catch(...) { return false; } } /* inline bool load_form_handle(HANDLE hfile, std::string& str) { if( INVALID_HANDLE_VALUE != hfile ) { bool res = true; DWORD dw = 0; DWORD fsize = ::GetFileSize(hfile, &dw); if(fsize > 300000000) { ::CloseHandle(hfile); return false; } if(fsize) { str.resize(fsize); if(!::ReadFile( hfile, (LPVOID)str.data(), (DWORD)str.size(), &dw, NULL)) res = false; } ::CloseHandle(hfile); return res; } return false; } */ inline bool get_file_time(const std::string& path_to_file, OUT time_t& ft) { boost::system::error_code ec; ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec); if(!ec) return true; else return false; } inline bool set_file_time(const std::string& path_to_file, const time_t& ft) { boost::system::error_code ec; boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec); if(!ec) return true; else return false; } inline bool load_file_to_string(const std::string& path_to_file, std::string& target_str) { try { std::ifstream fstream; fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit); fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate); std::ifstream::pos_type file_size = fstream.tellg(); if(file_size > 1000000000) return false;//don't go crazy size_t file_size_t = static_cast(file_size); target_str.resize(file_size_t); fstream.seekg (0, std::ios::beg); fstream.read((char*)target_str.data(), target_str.size()); fstream.close(); return true; } catch(...) { return false; } } inline bool append_string_to_file(const std::string& path_to_file, const std::string& str) { try { std::ofstream fstream; fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit); fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app); fstream << str; fstream.close(); return true; } catch(...) { return false; } } /* bool remove_dir_and_subirs(const char* path_to_dir); inline bool clean_dir(const char* path_to_dir) { if(!path_to_dir) return false; std::string folder = path_to_dir; WIN32_FIND_DATAA find_data = {0}; HANDLE hfind = ::FindFirstFileA((folder + "\\*.*").c_str(), &find_data); if(INVALID_HANDLE_VALUE == hfind) return false; do{ if(!strcmp("..", find_data.cFileName) || (!strcmp(".", find_data.cFileName))) continue; if(find_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) { if(!remove_dir_and_subirs((folder + "\\" + find_data.cFileName).c_str())) return false; }else { if(!::DeleteFileA((folder + "\\" + find_data.cFileName).c_str())) return false; } }while(::FindNextFileA(hfind, &find_data)); ::FindClose(hfind); return true; } */ #ifdef WINDOWS_PLATFORM inline bool get_folder_content(const std::string& path, std::list& OUT target_list) { WIN32_FIND_DATAA find_data = {0}; HANDLE hfind = ::FindFirstFileA((path + "\\*.*").c_str(), &find_data); if(INVALID_HANDLE_VALUE == hfind) return false; do{ if(!strcmp("..", find_data.cFileName) || (!strcmp(".", find_data.cFileName))) continue; target_list.push_back(find_data); }while(::FindNextFileA(hfind, &find_data)); ::FindClose(hfind); return true; } #endif inline bool get_folder_content(const std::string& path, std::list& OUT target_list, bool only_files = false) { try { boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end for ( boost::filesystem::directory_iterator itr( path ); itr != end_itr; ++itr ) { if ( only_files && boost::filesystem::is_directory(itr->status()) ) { continue; } target_list.push_back(itr->path().filename().string()); } } catch(...) { return false; } return true; } } } #endif //_FILE_IO_UTILS_H_