CyberEngineMkIII
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
CYBWin32Process.cpp
1 #include "CYB.hpp"
2 
3 using namespace CYB::Platform::Win32;
4 
6  //Self terminating is actually safer than exiting due to locks and shit, also allows for us to kill ourselves and other processes in one line
7  //No FK32 because this can be called without Core
8  if(Sys::Call(Sys::TERMINATE_PROC, FHandle) == 0)
10 }
11 
12 //No FK32 because this can be called without Core
14  FHandle(reinterpret_cast<Win32::HANDLE>(System::Sys::Call(Sys::GET_CURRENT_PROCESS)))
15 {}
16 
18  FHandle(AMove.FHandle)
19 {
20  AMove.FHandle = nullptr;
21 }
22 
24  FHandle = AMove.FHandle;
25  AMove.FHandle = nullptr;
26  return *this;
27 }
28 
30  if(FHandle != nullptr)
31  Core().FModuleManager.Call<Modules::Kernel32::CloseHandle>(FHandle);
32 }
33 
35 
36  CYB::API::String::UTF16 ExeAs16(APath()), CmdlAs16(ACommandLine);
37  STARTUPINFO StartupInfo{ sizeof(STARTUPINFO), nullptr, nullptr, nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, 0, 0, 0};
38  PROCESS_INFORMATION ProcessInformation;
39  auto& MM(CYB::Core().FModuleManager);
40 
41  const auto Result(MM.Call<CYB::Platform::Modules::Kernel32::CreateProcessW>(ExeAs16.WString(), CmdlAs16.WideData(), nullptr, nullptr, FALSE, DWORD(0), nullptr, nullptr, &StartupInfo, &ProcessInformation));
42 
43  if (Result == 0)
44  switch (MM.Call<CYB::Platform::Modules::Kernel32::GetLastError>()) {
45  case ERROR_ACCESS_DENIED:
47  case ERROR_FILE_NOT_FOUND:
49  case ERROR_ELEVATION_REQUIRED:
50  //try again with elevation by using shell execute
51  {
52  SHELLEXECUTEINFO ShellExecuteInfo{ sizeof(SHELLEXECUTEINFO), SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS, nullptr, L"runas", ExeAs16.WString(), CmdlAs16.WString(), nullptr, SW_SHOWNORMAL, 0, nullptr, nullptr, 0 };
53  ShellExecuteInfo.hIcon = 0;
54  ShellExecuteInfo.hMonitor = 0;
55  ShellExecuteInfo.hProcess = 0;
56  const auto Result2(MM.Call<CYB::Platform::Modules::Shell::ShellExecuteExW>(&ShellExecuteInfo));
57  if (Result2 == TRUE) {
58  CYB::API::Assert::LessThan(reinterpret_cast<HINSTANCE>(32), ShellExecuteInfo.hInstApp);
59  CYB::API::Assert::NotEqual(ShellExecuteInfo.hProcess, static_cast<HANDLE>(nullptr));
60  return ShellExecuteInfo.hProcess;
61  }
62  }
63  default:
65  }
66 
67  MM.Call<CYB::Platform::Modules::Kernel32::CloseHandle>(ProcessInformation.hThread);
68  return ProcessInformation.hProcess;
69 }
70 
72  FHandle(CreateProcess(APath, ACommandLine))
73 {}
74 
75 bool CYB::Platform::System::Process::Active(void) const noexcept {
76  return Core().FModuleManager.Call<Modules::Kernel32::WaitForSingleObject>(FHandle, Win32::DWORD(0)) == WAIT_TIMEOUT;
77 }
78 
79 bool CYB::Platform::System::Process::operator==(const Process& ARHS) const noexcept {
80  if (Active() && ARHS.Active()) {
81  const auto Result(Core().FModuleManager.Call<Modules::Kernel32::GetProcessId>(FHandle));
82  if (Result != 0)
83  return Result == Core().FModuleManager.Call<Modules::Kernel32::GetProcessId>(ARHS.FHandle);
84  }
85  return false;
86 }
87 
88 bool CYB::Platform::System::Process::Wait(const unsigned int AMilliseconds) {
89  const auto Result(Core().FModuleManager.Call<Modules::Kernel32::WaitForSingleObject>(FHandle, AMilliseconds == 0 ? INFINITE : AMilliseconds));
90  API::Assert::NotEqual<decltype(Result)>(Result, WAIT_FAILED);
91  return Result == WAIT_OBJECT_0;
92 }
93 
95  Wait();
96  DWORD Result;
97  auto& MM(Core().FModuleManager);
98  if (MM.Call<Modules::Kernel32::GetExitCodeProcess>(FHandle, &Result) == 0) {
99  const auto ErrorCode(MM.Call<Modules::Kernel32::GetLastError>());
100  API::Assert::NotEqual<decltype(ErrorCode)>(ErrorCode, ERROR_INVALID_HANDLE);
102  }
103  return static_cast<int>(Result);
104 }
A variable length UTF-8 string.
Definition: UTF8String.hpp:8
Contains the Process handle and spawning function.
Process() noexcept
Get's the Process representing the current execution.
~Process()
Destroy the Process object without affecting the actual process.
bool operator==(const Process &ARHS) const noexcept
Check the equivalence of two Process objects.
static Win32::HANDLE CreateProcess(const System::Path &APath, const API::String::UTF8 &ACommandLine)
Spawn a process with the specified command line.
int GetExitCode(void)
Blocks execution until the associated Process is terminated and returns it's exit code...
void Terminate(void)
Terminates the Process with exit code 0.
Win32::HANDLE FHandle
The Process handle.
wchar_t * WideData(void) noexcept
Get the underlying wide char array.
UTF-16 String enabled only under windows.
Platform::Modules::Manager FModuleManager
Loads and contains required modules.
Definition: CYBCore.hpp:20
static void LessThan(const AType &ALHS, const AType &ARHS) noexcept
Less than assertion function. May not be evaluated.
A required file was not found in the filesystem.
Definition: Exception.hpp:71
static void NotEqual(const AType &ALHS, const AType &ARHS) noexcept
Unequivalence assertion function. May not be evaluated.
Exceptions caused by external call failures or invalid external data. Only classifies ones that can p...
Definition: Exception.hpp:65
Process & operator=(Process &&AMove) noexcept
See Default Constructors and Destructor.
Tried to check the error code of a Process the OS would not allow.
Definition: Exception.hpp:115
bool Active(void) const noexcept
Check if the Process is still running.
Process could not be terminated, most likely due to insufficient priviledges.
Definition: Exception.hpp:116
const wchar_t * WString(void) const noexcept
Get the underlying const wide char array.
Generic error for read failures. See functions for further documentation.
Definition: Exception.hpp:72
Precompiled header for inter-engine operations.
bool Wait(const unsigned int AMilliseconds=0U)
Blocks execution until the associated Process is terminated or a timer expires.
Engine::Core & Core(void) noexcept
Retrieve the Core singleton.
Definition: CYBCore.cpp:69
Used for manipulating Paths. Paths will always exist either as a file or directory. Paths are '/' delimited when forming though may not be while retrieving. File names ".." will ascend a directory and '.' represents a no-op.
Definition: CYBPath.hpp:10
Exceptions that are thrown internally in the engine that the should never see, these are a superset o...
Definition: Exception.hpp:104
auto Call(AArgs &&...AArguments)
Call a loaded function.
An object representing an operating system process.
Definition: CYBProcess.hpp:13
Process could not be created for unknown reasons.
Definition: Exception.hpp:114