diff --git a/build_win_find_interfaces.bat b/build_win_find_interfaces.bat index 36f834e..c2cab0d 100755 --- a/build_win_find_interfaces.bat +++ b/build_win_find_interfaces.bat @@ -7,14 +7,14 @@ IF NOT "%1" == "" ( SET JOB_COUNT=%~1 ) IF NOT DEFINED BUILT_ALL_DEPS ( call generate_all_deps.bat ) -IF EXIST build\release\tools\x86\*.* ( DEL /F /S /Q build\release\tools\x86\*.* ) -IF EXIST build\release\tools\x64\*.* ( DEL /F /S /Q build\release\tools\x64\*.* ) +IF EXIST build\tools\release\x86\*.* ( DEL /F /S /Q build\tools\release\x86\*.* ) +IF EXIST build\tools\release\x64\*.* ( DEL /F /S /Q build\tools\release\x64\*.* ) IF EXIST release\tools\*.* ( DEL /F /S /Q release\tools\*.* ) setlocal call build_env_x86.bat -cd %OLD_DIR%\build\release\tools\x86 +cd %OLD_DIR%\build\tools\release\x86 cl /c @%CDS_DIR%\RELEASE.BLD @%CDS_DIR%\GENERATE_INTERFACES_FILE.BLD IF EXIST %CDS_DIR%\RELEASE_GENERATE_INTERFACES_FILE_X86.LKS ( DEL /F /Q %CDS_DIR%\RELEASE_GENERATE_INTERFACES_FILE_X86.LKS ) where "generate_interfaces_file.obj" > %CDS_DIR%\RELEASE_GENERATE_INTERFACES_FILE_X86.LKS @@ -26,7 +26,7 @@ endlocal setlocal call build_env_x64.bat -cd %OLD_DIR%\build\release\tools\x64 +cd %OLD_DIR%\build\tools\release\x64 cl /c @%CDS_DIR%\RELEASE.BLD @%CDS_DIR%\GENERATE_INTERFACES_FILE.BLD IF EXIST %CDS_DIR%\RELEASE_GENERATE_INTERFACES_FILE_X64.LKS ( DEL /F /Q %CDS_DIR%\RELEASE_GENERATE_INTERFACES_FILE_X64.LKS ) where "generate_interfaces_file.obj" > %CDS_DIR%\RELEASE_GENERATE_INTERFACES_FILE_X64.LKS diff --git a/dll/dll.cpp b/dll/dll.cpp index 7029d37..c90dee9 100644 --- a/dll/dll.cpp +++ b/dll/dll.cpp @@ -17,7 +17,9 @@ #define STEAM_API_FUNCTIONS_IMPL #include "dll.h" - +#ifdef STEAM_WIN32 +#include +#endif static char old_client[128] = "SteamClient017"; static char old_gameserver[128] = "SteamGameServer012"; @@ -244,6 +246,40 @@ STEAMAPI_API void * S_CALLTYPE SteamInternal_ContextInit( void *pContextInitData return &contextInitData->ctx; } +static std::mutex minidump_global_mutex; +static bool minidump_enable = true; +static bool minidump_comment_enable = true; +static std::string minidump_comment; +static std::string minidump_path; +static std::string start_time; + +bool get_minidump_enable() { + std::lock_guard lock(minidump_global_mutex); + return minidump_enable; +} + +bool get_minidump_comment_enable() { + std::lock_guard lock(minidump_global_mutex); + return minidump_comment_enable; +} + +void set_minidump_enable(bool enable) { + std::lock_guard lock(minidump_global_mutex); + minidump_enable = enable; + return; +} + +void set_minidump_comment_enable(bool enable) { + std::lock_guard lock(minidump_global_mutex); + minidump_comment_enable = enable; + return; +} + +std::string get_start_time() { + std::lock_guard lock(minidump_global_mutex); + return start_time; +} + //steam_api.h // SteamAPI_Init must be called before using any other API functions. If it fails, an // error message will be output to the debugger (or stderr) with further information. @@ -252,6 +288,11 @@ STEAMAPI_API steam_bool S_CALLTYPE SteamAPI_Init() { PRINT_DEBUG("SteamAPI_Init called\n"); if (user_steam_pipe) return true; + { + std::lock_guard lock(minidump_global_mutex); + if (start_time.length() <= 0) start_time = std::to_string((std::chrono::duration_cast(((std::chrono::system_clock::now()).time_since_epoch()))).count()); + if (minidump_path.length() <= 0) minidump_path = Local_Storage::get_user_appdata_path().append(PATH_SEPARATOR).append("minidumps").append(PATH_SEPARATOR).append("steam_minidump_").append(start_time).append(".mdmp"); + } #ifdef EMU_EXPERIMENTAL_BUILD crack_SteamAPI_Init(); #endif @@ -340,6 +381,11 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_Shutdown() STEAMAPI_API steam_bool S_CALLTYPE SteamAPI_RestartAppIfNecessary( uint32 unOwnAppID ) { PRINT_DEBUG("SteamAPI_RestartAppIfNecessary %u\n", unOwnAppID); + { + std::lock_guard lock(minidump_global_mutex); + if (start_time.length() <= 0) start_time = std::to_string((std::chrono::duration_cast(((std::chrono::system_clock::now()).time_since_epoch()))).count()); + if (minidump_path.length() <= 0) minidump_path = Local_Storage::get_user_appdata_path().append(PATH_SEPARATOR).append("minidumps").append(PATH_SEPARATOR).append("steam_minidump_").append(start_time).append(".mdmp"); + } #ifdef EMU_EXPERIMENTAL_BUILD crack_SteamAPI_RestartAppIfNecessary(unOwnAppID); #endif @@ -360,11 +406,93 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_ReleaseCurrentThreadMemory() STEAMAPI_API void S_CALLTYPE SteamAPI_WriteMiniDump( uint32 uStructuredExceptionCode, void* pvExceptionInfo, uint32 uBuildID ) { PRINT_DEBUG("SteamAPI_WriteMiniDump\n"); +#ifdef STEAM_WIN32 + if (!get_minidump_enable()) + return; + + std::lock_guard lock(minidump_global_mutex); + + MINIDUMP_EXCEPTION_INFORMATION mei; + memset(&mei, '\0', sizeof(MINIDUMP_EXCEPTION_INFORMATION)); + mei.ThreadId = GetCurrentThreadId(); + mei.ExceptionPointers = (EXCEPTION_POINTERS*)pvExceptionInfo; + mei.ClientPointers = false; + + char expCode[40] = {'S', 't', 'r', 'u', 'c', 't', 'u', 'r', 'e', 'd', ' ', + 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n', ' ', + 'C', 'o', 'd', 'e', ':', ' ', + '4', '2', '9', '4', '9', '6', '7', '2', '9', '5', '\0', '\0'}; + char * printExpCode = &expCode[26]; + snprintf(printExpCode, (39 - 26), "%u", uStructuredExceptionCode); + + char buildId[25] = { 'B', 'u', 'i', 'l', 'd', ' ', + 'I', 'D', ':', ' ', + '4', '2', '9', '4', '9', '6', '7', '2', '9', '5', '\0', '\0', '\0', '\0', '\0'}; + char * printBuildId = &expCode[10]; + snprintf(printBuildId, (24 - 10), "%u", uBuildID); + + MINIDUMP_USER_STREAM mus[3]; + memset(&mus, '\0', sizeof(MINIDUMP_USER_STREAM) * 3); + + mus[0].Type = CommentStreamA; + mus[0].BufferSize = 40; + mus[0].Buffer = (void*)&expCode; + + mus[1].Type = CommentStreamA; + mus[1].BufferSize = 25; + mus[1].Buffer = (void*)&buildId; + + mus[2].BufferSize = minidump_comment.length(); + if (minidump_comment.length() > 0) { + mus[2].Type = CommentStreamA; + mus[2].BufferSize = minidump_comment.length(); + if (mus[2].BufferSize > 0) { + mus[2].Buffer = (void*)minidump_comment.c_str(); + } + } + + MINIDUMP_USER_STREAM_INFORMATION musi; + memset(&musi, '\0', sizeof(MINIDUMP_USER_STREAM_INFORMATION)); + musi.UserStreamCount = (minidump_comment.length() > 0) ? 3 : 2; + musi.UserStreamArray = (MINIDUMP_USER_STREAM*)&mus; + if (minidump_path.length() > 0) { + HANDLE hFile = CreateFile(minidump_path.c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile != INVALID_HANDLE_VALUE) { + MiniDumpWriteDump(GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithProcessThreadData | MiniDumpWithThreadInfo | MiniDumpWithUnloadedModules | MiniDumpWithTokenInformation), + ((pvExceptionInfo != NULL) ? &mei : NULL), + &musi, + NULL); + CloseHandle(hFile); + } + } +#endif + return; } STEAMAPI_API void S_CALLTYPE SteamAPI_SetMiniDumpComment( const char *pchMsg ) { - PRINT_DEBUG("SteamAPI_SetMiniDumpComment: %s\n", pchMsg); + if (get_minidump_enable() == false || get_minidump_comment_enable() == false) + return; + + std::lock_guard lock(minidump_global_mutex); + + if (pchMsg != NULL) { + PRINT_DEBUG("SteamAPI_SetMiniDumpComment: %s\n", pchMsg); + minidump_comment = std::string(pchMsg); + } else { + PRINT_DEBUG("SteamAPI_SetMiniDumpComment: Empty string.\n"); + minidump_comment.clear(); + } + return; } //----------------------------------------------------------------------------------------------------------------------------------------------------------// diff --git a/dll/dll.h b/dll/dll.h index 29cee54..72ed264 100644 --- a/dll/dll.h +++ b/dll/dll.h @@ -29,6 +29,12 @@ Steam_Client *get_steam_client(); bool steamclient_has_ipv6_functions(); Steam_Client *try_get_steam_client(); +bool get_minidump_enable(); +bool get_minidump_comment_enable(); +void set_minidump_enable(bool enable); +void set_minidump_comment_enable(bool enable); +std::string get_start_time(); + HSteamUser flat_hsteamuser(); HSteamPipe flat_hsteampipe(); HSteamUser flat_gs_hsteamuser(); diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index 802b540..79ceec4 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -302,6 +302,12 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s local_storage->store_data_settings("user_steam_id.txt", temp_text, strlen(temp_text)); } + if (Local_Storage::is_directory(Local_Storage::get_user_appdata_path().append(PATH_SEPARATOR).append("minidumps")) == false) { + local_storage->store_data_settings(std::string("minidumps").append(PATH_SEPARATOR).append("dummy.txt"), + " ", + sizeof(" ") / sizeof(char)); + } + std::set supported_languages; { diff --git a/generate_build_win.bat b/generate_build_win.bat index 4788069..3b7b231 100644 --- a/generate_build_win.bat +++ b/generate_build_win.bat @@ -20,9 +20,9 @@ IF NOT EXIST build\experimental_steamclient\steamclient_loader\debug ( mkdir bui IF NOT EXIST build\experimental_steamclient\steamclient_loader\release ( mkdir build\experimental_steamclient\steamclient_loader\release ) IF NOT EXIST build\lobby_connect\debug ( mkdir build\lobby_connect\debug ) IF NOT EXIST build\lobby_connect\release ( mkdir build\lobby_connect\release ) -IF NOT EXIST build\release\tools ( mkdir build\release\tools ) -IF NOT EXIST build\release\tools\debug ( mkdir build\release\tools\debug ) -IF NOT EXIST build\release\tools\release ( mkdir build\release\tools\release ) +IF NOT EXIST build\tools ( mkdir build\tools ) +IF NOT EXIST build\tools\debug ( mkdir build\tools\debug ) +IF NOT EXIST build\tools\release ( mkdir build\tools\release ) IF NOT EXIST build\debug\x86 ( mkdir build\debug\x86 ) IF NOT EXIST build\debug\x64 ( mkdir build\debug\x64 ) @@ -61,10 +61,10 @@ IF NOT EXIST build\lobby_connect\debug\x86 ( mkdir build\lobby_connect\debug\x86 IF NOT EXIST build\lobby_connect\debug\x64 ( mkdir build\lobby_connect\debug\x64 ) IF NOT EXIST build\lobby_connect\release\x86 ( mkdir build\lobby_connect\release\x86 ) IF NOT EXIST build\lobby_connect\release\x64 ( mkdir build\lobby_connect\release\x64 ) -IF NOT EXIST build\release\tools\debug\x86 ( mkdir build\release\tools\debug\x86 ) -IF NOT EXIST build\release\tools\debug\x64 ( mkdir build\release\tools\debug\x64 ) -IF NOT EXIST build\release\tools\release\x86 ( mkdir build\release\tools\release\x86 ) -IF NOT EXIST build\release\tools\release\x64 ( mkdir build\release\tools\release\x64 ) +IF NOT EXIST build\tools\debug\x86 ( mkdir build\tools\debug\x86 ) +IF NOT EXIST build\tools\debug\x64 ( mkdir build\tools\debug\x64 ) +IF NOT EXIST build\tools\release\x86 ( mkdir build\tools\release\x86 ) +IF NOT EXIST build\tools\release\x64 ( mkdir build\tools\release\x64 ) IF NOT EXIST debug ( mkdir debug ) IF NOT EXIST debug\experimental ( mkdir debug\experimental ) @@ -178,7 +178,7 @@ dir /b /s %PROTOBUF_X64_LIBRARY% > %CDS_DIR%\PROTOBUF_X64.OS REM BASE DLL. IF EXIST %CDS_DIR%\DLL_MAIN_CPP.OS ( DEL /F /S /Q %CDS_DIR%\DLL_MAIN_CPP.OS ) -echo dbghelp.lib > %CDS_DIR%\EXPERIMENTAL.OS +echo dbghelp.lib > %CDS_DIR%\DLL_MAIN_CPP.OS echo Iphlpapi.lib >> %CDS_DIR%\DLL_MAIN_CPP.OS echo Ws2_32.lib >> %CDS_DIR%\DLL_MAIN_CPP.OS echo Shell32.lib >> %CDS_DIR%\DLL_MAIN_CPP.OS