// // boost/process/v2/windows/default_launcher.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2022 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_PROCESS_V2_WINDOWS_AS_USER_LAUNCHER_HPP #define BOOST_PROCESS_V2_WINDOWS_AS_USER_LAUNCHER_HPP #include <boost/process/v2/detail/config.hpp> #include <boost/process/v2/windows/default_launcher.hpp> BOOST_PROCESS_V2_BEGIN_NAMESPACE namespace windows { /// A windows launcher using CreateProcessAsUser instead of CreateProcess struct as_user_launcher : default_launcher { /// The token to be used in CreateProcessAsUser. HANDLE token; as_user_launcher(HANDLE token = INVALID_HANDLE_VALUE) : token(token) {} template<typename ExecutionContext, typename Args, typename ... Inits> auto operator()(ExecutionContext & context, const typename std::enable_if<std::is_convertible< ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, filesystem::path >::type & executable, Args && args, Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> { error_code ec; auto proc = (*this)(context, ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...); if (ec) v2::detail::throw_error(ec, "as_user_launcher"); return proc; } template<typename ExecutionContext, typename Args, typename ... Inits> auto operator()(ExecutionContext & context, error_code & ec, const typename std::enable_if<std::is_convertible< ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, filesystem::path >::type & executable, Args && args, Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> { return (*this)(context.get_executor(), ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...); } template<typename Executor, typename Args, typename ... Inits> auto operator()(Executor exec, const typename std::enable_if< BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, filesystem::path >::type & executable, Args && args, Inits && ... inits ) -> basic_process<Executor> { error_code ec; auto proc = (*this)(std::move(exec), ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...); if (ec) detail::throw_error(ec, "as_user_launcher"); return proc; } template<typename Executor, typename Args, typename ... Inits> auto operator()(Executor exec, error_code & ec, const typename std::enable_if< BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, filesystem::path >::type & executable, Args && args, Inits && ... inits ) -> basic_process<Executor> { auto command_line = this->build_command_line(executable, args); ec = detail::on_setup(*this, executable, command_line, inits...); if (ec) { detail::on_error(*this, executable, command_line, ec, inits...); return basic_process<Executor>(exec); } auto ok = ::CreateProcessAsUserW( token, executable.empty() ? nullptr : executable.c_str(), command_line.empty() ? nullptr : &command_line.front(), process_attributes, thread_attributes, inherit_handles ? TRUE : FALSE, creation_flags, environment, current_directory.empty() ? nullptr : current_directory.c_str(), &startup_info.StartupInfo, &process_information); if (ok == 0) { BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) detail::on_error(*this, executable, command_line, ec, inits...); if (process_information.hProcess != INVALID_HANDLE_VALUE) ::CloseHandle(process_information.hProcess); if (process_information.hThread != INVALID_HANDLE_VALUE) ::CloseHandle(process_information.hThread); return basic_process<Executor>(exec); } else { detail::on_success(*this, executable, command_line, inits...); if (process_information.hThread != INVALID_HANDLE_VALUE) ::CloseHandle(process_information.hThread); return basic_process<Executor>(exec, this->process_information.dwProcessId, this->process_information.hProcess); } } }; } BOOST_PROCESS_V2_END_NAMESPACE #endif // BOOST_PROCESS_V2_WINDOWS_AS_USER_LAUNCHER_HPP