Sunshine latest
Self-hosted game stream host for Moonlight.
misc.cpp File Reference

Miscellaneous definitions for Windows. More...

#include <csignal>
#include <filesystem>
#include <iomanip>
#include <iterator>
#include <set>
#include <sstream>
#include <boost/algorithm/string.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/process/v1.hpp>
#include <boost/program_options/parsers.hpp>
#include <dwmapi.h>
#include <iphlpapi.h>
#include <timeapi.h>
#include <userenv.h>
#include <winsock2.h>
#include <windows.h>
#include <winuser.h>
#include <wlanapi.h>
#include <ws2tcpip.h>
#include <wtsapi32.h>
#include <sddl.h>
#include <Shlwapi.h>
#include "misc.h"
#include "nvprefs/nvprefs_interface.h"
#include "src/entry_handler.h"
#include "src/globals.h"
#include "src/logging.h"
#include "src/platform/common.h"
#include "src/utility.h"
#include <qos2.h>
#include <winternl.h>
Include dependency graph for misc.cpp:

Classes

struct  platf::enum_wnd_context_t
 
class  platf::qos_t
 
class  platf::win32_high_precision_timer
 

Macros

#define NTDDI_VERSION   NTDDI_WIN10
 
#define PROC_THREAD_ATTRIBUTE_JOB_LIST   ProcThreadAttributeValue(13, FALSE, TRUE, FALSE)
 
#define UDP_SEND_MSG_SIZE   2
 
#define WLAN_API_MAKE_VERSION(_major, _minor)   (((DWORD) (_minor)) << 16 | (_major))
 

Typedefs

using platf::adapteraddrs_t = util::c_ptr<IP_ADAPTER_ADDRESSES>
 

Functions

void platf::adjust_thread_priority (thread_priority_e priority)
 
LPPROC_THREAD_ATTRIBUTE_LIST platf::allocate_proc_thread_attr_list (DWORD attribute_count)
 
std::filesystem::path platf::appdata ()
 Performs migration if necessary, then returns the appdata directory.
 
void platf::append_string_to_environment_block (wchar_t *env_block, int &offset, const std::wstring &wstr)
 
bp::child platf::create_boost_child_from_results (bool process_launched, const std::string &cmd, std::error_code &ec, PROCESS_INFORMATION &process_info)
 Create a bp::child object from the results of launching a process.
 
std::wstring platf::create_environment_block (bp::environment &env)
 
std::unique_ptr< high_precision_timerplatf::create_high_precision_timer ()
 Create platform-specific timer capable of high-precision sleep.
 
STARTUPINFOEXW platf::create_startup_info (FILE *file, HANDLE *job, std::error_code &ec)
 Create a STARTUPINFOEXW structure for launching a process.
 
std::unique_ptr< deinit_tplatf::enable_socket_qos (uintptr_t native_socket, boost::asio::ip::address &address, uint16_t port, qos_data_type_e data_type, bool dscp_tagging)
 Enable QoS on the given socket for traffic to the specified destination.
 
std::wstring platf::escape_argument (const std::wstring &argument)
 Quote/escape an argument according to the Windows parsing convention.
 
std::wstring platf::escape_argument_for_cmd (const std::wstring &argument)
 Escape an argument according to cmd's parsing convention.
 
void platf::free_proc_thread_attr_list (LPPROC_THREAD_ATTRIBUTE_LIST list)
 
std::string platf::from_sockaddr (const sockaddr *const)
 
std::pair< std::uint16_t, std::string > platf::from_sockaddr_ex (const sockaddr *const)
 
std::wstring platf::from_utf8 (const std::string &string)
 Convert a UTF-8 string into a UTF-16 wide string.
 
adapteraddrs_t platf::get_adapteraddrs ()
 
std::string platf::get_host_name ()
 Returns the current computer name in UTF-8.
 
std::string platf::get_mac_address (const std::string_view &address)
 
std::error_code platf::impersonate_current_user (HANDLE user_token, std::function< void()> callback)
 Impersonate the current user and invoke the callback function.
 
bool platf::is_running_as_system ()
 Check if the current process is running with system-level privileges.
 
bool platf::IsUserAdmin (HANDLE user_token)
 
bool platf::merge_user_environment_block (bp::environment &env, HANDLE shell_token)
 
NTSTATUS NTAPI NtSetTimerResolution (ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution)
 
void platf::open_url (const std::string &url)
 Open a url in the default web browser.
 
bool platf::override_per_user_predefined_keys (HANDLE token)
 This function overrides HKEY_CURRENT_USER and HKEY_CLASSES_ROOT using the provided token.
 
void platf::print_status (const std::string_view &prefix, HRESULT status)
 
bool platf::process_group_running (std::uintptr_t native_handle)
 Check if a process group still has running children.
 
int64_t platf::qpc_counter ()
 
std::chrono::nanoseconds platf::qpc_time_difference (int64_t performance_counter1, int64_t performance_counter2)
 
bool platf::request_process_group_exit (std::uintptr_t native_handle)
 Attempt to gracefully terminate a process group.
 
std::wstring platf::resolve_command_string (const std::string &raw_cmd, const std::wstring &working_dir, HANDLE token, DWORD &creation_flags)
 Resolve the given raw command into a proper command string for CreateProcess().
 
void platf::restart ()
 
void platf::restart_on_exit ()
 
HANDLE platf::retrieve_users_token (bool elevated)
 Obtain the current sessions user's primary token with elevated privileges.
 
bp::child platf::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)
 Run a command on the users profile.
 
bool platf::send (send_info_t &send_info)
 
bool platf::send_batch (batched_send_info_t &send_info)
 
int platf::set_env (const std::string &name, const std::string &value)
 Set an environment variable.
 
void platf::streaming_will_start ()
 
void platf::streaming_will_stop ()
 
HDESK platf::syncThreadDesktop ()
 
struct sockaddr_in platf::to_sockaddr (boost::asio::ip::address_v4 address, uint16_t port)
 
struct sockaddr_in6 platf::to_sockaddr (boost::asio::ip::address_v6 address, uint16_t port)
 
std::string platf::to_utf8 (const std::wstring &string)
 Convert a UTF-16 wide string into a UTF-8 string.
 
int platf::unset_env (const std::string &name)
 Unset an environment variable.
 

Variables

bool platf::enabled_mouse_keys = false
 
decltype(QOSAddSocketToFlow) * platf::fn_QOSAddSocketToFlow = nullptr
 
decltype(QOSCreateHandle) * platf::fn_QOSCreateHandle = nullptr
 
decltype(QOSRemoveSocketFromFlow) * platf::fn_QOSRemoveSocketFromFlow = nullptr
 
decltype(WlanCloseHandle) * platf::fn_WlanCloseHandle = nullptr
 
decltype(WlanEnumInterfaces) * platf::fn_WlanEnumInterfaces = nullptr
 
decltype(WlanFreeMemory) * platf::fn_WlanFreeMemory = nullptr
 
decltype(WlanOpenHandle) * platf::fn_WlanOpenHandle = nullptr
 
decltype(WlanSetInterface) * platf::fn_WlanSetInterface = nullptr
 
MOUSEKEYS platf::previous_mouse_keys_state
 
HANDLE platf::qos_handle = nullptr
 
HANDLE platf::wlan_handle = nullptr
 

Detailed Description

Miscellaneous definitions for Windows.

Function Documentation

◆ appdata()

std::filesystem::path platf::appdata ( )

Performs migration if necessary, then returns the appdata directory.

This is used for the log directory, so it cannot invoke Boost logging!

Returns
The path of the appdata directory that should be used.

◆ create_boost_child_from_results()

bp::child platf::create_boost_child_from_results ( bool process_launched,
const std::string & cmd,
std::error_code & ec,
PROCESS_INFORMATION & process_info )

Create a bp::child object from the results of launching a process.

Parameters
process_launchedA boolean indicating if the launch was successful.
cmdThe command that was used to launch the process.
ecA reference to an std::error_code object that will store any error that occurred during the launch.
process_infoA reference to a PROCESS_INFORMATION structure that contains information about the new process.
Returns
A bp::child object representing the new process, or an empty bp::child object if the launch failed.

◆ create_high_precision_timer()

std::unique_ptr< high_precision_timer > platf::create_high_precision_timer ( )

Create platform-specific timer capable of high-precision sleep.

Returns
A unique pointer to timer

◆ create_startup_info()

STARTUPINFOEXW platf::create_startup_info ( FILE * file,
HANDLE * job,
std::error_code & ec )

Create a STARTUPINFOEXW structure for launching a process.

Parameters
fileA pointer to a FILE object that will be used as the standard output and error for the new process, or null if not needed.
jobA job object handle to insert the new process into. This pointer must remain valid for the life of this startup info!
ecA reference to a std::error_code object that will store any error that occurred during the creation of the structure.
Returns
A structure that contains information about how to launch the new process.

◆ enable_socket_qos()

std::unique_ptr< deinit_t > platf::enable_socket_qos ( uintptr_t native_socket,
boost::asio::ip::address & address,
uint16_t port,
qos_data_type_e data_type,
bool dscp_tagging )

Enable QoS on the given socket for traffic to the specified destination.

Enables QoS on the given socket for traffic to the specified destination.

Parameters
native_socketThe native socket handle.
addressThe destination address for traffic sent on this socket.
portThe destination port for traffic sent on this socket.
data_typeThe type of traffic sent on this socket.
dscp_taggingSpecifies whether to enable DSCP tagging on outgoing traffic.

◆ escape_argument()

std::wstring platf::escape_argument ( const std::wstring & argument)

Quote/escape an argument according to the Windows parsing convention.

Parameters
argumentThe raw argument to process.
Returns
An argument string suitable for use by CreateProcess().

◆ escape_argument_for_cmd()

std::wstring platf::escape_argument_for_cmd ( const std::wstring & argument)

Escape an argument according to cmd's parsing convention.

Parameters
argumentAn argument already escaped by escape_argument().
Returns
An argument string suitable for use by cmd.exe.

◆ from_utf8()

std::wstring platf::from_utf8 ( const std::string & string)

Convert a UTF-8 string into a UTF-16 wide string.

Parameters
stringThe UTF-8 string.
Returns
The converted UTF-16 wide string.

◆ get_host_name()

std::string platf::get_host_name ( )

Returns the current computer name in UTF-8.

Returns
Computer name or a placeholder upon failure.

◆ impersonate_current_user()

std::error_code platf::impersonate_current_user ( HANDLE user_token,
std::function< void()> callback )

Impersonate the current user and invoke the callback function.

Parameters
user_tokenA handle to the user's token that was obtained from the shell.
callbackA function that will be executed while impersonating the user.
Returns
Object that will store any error that occurred during the impersonation

◆ is_running_as_system()

bool platf::is_running_as_system ( )

Check if the current process is running with system-level privileges.

Returns
true if the current process has system-level privileges, false otherwise.

◆ open_url()

void platf::open_url ( const std::string & url)

Open a url in the default web browser.

Parameters
urlThe url to open.

◆ override_per_user_predefined_keys()

bool platf::override_per_user_predefined_keys ( HANDLE token)

This function overrides HKEY_CURRENT_USER and HKEY_CLASSES_ROOT using the provided token.

Parameters
tokenThe primary token identifying the user to use, or NULL to restore original keys.
Returns
true if the override or restore operation was successful.

◆ process_group_running()

bool platf::process_group_running ( std::uintptr_t native_handle)

Check if a process group still has running children.

Parameters
native_handleThe native handle of the process group.
Returns
true if processes are still running.

◆ request_process_group_exit()

bool platf::request_process_group_exit ( std::uintptr_t native_handle)

Attempt to gracefully terminate a process group.

Parameters
native_handleThe native handle of the process group.
Returns
true if termination was successfully requested.

◆ resolve_command_string()

std::wstring platf::resolve_command_string ( const std::string & raw_cmd,
const std::wstring & working_dir,
HANDLE token,
DWORD & creation_flags )

Resolve the given raw command into a proper command string for CreateProcess().

This converts URLs and non-executable file paths into a runnable command like ShellExecute().

Parameters
raw_cmdThe raw command provided by the user.
working_dirThe working directory for the new process.
tokenThe user token currently being impersonated or NULL if running as ourselves.
creation_flagsThe creation flags for CreateProcess(), which may be modified by this function.
Returns
A command string suitable for use by CreateProcess().

◆ retrieve_users_token()

HANDLE platf::retrieve_users_token ( bool elevated)

Obtain the current sessions user's primary token with elevated privileges.

Returns
The user's token. If user has admin capability it will be elevated, otherwise it will be a limited token. On error, nullptr.

◆ run_command()

bp::child platf::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 )

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.

Parameters
elevatedSpecify whether to elevate the process.
interactiveSpecify whether this will run in a window or hidden.
cmdThe command to run.
working_dirThe working directory for the new process.
envThe environment variables to use for the new process.
fileA file object to redirect the child process's output to (may be nullptr).
ecAn error code, set to indicate any errors that occur during the launch process.
groupA pointer to a bp::group object to which the new process should belong (may be nullptr).
Returns
A bp::child object representing the new process, or an empty bp::child object if the launch fails.

◆ set_env()

int platf::set_env ( const std::string & name,
const std::string & value )

Set an environment variable.

Parameters
nameThe name of the environment variable.
valueThe value to set the environment variable to.
Returns
0 on success, non-zero on failure.

◆ to_utf8()

std::string platf::to_utf8 ( const std::wstring & string)

Convert a UTF-16 wide string into a UTF-8 string.

Parameters
stringThe UTF-16 wide string.
Returns
The converted UTF-8 string.

◆ unset_env()

int platf::unset_env ( const std::string & name)

Unset an environment variable.

Parameters
nameThe name of the environment variable.
Returns
0 on success, non-zero on failure.