File indexing completed on 2025-01-18 09:50:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_PROCESS_V2_WINDOWS_AS_USER_LAUNCHER_HPP
0012 #define BOOST_PROCESS_V2_WINDOWS_AS_USER_LAUNCHER_HPP
0013
0014 #include <boost/process/v2/detail/config.hpp>
0015 #include <boost/process/v2/windows/default_launcher.hpp>
0016
0017 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0018 namespace windows
0019 {
0020
0021
0022 struct as_user_launcher : default_launcher
0023 {
0024
0025 HANDLE token;
0026 as_user_launcher(HANDLE token = INVALID_HANDLE_VALUE) : token(token) {}
0027
0028 template<typename ExecutionContext, typename Args, typename ... Inits>
0029 auto operator()(ExecutionContext & context,
0030 const typename std::enable_if<std::is_convertible<
0031 ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
0032 filesystem::path >::type & executable,
0033 Args && args,
0034 Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
0035 {
0036 error_code ec;
0037 auto proc = (*this)(context, ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
0038
0039 if (ec)
0040 v2::detail::throw_error(ec, "as_user_launcher");
0041
0042 return proc;
0043 }
0044
0045
0046 template<typename ExecutionContext, typename Args, typename ... Inits>
0047 auto operator()(ExecutionContext & context,
0048 error_code & ec,
0049 const typename std::enable_if<std::is_convertible<
0050 ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
0051 filesystem::path >::type & executable,
0052 Args && args,
0053 Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
0054 {
0055 return (*this)(context.get_executor(), executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
0056 }
0057
0058 template<typename Executor, typename Args, typename ... Inits>
0059 auto operator()(Executor exec,
0060 const typename std::enable_if<
0061 BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
0062 BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
0063 filesystem::path >::type & executable,
0064 Args && args,
0065 Inits && ... inits ) -> basic_process<Executor>
0066 {
0067 error_code ec;
0068 auto proc = (*this)(std::move(exec), ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
0069
0070 if (ec)
0071 detail::throw_error(ec, "as_user_launcher");
0072
0073 return proc;
0074 }
0075
0076 template<typename Executor, typename Args, typename ... Inits>
0077 auto operator()(Executor exec,
0078 error_code & ec,
0079 const typename std::enable_if<
0080 BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
0081 BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
0082 filesystem::path >::type & executable,
0083 Args && args,
0084 Inits && ... inits ) -> basic_process<Executor>
0085 {
0086 auto command_line = this->build_command_line(executable, args);
0087
0088 ec = detail::on_setup(*this, executable, command_line, inits...);
0089 if (ec)
0090 {
0091 detail::on_error(*this, executable, command_line, ec, inits...);
0092 return basic_process<Executor>(exec);
0093 }
0094 auto ok = ::CreateProcessAsUserW(
0095 token,
0096 executable.empty() ? nullptr : executable.c_str(),
0097 command_line.empty() ? nullptr : &command_line.front(),
0098 process_attributes,
0099 thread_attributes,
0100 inherit_handles ? TRUE : FALSE,
0101 creation_flags,
0102 environment,
0103 current_directory.empty() ? nullptr : current_directory.c_str(),
0104 &startup_info.StartupInfo,
0105 &process_information);
0106
0107
0108 if (ok == 0)
0109 {
0110 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0111 detail::on_error(*this, executable, command_line, ec, inits...);
0112
0113 if (process_information.hProcess != INVALID_HANDLE_VALUE)
0114 ::CloseHandle(process_information.hProcess);
0115 if (process_information.hThread != INVALID_HANDLE_VALUE)
0116 ::CloseHandle(process_information.hThread);
0117
0118 return basic_process<Executor>(exec);
0119 } else
0120 {
0121 detail::on_success(*this, executable, command_line, inits...);
0122
0123 if (process_information.hThread != INVALID_HANDLE_VALUE)
0124 ::CloseHandle(process_information.hThread);
0125
0126 return basic_process<Executor>(exec,
0127 this->process_information.dwProcessId,
0128 this->process_information.hProcess);
0129 }
0130 }
0131 };
0132
0133 }
0134 BOOST_PROCESS_V2_END_NAMESPACE
0135
0136 #endif