Module: check_mk
Branch: master
Commit: cbd8909d9718cf11d0ae4d98176a6836a59158dc
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=cbd8909d9718cf…
Author: Jukka Aro <ja(a)mathias-kettner.de>
Date: Fri Dec 22 11:48:29 2017 +0100
Windows agent: use RAII for service handles
Change-Id: I9785efeda92532e1ff3606e3a70fe9af75d37afa
---
agents/windows/build_version | 2 +-
agents/windows/check_mk_agent.cc | 27 ++++++++++---------------
agents/windows/sections/SectionServices.cc | 32 ++++++++++++++++--------------
agents/windows/types.h | 12 +++++++++++
4 files changed, 41 insertions(+), 32 deletions(-)
diff --git a/agents/windows/build_version b/agents/windows/build_version
index 45a020f..4dd9c1b 100644
--- a/agents/windows/build_version
+++ b/agents/windows/build_version
@@ -1 +1 @@
-3032
+3034
diff --git a/agents/windows/check_mk_agent.cc b/agents/windows/check_mk_agent.cc
index ca0498d..4977b5d 100644
--- a/agents/windows/check_mk_agent.cc
+++ b/agents/windows/check_mk_agent.cc
@@ -365,12 +365,11 @@ void InstallService() {
sizeof(path) / sizeof(path[0])) > 0) {
char quoted_path[1024];
snprintf(quoted_path, sizeof(quoted_path), "\"%s\"",
path);
- SC_HANDLE service = s_winapi.CreateService(
+ ServiceHandle service{s_winapi.CreateService(
serviceControlManager, gszServiceName, gszServiceName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
- SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, quoted_path);
+ SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, quoted_path), s_winapi};
if (service) {
- s_winapi.CloseServiceHandle(service);
printf(SERVICE_NAME " Installed Successfully\n");
} else {
const DWORD lastError = s_winapi.GetLastError();
@@ -382,22 +381,20 @@ void InstallService() {
static_cast<int>(lastError));
}
}
-
- s_winapi.CloseServiceHandle(serviceControlManager);
}
}
void UninstallService() {
- SC_HANDLE serviceControlManager =
- s_winapi.OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ ServiceHandle serviceControlManager{
+ s_winapi.OpenSCManager(0, 0, SC_MANAGER_CONNECT), s_winapi};
if (serviceControlManager) {
- SC_HANDLE service =
- s_winapi.OpenService(serviceControlManager, gszServiceName,
- SERVICE_QUERY_STATUS | DELETE);
+ ServiceHandle service{
+ s_winapi.OpenService(serviceControlManager.get(), gszServiceName,
+ SERVICE_QUERY_STATUS | DELETE), s_winapi};
if (service) {
SERVICE_STATUS serviceStatus;
- if (s_winapi.QueryServiceStatus(service, &serviceStatus)) {
+ if (s_winapi.QueryServiceStatus(service.get(), &serviceStatus)) {
while (in_set(serviceStatus.dwCurrentState,
{SERVICE_RUNNING, SERVICE_STOP_PENDING})) {
if (serviceStatus.dwCurrentState == SERVICE_STOP_PENDING) {
@@ -407,12 +404,12 @@ void UninstallService() {
waitTime =
std::max(1000UL, std::min(waitTime, 10000UL));
s_winapi.Sleep(waitTime);
- if (!s_winapi.QueryServiceStatus(service,
+ if (!s_winapi.QueryServiceStatus(service.get(),
&serviceStatus)) {
break;
}
} else {
- if (s_winapi.ControlService(service,
+ if (s_winapi.ControlService(service.get(),
SERVICE_CONTROL_STOP,
&serviceStatus) == 0) {
break;
@@ -421,7 +418,7 @@ void UninstallService() {
}
if (serviceStatus.dwCurrentState == SERVICE_STOPPED) {
- if (s_winapi.DeleteService(service))
+ if (s_winapi.DeleteService(service.get()))
printf(SERVICE_NAME " Removed Successfully\n");
else {
const DWORD dwError = s_winapi.GetLastError();
@@ -441,9 +438,7 @@ void UninstallService() {
printf(SERVICE_NAME " is still Running.\n");
}
}
- s_winapi.CloseServiceHandle(service);
}
- s_winapi.CloseServiceHandle(serviceControlManager);
}
}
void do_install() { InstallService(); }
diff --git a/agents/windows/sections/SectionServices.cc
b/agents/windows/sections/SectionServices.cc
index b9294fa..ff30ed2 100644
--- a/agents/windows/sections/SectionServices.cc
+++ b/agents/windows/sections/SectionServices.cc
@@ -27,6 +27,7 @@ typedef short SHORT;
#include "Logger.h"
#include "WinApiAdaptor.h"
#include "stringutil.h"
+#include "types.h"
SectionServices::SectionServices(const Environment &env, Logger *logger,
const WinApiAdaptor &winapi)
@@ -38,13 +39,14 @@ const char *SectionServices::serviceStartType(SC_HANDLE scm,
LPCWSTR service_name) {
// Query the start type of the service
const char *start_type = "invalid1";
- SC_HANDLE schService;
LPQUERY_SERVICE_CONFIGW lpsc;
- schService = _winapi.OpenServiceW(scm, service_name, SERVICE_QUERY_CONFIG);
+ ServiceHandle schService{
+ _winapi.OpenServiceW(scm, service_name, SERVICE_QUERY_CONFIG), _winapi};
if (schService) {
start_type = "invalid2";
DWORD dwBytesNeeded, cbBufSize;
- if (!_winapi.QueryServiceConfig(schService, NULL, 0, &dwBytesNeeded)) {
+ if (!_winapi.QueryServiceConfig(schService.get(), NULL, 0,
+ &dwBytesNeeded)) {
start_type = "invalid3";
DWORD dwError = _winapi.GetLastError();
if (dwError == ERROR_INSUFFICIENT_BUFFER) {
@@ -52,8 +54,8 @@ const char *SectionServices::serviceStartType(SC_HANDLE scm,
cbBufSize = dwBytesNeeded;
lpsc = (LPQUERY_SERVICE_CONFIGW)_winapi.LocalAlloc(LMEM_FIXED,
cbBufSize);
- if (_winapi.QueryServiceConfig(schService, lpsc, cbBufSize,
- &dwBytesNeeded)) {
+ if (_winapi.QueryServiceConfig(schService.get(), lpsc,
+ cbBufSize, &dwBytesNeeded)) {
switch (lpsc->dwStartType) {
case SERVICE_AUTO_START:
start_type = "auto";
@@ -77,27 +79,28 @@ const char *SectionServices::serviceStartType(SC_HANDLE scm,
_winapi.LocalFree(lpsc);
}
}
- _winapi.CloseServiceHandle(schService);
}
return start_type;
}
bool SectionServices::produceOutputInner(std::ostream &out) {
Debug(_logger) << "SectionServices::produceOutputInner";
- SC_HANDLE scm = _winapi.OpenSCManager(
- 0, 0, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
- if (scm != INVALID_HANDLE_VALUE) {
+ ServiceHandle scm{
+ _winapi.OpenSCManager(
+ 0, 0, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE),
+ _winapi};
+ if (scm) {
DWORD bytes_needed = 0;
DWORD num_services = 0;
// first determine number of bytes needed
- _winapi.EnumServicesStatusExW(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
- SERVICE_STATE_ALL, NULL, 0, &bytes_needed,
- &num_services, 0, 0);
+ _winapi.EnumServicesStatusExW(scm.get(), SC_ENUM_PROCESS_INFO,
+ SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
+ &bytes_needed, &num_services, 0, 0);
if (_winapi.GetLastError() == ERROR_MORE_DATA && bytes_needed > 0) {
BYTE *buffer = (BYTE *)malloc(bytes_needed);
if (buffer) {
if (_winapi.EnumServicesStatusExW(
- scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
+ scm.get(), SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
SERVICE_STATE_ALL, buffer, bytes_needed, &bytes_needed,
&num_services, 0, 0)) {
ENUM_SERVICE_STATUS_PROCESSW *service =
@@ -131,7 +134,7 @@ bool SectionServices::produceOutputInner(std::ostream &out) {
}
const char *start_type =
- serviceStartType(scm, service->lpServiceName);
+ serviceStartType(scm.get(), service->lpServiceName);
// The service name usually does not contain spaces. But
// in some cases it does. We replace them with _ in
@@ -152,7 +155,6 @@ bool SectionServices::produceOutputInner(std::ostream &out) {
free(buffer);
}
}
- _winapi.CloseServiceHandle(scm);
}
return true;
}
diff --git a/agents/windows/types.h b/agents/windows/types.h
index e6d5b0c..c4b20eb 100644
--- a/agents/windows/types.h
+++ b/agents/windows/types.h
@@ -470,4 +470,16 @@ struct HKeyHandleTraits {
};
using HKeyHandle = WrappedHandle<HKeyHandleTraits>;
+
+struct ServiceHandleTraits {
+ using HandleT = SC_HANDLE;
+ static HandleT invalidValue() { return nullptr; }
+
+ static void closeHandle(HandleT value, const WinApiAdaptor &winapi) {
+ winapi.CloseServiceHandle(value);
+ }
+};
+
+using ServiceHandle = WrappedHandle<ServiceHandleTraits>;
+
#endif // types_h