diff options
| author | jasjuang <jasjuang@gmail.com> | 2017-09-22 08:16:32 -0700 |
|---|---|---|
| committer | jasjuang <jasjuang@gmail.com> | 2017-09-22 08:16:32 -0700 |
| commit | f643a8422f87c5a16e3cc77e3e321e34a45f7103 (patch) | |
| tree | 419c9a2e74ab577aab0e868441b9a0e4c15d4919 /toolsrc/src/vcpkg_System.cpp | |
| parent | 9989177fed607cdc9e20127ff7c22e3266e7c913 (diff) | |
| parent | fac96eb344a500405ab65b7e7f3755af0ad00b7e (diff) | |
| download | vcpkg-f643a8422f87c5a16e3cc77e3e321e34a45f7103.tar.gz vcpkg-f643a8422f87c5a16e3cc77e3e321e34a45f7103.zip | |
Merge branch 'master' of https://github.com/jasjuang/vcpkg
Diffstat (limited to 'toolsrc/src/vcpkg_System.cpp')
| -rw-r--r-- | toolsrc/src/vcpkg_System.cpp | 182 |
1 files changed, 119 insertions, 63 deletions
diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 883fe6612..40e335117 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "vcpkg_Checks.h" +#include "vcpkg_GlobalState.h" #include "vcpkg_System.h" #include "vcpkglib.h" @@ -18,7 +19,7 @@ namespace vcpkg::System fs::path get_exe_path_of_current_process() { wchar_t buf[_MAX_PATH]; - int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); + const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); if (bytes == 0) std::abort(); return fs::path(buf, buf + bytes); } @@ -36,18 +37,32 @@ namespace vcpkg::System CPUArchitecture get_host_processor() { auto w6432 = get_environment_variable(L"PROCESSOR_ARCHITEW6432"); - if (auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); + if (const auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); - auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); + const auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO); } + std::vector<CPUArchitecture> get_supported_host_architectures() + { + std::vector<CPUArchitecture> supported_architectures; + supported_architectures.push_back(get_host_processor()); + + // AMD64 machines support to run x86 applications + if (supported_architectures.back() == CPUArchitecture::X64) + { + supported_architectures.push_back(CPUArchitecture::X86); + } + + return supported_architectures; + } + int cmd_execute_clean(const CWStringView cmd_line) { - static const std::wstring system_root = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); - static const std::wstring system_32 = system_root + LR"(\system32)"; - static const std::wstring new_PATH = Strings::wformat( - LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", system_32, system_root, system_32, system_32); + static const std::wstring SYSTEM_ROOT = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); + static const std::wstring SYSTEM_32 = SYSTEM_ROOT + LR"(\system32)"; + static const std::wstring NEW_PATH = Strings::wformat( + LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); std::vector<std::wstring> env_wstrings = { L"ALLUSERSPROFILE", @@ -94,47 +109,84 @@ namespace vcpkg::System }; // Flush stdout before launching external process - fflush(nullptr); + fflush(nullptr); - std::vector<const wchar_t*> env_cstr; - env_cstr.reserve(env_wstrings.size() + 2); + std::wstring env_cstr; for (auto&& env_wstring : env_wstrings) { const Optional<std::wstring> value = System::get_environment_variable(env_wstring); - auto v = value.get(); + const auto v = value.get(); if (!v || v->empty()) continue; - env_wstring.push_back(L'='); - env_wstring.append(*v); - env_cstr.push_back(env_wstring.c_str()); + env_cstr.append(env_wstring); + env_cstr.push_back(L'='); + env_cstr.append(*v); + env_cstr.push_back(L'\0'); } - env_cstr.push_back(new_PATH.c_str()); - env_cstr.push_back(nullptr); + env_cstr.append(NEW_PATH); + env_cstr.push_back(L'\0'); + + STARTUPINFOW startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFOW)); + startup_info.cb = sizeof(STARTUPINFOW); + + PROCESS_INFORMATION process_info; + memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); // Basically we are wrapping it in quotes - const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); - Debug::println("_wspawnlpe(cmd.exe /c %s)", Strings::to_utf8(actual_cmd_line)); - auto exit_code = - _wspawnlpe(_P_WAIT, L"cmd.exe", L"cmd.exe", L"/c", actual_cmd_line.c_str(), nullptr, env_cstr.data()); - Debug::println("_wspawnlpe() returned %d", exit_code); + std::wstring actual_cmd_line = Strings::wformat(LR"###(cmd.exe /c "%s")###", cmd_line); + Debug::println("CreateProcessW(%s)", Strings::to_utf8(actual_cmd_line)); + bool succeeded = TRUE == CreateProcessW(nullptr, + actual_cmd_line.data(), + nullptr, + nullptr, + FALSE, + BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, + env_cstr.data(), + nullptr, + &startup_info, + &process_info); + + Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); + + CloseHandle(process_info.hThread); + + const DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); + Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); + + DWORD exit_code = 0; + GetExitCodeProcess(process_info.hProcess, &exit_code); + + Debug::println("CreateProcessW() returned %lu", exit_code); return static_cast<int>(exit_code); } int cmd_execute(const CWStringView cmd_line) { // Flush stdout before launching external process - fflush(nullptr); + fflush(nullptr); // Basically we are wrapping it in quotes const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); Debug::println("_wsystem(%s)", Strings::to_utf8(actual_cmd_line)); - int exit_code = _wsystem(actual_cmd_line.c_str()); + const int exit_code = _wsystem(actual_cmd_line.c_str()); Debug::println("_wsystem() returned %d", exit_code); return exit_code; } + // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present + static void remove_byte_order_mark(std::wstring* s) + { + const wchar_t* a = s->c_str(); + // This is the UTF-8 byte-order mark + if (a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) + { + s->erase(0, 3); + } + } + ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line) { // Flush stdout before launching external process @@ -143,24 +195,26 @@ namespace vcpkg::System const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line); Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); - std::string output; - char buf[1024]; - auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); + std::wstring output; + wchar_t buf[1024]; + const auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); if (pipe == nullptr) { - return {1, output}; + return {1, Strings::to_utf8(output)}; } - while (fgets(buf, 1024, pipe)) + while (fgetws(buf, 1024, pipe)) { output.append(buf); } if (!feof(pipe)) { - return {1, output}; + return {1, Strings::to_utf8(output)}; } - auto ec = _pclose(pipe); - Debug::println("_wpopen() returned %d", ec); - return {ec, output}; + + const auto ec = _pclose(pipe); + Debug::println("_pclose() returned %d", ec); + remove_byte_order_mark(&output); + return {ec, Strings::to_utf8(output)}; } std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args) @@ -170,6 +224,8 @@ namespace vcpkg::System LR"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args); } + void println() { println(Strings::EMPTY); } + void print(const CStringView message) { fputs(message, stdout); } void println(const CStringView message) @@ -180,15 +236,15 @@ namespace vcpkg::System void print(const Color c, const CStringView message) { - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO consoleScreenBufferInfo{}; - GetConsoleScreenBufferInfo(hConsole, &consoleScreenBufferInfo); - auto original_color = consoleScreenBufferInfo.wAttributes; + CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; + GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); + const auto original_color = console_screen_buffer_info.wAttributes; - SetConsoleTextAttribute(hConsole, static_cast<WORD>(c) | (original_color & 0xF0)); + SetConsoleTextAttribute(console_handle, static_cast<WORD>(c) | (original_color & 0xF0)); print(message); - SetConsoleTextAttribute(hConsole, original_color); + SetConsoleTextAttribute(console_handle, original_color); } void println(const Color c, const CStringView message) @@ -199,13 +255,13 @@ namespace vcpkg::System Optional<std::wstring> get_environment_variable(const CWStringView varname) noexcept { - auto sz = GetEnvironmentVariableW(varname, nullptr, 0); + const auto sz = GetEnvironmentVariableW(varname, nullptr, 0); if (sz == 0) return nullopt; std::wstring ret(sz, L'\0'); Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size()); - auto sz2 = GetEnvironmentVariableW(varname, ret.data(), static_cast<DWORD>(ret.size())); + const auto sz2 = GetEnvironmentVariableW(varname, ret.data(), static_cast<DWORD>(ret.size())); Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); ret.pop_back(); return ret; @@ -216,59 +272,59 @@ namespace vcpkg::System return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; } - Optional<std::wstring> get_registry_string(HKEY base, const CWStringView subKey, const CWStringView valuename) + Optional<std::wstring> get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename) { HKEY k = nullptr; - LSTATUS ec = RegOpenKeyExW(base, subKey, NULL, KEY_READ, &k); + const LSTATUS ec = RegOpenKeyExW(base, sub_key, NULL, KEY_READ, &k); if (ec != ERROR_SUCCESS) return nullopt; - DWORD dwBufferSize = 0; - DWORD dwType = 0; - auto rc = RegQueryValueExW(k, valuename, nullptr, &dwType, nullptr, &dwBufferSize); - if (rc != ERROR_SUCCESS || !is_string_keytype(dwType) || dwBufferSize == 0 || - dwBufferSize % sizeof(wchar_t) != 0) + DWORD dw_buffer_size = 0; + DWORD dw_type = 0; + auto rc = RegQueryValueExW(k, valuename, nullptr, &dw_type, nullptr, &dw_buffer_size); + if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || + dw_buffer_size % sizeof(wchar_t) != 0) return nullopt; std::wstring ret; - ret.resize(dwBufferSize / sizeof(wchar_t)); + ret.resize(dw_buffer_size / sizeof(wchar_t)); - rc = RegQueryValueExW(k, valuename, nullptr, &dwType, reinterpret_cast<LPBYTE>(ret.data()), &dwBufferSize); - if (rc != ERROR_SUCCESS || !is_string_keytype(dwType) || dwBufferSize != sizeof(wchar_t) * ret.size()) + rc = RegQueryValueExW(k, valuename, nullptr, &dw_type, reinterpret_cast<LPBYTE>(ret.data()), &dw_buffer_size); + if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) return nullopt; ret.pop_back(); // remove extra trailing null byte return ret; } - static const fs::path& get_ProgramFiles() + static const fs::path& get_program_files() { - static const fs::path p = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); - return p; + static const fs::path PATH = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); + return PATH; } - const fs::path& get_ProgramFiles_32_bit() + const fs::path& get_program_files_32_bit() { - static const fs::path p = []() -> fs::path { + static const fs::path PATH = []() -> fs::path { auto value = System::get_environment_variable(L"ProgramFiles(x86)"); if (auto v = value.get()) { return std::move(*v); } - return get_ProgramFiles(); + return get_program_files(); }(); - return p; + return PATH; } - const fs::path& get_ProgramFiles_platform_bitness() + const fs::path& get_program_files_platform_bitness() { - static const fs::path p = []() -> fs::path { + static const fs::path PATH = []() -> fs::path { auto value = System::get_environment_variable(L"ProgramW6432"); if (auto v = value.get()) { return std::move(*v); } - return get_ProgramFiles(); + return get_program_files(); }(); - return p; + return PATH; } } @@ -276,7 +332,7 @@ namespace vcpkg::Debug { void println(const CStringView message) { - if (g_debugging) + if (GlobalState::debugging) { System::println("[DEBUG] %s", message); } @@ -284,7 +340,7 @@ namespace vcpkg::Debug void println(const System::Color c, const CStringView message) { - if (g_debugging) + if (GlobalState::debugging) { System::println(c, "[DEBUG] %s", message); } |
