Changed code formatting.

This commit is contained in:
2024-02-16 01:17:39 +03:00
parent b09c969798
commit 2b55035234
5 changed files with 759 additions and 853 deletions

View File

@@ -28,80 +28,69 @@
#include <filesystem> #include <filesystem>
#include <strsafe.h> #include <strsafe.h>
inline wchar_t* CLogger::GetTimeStamp() inline wchar_t* CLogger::GetTimeStamp() {
{ GetLocalTime(&lt);
GetLocalTime(&lt); StringCchPrintfW(logTimeBuffer, _countof(logTimeBuffer), L"%d-%02d-%02d %02d:%02d:%02d.%03d | ", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds);
StringCchPrintfW(logTimeBuffer, _countof(logTimeBuffer), L"%d-%02d-%02d %02d:%02d:%02d.%03d | ", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds); return logTimeBuffer;
return logTimeBuffer;
} }
void CLogger::Out(const wchar_t* fmt, ...) void CLogger::Out(const wchar_t* fmt, ...) {
{ if (fsLogFile.is_open()) {
if (fsLogFile.is_open()) va_list args;
{ va_start(args, fmt);
va_list args; EnterCriticalSection(&cs);
va_start(args, fmt); StringCchVPrintfW(logBuffer, _countof(logBuffer), fmt, args);
EnterCriticalSection(&cs); va_end(args);
StringCchVPrintfW(logBuffer, _countof(logBuffer), fmt, args); fsLogFile << GetTimeStamp() << logBuffer << std::endl;
va_end(args); LeaveCriticalSection(&cs);
fsLogFile << GetTimeStamp() << logBuffer << std::endl; }
LeaveCriticalSection(&cs);
}
} }
void CLogger::Init() void CLogger::Init() {
{ wchar_t szPath[MAX_PATH] = { 0 };
wchar_t szPath[MAX_PATH] = { 0 }; DWORD dwPathLength = GetModuleFileNameW(NULL, szPath, MAX_PATH);
DWORD dwPathLength = GetModuleFileNameW(NULL, szPath, MAX_PATH); DWORD dwError = GetLastError();
DWORD dwError = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == dwError) {
if (ERROR_INSUFFICIENT_BUFFER == dwError) MessageBoxW(NULL, L"Warning!\nPath to log file is too long! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
{ return;
MessageBoxW(NULL, L"Warning!\nPath to log file is too long! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL); }
return; if (NULL == dwPathLength) {
} MessageBoxW(NULL, L"Warning!\nCan't get application's filename! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
if (NULL == dwPathLength) return;
{ }
MessageBoxW(NULL, L"Warning!\nCan't get application's filename! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
return;
}
std::filesystem::path log_path = szPath; std::filesystem::path log_path = szPath;
log_path.replace_extension(L".log"); log_path.replace_extension(L".log");
std::filesystem::path bak_path = log_path; std::filesystem::path bak_path = log_path;
bak_path.replace_extension(L".bak"); bak_path.replace_extension(L".bak");
if (std::filesystem::exists(log_path)) std::filesystem::rename(log_path, bak_path); if (std::filesystem::exists(log_path)) std::filesystem::rename(log_path, bak_path);
#ifdef _DEBUG #ifdef _DEBUG
log_path = L"D:\\test.log"; log_path = L"D:\\test.log";
#endif #endif
fsLogFile.open(log_path, std::ios::trunc); fsLogFile.open(log_path, std::ios::trunc);
if (fsLogFile.is_open()) if (fsLogFile.is_open()) {
{ InitializeCriticalSection(&cs);
InitializeCriticalSection(&cs); fsLogFile << "\xEF\xBB\xBF"; // (0xEF, 0xBB, 0xBF) - UTF-8 BOM
fsLogFile << "\xEF\xBB\xBF"; // (0xEF, 0xBB, 0xBF) - UTF-8 BOM fsLogFile.imbue(std::locale("en-US.utf8"));
fsLogFile.imbue(std::locale("en-US.utf8")); fsLogFile << GetTimeStamp() << "[ " << szAppTitleVer.c_str() << " ] Start log." << std::endl;
fsLogFile << GetTimeStamp() << "[ " << szAppTitleVer.c_str() << " ] Start log." << std::endl; fsLogFile << GetTimeStamp() << "Logfile: \"" << log_path.native() << "\"" << std::endl;
fsLogFile << GetTimeStamp() << "Logfile: \"" << log_path.native() << "\"" << std::endl; }
} else {
else MessageBoxW(NULL, L"Warning!\nCan't create log file! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
{ }
MessageBoxW(NULL, L"Warning!\nCan't create log file! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
}
} }
CLogger::CLogger(const wchar_t* _appTitle) CLogger::CLogger(const wchar_t* _appTitle) {
{ szAppTitle = _appTitle;
szAppTitle = _appTitle; szAppTitleVer = _appTitle;
szAppTitleVer = _appTitle; Init();
Init();
} }
CLogger::~CLogger() CLogger::~CLogger() {
{ if (fsLogFile) {
if (fsLogFile) fsLogFile << GetTimeStamp() << "Stop log." << std::endl;
{ fsLogFile.close();
fsLogFile << GetTimeStamp() << "Stop log." << std::endl; DeleteCriticalSection(&cs);
fsLogFile.close(); }
DeleteCriticalSection(&cs);
}
} }

View File

@@ -29,24 +29,23 @@
#define MAX_LOGBUFFER_LENGTH 512 #define MAX_LOGBUFFER_LENGTH 512
class CLogger class CLogger {
{
public: public:
void Out(const wchar_t*, ...); void Out(const wchar_t*, ...);
CLogger(const wchar_t*); CLogger(const wchar_t*);
~CLogger(); ~CLogger();
private: private:
SYSTEMTIME lt; SYSTEMTIME lt;
CRITICAL_SECTION cs; CRITICAL_SECTION cs;
wchar_t logTimeBuffer[28]{ 0 }; wchar_t logTimeBuffer[28]{ 0 };
wchar_t logBuffer[MAX_LOGBUFFER_LENGTH]{ 0 }; wchar_t logBuffer[MAX_LOGBUFFER_LENGTH]{ 0 };
std::wofstream fsLogFile; std::wofstream fsLogFile;
std::wstring szAppTitle{ 0 }; std::wstring szAppTitle{ 0 };
std::wstring szAppVersion{ 0 }; std::wstring szAppVersion{ 0 };
std::wstring szAppPlatform{ 0 }; std::wstring szAppPlatform{ 0 };
std::wstring szAppTitleVer{ 0 }; std::wstring szAppTitleVer{ 0 };
inline wchar_t* GetTimeStamp(); inline wchar_t* GetTimeStamp();
void Init(); void Init();
}; };

View File

@@ -25,4 +25,4 @@
#pragma once #pragma once
#include "targetver.h" #include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

View File

@@ -33,12 +33,11 @@
picojson::value json; picojson::value json;
struct Version struct Version {
{ UINT Major = 0;
UINT Major = 0; UINT Minor = 0;
UINT Minor = 0; UINT Build = 0;
UINT Build = 0; UINT Patch = 0;
UINT Patch = 0;
} verApp, verGh; } verApp, verGh;
bool GetLatestRelease(const std::wstring& urn); bool GetLatestRelease(const std::wstring& urn);
@@ -46,204 +45,179 @@ void FillVersionStructure(Version& ver, const std::wstring& str);
std::vector<std::wstring> Split(const std::wstring& s, wchar_t delim); std::vector<std::wstring> Split(const std::wstring& s, wchar_t delim);
std::wstring ConvertUtf8ToWide(const std::string& str); std::wstring ConvertUtf8ToWide(const std::string& str);
UINT WINAPI Updater(void*) UINT WINAPI Updater(void*) {
{ logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__)); logger.Out(L"[UPDT] Sleeping %d seconds", T0);
logger.Out(L"[UPDT] Sleeping %d seconds", T0);
Sleep(T0 * 1000); // 10 seconds Sleep(T0 * 1000); // 10 seconds
if (!GetLatestRelease(GITHUB_URI)) if (!GetLatestRelease(GITHUB_URI)) {
{ logger.Out(L"[UPDT] %s(%d): Failed getting releases!", TEXT(__FUNCTION__), __LINE__);
logger.Out(L"[UPDT] %s(%d): Failed getting releases!", TEXT(__FUNCTION__), __LINE__);
MessageBoxW(NULL, L"Failed getting releases!", szTitle, MB_OK | MB_ICONERROR); MessageBoxW(NULL, L"Failed getting releases!", szTitle, MB_OK | MB_ICONERROR);
return 101; return 101;
_endthreadex(101); _endthreadex(101);
} }
std::wstring j_tag_name, j_file_name, j_file_ext, j_file_url, j_page_url; std::wstring j_tag_name, j_file_name, j_file_ext, j_file_url, j_page_url;
int64_t j_file_size = 0; int64_t j_file_size = 0;
picojson::object obj, obj2; picojson::object obj, obj2;
picojson::object::iterator it, it2; picojson::object::iterator it, it2;
if (json.is<picojson::object>()) if (json.is<picojson::object>()) {
{ logger.Out(L"[UPDT] %s(%d): Parsing JSON object", TEXT(__FUNCTION__), __LINE__);
logger.Out(L"[UPDT] %s(%d): Parsing JSON object", TEXT(__FUNCTION__), __LINE__);
obj = json.get<picojson::object>(); obj = json.get<picojson::object>();
it = obj.find("message"), it2; it = obj.find("message"), it2;
if (it != obj.end()) if (it != obj.end()) {
{ std::string u = (*it).second.get<std::string>();
std::string u = (*it).second.get<std::string>(); logger.Out(L"[UPDT] %s(%d): Error! The url is %s", TEXT(__FUNCTION__), __LINE__, u);
logger.Out(L"[UPDT] %s(%d): Error! The url is %s", TEXT(__FUNCTION__), __LINE__, u); return 102;
return 102; _endthreadex(102);
_endthreadex(102); }
}
for (it = obj.begin(); it != obj.end(); it++) for (it = obj.begin(); it != obj.end(); it++) {
{ if ((*it).first == "tag_name") j_tag_name = ConvertUtf8ToWide((*it).second.to_str());
if ((*it).first == "tag_name") j_tag_name = ConvertUtf8ToWide((*it).second.to_str()); if ((*it).first == "html_url") j_page_url = ConvertUtf8ToWide((*it).second.to_str());
if ((*it).first == "html_url") j_page_url = ConvertUtf8ToWide((*it).second.to_str()); if ((*it).first == "assets" && (*it).second.is<picojson::array>()) {
if ((*it).first == "assets" && (*it).second.is<picojson::array>()) picojson::array a = (*it).second.get<picojson::array>();
{ obj2 = a[0].get<picojson::object>();
picojson::array a = (*it).second.get<picojson::array>(); for (it2 = obj2.begin(); it2 != obj2.end(); it2++) {
obj2 = a[0].get<picojson::object>(); if ((*it2).first == "name") j_file_name = ConvertUtf8ToWide((*it2).second.to_str());
for (it2 = obj2.begin(); it2 != obj2.end(); it2++) if ((*it2).first == "browser_download_url") j_file_url = ConvertUtf8ToWide((*it2).second.to_str());
{ if ((*it2).first == "size") j_file_size = static_cast<int64_t>((*it2).second.get<double>());
if ((*it2).first == "name") j_file_name = ConvertUtf8ToWide((*it2).second.to_str()); }
if ((*it2).first == "browser_download_url") j_file_url = ConvertUtf8ToWide((*it2).second.to_str()); }
if ((*it2).first == "size") j_file_size = static_cast<int64_t>((*it2).second.get<double>()); }
} }
} else {
} logger.Out(L"[UPDT] %s(%d): Error! Cannot recognize JSON object!", TEXT(__FUNCTION__), __LINE__);
} return 103;
else _endthreadex(103);
{ }
logger.Out(L"[UPDT] %s(%d): Error! Cannot recognize JSON object!", TEXT(__FUNCTION__), __LINE__);
return 103;
_endthreadex(103);
}
size_t pos = 0; size_t pos = 0;
while (std::iswdigit(j_tag_name.at(pos)) == 0) pos++; while (std::iswdigit(j_tag_name.at(pos)) == 0) pos++;
std::wstring gh_version = j_tag_name.substr(pos); std::wstring gh_version = j_tag_name.substr(pos);
logger.Out(L"[UPDT] %s(%d): AppVersion : %s", TEXT(__FUNCTION__), __LINE__, TEXT(VERSION_STR)); logger.Out(L"[UPDT] %s(%d): AppVersion : %s", TEXT(__FUNCTION__), __LINE__, TEXT(VERSION_STR));
logger.Out(L"[UPDT] %s(%d): GitVersion : %s", TEXT(__FUNCTION__), __LINE__, gh_version.c_str()); logger.Out(L"[UPDT] %s(%d): GitVersion : %s", TEXT(__FUNCTION__), __LINE__, gh_version.c_str());
//logger.Out(L"[UPDT] %s(%d): FileName : %s", TEXT(__FUNCTION__), __LINE__, j_file_name.c_str()); //logger.Out(L"[UPDT] %s(%d): FileName : %s", TEXT(__FUNCTION__), __LINE__, j_file_name.c_str());
//logger.Out(L"[UPDT] %s(%d): FileSize : %d", TEXT(__FUNCTION__), __LINE__, j_file_size); //logger.Out(L"[UPDT] %s(%d): FileSize : %d", TEXT(__FUNCTION__), __LINE__, j_file_size);
//logger.Out(L"[UPDT] %s(%d): File Url : %s", TEXT(__FUNCTION__), __LINE__, j_file_url.c_str()); //logger.Out(L"[UPDT] %s(%d): File Url : %s", TEXT(__FUNCTION__), __LINE__, j_file_url.c_str());
//logger.Out(L"[UPDT] %s(%d): Page Url : %s", TEXT(__FUNCTION__), __LINE__, j_page_url.c_str()); //logger.Out(L"[UPDT] %s(%d): Page Url : %s", TEXT(__FUNCTION__), __LINE__, j_page_url.c_str());
FillVersionStructure(verApp, TEXT(VERSION_STR)); FillVersionStructure(verApp, TEXT(VERSION_STR));
FillVersionStructure(verGh, gh_version); FillVersionStructure(verGh, gh_version);
if ((verGh.Major > verApp.Major) || (verGh.Minor > verApp.Minor) || (verGh.Build > verApp.Build) || (verGh.Patch > verApp.Patch)) if ((verGh.Major > verApp.Major) || (verGh.Minor > verApp.Minor) || (verGh.Build > verApp.Build) || (verGh.Patch > verApp.Patch)) {
{
logger.Out(L"[UPDT] %s(%d): An update is available!", TEXT(__FUNCTION__), __LINE__); logger.Out(L"[UPDT] %s(%d): An update is available!", TEXT(__FUNCTION__), __LINE__);
if (IDYES == MessageBoxW(NULL, L"An update is available!\nDo you want to open the download page?", szTitle, MB_YESNO | MB_ICONINFORMATION)) if (IDYES == MessageBoxW(NULL, L"An update is available!\nDo you want to open the download page?", szTitle, MB_YESNO | MB_ICONINFORMATION)) {
{ logger.Out(L"[UPDT] %s(%d): Opening download page by default browser", TEXT(__FUNCTION__), __LINE__);
logger.Out(L"[UPDT] %s(%d): Opening download page by default browser", TEXT(__FUNCTION__), __LINE__); ShellExecuteW(NULL, L"open", j_page_url.c_str(), NULL, NULL, SW_SHOW);
ShellExecuteW(NULL, L"open", j_page_url.c_str(), NULL, NULL, SW_SHOW); }
} else {
else logger.Out(L"[UPDT] %s(%d): The user refused the update", TEXT(__FUNCTION__), __LINE__);
{ }
logger.Out(L"[UPDT] %s(%d): The user refused the update", TEXT(__FUNCTION__), __LINE__); }
} else {
} logger.Out(L"[UPDT] %s(%d): No updates is available", TEXT(__FUNCTION__), __LINE__);
else }
{
logger.Out(L"[UPDT] %s(%d): No updates is available", TEXT(__FUNCTION__), __LINE__);
}
logger.Out(L"[UPDT] Exit from the %s() function", TEXT(__FUNCTION__)); logger.Out(L"[UPDT] Exit from the %s() function", TEXT(__FUNCTION__));
return 0; return 0;
_endthreadex(0); _endthreadex(0);
} }
bool GetLatestRelease(const std::wstring& urn) bool GetLatestRelease(const std::wstring& urn) {
{ std::wstring user_agent = L"User-Agent: ";
std::wstring user_agent = L"User-Agent: "; user_agent.append(szTitle);
user_agent.append(szTitle); const std::wstring url = GITHUB_URL;
const std::wstring url = GITHUB_URL; bool ret = true;
bool ret = true; DWORD err = 0;
DWORD err = 0;
logger.Out(L"[UPDT] %s(%d): %s", TEXT(__FUNCTION__), __LINE__, user_agent.c_str()); logger.Out(L"[UPDT] %s(%d): %s", TEXT(__FUNCTION__), __LINE__, user_agent.c_str());
HINTERNET hInternet = InternetOpenW(user_agent.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); HINTERNET hInternet = InternetOpenW(user_agent.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet != NULL) if (hInternet != NULL) {
{ HINTERNET hConnect = InternetConnectW(hInternet, url.c_str(), INTERNET_DEFAULT_HTTPS_PORT, L"", L"", INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0);
HINTERNET hConnect = InternetConnectW(hInternet, url.c_str(), INTERNET_DEFAULT_HTTPS_PORT, L"", L"", INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0); if (hConnect != NULL) {
if (hConnect != NULL) HINTERNET hRequest = HttpOpenRequestW(hConnect, L"GET", urn.c_str(), NULL, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_UI, 0);
{ if (hRequest != NULL) {
HINTERNET hRequest = HttpOpenRequestW(hConnect, L"GET", urn.c_str(), NULL, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_UI, 0); BOOL isSend = HttpSendRequestW(hRequest, NULL, 0, 0, 0);
if (hRequest != NULL) if (isSend) {
{ char szData[1024]{ 0 };
BOOL isSend = HttpSendRequestW(hRequest, NULL, 0, 0, 0); DWORD dwBytesRead = 0;
if (isSend) std::string buffer;
{ do {
char szData[1024]{ 0 }; InternetReadFile(hRequest, szData, sizeof(szData), &dwBytesRead);
DWORD dwBytesRead = 0; buffer.append(szData, dwBytesRead);
std::string buffer; }
do while (dwBytesRead != 0);
{
InternetReadFile(hRequest, szData, sizeof(szData), &dwBytesRead);
buffer.append(szData, dwBytesRead);
} while (dwBytesRead != 0);
picojson::parse(json, buffer); picojson::parse(json, buffer);
std::string jerr = picojson::get_last_error(); std::string jerr = picojson::get_last_error();
if (!jerr.empty()) if (!jerr.empty()) {
{ logger.Out(L"[UPDT] %s(%d): Error while parsing JSON object: %s", TEXT(__FUNCTION__), __LINE__, ConvertUtf8ToWide(jerr));
logger.Out(L"[UPDT] %s(%d): Error while parsing JSON object: %s", TEXT(__FUNCTION__), __LINE__, ConvertUtf8ToWide(jerr));
MessageBoxW(NULL, L"Error while parsing JSON object!", szTitle, MB_OK | MB_ICONERROR); MessageBoxW(NULL, L"Error while parsing JSON object!", szTitle, MB_OK | MB_ICONERROR);
ret = false; ret = false;
} }
} }
else else {
{ err = GetLastError();
err = GetLastError(); logger.Out(L"[UPDT] %s(%d): HttpSendRequestW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
logger.Out(L"[UPDT] %s(%d): HttpSendRequestW() error: %d", TEXT(__FUNCTION__), __LINE__, err); ret = false;
ret = false; }
} }
} else {
else err = GetLastError();
{ logger.Out(L"[UPDT] %s(%d): HttpOpenRequestW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
err = GetLastError(); ret = false;
logger.Out(L"[UPDT] %s(%d): HttpOpenRequestW() error: %d", TEXT(__FUNCTION__), __LINE__, err); }
ret = false; InternetCloseHandle(hRequest);
} }
InternetCloseHandle(hRequest); else {
} err = GetLastError();
else logger.Out(L"[UPDT] %s(%d): InternetConnectW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
{ ret = false;
err = GetLastError(); }
logger.Out(L"[UPDT] %s(%d): InternetConnectW() error: %d", TEXT(__FUNCTION__), __LINE__, err); InternetCloseHandle(hConnect);
ret = false; }
} else {
InternetCloseHandle(hConnect); err = GetLastError();
} logger.Out(L"[UPDT] %s(%d): InternetOpenW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
else ret = false;
{ }
err = GetLastError(); InternetCloseHandle(hInternet);
logger.Out(L"[UPDT] %s(%d): InternetOpenW() error: %d", TEXT(__FUNCTION__), __LINE__, err); return ret;
ret = false;
}
InternetCloseHandle(hInternet);
return ret;
} }
std::vector<std::wstring> Split(const std::wstring& s, wchar_t delim) std::vector<std::wstring> Split(const std::wstring& s, wchar_t delim) {
{ std::vector<std::wstring> result;
std::vector<std::wstring> result; std::wstringstream ss(s);
std::wstringstream ss(s); std::wstring item;
std::wstring item; while (getline(ss, item, delim)) result.push_back(item);
while (getline(ss, item, delim)) result.push_back(item); return result;
return result;
} }
void FillVersionStructure(Version& ver, const std::wstring& str) void FillVersionStructure(Version& ver, const std::wstring& str) {
{ std::vector<std::wstring> v;
std::vector<std::wstring> v; v = Split(str, '.');
v = Split(str, '.'); if (v.size() < 4) v.push_back(L"0");
if (v.size() < 4) v.push_back(L"0"); ver.Major = std::stoul(v[0]);
ver.Major = std::stoul(v[0]); ver.Minor = std::stoul(v[1]);
ver.Minor = std::stoul(v[1]); ver.Build = std::stoul(v[2]);
ver.Build = std::stoul(v[2]); ver.Patch = std::stoul(v[3]);
ver.Patch = std::stoul(v[3]);
} }
std::wstring ConvertUtf8ToWide(const std::string& str) std::wstring ConvertUtf8ToWide(const std::string& str) {
{ int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0); std::wstring wstr(count, 0);
std::wstring wstr(count, 0); MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count); return wstr;
return wstr;
} }

File diff suppressed because it is too large Load Diff