File indexing completed on 2025-01-18 09:50:09
0001
0002
0003
0004
0005 #ifndef BOOST_PROCESS_V2_DETAIL_IMPL_PROCESS_HANDLE_WINDOWS_IPP
0006 #define BOOST_PROCESS_V2_DETAIL_IMPL_PROCESS_HANDLE_WINDOWS_IPP
0007
0008 #include <boost/process/v2/detail/config.hpp>
0009 #include <boost/process/v2/detail/last_error.hpp>
0010 #include <boost/process/v2/detail/throw_error.hpp>
0011 #include <boost/process/v2/detail/process_handle_windows.hpp>
0012 #include <boost/process/v2/ext/detail/proc_info.hpp>
0013
0014 #include <windows.h>
0015
0016 #if !defined(BOOST_PROCESS_V2_DISABLE_UNDOCUMENTED_API)
0017 extern "C"
0018 {
0019
0020 LONG WINAPI NtResumeProcess(HANDLE ProcessHandle);
0021 LONG WINAPI NtSuspendProcess(HANDLE ProcessHandle);
0022
0023 }
0024 #endif
0025
0026 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0027
0028 namespace detail
0029 {
0030
0031 void get_exit_code_(
0032 HANDLE handle,
0033 native_exit_code_type & exit_code,
0034 error_code & ec)
0035 {
0036 if (!::GetExitCodeProcess(handle, &exit_code))
0037 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0038 }
0039
0040
0041 HANDLE open_process_(DWORD pid)
0042 {
0043 auto proc = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid);
0044 if (proc == nullptr)
0045 {
0046 error_code ec;
0047 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0048 throw system_error(ec, "open_process()");
0049 }
0050
0051 return proc;
0052 }
0053
0054
0055 void terminate_if_running_(HANDLE handle)
0056 {
0057 DWORD exit_code = 0u;
0058 if (handle == INVALID_HANDLE_VALUE)
0059 return ;
0060 if (::GetExitCodeProcess(handle, &exit_code))
0061 if (exit_code == STILL_ACTIVE)
0062 ::TerminateProcess(handle, 260);
0063 }
0064
0065 bool check_handle_(HANDLE handle, error_code & ec)
0066 {
0067 if (handle == INVALID_HANDLE_VALUE)
0068 {
0069 BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_INVALID_HANDLE_STATE, system_category())
0070 return false;
0071 }
0072 return true;
0073 }
0074
0075 bool check_pid_(pid_type pid_, error_code & ec)
0076 {
0077 if (pid_ == 0)
0078 {
0079 BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_INVALID_HANDLE_STATE, system_category())
0080 return false;
0081 }
0082 return true;
0083 }
0084
0085 struct enum_windows_data_t
0086 {
0087 error_code &ec;
0088 pid_type pid;
0089 };
0090
0091 static BOOL CALLBACK enum_window(HWND hwnd, LPARAM param)
0092 {
0093 auto data = reinterpret_cast<enum_windows_data_t*>(param);
0094 DWORD pid{0u};
0095 GetWindowThreadProcessId(hwnd, &pid);
0096 if (pid != data->pid)
0097 return TRUE;
0098
0099 LRESULT res = ::SendMessageW(hwnd, WM_CLOSE, 0, 0);
0100
0101 if (res)
0102 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(data->ec)
0103 return res == 0;
0104 }
0105
0106 void request_exit_(pid_type pid_, error_code & ec)
0107 {
0108 enum_windows_data_t data{ec, pid_};
0109
0110 if (!::EnumWindows(enum_window, reinterpret_cast<LONG_PTR>(&data)))
0111 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0112 }
0113
0114 void interrupt_(pid_type pid_, error_code & ec)
0115 {
0116 if (!::GenerateConsoleCtrlEvent(CTRL_C_EVENT, pid_))
0117 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0118 }
0119
0120 void terminate_(HANDLE handle, error_code & ec, DWORD & exit_status)
0121 {
0122 if (!::TerminateProcess(handle, 260))
0123 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0124 }
0125
0126 void check_running_(HANDLE handle, error_code & ec, DWORD & exit_status)
0127 {
0128 if (!::GetExitCodeProcess(handle, &exit_status))
0129 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0130 }
0131
0132 #if !defined(BOOST_PROCESS_V2_DISABLE_UNDOCUMENTED_API)
0133 void suspend_(HANDLE handle, error_code & ec)
0134 {
0135 auto nt_err = NtSuspendProcess(handle);
0136 ULONG dos_err = RtlNtStatusToDosError(nt_err);
0137 if (dos_err)
0138 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0139 }
0140
0141 void resume_(HANDLE handle, error_code & ec)
0142 {
0143 auto nt_err = NtResumeProcess(handle);
0144 ULONG dos_err = RtlNtStatusToDosError(nt_err);
0145 if (dos_err)
0146 BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
0147 }
0148 #else
0149 void suspend_(HANDLE, error_code & ec)
0150 {
0151 BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_CALL_NOT_IMPLEMENTED, system_category())
0152 }
0153
0154 void resume_(HANDLE handle, error_code & ec)
0155 {
0156 BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_CALL_NOT_IMPLEMENTED, system_category())
0157 }
0158 #endif
0159
0160 #if !defined(BOOST_PROCESS_V2_HEADER_ONLY)
0161 template struct basic_process_handle_win<>;
0162 #endif
0163
0164 }
0165
0166
0167 BOOST_PROCESS_V2_END_NAMESPACE
0168
0169 #endif