summaryrefslogtreecommitdiffhomepage
path: root/windows/driverlogic/src/service.cpp
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-07-21 16:30:28 +0200
committerDavid Lönnhager <david.l@mullvad.net>2022-08-25 15:16:40 +0200
commit29df2434c5e726574379860329eb123c2139dad6 (patch)
tree34be2878dae0de5a5929d8eaa53f82cf89667fc1 /windows/driverlogic/src/service.cpp
parent91d8377262050012de75979e5c940cb6812f25ea (diff)
downloadmullvadvpn-29df2434c5e726574379860329eb123c2139dad6.tar.xz
mullvadvpn-29df2434c5e726574379860329eb123c2139dad6.zip
Remove ST setup from installer and increase robustness of cleanup
Cleanup will now succeed in these cases: 1. There is no devnode, but the driver service exists. 2. There is no driver service, but there is a devnode. 3. The service exists but isn't running.
Diffstat (limited to 'windows/driverlogic/src/service.cpp')
-rw-r--r--windows/driverlogic/src/service.cpp93
1 files changed, 77 insertions, 16 deletions
diff --git a/windows/driverlogic/src/service.cpp b/windows/driverlogic/src/service.cpp
index 14ed7880fa..f1daa1abfb 100644
--- a/windows/driverlogic/src/service.cpp
+++ b/windows/driverlogic/src/service.cpp
@@ -43,29 +43,46 @@ private:
TTime m_maxWaitTime;
};
+SERVICE_STATUS_PROCESS GetServiceProcessStatus(SC_HANDLE service)
+{
+ SERVICE_STATUS_PROCESS ssp;
+
+ DWORD bytesNeeded;
+
+ auto status = QueryServiceStatusEx
+ (
+ service,
+ SC_STATUS_PROCESS_INFO,
+ reinterpret_cast<BYTE*>(&ssp),
+ sizeof(ssp),
+ &bytesNeeded
+ );
+
+ if (status != 0)
+ {
+ return ssp;
+ }
+
+ THROW_WINDOWS_ERROR(GetLastError(), "QueryServiceStatusEx");
+}
+
void WaitUntilServiceStopped(SC_HANDLE service, DWORD maxWaitMs)
{
TimeBox timer(maxWaitMs);
for (;;)
{
- SERVICE_STATUS_PROCESS ssp;
-
- DWORD bytesNeeded;
-
- auto status = QueryServiceStatusEx
- (
- service,
- SC_STATUS_PROCESS_INFO,
- reinterpret_cast<BYTE*>(&ssp),
- sizeof(ssp),
- &bytesNeeded
- );
+ try
+ {
+ const auto status = GetServiceProcessStatus(service);
- if (status != 0
- && ssp.dwCurrentState == SERVICE_STOPPED)
+ if (status.dwCurrentState == SERVICE_STOPPED)
+ {
+ return;
+ }
+ }
+ catch (...)
{
- return;
}
if (timer.expired())
@@ -77,6 +94,41 @@ void WaitUntilServiceStopped(SC_HANDLE service, DWORD maxWaitMs)
}
}
+bool ServiceIsRunning(const std::wstring &serviceName)
+{
+ const auto serviceManager = OpenSCManagerW(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
+
+ if (serviceManager == NULL)
+ {
+ THROW_WINDOWS_ERROR(GetLastError(), "OpenSCManagerW");
+ }
+
+ common::memory::ScopeDestructor dtor;
+
+ dtor += [serviceManager]()
+ {
+ CloseServiceHandle(serviceManager);
+ };
+
+ const auto service = OpenServiceW(serviceManager, serviceName.c_str(), SERVICE_ALL_ACCESS);
+
+ if (service == NULL)
+ {
+ const auto error = GetLastError();
+
+ if (error != ERROR_SERVICE_DOES_NOT_EXIST)
+ {
+ THROW_WINDOWS_ERROR(error, "OpenServiceW");
+ }
+
+ return false;
+ }
+
+ CloseServiceHandle(service);
+
+ return GetServiceProcessStatus(service).dwCurrentState == SERVICE_RUNNING;
+}
+
void PokeService(const std::wstring &serviceName, bool stopService, bool deleteService)
{
auto serviceManager = OpenSCManagerW(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
@@ -97,7 +149,16 @@ void PokeService(const std::wstring &serviceName, bool stopService, bool deleteS
if (service == NULL)
{
- THROW_WINDOWS_ERROR(GetLastError(), "OpenServiceW");
+ const auto error = GetLastError();
+
+ if (error != ERROR_SERVICE_DOES_NOT_EXIST)
+ {
+ THROW_WINDOWS_ERROR(error, "OpenServiceW");
+ }
+
+ // If the service does not exist, we're done.
+
+ return;
}
dtor += [service]()