Implement SteamAPI_WriteMiniDump.

This commit is contained in:
redpolline 2024-12-26 10:04:39 -05:00
parent 8726d331f9
commit 32689355d0
5 changed files with 154 additions and 14 deletions

View file

@ -7,14 +7,14 @@ IF NOT "%1" == "" ( SET JOB_COUNT=%~1 )
IF NOT DEFINED BUILT_ALL_DEPS ( call generate_all_deps.bat ) 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\tools\release\x86\*.* ( DEL /F /S /Q build\tools\release\x86\*.* )
IF EXIST build\release\tools\x64\*.* ( DEL /F /S /Q build\release\tools\x64\*.* ) IF EXIST build\tools\release\x64\*.* ( DEL /F /S /Q build\tools\release\x64\*.* )
IF EXIST release\tools\*.* ( DEL /F /S /Q release\tools\*.* ) IF EXIST release\tools\*.* ( DEL /F /S /Q release\tools\*.* )
setlocal setlocal
call build_env_x86.bat 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 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 ) 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 where "generate_interfaces_file.obj" > %CDS_DIR%\RELEASE_GENERATE_INTERFACES_FILE_X86.LKS
@ -26,7 +26,7 @@ endlocal
setlocal setlocal
call build_env_x64.bat 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 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 ) 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 where "generate_interfaces_file.obj" > %CDS_DIR%\RELEASE_GENERATE_INTERFACES_FILE_X64.LKS

View file

@ -17,7 +17,9 @@
#define STEAM_API_FUNCTIONS_IMPL #define STEAM_API_FUNCTIONS_IMPL
#include "dll.h" #include "dll.h"
#ifdef STEAM_WIN32
#include <DbgHelp.h>
#endif
static char old_client[128] = "SteamClient017"; static char old_client[128] = "SteamClient017";
static char old_gameserver[128] = "SteamGameServer012"; static char old_gameserver[128] = "SteamGameServer012";
@ -244,6 +246,40 @@ STEAMAPI_API void * S_CALLTYPE SteamInternal_ContextInit( void *pContextInitData
return &contextInitData->ctx; 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<std::mutex> lock(minidump_global_mutex);
return minidump_enable;
}
bool get_minidump_comment_enable() {
std::lock_guard<std::mutex> lock(minidump_global_mutex);
return minidump_comment_enable;
}
void set_minidump_enable(bool enable) {
std::lock_guard<std::mutex> lock(minidump_global_mutex);
minidump_enable = enable;
return;
}
void set_minidump_comment_enable(bool enable) {
std::lock_guard<std::mutex> lock(minidump_global_mutex);
minidump_comment_enable = enable;
return;
}
std::string get_start_time() {
std::lock_guard<std::mutex> lock(minidump_global_mutex);
return start_time;
}
//steam_api.h //steam_api.h
// SteamAPI_Init must be called before using any other API functions. If it fails, an // 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. // 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"); PRINT_DEBUG("SteamAPI_Init called\n");
if (user_steam_pipe) return true; if (user_steam_pipe) return true;
{
std::lock_guard<std::mutex> lock(minidump_global_mutex);
if (start_time.length() <= 0) start_time = std::to_string((std::chrono::duration_cast<std::chrono::seconds>(((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 #ifdef EMU_EXPERIMENTAL_BUILD
crack_SteamAPI_Init(); crack_SteamAPI_Init();
#endif #endif
@ -340,6 +381,11 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_Shutdown()
STEAMAPI_API steam_bool S_CALLTYPE SteamAPI_RestartAppIfNecessary( uint32 unOwnAppID ) STEAMAPI_API steam_bool S_CALLTYPE SteamAPI_RestartAppIfNecessary( uint32 unOwnAppID )
{ {
PRINT_DEBUG("SteamAPI_RestartAppIfNecessary %u\n", unOwnAppID); PRINT_DEBUG("SteamAPI_RestartAppIfNecessary %u\n", unOwnAppID);
{
std::lock_guard<std::mutex> lock(minidump_global_mutex);
if (start_time.length() <= 0) start_time = std::to_string((std::chrono::duration_cast<std::chrono::seconds>(((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 #ifdef EMU_EXPERIMENTAL_BUILD
crack_SteamAPI_RestartAppIfNecessary(unOwnAppID); crack_SteamAPI_RestartAppIfNecessary(unOwnAppID);
#endif #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 ) STEAMAPI_API void S_CALLTYPE SteamAPI_WriteMiniDump( uint32 uStructuredExceptionCode, void* pvExceptionInfo, uint32 uBuildID )
{ {
PRINT_DEBUG("SteamAPI_WriteMiniDump\n"); PRINT_DEBUG("SteamAPI_WriteMiniDump\n");
#ifdef STEAM_WIN32
if (!get_minidump_enable())
return;
std::lock_guard<std::mutex> 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 ) 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<std::mutex> 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;
} }
//----------------------------------------------------------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------------------------------------------------------//

View file

@ -29,6 +29,12 @@ Steam_Client *get_steam_client();
bool steamclient_has_ipv6_functions(); bool steamclient_has_ipv6_functions();
Steam_Client *try_get_steam_client(); 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(); HSteamUser flat_hsteamuser();
HSteamPipe flat_hsteampipe(); HSteamPipe flat_hsteampipe();
HSteamUser flat_gs_hsteamuser(); HSteamUser flat_gs_hsteamuser();

View file

@ -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)); 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<std::string> supported_languages; std::set<std::string> supported_languages;
{ {

View file

@ -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\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\debug ( mkdir build\lobby_connect\debug )
IF NOT EXIST build\lobby_connect\release ( mkdir build\lobby_connect\release ) 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\tools ( mkdir build\tools )
IF NOT EXIST build\release\tools\debug ( mkdir build\release\tools\debug ) IF NOT EXIST build\tools\debug ( mkdir build\tools\debug )
IF NOT EXIST build\release\tools\release ( mkdir build\release\tools\release ) 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\x86 ( mkdir build\debug\x86 )
IF NOT EXIST build\debug\x64 ( mkdir build\debug\x64 ) 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\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\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\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\tools\debug\x86 ( mkdir build\tools\debug\x86 )
IF NOT EXIST build\release\tools\debug\x64 ( mkdir build\release\tools\debug\x64 ) IF NOT EXIST build\tools\debug\x64 ( mkdir build\tools\debug\x64 )
IF NOT EXIST build\release\tools\release\x86 ( mkdir build\release\tools\release\x86 ) IF NOT EXIST build\tools\release\x86 ( mkdir build\tools\release\x86 )
IF NOT EXIST build\release\tools\release\x64 ( mkdir build\release\tools\release\x64 ) IF NOT EXIST build\tools\release\x64 ( mkdir build\tools\release\x64 )
IF NOT EXIST debug ( mkdir debug ) IF NOT EXIST debug ( mkdir debug )
IF NOT EXIST debug\experimental ( mkdir debug\experimental ) 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. REM BASE DLL.
IF EXIST %CDS_DIR%\DLL_MAIN_CPP.OS ( DEL /F /S /Q %CDS_DIR%\DLL_MAIN_CPP.OS ) 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 Iphlpapi.lib >> %CDS_DIR%\DLL_MAIN_CPP.OS
echo Ws2_32.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 echo Shell32.lib >> %CDS_DIR%\DLL_MAIN_CPP.OS