with_logon_launcher.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //
  2. // boost/process/v2/windows/default_launcher.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2022 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_PROCESS_V2_WINDOWS_WITH_LOGON_LAUNCHER_HPP
  11. #define BOOST_PROCESS_V2_WINDOWS_WITH_LOGON_LAUNCHER_HPP
  12. #include <boost/process/v2/windows/default_launcher.hpp>
  13. BOOST_PROCESS_V2_BEGIN_NAMESPACE
  14. namespace windows
  15. {
  16. /// A windows launcher using CreateProcessWithLogon instead of CreateProcess
  17. struct with_logon_launcher : default_launcher
  18. {
  19. std::wstring username, password, domain;
  20. DWORD logon_flags{0u};
  21. with_logon_launcher(std::wstring username = L"",
  22. std::wstring password = L"",
  23. std::wstring domain = L"",
  24. DWORD logon_flags = 0u) :
  25. username(std::move(username)),
  26. password(std::move(password)),
  27. domain(std::move(domain)),
  28. logon_flags(logon_flags)
  29. {
  30. }
  31. template<typename ExecutionContext, typename Args, typename ... Inits>
  32. auto operator()(ExecutionContext & context,
  33. error_code & ec,
  34. const typename std::enable_if<std::is_convertible<
  35. ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
  36. filesystem::path >::type & executable,
  37. Args && args,
  38. Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
  39. {
  40. return (*this)(context.get_executor(), ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
  41. }
  42. template<typename ExecutionContext, typename Args, typename ... Inits>
  43. auto operator()(ExecutionContext & context,
  44. const typename std::enable_if<std::is_convertible<
  45. ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value,
  46. filesystem::path >::type & executable,
  47. Args && args,
  48. Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
  49. {
  50. return (*this)(context.get_executor(), executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
  51. }
  52. template<typename Executor, typename Args, typename ... Inits>
  53. auto operator()(Executor exec,
  54. const typename std::enable_if<
  55. BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
  56. BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
  57. filesystem::path >::type & executable,
  58. Args && args,
  59. Inits && ... inits ) -> basic_process<Executor>
  60. {
  61. error_code ec;
  62. auto proc = (*this)(std::move(exec), ec, executable, std::forward<Args>(args), std::forward<Inits>(inits)...);
  63. if (ec)
  64. v2::detail::throw_error(ec, "with_logon_launcher");
  65. return proc;
  66. }
  67. template<typename Executor, typename Args, typename ... Inits>
  68. auto operator()(Executor exec,
  69. error_code & ec,
  70. const typename std::enable_if<
  71. BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value ||
  72. BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value,
  73. filesystem::path >::type & executable,
  74. Args && args,
  75. Inits && ... inits ) -> basic_process<Executor>
  76. {
  77. auto command_line = this->build_command_line(executable, args);
  78. ec = detail::on_setup(*this, executable, command_line, inits...);
  79. if (ec)
  80. {
  81. detail::on_error(*this, executable, command_line, ec, inits...);
  82. return basic_process<Executor>(exec);
  83. }
  84. auto ok = ::CreateProcessWithLogonW(
  85. username.c_str(),
  86. domain.empty() ? nullptr : domain.c_str(),
  87. password.c_str(),
  88. logon_flags,
  89. executable.empty() ? nullptr : executable.c_str(),
  90. command_line.empty() ? nullptr : &command_line.front(),
  91. creation_flags,
  92. environment,
  93. current_directory.empty() ? nullptr : current_directory.c_str(),
  94. &startup_info.StartupInfo,
  95. &process_information);
  96. if (ok == 0)
  97. {
  98. BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
  99. detail::on_error(*this, executable, command_line, ec, inits...);
  100. if (process_information.hProcess != INVALID_HANDLE_VALUE)
  101. ::CloseHandle(process_information.hProcess);
  102. if (process_information.hThread != INVALID_HANDLE_VALUE)
  103. ::CloseHandle(process_information.hThread);
  104. return basic_process<Executor>(exec);
  105. } else
  106. {
  107. detail::on_success(*this, executable, command_line, inits...);
  108. if (process_information.hThread != INVALID_HANDLE_VALUE)
  109. ::CloseHandle(process_information.hThread);
  110. return basic_process<Executor>(exec,
  111. this->process_information.dwProcessId,
  112. this->process_information.hProcess);
  113. }
  114. }
  115. };
  116. }
  117. BOOST_PROCESS_V2_END_NAMESPACE
  118. #endif // BOOST_PROCESS_V2_WINDOWS_WITH_LOGON_LAUNCHER_HPP