Compare commits

..

1 Commits

Author SHA1 Message Date
ReenigneArcher
5f390d2ea0 build(deps): use pre-compiled boost 2025-08-05 18:52:10 -04:00
52 changed files with 1723 additions and 403 deletions

View File

@@ -49,7 +49,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download build artifacts
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: build-*

View File

@@ -36,6 +36,8 @@ jobs:
include:
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories
# while GitHub has larger macOS runners, they are not available for our repos :(
- os_version: "13"
os_name: "macos"
- os_version: "14"
os_name: "macos"
- os_version: "15"

View File

@@ -56,7 +56,6 @@ jobs:
uses: LizardByte/.github/.github/workflows/__call-docker.yml@master
with:
maximize_build_space: true
maximize_build_space_root_reserve_size: 32768
publish_release: ${{ needs.release-setup.outputs.publish_release }}
release_commit: ${{ needs.release-setup.outputs.release_commit }}
release_tag: ${{ needs.release-setup.outputs.release_tag }}
@@ -137,6 +136,8 @@ jobs:
include:
- name: Linux-AppImage
coverage: true
- name: Homebrew-macos-13
coverage: false
- name: Homebrew-macos-14
coverage: false
- name: Homebrew-macos-15
@@ -150,7 +151,7 @@ jobs:
uses: actions/checkout@v4
- name: Download coverage artifact
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
name: coverage-${{ matrix.name }}
path: _coverage
@@ -191,7 +192,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download build artifacts
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: build-*
@@ -224,7 +225,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download homebrew artifacts
uses: actions/download-artifact@v5
uses: actions/download-artifact@v4
with:
name: beta-Homebrew
path: homebrew

View File

@@ -47,6 +47,10 @@ if(${END_BUILD})
return()
endif()
# CPM
include(${CMAKE_MODULE_PATH}/cpm/CPM.cmake)
CPMUsePackageLock(package-lock.cmake)
# project constants
include(${CMAKE_MODULE_PATH}/prep/constants.cmake)

View File

@@ -72,13 +72,13 @@ LizardByte has the full documentation hosted on [Read the Docs](https://docs.liz
<td>Windows: 10+ (Windows Server does not support virtual gamepads)</td>
</tr>
<tr>
<td>macOS: 14+</td>
<td>macOS: 13+</td>
</tr>
<tr>
<td>Linux/Debian: 13+ (trixie)</td>
<td>Linux/Debian: 12+ (bookworm)</td>
</tr>
<tr>
<td>Linux/Fedora: 41+</td>
<td>Linux/Fedora: 40+</td>
</tr>
<tr>
<td>Linux/Ubuntu: 22.04+ (jammy)</td>

View File

@@ -13,7 +13,7 @@ foreach(dir ${MACOS_LINK_DIRECTORIES})
endif()
endforeach()
if(NOT BOOST_USE_STATIC AND NOT FETCH_CONTENT_BOOST_USED)
if(NOT BOOST_USE_STATIC AND NOT CPM_BOOST_USED)
ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)
endif()

View File

1363
cmake/cpm/CPM.cmake Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,102 +1,101 @@
#
# Loads the boost library giving the priority to the system package first, with a fallback to FetchContent.
# Loads the boost library giving the following priority
# - LizardByte pre-built
# - System package
# - CPM/FetchContent
#
include_guard(GLOBAL)
set(BOOST_VERSION "1.87.0")
set(BOOST_COMPONENTS
filesystem
locale
log
program_options
system
)
# system is not used by Sunshine, but by Simple-Web-Server, added here for convenience
# algorithm, preprocessor, scope, and uuid are not used by Sunshine, but by libdisplaydevice, added here for convenience
if(WIN32)
list(APPEND BOOST_COMPONENTS
algorithm
preprocessor
scope
uuid
)
endif()
if(BOOST_USE_STATIC)
set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103
set(BOOST_PREPARED_BINARIES
"${CMAKE_SOURCE_DIR}/third-party/build-deps/dist/${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
# check if the directory exists
if(EXISTS "${BOOST_PREPARED_BINARIES}")
set(Boost_FOUND TRUE) # cmake-lint: disable=C0103
set(Boost_INCLUDE_DIRS # cmake-lint: disable=C0103
"$<BUILD_INTERFACE:${BOOST_PREPARED_BINARIES}/include/boost>")
file(GLOB Boost_LIBRARIES "${BOOST_PREPARED_BINARIES}/lib/libboost_*.a")
set(PREPARED_BOOST_USED TRUE)
# Create Boost::headers target
add_library(Boost::headers INTERFACE IMPORTED)
set_target_properties(Boost::headers PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BOOST_PREPARED_BINARIES}/include/boost"
)
else()
message(WARNING
"Boost pre-compiled binaries not found at ${BOOST_PREPARED_BINARIES}. \
Please consider contributing to the LizardByte/build-deps repository.")
endif()
endif()
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.30")
cmake_policy(SET CMP0167 NEW) # Get BoostConfig.cmake from upstream
endif()
find_package(Boost CONFIG ${BOOST_VERSION} EXACT COMPONENTS ${BOOST_COMPONENTS})
if(NOT Boost_FOUND)
message(STATUS "Boost v${BOOST_VERSION} package not found in the system. Falling back to FetchContent.")
include(FetchContent)
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
cmake_policy(SET CMP0135 NEW) # Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24
endif()
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.31.0")
cmake_policy(SET CMP0174 NEW) # Handle empty variables
endif()
# more components required for compiling boost targets
list(APPEND BOOST_COMPONENTS
asio
crc
format
process
property_tree)
set(BOOST_ENABLE_CMAKE ON)
# Limit boost to the required libraries only
set(BOOST_INCLUDE_LIBRARIES ${BOOST_COMPONENTS})
set(BOOST_URL "https://github.com/boostorg/boost/releases/download/boost-${BOOST_VERSION}/boost-${BOOST_VERSION}-cmake.tar.xz") # cmake-lint: disable=C0301
set(BOOST_HASH "SHA256=7da75f171837577a52bbf217e17f8ea576c7c246e4594d617bfde7fafd408be5")
if(CMAKE_VERSION VERSION_LESS "3.24.0")
FetchContent_Declare(
Boost
URL ${BOOST_URL}
URL_HASH ${BOOST_HASH}
)
elseif(APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.25.0")
# add SYSTEM to FetchContent_Declare, this fails on debian bookworm
FetchContent_Declare(
Boost
URL ${BOOST_URL}
URL_HASH ${BOOST_HASH}
SYSTEM # requires CMake 3.25+
OVERRIDE_FIND_PACKAGE # requires CMake 3.24+, but we have a macro to handle it for other versions
)
elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
FetchContent_Declare(
Boost
URL ${BOOST_URL}
URL_HASH ${BOOST_HASH}
OVERRIDE_FIND_PACKAGE # requires CMake 3.24+, but we have a macro to handle it for other versions
)
endif()
FetchContent_MakeAvailable(Boost)
set(FETCH_CONTENT_BOOST_USED TRUE)
set(Boost_FOUND TRUE) # cmake-lint: disable=C0103
set(Boost_INCLUDE_DIRS # cmake-lint: disable=C0103
"$<BUILD_INTERFACE:${Boost_SOURCE_DIR}/libs/headers/include>")
set(BOOST_COMPONENTS
filesystem
locale
log
program_options
system
)
# system is not used by Sunshine, but by Simple-Web-Server, added here for convenience
# algorithm, preprocessor, scope, and uuid are not used by Sunshine,
# but by libdisplaydevice, added here for convenience
if(WIN32)
# Windows build is failing to create .h file in this directory
file(MAKE_DIRECTORY ${Boost_BINARY_DIR}/libs/log/src/windows)
list(APPEND BOOST_COMPONENTS
algorithm
preprocessor
scope
uuid
)
endif()
set(Boost_LIBRARIES "") # cmake-lint: disable=C0103
foreach(component ${BOOST_COMPONENTS})
list(APPEND Boost_LIBRARIES "Boost::${component}")
endforeach()
if(BOOST_USE_STATIC)
set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103
endif()
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.30")
cmake_policy(SET CMP0167 NEW) # Get BoostConfig.cmake from upstream
endif()
find_package(Boost CONFIG ${BOOST_VERSION} EXACT COMPONENTS ${BOOST_COMPONENTS})
if(NOT Boost_FOUND)
message(STATUS "Boost v${BOOST_VERSION} package not found in the system. Falling back to CPM.")
CPMGetPackage(Boost)
# more components required for compiling boost targets
list(APPEND BOOST_COMPONENTS
asio
crc
format
process
property_tree)
set(BOOST_ENABLE_CMAKE ON) # Use experimental superproject to pull library dependencies recursively
set(BOOST_INCLUDE_LIBRARIES ${BOOST_COMPONENTS}) # Limit boost to the required libraries only
set(BOOST_SKIP_INSTALL_RULES ON) # do not install Boost libraries or headers
set(CPM_BOOST_USED TRUE)
set(Boost_FOUND TRUE) # cmake-lint: disable=C0103
set(Boost_INCLUDE_DIRS # cmake-lint: disable=C0103
"$<BUILD_INTERFACE:${Boost_SOURCE_DIR}/libs/headers/include>")
message(STATUS "Boost_BINARY_DIR: ${Boost_BINARY_DIR}")
message(STATUS "Boost_SOURCE_DIR: ${Boost_SOURCE_DIR}")
if(WIN32)
# Windows build is failing to create .h file in this directory
file(MAKE_DIRECTORY ${Boost_BINARY_DIR}/libs/log/src/windows)
endif()
add_subdirectory(${Boost_SOURCE_DIR} ${Boost_BINARY_DIR} SYSTEM)
set(Boost_LIBRARIES "") # cmake-lint: disable=C0103
foreach(component ${BOOST_COMPONENTS})
list(APPEND Boost_LIBRARIES "Boost::${component}")
endforeach()
endif()
endif()
message(STATUS "Boost include dirs: ${Boost_INCLUDE_DIRS}")

View File

@@ -18,7 +18,7 @@ endif()
macro(find_package) # cmake-lint: disable=C0103
string(TOLOWER "${ARGV0}" ARGV0_LOWER)
if(
(("${ARGV0_LOWER}" STREQUAL "boost") AND DEFINED FETCH_CONTENT_BOOST_USED) OR
(("${ARGV0_LOWER}" STREQUAL "boost") AND (DEFINED CPM_BOOST_USED OR DEFINED PREPARED_BOOST_USED)) OR
(("${ARGV0_LOWER}" STREQUAL "libevdev") AND DEFINED EXTERNAL_PROJECT_LIBEVDEV_USED)
)
# Do nothing, as the package has already been fetched

View File

@@ -20,6 +20,9 @@ option(SUNSHINE_ENABLE_TRAY "Enable system tray icon. This option will be ignore
option(SUNSHINE_SYSTEM_WAYLAND_PROTOCOLS "Use system installation of wayland-protocols rather than the submodule." OFF)
option(CPM_USE_LOCAL_PACKAGES "Try to use local packages instead of downloading them." OFF)
option(CPM_LOCAL_PACKAGES_ONLY "Only use local packages, do not download them." OFF)
if(APPLE)
option(BOOST_USE_STATIC "Use static boost libraries." OFF)
else()

View File

@@ -3,8 +3,8 @@
# platforms: linux/amd64
# platforms_pr: linux/amd64
# no-cache-filters: toolchain-base,toolchain
ARG BASE=debian
ARG TAG=trixie-slim
ARG BASE=ubuntu
ARG TAG=22.04
FROM ${BASE}:${TAG} AS toolchain-base
ENV DEBIAN_FRONTEND=noninteractive
@@ -25,11 +25,11 @@ set -e
apt-get update -y
apt-get install -y --no-install-recommends \
build-essential \
cmake=3.31.* \
cmake=3.22.* \
ca-certificates \
doxygen \
gcc=4:14.2.* \
g++=4:14.2.* \
gcc=4:11.2.* \
g++=4:11.2.* \
gdb \
git \
graphviz \
@@ -59,13 +59,20 @@ apt-get install -y --no-install-recommends \
xvfb
apt-get clean
rm -rf /var/lib/apt/lists/*
# Install Node
wget --max-redirect=0 -qO- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
source "$HOME/.nvm/nvm.sh"
nvm install node
nvm use node
nvm alias default node
_DEPS
# install cuda
WORKDIR /build/cuda
# versions: https://developer.nvidia.com/cuda-toolkit-archive
ENV CUDA_VERSION="12.9.1"
ENV CUDA_BUILD="575.57.08"
ENV CUDA_VERSION="11.8.0"
ENV CUDA_BUILD="520.61.05"
RUN <<_INSTALL_CUDA
#!/bin/bash
set -e
@@ -76,31 +83,18 @@ if [[ "${TARGETPLATFORM}" == 'linux/arm64' ]]; then
fi
url="${cuda_prefix}${CUDA_VERSION}/local_installers/cuda_${CUDA_VERSION}_${CUDA_BUILD}_linux${cuda_suffix}.run"
echo "cuda url: ${url}"
tmpfile="/tmp/cuda.run"
wget "$url" --progress=bar:force:noscroll --show-progress -O "$tmpfile"
chmod a+x "${tmpfile}"
"${tmpfile}" --silent --toolkit --toolkitpath=/usr/local --no-opengl-libs --no-man-page --no-drm
rm -f "${tmpfile}"
wget "$url" --progress=bar:force:noscroll -q --show-progress -O ./cuda.run
chmod a+x ./cuda.run
./cuda.run --silent --toolkit --toolkitpath=/usr/local --no-opengl-libs --no-man-page --no-drm
rm ./cuda.run
_INSTALL_CUDA
WORKDIR /
# install node
RUN <<_INSTALL_NODE
#!/bin/bash
set -e
wget --max-redirect=0 -qO- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
source "$HOME/.nvm/nvm.sh"
nvm install node
nvm use node
nvm alias default node
_INSTALL_NODE
WORKDIR /toolchain
# Create a shell script that starts Xvfb and then runs a shell
# Write a shell script that starts Xvfb and then runs a shell
RUN <<_ENTRYPOINT
#!/bin/bash
set -e
cat <<EOF > entrypoint.sh
cat <<EOF > /entrypoint.sh
#!/bin/bash
Xvfb ${DISPLAY} -screen 0 1024x768x24 &
if [ "\$#" -eq 0 ]; then
@@ -111,11 +105,11 @@ fi
EOF
# Make the script executable
chmod +x entrypoint.sh
chmod +x /entrypoint.sh
# Note about CLion
echo "ATTENTION: CLion will override the entrypoint, you can disable this in the toolchain settings"
_ENTRYPOINT
# Use the shell script as the entrypoint
ENTRYPOINT ["/toolchain/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -4,7 +4,7 @@
# platforms_pr: linux/amd64
# no-cache-filters: sunshine-base,artifacts,sunshine
ARG BASE=debian
ARG TAG=trixie
ARG TAG=bookworm
FROM ${BASE}:${TAG} AS sunshine-base
ENV DEBIAN_FRONTEND=noninteractive
@@ -32,7 +32,6 @@ RUN <<_BUILD
set -e
chmod +x ./scripts/linux_build.sh
./scripts/linux_build.sh \
--cuda-patches \
--publisher-name='LizardByte' \
--publisher-website='https://app.lizardbyte.dev' \
--publisher-issue-url='https://app.lizardbyte.dev/support' \

View File

@@ -35,8 +35,7 @@ chmod +x ./scripts/linux_build.sh
--publisher-name='LizardByte' \
--publisher-website='https://app.lizardbyte.dev' \
--publisher-issue-url='https://app.lizardbyte.dev/support' \
--sudo-off \
--ubuntu-test-repo
--sudo-off
apt-get clean
rm -rf /var/lib/apt/lists/*
_BUILD

View File

@@ -3,15 +3,6 @@ Sunshine binaries are built using [CMake](https://cmake.org) and requires `cmake
## Building Locally
### Compiler
It is recommended to use one of the following compilers:
| Compiler | Version |
|:------------|:--------|
| GCC | 13+ |
| Clang | 17+ |
| Apple Clang | 15+ |
### Dependencies
#### Linux
@@ -25,7 +16,7 @@ Sunshine requires CUDA Toolkit for NVFBC capture. There are two caveats to CUDA:
1. The version installed depends on the version of GCC.
2. The version of CUDA you use will determine compatibility with various GPU generations.
At the time of writing, the recommended version to use is CUDA ~12.9.
At the time of writing, the recommended version to use is CUDA ~11.8.
See [CUDA compatibility](https://docs.nvidia.com/deploy/cuda-compatibility/index.html) for more info.
@tip{To install older versions, select the appropriate run file based on your desired CUDA version and architecture

View File

@@ -31,7 +31,7 @@ See [Docker](../DOCKER_README.md) for more information.
CUDA is used for NVFBC capture.
@tip{See [CUDA GPUS](https://developer.nvidia.com/cuda-gpus) to cross-reference Compute Capability to your GPU.
The table below applies to packages provided by LizardByte. If you use an official LizardByte package, then you do not
The table below applies to packages provided by LizardByte. If you use an official LizardByte package then you do not
need to install CUDA.}
<table>
@@ -43,9 +43,9 @@ need to install CUDA.}
<th>Package</th>
</tr>
<tr>
<td rowspan="8">12.9.1</td>
<td rowspan="8">575.57.08</td>
<td rowspan="8">50;52;60;61;62;70;72;75;80;86;87;89;90</td>
<td rowspan="3">11.8.0</td>
<td rowspan="3">450.80.02</td>
<td rowspan="3">35;50;52;60;61;62;70;72;75;80;86;87;89;90</td>
<td>sunshine.AppImage</td>
</tr>
<tr>
@@ -55,18 +55,27 @@ need to install CUDA.}
<td>sunshine-ubuntu-24.04-{arch}.deb</td>
</tr>
<tr>
<td>sunshine-debian-trixie-{arch}.deb</td>
<td rowspan="1">12.0.0</td>
<td rowspan="1">525.60.13</td>
<td rowspan="5">50;52;60;61;62;70;72;75;80;86;87;89;90</td>
<td>sunshine-debian-bookworm-{arch}.deb</td>
</tr>
<tr>
<td rowspan="2">12.6.2</td>
<td rowspan="2">560.35.03</td>
<td>sunshine_{arch}.flatpak</td>
</tr>
<tr>
<td>Sunshine (copr - Fedora 41)</td>
</tr>
<tr>
<td rowspan="1">12.8.1</td>
<td rowspan="1">570.124.06</td>
<td>Sunshine (copr - Fedora 42)</td>
</tr>
<tr>
<td rowspan="1">12.9.1</td>
<td rowspan="1">575.57.08</td>
<td>sunshine.pkg.tar.zst</td>
</tr>
</table>
@@ -80,15 +89,13 @@ According to AppImageLint the supported distro matrix of the AppImage is below.
- ✔ Debian bookworm
- ✔ Debian trixie
- ✔ Debian sid
- ✔ Ubuntu plucky
- ✔ Ubuntu noble
- ✔ Ubuntu jammy
- ✖ Ubuntu focal
- ✖ Ubuntu bionic
- ✖ Ubuntu xenial
- ✖ Ubuntu trusty
-Rocky Linux 8
- ✖ Rocky Linux 9
-CentOS 7
##### Install
1. Download [sunshine.AppImage](https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine.AppImage)

20
package-lock.cmake Normal file
View File

@@ -0,0 +1,20 @@
# CPM Package Lock
# This file should be committed to version control
# The first argument of CPMDeclarePackage can be freely chosen and is used as argument in CPMGetPackage.
# The NAME argument should be package name that would also be used in a find_package call.
# Ideally, both are the same, which might not always be possible: https://github.com/cpm-cmake/CPM.cmake/issues/603
# This is needed to support CPM_USE_LOCAL_PACKAGES
# TODO: update dependencies with renovate
# https://joht.github.io/johtizen/automation/2022/08/03/keep-your-cpp-dependencies-up-to-date.html
# Boost
set(BOOST_VERSION 1.87.0)
CPMDeclarePackage(Boost
NAME Boost
VERSION ${BOOST_VERSION}
URL https://github.com/boostorg/boost/releases/download/boost-${BOOST_VERSION}/boost-${BOOST_VERSION}-cmake.tar.xz
URL_HASH SHA256=7da75f171837577a52bbf217e17f8ea576c7c246e4594d617bfde7fafd408be5
DOWNLOAD_ONLY YES # boost is a bit complicated so we handle it separately
)

View File

@@ -56,18 +56,18 @@ BuildRequires: which
BuildRequires: xorg-x11-server-Xvfb
# Conditional BuildRequires for cuda-gcc based on Fedora version
%if 0%{?fedora} <= 41
%if 0%{?fedora} >= 40 && 0%{?fedora} <= 41
BuildRequires: gcc13
BuildRequires: gcc13-c++
%global gcc_version 13
%global cuda_version 12.9.1
%global cuda_build 575.57.08
%global cuda_version 12.6.3
%global cuda_build 560.35.05
%elif %{?fedora} >= 42
BuildRequires: gcc14
BuildRequires: gcc14-c++
%global gcc_version 14
%global cuda_version 12.9.1
%global cuda_build 575.57.08
%global cuda_version 12.8.1
%global cuda_build 570.124.06
%endif
%global cuda_dir %{_builddir}/cuda
@@ -171,7 +171,7 @@ function install_cuda() {
--backup \
--directory="%{cuda_dir}" \
--verbose \
< "%{_builddir}/Sunshine/packaging/linux/patches/${architecture}/01-math_functions.patch"
< "%{_builddir}/Sunshine/packaging/linux/fedora/patches/f42/${architecture}/01-math_functions.patch"
fi
}

View File

@@ -19,8 +19,8 @@
"only-arches": [
"x86_64"
],
"url": "https://developer.download.nvidia.com/compute/cuda/12.9.1/local_installers/cuda_12.9.1_575.57.08_linux.run",
"sha256": "0f6d806ddd87230d2adbe8a6006a9d20144fdbda9de2d6acc677daa5d036417a",
"url": "https://developer.download.nvidia.com/compute/cuda/12.6.2/local_installers/cuda_12.6.2_560.35.03_linux.run",
"sha256": "3729a89cb58f7ca6a46719cff110d6292aec7577585a8d71340f0dbac54fb237",
"dest-filename": "cuda.run"
},
{
@@ -28,8 +28,8 @@
"only-arches": [
"aarch64"
],
"url": "https://developer.download.nvidia.com/compute/cuda/12.9.1/local_installers/cuda_12.9.1_575.57.08_linux_sbsa.run",
"sha256": "64f47ab791a76b6889702425e0755385f5fa216c5a9f061875c7deed5f08cdb6",
"url": "https://developer.download.nvidia.com/compute/cuda/12.6.2/local_installers/cuda_12.6.2_560.35.03_linux_sbsa.run",
"sha256": "2249408848b705c18b9eadfb5161b52e4e36fcc5753647329cce93db141e5466",
"dest-filename": "cuda.run"
}
]

View File

@@ -37,10 +37,6 @@ class @PROJECT_NAME@ < Formula
depends_on "opus"
depends_on "icu4c" => :recommended
on_macos do
depends_on xcode: ["15.3", :build]
end
on_linux do
depends_on "avahi"
depends_on "libayatana-appindicator"
@@ -63,16 +59,6 @@ class @PROJECT_NAME@ < Formula
depends_on "wayland"
end
fails_with :clang do
build 1400
cause "Requires C++23 support"
end
fails_with :gcc do
version "12" # fails with GCC 12.x and earlier
cause "Requires C++23 support"
end
def install
ENV["BRANCH"] = "@GITHUB_BRANCH@"
ENV["BUILD_VERSION"] = "@BUILD_VERSION@"

View File

@@ -3,7 +3,6 @@ set -e
# Default value for arguments
appimage_build=0
cuda_patches=0
num_processors=$(nproc)
publisher_name="Third Party Publisher"
publisher_website=""
@@ -29,7 +28,6 @@ Options:
-h, --help Display this help message.
-s, --sudo-off Disable sudo command.
--appimage-build Compile for AppImage, this will not create the AppImage, just the executable.
--cuda-patches Apply cuda patches.
--num-processors The number of processors to use for compilation. Default is the value of 'nproc'.
--publisher-name The name of the publisher (not developer) of the application.
--publisher-website The URL of the publisher's website.
@@ -57,9 +55,6 @@ while getopts ":hs-:" opt; do
appimage_build=1
skip_libva=1
;;
cuda-patches)
cuda_patches=1
;;
num-processors=*)
num_processors="${OPTARG#*=}"
;;
@@ -190,15 +185,7 @@ function add_debian_based_deps() {
fi
}
function add_test_ppa() {
if [ "$ubuntu_test_repo" == 1 ]; then
$package_install_command "software-properties-common"
${sudo_cmd} add-apt-repository ppa:ubuntu-toolchain-r/test -y
fi
}
function add_debian_deps() {
add_test_ppa
add_debian_based_deps
dependencies+=(
"libayatana-appindicator3-dev"
@@ -206,7 +193,11 @@ function add_debian_deps() {
}
function add_ubuntu_deps() {
add_test_ppa
if [ "$ubuntu_test_repo" == 1 ]; then
# allow newer gcc
${sudo_cmd} add-apt-repository ppa:ubuntu-toolchain-r/test -y
fi
add_debian_based_deps
dependencies+=(
"libappindicator3-dev"
@@ -307,24 +298,6 @@ function install_cuda() {
"${build_dir}/cuda.run" --silent --toolkit --toolkitpath="${build_dir}/cuda" --no-opengl-libs --no-man-page --no-drm
rm "${build_dir}/cuda.run"
nvcc_path="${build_dir}/cuda/bin/nvcc"
# run cuda patches
if [ "$cuda_patches" == 1 ]; then
echo "Applying CUDA patches"
local patch_dir="${script_dir}/../packaging/linux/patches/${architecture}"
if [ -d "$patch_dir" ]; then
for patch in "$patch_dir"/*.patch; do
echo "Applying patch: $patch"
patch -p2 \
--backup \
--directory="${build_dir}/cuda" \
--verbose \
< "$patch"
done
else
echo "No patches found for architecture: $architecture"
fi
fi
}
function check_version() {
@@ -563,26 +536,27 @@ elif grep -q "Debian GNU/Linux 12 (bookworm)" /etc/os-release; then
version="12"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
cuda_version="12.0.0"
cuda_build="525.60.13"
gcc_version="12"
nvm_node=0
elif grep -q "PLATFORM_ID=\"platform:f40\"" /etc/os-release; then
distro="fedora"
version="40"
package_update_command="${sudo_cmd} dnf update -y"
package_install_command="${sudo_cmd} dnf install -y"
cuda_version=12.6.3
cuda_build=560.35.05
gcc_version="13"
nvm_node=0
elif grep -q "Debian GNU/Linux 13 (trixie)" /etc/os-release; then
distro="debian"
version="13"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
gcc_version="14"
nvm_node=0
dev_tools_group="Development Tools"
elif grep -q "PLATFORM_ID=\"platform:f41\"" /etc/os-release; then
distro="fedora"
version="41"
package_update_command="${sudo_cmd} dnf update -y"
package_install_command="${sudo_cmd} dnf install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
cuda_version=12.6.3
cuda_build=560.35.05
gcc_version="13"
nvm_node=0
dev_tools_group="development-tools"
@@ -591,8 +565,8 @@ elif grep -q "PLATFORM_ID=\"platform:f42\"" /etc/os-release; then
version="42"
package_update_command="${sudo_cmd} dnf update -y"
package_install_command="${sudo_cmd} dnf install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
cuda_version=12.8.1
cuda_build=570.124.06
gcc_version="14"
nvm_node=0
dev_tools_group="development-tools"
@@ -601,27 +575,27 @@ elif grep -q "Ubuntu 22.04" /etc/os-release; then
version="22.04"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
gcc_version="13"
cuda_version="11.8.0"
cuda_build="520.61.05"
gcc_version="11"
nvm_node=1
elif grep -q "Ubuntu 24.04" /etc/os-release; then
distro="ubuntu"
version="24.04"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
gcc_version="14"
cuda_version="11.8.0"
cuda_build="520.61.05"
gcc_version="11"
nvm_node=0
elif grep -q "Ubuntu 25.04" /etc/os-release; then
distro="ubuntu"
version="25.04"
package_update_command="${sudo_cmd} apt-get update"
package_install_command="${sudo_cmd} apt-get install -y"
cuda_version="12.9.1"
cuda_build="575.57.08"
gcc_version="14"
cuda_version="11.8.0"
cuda_build="520.61.05"
gcc_version="11"
nvm_node=0
else
echo "Unsupported Distro or Version"

View File

@@ -1421,7 +1421,7 @@ namespace config {
if (!service_ctrl::is_service_running()) {
// If the service isn't running, relaunch ourselves as admin to start it
WCHAR executable[MAX_PATH];
GetModuleFileNameW(nullptr, executable, ARRAYSIZE(executable));
GetModuleFileNameW(NULL, executable, ARRAYSIZE(executable));
SHELLEXECUTEINFOW shell_exec_info {};
shell_exec_info.cbSize = sizeof(shell_exec_info);

View File

@@ -8,7 +8,6 @@
// standard includes
#include <filesystem>
#include <format>
#include <fstream>
#include <set>
@@ -714,7 +713,7 @@ namespace confighttp {
if (const int max_index = static_cast<int>(apps_node.size()) - 1; max_index < 0) {
error = "No applications to delete";
} else {
error = std::format("'index' {} out of range, max index is {}", index, max_index);
error = "'index' out of range, max index is "s + std::to_string(max_index);
}
bad_request(response, request, error);
return;
@@ -731,7 +730,7 @@ namespace confighttp {
proc::refresh(config::stream.file_apps);
output_tree["status"] = true;
output_tree["result"] = std::format("application {} deleted", index);
output_tree["result"] = "application " + std::to_string(index) + " deleted";
send_response(response, output_tree);
} catch (std::exception &e) {
BOOST_LOG(warning) << "DeleteApp: "sv << e.what();

View File

@@ -4,7 +4,6 @@
*/
// standard includes
#include <csignal>
#include <format>
#include <iostream>
#include <thread>
@@ -26,11 +25,13 @@ extern "C" {
using namespace std::literals;
void launch_ui(const std::optional<std::string> &path) {
std::string url = std::format("https://localhost:{}", static_cast<int>(net::map_port(confighttp::PORT_HTTPS)));
if (path) {
url += *path;
}
void launch_ui() {
std::string url = "https://localhost:" + std::to_string(net::map_port(confighttp::PORT_HTTPS));
platf::open_url(url);
}
void launch_ui_with_path(std::string path) {
std::string url = "https://localhost:" + std::to_string(net::map_port(confighttp::PORT_HTTPS)) + path;
platf::open_url(url);
}
@@ -191,8 +192,8 @@ namespace service_ctrl {
}
private:
SC_HANDLE scm_handle = nullptr;
SC_HANDLE service_handle = nullptr;
SC_HANDLE scm_handle = NULL;
SC_HANDLE service_handle = NULL;
};
bool is_service_running() {

View File

@@ -14,13 +14,19 @@
/**
* @brief Launch the Web UI.
* @param path Optional path to append to the base URL.
* @examples
* launch_ui();
* launch_ui("/pin");
* @examples_end
*/
void launch_ui(const std::optional<std::string> &path = std::nullopt);
void launch_ui();
/**
* @brief Launch the Web UI at a specific endpoint.
* @examples
* launch_ui_with_path("/pin");
* @examples_end
*/
void launch_ui_with_path(std::string path);
/**
* @brief Functions for handling command line arguments.

View File

@@ -186,7 +186,7 @@ int main(int argc, char *argv[]) {
wnd_class.lpszClassName = "SunshineSessionMonitorClass";
wnd_class.lpfnWndProc = SessionMonitorWindowProc;
if (!RegisterClassA(&wnd_class)) {
session_monitor_hwnd_promise.set_value(nullptr);
session_monitor_hwnd_promise.set_value(NULL);
BOOST_LOG(error) << "Failed to register session monitor window class"sv << std::endl;
return;
}

View File

@@ -5,9 +5,6 @@
// this include
#include "nvenc_base.h"
// standard includes
#include <format>
// local includes
#include "src/config.h"
#include "src/logging.h"
@@ -430,7 +427,7 @@ namespace nvenc {
extra += " two-pass";
}
if (config.vbv_percentage_increase > 0 && get_encoder_cap(NV_ENC_CAPS_SUPPORT_CUSTOM_VBV_BUF_SIZE)) {
extra += std::format(" vbv+{}", config.vbv_percentage_increase);
extra += " vbv+" + std::to_string(config.vbv_percentage_increase);
}
if (encoder_params.rfi) {
extra += " rfi";
@@ -442,7 +439,7 @@ namespace nvenc {
extra += " spatial-aq";
}
if (enc_config.rcParams.enableMinQP) {
extra += std::format(" qpmin={}", enc_config.rcParams.minQP.qpInterP);
extra += " qpmin=" + std::to_string(enc_config.rcParams.minQP.qpInterP);
}
if (config.insert_filler_data) {
extra += " filler-data";

View File

@@ -12,13 +12,13 @@ namespace nvenc {
nvenc_d3d11::nvenc_d3d11(NV_ENC_DEVICE_TYPE device_type):
nvenc_base(device_type) {
async_event_handle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
async_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
}
nvenc_d3d11::~nvenc_d3d11() {
if (dll) {
FreeLibrary(dll);
dll = nullptr;
dll = NULL;
}
if (async_event_handle) {
CloseHandle(async_event_handle);
@@ -36,7 +36,7 @@ namespace nvenc {
constexpr auto dll_name = "nvEncodeAPI.dll";
#endif
if ((dll = LoadLibraryEx(dll_name, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if ((dll = LoadLibraryEx(dll_name, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if (auto create_instance = (decltype(NvEncodeAPICreateInstance) *) GetProcAddress(dll, "NvEncodeAPICreateInstance")) {
auto new_nvenc = std::make_unique<NV_ENCODE_API_FUNCTION_LIST>();
new_nvenc->version = min_struct_version(NV_ENCODE_API_FUNCTION_LIST_VER);
@@ -55,7 +55,7 @@ namespace nvenc {
if (dll) {
FreeLibrary(dll);
dll = nullptr;
dll = NULL;
}
return false;

View File

@@ -39,7 +39,7 @@ namespace nvenc {
bool wait_for_async_event(uint32_t timeout_ms) override;
private:
HMODULE dll = nullptr;
HMODULE dll = NULL;
};
} // namespace nvenc

View File

@@ -63,7 +63,7 @@ namespace nvenc {
constexpr auto dll_name = "nvcuda.dll";
if ((cuda_functions.dll = LoadLibraryEx(dll_name, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if ((cuda_functions.dll = LoadLibraryEx(dll_name, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
auto load_function = [&]<typename T>(T &location, auto symbol) -> bool {
location = (T) GetProcAddress(cuda_functions.dll, symbol);
return location != nullptr;

View File

@@ -56,7 +56,7 @@ namespace nvenc {
autopop_context push_context();
HMODULE dll = nullptr;
HMODULE dll = NULL;
const ID3D11DevicePtr d3d_device;
ID3D11Texture2DPtr d3d_input_texture;

View File

@@ -7,7 +7,6 @@
// standard includes
#include <filesystem>
#include <format>
#include <string>
#include <utility>
@@ -155,7 +154,7 @@ namespace nvhttp {
std::string get_arg(const args_t &args, const char *name, const char *default_value = nullptr) {
auto it = args.find(name);
if (it == std::end(args)) {
if (default_value != nullptr) {
if (default_value != NULL) {
return std::string(default_value);
}
@@ -637,7 +636,7 @@ namespace nvhttp {
tree.put("root.<xmlattr>.status_code", 400);
tree.put(
"root.<xmlattr>.status_message",
std::format("Pin must be 4 digits, {} provided", pin.size())
"Pin must be 4 digits, " + std::to_string(pin.size()) + " provided"
);
return false;
}
@@ -897,15 +896,7 @@ namespace nvhttp {
}
tree.put("root.<xmlattr>.status_code", 200);
tree.put(
"root.sessionUrl0",
std::format(
"{}{}:{}",
launch_session->rtsp_url_scheme,
net::addr_to_url_escaped_string(request->local_endpoint().address()),
static_cast<int>(net::map_port(rtsp_stream::RTSP_SETUP_PORT))
)
);
tree.put("root.sessionUrl0", launch_session->rtsp_url_scheme + net::addr_to_url_escaped_string(request->local_endpoint().address()) + ':' + std::to_string(net::map_port(rtsp_stream::RTSP_SETUP_PORT)));
tree.put("root.gamesession", 1);
rtsp_stream::launch_session_raise(launch_session);
@@ -987,15 +978,7 @@ namespace nvhttp {
}
tree.put("root.<xmlattr>.status_code", 200);
tree.put(
"root.sessionUrl0",
std::format(
"{}{}:{}",
launch_session->rtsp_url_scheme,
net::addr_to_url_escaped_string(request->local_endpoint().address()),
static_cast<int>(net::map_port(rtsp_stream::RTSP_SETUP_PORT))
)
);
tree.put("root.sessionUrl0", launch_session->rtsp_url_scheme + net::addr_to_url_escaped_string(request->local_endpoint().address()) + ':' + std::to_string(net::map_port(rtsp_stream::RTSP_SETUP_PORT)));
tree.put("root.resume", 1);
rtsp_stream::launch_session_raise(launch_session);

View File

@@ -4,7 +4,6 @@
*/
// standard includes
#include <fcntl.h>
#include <format>
#include <sstream>
#include <string>
@@ -575,7 +574,7 @@ namespace va {
if (!display) {
char string[1024];
auto bytes = readlink(std::format("/proc/self/fd/{}", fd).c_str(), string, sizeof(string));
auto bytes = readlink(("/proc/self/fd/" + std::to_string(fd)).c_str(), string, sizeof(string));
std::string_view render_device {string, (std::size_t) bytes};

View File

@@ -4,9 +4,6 @@
*/
#define INITGUID
// standard includes
#include <format>
// platform includes
#include <Audioclient.h>
#include <avrt.h>
@@ -171,7 +168,8 @@ namespace {
waveformat.SubFormat == KSDATAFORMAT_SUBTYPE_PCM ? "S" :
"UNKNOWN";
result += std::format("{} {} ", static_cast<int>(waveformat.Samples.wValidBitsPerSample), static_cast<int>(waveformat.Format.nSamplesPerSec));
result += std::to_string(waveformat.Samples.wValidBitsPerSample) + " " +
std::to_string(waveformat.Format.nSamplesPerSec) + " ";
switch (waveformat.dwChannelMask) {
case waveformat_mask_stereo:
@@ -191,7 +189,7 @@ namespace {
break;
default:
result += std::format("{} channels (unrecognized)", static_cast<int>(waveformat.Format.nChannels));
result += std::to_string(waveformat.Format.nChannels) + " channels (unrecognized)";
break;
}
@@ -377,7 +375,7 @@ namespace platf::audio {
*ppvInterface = (IMMNotificationClient *) this;
return S_OK;
} else {
*ppvInterface = nullptr;
*ppvInterface = NULL;
return E_NOINTERFACE;
}
}
@@ -679,7 +677,7 @@ namespace platf::audio {
float *sample_buf_pos;
int channels;
HANDLE mmcss_task_handle = nullptr;
HANDLE mmcss_task_handle = NULL;
};
class audio_control_t: public ::platf::audio_control_t {

View File

@@ -601,12 +601,12 @@ namespace platf::dxgi {
LUID val;
if (OpenProcessToken(GetCurrentProcess(), flags, &token) &&
!!LookupPrivilegeValue(nullptr, SE_INC_BASE_PRIORITY_NAME, &val)) {
!!LookupPrivilegeValue(NULL, SE_INC_BASE_PRIORITY_NAME, &val)) {
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = val;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(tp), nullptr, nullptr)) {
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL, NULL)) {
BOOST_LOG(warning) << "Could not set privilege to increase GPU priority";
}
}
@@ -918,20 +918,20 @@ namespace platf::dxgi {
"DXGI_FORMAT_A8P8",
"DXGI_FORMAT_B4G4R4A4_UNORM",
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"DXGI_FORMAT_P208",
"DXGI_FORMAT_V208",

View File

@@ -1739,7 +1739,7 @@ namespace platf::dxgi {
img->data = nullptr;
if (img->encoder_texture_handle) {
CloseHandle(img->encoder_texture_handle);
img->encoder_texture_handle = nullptr;
img->encoder_texture_handle = NULL;
}
// Initialize format-dependent fields

View File

@@ -293,7 +293,7 @@ namespace platf {
if (gamepad.repeat_task) {
task_pool.cancel(gamepad.repeat_task);
gamepad.repeat_task = nullptr;
gamepad.repeat_task = 0;
}
if (gamepad.gp && vigem_target_is_attached(gamepad.gp.get())) {
@@ -1452,7 +1452,7 @@ namespace platf {
// Cancel any pending updates. We will requeue one here when we're finished.
if (gamepad.repeat_task) {
task_pool.cancel(gamepad.repeat_task);
gamepad.repeat_task = nullptr;
gamepad.repeat_task = 0;
}
if (gamepad.gp && vigem_target_is_attached(gamepad.gp.get())) {

View File

@@ -117,7 +117,7 @@ namespace platf {
std::filesystem::path appdata() {
WCHAR sunshine_path[MAX_PATH];
GetModuleFileNameW(nullptr, sunshine_path, _countof(sunshine_path));
GetModuleFileNameW(NULL, sunshine_path, _countof(sunshine_path));
return std::filesystem::path {sunshine_path}.remove_filename() / L"config"sv;
}
@@ -410,16 +410,16 @@ namespace platf {
LPPROC_THREAD_ATTRIBUTE_LIST allocate_proc_thread_attr_list(DWORD attribute_count) {
SIZE_T size;
InitializeProcThreadAttributeList(nullptr, attribute_count, 0, &size);
InitializeProcThreadAttributeList(NULL, attribute_count, 0, &size);
auto list = (LPPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), 0, size);
if (list == nullptr) {
return nullptr;
if (list == NULL) {
return NULL;
}
if (!InitializeProcThreadAttributeList(list, attribute_count, 0, &size)) {
HeapFree(GetProcessHeap(), 0, list);
return nullptr;
return NULL;
}
return list;
@@ -518,7 +518,7 @@ namespace platf {
// Allocate a process attribute list with space for 2 elements
startup_info.lpAttributeList = allocate_proc_thread_attr_list(2);
if (startup_info.lpAttributeList == nullptr) {
if (startup_info.lpAttributeList == NULL) {
// If the allocation failed, set ec to an appropriate error code and return the structure
ec = std::make_error_code(std::errc::not_enough_memory);
return startup_info;
@@ -530,7 +530,7 @@ namespace platf {
// Populate std handles if the caller gave us a log file to use
startup_info.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
startup_info.StartupInfo.hStdInput = nullptr;
startup_info.StartupInfo.hStdInput = NULL;
startup_info.StartupInfo.hStdOutput = log_file_handle;
startup_info.StartupInfo.hStdError = log_file_handle;
@@ -539,7 +539,7 @@ namespace platf {
//
// Note: The value we point to here must be valid for the lifetime of the attribute list,
// so we need to point into the STARTUPINFO instead of our log_file_variable on the stack.
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &startup_info.StartupInfo.hStdOutput, sizeof(startup_info.StartupInfo.hStdOutput), nullptr, nullptr);
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &startup_info.StartupInfo.hStdOutput, sizeof(startup_info.StartupInfo.hStdOutput), NULL, NULL);
}
if (job) {
@@ -547,7 +547,7 @@ namespace platf {
//
// Note: The value we point to here must be valid for the lifetime of the attribute list,
// so we take a HANDLE* instead of just a HANDLE to use the caller's stack storage.
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, job, sizeof(*job), nullptr, nullptr);
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, job, sizeof(*job), NULL, NULL);
}
return startup_info;
@@ -555,11 +555,11 @@ namespace platf {
/**
* @brief This function overrides HKEY_CURRENT_USER and HKEY_CLASSES_ROOT using the provided token.
* @param token The primary token identifying the user to use, or `nullptr` to restore original keys.
* @param token The primary token identifying the user to use, or `NULL` to restore original keys.
* @return `true` if the override or restore operation was successful.
*/
bool override_per_user_predefined_keys(HANDLE token) {
HKEY user_classes_root = nullptr;
HKEY user_classes_root = NULL;
if (token) {
auto err = RegOpenUserClassesRoot(token, 0, GENERIC_ALL, &user_classes_root);
if (err != ERROR_SUCCESS) {
@@ -573,14 +573,14 @@ namespace platf {
}
});
HKEY user_key = nullptr;
HKEY user_key = NULL;
if (token) {
impersonate_current_user(token, [&]() {
// RegOpenCurrentUser() doesn't take a token. It assumes we're impersonating the desired user.
auto err = RegOpenCurrentUser(GENERIC_ALL, &user_key);
if (err != ERROR_SUCCESS) {
BOOST_LOG(error) << "Failed to open user key for target user: "sv << err;
user_key = nullptr;
user_key = NULL;
}
});
if (!user_key) {
@@ -602,7 +602,7 @@ namespace platf {
err = RegOverridePredefKey(HKEY_CURRENT_USER, user_key);
if (err != ERROR_SUCCESS) {
BOOST_LOG(error) << "Failed to override HKEY_CURRENT_USER: "sv << err;
RegOverridePredefKey(HKEY_CLASSES_ROOT, nullptr);
RegOverridePredefKey(HKEY_CLASSES_ROOT, NULL);
return false;
}
@@ -671,7 +671,7 @@ namespace platf {
* @details This converts URLs and non-executable file paths into a runnable command like ShellExecute().
* @param raw_cmd The raw command provided by the user.
* @param working_dir The working directory for the new process.
* @param token The user token currently being impersonated or `nullptr` if running as ourselves.
* @param token The user token currently being impersonated or `NULL` if running as ourselves.
* @param creation_flags The creation flags for CreateProcess(), which may be modified by this function.
* @return A command string suitable for use by CreateProcess().
*/
@@ -757,7 +757,7 @@ namespace platf {
}
// Reset per-user keys back to the original value
override_per_user_predefined_keys(nullptr);
override_per_user_predefined_keys(NULL);
}
if (res != S_OK) {
@@ -972,7 +972,7 @@ namespace platf {
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, nullptr, (LPWSTR) wcmd.c_str(), nullptr, nullptr, !!(startup_info.StartupInfo.dwFlags & STARTF_USESTDHANDLES), creation_flags, env_block.data(), start_dir.empty() ? nullptr : start_dir.c_str(), (LPSTARTUPINFOW) &startup_info, &process_info);
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()
@@ -995,8 +995,8 @@ namespace platf {
}
std::wstring env_block = create_environment_block(cloned_env);
std::wstring wcmd = resolve_command_string(cmd, start_dir, nullptr, creation_flags);
ret = CreateProcessW(nullptr, (LPWSTR) wcmd.c_str(), nullptr, nullptr, !!(startup_info.StartupInfo.dwFlags & STARTF_USESTDHANDLES), creation_flags, env_block.data(), start_dir.empty() ? nullptr : start_dir.c_str(), (LPSTARTUPINFOW) &startup_info, &process_info);
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
@@ -1052,7 +1052,7 @@ namespace platf {
static std::once_flag load_wlanapi_once_flag;
std::call_once(load_wlanapi_once_flag, []() {
// wlanapi.dll is not installed by default on Windows Server, so we load it dynamically
HMODULE wlanapi = LoadLibraryExA("wlanapi.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
HMODULE wlanapi = LoadLibraryExA("wlanapi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!wlanapi) {
BOOST_LOG(debug) << "wlanapi.dll is not available on this OS"sv;
return;
@@ -1129,7 +1129,7 @@ namespace platf {
fn_WlanFreeMemory(wlan_interface_list);
} else {
fn_WlanCloseHandle(wlan_handle, nullptr);
wlan_handle = nullptr;
wlan_handle = NULL;
}
}
}
@@ -1200,7 +1200,7 @@ namespace platf {
startup_info.StartupInfo.cb = sizeof(startup_info);
WCHAR executable[MAX_PATH];
if (GetModuleFileNameW(nullptr, executable, ARRAYSIZE(executable)) == 0) {
if (GetModuleFileNameW(NULL, executable, ARRAYSIZE(executable)) == 0) {
auto winerr = GetLastError();
BOOST_LOG(fatal) << "Failed to get Sunshine path: "sv << winerr;
return;
@@ -1220,7 +1220,7 @@ namespace platf {
void restart() {
// If we're running standalone, we have to respawn ourselves via CreateProcess().
// If we're running from the service, we should just exit and let it respawn us.
if (GetConsoleWindow() != nullptr) {
if (GetConsoleWindow() != NULL) {
// Avoid racing with the new process by waiting until we're exiting to start it.
atexit(restart_on_exit);
}
@@ -1538,7 +1538,7 @@ namespace platf {
}
virtual ~qos_t() {
if (!fn_QOSRemoveSocketFromFlow(qos_handle, (SOCKET) nullptr, flow_id, 0)) {
if (!fn_QOSRemoveSocketFromFlow(qos_handle, (SOCKET) NULL, flow_id, 0)) {
auto winerr = GetLastError();
BOOST_LOG(warning) << "QOSRemoveSocketFromFlow() failed: "sv << winerr;
}
@@ -1570,7 +1570,7 @@ namespace platf {
static std::once_flag load_qwave_once_flag;
std::call_once(load_qwave_once_flag, []() {
// qWAVE is not installed by default on Windows Server, so we load it dynamically
HMODULE qwave = LoadLibraryExA("qwave.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
HMODULE qwave = LoadLibraryExA("qwave.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!qwave) {
BOOST_LOG(debug) << "qwave.dll is not available on this OS"sv;
return;
@@ -1788,11 +1788,11 @@ namespace platf {
}
operator bool() override {
return timer != nullptr;
return timer != NULL;
}
private:
HANDLE timer = nullptr;
HANDLE timer = NULL;
};
std::unique_ptr<high_precision_timer> create_high_precision_timer() {

View File

@@ -60,7 +60,7 @@ namespace nvprefs {
void driver_settings_t::destroy() {
if (session_handle) {
NvAPI_DRS_DestroySession(session_handle);
session_handle = nullptr;
session_handle = 0;
}
NvAPI_Unload();
}
@@ -105,7 +105,7 @@ namespace nvprefs {
if (swapchain_data) {
NvAPI_Status status;
NvDRSProfileHandle profile_handle = nullptr;
NvDRSProfileHandle profile_handle = 0;
status = NvAPI_DRS_GetBaseProfile(session_handle, &profile_handle);
if (status != NVAPI_OK) {
nvapi_error_message(status);
@@ -168,7 +168,7 @@ namespace nvprefs {
return true;
}
NvDRSProfileHandle profile_handle = nullptr;
NvDRSProfileHandle profile_handle = 0;
status = NvAPI_DRS_GetBaseProfile(session_handle, &profile_handle);
if (status != NVAPI_OK) {
nvapi_error_message(status);
@@ -224,7 +224,7 @@ namespace nvprefs {
NvAPI_UnicodeString profile_name = {};
fill_nvapi_string(profile_name, sunshine_application_profile_name);
NvDRSProfileHandle profile_handle = nullptr;
NvDRSProfileHandle profile_handle = 0;
status = NvAPI_DRS_FindProfileByName(session_handle, profile_name, &profile_handle);
if (status != NVAPI_OK) {

View File

@@ -36,7 +36,7 @@ namespace nvprefs {
bool check_and_modify_application_profile(bool &modified);
private:
NvDRSSessionHandle session_handle = nullptr;
NvDRSSessionHandle session_handle = 0;
};
} // namespace nvprefs

View File

@@ -15,7 +15,7 @@
namespace {
std::map<const char *, void *> interfaces;
HMODULE dll = nullptr;
HMODULE dll = NULL;
template<typename Func, typename... Args>
NvAPI_Status call_interface(const char *name, Args... args) {
@@ -47,7 +47,7 @@ NvAPI_Initialize() {
auto dll_name = "nvapi.dll";
#endif
if ((dll = LoadLibraryEx(dll_name, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if ((dll = LoadLibraryEx(dll_name, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32))) {
if (auto query_interface = (decltype(nvapi_QueryInterface) *) GetProcAddress(dll, "nvapi_QueryInterface")) {
for (const auto &item : nvapi_interface_table) {
interfaces[item.func] = query_interface(item.id);
@@ -64,7 +64,7 @@ NVAPI_INTERFACE NvAPI_Unload() {
if (dll) {
interfaces.clear();
FreeLibrary(dll);
dll = nullptr;
dll = NULL;
}
return NVAPI_OK;
}

View File

@@ -21,7 +21,7 @@ namespace nvprefs {
explicit operator bool() const {
auto handle = get();
return handle != nullptr && handle != INVALID_HANDLE_VALUE;
return handle != NULL && handle != INVALID_HANDLE_VALUE;
}
};

View File

@@ -51,7 +51,7 @@ namespace nvprefs {
std::optional<undo_file_t> undo_file_t::open_existing_file(std::filesystem::path file_path, bool &access_denied) {
undo_file_t file;
file.file_handle.reset(CreateFileW(file_path.c_str(), GENERIC_READ | DELETE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
file.file_handle.reset(CreateFileW(file_path.c_str(), GENERIC_READ | DELETE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
if (file.file_handle) {
access_denied = false;
return file;
@@ -64,7 +64,7 @@ namespace nvprefs {
std::optional<undo_file_t> undo_file_t::create_new_file(std::filesystem::path file_path) {
undo_file_t file;
file.file_handle.reset(CreateFileW(file_path.c_str(), GENERIC_WRITE | STANDARD_RIGHTS_ALL, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr));
file.file_handle.reset(CreateFileW(file_path.c_str(), GENERIC_WRITE | STANDARD_RIGHTS_ALL, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL));
if (file.file_handle) {
// give GENERIC_READ, GENERIC_WRITE and DELETE permissions to Users group

View File

@@ -12,7 +12,6 @@ extern "C" {
// standard includes
#include <array>
#include <cctype>
#include <format>
#include <set>
#include <unordered_map>
#include <utility>
@@ -865,7 +864,7 @@ namespace rtsp_stream {
session_option.next = &port_option;
// Moonlight merely requires 'server_port=<port>'
auto port_value = std::format("server_port={}", static_cast<int>(port));
auto port_value = "server_port=" + std::to_string(port);
port_option.option = const_cast<char *>("Transport");
port_option.content = port_value.data();

View File

@@ -84,7 +84,7 @@ namespace system_tray {
#ifdef _WIN32
// If we're running in a service, return a special status to
// tell it to terminate too, otherwise it will just respawn us.
if (GetConsoleWindow() == nullptr) {
if (GetConsoleWindow() == NULL) {
lifetime::exit_sunshine(ERROR_SHUTDOWN_IN_PROGRESS, true);
return;
}
@@ -230,10 +230,10 @@ namespace system_tray {
return;
}
tray.notification_title = nullptr;
tray.notification_text = nullptr;
tray.notification_cb = nullptr;
tray.notification_icon = nullptr;
tray.notification_title = NULL;
tray.notification_text = NULL;
tray.notification_cb = NULL;
tray.notification_icon = NULL;
tray.icon = TRAY_ICON_PLAYING;
tray_update(&tray);
tray.icon = TRAY_ICON_PLAYING;
@@ -251,10 +251,10 @@ namespace system_tray {
return;
}
tray.notification_title = nullptr;
tray.notification_text = nullptr;
tray.notification_cb = nullptr;
tray.notification_icon = nullptr;
tray.notification_title = NULL;
tray.notification_text = NULL;
tray.notification_cb = NULL;
tray.notification_icon = NULL;
tray.icon = TRAY_ICON_PAUSING;
tray_update(&tray);
char msg[256];
@@ -272,10 +272,10 @@ namespace system_tray {
return;
}
tray.notification_title = nullptr;
tray.notification_text = nullptr;
tray.notification_cb = nullptr;
tray.notification_icon = nullptr;
tray.notification_title = NULL;
tray.notification_text = NULL;
tray.notification_cb = NULL;
tray.notification_icon = NULL;
tray.icon = TRAY_ICON;
tray_update(&tray);
char msg[256];
@@ -293,10 +293,10 @@ namespace system_tray {
return;
}
tray.notification_title = nullptr;
tray.notification_text = nullptr;
tray.notification_cb = nullptr;
tray.notification_icon = nullptr;
tray.notification_title = NULL;
tray.notification_text = NULL;
tray.notification_cb = NULL;
tray.notification_icon = NULL;
tray.icon = TRAY_ICON;
tray_update(&tray);
tray.icon = TRAY_ICON;
@@ -305,7 +305,7 @@ namespace system_tray {
tray.notification_icon = TRAY_ICON_LOCKED;
tray.tooltip = PROJECT_NAME;
tray.notification_cb = []() {
launch_ui("/pin");
launch_ui_with_path("/pin");
};
tray_update(&tray);
}

View File

@@ -4,7 +4,6 @@
*/
#include "../tests_common.h"
#include <format>
#include <src/config.h>
#include <src/display_device.h>
#include <src/rtsp.h>
@@ -474,7 +473,7 @@ namespace {
} else {
const auto [manual_res] = std::get<manual_value_t<res_t>>(input_res);
video_config.dd.resolution_option = manual;
video_config.dd.manual_resolution = std::format("{}x{}", static_cast<int>(manual_res.m_width), static_cast<int>(manual_res.m_height));
video_config.dd.manual_resolution = std::to_string(manual_res.m_width) + "x"s + std::to_string(manual_res.m_height);
}
}

View File

@@ -4,7 +4,6 @@
*/
#include "../tests_common.h"
#include <format>
#include <src/file_handler.h>
struct FileHandlerParentDirectoryTest: testing::TestWithParam<std::tuple<std::string, std::string>> {};
@@ -80,13 +79,13 @@ Hey, hey, hey!
TEST_P(FileHandlerTests, WriteFileTest) {
auto [fileNum, content] = GetParam();
const std::string fileName = std::format("write_file_test_{}.txt", fileNum);
std::string fileName = "write_file_test_" + std::to_string(fileNum) + ".txt";
EXPECT_EQ(file_handler::write_file(fileName.c_str(), content), 0);
}
TEST_P(FileHandlerTests, ReadFileTest) {
auto [fileNum, content] = GetParam();
const std::string fileName = std::format("write_file_test_{}.txt", fileNum);
std::string fileName = "write_file_test_" + std::to_string(fileNum) + ".txt";
EXPECT_EQ(file_handler::read_file(fileName.c_str()), content);
}

View File

@@ -5,7 +5,6 @@
#include "../tests_common.h"
#include "../tests_log_checker.h"
#include <format>
#include <random>
#include <src/logging.h>
@@ -40,7 +39,7 @@ TEST_P(LogLevelsTest, PutMessage) {
std::random_device rand_dev;
std::mt19937_64 rand_gen(rand_dev());
auto test_message = std::format("{}{}", rand_gen(), rand_gen());
auto test_message = std::to_string(rand_gen()) + std::to_string(rand_gen());
BOOST_LOG(logger) << test_message;
ASSERT_TRUE(log_checker::line_contains(log_file, test_message));

View File

@@ -3,7 +3,6 @@
* @brief Handles launching Sunshine.exe into user sessions as SYSTEM
*/
#define WIN32_LEAN_AND_MEAN
#include <format>
#include <string>
#include <Windows.h>
#include <WtsApi32.h>
@@ -52,9 +51,9 @@ DWORD WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, L
}
HANDLE CreateJobObjectForChildProcess() {
HANDLE job_handle = CreateJobObjectW(nullptr, nullptr);
HANDLE job_handle = CreateJobObjectW(NULL, NULL);
if (!job_handle) {
return nullptr;
return NULL;
}
JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_limit_info = {};
@@ -69,7 +68,7 @@ HANDLE CreateJobObjectForChildProcess() {
if (!SetInformationJobObject(job_handle, JobObjectExtendedLimitInformation, &job_limit_info, sizeof(job_limit_info))) {
CloseHandle(job_handle);
return nullptr;
return NULL;
}
return job_handle;
@@ -77,16 +76,16 @@ HANDLE CreateJobObjectForChildProcess() {
LPPROC_THREAD_ATTRIBUTE_LIST AllocateProcThreadAttributeList(DWORD attribute_count) {
SIZE_T size;
InitializeProcThreadAttributeList(nullptr, attribute_count, 0, &size);
InitializeProcThreadAttributeList(NULL, attribute_count, 0, &size);
auto list = (LPPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), 0, size);
if (list == nullptr) {
return nullptr;
if (list == NULL) {
return NULL;
}
if (!InitializeProcThreadAttributeList(list, attribute_count, 0, &size)) {
HeapFree(GetProcessHeap(), 0, list);
return nullptr;
return NULL;
}
return list;
@@ -95,14 +94,14 @@ LPPROC_THREAD_ATTRIBUTE_LIST AllocateProcThreadAttributeList(DWORD attribute_cou
HANDLE DuplicateTokenForSession(DWORD console_session_id) {
HANDLE current_token;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &current_token)) {
return nullptr;
return NULL;
}
// Duplicate our own LocalSystem token
HANDLE new_token;
if (!DuplicateTokenEx(current_token, TOKEN_ALL_ACCESS, nullptr, SecurityImpersonation, TokenPrimary, &new_token)) {
if (!DuplicateTokenEx(current_token, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &new_token)) {
CloseHandle(current_token);
return nullptr;
return NULL;
}
CloseHandle(current_token);
@@ -110,7 +109,7 @@ HANDLE DuplicateTokenForSession(DWORD console_session_id) {
// Change the duplicated token to the console session ID
if (!SetTokenInformation(new_token, TokenSessionId, &console_session_id, sizeof(console_session_id))) {
CloseHandle(new_token);
return nullptr;
return NULL;
}
return new_token;
@@ -124,21 +123,21 @@ HANDLE OpenLogFileHandle() {
wcscat_s(log_file_name, L"sunshine.log");
// The file handle must be inheritable for our child process to use it
SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), nullptr, TRUE};
SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), NULL, TRUE};
// Overwrite the old sunshine.log
return CreateFileW(log_file_name, GENERIC_WRITE, FILE_SHARE_READ, &security_attributes, CREATE_ALWAYS, 0, nullptr);
return CreateFileW(log_file_name, GENERIC_WRITE, FILE_SHARE_READ, &security_attributes, CREATE_ALWAYS, 0, NULL);
}
bool RunTerminationHelper(HANDLE console_token, DWORD pid) {
WCHAR module_path[MAX_PATH];
GetModuleFileNameW(nullptr, module_path, _countof(module_path));
GetModuleFileNameW(NULL, module_path, _countof(module_path));
std::wstring command;
command += L'"';
command += module_path;
command += L'"';
command += std::format(L" --terminate {}", pid);
command += L" --terminate " + std::to_wstring(pid);
STARTUPINFOW startup_info = {};
startup_info.cb = sizeof(startup_info);
@@ -147,7 +146,7 @@ bool RunTerminationHelper(HANDLE console_token, DWORD pid) {
// Execute ourselves as a detached process in the user session with the --terminate argument.
// This will allow us to attach to Sunshine's console and send it a Ctrl-C event.
PROCESS_INFORMATION process_info;
if (!CreateProcessAsUserW(console_token, module_path, (LPWSTR) command.c_str(), nullptr, nullptr, FALSE, CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS, nullptr, nullptr, &startup_info, &process_info)) {
if (!CreateProcessAsUserW(console_token, module_path, (LPWSTR) command.c_str(), NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS, NULL, NULL, &startup_info, &process_info)) {
return false;
}
@@ -167,8 +166,8 @@ bool RunTerminationHelper(HANDLE console_token, DWORD pid) {
}
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
service_status_handle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, HandlerEx, nullptr);
if (service_status_handle == nullptr) {
service_status_handle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, HandlerEx, NULL);
if (service_status_handle == NULL) {
// Nothing we can really do here but terminate ourselves
ExitProcess(GetLastError());
return;
@@ -185,8 +184,8 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
SetServiceStatus(service_status_handle, &service_status);
// Create a manual-reset stop event
stop_event = CreateEventA(nullptr, TRUE, FALSE, nullptr);
if (stop_event == nullptr) {
stop_event = CreateEventA(NULL, TRUE, FALSE, NULL);
if (stop_event == NULL) {
// Tell SCM we failed to start
service_status.dwWin32ExitCode = GetLastError();
service_status.dwCurrentState = SERVICE_STOPPED;
@@ -195,8 +194,8 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
}
// Create an auto-reset session change event
session_change_event = CreateEventA(nullptr, FALSE, FALSE, nullptr);
if (session_change_event == nullptr) {
session_change_event = CreateEventA(NULL, FALSE, FALSE, NULL);
if (session_change_event == NULL) {
// Tell SCM we failed to start
service_status.dwWin32ExitCode = GetLastError();
service_status.dwCurrentState = SERVICE_STOPPED;
@@ -218,13 +217,13 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
startup_info.StartupInfo.cb = sizeof(startup_info);
startup_info.StartupInfo.lpDesktop = (LPWSTR) L"winsta0\\default";
startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
startup_info.StartupInfo.hStdInput = nullptr;
startup_info.StartupInfo.hStdInput = NULL;
startup_info.StartupInfo.hStdOutput = log_file_handle;
startup_info.StartupInfo.hStdError = log_file_handle;
// Allocate an attribute list with space for 2 entries
startup_info.lpAttributeList = AllocateProcThreadAttributeList(2);
if (startup_info.lpAttributeList == nullptr) {
if (startup_info.lpAttributeList == NULL) {
// Tell SCM we failed to start
service_status.dwWin32ExitCode = GetLastError();
service_status.dwCurrentState = SERVICE_STOPPED;
@@ -233,7 +232,7 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
}
// Only allow Sunshine.exe to inherit the log file handle, not all inheritable handles
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &log_file_handle, sizeof(log_file_handle), nullptr, nullptr);
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &log_file_handle, sizeof(log_file_handle), NULL, NULL);
// Tell SCM we're running (and stoppable now)
service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN | SERVICE_ACCEPT_SESSIONCHANGE;
@@ -249,22 +248,22 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {
}
auto console_token = DuplicateTokenForSession(console_session_id);
if (console_token == nullptr) {
if (console_token == NULL) {
continue;
}
// Job objects cannot span sessions, so we must create one for each process
auto job_handle = CreateJobObjectForChildProcess();
if (job_handle == nullptr) {
if (job_handle == NULL) {
CloseHandle(console_token);
continue;
}
// Start Sunshine.exe inside our job object
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, &job_handle, sizeof(job_handle), nullptr, nullptr);
UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, &job_handle, sizeof(job_handle), NULL, NULL);
PROCESS_INFORMATION process_info;
if (!CreateProcessAsUserW(console_token, L"Sunshine.exe", nullptr, nullptr, nullptr, TRUE, CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, nullptr, nullptr, (LPSTARTUPINFOW) &startup_info, &process_info)) {
if (!CreateProcessAsUserW(console_token, L"Sunshine.exe", NULL, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (LPSTARTUPINFOW) &startup_info, &process_info)) {
CloseHandle(console_token);
CloseHandle(job_handle);
continue;
@@ -327,7 +326,7 @@ int DoGracefulTermination(DWORD pid) {
}
// Disable our own Ctrl-C handling
SetConsoleCtrlHandler(nullptr, TRUE);
SetConsoleCtrlHandler(NULL, TRUE);
// Send a Ctrl-C event to Sunshine
if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)) {
@@ -340,7 +339,7 @@ int DoGracefulTermination(DWORD pid) {
int main(int argc, char *argv[]) {
static const SERVICE_TABLE_ENTRY service_table[] = {
{(LPSTR) SERVICE_NAME, ServiceMain},
{nullptr, nullptr}
{NULL, NULL}
};
// Check if this is a reinvocation of ourselves to send Ctrl-C to Sunshine.exe
@@ -352,7 +351,7 @@ int main(int argc, char *argv[]) {
// We want to use the directory where Sunshine.exe is located instead of system32.
// This requires stripping off 2 path components: the file name and the last folder
WCHAR module_path[MAX_PATH];
GetModuleFileNameW(nullptr, module_path, _countof(module_path));
GetModuleFileNameW(NULL, module_path, _countof(module_path));
for (auto i = 0; i < 2; i++) {
auto last_sep = wcsrchr(module_path, '\\');
if (last_sep) {