static void UI_Con_GetText( char *buf, int size, int c ) { size_t len, cp, ofs; const char *conText; conText = Con_GetText( c ); len = strlen( conText ); if( len > size ) { cp = size - 1; ofs = len - cp; } else { cp = len; ofs = 0; } memcpy( buf, conText + ofs, cp ); buf[len] = 0; }
/* ============== DoGenerateCrashDump ============== */ static DWORD WINAPI DoGenerateCrashDump( LPVOID pParams ) { dumpParams_t *params = (dumpParams_t*)pParams; static int nDump = 0; HANDLE hFile, hIncludeFile; DWORD dummy; char basePath[MAX_PATH], path[MAX_PATH]; MiniDumpWriteDumpFunc_t MiniDumpWriteDump; { HMODULE hDbgHelp = LoadLibrary( "DbgHelp.dll" ); if( !hDbgHelp ) { return 1; } MiniDumpWriteDump = (MiniDumpWriteDumpFunc_t)GetProcAddress( hDbgHelp, "MiniDumpWriteDump" ); if( !MiniDumpWriteDump ) { return 2; } params->ignoreModules[params->numIgnoreModules++] = hDbgHelp; } { char homePath[ MAX_OSPATH ]; Sys_DefaultHomePath( homePath, sizeof(homePath) ); if( !homePath[0] ) { return 3; } Com_sprintf( basePath, sizeof( basePath ), "%s/bugs", homePath ); } #define BASE_DUMP_FILE_NAME "dump%04i" CreatePath( basePath ); for( ; ; ) { DWORD err; Com_sprintf( path, sizeof( path ), "%s/"BASE_DUMP_FILE_NAME".dmp", basePath, nDump ); hFile = CreateFile( path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0 ); if( hFile != INVALID_HANDLE_VALUE ) { break; } err = GetLastError(); switch( err ) { case ERROR_FILE_EXISTS: case ERROR_ALREADY_EXISTS: break; case 0: return (DWORD)-1; default: return 0x80000000 | err; } nDump++; } Com_sprintf( path, sizeof( path ), "%s/"BASE_DUMP_FILE_NAME".include", basePath, nDump ); hIncludeFile = CreateFile( path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); { dumpCbParams_t cbParams; MINIDUMP_EXCEPTION_INFORMATION excInfo; MINIDUMP_CALLBACK_INFORMATION cbInfo; MINIDUMP_TYPE flags; excInfo.ThreadId = params->excThreadId; excInfo.ExceptionPointers = params->pExcPtrs; excInfo.ClientPointers = TRUE; cbParams.p = params; cbParams.hModulesFile = hIncludeFile; cbInfo.CallbackParam = &cbParams; cbInfo.CallbackRoutine = MiniDumpCallback; MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, flags, &excInfo, NULL, &cbInfo ); } CloseHandle( hFile ); { /* Write any additional include files here. Remember, the include file is unicode (wchar_t), has one file per line, and lines are seperated by a single LF (L'\n'). */ } CloseHandle( hIncludeFile ); Com_sprintf( path, sizeof( path ), "%s/"BASE_DUMP_FILE_NAME".build", basePath, nDump ); hFile = CreateFile( path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); { HMODULE hMod; HRSRC rcVer, rcBuild, rcMachine; HGLOBAL hgVer, hgBuild, hgMachine; DWORD lVer, lBuild, lMachine; char *pVer, *pBuild, *pMachine; hMod = GetModuleHandle( NULL ); rcVer = FindResource( hMod, MAKEINTRESOURCE( IDR_INFO_SVNSTAT ), "INFO" ); rcBuild = FindResource( hMod, MAKEINTRESOURCE( IDR_INFO_BUILDCONFIG ), "INFO" ); rcMachine = FindResource( hMod, MAKEINTRESOURCE( IDR_INFO_BUILDMACHINE ), "INFO" ); hgVer = LoadResource( hMod, rcVer ); hgBuild = LoadResource( hMod, rcBuild ); hgMachine = LoadResource( hMod, rcMachine ); lVer = SizeofResource( hMod, rcVer ); pVer = (char*)LockResource( hgVer ); lBuild = SizeofResource( hMod, rcBuild ); pBuild = (char*)LockResource( hgBuild ); lMachine = SizeofResource( hMod, rcMachine ); pMachine = (char*)LockResource( hgMachine ); WriteFile( hFile, pBuild, lBuild, &dummy, NULL ); WriteFile( hFile, pMachine, lMachine, &dummy, NULL ); WriteFile( hFile, pVer, lVer, &dummy, NULL ); } CloseHandle( hFile ); Com_sprintf( path, sizeof( path ), "%s/"BASE_DUMP_FILE_NAME".info", basePath, nDump ); hFile = CreateFile( path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); { /* The .info contains one line of bug title and the rest is all bug description. */ const char *msg; switch( params->excCode ) { case 1: //SEH_CAPTURE_EXC: msg = (const char*)params->pExcPtrs->ExceptionRecord->ExceptionInformation[0]; break; //*/ default: msg = "Crash Dump\nOpenWolf crashed, see the attached dump for more information."; break; } WriteFile( hFile, msg, strlen( msg ), &dummy, NULL ); } CloseHandle( hFile ); Com_sprintf( path, sizeof( path ), "%s/"BASE_DUMP_FILE_NAME".con", basePath, nDump ); hFile = CreateFile( path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); { const char *conDump = Con_GetText( 0 ); WriteFile( hFile, conDump, strlen( conDump ), &dummy, NULL ); } CloseHandle( hFile ); #undef BASE_DUMP_FILE_NAME return 0; }