<commit_before>#pragma once

/*!
@copyright 2017 <NAME>
Distributed under the Apache Software License, Version 2.0.
(See accompanying file LICENSE.md or copy at http://www.apache.org/licenses/LICENSE-2.0)
*/

// Implementation header of distant::windows::kernel::process
#include <distant\windows\kernel\process.hpp>
#include <distant\windows\wait.hpp>


// 01312160
namespace distant::windows::kernel {

//public:
	//===========================//
	// Static process functions //
	//===========================//
	template <access_rights::process T>
	inline process<T> process<T>::get_current()
	{
		const auto native_handle = ::GetCurrentProcess();
		const auto pid = ::GetProcessId(native_handle);
		return process{ pid };
	}

//protected:
	// Type-safe version of OpenProcess
	template <access_rights::process T>
	inline typename process<T>::handle_type process<T>::open(pid_type id)
	{
		using flag_t = std::underlying_type_t<flag_type>;
	
		const auto result = ::OpenProcess(static_cast<flag_t>(T), false, id);
		return handle_type(result); // Returns windows::handle with result as value
	}

	template <access_rights::process T>
	inline typename process<T>::pid_type process<T>::get_pid(const handle_type& h)
	{
		const auto native_handle = expose::native_handle(h);
		const auto id = ::GetProcessId(native_handle);
		return static_cast<pid_type>(id);
	}

//public:
	//====================================//
	// Process id and access_rights flags //
	// accessors                          //
	//====================================//
	// Check if the process handle is valid
	template <access_rights::process T>
	inline bool process<T>::valid()  const
	{
		return this->weakly_valid() &&
			pid() != std::numeric_limits<pid_type>::infinity();
	}

	template <access_rights::process T>
	inline void process<T>::terminate() const
	{
		static_assert(
			check_permission(access_rights::terminate),
			"Invalid access_rights (process::terminate): "
			"Process must have terminate access right");

		if (!this->valid())
			//throw std::invalid_argument(this->format_gle());
		{
			this->set_last_error(ERROR_INVALID_HANDLE);
			return;
		}

		const unsigned int exit_code = 0;
		auto native_handle = expose::native_handle(m_handle);
		if (!::TerminateProcess(native_handle, exit_code))
			this->update_gle();
		else
			this->set_success();
		return;
	}

	// Check if we have permission to perform the given action
	template <access_rights::process T>
	inline constexpr bool process<T>::check_permission(flag_type access)
	{ 
		return (T & access) == access; 
	}

	template <access_rights::process T>
	inline bool process<T>::is_active() const
	{
		// Ensure we have the synchronize access_rights
		// This is required to call WaitForSingleObject
		static_assert(
			check_permission(access_rights::synchronize),
			"Invalid access rights (process::is_running): "
			"Process must have synchronize access right");

		using windows::wait;

		if (!this->valid())
			//throw std::invalid_argument(this->format_gle());
		{
			this->set_last_error(ERROR_INVALID_HANDLE);
			return false;
		}

		wait wait_for;

		// Return immediately
		const auto result = wait_for(*this, 0);
		this->update_gle(wait_for);
		return result == wait::state::timeout;
	}

	template <access_rights::process T>
	auto process<T>::name() const
	{
		const auto path = file_path();
		const auto start = path.find_last_of('\\'); // Get file name from directory string

		return path.substr(start + 1);
	}

	template <access_rights::process T>
	inline std::string process<T>::file_path() const
	{
		static_assert(
			check_permission(access_rights::query_information) ||
			check_permission(access_rights::query_limited_information),
			"Invalid access rights (process::file_path): "
			"Process must have query_information or query_limited_information access rights");

		if (!this->valid())
			//throw std::invalid_argument(this->format_gle());
		{
			this->set_last_error(ERROR_INVALID_HANDLE);
			return "";
		}

		const auto native_handle = expose::native_handle(m_handle);

		char out_path[MAX_PATH];
		DWORD max_path = MAX_PATH;

		// 0 indicates: The name should use the Win32 path format.
		if (!::QueryFullProcessImageNameA(native_handle, 0, out_path, &max_path))
			this->update_gle();
		else
			this->set_success();
		
		return { out_path };
	}

	template <access_rights::process T>
	inline auto process<T>::memory_status() const
	{
		return memory_status_t{ *this };
	}<commit_msg>Fix uninitialized string<commit_after>#pragma once

/*!
@copyright 2017 <NAME>
Distributed under the Apache Software License, Version 2.0.
(See accompanying file LICENSE.md or copy at http://www.apache.org/licenses/LICENSE-2.0)
*/

// Implementation header of distant::windows::kernel::process
#include <distant\windows\kernel\process.hpp>
#include <distant\windows\wait.hpp>


// 01312160
namespace distant::windows::kernel {

//public:
	//===========================//
	// Static process functions //
	//===========================//
	template <access_rights::process T>
	inline process<T> process<T>::get_current()
	{
		const auto native_handle = ::GetCurrentProcess();
		const auto pid = ::GetProcessId(native_handle);
		return process{ pid };
	}

//protected:
	// Type-safe version of OpenProcess
	template <access_rights::process T>
	inline typename process<T>::handle_type process<T>::open(pid_type id)
	{
		using flag_t = std::underlying_type_t<flag_type>;
	
		const auto result = ::OpenProcess(static_cast<flag_t>(T), false, id);
		return handle_type(result); // Returns windows::handle with result as value
	}

	template <access_rights::process T>
	inline typename process<T>::pid_type process<T>::get_pid(const handle_type& h)
	{
		const auto native_handle = expose::native_handle(h);
		const auto id = ::GetProcessId(native_handle);
		return static_cast<pid_type>(id);
	}

//public:
	//====================================//
	// Process id and access_rights flags //
	// accessors                          //
	//====================================//
	// Check if the process handle is valid
	template <access_rights::process T>
	inline bool process<T>::valid()  const
	{
		return this->weakly_valid() &&
			pid() != std::numeric_limits<pid_type>::infinity();
	}

	template <access_rights::process T>
	inline void process<T>::terminate() const
	{
		static_assert(
			check_permission(access_rights::terminate),
			"Invalid access_rights (process::terminate): "
			"Process must have terminate access right");

		if (!this->valid())
			//throw std::invalid_argument(this->format_gle());
		{
			this->set_last_error(ERROR_INVALID_HANDLE);
			return;
		}

		const unsigned int exit_code = 0;
		auto native_handle = expose::native_handle(m_handle);
		if (!::TerminateProcess(native_handle, exit_code))
			this->update_gle();
		else
			this->set_success();
		return;
	}

	// Check if we have permission to perform the given action
	template <access_rights::process T>
	inline constexpr bool process<T>::check_permission(flag_type access)
	{ 
		return (T & access) == access; 
	}

	template <access_rights::process T>
	inline bool process<T>::is_active() const
	{
		// Ensure we have the synchronize access_rights
		// This is required to call WaitForSingleObject
		static_assert(
			check_permission(access_rights::synchronize),
			"Invalid access rights (process::is_running): "
			"Process must have synchronize access right");

		using windows::wait;

		if (!this->valid())
			//throw std::invalid_argument(this->format_gle());
		{
			this->set_last_error(ERROR_INVALID_HANDLE);
			return false;
		}

		wait wait_for;

		// Return immediately
		const auto result = wait_for(*this, 0);
		this->update_gle(wait_for);
		return result == wait::state::timeout;
	}

	template <access_rights::process T>
	auto process<T>::name() const
	{
		const auto path = file_path();
		const auto start = path.find_last_of('\\'); // Get file name from directory string

		return path.substr(start + 1);
	}

	template <access_rights::process T>
	inline std::string process<T>::file_path() const
	{
		static_assert(
			check_permission(access_rights::query_information) ||
			check_permission(access_rights::query_limited_information),
			"Invalid access rights (process::file_path): "
			"Process must have query_information or query_limited_information access rights");

		if (!this->valid())
			//throw std::invalid_argument(this->format_gle());
		{
			this->set_last_error(ERROR_INVALID_HANDLE);
			return "";
		}

		const auto native_handle = expose::native_handle(m_handle);

		char out_path[MAX_PATH] = "";
		DWORD max_path = MAX_PATH;

		// 0 indicates: The name should use the Win32 path format.
		if (!::QueryFullProcessImageNameA(native_handle, 0, out_path, &max_path))
			this->update_gle();
		else
			this->set_success();
		
		return { out_path };
	}

	template <access_rights::process T>
	inline auto process<T>::memory_status() const
	{
		return memory_status_t{ *this };
	}
{'fraction_non_alphanumeric': 0.1558514208995301, 'fraction_numerical': 0.005146565227120161, 'mean_word_length': 4.6755555555555555, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6795150', 'n_tokens_mistral': 3030, 'n_tokens_neox': 2699, 'n_words': 664}