forked from lthn/blockchain
661 lines
22 KiB
C++
661 lines
22 KiB
C++
// Copyright (c) 2014-2018 Zano Project
|
|
// Copyright (c) 2014-2018 The Louisdor Project
|
|
// Copyright (c) 2012-2013 The Cryptonote developers
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include "include_base_utils.h"
|
|
#include "zlib_helper.h"
|
|
using namespace epee;
|
|
|
|
#include "util.h"
|
|
#include "currency_core/currency_config.h"
|
|
#include "version.h"
|
|
|
|
#ifdef WIN32
|
|
#include <windows.h>
|
|
#include <shlobj.h>
|
|
#include <strsafe.h>
|
|
#include <lm.h>
|
|
#pragma comment(lib, "netapi32.lib")
|
|
#else
|
|
#include <sys/utsname.h>
|
|
#endif
|
|
|
|
#include <boost/asio.hpp>
|
|
|
|
#include "string_coding.h"
|
|
|
|
namespace tools
|
|
{
|
|
std::function<void(void)> signal_handler::m_handler;
|
|
std::function<void(int, void*)> signal_handler::m_fatal_handler;
|
|
|
|
#ifdef WIN32
|
|
|
|
bool GetWinMajorMinorVersion(DWORD& major, DWORD& minor)
|
|
{
|
|
bool bRetCode = false;
|
|
LPBYTE pinfoRawData = 0;
|
|
if (NERR_Success == NetWkstaGetInfo(NULL, 100, &pinfoRawData))
|
|
{
|
|
WKSTA_INFO_100* pworkstationInfo = (WKSTA_INFO_100*)pinfoRawData;
|
|
major = pworkstationInfo->wki100_ver_major;
|
|
minor = pworkstationInfo->wki100_ver_minor;
|
|
::NetApiBufferFree(pinfoRawData);
|
|
bRetCode = true;
|
|
}
|
|
return bRetCode;
|
|
}
|
|
|
|
|
|
std::string get_windows_version_display_string()
|
|
{
|
|
std::string winver;
|
|
OSVERSIONINFOEX osver;
|
|
SYSTEM_INFO sysInfo;
|
|
typedef void(__stdcall *GETSYSTEMINFO) (LPSYSTEM_INFO);
|
|
|
|
#pragma warning (push)
|
|
#pragma warning (disable:4996)
|
|
memset(&osver, 0, sizeof(osver));
|
|
osver.dwOSVersionInfoSize = sizeof(osver);
|
|
GetVersionEx((LPOSVERSIONINFO)&osver);
|
|
#pragma warning (pop)
|
|
DWORD major = 0;
|
|
DWORD minor = 0;
|
|
if (GetWinMajorMinorVersion(major, minor))
|
|
{
|
|
osver.dwMajorVersion = major;
|
|
osver.dwMinorVersion = minor;
|
|
}
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2)
|
|
{
|
|
OSVERSIONINFOEXW osvi;
|
|
ULONGLONG cm = 0;
|
|
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_EQUAL);
|
|
ZeroMemory(&osvi, sizeof(osvi));
|
|
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
|
osvi.dwMinorVersion = 3;
|
|
if (VerifyVersionInfoW(&osvi, VER_MINORVERSION, cm))
|
|
{
|
|
osver.dwMinorVersion = 3;
|
|
}
|
|
}
|
|
|
|
GETSYSTEMINFO getSysInfo = (GETSYSTEMINFO)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetNativeSystemInfo");
|
|
if (getSysInfo == NULL) getSysInfo = ::GetSystemInfo;
|
|
getSysInfo(&sysInfo);
|
|
|
|
if (osver.dwMajorVersion == 10 && osver.dwMinorVersion >= 0 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows 10 Server";
|
|
else if (osver.dwMajorVersion == 10 && osver.dwMinorVersion >= 0 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows 10";
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows Server 2012 R2";
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows 8.1";
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows Server 2012";
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows 8";
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows Server 2008 R2";
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows 7";
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows Server 2008";
|
|
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows Vista";
|
|
else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2 && osver.wProductType == VER_NT_WORKSTATION
|
|
&& sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
|
|
winver = "Windows XP x64";
|
|
else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2) winver = "Windows Server 2003";
|
|
else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1) winver = "Windows XP";
|
|
else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0) winver = "Windows 2000";
|
|
else winver = "unknown";
|
|
|
|
if (osver.wServicePackMajor != 0)
|
|
{
|
|
std::string sp;
|
|
char buf[128] = { 0 };
|
|
sp = " Service Pack ";
|
|
sprintf_s(buf, sizeof(buf), "%hd", osver.wServicePackMajor);
|
|
sp.append(buf);
|
|
winver += sp;
|
|
}
|
|
|
|
if (osver.dwMajorVersion >= 6)
|
|
{
|
|
if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
|
|
winver += ", 64-bit";
|
|
else if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
|
|
winver += ", 32-bit";
|
|
}
|
|
|
|
|
|
winver += "("
|
|
+ std::to_string(osver.dwMajorVersion) + ":"
|
|
+ std::to_string(osver.dwMinorVersion) + ":"
|
|
+ std::to_string(osver.dwBuildNumber) + ":"
|
|
+ std::to_string(osver.dwPlatformId) + ":"
|
|
+ std::to_string(osver.wServicePackMajor) + ":"
|
|
+ std::to_string(osver.wServicePackMinor) + ":"
|
|
+ std::to_string(osver.wSuiteMask) + ":"
|
|
+ std::to_string(osver.wProductType) + ")";
|
|
|
|
return winver;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string get_windows_version_display_string_()
|
|
{
|
|
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
|
|
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
|
|
#define BUFSIZE 10000
|
|
|
|
char pszOS[BUFSIZE] = {0};
|
|
OSVERSIONINFOEX osvi;
|
|
SYSTEM_INFO si;
|
|
PGNSI pGNSI;
|
|
PGPI pGPI;
|
|
BOOL bOsVersionInfoEx;
|
|
DWORD dwType;
|
|
|
|
ZeroMemory(&si, sizeof(SYSTEM_INFO));
|
|
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
|
|
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);
|
|
|
|
if(!bOsVersionInfoEx) return pszOS;
|
|
|
|
// Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
|
|
|
|
pGNSI = (PGNSI) GetProcAddress(
|
|
GetModuleHandle(TEXT("kernel32.dll")),
|
|
"GetNativeSystemInfo");
|
|
if(NULL != pGNSI)
|
|
pGNSI(&si);
|
|
else GetSystemInfo(&si);
|
|
|
|
if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId &&
|
|
osvi.dwMajorVersion > 4 )
|
|
{
|
|
StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft "));
|
|
|
|
// Test for the specific product.
|
|
|
|
if ( osvi.dwMajorVersion == 6 )
|
|
{
|
|
if( osvi.dwMinorVersion == 0 )
|
|
{
|
|
if( osvi.wProductType == VER_NT_WORKSTATION )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista "));
|
|
else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 " ));
|
|
}
|
|
|
|
if ( osvi.dwMinorVersion == 1 )
|
|
{
|
|
if( osvi.wProductType == VER_NT_WORKSTATION )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 7 "));
|
|
else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 " ));
|
|
}
|
|
|
|
pGPI = (PGPI) GetProcAddress(
|
|
GetModuleHandle(TEXT("kernel32.dll")),
|
|
"GetProductInfo");
|
|
|
|
pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
|
|
|
|
switch( dwType )
|
|
{
|
|
case PRODUCT_ULTIMATE:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition" ));
|
|
break;
|
|
case PRODUCT_PROFESSIONAL:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Professional" ));
|
|
break;
|
|
case PRODUCT_HOME_PREMIUM:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition" ));
|
|
break;
|
|
case PRODUCT_HOME_BASIC:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition" ));
|
|
break;
|
|
case PRODUCT_ENTERPRISE:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
|
|
break;
|
|
case PRODUCT_BUSINESS:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition" ));
|
|
break;
|
|
case PRODUCT_STARTER:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition" ));
|
|
break;
|
|
case PRODUCT_CLUSTER_SERVER:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition" ));
|
|
break;
|
|
case PRODUCT_DATACENTER_SERVER:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition" ));
|
|
break;
|
|
case PRODUCT_DATACENTER_SERVER_CORE:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)" ));
|
|
break;
|
|
case PRODUCT_ENTERPRISE_SERVER:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
|
|
break;
|
|
case PRODUCT_ENTERPRISE_SERVER_CORE:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)" ));
|
|
break;
|
|
case PRODUCT_ENTERPRISE_SERVER_IA64:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems" ));
|
|
break;
|
|
case PRODUCT_SMALLBUSINESS_SERVER:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server" ));
|
|
break;
|
|
case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition" ));
|
|
break;
|
|
case PRODUCT_STANDARD_SERVER:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition" ));
|
|
break;
|
|
case PRODUCT_STANDARD_SERVER_CORE:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)" ));
|
|
break;
|
|
case PRODUCT_WEB_SERVER:
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition" ));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
|
|
{
|
|
if( GetSystemMetrics(SM_SERVERR2) )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Server 2003 R2, "));
|
|
else if ( osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Storage Server 2003"));
|
|
else if ( osvi.wSuiteMask & VER_SUITE_WH_SERVER )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Home Server"));
|
|
else if( osvi.wProductType == VER_NT_WORKSTATION &&
|
|
si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
|
|
{
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Windows XP Professional x64 Edition"));
|
|
}
|
|
else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003, "));
|
|
|
|
// Test for the server type.
|
|
if ( osvi.wProductType != VER_NT_WORKSTATION )
|
|
{
|
|
if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 )
|
|
{
|
|
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition for Itanium-based Systems" ));
|
|
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition for Itanium-based Systems" ));
|
|
}
|
|
|
|
else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
|
|
{
|
|
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter x64 Edition" ));
|
|
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise x64 Edition" ));
|
|
else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard x64 Edition" ));
|
|
}
|
|
|
|
else
|
|
{
|
|
if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Compute Cluster Edition" ));
|
|
else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition" ));
|
|
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition" ));
|
|
else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Web Edition" ));
|
|
else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard Edition" ));
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
|
|
{
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP "));
|
|
if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Home Edition" ));
|
|
else StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
|
|
}
|
|
|
|
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
|
|
{
|
|
StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 "));
|
|
|
|
if ( osvi.wProductType == VER_NT_WORKSTATION )
|
|
{
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
|
|
}
|
|
else
|
|
{
|
|
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Server" ));
|
|
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( "Advanced Server" ));
|
|
else StringCchCat(pszOS, BUFSIZE, TEXT( "Server" ));
|
|
}
|
|
}
|
|
|
|
// Include service pack (if any) and build number.
|
|
|
|
if( strlen(osvi.szCSDVersion) > 0 )
|
|
{
|
|
StringCchCat(pszOS, BUFSIZE, TEXT(" ") );
|
|
StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion);
|
|
}
|
|
|
|
TCHAR buf[80];
|
|
|
|
StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber);
|
|
StringCchCat(pszOS, BUFSIZE, buf);
|
|
|
|
if ( osvi.dwMajorVersion >= 6 )
|
|
{
|
|
if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" ));
|
|
else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
|
|
StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit"));
|
|
}
|
|
|
|
return pszOS;
|
|
}
|
|
else
|
|
{
|
|
printf( "This sample does not support this version of Windows.\n");
|
|
return pszOS;
|
|
}
|
|
}
|
|
|
|
void signal_handler::GenerateCrashDump(EXCEPTION_POINTERS *pep /* = NULL*/)
|
|
{
|
|
SYSTEMTIME sysTime = { 0 };
|
|
GetSystemTime(&sysTime);
|
|
// get the computer name
|
|
char compName[MAX_COMPUTERNAME_LENGTH + 1] = { 0 };
|
|
DWORD compNameLen = ARRAYSIZE(compName);
|
|
GetComputerNameA(compName, &compNameLen);
|
|
// build the filename: APPNAME_COMPUTERNAME_DATE_TIME.DMP
|
|
char path[MAX_PATH*10] = { 0 };
|
|
std::string folder = epee::log_space::log_singletone::get_default_log_folder();
|
|
sprintf_s(path, ARRAYSIZE(path),"%s\\crashdump_" PROJECT_VERSION_LONG "_%s_%04u-%02u-%02u_%02u-%02u-%02u.dmp",
|
|
folder.c_str(), compName, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
|
|
sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
|
|
|
|
HANDLE hFile = CreateFileA(path, GENERIC_READ | GENERIC_WRITE,
|
|
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
|
|
{
|
|
// Create the minidump
|
|
MINIDUMP_EXCEPTION_INFORMATION mdei;
|
|
|
|
mdei.ThreadId = GetCurrentThreadId();
|
|
mdei.ExceptionPointers = pep;
|
|
mdei.ClientPointers = FALSE;
|
|
|
|
MINIDUMP_CALLBACK_INFORMATION mci;
|
|
|
|
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MyMiniDumpCallback;
|
|
mci.CallbackParam = 0;
|
|
|
|
MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory |
|
|
MiniDumpWithDataSegs |
|
|
MiniDumpWithHandleData |
|
|
MiniDumpWithFullMemoryInfo |
|
|
MiniDumpWithThreadInfo |
|
|
MiniDumpWithUnloadedModules);
|
|
|
|
BOOL rv = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
|
|
hFile, mdt, (pep != 0) ? &mdei : 0, 0, &mci);
|
|
|
|
if (!rv)
|
|
{
|
|
LOG_ERROR("Minidump file create FAILED(error " << GetLastError() << ") on path: " << path);
|
|
}
|
|
else
|
|
{
|
|
LOG_PRINT_L0("Minidump file created on path: " << path);
|
|
}
|
|
// Close the file
|
|
CloseHandle(hFile);
|
|
}
|
|
else
|
|
{
|
|
LOG_ERROR("Minidump FAILED to create file (error " << GetLastError() << ") on path: " << path);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#else // ifdef WIN32
|
|
std::string get_nix_version_display_string()
|
|
{
|
|
utsname un;
|
|
|
|
if(uname(&un) < 0)
|
|
return std::string("*nix: failed to get os version");
|
|
return std::string() + un.sysname + " " + un.version + " " + un.release;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
std::string get_os_version_string()
|
|
{
|
|
#ifdef WIN32
|
|
return get_windows_version_display_string();
|
|
#else
|
|
return get_nix_version_display_string();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
std::wstring get_special_folder_path_w(int nfolder, bool iscreate)
|
|
{
|
|
wchar_t psz_path[MAX_PATH] = L"";
|
|
|
|
if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate))
|
|
{
|
|
return psz_path;
|
|
}
|
|
|
|
LOG_ERROR("SHGetSpecialFolderPathW(" << nfolder << ", " << iscreate << ") failed, could not obtain requested path.");
|
|
return L"";
|
|
}
|
|
|
|
std::string get_special_folder_path_utf8(int nfolder, bool iscreate)
|
|
{
|
|
return epee::string_encoding::wstring_to_utf8(get_special_folder_path_w(nfolder, iscreate));
|
|
}
|
|
#endif
|
|
|
|
std::string get_default_data_dir()
|
|
{
|
|
//namespace fs = boost::filesystem;
|
|
// Windows < Vista: C:\Documents and Settings\Username\Application Data\CURRENCY_NAME_SHORT
|
|
// Windows >= Vista: C:\Users\Username\AppData\Roaming\CURRENCY_NAME_SHORT
|
|
// Mac: ~/Library/Application Support/CURRENCY_NAME_SHORT
|
|
// Unix: ~/.CURRENCY_NAME_SHORT
|
|
std::string config_folder;
|
|
#ifdef WIN32
|
|
// Windows
|
|
#ifdef _M_X64
|
|
config_folder = get_special_folder_path_utf8(CSIDL_APPDATA, true) + "/" + CURRENCY_NAME_SHORT;
|
|
#else
|
|
config_folder = get_special_folder_path_utf8(CSIDL_APPDATA, true) + "/" + CURRENCY_NAME_SHORT + "-x86";
|
|
#endif
|
|
#else
|
|
std::string pathRet;
|
|
char* pszHome = getenv("HOME");
|
|
if (pszHome == NULL || strlen(pszHome) == 0)
|
|
pathRet = "/";
|
|
else
|
|
pathRet = pszHome;
|
|
#ifdef __APPLE__
|
|
// Mac
|
|
pathRet += "/Library/Application Support";
|
|
config_folder = (pathRet + "/" + CURRENCY_NAME_SHORT);
|
|
#else
|
|
// Unix
|
|
config_folder = (pathRet + "/." + CURRENCY_NAME_SHORT);
|
|
#endif
|
|
#endif
|
|
|
|
return config_folder;
|
|
}
|
|
std::string get_host_computer_name()
|
|
{
|
|
char szname[1024] = "";
|
|
gethostname(szname, sizeof(szname));
|
|
szname[sizeof(szname)-1] = 0; //just to be sure
|
|
return szname;
|
|
}
|
|
|
|
|
|
std::string get_default_user_dir()
|
|
{
|
|
//namespace fs = boost::filesystem;
|
|
// Windows < Vista: C:\Documents and Settings\Username
|
|
// Windows >= Vista: C:\Users\Username\AppData\Roaming\CURRENCY_NAME_SHORT
|
|
// Mac: ~/Library/Application Support/CURRENCY_NAME_SHORT
|
|
// Unix: ~/.CURRENCY_NAME_SHORT
|
|
std::string wallets_dir;
|
|
#ifdef WIN32
|
|
// Windows
|
|
wallets_dir = get_special_folder_path_utf8(CSIDL_PERSONAL, true) + "/" + CURRENCY_NAME_BASE;
|
|
#else
|
|
std::string pathRet;
|
|
char* pszHome = getenv("HOME");
|
|
if (pszHome == NULL || strlen(pszHome) == 0)
|
|
pathRet = "/";
|
|
else
|
|
pathRet = pszHome;
|
|
|
|
wallets_dir = (pathRet + "/" + CURRENCY_NAME_BASE);
|
|
|
|
#endif
|
|
return wallets_dir;
|
|
}
|
|
|
|
std::string get_current_username()
|
|
{
|
|
#ifdef WIN32
|
|
// Windows
|
|
const char* psz_username = getenv("USERNAME");
|
|
#else
|
|
const char* psz_username = getenv("USER");
|
|
#endif
|
|
if (psz_username == NULL || strlen(psz_username) == 0)
|
|
psz_username = "unknown_user";
|
|
|
|
return std::string(psz_username);
|
|
}
|
|
|
|
|
|
|
|
bool create_directories_if_necessary(const std::string& path)
|
|
{
|
|
namespace fs = boost::filesystem;
|
|
boost::system::error_code ec;
|
|
fs::path fs_path = epee::string_encoding::utf8_to_wstring(path);
|
|
if (fs::is_directory(fs_path, ec))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool res = fs::create_directories(fs_path, ec);
|
|
if (res)
|
|
{
|
|
LOG_PRINT_L2("Created directory: " << path);
|
|
}
|
|
else
|
|
{
|
|
LOG_PRINT_L2("Can't create directory: " << path << ", err: "<< ec.message());
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
std::error_code replace_file(const std::string& replacement_name, const std::string& replaced_name)
|
|
{
|
|
int code;
|
|
#if defined(WIN32)
|
|
// Maximizing chances for success
|
|
DWORD attributes = ::GetFileAttributes(replaced_name.c_str());
|
|
if (INVALID_FILE_ATTRIBUTES != attributes)
|
|
{
|
|
::SetFileAttributes(replaced_name.c_str(), attributes & (~FILE_ATTRIBUTE_READONLY));
|
|
}
|
|
|
|
bool ok = 0 != ::MoveFileEx(replacement_name.c_str(), replaced_name.c_str(), MOVEFILE_REPLACE_EXISTING);
|
|
code = ok ? 0 : static_cast<int>(::GetLastError());
|
|
#else
|
|
bool ok = 0 == std::rename(replacement_name.c_str(), replaced_name.c_str());
|
|
code = ok ? 0 : errno;
|
|
#endif
|
|
return std::error_code(code, std::system_category());
|
|
}
|
|
|
|
#define REQUEST_LOG_CHUNK_SIZE_MAX (10 * 1024 * 1024)
|
|
|
|
bool get_log_chunk_gzipped(uint64_t offset, uint64_t size, std::string& output, std::string& error)
|
|
{
|
|
if (size > REQUEST_LOG_CHUNK_SIZE_MAX)
|
|
{
|
|
error = std::string("size is exceeding the limit = ") + epee::string_tools::num_to_string_fast(REQUEST_LOG_CHUNK_SIZE_MAX);
|
|
return false;
|
|
}
|
|
|
|
std::string log_filename = epee::log_space::log_singletone::get_actual_log_file_path();
|
|
if (std::ifstream log{ log_filename, std::ifstream::ate | std::ifstream::binary })
|
|
{
|
|
uint64_t file_size = log.tellg();
|
|
|
|
if (offset >= file_size)
|
|
{
|
|
error = "offset is out of bounds";
|
|
return false;
|
|
}
|
|
|
|
if (offset + size > file_size)
|
|
{
|
|
error = "offset + size if out of bounds";
|
|
return false;
|
|
}
|
|
|
|
if (size != 0)
|
|
{
|
|
log.seekg(offset);
|
|
output.resize(size);
|
|
log.read(&output.front(), size);
|
|
uint64_t read_bytes = log.gcount();
|
|
if (read_bytes != size)
|
|
{
|
|
error = std::string("read bytes: ") + epee::string_tools::num_to_string_fast(read_bytes);
|
|
return false;
|
|
}
|
|
|
|
if (!epee::zlib_helper::pack(output))
|
|
{
|
|
error = "zlib pack failed";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
error = std::string("can't open ") + log_filename;
|
|
return false;
|
|
}
|
|
|
|
uint64_t get_log_file_size()
|
|
{
|
|
std::string log_filename = epee::log_space::log_singletone::get_actual_log_file_path();
|
|
std::ifstream in(log_filename, std::ifstream::ate | std::ifstream::binary);
|
|
return static_cast<uint64_t>(in.tellg());
|
|
}
|
|
|
|
} // namespace tools
|