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: // This file is a .cpp file meant to be included in nsBrowserApp.cpp and other michael@0: // similar bootstrap code. It converts wide-character windows wmain into UTF-8 michael@0: // narrow-character strings. michael@0: michael@0: #ifndef XP_WIN michael@0: #error This file only makes sense on Windows. michael@0: #endif michael@0: michael@0: #include "nsUTF8Utils.h" michael@0: michael@0: #ifndef XRE_DONT_PROTECT_DLL_LOAD michael@0: #include "nsSetDllDirectory.h" michael@0: #endif michael@0: michael@0: #ifdef __MINGW32__ michael@0: 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 411826 */ michael@0: michael@0: #include michael@0: michael@0: int wmain(int argc, WCHAR **argv); michael@0: michael@0: int main(int argc, char **argv) michael@0: { michael@0: LPWSTR commandLine = GetCommandLineW(); michael@0: int argcw = 0; michael@0: LPWSTR *argvw = CommandLineToArgvW(commandLine, &argcw); michael@0: if (!argvw) michael@0: return 127; michael@0: michael@0: int result = wmain(argcw, argvw); michael@0: LocalFree(argvw); michael@0: return result; michael@0: } michael@0: #endif /* __MINGW32__ */ michael@0: michael@0: #define main NS_internal_main michael@0: michael@0: #ifndef XRE_WANT_ENVIRON michael@0: int main(int argc, char **argv); michael@0: #else michael@0: int main(int argc, char **argv, char **envp); michael@0: #endif michael@0: michael@0: static char* michael@0: AllocConvertUTF16toUTF8(char16ptr_t arg) michael@0: { michael@0: // be generous... UTF16 units can expand up to 3 UTF8 units michael@0: int len = wcslen(arg); michael@0: char *s = new char[len * 3 + 1]; michael@0: if (!s) michael@0: return nullptr; michael@0: michael@0: ConvertUTF16toUTF8 convert(s); michael@0: convert.write(arg, len); michael@0: convert.write_terminator(); michael@0: return s; michael@0: } michael@0: michael@0: static void michael@0: FreeAllocStrings(int argc, char **argv) michael@0: { michael@0: while (argc) { michael@0: --argc; michael@0: delete [] argv[argc]; michael@0: } michael@0: michael@0: delete [] argv; michael@0: } michael@0: michael@0: int wmain(int argc, WCHAR **argv) michael@0: { michael@0: #ifndef XRE_DONT_PROTECT_DLL_LOAD michael@0: mozilla::SanitizeEnvironmentVariables(); michael@0: SetDllDirectoryW(L""); michael@0: #endif michael@0: michael@0: char **argvConverted = new char*[argc + 1]; michael@0: if (!argvConverted) michael@0: return 127; michael@0: michael@0: for (int i = 0; i < argc; ++i) { michael@0: argvConverted[i] = AllocConvertUTF16toUTF8(argv[i]); michael@0: if (!argvConverted[i]) { michael@0: return 127; michael@0: } michael@0: } michael@0: argvConverted[argc] = nullptr; michael@0: michael@0: // need to save argvConverted copy for later deletion. michael@0: char **deleteUs = new char*[argc+1]; michael@0: if (!deleteUs) { michael@0: FreeAllocStrings(argc, argvConverted); michael@0: return 127; michael@0: } michael@0: for (int i = 0; i < argc; i++) michael@0: deleteUs[i] = argvConverted[i]; michael@0: #ifndef XRE_WANT_ENVIRON michael@0: int result = main(argc, argvConverted); michael@0: #else michael@0: // Force creation of the multibyte _environ variable. michael@0: getenv("PATH"); michael@0: int result = main(argc, argvConverted, _environ); michael@0: #endif michael@0: michael@0: delete[] argvConverted; michael@0: FreeAllocStrings(argc, deleteUs); michael@0: michael@0: return result; michael@0: }