diff options
Diffstat (limited to 'contrib/epee/include/file_io_utils.h')
-rw-r--r-- | contrib/epee/include/file_io_utils.h | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h new file mode 100644 index 000000000..7e8521838 --- /dev/null +++ b/contrib/epee/include/file_io_utils.h @@ -0,0 +1,455 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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. +// + + +#ifndef _FILE_IO_UTILS_H_ +#define _FILE_IO_UTILS_H_ + + +//#include <sys/types.h> +//#include <sys/stat.h> + +#include <iostream> +#include <boost/filesystem.hpp> + + +#ifndef MAKE64 + #define MAKE64(low,high) ((__int64)(((DWORD)(low)) | ((__int64)((DWORD)(high))) << 32)) +#endif + +#ifdef WINDOWS_PLATFORM +#include <psapi.h> +#include <strsafe.h> +#include <string.h> +#include <mbstring.h> + +#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<std::string>(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<std::string>(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<size_t>(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<WIN32_FIND_DATAA>& 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<std::string>& 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_ |