DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (6863f516ba38)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsWindowsWMain_cpp
#define nsWindowsWMain_cpp

// This file is a .cpp file meant to be included in nsBrowserApp.cpp and other
// similar bootstrap code. It converts wide-character windows wmain into UTF-8
// narrow-character strings.

#ifndef XP_WIN
#  error This file only makes sense on Windows.
#endif

#include "mozilla/Char16.h"
#include "nsUTF8Utils.h"

#include <windows.h>

#ifdef __MINGW32__

/* MingW currently does not implement a wide version of the
   startup routines.  Workaround is to implement something like
   it ourselves.  See bug 411826 */

#  include <shellapi.h>

int wmain(int argc, WCHAR** argv);

int main(int argc, char** argv) {
  LPWSTR commandLine = GetCommandLineW();
  int argcw = 0;
  LPWSTR* argvw = CommandLineToArgvW(commandLine, &argcw);
  if (!argvw) return 127;

  int result = wmain(argcw, argvw);
  LocalFree(argvw);
  return result;
}
#endif /* __MINGW32__ */

#define main NS_internal_main

#ifndef XRE_WANT_ENVIRON
int main(int argc, char** argv);
#else
int main(int argc, char** argv, char** envp);
#endif

static void SanitizeEnvironmentVariables() {
  DWORD bufferSize = GetEnvironmentVariableW(L"PATH", nullptr, 0);
  if (bufferSize) {
    wchar_t* originalPath = new wchar_t[bufferSize];
    if (bufferSize - 1 ==
        GetEnvironmentVariableW(L"PATH", originalPath, bufferSize)) {
      bufferSize = ExpandEnvironmentStringsW(originalPath, nullptr, 0);
      if (bufferSize) {
        wchar_t* newPath = new wchar_t[bufferSize];
        if (ExpandEnvironmentStringsW(originalPath, newPath, bufferSize)) {
          SetEnvironmentVariableW(L"PATH", newPath);
        }
        delete[] newPath;
      }
    }
    delete[] originalPath;
  }
}

static char* AllocConvertUTF16toUTF8(char16ptr_t arg) {
  // be generous... UTF16 units can expand up to 3 UTF8 units
  size_t len = wcslen(arg);
  // ConvertUTF16toUTF8 requires +1. Let's do that here, too, lacking
  // knowledge of Windows internals.
  size_t dstLen = len * 3 + 1;
  char* s = new char[dstLen + 1];  // Another +1 for zero terminator
  if (!s) return nullptr;

  int written =
      ::WideCharToMultiByte(CP_UTF8, 0, arg, len, s, dstLen, nullptr, nullptr);
  s[written] = 0;
  return s;
}

static void FreeAllocStrings(int argc, char** argv) {
  while (argc) {
    --argc;
    delete[] argv[argc];
  }

  delete[] argv;
}

int wmain(int argc, WCHAR** argv) {
  SanitizeEnvironmentVariables();
  SetDllDirectoryW(L"");

  // Only run this code if LauncherProcessWin.h was included beforehand, thus
  // signalling that the hosting process should support launcher mode.
#if defined(mozilla_LauncherProcessWin_h)
  mozilla::Maybe<int> launcherResult =
      mozilla::LauncherMain(argc, argv, sAppData);
  if (launcherResult) {
    return launcherResult.value();
  }
#endif  // defined(mozilla_LauncherProcessWin_h)

  char** argvConverted = new char*[argc + 1];
  if (!argvConverted) return 127;

  for (int i = 0; i < argc; ++i) {
    argvConverted[i] = AllocConvertUTF16toUTF8(argv[i]);
    if (!argvConverted[i]) {
      return 127;
    }
  }
  argvConverted[argc] = nullptr;

  // need to save argvConverted copy for later deletion.
  char** deleteUs = new char*[argc + 1];
  if (!deleteUs) {
    FreeAllocStrings(argc, argvConverted);
    return 127;
  }
  for (int i = 0; i < argc; i++) deleteUs[i] = argvConverted[i];
#ifndef XRE_WANT_ENVIRON
  int result = main(argc, argvConverted);
#else
  // Force creation of the multibyte _environ variable.
  getenv("PATH");
  int result = main(argc, argvConverted, _environ);
#endif

  delete[] argvConverted;
  FreeAllocStrings(argc, deleteUs);

  return result;
}

#endif  // nsWindowsWMain_cpp