aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src/vcpkg_System.cpp
diff options
context:
space:
mode:
authorJan HrubĂ˝ <jhruby.web@gmail.com>2017-03-13 08:56:05 +0100
committerGitHub <noreply@github.com>2017-03-13 08:56:05 +0100
commit665f4118f603c5858217ed7a2f2f824b18ff4fc5 (patch)
treef0167041edf71e90f2331b5025f603392a8de67a /toolsrc/src/vcpkg_System.cpp
parent1bec0fcb73073b5b1719f454c368a63f1bff625e (diff)
parent1c9873a0daf625f67474aaf3e163c592c27ecb65 (diff)
downloadvcpkg-665f4118f603c5858217ed7a2f2f824b18ff4fc5.tar.gz
vcpkg-665f4118f603c5858217ed7a2f2f824b18ff4fc5.zip
Merge pull request #1 from Microsoft/master
pull
Diffstat (limited to 'toolsrc/src/vcpkg_System.cpp')
-rw-r--r--toolsrc/src/vcpkg_System.cpp181
1 files changed, 142 insertions, 39 deletions
diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp
index 71b4087d2..472f8450f 100644
--- a/toolsrc/src/vcpkg_System.cpp
+++ b/toolsrc/src/vcpkg_System.cpp
@@ -1,39 +1,116 @@
+#include "pch.h"
#include "vcpkg_System.h"
-#include <iostream>
-#include <Windows.h>
-#include <regex>
+#include "vcpkg_Checks.h"
-namespace fs = std::tr2::sys;
-
-namespace vcpkg {namespace System
+namespace vcpkg::System
{
fs::path get_exe_path_of_current_process()
{
- wchar_t buf[_MAX_PATH ];
+ wchar_t buf[_MAX_PATH];
int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH);
if (bytes == 0)
std::abort();
return fs::path(buf, buf + bytes);
}
+ int cmd_execute_clean(const wchar_t* cmd_line)
+ {
+ static const std::wstring system_root = *get_environmental_variable(L"SystemRoot");
+ static const std::wstring system_32 = system_root + LR"(\system32)";
+ static const std::wstring new_PATH = Strings::wformat(LR"(Path=%s;%s;%s\WindowsPowerShell\v1.0\)", system_32, system_root, system_32);
+
+ std::vector<std::wstring> env_wstrings =
+ {
+ L"ALLUSERSPROFILE",
+ L"APPDATA",
+ L"CommonProgramFiles",
+ L"CommonProgramFiles(x86)",
+ L"CommonProgramW6432",
+ L"COMPUTERNAME",
+ L"ComSpec",
+ L"HOMEDRIVE",
+ L"HOMEPATH",
+ L"LOCALAPPDATA",
+ L"LOGONSERVER",
+ L"NUMBER_OF_PROCESSORS",
+ L"OS",
+ L"PATHEXT",
+ L"PROCESSOR_ARCHITECTURE",
+ L"PROCESSOR_IDENTIFIER",
+ L"PROCESSOR_LEVEL",
+ L"PROCESSOR_REVISION",
+ L"ProgramData",
+ L"ProgramFiles",
+ L"ProgramFiles(x86)",
+ L"ProgramW6432",
+ L"PROMPT",
+ L"PSModulePath",
+ L"PUBLIC",
+ L"SystemDrive",
+ L"SystemRoot",
+ L"TEMP",
+ L"TMP",
+ L"USERDNSDOMAIN",
+ L"USERDOMAIN",
+ L"USERDOMAIN_ROAMINGPROFILE",
+ L"USERNAME",
+ L"USERPROFILE",
+ L"windir",
+ // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe
+ L"HTTP_PROXY",
+ L"HTTPS_PROXY",
+ };
+
+ // Flush stdout before launching external process
+ _flushall();
+
+ std::vector<const wchar_t*> env_cstr;
+ env_cstr.reserve(env_wstrings.size() + 2);
+
+ for (auto&& env_wstring : env_wstrings)
+ {
+ auto v = System::get_environmental_variable(env_wstring.c_str());
+ if (v == nullptr || v->empty())
+ continue;
+
+ env_wstring.push_back(L'=');
+ env_wstring.append(*v);
+ env_cstr.push_back(env_wstring.c_str());
+ }
+
+ env_cstr.push_back(new_PATH.c_str());
+ env_cstr.push_back(nullptr);
+
+ // Basically we are wrapping it in quotes
+ const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", 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());
+ return static_cast<int>(exit_code);
+ }
+
int cmd_execute(const wchar_t* cmd_line)
{
+ // Flush stdout before launching external process
+ _flushall();
+
// Basically we are wrapping it in quotes
- const std::wstring& actual_cmd_line = Strings::format(LR"###("%s")###", cmd_line);
+ const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line);
int exit_code = _wsystem(actual_cmd_line.c_str());
return exit_code;
}
exit_code_and_output cmd_execute_and_capture_output(const wchar_t* cmd_line)
{
- const std::wstring& actual_cmd_line = Strings::format(LR"###("%s")###", cmd_line);
+ // Flush stdout before launching external process
+ fflush(stdout);
+
+ const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line);
std::string output;
char buf[1024];
auto pipe = _wpopen(actual_cmd_line.c_str(), L"r");
if (pipe == nullptr)
{
- return {1, output};
+ return { 1, output };
}
while (fgets(buf, 1024, pipe))
{
@@ -41,24 +118,35 @@ namespace vcpkg {namespace System
}
if (!feof(pipe))
{
- return {1, output};
+ return { 1, output };
}
auto ec = _pclose(pipe);
- return {ec, output};
+ return { ec, output };
+ }
+
+ std::wstring create_powershell_script_cmd(const fs::path& script_path)
+ {
+ return create_powershell_script_cmd(script_path, L"");
+ }
+
+ std::wstring create_powershell_script_cmd(const fs::path& script_path, const std::wstring& args)
+ {
+ // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned
+ return Strings::wformat(LR"(powershell -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args);
}
void print(const char* message)
{
- std::cout << message;
+ fputs(message, stdout);
}
void println(const char* message)
{
print(message);
- std::cout << "\n";
+ putchar('\n');
}
- void print(color c, const char* message)
+ void print(const color c, const char* message)
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -66,46 +154,61 @@ namespace vcpkg {namespace System
GetConsoleScreenBufferInfo(hConsole, &consoleScreenBufferInfo);
auto original_color = consoleScreenBufferInfo.wAttributes;
- SetConsoleTextAttribute(hConsole, static_cast<int>(c) | (original_color & 0xF0));
- std::cout << message;
+ SetConsoleTextAttribute(hConsole, static_cast<WORD>(c) | (original_color & 0xF0));
+ print(message);
SetConsoleTextAttribute(hConsole, original_color);
}
- void println(color c, const char* message)
+ void println(const color c, const char* message)
{
print(c, message);
- std::cout << "\n";
+ putchar('\n');
}
- std::wstring wdupenv_str(const wchar_t* varname) noexcept
+ optional<std::wstring> get_environmental_variable(const wchar_t* varname) noexcept
{
- std::wstring ret;
- wchar_t* buffer;
- _wdupenv_s(&buffer, nullptr, varname);
- if (buffer != nullptr)
- {
- ret = buffer;
- free(buffer);
- }
+ auto sz = GetEnvironmentVariableW(varname, nullptr, 0);
+ if (sz == 0)
+ return nullptr;
+
+ auto ret = std::make_unique<std::wstring>(sz, L'\0');
+ Checks::check_exit(MAXDWORD >= ret->size());
+ auto sz2 = GetEnvironmentVariableW(varname, ret->data(), static_cast<DWORD>(ret->size()));
+ Checks::check_exit(sz2 + 1 == sz);
+ ret->pop_back();
return ret;
}
- void Stopwatch::start()
+ void set_environmental_variable(const wchar_t* varname, const wchar_t* varvalue) noexcept
{
- static_assert(sizeof(start_time) == sizeof(LARGE_INTEGER), "");
-
- QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&start_time));
+ _wputenv_s(varname, varvalue);
}
- void Stopwatch::stop()
+ static bool is_string_keytype(DWORD hkey_type)
{
- QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&end_time));
- QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&freq));
+ return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ;
}
- double Stopwatch::microseconds() const
+ optional<std::wstring> get_registry_string(HKEY base, const wchar_t* subKey, const wchar_t* valuename)
{
- return (reinterpret_cast<const LARGE_INTEGER*>(&end_time)->QuadPart -
- reinterpret_cast<const LARGE_INTEGER*>(&start_time)->QuadPart) * 1000000.0 / reinterpret_cast<const LARGE_INTEGER*>(&freq)->QuadPart;
+ HKEY k = nullptr;
+ LSTATUS ec = RegOpenKeyExW(base, subKey, NULL, KEY_READ, &k);
+ if (ec != ERROR_SUCCESS)
+ return nullptr;
+
+ 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)
+ return nullptr;
+ std::wstring ret;
+ ret.resize(dwBufferSize / 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())
+ return nullptr;
+
+ ret.pop_back(); // remove extra trailing null byte
+ return std::make_unique<std::wstring>(std::move(ret));
}
-}}
+}