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

📄 enum_services_sequence.hpp

📁 j2me is based on j2mepolish, client & server for mobile application.
💻 HPP
字号:

//         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)

// Written following STLSoft's listview_sequence.hpp as an example

#ifndef ENUM_SERVICES_ITERATOR_HPP_INCLUDED
#define ENUM_SERVICES_ITERATOR_HPP_INCLUDED

#include "StdAfx.hpp"
#include "nt_service_control_manager.hpp"

class nt_service;

class enum_services_sequence_item
{
public:
    enum_services_sequence_item(nt_service_control_manager_ptr manager, ENUM_SERVICE_STATUS_PROCESS ssp) : 
		manager_(manager),
		ssp_(ssp)
    {}

	LPTSTR lpServiceName() { return ssp_.lpServiceName; }

	LPTSTR lpDisplayName() { return ssp_.lpDisplayName; }

	friend class nt_service;

public:
	nt_service_control_manager_ptr manager_;
	ENUM_SERVICE_STATUS_PROCESS ssp_;
};

class enum_services_sequence
{
public:
    typedef enum_services_sequence_item  sequence_value_type;
    typedef sequence_value_type value_type;

    typedef size_t size_type;

    typedef enum_services_sequence sequence_class_type;

public:
    explicit enum_services_sequence(nt_service_control_manager_ptr manager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, 
			DWORD dwServiceState, LPCTSTR pszGroupName = NULL) : 
		manager_(manager),
		InfoLevel_(InfoLevel),
		dwServiceType_(dwServiceType),
		dwServiceState_(dwServiceState),
		pszGroupName_(pszGroupName)
    {}

public:
    /// const_iterator for the enum_services_sequence
    class const_iterator
    {
        typedef const_iterator class_type;
		typedef enum_services_sequence sequence_class_type;

    public:
        typedef sequence_value_type value_type;

		typedef ENUM_SERVICE_STATUS_PROCESS array_elems;
		typedef boost::shared_array<array_elems> array_type;
		enum { array_size = 16 };

    public:
        const_iterator() : 
			parent_sequence_(0),
			ssp_i_(-1),
			ssp_end_(-1),
			lpResumeHandle_(0)
        {}

		const_iterator(const sequence_class_type* parent_sequence, array_type ssp_array,
				size_t ssp_i=-1, size_t ssp_end=-1, DWORD lpResumeHandle=0) : 
			parent_sequence_(parent_sequence),
			ssp_array_(ssp_array),
			ssp_i_(ssp_i),
			ssp_end_(ssp_end),
			lpResumeHandle_(lpResumeHandle)
        {}

        const_iterator(class_type const& r) : 
			parent_sequence_(r.parent_sequence_),
			ssp_array_(r.ssp_array_),
			ssp_i_(r.ssp_i_),
			ssp_end_(r.ssp_end_),
			lpResumeHandle_(r.lpResumeHandle_)
        {}

        class_type& operator=(class_type const& r)
        { 
			parent_sequence_ = r.parent_sequence_;
			ssp_array_ = r.ssp_array_;
			ssp_i_ = r.ssp_i_;
			ssp_end_ = r.ssp_end_;
			lpResumeHandle_ = r.lpResumeHandle_;

            return *this;
        }

	// operators
    public:
        value_type operator*() const
		{
			assert(-1 != ssp_i_ && -1 != ssp_end_);

			return value_type(parent_sequence_->manager_, ssp_array_[ssp_i_]);
        }

        bool operator==(class_type const& r) const
        {
			assert(parent_sequence_ == r.parent_sequence_);

			if (ssp_i_ == -1 && r.ssp_i_ == -1)
				return true;
			else
				return (ssp_array_ == r.ssp_array_) && (ssp_i_ == r.ssp_i_) && 
					(ssp_end_ == r.ssp_end_) && (lpResumeHandle_ == r.lpResumeHandle_);
        }

        bool operator!=(class_type const& r) const
        {
			assert(parent_sequence_ == r.parent_sequence_);

            if (ssp_i_ == -1 && r.ssp_i_ == -1)
				return false;
			else
				return (ssp_array_ != r.ssp_array_) || (ssp_i_ != r.ssp_i_) ||  
				(ssp_end_ != r.ssp_end_) || (lpResumeHandle_ != r.lpResumeHandle_);
        }

		// pre-increment
        class_type& operator++()
        {
			assert(ssp_i_ < ssp_end_);

            ++ssp_i_;

			if (ssp_i_ == ssp_end_)
			{
				if (0 == lpResumeHandle_)
				{				
					ssp_end_ = -1;
					ssp_i_ = -1;
				}
				else
				{
					ssp_end_ = parent_sequence_->refill_array(ssp_array_, lpResumeHandle_);
					ssp_i_ = 0;
				}
			}

            return *this;
        }

		// post-increment
        class_type operator ++(int)
        {
            class_type  ret(*this);

            operator ++();

            return ret;
        }

    private:
		const sequence_class_type* parent_sequence_;

		mutable array_type ssp_array_;
		mutable size_t ssp_i_;
		mutable size_t ssp_end_;

		mutable DWORD lpResumeHandle_;
    };

// Iteration
public:
    const_iterator begin() const
    {
		const_iterator::array_type ssp_array( 
			new const_iterator::array_elems[const_iterator::array_size]);
		DWORD lpResumeHandle = 0;

		size_t ssp_end = refill_array(ssp_array, lpResumeHandle);

        return const_iterator(this, ssp_array, 0, ssp_end, lpResumeHandle);
    }

    const_iterator end() const
    {
        return const_iterator(this, const_iterator::array_type());
    }

private:
	size_t refill_array(const_iterator::array_type& ssp_array, DWORD& lpResumeHandle) const
	{	
		DWORD pcbBytesNeeded = 0;
		DWORD lpServicesReturned = 0;

		BOOL ret = EnumServicesStatusEx(*manager_, InfoLevel_, dwServiceType_, dwServiceState_, 
			(LPBYTE)&ssp_array[0], const_iterator::array_size*sizeof(const_iterator::array_type::element_type), 
			&pcbBytesNeeded, &lpServicesReturned, &lpResumeHandle, pszGroupName_);

		aux::wlog() << boost::wformat(L"ret %1%, pcbBytesNeeded %2%, lpServicesReturned %3%, lpResumeHandle %4%")
			% ret % pcbBytesNeeded % lpServicesReturned % lpResumeHandle;

		// Don't know what I'm doing wrong here but GetLastError never equals ERROR_MORE_DATA
		// so I can't test for actualy errors!!!
		// assert(0 != ret || GetLastError() == ERROR_MORE_DATA);

		return lpServicesReturned;
	}

	nt_service_control_manager_ptr manager_;
	SC_ENUM_TYPE InfoLevel_;
	DWORD dwServiceType_;
	DWORD dwServiceState_;
	LPCTSTR pszGroupName_;
};

#endif // ENUM_SERVICES_ITERATOR_HPP_INCLUDED

⌨️ 快捷键说明

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