⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nt_service.hpp

📁 j2me is based on j2mepolish, client & server for mobile application.
💻 HPP
📖 第 1 页 / 共 2 页
字号:

//         Copyright E骾n O'Callaghan 2008 - 2008.
// 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 NT_SERVICE_HPP_INCLUDED
#define NT_SERVICE_HPP_INCLUDED

#include "StdAfx.hpp"

#include "auxiliary/logger.hpp"

#include <boost/algorithm/string/case_conv.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/split_free.hpp>

#include "nt_service_exception.hpp"
#include "nt_service_control_manager.hpp"
#include "enum_services_sequence.hpp"

class nt_service : private boost::noncopyable
{
#if defined(UNICODE_) || defined(UNICODE)
	typedef std::wstring t_string;
#else
	typedef std::string t_string;
#endif

public:
	class service_settings
	{
		friend class nt_service;

	public:
		service_settings() :
			dwServiceType_(0),
			dwCurrentState_(SERVICE_NO_CHANGE),
			dwStartType_(SERVICE_NO_CHANGE),
			inherited_(false)
		{
			assert(is_inert());
		}

		service_settings(nt_service_control_manager::manager_settings_ptr manager, t_string lpServiceName) :
			manager_(manager),
			lpServiceName_(lpServiceName),
			dwServiceType_(0),
			dwCurrentState_(SERVICE_NO_CHANGE),
			dwStartType_(SERVICE_NO_CHANGE),
			inherited_(false)
		{
			boost::to_lower(lpServiceName_);
			assert(is_inert());
		}

		service_settings(const nt_service& svc, bool inherit_state=true, bool inherit_start_type=true) :
			manager_(svc.manager_->settings()),
			lpServiceName_(svc.lpServiceName_),
			dwServiceType_(0),
			dwCurrentState_(SERVICE_NO_CHANGE),
			dwStartType_(SERVICE_NO_CHANGE),
			inherited_(false)
		{
			boost::to_lower(lpServiceName_);
			assert(is_inert());

			if (inherit_state)
			{
				std::pair<DWORD, t_string> cs = svc.dwCurrentState();
				set_dwCurrentState(cs.first);
			}
			
			if (inherit_start_type)
			{
				std::pair<DWORD, t_string> st = svc.dwStartType();
				set_dwStartType(st.first);
			}
		}

		bool operator==(const service_settings& svc_s) const
		{
			return (lpServiceName_ == svc_s.lpServiceName_);
		}
		
		bool operator!=(const service_settings& svc_s) const
		{
			return !(*this == svc_s);
		}
		
		bool operator<(const service_settings& svc_s) const
		{
			return (lpServiceName_ < svc_s.lpServiceName_);
		}

		bool compare_state(const service_settings& svc_s) const
		{
			return (lpServiceName_ == svc_s.lpServiceName_ && 
				(dwServiceType_ == 0 || dwServiceType_ == svc_s.dwServiceType_) && 
				(dwCurrentState_ == SERVICE_NO_CHANGE || dwCurrentState_ == svc_s.dwCurrentState_) && 
				(dwStartType_ == SERVICE_NO_CHANGE || dwStartType_ == svc_s.dwStartType_) && 
				(!lpServiceStartName_ || lpServiceStartName_ == svc_s.lpServiceStartName_) && 
				(!lpBinaryPathName_ || lpBinaryPathName_ == svc_s.lpBinaryPathName_) && 
				(!lpDescription_ || lpDescription_ == svc_s.lpDescription_));
		}

		bool is_inert()
		{
			return (dwServiceType_ == 0 && 
				dwCurrentState_ == SERVICE_NO_CHANGE && 
				dwStartType_ == SERVICE_NO_CHANGE && 
				!lpServiceStartName_ && 
				!lpBinaryPathName_ && 
				!lpDescription_);
		}

		bool is_inherited() const { return inherited_; }

		void set_inherited(bool i=true) { inherited_ = i; }

		void set_dwCurrentState(DWORD CurrentState)
		{
			switch (CurrentState)
			{
			case SERVICE_STOPPED:
			case SERVICE_STOP_PENDING:
				dwCurrentState_ = SERVICE_STOPPED;
				break;
			case SERVICE_START_PENDING:
			case SERVICE_CONTINUE_PENDING:
			case SERVICE_RUNNING:
				dwCurrentState_ = SERVICE_RUNNING;
				break;
			case SERVICE_PAUSED:
			case SERVICE_PAUSE_PENDING:
				dwCurrentState_ = SERVICE_PAUSED;
				break;
			case SERVICE_NO_CHANGE:
			default:
				dwCurrentState_ = SERVICE_NO_CHANGE;		
			};
		}

		const t_string lpServiceName() const { return lpServiceName_; }

		DWORD dwCurrentState() const { return dwCurrentState_; }

		void set_dwStartType(DWORD StartType)
		{	
			dwStartType_ = StartType;
		}

		DWORD dwStartType() const { return dwStartType_; }

		nt_service_control_manager::manager_settings_ptr manager() { return manager_; }

		friend class boost::serialization::access;
		template<class Archive>
		void serialize(Archive & ar, const unsigned int version)
		{
			using boost::serialization::make_nvp;

			ar & make_nvp("manager", manager_);
			ar & make_nvp("service_name", lpServiceName_);
			boost::to_lower(lpServiceName_);
			
			ar & make_nvp("current_state", dwCurrentState_);			
			ar & make_nvp("start_type", dwStartType_);
		}

	private:
		nt_service_control_manager::manager_settings_ptr manager_;
		t_string lpServiceName_;

		DWORD dwServiceType_;
		DWORD dwCurrentState_;
		DWORD dwStartType_;

		boost::optional<t_string> lpServiceStartName_;
		boost::optional<t_string> lpBinaryPathName_;
		boost::optional<t_string> lpDescription_;

		bool inherited_;
	};

	friend class service_settings;

public:
	nt_service(nt_service_control_manager_ptr manager, LPCTSTR lpServiceName, DWORD dwDesiredAccess=SERVICE_ALL_ACCESS) :
		manager_(manager),
		dwDesiredAccess_(dwDesiredAccess)
	{
		if (lpServiceName) 
		{
			lpServiceName_ = lpServiceName;
			boost::to_lower(lpServiceName_);
		}

		aux::wlog() << L"Opening service...";
		handle_ = OpenService(*manager, lpServiceName, dwDesiredAccess);

		if (!handle_) throw_nt_service_exception(lpServiceName);

		aux::wlog() << L"...success.";
	}

	explicit nt_service(enum_services_sequence_item essi, DWORD dwDesiredAccess=SERVICE_ALL_ACCESS) :
		manager_(essi.manager_),
		dwDesiredAccess_(dwDesiredAccess)
	{
		if (essi.lpServiceName()) 
		{
			lpServiceName_ = essi.lpServiceName();
			boost::to_lower(lpServiceName_);
		}

		aux::wlog() << L"Opening service...";
		handle_ = OpenService(*essi.manager_, essi.lpServiceName(), dwDesiredAccess);

		if (!handle_) throw_nt_service_exception(essi.lpServiceName());

		aux::wlog() << L"...success.";
	}

	explicit nt_service(nt_service_control_manager_ptr manager, 
			const service_settings ss, DWORD dwDesiredAccess=SERVICE_ALL_ACCESS) :
		manager_(manager),
		dwDesiredAccess_(dwDesiredAccess)
	{
		lpServiceName_ = ss.lpServiceName();
		boost::to_lower(lpServiceName_);

		aux::wlog() << L"Opening service...";
		handle_ = OpenService(*manager_, lpServiceName_.c_str(), dwDesiredAccess);

		if (!handle_) throw_nt_service_exception(lpServiceName_.c_str());

		aux::wlog() << L"...success.";
	}

	~nt_service()
	{
		if (handle_) CloseServiceHandle(handle_);
	}

	bool operator==(const nt_service& nt_s) const
	{
		return (handle_ == nt_s.handle_ && lpServiceName_ == nt_s.lpServiceName_);
	}

	bool operator!=(const nt_service& nt_s) const
	{
		return !(*this == nt_s);
	}	

	bool operator<(const nt_service& nt_s) const
	{
		return (handle_ < nt_s.handle_);
	}

	bool matches_settings(const service_settings& svc_s) const
	{
		SERVICE_STATUS_PROCESS ssp = QueryServiceStatus();

		std::pair<DWORD, t_string> st = dwServiceType(&ssp);
		std::pair<DWORD, t_string> cs = dwCurrentState(&ssp);

		boost::shared_array<BYTE> qsc = QueryServiceConfig();

		std::pair<DWORD, t_string> stt = dwStartType(qsc);

		return (lpServiceName_ == svc_s.lpServiceName_ &&
			cs.first == svc_s.dwCurrentState_ &&
			stt.first == svc_s.dwStartType_);
	}
	
	t_string lpServiceName() const { return lpServiceName_; }

	t_string lpServiceDisplayName() const
	{
		DWORD BytesNeeded = 4096;
		boost::scoped_array<TCHAR> dis_name(new TCHAR[BytesNeeded]);

		BOOL result = ::GetServiceDisplayName(*manager_, (LPCTSTR)lpServiceName_.c_str(), dis_name.get(), & BytesNeeded);
		assert(result);

		return t_string(dis_name.get(), BytesNeeded+1);
	}	

	SERVICE_STATUS_PROCESS QueryServiceStatus() const
	{
		assert (dwDesiredAccess_ | SERVICE_QUERY_STATUS);

		SERVICE_STATUS_PROCESS ssp;
		DWORD BytesNeeded = 0;

		BOOL ret = QueryServiceStatusEx(handle_, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, 
			sizeof(SERVICE_STATUS_PROCESS), &BytesNeeded);

		assert(ret);
		return ssp;
	}

	boost::shared_array<BYTE> QueryServiceConfig() const
	{
		assert (dwDesiredAccess_ | SERVICE_QUERY_CONFIG);

		DWORD BytesNeeded = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -