From 8a5e49251cabfbc7a3ffe7a21bc9a5f84d07aaf7 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Fri, 2 Apr 2021 23:40:54 -0400 Subject: [PATCH 1/7] Remove hex symbols in overlay chat window. --- overlay_experimental/steam_overlay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index 93f739e..387962c 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -698,7 +698,7 @@ void Steam_Overlay::Callback(Common_Message *msg) { Steam_Messages const& steam_message = msg->steam_messages(); // Change color to cyan for friend - friend_info->second.chat_history.append("\x1""00FFFFFF", 9).append(steam_message.message()).append("\n", 1); + friend_info->second.chat_history.append(steam_message.message()).append("\n", 1); if (!(friend_info->second.window_state & window_state_show)) { friend_info->second.window_state |= window_state_need_attention; @@ -758,7 +758,7 @@ void Steam_Overlay::RunCallbacks() msg.set_dest_id(friend_id); network->sendTo(&msg, true); - friend_info->second.chat_history.append("\x1""00FF00FF", 9).append(input).append("\n", 1); + friend_info->second.chat_history.append(input).append("\n", 1); } *input = 0; // Reset the input field friend_info->second.window_state &= ~window_state_send_message; From dc95076faa2a597c33252fa29a9dc93329d97be6 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Fri, 2 Apr 2021 23:42:22 -0400 Subject: [PATCH 2/7] Achievement names are now treated as case insensitive. This should fix achievements in a few games. --- dll/steam_user_stats.h | 77 ++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/dll/steam_user_stats.h b/dll/steam_user_stats.h index 7de7923..a35d3a0 100644 --- a/dll/steam_user_stats.h +++ b/dll/steam_user_stats.h @@ -66,6 +66,17 @@ unsigned int find_leaderboard(std::string name) return 0; } +nlohmann::detail::iter_impl defined_achievements_find(std::string key) +{ + return std::find_if(defined_achievements.begin(), defined_achievements.end(), [key](nlohmann::json& item) { + std::string name = static_cast(item["name"]); + return key.size() == name.size() && std::equal(name.begin(), name.end(), key.begin(), + [](char a, char b) { + return tolower(a) == tolower(b); + }); + }); +} + void load_achievements_db() { std::string file_path = Local_Storage::get_game_settings_path() + achievements_user_file; @@ -227,10 +238,10 @@ bool GetAchievement( const char *pchName, bool *pbAchieved ) std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName]( nlohmann::json &item ) { - return item["name"].get() == pchName; - }); - auto ach = user_achievements.find(pchName); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + + auto ach = user_achievements.find(pch_name); if (it != defined_achievements.end() && ach != user_achievements.end()) { if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"]; return true; @@ -249,13 +260,13 @@ bool SetAchievement( const char *pchName ) std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return item["name"].get() == pchName; - }); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + if (it != defined_achievements.end()) { - if (user_achievements.find(pchName) == user_achievements.end() || user_achievements[pchName].value("earned", false) == false) { - user_achievements[pchName]["earned"] = true; - user_achievements[pchName]["earned_time"] = std::chrono::duration_cast>(std::chrono::system_clock::now().time_since_epoch()).count(); + if (user_achievements.find(pch_name) == user_achievements.end() || user_achievements[pch_name].value("earned", false) == false) { + user_achievements[pch_name]["earned"] = true; + user_achievements[pch_name]["earned_time"] = std::chrono::duration_cast>(std::chrono::system_clock::now().time_since_epoch()).count(); #ifdef EMU_OVERLAY overlay->AddAchievementNotification(it.value()); #endif @@ -276,12 +287,12 @@ bool ClearAchievement( const char *pchName ) std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + if (it != defined_achievements.end()) { - user_achievements[pchName]["earned"] = false; - user_achievements[pchName]["earned_time"] = static_cast(0); + user_achievements[pch_name]["earned"] = false; + user_achievements[pch_name]["earned_time"] = static_cast(0); save_achievements(); return true; } @@ -301,10 +312,10 @@ bool GetAchievementAndUnlockTime( const char *pchName, bool *pbAchieved, uint32 std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); - auto ach = user_achievements.find(pchName); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + + auto ach = user_achievements.find(pch_name); if (it != defined_achievements.end() && ach != user_achievements.end()) { if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"]; if(punUnlockTime != nullptr) *punUnlockTime = (*ach)["earned_time"]; @@ -367,9 +378,7 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc if (strcmp (pchKey, "name") == 0) { try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); + auto it = defined_achievements_find(pchName); if (it != defined_achievements.end()) { return it.value()["displayName"].get_ptr()->c_str(); } @@ -378,9 +387,7 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc if (strcmp (pchKey, "desc") == 0) { try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); + auto it = defined_achievements_find(pchName); if (it != defined_achievements.end()) { return it.value()["description"].get_ptr()->c_str(); } @@ -389,9 +396,7 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc if (strcmp (pchKey, "hidden") == 0) { try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); + auto it = defined_achievements_find(pchName); if (it != defined_achievements.end()) { return it.value()["hidden"].get_ptr()->c_str(); } @@ -406,15 +411,15 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc // Calling this w/ N out of N progress will NOT set the achievement, the game must still do that. bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint32 nMaxProgress ) { - PRINT_DEBUG("IndicateAchievementProgress\n"); + PRINT_DEBUG("IndicateAchievementProgress %s\n", pchName); if (pchName == nullptr) return false; std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); - auto ach = user_achievements.find(pchName); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + + auto ach = user_achievements.find(pch_name); if (it != defined_achievements.end()) { bool achieved = false; if ( ach != user_achievements.end()) { @@ -424,14 +429,14 @@ bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint UserAchievementStored_t data = {}; data.m_nGameID = settings->get_local_game_id().ToUint64(); data.m_bGroupAchievement = false; - strncpy(data.m_rgchAchievementName, pchName, k_cchStatNameMax); + strncpy(data.m_rgchAchievementName, pch_name.c_str(), k_cchStatNameMax); if (achieved) { data.m_nCurProgress = 0; data.m_nMaxProgress = 0; } else { - user_achievements[pchName]["progress"] = nCurProgress; - user_achievements[pchName]["max_progress"] = nMaxProgress; + user_achievements[pch_name]["progress"] = nCurProgress; + user_achievements[pch_name]["max_progress"] = nMaxProgress; data.m_nCurProgress = nCurProgress; data.m_nMaxProgress = nMaxProgress; } From c48526d49af7147e8a7f64c26b19d8396a999bcd Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Fri, 9 Apr 2021 14:52:45 -0400 Subject: [PATCH 3/7] Fix possible crash. --- dll/steam_user_stats.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dll/steam_user_stats.h b/dll/steam_user_stats.h index a35d3a0..8d22cb7 100644 --- a/dll/steam_user_stats.h +++ b/dll/steam_user_stats.h @@ -239,6 +239,7 @@ bool GetAchievement( const char *pchName, bool *pbAchieved ) try { auto it = defined_achievements_find(pchName); + if (it == defined_achievements.end()) return false; std::string pch_name = it->value("name", std::string()); auto ach = user_achievements.find(pch_name); @@ -261,6 +262,7 @@ bool SetAchievement( const char *pchName ) try { auto it = defined_achievements_find(pchName); + if (it == defined_achievements.end()) return false; std::string pch_name = it->value("name", std::string()); if (it != defined_achievements.end()) { @@ -288,6 +290,7 @@ bool ClearAchievement( const char *pchName ) try { auto it = defined_achievements_find(pchName); + if (it == defined_achievements.end()) return false; std::string pch_name = it->value("name", std::string()); if (it != defined_achievements.end()) { @@ -313,6 +316,7 @@ bool GetAchievementAndUnlockTime( const char *pchName, bool *pbAchieved, uint32 try { auto it = defined_achievements_find(pchName); + if (it == defined_achievements.end()) return false; std::string pch_name = it->value("name", std::string()); auto ach = user_achievements.find(pch_name); @@ -417,6 +421,8 @@ bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint try { auto it = defined_achievements_find(pchName); + if (it == defined_achievements.end()) return false; + std::string pch_name = it->value("name", std::string()); auto ach = user_achievements.find(pch_name); From 19015c097c41a59107c62487a11273047fccb219 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Fri, 9 Apr 2021 14:53:20 -0400 Subject: [PATCH 4/7] Hopefully this fixes the SteamAPI_ISteamGameServer_GetPublicIP function --- dll/dll.cpp | 2 +- dll/flat.cpp | 9 +++++---- dll/steam_client.cpp | 4 ++++ dll/steam_client.h | 2 ++ dll/steam_gameserver.cpp | 6 ++++++ dll/steam_gameserver.h | 1 + 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/dll/dll.cpp b/dll/dll.cpp index be5587a..1385b92 100644 --- a/dll/dll.cpp +++ b/dll/dll.cpp @@ -136,7 +136,7 @@ Steam_Client *get_steam_clientserver_old() static bool steamclient_has_ipv6_functions_flag; bool steamclient_has_ipv6_functions() { - return steamclient_has_ipv6_functions_flag; + return steamclient_has_ipv6_functions_flag || get_steam_client()->gameserver_has_ipv6_functions; } static void *create_client_interface(const char *ver) diff --git a/dll/flat.cpp b/dll/flat.cpp index d7da4ca..534e4a5 100644 --- a/dll/flat.cpp +++ b/dll/flat.cpp @@ -5843,13 +5843,14 @@ STEAMAPI_API SteamAPICall_t SteamAPI_ISteamGameServer_GetServerReputation( IStea return self->GetServerReputation(); } -STEAMAPI_API uint32 SteamAPI_ISteamGameServer_GetPublicIP( intptr_t instancePtr, void *instancePtr_possible ) +STEAMAPI_API void *SteamAPI_ISteamGameServer_GetPublicIP( intptr_t instancePtr, void *instancePtr_possible ) { - //TODO: check if this actually works (ret value changed from uint32 to struct) + //abuse call convention rules to get this working. if (steamclient_has_ipv6_functions()) { - return ((ISteamGameServer012 *)instancePtr_possible)->GetPublicIP_old(); + get_steam_client()->steam_gameserver->GetPublicIP_fix((SteamIPAddress_t *)instancePtr); + return (void *)instancePtr; } else { - return ((ISteamGameServer012 *)instancePtr)->GetPublicIP_old(); + return (void *)((ISteamGameServer012 *)instancePtr)->GetPublicIP_old(); } } diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp index 0ce6324..27757f0 100644 --- a/dll/steam_client.cpp +++ b/dll/steam_client.cpp @@ -109,6 +109,8 @@ Steam_Client::Steam_Client() steam_gameserver_game_coordinator = new Steam_Game_Coordinator(settings_server, network, callback_results_server, callbacks_server, run_every_runcb); steam_masterserver_updater = new Steam_Masterserver_Updater(settings_server, network, callback_results_server, callbacks_server, run_every_runcb); + gameserver_has_ipv6_functions = false; + last_cb_run = 0; PRINT_DEBUG("client init end\n"); } @@ -303,8 +305,10 @@ ISteamGameServer *Steam_Client::GetISteamGameServer( HSteamUser hSteamUser, HSte } else if (strcmp(pchVersion, "SteamGameServer012") == 0) { return (ISteamGameServer *)(void *)(ISteamGameServer012 *)steam_gameserver; } else if (strcmp(pchVersion, STEAMGAMESERVER_INTERFACE_VERSION) == 0) { + gameserver_has_ipv6_functions = true; return (ISteamGameServer *)(void *)(ISteamGameServer *)steam_gameserver; } else { + gameserver_has_ipv6_functions = true; return (ISteamGameServer *)(void *)(ISteamGameServer *)steam_gameserver; } diff --git a/dll/steam_client.h b/dll/steam_client.h index b46285e..d00cb6a 100644 --- a/dll/steam_client.h +++ b/dll/steam_client.h @@ -139,6 +139,8 @@ public: unsigned steam_pipe_counter = 1; std::map steam_pipes; + bool gameserver_has_ipv6_functions; + Steam_Client(); ~Steam_Client(); // Creates a communication pipe to the Steam client. diff --git a/dll/steam_gameserver.cpp b/dll/steam_gameserver.cpp index 6735456..584f369 100644 --- a/dll/steam_gameserver.cpp +++ b/dll/steam_gameserver.cpp @@ -559,6 +559,12 @@ SteamIPAddress_t Steam_GameServer::GetPublicIP() return ip; } +void Steam_GameServer::GetPublicIP_fix(SteamIPAddress_t *out) +{ + PRINT_DEBUG("GetPublicIP_fix\n"); + if (out) *out = GetPublicIP(); +} + // These are in GameSocketShare mode, where instead of ISteamGameServer creating its own // socket to talk to the master server on, it lets the game use its socket to forward messages // back and forth. This prevents us from requiring server ops to open up yet another port diff --git a/dll/steam_gameserver.h b/dll/steam_gameserver.h index cc11682..e66f3b9 100644 --- a/dll/steam_gameserver.h +++ b/dll/steam_gameserver.h @@ -278,6 +278,7 @@ public: // connect to uint32 GetPublicIP_old(); SteamIPAddress_t GetPublicIP(); + void GetPublicIP_fix(SteamIPAddress_t *out); // These are in GameSocketShare mode, where instead of ISteamGameServer creating its own // socket to talk to the master server on, it lets the game use its socket to forward messages From b8eae2b709a75483ce6ac1219006437543a31748 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 18 Apr 2021 22:36:48 -0400 Subject: [PATCH 5/7] Don't memset the whole connection status structs to zero. Some games pass smaller versions of the struct. --- dll/steam_networking_sockets.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dll/steam_networking_sockets.h b/dll/steam_networking_sockets.h index bb5ccd6..7550413 100644 --- a/dll/steam_networking_sockets.h +++ b/dll/steam_networking_sockets.h @@ -882,17 +882,20 @@ bool GetConnectionInfo( HSteamNetConnection hConn, SteamNetConnectionInfo_t *pIn auto connect_socket = connect_sockets.find(hConn); if (connect_socket == connect_sockets.end()) return false; - memset(pInfo, 0, sizeof(SteamNetConnectionInfo_t)); pInfo->m_identityRemote = connect_socket->second.remote_identity; pInfo->m_nUserData = connect_socket->second.user_data; pInfo->m_hListenSocket = connect_socket->second.listen_socket_id; - //pInfo->m_addrRemote; //TODO + pInfo->m_addrRemote.Clear(); //TODO pInfo->m_idPOPRemote = 0; pInfo->m_idPOPRelay = 0; pInfo->m_eState = convert_status(connect_socket->second.status); pInfo->m_eEndReason = 0; //TODO pInfo->m_szEndDebug[0] = 0; sprintf(pInfo->m_szConnectionDescription, "%u", hConn); + + //Note some games might not allocate a struct the whole size of SteamNetConnectionInfo_t + //keep this in mind in future interface updates + return true; } @@ -954,13 +957,21 @@ bool GetQuickConnectionStatus( HSteamNetConnection hConn, SteamNetworkingQuickCo std::lock_guard lock(global_mutex); auto connect_socket = connect_sockets.find(hConn); if (connect_socket == connect_sockets.end()) return false; - memset(pStats, 0, sizeof(SteamNetworkingQuickConnectionStatus)); pStats->m_eState = convert_status(connect_socket->second.status); pStats->m_nPing = 10; //TODO: calculate real numbers? pStats->m_flConnectionQualityLocal = 1.0; pStats->m_flConnectionQualityRemote = 1.0; //TODO: rest + pStats->m_flOutPacketsPerSec = 0.0; + pStats->m_flOutBytesPerSec = 0.0; + pStats->m_flInPacketsPerSec = 0.0; + pStats->m_flInBytesPerSec = 0.0; + pStats->m_cbSentUnackedReliable = 0.0; + pStats->m_usecQueueTime = 0.0; + + //Note some games (volcanoids) might not allocate a struct the whole size of SteamNetworkingQuickConnectionStatus + //keep this in mind in future interface updates return true; } From 51702b898e99ad111b57e4259198adaa7d23452e Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 25 Apr 2021 12:44:41 -0400 Subject: [PATCH 6/7] UTF8 paths are now properly handled on windows. --- dll/base.cpp | 25 +++--- dll/common_includes.h | 23 ++++++ dll/dll.cpp | 2 +- dll/local_storage.cpp | 175 +++++++++++++++++++++++----------------- dll/settings_parser.cpp | 18 ++--- 5 files changed, 147 insertions(+), 96 deletions(-) diff --git a/dll/base.cpp b/dll/base.cpp index 4e805e5..7a07926 100644 --- a/dll/base.cpp +++ b/dll/base.cpp @@ -28,14 +28,14 @@ randombytes(char * const buf, const size_t size) std::string get_env_variable(std::string name) { - char env_variable[1024]; - DWORD ret = GetEnvironmentVariableA(name.c_str(), env_variable, sizeof(env_variable)); + wchar_t env_variable[1024]; + DWORD ret = GetEnvironmentVariableW(utf8_decode(name).c_str(), env_variable, _countof(env_variable)); if (ret <= 0) { return std::string(); } env_variable[ret] = 0; - return std::string(env_variable); + return utf8_encode(env_variable); } #else @@ -194,9 +194,9 @@ std::string get_full_lib_path() { std::string program_path; #if defined(__WINDOWS__) - char DllPath[MAX_PATH] = {0}; - GetModuleFileName((HINSTANCE)&__ImageBase, DllPath, _countof(DllPath)); - program_path = DllPath; + wchar_t DllPath[2048] = {0}; + GetModuleFileNameW((HINSTANCE)&__ImageBase, DllPath, _countof(DllPath)); + program_path = utf8_encode(DllPath); #else program_path = get_lib_path(); #endif @@ -240,15 +240,18 @@ std::string canonical_path(std::string path) { std::string output; #if defined(STEAM_WIN32) - char *buffer = _fullpath(NULL, path.c_str(), 0); + wchar_t *buffer = _wfullpath(NULL, utf8_decode(path).c_str(), 0); + if (buffer) { + output = utf8_encode(buffer); + free(buffer); + } #else char *buffer = canonicalize_file_name(path.c_str()); -#endif - if (buffer) { output = buffer; free(buffer); } +#endif return output; } @@ -633,7 +636,7 @@ static void load_dll() PRINT_DEBUG("Crack file %s\n", path.c_str()); if (file_exists(path)) { redirect_crackdll(); - crack_dll_handle = LoadLibraryA(path.c_str()); + crack_dll_handle = LoadLibraryW(utf8_decode(path).c_str()); unredirect_crackdll(); PRINT_DEBUG("Loaded crack file\n"); } @@ -657,7 +660,7 @@ static void load_dlls() if (full_path[length - 4] != '.') continue; PRINT_DEBUG("Trying to load %s\n", full_path.c_str()); - if (LoadLibraryA(full_path.c_str())) { + if (LoadLibraryW(utf8_decode(full_path).c_str())) { PRINT_DEBUG("LOADED %s\n", full_path.c_str()); } } diff --git a/dll/common_includes.h b/dll/common_includes.h index 7214d78..4dc55d1 100644 --- a/dll/common_includes.h +++ b/dll/common_includes.h @@ -84,6 +84,27 @@ #endif #endif +#include +// Convert a wide Unicode string to an UTF8 string +inline std::string utf8_encode(const std::wstring &wstr) +{ + if( wstr.empty() ) return std::string(); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); + std::string strTo( size_needed, 0 ); + WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); + return strTo; +} + +// Convert an UTF8 string to a wide Unicode String +inline std::wstring utf8_decode(const std::string &str) +{ + if( str.empty() ) return std::wstring(); + int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); + std::wstring wstrTo( size_needed, 0 ); + MultiByteToWideChar (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); + return wstrTo; +} + #elif defined(__LINUX__) #include @@ -112,6 +133,8 @@ #define PRINT_DEBUG(...) {FILE *t = fopen("STEAM_LOG.txt", "a"); fprintf(t, __VA_ARGS__); fclose(t);} #endif #define PATH_SEPARATOR "/" + + #define utf8_decode(a) a #endif //#define PRINT_DEBUG(...) fprintf(stdout, __VA_ARGS__) #ifdef EMU_RELEASE_BUILD diff --git a/dll/dll.cpp b/dll/dll.cpp index 1385b92..3857d05 100644 --- a/dll/dll.cpp +++ b/dll/dll.cpp @@ -49,7 +49,7 @@ static void load_old_interface_versions() static bool loaded = false; if (loaded) return; std::string interfaces_path = Local_Storage::get_program_path() + "steam_interfaces.txt"; - std::ifstream input( interfaces_path ); + std::ifstream input( utf8_decode(interfaces_path) ); PRINT_DEBUG("load from: %s\n", interfaces_path.c_str()); for( std::string line; getline( input, line ); ) diff --git a/dll/local_storage.cpp b/dll/local_storage.cpp index 81e17b9..8697600 100644 --- a/dll/local_storage.cpp +++ b/dll/local_storage.cpp @@ -21,6 +21,9 @@ #define STB_IMAGE_STATIC #define STBI_ONLY_PNG #define STBI_ONLY_JPEG +#if defined(__WINDOWS__) +#define STBI_WINDOWS_UTF8 +#endif #include "../stb/stb_image.h" #define STB_IMAGE_WRITE_IMPLEMENTATION @@ -166,49 +169,93 @@ bool Local_Storage::save_screenshot(std::string const& image_path, uint8_t* img_ #else #if defined(__WINDOWS__) -static BOOL DirectoryExists(LPCSTR szPath) +static BOOL DirectoryExists(LPCWSTR szPath) { - DWORD dwAttrib = GetFileAttributesA(szPath); + DWORD dwAttrib = GetFileAttributesW(szPath); return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); } -static void createDirectoryRecursively(std::string path) +static void createDirectoryRecursively(std::wstring path) { unsigned long long pos = 0; do { - pos = path.find_first_of("\\/", pos + 1); - CreateDirectoryA(path.substr(0, pos).c_str(), NULL); + pos = path.find_first_of(L"\\/", pos + 1); + CreateDirectoryW(path.substr(0, pos).c_str(), NULL); } while (pos != std::string::npos); } -static void create_directory(std::string strPath) +static void create_directory(std::string in_path) { + std::wstring strPath = utf8_decode(in_path); if (DirectoryExists(strPath.c_str()) == FALSE) createDirectoryRecursively(strPath); } -static std::vector get_filenames(std::string strPath) +static std::vector get_filenames(std::string in_path) { std::vector output; - strPath = strPath.append("\\*"); - WIN32_FIND_DATAA ffd; + in_path = in_path.append("\\*"); + WIN32_FIND_DATAW ffd; HANDLE hFind = INVALID_HANDLE_VALUE; + std::wstring strPath = utf8_decode(in_path); // Start iterating over the files in the path directory. - hFind = ::FindFirstFileA (strPath.c_str(), &ffd); + hFind = ::FindFirstFileW (strPath.c_str(), &ffd); if (hFind != INVALID_HANDLE_VALUE) { do // Managed to locate and create an handle to that folder. { - if (strcmp(".", ffd.cFileName) == 0) continue; - if (strcmp("..", ffd.cFileName) == 0) continue; + if (wcscmp(L".", ffd.cFileName) == 0) continue; + if (wcscmp(L"..", ffd.cFileName) == 0) continue; struct File_Data f_data; - f_data.name = ffd.cFileName; + f_data.name = utf8_encode(ffd.cFileName); output.push_back(f_data); - } while (::FindNextFileA(hFind, &ffd) == TRUE); + } while (::FindNextFileW(hFind, &ffd) == TRUE); + ::FindClose(hFind); + } else { + //printf("Failed to find path: %s", strPath.c_str()); + } + + return output; +} + +static std::vector get_filenames_recursive_w(std::wstring base_path) +{ + if (base_path.back() == *L"\\") + base_path.pop_back(); + std::vector output; + std::wstring strPath = base_path; + strPath = strPath.append(L"\\*"); + WIN32_FIND_DATAW ffd; + HANDLE hFind = INVALID_HANDLE_VALUE; + + // Start iterating over the files in the path directory. + hFind = ::FindFirstFileW (strPath.c_str(), &ffd); + if (hFind != INVALID_HANDLE_VALUE) + { + do // Managed to locate and create an handle to that folder. + { + if (wcscmp(L".", ffd.cFileName) == 0) continue; + if (wcscmp(L"..", ffd.cFileName) == 0) continue; + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + // Construct new path from our base path + std::wstring dir_name = ffd.cFileName; + + std::wstring path = base_path; + path += L"\\"; + path += dir_name; + + std::vector lower = get_filenames_recursive_w(path); + std::transform(lower.begin(), lower.end(), std::back_inserter(output), [&dir_name](File_Data f) {f.name = utf8_encode(dir_name) + "\\" + f.name; return f;}); + } else { + File_Data f; + f.name = utf8_encode(ffd.cFileName); + output.push_back(f); + } + } while (::FindNextFileW(hFind, &ffd) == TRUE); ::FindClose(hFind); } else { //printf("Failed to find path: %s", strPath.c_str()); @@ -219,44 +266,7 @@ static std::vector get_filenames(std::string strPath) static std::vector get_filenames_recursive(std::string base_path) { - if (base_path.back() == *PATH_SEPARATOR) - base_path.pop_back(); - std::vector output; - std::string strPath = base_path; - strPath = strPath.append("\\*"); - WIN32_FIND_DATAA ffd; - HANDLE hFind = INVALID_HANDLE_VALUE; - - // Start iterating over the files in the path directory. - hFind = ::FindFirstFileA (strPath.c_str(), &ffd); - if (hFind != INVALID_HANDLE_VALUE) - { - do // Managed to locate and create an handle to that folder. - { - if (strcmp(".", ffd.cFileName) == 0) continue; - if (strcmp("..", ffd.cFileName) == 0) continue; - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - // Construct new path from our base path - std::string dir_name = ffd.cFileName; - - std::string path = base_path; - path += PATH_SEPARATOR; - path += dir_name; - - std::vector lower = get_filenames_recursive(path); - std::transform(lower.begin(), lower.end(), std::back_inserter(output), [&dir_name](File_Data f) {f.name = dir_name + "\\" + f.name; return f;}); - } else { - File_Data f; - f.name = ffd.cFileName; - output.push_back(f); - } - } while (::FindNextFileA(hFind, &ffd) == TRUE); - ::FindClose(hFind); - } else { - //printf("Failed to find path: %s", strPath.c_str()); - } - - return output; + return get_filenames_recursive_w(utf8_decode(base_path)); } #else @@ -403,12 +413,12 @@ std::string Local_Storage::get_user_appdata_path() { std::string user_appdata_path = "SAVE"; #if defined(STEAM_WIN32) - CHAR szPath[MAX_PATH] = {}; + WCHAR szPath[MAX_PATH] = {}; - HRESULT hr = SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, szPath); + HRESULT hr = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, szPath); if (SUCCEEDED(hr)) { - user_appdata_path = szPath; + user_appdata_path = utf8_encode(szPath); } #else @@ -504,7 +514,7 @@ int Local_Storage::store_file_data(std::string folder, std::string file, char *d create_directory(folder + file_folder); std::ofstream myfile; - myfile.open(folder + file, std::ios::binary | std::ios::out); + myfile.open(utf8_decode(folder + file), std::ios::binary | std::ios::out); if (!myfile.is_open()) return -1; myfile.write(data, length); int position = myfile.tellp(); @@ -553,7 +563,7 @@ int Local_Storage::store_data_settings(std::string file, char *data, unsigned in int Local_Storage::get_file_data(std::string full_path, char *data, unsigned int max_length, unsigned int offset) { std::ifstream myfile; - myfile.open(full_path, std::ios::binary | std::ios::in); + myfile.open(utf8_decode(full_path), std::ios::binary | std::ios::in); if (!myfile.is_open()) return -1; myfile.seekg (offset, std::ios::beg); @@ -597,15 +607,19 @@ bool Local_Storage::file_exists(std::string folder, std::string file) } std::string full_path = save_directory + appid + folder + file; - struct stat buffer; - - if (stat(full_path.c_str(), &buffer) != 0) - return false; #if defined(STEAM_WIN32) + struct _stat buffer; + if (_wstat(utf8_decode(full_path).c_str(), &buffer) != 0) + return false; + if ( buffer.st_mode & _S_IFDIR) return false; #else + struct stat buffer; + if (stat(full_path.c_str(), &buffer) != 0) + return false; + if (S_ISDIR(buffer.st_mode)) return false; #endif @@ -621,8 +635,14 @@ unsigned int Local_Storage::file_size(std::string folder, std::string file) } std::string full_path = save_directory + appid + folder + file; - struct stat buffer = {}; + +#if defined(STEAM_WIN32) + struct _stat buffer = {}; + if (_wstat(utf8_decode(full_path).c_str(), &buffer) != 0) return 0; +#else + struct stat buffer = {}; if (stat (full_path.c_str(), &buffer) != 0) return 0; +#endif return buffer.st_size; } @@ -634,7 +654,11 @@ bool Local_Storage::file_delete(std::string folder, std::string file) } std::string full_path = save_directory + appid + folder + file; +#if defined(STEAM_WIN32) + return _wremove(utf8_decode(full_path).c_str()) == 0; +#else return remove(full_path.c_str()) == 0; +#endif } uint64_t Local_Storage::file_timestamp(std::string folder, std::string file) @@ -645,8 +669,14 @@ uint64_t Local_Storage::file_timestamp(std::string folder, std::string file) } std::string full_path = save_directory + appid + folder + file; + +#if defined(STEAM_WIN32) + struct _stat buffer = {}; + if (_wstat(utf8_decode(full_path).c_str(), &buffer) != 0) return 0; +#else struct stat buffer = {}; if (stat (full_path.c_str(), &buffer) != 0) return 0; +#endif return buffer.st_mtime; } @@ -695,7 +725,7 @@ bool Local_Storage::update_save_filenames(std::string folder) bool Local_Storage::load_json(std::string full_path, nlohmann::json& json) { - std::ifstream inventory_file(full_path); + std::ifstream inventory_file(utf8_decode(full_path)); // If there is a file and we opened it if (inventory_file) { @@ -745,7 +775,7 @@ bool Local_Storage::write_json_file(std::string folder, std::string const&file, create_directory(inv_path); - std::ofstream inventory_file(full_path, std::ios::trunc | std::ios::out); + std::ofstream inventory_file(utf8_decode(full_path), std::ios::trunc | std::ios::out); if (inventory_file) { inventory_file << std::setw(2) << json; @@ -760,19 +790,14 @@ bool Local_Storage::write_json_file(std::string folder, std::string const&file, std::vector Local_Storage::load_image(std::string const& image_path) { std::vector res; - FILE* hFile = fopen(image_path.c_str(), "r"); - if (hFile != nullptr) + int width, height; + image_pixel_t* img = (image_pixel_t*)stbi_load(image_path.c_str(), &width, &height, nullptr, 4); + if (img != nullptr) { - int width, height; - image_pixel_t* img = (image_pixel_t*)stbi_load_from_file(hFile, &width, &height, nullptr, 4); - if (img != nullptr) - { - res.resize(width*height); - std::copy(img, img + width * height, res.begin()); + res.resize(width*height); + std::copy(img, img + width * height, res.begin()); - stbi_image_free(img); - } - fclose(hFile); + stbi_image_free(img); } return res; } diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index 78df6c6..f369cd6 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -31,7 +31,7 @@ static void consume_bom(std::ifstream &input) static void load_custom_broadcasts(std::string broadcasts_filepath, std::set &custom_broadcasts) { PRINT_DEBUG("Broadcasts file path: %s\n", broadcasts_filepath.c_str()); - std::ifstream broadcasts_file(broadcasts_filepath); + std::ifstream broadcasts_file(utf8_decode(broadcasts_filepath)); consume_bom(broadcasts_file); if (broadcasts_file.is_open()) { std::string line; @@ -69,7 +69,7 @@ static void load_gamecontroller_settings(Settings *settings) std::transform(action_set_name.begin(), action_set_name.end(), action_set_name.begin(),[](unsigned char c){ return std::toupper(c); }); std::string controller_config_path = path + PATH_SEPARATOR + p; - std::ifstream input( controller_config_path ); + std::ifstream input( utf8_decode(controller_config_path) ); if (input.is_open()) { consume_bom(input); std::map, std::string>> button_pairs; @@ -307,7 +307,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s { std::string dlc_config_path = Local_Storage::get_game_settings_path() + "DLC.txt"; - std::ifstream input( dlc_config_path ); + std::ifstream input( utf8_decode(dlc_config_path) ); if (input.is_open()) { consume_bom(input); settings_client->unlockAllDLC(false); @@ -349,7 +349,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s { std::string dlc_config_path = Local_Storage::get_game_settings_path() + "app_paths.txt"; - std::ifstream input( dlc_config_path ); + std::ifstream input( utf8_decode(dlc_config_path) ); if (input.is_open()) { consume_bom(input); @@ -384,7 +384,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s { std::string dlc_config_path = Local_Storage::get_game_settings_path() + "leaderboards.txt"; - std::ifstream input( dlc_config_path ); + std::ifstream input( utf8_decode(dlc_config_path) ); if (input.is_open()) { consume_bom(input); settings_client->setCreateUnknownLeaderboards(false); @@ -426,7 +426,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s { std::string stats_config_path = Local_Storage::get_game_settings_path() + "stats.txt"; - std::ifstream input( stats_config_path ); + std::ifstream input( utf8_decode(stats_config_path) ); if (input.is_open()) { consume_bom(input); for( std::string line; getline( input, line ); ) { @@ -491,7 +491,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s { std::string depots_config_path = Local_Storage::get_game_settings_path() + "depots.txt"; - std::ifstream input( depots_config_path ); + std::ifstream input( utf8_decode(depots_config_path) ); if (input.is_open()) { consume_bom(input); for( std::string line; getline( input, line ); ) { @@ -513,7 +513,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s { std::string depots_config_path = Local_Storage::get_game_settings_path() + "subscribed_groups.txt"; - std::ifstream input( depots_config_path ); + std::ifstream input( utf8_decode(depots_config_path) ); if (input.is_open()) { consume_bom(input); for( std::string line; getline( input, line ); ) { @@ -553,4 +553,4 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s *local_storage_out = local_storage; return appid; -} \ No newline at end of file +} From ff6c3e994b18b2b500d8a51be4d509ce453af745 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Thu, 29 Apr 2021 18:53:13 -0400 Subject: [PATCH 7/7] UNICODE support in the steamclient loader. --- steamclient_loader/ColdClientLoader.cpp | 107 ++++++++++++------------ 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/steamclient_loader/ColdClientLoader.cpp b/steamclient_loader/ColdClientLoader.cpp index 4c364fa..6e790ab 100644 --- a/steamclient_loader/ColdClientLoader.cpp +++ b/steamclient_loader/ColdClientLoader.cpp @@ -10,13 +10,13 @@ #include #include -bool IsNotRelativePathOrRemoveFileName(CHAR* output, bool Remove) +bool IsNotRelativePathOrRemoveFileName(WCHAR* output, bool Remove) { - int LG = lstrlenA(output); + int LG = lstrlenW(output); for (int i = LG; i > 0; i--) { if (output[i] == '\\') { if(Remove) - RtlFillMemory(&output[i], LG - i, NULL); + RtlFillMemory(&output[i], (LG - i) * sizeof(WCHAR), NULL); return true; } } @@ -25,81 +25,84 @@ bool IsNotRelativePathOrRemoveFileName(CHAR* output, bool Remove) int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { - CHAR CurrentDirectory[MAX_PATH] = { 0 }; - CHAR Client64Path[MAX_PATH] = { 0 }; - CHAR ClientPath[MAX_PATH] = { 0 }; - CHAR ExeFile[MAX_PATH] = { 0 }; - CHAR ExeRunDir[MAX_PATH] = { 0 }; - CHAR ExeCommandLine[4096] = { 0 }; - CHAR AppId[128] = { 0 }; + WCHAR CurrentDirectory[MAX_PATH] = { 0 }; + WCHAR Client64Path[MAX_PATH] = { 0 }; + WCHAR ClientPath[MAX_PATH] = { 0 }; + WCHAR ExeFile[MAX_PATH] = { 0 }; + WCHAR ExeRunDir[MAX_PATH] = { 0 }; + WCHAR ExeCommandLine[4096] = { 0 }; + WCHAR AppId[128] = { 0 }; - STARTUPINFOA info = { sizeof(info) }; + STARTUPINFOW info = { sizeof(info) }; PROCESS_INFORMATION processInfo; - int Length = GetModuleFileNameA(GetModuleHandleA(NULL), CurrentDirectory, sizeof(CurrentDirectory)) + 1; + int Length = GetModuleFileNameW(GetModuleHandleW(NULL), CurrentDirectory, sizeof(CurrentDirectory)) + 1; for (int i = Length; i > 0; i--) { if (CurrentDirectory[i] == '\\') { - lstrcpyA(&CurrentDirectory[i + 1], "ColdClientLoader.ini"); + lstrcpyW(&CurrentDirectory[i + 1], L"ColdClientLoader.ini"); break; } } - if (GetFileAttributesA(CurrentDirectory) == INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributesW(CurrentDirectory) == INVALID_FILE_ATTRIBUTES) { MessageBoxA(NULL, "Couldn't find the configuration file(ColdClientLoader.ini).", "ColdClientLoader", MB_ICONERROR); return 0; } - GetPrivateProfileStringA("SteamClient", "SteamClient64Dll", "", Client64Path, MAX_PATH, CurrentDirectory); - GetPrivateProfileStringA("SteamClient", "SteamClientDll", "", ClientPath, MAX_PATH, CurrentDirectory); - GetPrivateProfileStringA("SteamClient", "Exe", NULL, ExeFile, MAX_PATH, CurrentDirectory); - GetPrivateProfileStringA("SteamClient", "ExeRunDir", NULL, ExeRunDir, MAX_PATH, CurrentDirectory); - GetPrivateProfileStringA("SteamClient", "ExeCommandLine", NULL, ExeCommandLine, 4096, CurrentDirectory); - GetPrivateProfileStringA("SteamClient", "AppId", NULL, AppId, sizeof(AppId), CurrentDirectory); + GetPrivateProfileStringW(L"SteamClient", L"SteamClient64Dll", L"", Client64Path, MAX_PATH, CurrentDirectory); + GetPrivateProfileStringW(L"SteamClient", L"SteamClientDll", L"", ClientPath, MAX_PATH, CurrentDirectory); + GetPrivateProfileStringW(L"SteamClient", L"Exe", NULL, ExeFile, MAX_PATH, CurrentDirectory); + GetPrivateProfileStringW(L"SteamClient", L"ExeRunDir", NULL, ExeRunDir, MAX_PATH, CurrentDirectory); + GetPrivateProfileStringW(L"SteamClient", L"ExeCommandLine", NULL, ExeCommandLine, 4096, CurrentDirectory); + GetPrivateProfileStringW(L"SteamClient", L"AppId", NULL, AppId, sizeof(AppId), CurrentDirectory); if (AppId[0]) { - SetEnvironmentVariableA("SteamAppId", AppId); - SetEnvironmentVariableA("SteamGameId", AppId); + SetEnvironmentVariableW(L"SteamAppId", AppId); + SetEnvironmentVariableW(L"SteamGameId", AppId); + } else { + MessageBoxA(NULL, "You forgot to set the AppId.", "ColdClientLoader", MB_ICONERROR); + return 0; } - CHAR TMP[MAX_PATH] = {}; + WCHAR TMP[MAX_PATH] = {}; if (!IsNotRelativePathOrRemoveFileName(Client64Path, false)) { - lstrcpyA(TMP, Client64Path); + lstrcpyW(TMP, Client64Path); ZeroMemory(Client64Path, sizeof(Client64Path)); - GetFullPathNameA(TMP, MAX_PATH, Client64Path, NULL); + GetFullPathNameW(TMP, MAX_PATH, Client64Path, NULL); } if (!IsNotRelativePathOrRemoveFileName(ClientPath, false)) { - lstrcpyA(TMP, ClientPath); + lstrcpyW(TMP, ClientPath); ZeroMemory(ClientPath, sizeof(ClientPath)); - GetFullPathNameA(TMP, MAX_PATH, ClientPath, NULL); + GetFullPathNameW(TMP, MAX_PATH, ClientPath, NULL); } if (!IsNotRelativePathOrRemoveFileName(ExeFile, false)) { - lstrcpyA(TMP, ExeFile); + lstrcpyW(TMP, ExeFile); ZeroMemory(ExeFile, sizeof(ExeFile)); - GetFullPathNameA(TMP, MAX_PATH, ExeFile, NULL); + GetFullPathNameW(TMP, MAX_PATH, ExeFile, NULL); } if (!IsNotRelativePathOrRemoveFileName(ExeRunDir, false)) { - lstrcpyA(TMP, ExeRunDir); + lstrcpyW(TMP, ExeRunDir); ZeroMemory(ExeRunDir, sizeof(ExeRunDir)); - GetFullPathNameA(TMP, MAX_PATH, ExeRunDir, NULL); + GetFullPathNameW(TMP, MAX_PATH, ExeRunDir, NULL); } - if (GetFileAttributesA(Client64Path) == INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributesW(Client64Path) == INVALID_FILE_ATTRIBUTES) { MessageBoxA(NULL, "Couldn't find the requested SteamClient64Dll.", "ColdClientLoader", MB_ICONERROR); return 0; } - if (GetFileAttributesA(ClientPath) == INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributesW(ClientPath) == INVALID_FILE_ATTRIBUTES) { MessageBoxA(NULL, "Couldn't find the requested SteamClientDll.", "ColdClientLoader", MB_ICONERROR); return 0; } - if (GetFileAttributesA(ExeFile) == INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributesW(ExeFile) == INVALID_FILE_ATTRIBUTES) { MessageBoxA(NULL, "Couldn't find the requested Exe file.", "ColdClientLoader", MB_ICONERROR); return 0; } - CHAR CommandLine[8192]; - snprintf(CommandLine, sizeof(CommandLine), "\"%s\" %s", ExeFile, ExeCommandLine); - if (!ExeFile[0] || !CreateProcessA(ExeFile, CommandLine, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, ExeRunDir, &info, &processInfo)) + WCHAR CommandLine[8192]; + _snwprintf(CommandLine, _countof(CommandLine), L"\"%ls\" %ls", ExeFile, ExeCommandLine); + if (!ExeFile[0] || !CreateProcessW(ExeFile, CommandLine, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, ExeRunDir, &info, &processInfo)) { MessageBoxA(NULL, "Unable to load the requested EXE file.", "ColdClientLoader", MB_ICONERROR); return 0; @@ -111,18 +114,18 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance bool orig_steam = false; DWORD keyType = REG_SZ; - CHAR OrgSteamCDir[MAX_PATH] = { 0 }; - CHAR OrgSteamCDir64[MAX_PATH] = { 0 }; + WCHAR OrgSteamCDir[MAX_PATH] = { 0 }; + WCHAR OrgSteamCDir64[MAX_PATH] = { 0 }; DWORD Size1 = MAX_PATH; DWORD Size2 = MAX_PATH; - if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS) + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS) { orig_steam = true; // Get original values to restore later. - RegQueryValueExA(Registrykey, "SteamClientDll", 0, &keyType, (LPBYTE)& OrgSteamCDir, &Size1); - RegQueryValueExA(Registrykey, "SteamClientDll64", 0, &keyType, (LPBYTE)& OrgSteamCDir64, &Size2); + RegQueryValueExW(Registrykey, L"SteamClientDll", 0, &keyType, (LPBYTE)& OrgSteamCDir, &Size1); + RegQueryValueExW(Registrykey, L"SteamClientDll64", 0, &keyType, (LPBYTE)& OrgSteamCDir64, &Size2); } else { - if (RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, 0, REG_OPTION_NON_VOLATILE, + if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &Registrykey, NULL) != ERROR_SUCCESS) { MessageBoxA(NULL, "Unable to patch Steam process informations on the Windows registry.", "ColdClientLoader", MB_ICONERROR); @@ -137,17 +140,17 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance { // Before saving to the registry check again if the path was valid and if the file exist - if (GetFileAttributesA(ClientPath) != INVALID_FILE_ATTRIBUTES) { - RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)ClientPath, (DWORD)lstrlenA(ClientPath) + 1); + if (GetFileAttributesW(ClientPath) != INVALID_FILE_ATTRIBUTES) { + RegSetValueExW(Registrykey, L"SteamClientDll", NULL, REG_SZ, (LPBYTE)ClientPath, (DWORD)(lstrlenW(ClientPath) * sizeof(WCHAR)) + 1); } else { - RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)"", 0); + RegSetValueExW(Registrykey, L"SteamClientDll", NULL, REG_SZ, (LPBYTE)"", 0); } - if (GetFileAttributesA(Client64Path) != INVALID_FILE_ATTRIBUTES) { - RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)Client64Path, (DWORD)lstrlenA(Client64Path) + 1); + if (GetFileAttributesW(Client64Path) != INVALID_FILE_ATTRIBUTES) { + RegSetValueExW(Registrykey, L"SteamClientDll64", NULL, REG_SZ, (LPBYTE)Client64Path, (DWORD)(lstrlenW(Client64Path) * sizeof(WCHAR)) + 1); } else { - RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)"", 0); + RegSetValueExW(Registrykey, L"SteamClientDll64", NULL, REG_SZ, (LPBYTE)"", 0); } } RegSetValueExA(Registrykey, "Universe", NULL, REG_SZ, (LPBYTE)"Public", (DWORD)lstrlenA("Public") + 1); @@ -161,11 +164,11 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance CloseHandle(processInfo.hThread); if (orig_steam) { - if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS) + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_ALL_ACCESS, &Registrykey) == ERROR_SUCCESS) { // Restore the values. - RegSetValueExA(Registrykey, "SteamClientDll", NULL, REG_SZ, (LPBYTE)OrgSteamCDir, (DWORD)lstrlenA(OrgSteamCDir) + 1); - RegSetValueExA(Registrykey, "SteamClientDll64", NULL, REG_SZ, (LPBYTE)OrgSteamCDir64, (DWORD)lstrlenA(OrgSteamCDir64) + 1); + RegSetValueExW(Registrykey, L"SteamClientDll", NULL, REG_SZ, (LPBYTE)OrgSteamCDir, Size1); + RegSetValueExW(Registrykey, L"SteamClientDll64", NULL, REG_SZ, (LPBYTE)OrgSteamCDir64, Size2); // Close the HKEY Handle. RegCloseKey(Registrykey);