diff options
Diffstat (limited to 'utils/libservice/include')
-rw-r--r-- | utils/libservice/include/libservice/common.hpp | 19 | ||||
-rw-r--r-- | utils/libservice/include/libservice/interface.hpp | 15 | ||||
-rw-r--r-- | utils/libservice/include/libservice/service.hpp | 69 | ||||
-rw-r--r-- | utils/libservice/include/libservice/service_handle.hpp | 80 | ||||
-rw-r--r-- | utils/libservice/include/libservice/service_manager.hpp | 65 | ||||
-rw-r--r-- | utils/libservice/include/libservice/singleton.hpp | 45 | ||||
-rw-r--r-- | utils/libservice/include/libservice/windows_error.hpp | 36 |
7 files changed, 329 insertions, 0 deletions
diff --git a/utils/libservice/include/libservice/common.hpp b/utils/libservice/include/libservice/common.hpp new file mode 100644 index 0000000..32e2a50 --- /dev/null +++ b/utils/libservice/include/libservice/common.hpp @@ -0,0 +1,19 @@ +/** + * \author Egor Tensin <Egor.Tensin@gmail.com> + * \date 2015 + * \copyright This file is licensed under the terms of the MIT License. + * See LICENSE.txt for details. + */ + +#pragma once + +#define LIBSERVICE_FILE_PATH __FILE__ +#define LIBSERVICE_LINE_NUMBER __LINE__ +#define LIBSERVICE_FUNCTION_NAME __FUNCTION__ + +#define LIBSERVICE_TO_STRING(s) LIBSERVICE_TO_STRING_(s) +#define LIBSERVICE_TO_STRING_(s) #s + +#define LIBSERVICE_LINE_NUMBER_STRING LIBSERVICE_TO_STRING(LIBSERVICE_LINE_NUMBER) + +#define LIBSERVICE_NOEXCEPT throw() diff --git a/utils/libservice/include/libservice/interface.hpp b/utils/libservice/include/libservice/interface.hpp new file mode 100644 index 0000000..058470c --- /dev/null +++ b/utils/libservice/include/libservice/interface.hpp @@ -0,0 +1,15 @@ +/** + * \author Egor Tensin <Egor.Tensin@gmail.com> + * \date 2015 + * \copyright This file is licensed under the terms of the MIT License. + * See LICENSE.txt for details. + */ + +#pragma once + +#include "common.hpp" +#include "service.hpp" +#include "service_handle.hpp" +#include "service_manager.hpp" +#include "singleton.hpp" +#include "windows_error.hpp" diff --git a/utils/libservice/include/libservice/service.hpp b/utils/libservice/include/libservice/service.hpp new file mode 100644 index 0000000..a14f0e2 --- /dev/null +++ b/utils/libservice/include/libservice/service.hpp @@ -0,0 +1,69 @@ +/** + * \file + * \author Egor Tensin <Egor.Tensin@gmail.com> + * \date 2015 + * \copyright This file is licensed under the terms of the MIT License. + * See LICENSE.txt for details. + */ + +#pragma once + +#include "common.hpp" +#include "service_handle.hpp" +#include "service_manager.hpp" + +#include <string> +#include <utility> + +namespace libservice +{ + class Service + { + public: + static Service open(const ServiceManager&, + const std::string& name); + static Service install(const ServiceManager&, + const std::string& name, + const std::string& bin_path); + + void start() const; + void stop() const; + void uninstall() const; + + Service(Service&& other) LIBSERVICE_NOEXCEPT + { + swap(other); + } + + Service& operator=(Service other) LIBSERVICE_NOEXCEPT + { + swap(other); + return *this; + } + + void swap(Service& other) LIBSERVICE_NOEXCEPT + { + using std::swap; + swap(m_handle, other.m_handle); + } + + private: + explicit Service(ServiceHandle h) + : m_handle(std::move(h)) + { } + + ServiceHandle m_handle; + + Service(const Service&) = delete; + }; + + void swap(Service&, Service&) LIBSERVICE_NOEXCEPT; +} + +namespace std +{ + template <> + void swap<libservice::Service>( + libservice::Service&, + libservice::Service&) LIBSERVICE_NOEXCEPT; +} diff --git a/utils/libservice/include/libservice/service_handle.hpp b/utils/libservice/include/libservice/service_handle.hpp new file mode 100644 index 0000000..2068102 --- /dev/null +++ b/utils/libservice/include/libservice/service_handle.hpp @@ -0,0 +1,80 @@ +/** + * \file + * \author Egor Tensin <Egor.Tensin@gmail.com> + * \date 2015 + * \copyright This file is licensed under the terms of the MIT License. + * See LICENSE.txt for details. + */ + +#pragma once + +#include "common.hpp" + +#include <Windows.h> + +#include <memory> +#include <type_traits> +#include <utility> + +namespace libservice +{ + class ServiceHandle + { + public: + ServiceHandle() = default; + + explicit ServiceHandle(SC_HANDLE raw) + : m_impl(raw) + { } + + ServiceHandle(ServiceHandle&& other) LIBSERVICE_NOEXCEPT + { + swap(other); + } + + ServiceHandle& operator=(ServiceHandle other) LIBSERVICE_NOEXCEPT + { + swap(other); + return *this; + } + + explicit operator bool() const + { + return static_cast<bool>(m_impl); + } + + explicit operator SC_HANDLE() const + { + return m_impl.get(); + } + + void swap(ServiceHandle& other) LIBSERVICE_NOEXCEPT + { + using std::swap; + swap(m_impl, other.m_impl); + } + + private: + struct Deleter + { + void operator()(SC_HANDLE raw) + { + ::CloseServiceHandle(raw); + } + }; + + std::unique_ptr<SC_HANDLE__, Deleter> m_impl; + + ServiceHandle(const ServiceHandle&) = delete; + }; + + void swap(ServiceHandle&, ServiceHandle&) LIBSERVICE_NOEXCEPT; +} + +namespace std +{ + template <> + void swap<libservice::ServiceHandle>( + libservice::ServiceHandle&, + libservice::ServiceHandle&) LIBSERVICE_NOEXCEPT; +} diff --git a/utils/libservice/include/libservice/service_manager.hpp b/utils/libservice/include/libservice/service_manager.hpp new file mode 100644 index 0000000..a2bb268 --- /dev/null +++ b/utils/libservice/include/libservice/service_manager.hpp @@ -0,0 +1,65 @@ +/** + * \author Egor Tensin <Egor.Tensin@gmail.com> + * \date 2015 + * \copyright This file is licensed under the terms of the MIT License. + * See LICENSE.txt for details. + */ + +#pragma once + +#include "common.hpp" +#include "service_handle.hpp" + +#include <Windows.h> + +#include <utility> + +namespace libservice +{ + class ServiceManager + { + public: + static ServiceManager open(); + + ServiceManager(ServiceManager&& other) LIBSERVICE_NOEXCEPT + { + swap(other); + } + + ServiceManager& operator=(ServiceManager other) LIBSERVICE_NOEXCEPT + { + swap(other); + return *this; + } + + void swap(ServiceManager& other) LIBSERVICE_NOEXCEPT + { + using std::swap; + swap(m_handle, other.m_handle); + } + + explicit operator SC_HANDLE() const + { + return static_cast<SC_HANDLE>(m_handle); + } + + private: + explicit ServiceManager(ServiceHandle h) + : m_handle(std::move(h)) + { } + + ServiceHandle m_handle; + + ServiceManager(const ServiceManager&) = delete; + }; + + void swap(ServiceManager& a, ServiceManager& b) LIBSERVICE_NOEXCEPT; +} + +namespace std +{ + template <> + void swap<libservice::ServiceManager>( + libservice::ServiceManager&, + libservice::ServiceManager&) LIBSERVICE_NOEXCEPT; +} diff --git a/utils/libservice/include/libservice/singleton.hpp b/utils/libservice/include/libservice/singleton.hpp new file mode 100644 index 0000000..bd137e7 --- /dev/null +++ b/utils/libservice/include/libservice/singleton.hpp @@ -0,0 +1,45 @@ +/** + * \author Egor Tensin <Egor.Tensin@gmail.com> + * \date 2015 + * \copyright This file is licensed under the terms of the MIT License. + * See LICENSE.txt for details. + */ + +#pragma once + +#include <mutex> + +namespace libservice +{ + template <typename DerivedType> + class Singleton + { + public: + static DerivedType& get() + { + std::call_once(is_initialized, initialize); + return get_unsafe(); + } + + protected: + Singleton() = default; + virtual ~Singleton() = default; + + private: + static void initialize() + { + get_unsafe(); + } + + static DerivedType& get_unsafe() + { + static DerivedType instance; + return instance; + } + + static std::once_flag is_initialized; + }; + + template <typename DerivedType> + std::once_flag Singleton<DerivedType>::is_initialized; +} diff --git a/utils/libservice/include/libservice/windows_error.hpp b/utils/libservice/include/libservice/windows_error.hpp new file mode 100644 index 0000000..57730d5 --- /dev/null +++ b/utils/libservice/include/libservice/windows_error.hpp @@ -0,0 +1,36 @@ +/** + * \author Egor Tensin <Egor.Tensin@gmail.com> + * \date 2015 + * \copyright This file is licensed under the terms of the MIT License. + * See LICENSE.txt for details. + */ + +#pragma once + +#include "common.hpp" +#include "singleton.hpp" + +#include <string> +#include <system_error> + +namespace libservice +{ + class WinErrorCategory : public std::error_category + , public Singleton<WinErrorCategory> + { + public: + const char* name() const LIBSERVICE_NOEXCEPT { return "windows"; } + + std::string message(int) const; + + private: + friend class Singleton<WinErrorCategory>; + }; +} + +#define LIBSERVICE_ERROR_PREFIX "Error in function '" \ + LIBSERVICE_FUNCTION_NAME \ + "' at file '" \ + LIBSERVICE_FILE_PATH \ + "', line " \ + LIBSERVICE_LINE_NUMBER_STRING |