mirror of
https://github.com/thinkonmay/sunshine-sdk.git
synced 2026-01-10 07:12:04 +00:00
fix compile
This commit is contained in:
parent
4f2f73d893
commit
cf440a512c
@ -42,9 +42,6 @@ namespace boost {
|
||||
namespace process {
|
||||
class child;
|
||||
class group;
|
||||
template <typename Char>
|
||||
class basic_environment;
|
||||
typedef basic_environment<char> environment;
|
||||
} // namespace process
|
||||
} // namespace boost
|
||||
namespace video {
|
||||
@ -585,8 +582,6 @@ namespace platf {
|
||||
bool
|
||||
needs_encoder_reenumeration();
|
||||
|
||||
boost::process::child
|
||||
run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const boost::process::environment &env, FILE *file, std::error_code &ec, boost::process::group *group);
|
||||
|
||||
enum class thread_priority_e : int {
|
||||
low,
|
||||
@ -647,12 +642,7 @@ namespace platf {
|
||||
std::unique_ptr<deinit_t>
|
||||
enable_socket_qos(uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type, bool dscp_tagging);
|
||||
|
||||
/**
|
||||
* @brief Open a url in the default web browser.
|
||||
* @param url The url to open.
|
||||
*/
|
||||
void
|
||||
open_url(const std::string &url);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Attempt to gracefully terminate a process group.
|
||||
|
||||
@ -238,47 +238,6 @@ namespace platf {
|
||||
return "00:00:00:00:00:00"s;
|
||||
}
|
||||
|
||||
bp::child
|
||||
run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
|
||||
if (!group) {
|
||||
if (!file) {
|
||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec);
|
||||
}
|
||||
else {
|
||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!file) {
|
||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group);
|
||||
}
|
||||
else {
|
||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open a url in the default web browser.
|
||||
* @param url The url to open.
|
||||
*/
|
||||
void
|
||||
open_url(const std::string &url) {
|
||||
// set working dir to user home directory
|
||||
auto working_dir = boost::filesystem::path(std::getenv("HOME"));
|
||||
std::string cmd = R"(xdg-open ")" + url + R"(")";
|
||||
|
||||
boost::process::environment _env = boost::this_process::environment();
|
||||
std::error_code ec;
|
||||
auto child = run_command(false, false, cmd, working_dir, _env, nullptr, ec, nullptr);
|
||||
if (ec) {
|
||||
BOOST_LOG(warning) << "Couldn't open url ["sv << url << "]: System: "sv << ec.message();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG(info) << "Opened url ["sv << url << "]"sv;
|
||||
child.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
adjust_thread_priority(thread_priority_e priority) {
|
||||
|
||||
@ -167,46 +167,6 @@ namespace platf {
|
||||
return "00:00:00:00:00:00"s;
|
||||
}
|
||||
|
||||
bp::child
|
||||
run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
|
||||
if (!group) {
|
||||
if (!file) {
|
||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec);
|
||||
}
|
||||
else {
|
||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!file) {
|
||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group);
|
||||
}
|
||||
else {
|
||||
return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open a url in the default web browser.
|
||||
* @param url The url to open.
|
||||
*/
|
||||
void
|
||||
open_url(const std::string &url) {
|
||||
boost::filesystem::path working_dir;
|
||||
std::string cmd = R"(open ")" + url + R"(")";
|
||||
|
||||
boost::process::environment _env = boost::this_process::environment();
|
||||
std::error_code ec;
|
||||
auto child = run_command(false, false, cmd, working_dir, _env, nullptr, ec, nullptr);
|
||||
if (ec) {
|
||||
BOOST_LOG(warning) << "Couldn't open url ["sv << url << "]: System: "sv << ec.message();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG(info) << "Opened url ["sv << url << "]"sv;
|
||||
child.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
adjust_thread_priority(thread_priority_e priority) {
|
||||
|
||||
@ -417,45 +417,6 @@ namespace platf {
|
||||
HeapFree(GetProcessHeap(), 0, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a `bp::child` object from the results of launching a process.
|
||||
* @param process_launched A boolean indicating if the launch was successful.
|
||||
* @param cmd The command that was used to launch the process.
|
||||
* @param ec A reference to an `std::error_code` object that will store any error that occurred during the launch.
|
||||
* @param process_info A reference to a `PROCESS_INFORMATION` structure that contains information about the new process.
|
||||
* @return A `bp::child` object representing the new process, or an empty `bp::child` object if the launch failed.
|
||||
*/
|
||||
bp::child
|
||||
create_boost_child_from_results(bool process_launched, const std::string &cmd, std::error_code &ec, PROCESS_INFORMATION &process_info) {
|
||||
// Use RAII to ensure the process is closed when we're done with it, even if there was an error.
|
||||
auto close_process_handles = util::fail_guard([process_launched, process_info]() {
|
||||
if (process_launched) {
|
||||
CloseHandle(process_info.hThread);
|
||||
CloseHandle(process_info.hProcess);
|
||||
}
|
||||
});
|
||||
|
||||
if (ec) {
|
||||
// If there was an error, return an empty bp::child object
|
||||
return bp::child();
|
||||
}
|
||||
|
||||
if (process_launched) {
|
||||
// If the launch was successful, create a new bp::child object representing the new process
|
||||
auto child = bp::child((bp::pid_t) process_info.dwProcessId);
|
||||
BOOST_LOG(info) << cmd << " running with PID "sv << child.id();
|
||||
return child;
|
||||
}
|
||||
else {
|
||||
auto winerror = GetLastError();
|
||||
BOOST_LOG(error) << "Failed to launch process: "sv << winerror;
|
||||
ec = std::make_error_code(std::errc::invalid_argument);
|
||||
// We must NOT attach the failed process here, since this case can potentially be induced by ACL
|
||||
// manipulation (denying yourself execute permission) to cause an escalation of privilege.
|
||||
// So to protect ourselves against that, we'll return an empty child process instead.
|
||||
return bp::child();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Impersonate the current user and invoke the callback function.
|
||||
@ -890,167 +851,6 @@ namespace platf {
|
||||
return cmd_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Run a command on the users profile.
|
||||
*
|
||||
* Launches a child process as the user, using the current user's environment and a specific working directory.
|
||||
*
|
||||
* @param elevated Specify whether to elevate the process.
|
||||
* @param interactive Specify whether this will run in a window or hidden.
|
||||
* @param cmd The command to run.
|
||||
* @param working_dir The working directory for the new process.
|
||||
* @param env The environment variables to use for the new process.
|
||||
* @param file A file object to redirect the child process's output to (may be `nullptr`).
|
||||
* @param ec An error code, set to indicate any errors that occur during the launch process.
|
||||
* @param group A pointer to a `bp::group` object to which the new process should belong (may be `nullptr`).
|
||||
* @return A `bp::child` object representing the new process, or an empty `bp::child` object if the launch fails.
|
||||
*/
|
||||
bp::child
|
||||
run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) {
|
||||
std::wstring start_dir = from_utf8(working_dir.string());
|
||||
HANDLE job = group ? group->native_handle() : nullptr;
|
||||
STARTUPINFOEXW startup_info = create_startup_info(file, job ? &job : nullptr, ec);
|
||||
PROCESS_INFORMATION process_info;
|
||||
|
||||
// Clone the environment to create a local copy. Boost.Process (bp) shares the environment with all spawned processes.
|
||||
// Since we're going to modify the 'env' variable by merging user-specific environment variables into it,
|
||||
// we make a clone to prevent side effects to the shared environment.
|
||||
bp::environment cloned_env = env;
|
||||
|
||||
if (ec) {
|
||||
// In the event that startup_info failed, return a blank child process.
|
||||
return bp::child();
|
||||
}
|
||||
|
||||
// Use RAII to ensure the attribute list is freed when we're done with it
|
||||
auto attr_list_free = util::fail_guard([list = startup_info.lpAttributeList]() {
|
||||
free_proc_thread_attr_list(list);
|
||||
});
|
||||
|
||||
DWORD creation_flags = EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT | CREATE_BREAKAWAY_FROM_JOB;
|
||||
|
||||
// Create a new console for interactive processes and use no console for non-interactive processes
|
||||
creation_flags |= interactive ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW;
|
||||
|
||||
// Find the PATH variable in our environment block using a case-insensitive search
|
||||
auto sunshine_wenv = boost::this_process::wenvironment();
|
||||
std::wstring path_var_name { L"PATH" };
|
||||
std::wstring old_path_val;
|
||||
auto itr = std::find_if(sunshine_wenv.cbegin(), sunshine_wenv.cend(), [&](const auto &e) { return boost::iequals(e.get_name(), path_var_name); });
|
||||
if (itr != sunshine_wenv.cend()) {
|
||||
// Use the existing variable if it exists, since Boost treats these as case-sensitive.
|
||||
path_var_name = itr->get_name();
|
||||
old_path_val = sunshine_wenv[path_var_name].to_string();
|
||||
}
|
||||
|
||||
// Temporarily prepend the specified working directory to PATH to ensure CreateProcess()
|
||||
// will (preferentially) find binaries that reside in the working directory.
|
||||
sunshine_wenv[path_var_name].assign(start_dir + L";" + old_path_val);
|
||||
|
||||
// Restore the old PATH value for our process when we're done here
|
||||
auto restore_path = util::fail_guard([&]() {
|
||||
if (old_path_val.empty()) {
|
||||
sunshine_wenv[path_var_name].clear();
|
||||
}
|
||||
else {
|
||||
sunshine_wenv[path_var_name].assign(old_path_val);
|
||||
}
|
||||
});
|
||||
|
||||
BOOL ret;
|
||||
if (is_running_as_system()) {
|
||||
// Duplicate the current user's token
|
||||
HANDLE user_token = retrieve_users_token(elevated);
|
||||
if (!user_token) {
|
||||
// Fail the launch rather than risking launching with Sunshine's permissions unmodified.
|
||||
ec = std::make_error_code(std::errc::permission_denied);
|
||||
return bp::child();
|
||||
}
|
||||
|
||||
// Use RAII to ensure the shell token is closed when we're done with it
|
||||
auto token_close = util::fail_guard([user_token]() {
|
||||
CloseHandle(user_token);
|
||||
});
|
||||
|
||||
// Populate env with user-specific environment variables
|
||||
if (!merge_user_environment_block(cloned_env, user_token)) {
|
||||
ec = std::make_error_code(std::errc::not_enough_memory);
|
||||
return bp::child();
|
||||
}
|
||||
|
||||
// Open the process as the current user account, elevation is handled in the token itself.
|
||||
ec = impersonate_current_user(user_token, [&]() {
|
||||
std::wstring env_block = create_environment_block(cloned_env);
|
||||
std::wstring wcmd = resolve_command_string(cmd, start_dir, user_token, creation_flags);
|
||||
ret = CreateProcessAsUserW(user_token,
|
||||
NULL,
|
||||
(LPWSTR) wcmd.c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
!!(startup_info.StartupInfo.dwFlags & STARTF_USESTDHANDLES),
|
||||
creation_flags,
|
||||
env_block.data(),
|
||||
start_dir.empty() ? NULL : start_dir.c_str(),
|
||||
(LPSTARTUPINFOW) &startup_info,
|
||||
&process_info);
|
||||
});
|
||||
}
|
||||
// Otherwise, launch the process using CreateProcessW()
|
||||
// This will inherit the elevation of whatever the user launched Sunshine with.
|
||||
else {
|
||||
// Open our current token to resolve environment variables
|
||||
HANDLE process_token;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &process_token)) {
|
||||
ec = std::make_error_code(std::errc::permission_denied);
|
||||
return bp::child();
|
||||
}
|
||||
auto token_close = util::fail_guard([process_token]() {
|
||||
CloseHandle(process_token);
|
||||
});
|
||||
|
||||
// Populate env with user-specific environment variables
|
||||
if (!merge_user_environment_block(cloned_env, process_token)) {
|
||||
ec = std::make_error_code(std::errc::not_enough_memory);
|
||||
return bp::child();
|
||||
}
|
||||
|
||||
std::wstring env_block = create_environment_block(cloned_env);
|
||||
std::wstring wcmd = resolve_command_string(cmd, start_dir, NULL, creation_flags);
|
||||
ret = CreateProcessW(NULL,
|
||||
(LPWSTR) wcmd.c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
!!(startup_info.StartupInfo.dwFlags & STARTF_USESTDHANDLES),
|
||||
creation_flags,
|
||||
env_block.data(),
|
||||
start_dir.empty() ? NULL : start_dir.c_str(),
|
||||
(LPSTARTUPINFOW) &startup_info,
|
||||
&process_info);
|
||||
}
|
||||
|
||||
// Use the results of the launch to create a bp::child object
|
||||
return create_boost_child_from_results(ret, cmd, ec, process_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open a url in the default web browser.
|
||||
* @param url The url to open.
|
||||
*/
|
||||
void
|
||||
open_url(const std::string &url) {
|
||||
boost::process::environment _env = boost::this_process::environment();
|
||||
auto working_dir = boost::filesystem::path();
|
||||
std::error_code ec;
|
||||
|
||||
auto child = run_command(false, false, url, working_dir, _env, nullptr, ec, nullptr);
|
||||
if (ec) {
|
||||
BOOST_LOG(warning) << "Couldn't open url ["sv << url << "]: System: "sv << ec.message();
|
||||
}
|
||||
else {
|
||||
BOOST_LOG(info) << "Opened url ["sv << url << "]"sv;
|
||||
child.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
adjust_thread_priority(thread_priority_e priority) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user