| // Copyright 2017 The Bazel Authors. All rights reserved. | 
 | // | 
 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | // you may not use this file except in compliance with the License. | 
 | // You may obtain a copy of the License at | 
 | // | 
 | //    http://www.apache.org/licenses/LICENSE-2.0 | 
 | // | 
 | // Unless required by applicable law or agreed to in writing, software | 
 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | // See the License for the specific language governing permissions and | 
 | // limitations under the License. | 
 |  | 
 | #ifndef STRICT | 
 | #define STRICT | 
 | #endif | 
 |  | 
 | #ifndef NOMINMAX | 
 | #define NOMINMAX | 
 | #endif | 
 |  | 
 | #ifndef UNICODE | 
 | #define UNICODE | 
 | #endif | 
 |  | 
 | #ifndef WIN32_LEAN_AND_MEAN | 
 | #define WIN32_LEAN_AND_MEAN | 
 | #endif | 
 |  | 
 | #include <windows.h> | 
 | #include <processenv.h> | 
 | #include <shellapi.h> | 
 | #include <winbase.h> | 
 |  | 
 | #include <memory> | 
 | #include <string> | 
 |  | 
 | #include "src/tools/launcher/bash_launcher.h" | 
 | #include "src/tools/launcher/java_launcher.h" | 
 | #include "src/tools/launcher/launcher.h" | 
 | #include "src/tools/launcher/python_launcher.h" | 
 | #include "src/tools/launcher/util/data_parser.h" | 
 | #include "src/tools/launcher/util/launcher_util.h" | 
 |  | 
 | static constexpr const char* BINARY_TYPE = "binary_type"; | 
 |  | 
 | using bazel::launcher::BashBinaryLauncher; | 
 | using bazel::launcher::BinaryLauncherBase; | 
 | using bazel::launcher::die; | 
 | using bazel::launcher::GetBinaryPathWithExtension; | 
 | using bazel::launcher::GetWindowsLongPath; | 
 | using bazel::launcher::JavaBinaryLauncher; | 
 | using bazel::launcher::LaunchDataParser; | 
 | using bazel::launcher::PythonBinaryLauncher; | 
 | using std::make_unique; | 
 | using std::unique_ptr; | 
 |  | 
 | static std::wstring GetExecutableFileName() { | 
 |   // https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation | 
 |   constexpr std::wstring::size_type maximum_file_name_length = 0x8000; | 
 |   std::wstring buffer(maximum_file_name_length, L'\0'); | 
 |   DWORD length = GetModuleFileNameW(nullptr, &buffer.front(), buffer.size()); | 
 |   if (length == 0 || length >= buffer.size()) { | 
 |     die(L"Failed to obtain executable filename"); | 
 |   } | 
 |   return buffer.substr(0, length); | 
 | } | 
 |  | 
 | #if defined(__MINGW32__) && not defined(BAZEL_MINGW_UNICODE) | 
 | // MinGW requires linkopt=-municode to use wmain as entry point. | 
 | // The below allows fallback to main when BAZEL_MINGW_UNICODE is not defined. | 
 | // Otherwise, to use wmain directly, one needs to use both linkopt=-municode and | 
 | // copt=-DBAZEL_MINGW_UNICODE. | 
 | int wmain(int argc, wchar_t* argv[]); | 
 | int main() { | 
 |   int argc = 0; | 
 |   wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc); | 
 |   if (argv == nullptr) { | 
 |     die(L"CommandLineToArgvW failed."); | 
 |   } | 
 |   int result = wmain(argc, argv); | 
 |   LocalFree(argv); | 
 |   return result; | 
 | } | 
 | #endif | 
 |  | 
 | int wmain(int argc, wchar_t* argv[]) { | 
 |   // In case the given binary path is a shortened Windows 8dot3 path, we convert | 
 |   // it back to its long path form so that path manipulations (e.g. appending | 
 |   // ".runfiles") work as expected. Note that GetExecutableFileName may return a | 
 |   // path different from argv[0]. | 
 |   const std::wstring launcher_path = | 
 |       GetWindowsLongPath(GetExecutableFileName()); | 
 |   LaunchDataParser::LaunchInfo launch_info; | 
 |   if (!LaunchDataParser::GetLaunchInfo(launcher_path, &launch_info)) { | 
 |     die(L"Failed to parse launch info."); | 
 |   } | 
 |  | 
 |   auto result = launch_info.find(BINARY_TYPE); | 
 |   if (result == launch_info.end()) { | 
 |     die(L"Cannot find key \"%hs\" from launch data.", BINARY_TYPE); | 
 |   } | 
 |  | 
 |   unique_ptr<BinaryLauncherBase> binary_launcher; | 
 |  | 
 |   if (result->second == L"Python") { | 
 |     binary_launcher = make_unique<PythonBinaryLauncher>( | 
 |         launch_info, launcher_path, argc, argv); | 
 |   } else if (result->second == L"Bash") { | 
 |     binary_launcher = | 
 |         make_unique<BashBinaryLauncher>(launch_info, launcher_path, argc, argv); | 
 |   } else if (result->second == L"Java") { | 
 |     binary_launcher = | 
 |         make_unique<JavaBinaryLauncher>(launch_info, launcher_path, argc, argv); | 
 |   } else { | 
 |     die(L"Unknown binary type, cannot launch anything."); | 
 |   } | 
 |  | 
 |   return binary_launcher->Launch(); | 
 | } |