michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* Windows only app to show a modal debug dialog - launched by nsDebug.cpp */ michael@0: #include michael@0: #include michael@0: #ifdef _MSC_VER michael@0: #include michael@0: #endif michael@0: #ifdef __MINGW32__ michael@0: /* MingW currently does not implement a wide version of the michael@0: startup routines. Workaround is to implement something like michael@0: it ourselves. See bug 472063 */ michael@0: #include michael@0: #include michael@0: int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); michael@0: michael@0: #undef __argc michael@0: #undef __wargv michael@0: michael@0: static int __argc; michael@0: static wchar_t** __wargv; michael@0: michael@0: int WINAPI michael@0: WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, michael@0: LPSTR lpszCommandLine, int nCmdShow) michael@0: { michael@0: LPWSTR commandLine = GetCommandLineW(); michael@0: michael@0: /* parse for __argc and __wargv for compatibility, since mingw michael@0: * doesn't claim to support it :( michael@0: */ michael@0: __wargv = CommandLineToArgvW(commandLine, &__argc); michael@0: if (!__wargv) michael@0: return 127; michael@0: michael@0: /* need to strip off any leading whitespace plus the first argument michael@0: * (the executable itself) to match what should be passed to wWinMain michael@0: */ michael@0: while ((*commandLine <= L' ') && *commandLine) { michael@0: ++commandLine; michael@0: } michael@0: if (*commandLine == L'"') { michael@0: ++commandLine; michael@0: while ((*commandLine != L'"') && *commandLine) { michael@0: ++commandLine; michael@0: } michael@0: if (*commandLine) { michael@0: ++commandLine; michael@0: } michael@0: } else { michael@0: while (*commandLine > L' ') { michael@0: ++commandLine; michael@0: } michael@0: } michael@0: while ((*commandLine <= L' ') && *commandLine) { michael@0: ++commandLine; michael@0: } michael@0: michael@0: int result = wWinMain(hInstance, hPrevInstance, commandLine, nCmdShow); michael@0: LocalFree(__wargv); michael@0: return result; michael@0: } michael@0: #endif /* __MINGW32__ */ michael@0: michael@0: michael@0: int WINAPI michael@0: wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, michael@0: LPWSTR lpszCmdLine, int nCmdShow) michael@0: { michael@0: /* support for auto answering based on words in the assertion. michael@0: * the assertion message is sent as a series of arguements (words) to the commandline. michael@0: * set a "word" to 0xffffffff to let the word not affect this code. michael@0: * set a "word" to 0xfffffffe to show the dialog. michael@0: * set a "word" to 0x5 to ignore (program should continue). michael@0: * set a "word" to 0x4 to retry (should fall into debugger). michael@0: * set a "word" to 0x3 to abort (die). michael@0: */ michael@0: DWORD regType; michael@0: DWORD regValue = -1; michael@0: DWORD regLength = sizeof regValue; michael@0: HKEY hkeyCU, hkeyLM; michael@0: RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\mozilla.org\\windbgdlg", 0, KEY_READ, &hkeyCU); michael@0: RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\mozilla.org\\windbgdlg", 0, KEY_READ, &hkeyLM); michael@0: int argc =0; michael@0: for (int i = __argc - 1; regValue == (DWORD)-1 && i; --i) { michael@0: bool ok = false; michael@0: if (hkeyCU) michael@0: ok = RegQueryValueExW(hkeyCU, __wargv[i], 0, ®Type, (LPBYTE)®Value, ®Length) == ERROR_SUCCESS; michael@0: if (!ok && hkeyLM) michael@0: ok = RegQueryValueExW(hkeyLM, __wargv[i], 0, ®Type, (LPBYTE)®Value, ®Length) == ERROR_SUCCESS; michael@0: if (!ok) michael@0: regValue = -1; michael@0: } michael@0: if (hkeyCU) michael@0: RegCloseKey(hkeyCU); michael@0: if (hkeyLM) michael@0: RegCloseKey(hkeyLM); michael@0: if (regValue != (DWORD)-1 && regValue != (DWORD)-2) michael@0: return regValue; michael@0: static const int size = 4096; michael@0: static WCHAR msg[size]; michael@0: michael@0: #ifdef _MSC_VER michael@0: StringCchPrintfW(msg, michael@0: #else michael@0: snwprintf(msg, michael@0: #endif michael@0: size, michael@0: L"%s\n\nClick Abort to exit the Application.\n" michael@0: L"Click Retry to Debug the Application.\n" michael@0: L"Click Ignore to continue running the Application.", michael@0: lpszCmdLine); michael@0: msg[size - 1] = L'\0'; michael@0: return MessageBoxW(nullptr, msg, L"NSGlue_Assertion", michael@0: MB_ICONSTOP | MB_SYSTEMMODAL | michael@0: MB_ABORTRETRYIGNORE | MB_DEFBUTTON3); michael@0: }