#include "../Config.h" #include "Utils.h" #include "DynImport.h" #include #include namespace blackbone { /// /// Convert UTF-8 string to wide char one /// /// UTF-8 string /// wide char string std::wstring Utils::UTF8ToWstring( const std::string& str ) { return AnsiToWstring( str, CP_UTF8 ); } /// /// Convert wide string to UTF-8 /// /// Wide char string /// UTF-8 string std::string Utils::WstringToUTF8( const std::wstring& str ) { return WstringToAnsi( str, CP_UTF8 ); } /// /// Convert ANSI string to wide char one /// /// ANSI string. /// String locale /// wide char string std::wstring Utils::AnsiToWstring( const std::string& input, DWORD locale /*= CP_ACP*/ ) { wchar_t buf[2048] = { 0 }; MultiByteToWideChar( locale, 0, input.c_str(), (int)input.length(), buf, ARRAYSIZE( buf ) ); return buf; } /// /// Convert wide char string to ANSI one /// /// wide char string. /// String locale /// ANSI string std::string Utils::WstringToAnsi( const std::wstring& input, DWORD locale /*= CP_ACP*/ ) { char buf[2048] = { 0 }; WideCharToMultiByte( locale, 0, input.c_str(), (int)input.length(), buf, ARRAYSIZE( buf ), nullptr, nullptr ); return buf; } /// /// Format string /// /// Format specifier /// Arguments /// Formatted string std::wstring Utils::FormatString( const wchar_t* fmt, ... ) { wchar_t buf[4096] = { 0 }; va_list vl; va_start( vl, fmt ); vswprintf_s( buf, fmt, vl ); va_end( vl ); return buf; } /// /// Get filename from full-qualified path /// /// File path /// Filename std::wstring Utils::StripPath( const std::wstring& path ) { if (path.empty()) return path; auto idx = path.rfind( L'\\' ); if(idx == path.npos) idx = path.rfind( L'/' ); if (idx != path.npos) return path.substr( idx + 1 ); else return path; } /// /// Get parent directory /// /// File path /// Parent directory std::wstring Utils::GetParent( const std::wstring& path ) { if (path.empty()) return path; auto idx = path.rfind( L'\\' ); if (idx == path.npos) idx = path.rfind( L'/' ); if (idx != path.npos) return path.substr( 0, idx ); else return path; } /// /// Get current process exe file directory /// /// Exe directory std::wstring Utils::GetExeDirectory() { wchar_t imgName[MAX_PATH] = { 0 }; DWORD len = ARRAYSIZE(imgName); auto pFunc = GET_IMPORT( QueryFullProcessImageNameW ); if (pFunc != nullptr) pFunc( GetCurrentProcess(), 0, imgName, &len ); else GetModuleFileNameW( NULL, imgName, len ); return GetParent( imgName ); } /// /// Generate random alpha-numeric string /// /// Desired length. 0 - random length from 5 to 15 /// Generated string std::wstring Utils::RandomANString( int length /*= 0*/ ) { static constexpr wchar_t alphabet[] = L"ABCDEFGHIJKLMNOPQRSTUVWXYZbcdefghijklmnopqrstuvwxyz1234567890"; static std::random_device rd; static std::uniform_int_distribution<> dist( 0, _countof( alphabet ) - 2 ); static std::uniform_int_distribution<> dist_len( 5, 15 ); std::wstring result; // Get random string length if (length == 0) length = dist_len( rd ); for (int i = 0; i < length; i++) result.push_back( alphabet[dist( rd )] ); return result; } /// /// Cast string characters to lower case /// /// Source string. /// Result string std::wstring Utils::ToLower( std::wstring str ) { std::transform( str.begin(), str.end(), str.begin(), ::towlower ); return str; } /// /// Get system error description /// /// The code. /// Error message std::wstring Utils::GetErrorDescription( NTSTATUS code ) { LPWSTR lpMsgBuf = nullptr; if (FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, GetModuleHandleW( L"ntdll.dll" ), code, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPWSTR)&lpMsgBuf, 0, NULL ) != 0) { std::wstring ret( lpMsgBuf ); LocalFree( lpMsgBuf ); return ret; } return L""; } /// /// Check if file exists /// /// Full-qualified file path /// true if exists bool Utils::FileExists( const std::wstring& path ) { return (GetFileAttributesW( path.c_str() ) != 0xFFFFFFFF ); } }