123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- // Copyright (c) 2022 Klemens D. Morgenstern
- //
- // 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_DETAIL_IMPL_PROCESS_HANDLE_WINDOWS_IPP
- #define BOOST_PROCESS_V2_DETAIL_IMPL_PROCESS_HANDLE_WINDOWS_IPP
- #include <boost/process/v2/detail/config.hpp>
- #include <boost/process/v2/detail/last_error.hpp>
- #include <boost/process/v2/detail/throw_error.hpp>
- #include <boost/process/v2/detail/process_handle_windows.hpp>
- #include <boost/process/v2/ext/detail/proc_info.hpp>
- #include <windows.h>
- #if !defined(BOOST_PROCESS_V2_DISABLE_UNDOCUMENTED_API)
- extern "C"
- {
- LONG WINAPI NtResumeProcess(HANDLE ProcessHandle);
- LONG WINAPI NtSuspendProcess(HANDLE ProcessHandle);
- }
- #endif
- BOOST_PROCESS_V2_BEGIN_NAMESPACE
- namespace detail
- {
- void get_exit_code_(
- HANDLE handle,
- native_exit_code_type & exit_code,
- error_code & ec)
- {
- if (!::GetExitCodeProcess(handle, &exit_code))
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- }
- HANDLE open_process_(DWORD pid)
- {
- auto proc = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid);
- if (proc == nullptr)
- {
- error_code ec;
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- throw system_error(ec, "open_process()");
- }
- return proc;
- }
- void terminate_if_running_(HANDLE handle)
- {
- DWORD exit_code = 0u;
- if (handle == INVALID_HANDLE_VALUE)
- return ;
- if (::GetExitCodeProcess(handle, &exit_code))
- if (exit_code == STILL_ACTIVE)
- ::TerminateProcess(handle, 260);
- }
- bool check_handle_(HANDLE handle, error_code & ec)
- {
- if (handle == INVALID_HANDLE_VALUE)
- {
- BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_INVALID_HANDLE_STATE, system_category())
- return false;
- }
- return true;
- }
- bool check_pid_(pid_type pid_, error_code & ec)
- {
- if (pid_ == 0)
- {
- BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_INVALID_HANDLE_STATE, system_category())
- return false;
- }
- return true;
- }
- struct enum_windows_data_t
- {
- error_code &ec;
- pid_type pid;
- };
- static BOOL CALLBACK enum_window(HWND hwnd, LPARAM param)
- {
- auto data = reinterpret_cast<enum_windows_data_t*>(param);
- DWORD pid{0u};
- GetWindowThreadProcessId(hwnd, &pid);
- if (pid != data->pid)
- return TRUE;
-
- LRESULT res = ::SendMessageW(hwnd, WM_CLOSE, 0, 0);
- if (res)
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(data->ec)
- return res == 0;
- }
- void request_exit_(pid_type pid_, error_code & ec)
- {
- enum_windows_data_t data{ec, pid_};
- if (!::EnumWindows(enum_window, reinterpret_cast<LONG_PTR>(&data)))
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- }
- void interrupt_(pid_type pid_, error_code & ec)
- {
- if (!::GenerateConsoleCtrlEvent(CTRL_C_EVENT, pid_))
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- }
- void terminate_(HANDLE handle, error_code & ec, DWORD & exit_status)
- {
- if (!::TerminateProcess(handle, 260))
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- }
- void check_running_(HANDLE handle, error_code & ec, DWORD & exit_status)
- {
- if (!::GetExitCodeProcess(handle, &exit_status))
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- }
- #if !defined(BOOST_PROCESS_V2_DISABLE_UNDOCUMENTED_API)
- void suspend_(HANDLE handle, error_code & ec)
- {
- auto nt_err = NtSuspendProcess(handle);
- ULONG dos_err = RtlNtStatusToDosError(nt_err);
- if (dos_err)
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- }
- void resume_(HANDLE handle, error_code & ec)
- {
- auto nt_err = NtResumeProcess(handle);
- ULONG dos_err = RtlNtStatusToDosError(nt_err);
- if (dos_err)
- BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
- }
- #else
- void suspend_(HANDLE, error_code & ec)
- {
- BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_CALL_NOT_IMPLEMENTED, system_category())
- }
- void resume_(HANDLE handle, error_code & ec)
- {
- BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_CALL_NOT_IMPLEMENTED, system_category())
- }
- #endif
- #if !defined(BOOST_PROCESS_V2_HEADER_ONLY)
- template struct basic_process_handle_win<>;
- #endif
- }
- BOOST_PROCESS_V2_END_NAMESPACE
- #endif //BOOST_PROCESS_V2_DETAIL_IMPL_PROCESS_HANDLE_WINDOWS_IPP
|