11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors.
21cb0ef41Sopenharmony_ci//
31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a
41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the
51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including
61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish,
71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit
81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the
91cb0ef41Sopenharmony_ci// following conditions:
101cb0ef41Sopenharmony_ci//
111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included
121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software.
131cb0ef41Sopenharmony_ci//
141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE.
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#include "node.h"
231cb0ef41Sopenharmony_ci#include <cstdio>
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci#ifdef _WIN32
261cb0ef41Sopenharmony_ci#include <windows.h>
271cb0ef41Sopenharmony_ci#include <VersionHelpers.h>
281cb0ef41Sopenharmony_ci#include <WinError.h>
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci#define SKIP_CHECK_VAR "NODE_SKIP_PLATFORM_CHECK"
311cb0ef41Sopenharmony_ci#define SKIP_CHECK_VALUE "1"
321cb0ef41Sopenharmony_ci#define SKIP_CHECK_STRLEN (sizeof(SKIP_CHECK_VALUE) - 1)
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciint wmain(int argc, wchar_t* wargv[]) {
351cb0ef41Sopenharmony_ci  // Windows Server 2012 (not R2) is supported until 10/10/2023, so we allow it
361cb0ef41Sopenharmony_ci  // to run in the experimental support tier.
371cb0ef41Sopenharmony_ci  char buf[SKIP_CHECK_STRLEN + 1];
381cb0ef41Sopenharmony_ci  if (!IsWindows8Point1OrGreater() &&
391cb0ef41Sopenharmony_ci      !(IsWindowsServer() && IsWindows8OrGreater()) &&
401cb0ef41Sopenharmony_ci      (GetEnvironmentVariableA(SKIP_CHECK_VAR, buf, sizeof(buf)) !=
411cb0ef41Sopenharmony_ci           SKIP_CHECK_STRLEN ||
421cb0ef41Sopenharmony_ci       strncmp(buf, SKIP_CHECK_VALUE, SKIP_CHECK_STRLEN) != 0)) {
431cb0ef41Sopenharmony_ci    fprintf(stderr, "Node.js is only supported on Windows 8.1, Windows "
441cb0ef41Sopenharmony_ci                    "Server 2012 R2, or higher.\n"
451cb0ef41Sopenharmony_ci                    "Setting the " SKIP_CHECK_VAR " environment variable "
461cb0ef41Sopenharmony_ci                    "to 1 skips this\ncheck, but Node.js might not execute "
471cb0ef41Sopenharmony_ci                    "correctly. Any issues encountered on\nunsupported "
481cb0ef41Sopenharmony_ci                    "platforms will not be fixed.");
491cb0ef41Sopenharmony_ci    exit(ERROR_EXE_MACHINE_TYPE_MISMATCH);
501cb0ef41Sopenharmony_ci  }
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  // Convert argv to UTF8
531cb0ef41Sopenharmony_ci  char** argv = new char*[argc + 1];
541cb0ef41Sopenharmony_ci  for (int i = 0; i < argc; i++) {
551cb0ef41Sopenharmony_ci    // Compute the size of the required buffer
561cb0ef41Sopenharmony_ci    DWORD size = WideCharToMultiByte(CP_UTF8,
571cb0ef41Sopenharmony_ci                                     0,
581cb0ef41Sopenharmony_ci                                     wargv[i],
591cb0ef41Sopenharmony_ci                                     -1,
601cb0ef41Sopenharmony_ci                                     nullptr,
611cb0ef41Sopenharmony_ci                                     0,
621cb0ef41Sopenharmony_ci                                     nullptr,
631cb0ef41Sopenharmony_ci                                     nullptr);
641cb0ef41Sopenharmony_ci    if (size == 0) {
651cb0ef41Sopenharmony_ci      // This should never happen.
661cb0ef41Sopenharmony_ci      fprintf(stderr, "Could not convert arguments to utf8.");
671cb0ef41Sopenharmony_ci      exit(1);
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci    // Do the actual conversion
701cb0ef41Sopenharmony_ci    argv[i] = new char[size];
711cb0ef41Sopenharmony_ci    DWORD result = WideCharToMultiByte(CP_UTF8,
721cb0ef41Sopenharmony_ci                                       0,
731cb0ef41Sopenharmony_ci                                       wargv[i],
741cb0ef41Sopenharmony_ci                                       -1,
751cb0ef41Sopenharmony_ci                                       argv[i],
761cb0ef41Sopenharmony_ci                                       size,
771cb0ef41Sopenharmony_ci                                       nullptr,
781cb0ef41Sopenharmony_ci                                       nullptr);
791cb0ef41Sopenharmony_ci    if (result == 0) {
801cb0ef41Sopenharmony_ci      // This should never happen.
811cb0ef41Sopenharmony_ci      fprintf(stderr, "Could not convert arguments to utf8.");
821cb0ef41Sopenharmony_ci      exit(1);
831cb0ef41Sopenharmony_ci    }
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci  argv[argc] = nullptr;
861cb0ef41Sopenharmony_ci  // Now that conversion is done, we can finally start.
871cb0ef41Sopenharmony_ci  return node::Start(argc, argv);
881cb0ef41Sopenharmony_ci}
891cb0ef41Sopenharmony_ci#else
901cb0ef41Sopenharmony_ci// UNIX
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ciint main(int argc, char* argv[]) {
931cb0ef41Sopenharmony_ci  return node::Start(argc, argv);
941cb0ef41Sopenharmony_ci}
951cb0ef41Sopenharmony_ci#endif
96