Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:09

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 //BOOST_PROCESS_V2_DETAIL_IMPL_PROCESS_HANDLE_WINDOWS_IPP