diff --git a/polymer/eduke32/build/include/baselayer.h b/polymer/eduke32/build/include/baselayer.h index c9ec9176c..64ba4b3ec 100644 --- a/polymer/eduke32/build/include/baselayer.h +++ b/polymer/eduke32/build/include/baselayer.h @@ -12,6 +12,10 @@ extern "C" { #endif +extern int32_t app_main(int32_t argc, const char **argv); +extern const char* AppProperName; +extern const char* AppTechnicalName; + #ifdef DEBUGGINGAIDS # define DEBUG_MASK_DRAWING extern int32_t g_maskDrawMode; diff --git a/polymer/eduke32/build/src/sdlayer.c b/polymer/eduke32/build/src/sdlayer.c index 9cb2e8252..5567156d0 100644 --- a/polymer/eduke32/build/src/sdlayer.c +++ b/polymer/eduke32/build/src/sdlayer.c @@ -63,8 +63,6 @@ int32_t startwin_settitle(const char *s) { UNREFERENCED_PARAMETER(s); return 0; // fix for mousewheel int32_t inputchecked = 0; -extern int32_t app_main(int32_t argc, const char **argv); - char quitevent=0, appactive=1, novideo=0; // video diff --git a/polymer/eduke32/build/src/winbits.c b/polymer/eduke32/build/src/winbits.c index 72c706ea3..8952eff07 100644 --- a/polymer/eduke32/build/src/winbits.c +++ b/polymer/eduke32/build/src/winbits.c @@ -176,6 +176,7 @@ static void ToggleDesktopComposition(BOOL compEnable) } } +typedef void (*dllSetString)(const char*); // // win_open(), win_init(), win_setvideomode(), win_uninit(), win_close() -- shared code @@ -183,12 +184,18 @@ static void ToggleDesktopComposition(BOOL compEnable) void win_open(void) { #ifdef DEBUGGINGAIDS - LoadLibraryA(EBACKTRACEDLL); -/* - wm_msgbox("boo","didn't load backtrace DLL (code %d)\n", (int)GetLastError()); - else - wm_msgbox("yay","loaded backtrace DLL\n"); -*/ + HMODULE ebacktrace = LoadLibraryA(EBACKTRACEDLL); + if (ebacktrace) + { + dllSetString SetTechnicalName = (dllSetString) GetProcAddress(ebacktrace, "SetTechnicalName"); + dllSetString SetProperName = (dllSetString) GetProcAddress(ebacktrace, "SetProperName"); + + if (SetTechnicalName) + SetTechnicalName(AppTechnicalName); + + if (SetProperName) + SetProperName(AppProperName); + } #endif instanceflag = CreateSemaphore(NULL, 1,1, WindowClass); diff --git a/polymer/eduke32/build/src/winlayer.c b/polymer/eduke32/build/src/winlayer.c index dd2d214e5..90e0a4e30 100644 --- a/polymer/eduke32/build/src/winlayer.c +++ b/polymer/eduke32/build/src/winlayer.c @@ -81,7 +81,6 @@ static int32_t winlayer_have_ATI = 0; static int32_t _buildargc = 0; static const char **_buildargv = NULL; static char *argvbuf = NULL; -extern int32_t app_main(int32_t argc, const char **argv); // Windows crud static HINSTANCE hInstance = 0; diff --git a/polymer/eduke32/package/debug/win32/ebacktrace1.dll b/polymer/eduke32/package/debug/win32/ebacktrace1.dll index d5fd36183..9054a6818 100644 Binary files a/polymer/eduke32/package/debug/win32/ebacktrace1.dll and b/polymer/eduke32/package/debug/win32/ebacktrace1.dll differ diff --git a/polymer/eduke32/package/debug/win64/ebacktrace1-64.dll b/polymer/eduke32/package/debug/win64/ebacktrace1-64.dll index a2c44bd32..ecf56a002 100644 Binary files a/polymer/eduke32/package/debug/win64/ebacktrace1-64.dll and b/polymer/eduke32/package/debug/win64/ebacktrace1-64.dll differ diff --git a/polymer/eduke32/platform/Windows/src/backtrace.c b/polymer/eduke32/platform/Windows/src/backtrace.c index c4483a36a..4bbe88bbe 100644 --- a/polymer/eduke32/platform/Windows/src/backtrace.c +++ b/polymer/eduke32/platform/Windows/src/backtrace.c @@ -17,9 +17,7 @@ /* modified from original for EDuke32 */ -// warnings cleaned up and ported to 64-bit by Hendricks266 - -#define CRASH_LOG_FILE "eduke32_or_mapster32.crash.log" +// warnings cleaned up, ported to 64-bit, and heavily extended by Hendricks266 #include #include @@ -62,6 +60,9 @@ #include +#ifndef DBG_PRINTEXCEPTION_C +# define DBG_PRINTEXCEPTION_C (0x40010006) +#endif #ifndef MS_VC_EXCEPTION # define MS_VC_EXCEPTION 1080890248 #endif @@ -351,7 +352,7 @@ static LPTSTR FormatErrorMessage(DWORD dwMessageId) { LPTSTR lpBuffer = NULL; - // from http://stackoverflow.com/a/455533 + // adapted from http://stackoverflow.com/a/455533 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ALLOCATE_BUFFER @@ -366,6 +367,86 @@ static LPTSTR FormatErrorMessage(DWORD dwMessageId) return lpBuffer; // must be LocalFree()'d by caller } +static LPTSTR FormatExceptionCodeMessage(DWORD dwMessageId) +{ + LPTSTR lpBuffer = NULL; + + FormatMessage( + FORMAT_MESSAGE_FROM_HMODULE + |FORMAT_MESSAGE_ALLOCATE_BUFFER + |FORMAT_MESSAGE_IGNORE_INSERTS, + GetModuleHandleA("ntdll.dll"), + dwMessageId, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US) + (LPTSTR)&lpBuffer, + 0, + NULL); + + return lpBuffer; // must be LocalFree()'d by caller +} + + +// adapted from http://www.catch22.net/tuts/custom-messagebox +static HHOOK hMsgBoxHook; + +LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (nCode < 0) + return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam); + + switch (nCode) + { + case HCBT_ACTIVATE: + { + // Get handle to the message box! + HWND hwnd = (HWND)wParam; + + // Do customization! + SetWindowTextA(GetDlgItem(hwnd, IDYES), "Quit"); + SetWindowTextA(GetDlgItem(hwnd, IDNO), "Continue"); + SetWindowTextA(GetDlgItem(hwnd, IDCANCEL), "Ignore"); + return 0; + } + break; + } + + // Call the next hook, if there is one + return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam); +} + +int ExceptionMessage(TCHAR *szText, TCHAR *szCaption) +{ + int retval; + + // Install a window hook, so we can intercept the message-box + // creation, and customize it + hMsgBoxHook = SetWindowsHookEx( + WH_CBT, + CBTProc, + NULL, + GetCurrentThreadId() // Only install for THIS thread!!! + ); + + // Display a standard message box + retval = MessageBoxA(NULL, szText, szCaption, MB_YESNOCANCEL|MB_ICONERROR|MB_TASKMODAL); + + // remove the window hook + UnhookWindowsHookEx(hMsgBoxHook); + + return retval; +} + +static char crashlogfilename[MAX_PATH] = "crash.log"; +static char propername[MAX_PATH] = "this application"; + +__declspec(dllexport) void SetTechnicalName(const char* input) +{ + snprintf(crashlogfilename, MAX_PATH, "%s.crash.log", input); +} +__declspec(dllexport) void SetProperName(const char* input) +{ + strncpy(propername, input, MAX_PATH); +} static char * g_output = NULL; static PVOID g_prev = NULL; @@ -374,9 +455,10 @@ static LONG WINAPI exception_filter(LPEXCEPTION_POINTERS info) { struct output_buffer ob; - int logfd, written; + int logfd, written, msgboxID; PEXCEPTION_RECORD exception; BOOL initialized = FALSE; + char *ExceptionPrinted; for (exception = info->ExceptionRecord; exception != NULL; exception = exception->ExceptionRecord) { @@ -390,15 +472,25 @@ exception_filter(LPEXCEPTION_POINTERS info) case EXCEPTION_BREAKPOINT: case EXCEPTION_SINGLE_STEP: case DBG_CONTROL_C: + case DBG_PRINTEXCEPTION_C: case MS_VC_EXCEPTION: break; default: + { + LPTSTR ExceptionCodeMsg = FormatExceptionCodeMessage(exception->ExceptionCode); + // The message for this exception code is broken. + LPTSTR ExceptionText = exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ? "Access violation." : ExceptionCodeMsg; + if (!initialized) { output_init(&ob, g_output, BUFFER_MAX); initialized = TRUE; } - output_print(&ob, "Caught exception 0x%08X at 0x%p\n", exception->ExceptionCode, exception->ExceptionAddress); + + output_print(&ob, "Caught exception 0x%08X at 0x%p: %s\n", exception->ExceptionCode, exception->ExceptionAddress, ExceptionText); + + LocalFree(ExceptionCodeMsg); + } break; } } @@ -406,6 +498,14 @@ exception_filter(LPEXCEPTION_POINTERS info) if (!initialized) return EXCEPTION_CONTINUE_SEARCH; // EXCEPTION_CONTINUE_EXECUTION + ExceptionPrinted = (char*)calloc(strlen(g_output) + 37 + 2*MAX_PATH, sizeof(char)); + strcpy(ExceptionPrinted, g_output); + strcat(ExceptionPrinted, "\nPlease send "); + strcat(ExceptionPrinted, crashlogfilename); + strcat(ExceptionPrinted, " to the maintainers of "); + strcat(ExceptionPrinted, propername); + strcat(ExceptionPrinted, "."); + { DWORD error = 0; BOOL SymInitialized = SymInitialize(GetCurrentProcess(), NULL, TRUE); @@ -431,7 +531,7 @@ exception_filter(LPEXCEPTION_POINTERS info) } } - logfd = open(CRASH_LOG_FILE, O_APPEND | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + logfd = open(crashlogfilename, O_APPEND | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (logfd) { time_t curtime; @@ -455,7 +555,21 @@ exception_filter(LPEXCEPTION_POINTERS info) //fputs(g_output, stderr); - exit(0xBAC); + msgboxID = ExceptionMessage(ExceptionPrinted, propername); + + free(ExceptionPrinted); + + switch (msgboxID) + { + case IDYES: + exit(0xBAC); + break; + case IDNO: + break; + case IDCANCEL: + return EXCEPTION_CONTINUE_EXECUTION; + break; + } return EXCEPTION_CONTINUE_SEARCH; } diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index a1e70852f..5f35a16a6 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -73,6 +73,9 @@ extern const char *s_buildInfo; # undef stat #endif +const char* AppProperName = "Mapster32"; +const char* AppTechnicalName = "mapster32"; + static int32_t floor_over_floor; static int32_t g_fillCurSector = 0; diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 5cd67f1a5..4cb06f713 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -90,6 +90,9 @@ extern int32_t G_GetVersionFromWebsite(char *buffer); # endif #endif /* _WIN32 */ +const char* AppProperName = "EDuke32"; +const char* AppTechnicalName = "eduke32"; + static int32_t usecwd = 0; int32_t g_quitDeadline = 0;