From 78d0fa926923dd6d34a537c1a6bbfc5c7fe44be0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Feb 2019 10:10:41 +0100 Subject: [PATCH] - fixed Windows startup. * the window class name was still ASCII, thanks to some totally pointless and ultimately dangerous type cast to LPCTSTR which rendered all type checks ineffective. * use wWinMain instead of WinMain so that a Unicode argv gets created. For whatever reason, the ANSI startup leaves this variable empty. * added a 'disablecrashlog' CCMD for Windows. It is a lot more useful with a debugger present to get the standard crash notification from the system which allows opening a debugger than the crash log and no option to open a debugger. --- src/win32/i_main.cpp | 37 ++++++++++++++++++++++++++----------- src/win32/resource.h | 10 ---------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index f3ab51d73..e6a63980c 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -151,7 +151,7 @@ DYN_WIN32_SYM(SHGetKnownFolderPath); // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static const char WinClassName[] = GAMENAME "MainWindow"; +static const WCHAR WinClassName[] = WGAMENAME "MainWindow"; static HMODULE hwtsapi32; // handle to wtsapi32.dll static void (*TermFuncs[MAX_TERMS])(void); static int NumTerms; @@ -766,7 +766,7 @@ void ShowErrorPane(const char *text) paraformat.dwMask = PFM_STARTINDENT | PFM_OFFSETINDENT | PFM_RIGHTINDENT; paraformat.dxStartIndent = paraformat.dxOffset = paraformat.dxRightIndent = 120; SendMessage (ConWindow, EM_SETPARAFORMAT, 0, (LPARAM)¶format); - SendMessageW (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)"\n"); + SendMessageW (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)L"\n"); // Find out where the error lines start for the error icon display control. SendMessage (ConWindow, EM_EXGETSEL, 0, (LPARAM)&end); @@ -834,7 +834,15 @@ void DoMain (HINSTANCE hInstance) _set_new_handler (NewFailure); #endif - Args = new FArgs(__argc, __argv); + // Do not use the multibyte __argv here because we want UTF-8 arguments + // and those can only be done by converting the Unicode variants. + Args = new FArgs(); + auto argc = __argc; + auto wargv = __wargv; + for (int i = 0; i < argc; i++) + { + Args->AppendArg(FString(wargv[i])); + } // Load Win32 modules Kernel32Module.Load({"kernel32.dll"}); @@ -957,7 +965,7 @@ void DoMain (HINSTANCE hInstance) WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); WndClass.hbrBackground = NULL; WndClass.lpszMenuName = NULL; - WndClass.lpszClassName = (LPCTSTR)WinClassName; + WndClass.lpszClassName = WinClassName; /* register this new class with Windows */ if (!RegisterClass((LPWNDCLASS)&WndClass)) @@ -966,9 +974,9 @@ void DoMain (HINSTANCE hInstance) /* create window */ FStringf caption("" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime()); std::wstring wcaption = caption.WideString(); - Window = CreateWindowEx( + Window = CreateWindowExW( WS_EX_APPWINDOW, - (LPCTSTR)WinClassName, + WinClassName, wcaption.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN, x, y, width, height, @@ -1253,13 +1261,20 @@ static void infiniterecursion(int foo) } #endif +// Setting this to 'true' allows getting the standard notification for a crash +// which offers the very important feature to open a debugger and see the crash in context right away. +CUSTOM_CVAR(Bool, disablecrashlog, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + SetUnhandledExceptionFilter(!*self ? CatchAllExceptions : nullptr); +} + //========================================================================== // // WinMain // //========================================================================== -int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int nCmdShow) +int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE nothing, LPWSTR cmdline, int nCmdShow) { g_hInst = hInstance; @@ -1276,27 +1291,27 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n } #if !defined(__GNUC__) && defined(_DEBUG) - if (__argc == 2 && strcmp (__argv[1], "TestCrash") == 0) + if (__argc == 2 && __wargv != nullptr && wcscmp (__wargv[1], L"TestCrash") == 0) { __try { *(int *)0 = 0; } __except(CrashPointers = *GetExceptionInformation(), - CreateCrashLog (__argv[1], 9, NULL), EXCEPTION_EXECUTE_HANDLER) + CreateCrashLog ("TestCrash", 9, NULL), EXCEPTION_EXECUTE_HANDLER) { } DisplayCrashLog (); exit (0); } - if (__argc == 2 && strcmp (__argv[1], "TestStackCrash") == 0) + if (__argc == 2 && __wargv != nullptr && wcscmp (__wargv[1], L"TestStackCrash") == 0) { __try { infiniterecursion(1); } __except(CrashPointers = *GetExceptionInformation(), - CreateCrashLog (__argv[1], 14, NULL), EXCEPTION_EXECUTE_HANDLER) + CreateCrashLog ("TestStackCrash", 14, NULL), EXCEPTION_EXECUTE_HANDLER) { } DisplayCrashLog (); diff --git a/src/win32/resource.h b/src/win32/resource.h index cf41b6f1f..dcb94999f 100644 --- a/src/win32/resource.h +++ b/src/win32/resource.h @@ -20,15 +20,6 @@ #define IDB_BITMAP1 131 #define IDB_DEADGUY 131 #define IDD_CRASHDETAILS 133 -#define IDI_BOING1 137 -#define IDI_BOING2 138 -#define IDI_BOING3 139 -#define IDI_BOING4 140 -#define IDI_BOING5 141 -#define IDI_BOING6 142 -#define IDI_BOING7 143 -#define IDI_BOING8 144 -#define IDD_BOING 145 #define IDD_CRASHOVERVIEW 147 #define IDD_ERRORPANE 148 #define IDD_NETSTARTPANE 149 @@ -83,7 +74,6 @@ #define IDC_BUTTON2 1062 #define IDC_CRASHDETAILS 1062 #define IDC_DEADGUYVIEWER 1063 -#define IDC_BOING 1065 #define IDC_CRASHFILESIZE 1066 #define IDC_BUTTON1 1071 #define IDC_BOINGSTATUS 1072