📄 nt_service.hpp
字号:
BOOL ret = ::QueryServiceConfig(handle_, 0,
0, &BytesNeeded);
assert (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
boost::shared_array<BYTE> qsc(new BYTE[BytesNeeded]);
ret = ::QueryServiceConfig(handle_, (LPQUERY_SERVICE_CONFIG)qsc.get(),
BytesNeeded, &BytesNeeded);
if (!ret) throw_nt_service_exception(lpServiceName_.c_str());
assert(ret);
return qsc;
}
std::pair<DWORD, t_string> dwServiceType(SERVICE_STATUS_PROCESS* ssp = 0) const
{
DWORD flags;
t_string str;
if (ssp)
flags = ssp->dwServiceType;
else
{
assert (dwDesiredAccess_ & SERVICE_QUERY_STATUS);
flags = QueryServiceStatus().dwServiceType;
}
if (flags & SERVICE_FILE_SYSTEM_DRIVER)
str = L"Filesystem Driver";
else if (flags & SERVICE_KERNEL_DRIVER)
str = L"Device Driver";
else if (flags & SERVICE_WIN32_OWN_PROCESS)
str = L"Standalone Service";
else if (flags & SERVICE_WIN32_SHARE_PROCESS)
str = L"Shared Process Service";
if (flags & SERVICE_INTERACTIVE_PROCESS)
str += L", interactive";
return std::make_pair(flags, str);
}
std::pair<DWORD, t_string> dwCurrentState(SERVICE_STATUS_PROCESS* ssp = 0) const
{
DWORD flags;
t_string str;
if (ssp)
flags = ssp->dwCurrentState;
else
{
assert (dwDesiredAccess_ & SERVICE_QUERY_STATUS);
flags = QueryServiceStatus().dwCurrentState;
}
return std::make_pair(flags, dwCurrentState_to_string(flags));
}
std::pair<DWORD, t_string> dwStartType(boost::shared_array<BYTE> qsc = boost::shared_array<BYTE>()) const
{
DWORD flags;
t_string str;
if (qsc)
flags = ((LPQUERY_SERVICE_CONFIG)qsc.get())->dwStartType;
else
{
assert (dwDesiredAccess_ & SERVICE_QUERY_CONFIG);
flags = ((LPQUERY_SERVICE_CONFIG)QueryServiceConfig().get())->dwStartType;
}
return std::make_pair(flags, dwStartType_to_string(flags));
}
t_string lpServiceStartName(boost::shared_array<BYTE> qsc = boost::shared_array<BYTE>()) const
{
if (qsc)
return t_string(((LPQUERY_SERVICE_CONFIG)qsc.get())->lpServiceStartName);
else
{
assert (dwDesiredAccess_ & SERVICE_QUERY_CONFIG);
return t_string(((LPQUERY_SERVICE_CONFIG)QueryServiceConfig().get())->lpServiceStartName);
}
}
t_string lpBinaryPathName(boost::shared_array<BYTE> qsc = boost::shared_array<BYTE>()) const
{
if (qsc)
return t_string(((LPQUERY_SERVICE_CONFIG)qsc.get())->lpBinaryPathName);
else
{
assert (dwDesiredAccess_ & SERVICE_QUERY_CONFIG);
return t_string(((LPQUERY_SERVICE_CONFIG)QueryServiceConfig().get())->lpBinaryPathName);
}
}
t_string lpDescription() const
{
assert (dwDesiredAccess_ | SERVICE_QUERY_CONFIG);
DWORD BytesNeeded = 0;
BOOL ret = ::QueryServiceConfig2(handle_, SERVICE_CONFIG_DESCRIPTION, 0,
0, &BytesNeeded);
assert (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
boost::shared_array<BYTE> qsc(new BYTE[BytesNeeded]);
ret = ::QueryServiceConfig2(handle_, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)qsc.get(),
BytesNeeded, &BytesNeeded);
if (!ret) throw_nt_service_exception(lpServiceName_.c_str());
if ((DWORD)*qsc.get() != 0)
return t_string(((LPSERVICE_DESCRIPTION)qsc.get())->lpDescription);
else
return t_string();
}
bool ApplySettings(const service_settings& svc_s)
{
BOOL result = true;
std::pair<DWORD, t_string> st = dwStartType();
if (st.first != svc_s.dwStartType_)
{
if (!(dwDesiredAccess_ & SERVICE_CHANGE_CONFIG))
aquire_permission(SERVICE_CHANGE_CONFIG);
result = ::ChangeServiceConfig(handle_, SERVICE_NO_CHANGE, svc_s.dwStartType_, SERVICE_NO_CHANGE,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (!result) throw_nt_service_exception(lpServiceName_.c_str());
}
std::pair<DWORD, t_string> cs = dwCurrentState();
switch (svc_s.dwCurrentState_)
{
case SERVICE_RUNNING:
result = Start();
break;
case SERVICE_STOPPED:
result = Stop();
break;
case SERVICE_PAUSED:
result = Pause();
break;
}
return result ? true : false;
}
BOOL Start()
{
aux::wlog() << L"Service start requested";
std::pair<DWORD, t_string> cs = dwCurrentState();
if (cs.first == SERVICE_RUNNING ||
cs.first == SERVICE_START_PENDING ||
cs.first == SERVICE_CONTINUE_PENDING)
{
aux::wlog() << L"Already started";
return true;
}
if (!(dwDesiredAccess_ & SERVICE_START))
aquire_permission(SERVICE_START);
aux::wlog() << L"Making start request...";
BOOL result = ::StartService(handle_, NULL, NULL);
aux::wlog() << boost::wformat(L"... request %1%") % (result ? L"succeeded" : L"failed");
if (!result) throw_nt_service_exception(lpServiceName_.c_str());
return result;
}
BOOL Stop()
{
aux::wlog() << L"Service stop requested";
std::pair<DWORD, t_string> cs = dwCurrentState();
if (cs.first == SERVICE_STOPPED ||
cs.first == SERVICE_STOP_PENDING)
{
aux::wlog() << L"Already stopped";
return true;
}
if (!(dwDesiredAccess_ & SERVICE_STOP))
aquire_permission(SERVICE_STOP);
aux::wlog() << L"Making stop request...";
SERVICE_STATUS ss;
BOOL result = ::ControlService(handle_, SERVICE_CONTROL_STOP, &ss);
aux::wlog() << boost::wformat(L"... request %1%") % (result ? L"succeeded" : L"failed");
if (!result) throw_nt_service_exception(lpServiceName_.c_str());
return result;
}
BOOL Pause()
{
aux::wlog() << L"Service pause requested";
std::pair<DWORD, t_string> cs = dwCurrentState();
if (cs.first == SERVICE_PAUSED ||
cs.first == SERVICE_PAUSE_PENDING)
{
aux::wlog() << L"Already paused";
return true;
}
else if (cs.first == SERVICE_STOPPED ||
cs.first == SERVICE_STOP_PENDING)
{
aux::wlog() << L"Already stopped, not going to pause";
return true;
}
if (!(dwDesiredAccess_ & SERVICE_PAUSE_CONTINUE))
aquire_permission(SERVICE_PAUSE_CONTINUE);
aux::wlog() << L"Making pause request...";
SERVICE_STATUS ss;
BOOL result = ::ControlService(handle_, SERVICE_CONTROL_PAUSE, &ss);
aux::wlog() << boost::wformat(L"... request %1%") % (result ? L"succeeded" : L"failed");
if (!result) throw_nt_service_exception(lpServiceName_.c_str());
return result;
}
static t_string dwStartType_to_string(DWORD StartType)
{
if (StartType == SERVICE_AUTO_START)
return L"Automatic";
else if (StartType == SERVICE_BOOT_START)
return L"Boot Start";
else if (StartType == SERVICE_DEMAND_START)
return L"Manual";
else if (StartType == SERVICE_DISABLED)
return L"Disabled";
else if (StartType == SERVICE_SYSTEM_START)
return L"System Start";
else if (StartType == SERVICE_NO_CHANGE)
return L"(no change)";
else
return L"?No Start Type?";
}
static t_string dwCurrentState_to_string(DWORD CurrentState)
{
if (CurrentState == SERVICE_CONTINUE_PENDING)
return L"Continue";
else if (CurrentState == SERVICE_PAUSE_PENDING)
return L"Pause pending";
else if (CurrentState == SERVICE_PAUSED)
return L"Paused";
else if (CurrentState == SERVICE_RUNNING)
return L"Running";
else if (CurrentState == SERVICE_START_PENDING)
return L"Start pending";
else if (CurrentState == SERVICE_STOP_PENDING)
return L"Stop pending";
else if (CurrentState == SERVICE_NO_CHANGE)
return L"(no change)";
else if (CurrentState == SERVICE_STOPPED)
return L"Stopped";
else
return L"?No State?";
}
private:
void aquire_permission(DWORD permission)
{
aux::wlog() << L"Trying to get access...";
SC_HANDLE handle = OpenService(*manager_, lpServiceName_.c_str(), dwDesiredAccess_|permission);
if (!handle) throw_nt_service_exception(lpServiceName_.c_str());
aux::wlog() << L"Succeeded";
::CloseServiceHandle(handle_);
handle_ = handle;
dwDesiredAccess_ |= permission;
}
SC_HANDLE handle_;
nt_service_control_manager_ptr manager_;
t_string lpServiceName_;
DWORD dwDesiredAccess_;
};
typedef boost::shared_ptr<nt_service> service_ptr;
#endif // NT_SERVICE_HPP_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -