aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/utils/libservice/src/service.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/libservice/src/service.cpp')
-rw-r--r--utils/libservice/src/service.cpp276
1 files changed, 0 insertions, 276 deletions
diff --git a/utils/libservice/src/service.cpp b/utils/libservice/src/service.cpp
deleted file mode 100644
index 8b5e043..0000000
--- a/utils/libservice/src/service.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com>
-// This file is part of the "Windows 7 drivers" project.
-// For details, see https://github.com/egor-tensin/windows7-drivers.
-// Distributed under the MIT License.
-
-#include "libservice/all.hpp"
-
-#include <Windows.h>
-
-#include <string>
-#include <system_error>
-#include <utility>
-#include <vector>
-
-namespace libservice
-{
- namespace
- {
- ServiceHandle open_service(
- const ServiceManager& mgr,
- const std::string& name)
- {
- const auto raw = OpenServiceA(
- mgr,
- name.c_str(),
- SERVICE_ALL_ACCESS);
-
- if (NULL == raw)
- {
- const auto ec = GetLastError();
- throw std::system_error(
- ec, WindowsErrorCategory::get(), LIBSERVICE_ERROR_PREFIX);
- }
-
- return raw;
- }
-
- ServiceHandle install_service(
- const ServiceManager& mgr,
- const std::string& name,
- const std::string& bin_path)
- {
- const auto raw = CreateServiceA(
- mgr,
- name.c_str(),
- name.c_str(),
- SERVICE_ALL_ACCESS,
- SERVICE_KERNEL_DRIVER,
- SERVICE_DEMAND_START,
- SERVICE_ERROR_NORMAL,
- bin_path.c_str(),
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
-
- if (NULL == raw)
- {
- const auto ec = GetLastError();
- throw std::system_error(
- ec, WindowsErrorCategory::get(), LIBSERVICE_ERROR_PREFIX);
- }
-
- return raw;
- }
-
- void start_service(const ServiceHandle& handle)
- {
- if (!StartService(handle, 0, NULL))
- {
- const auto ec = GetLastError();
- throw std::system_error(
- ec, WindowsErrorCategory::get(), LIBSERVICE_ERROR_PREFIX);
- }
- }
-
- void stop_service(const ServiceHandle& handle)
- {
- SERVICE_STATUS service_status;
-
- if (!ControlService(handle, SERVICE_CONTROL_STOP, &service_status))
- {
- const auto ec = GetLastError();
- throw std::system_error(
- ec, WindowsErrorCategory::get(), LIBSERVICE_ERROR_PREFIX);
- }
- }
-
- void uninstall_service(const ServiceHandle& handle)
- {
- if (!DeleteService(handle))
- {
- const auto ec = GetLastError();
- throw std::system_error(
- ec, WindowsErrorCategory::get(), LIBSERVICE_ERROR_PREFIX);
- }
- }
-
- bool service_exists(
- const ServiceManager& mgr,
- const std::string& name)
- {
- const auto raw = OpenServiceA(
- mgr,
- name.c_str(),
- SERVICE_QUERY_STATUS);
-
- if (NULL != raw)
- {
- ServiceHandle handle(raw);
- return true;
- }
-
- const auto ec = GetLastError();
-
- switch (ec)
- {
- case ERROR_SERVICE_DOES_NOT_EXIST:
- return false;
-
- default:
- throw std::system_error(
- ec, WindowsErrorCategory::get(), LIBSERVICE_ERROR_PREFIX);
- }
- }
-
- SERVICE_STATUS_PROCESS query_service_status(const ServiceHandle& handle)
- {
- SERVICE_STATUS_PROCESS status;
- DWORD nbreq;
-
- const auto buf_ptr = reinterpret_cast<BYTE*>(&status);
- const auto buf_size = sizeof(status);
-
- if (!QueryServiceStatusEx(
- handle, SC_STATUS_PROCESS_INFO, buf_ptr, buf_size, &nbreq))
- {
- const auto ec = GetLastError();
- throw std::system_error(
- ec, WindowsErrorCategory::get(), LIBSERVICE_ERROR_PREFIX);
- }
-
- return status;
- }
-
- DWORD query_service_state(const ServiceHandle& handle)
- {
- return query_service_status(handle).dwCurrentState;
- }
-
- SERVICE_STATUS_PROCESS wait_for_service_state(
- const ServiceHandle& handle,
- const DWORD desired_state)
- {
- auto status = query_service_status(handle);
-
- DWORD old_timestamp = GetTickCount();
-
- DWORD old_check_point = status.dwCheckPoint;
- DWORD old_wait_hint = status.dwWaitHint;
-
- while (desired_state != status.dwCurrentState)
- {
- DWORD wait_time = old_wait_hint / 10;
-
- if (wait_time < 1000)
- wait_time = 1000;
- else if (wait_time > 10000)
- wait_time = 10000;
-
- Sleep(wait_time);
-
- status = query_service_status(handle);
-
- if (desired_state == status.dwCurrentState)
- break;
-
- if (status.dwCheckPoint > old_check_point)
- {
- old_timestamp = GetTickCount();
-
- old_check_point = status.dwCheckPoint;
- old_wait_hint = status.dwWaitHint;
- }
- else if (GetTickCount() - old_timestamp > old_wait_hint)
- {
- return status;
- }
- }
-
- return status;
- }
- }
-
- Service Service::open(
- const ServiceManager& mgr,
- const std::string& name)
- {
- return open_service(mgr, name);
- }
-
- Service Service::install(
- const ServiceManager& mgr,
- const std::string& name,
- const std::string& bin_path)
- {
- return install_service(mgr, name, bin_path);
- }
-
- bool Service::exists(
- const ServiceManager& mgr,
- const std::string& name)
- {
- return service_exists(mgr, name);
- }
-
- void Service::start() const
- {
- const auto state = query_service_state(handle);
-
- switch (state)
- {
- case SERVICE_STOPPED:
- break;
-
- case SERVICE_STOP_PENDING:
- wait_for_service_state(handle, SERVICE_STOPPED);
- break;
-
- default:
- return;
- }
-
- start_service(handle);
- wait_for_service_state(handle, SERVICE_RUNNING);
- }
-
- void Service::stop() const
- {
- switch (query_service_state(handle))
- {
- case SERVICE_STOPPED:
- return;
-
- case SERVICE_STOP_PENDING:
- wait_for_service_state(handle, SERVICE_STOPPED);
- return;
- }
-
- stop_service(handle);
- wait_for_service_state(handle, SERVICE_STOPPED);
- }
-
- void Service::uninstall() const
- {
- stop();
- uninstall_service(handle);
- }
-
- void swap(Service& a, Service& b) LIBSERVICE_NOEXCEPT
- {
- a.swap(b);
- }
-}
-
-namespace std
-{
- template <>
- void swap<libservice::Service>(
- libservice::Service& a,
- libservice::Service& b) LIBSERVICE_NOEXCEPT
- {
- a.swap(b);
- }
-}