📄 enum_services_sequence.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 + -